From eb63231830360f5acfea5dd2b545d7a14476bc3a Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Wed, 14 Aug 2013 12:27:33 +0200 Subject: ASoc: kirkwood: add DT support to the mvebu audio subsystem This patch adds DT support to the audio subsystem of the mvebu family (Kirkwood, Dove, Armada 370). Signed-off-by: Jean-Francois Moine Signed-off-by: Mark Brown --- sound/soc/kirkwood/kirkwood-i2s.c | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) (limited to 'sound') diff --git a/sound/soc/kirkwood/kirkwood-i2s.c b/sound/soc/kirkwood/kirkwood-i2s.c index e5f3f7a9ea26..7fce340ab3ef 100644 --- a/sound/soc/kirkwood/kirkwood-i2s.c +++ b/sound/soc/kirkwood/kirkwood-i2s.c @@ -22,6 +22,8 @@ #include #include #include +#include + #include "kirkwood.h" #define DRV_NAME "mvebu-audio" @@ -453,6 +455,7 @@ static int kirkwood_i2s_dev_probe(struct platform_device *pdev) struct snd_soc_dai_driver *soc_dai = &kirkwood_i2s_dai; struct kirkwood_dma_data *priv; struct resource *mem; + struct device_node *np = pdev->dev.of_node; int err; priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); @@ -473,14 +476,16 @@ static int kirkwood_i2s_dev_probe(struct platform_device *pdev) return -ENXIO; } - if (!data) { - dev_err(&pdev->dev, "no platform data ?!\n"); + if (np) { + priv->burst = 128; /* might be 32 or 128 */ + } else if (data) { + priv->burst = data->burst; + } else { + dev_err(&pdev->dev, "no DT nor platform data ?!\n"); return -EINVAL; } - priv->burst = data->burst; - - priv->clk = devm_clk_get(&pdev->dev, NULL); + priv->clk = devm_clk_get(&pdev->dev, np ? "internal" : NULL); if (IS_ERR(priv->clk)) { dev_err(&pdev->dev, "no clock\n"); return PTR_ERR(priv->clk); @@ -507,7 +512,7 @@ static int kirkwood_i2s_dev_probe(struct platform_device *pdev) priv->ctl_rec = KIRKWOOD_RECCTL_SIZE_24; /* Select the burst size */ - if (data->burst == 32) { + if (priv->burst == 32) { priv->ctl_play |= KIRKWOOD_PLAYCTL_BURST_32; priv->ctl_rec |= KIRKWOOD_RECCTL_BURST_32; } else { @@ -552,12 +557,21 @@ static int kirkwood_i2s_dev_remove(struct platform_device *pdev) return 0; } +#ifdef CONFIG_OF +static struct of_device_id mvebu_audio_of_match[] = { + { .compatible = "marvell,mvebu-audio" }, + { } +}; +MODULE_DEVICE_TABLE(of, mvebu_audio_of_match); +#endif + static struct platform_driver kirkwood_i2s_driver = { .probe = kirkwood_i2s_dev_probe, .remove = kirkwood_i2s_dev_remove, .driver = { .name = DRV_NAME, .owner = THIS_MODULE, + .of_match_table = of_match_ptr(mvebu_audio_of_match), }, }; -- cgit From c445be35956b0cefe85db75d1e7994af5cecf16a Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Fri, 23 Aug 2013 14:35:17 -0300 Subject: ASoC: simple-card: Provide owner and MODULE_ALIAS() Add .owner field and also MODULE_ALIAS(), so that auto module loading can work. Signed-off-by: Fabio Estevam Signed-off-by: Mark Brown --- sound/soc/generic/simple-card.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'sound') diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c index 6cf8355a8542..8c49147db84c 100644 --- a/sound/soc/generic/simple-card.c +++ b/sound/soc/generic/simple-card.c @@ -105,6 +105,7 @@ static int asoc_simple_card_remove(struct platform_device *pdev) static struct platform_driver asoc_simple_card = { .driver = { .name = "asoc-simple-card", + .owner = THIS_MODULE, }, .probe = asoc_simple_card_probe, .remove = asoc_simple_card_remove, @@ -112,6 +113,7 @@ static struct platform_driver asoc_simple_card = { module_platform_driver(asoc_simple_card); +MODULE_ALIAS("platform:asoc-simple-card"); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("ASoC Simple Sound Card"); MODULE_AUTHOR("Kuninori Morimoto "); -- cgit From 5af407cd365c8aab8a20e66aa6e4bc4a4983979e Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Fri, 23 Aug 2013 18:14:45 -0300 Subject: ASoC: fsl_spdif: Remove unnecessary dev_set_drvdata() Driver core clears the driver data to NULL after device_release or on probe failure, so just remove it from here. Signed-off-by: Fabio Estevam Reviewed-by: Nicolin Chen Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_spdif.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'sound') diff --git a/sound/soc/fsl/fsl_spdif.c b/sound/soc/fsl/fsl_spdif.c index 42a43820d993..a8ef46a3281b 100644 --- a/sound/soc/fsl/fsl_spdif.c +++ b/sound/soc/fsl/fsl_spdif.c @@ -1184,7 +1184,7 @@ static int fsl_spdif_probe(struct platform_device *pdev) &spdif_priv->cpu_dai_drv, 1); if (ret) { dev_err(&pdev->dev, "failed to register DAI: %d\n", ret); - goto error_dev; + return ret; } ret = imx_pcm_dma_init(pdev); @@ -1197,8 +1197,6 @@ static int fsl_spdif_probe(struct platform_device *pdev) error_component: snd_soc_unregister_component(&pdev->dev); -error_dev: - dev_set_drvdata(&pdev->dev, NULL); return ret; } @@ -1207,7 +1205,6 @@ static int fsl_spdif_remove(struct platform_device *pdev) { imx_pcm_dma_exit(pdev); snd_soc_unregister_component(&pdev->dev); - dev_set_drvdata(&pdev->dev, NULL); return 0; } -- cgit From 6d22db43cf8b841dae37e7e3ee284c2b6c91a58b Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Fri, 23 Aug 2013 18:14:46 -0300 Subject: ASoC: fsl_spdif: Reduce the noise on comments Remove the "====" pattern to let the comments cleaner and more uniform. Also, do not use multi-line style for a single line comment. Signed-off-by: Fabio Estevam Acked-by: Nicolin Chen Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_spdif.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'sound') diff --git a/sound/soc/fsl/fsl_spdif.c b/sound/soc/fsl/fsl_spdif.c index a8ef46a3281b..a9798aa1cd8d 100644 --- a/sound/soc/fsl/fsl_spdif.c +++ b/sound/soc/fsl/fsl_spdif.c @@ -555,7 +555,6 @@ struct snd_soc_dai_ops fsl_spdif_dai_ops = { /* - * ============================================ * FSL SPDIF IEC958 controller(mixer) functions * * Channel status get/put control @@ -563,7 +562,6 @@ struct snd_soc_dai_ops fsl_spdif_dai_ops = { * Valid bit value get control * DPLL lock status get control * User bit sync mode selection control - * ============================================ */ static int fsl_spdif_info(struct snd_kcontrol *kcontrol, @@ -942,11 +940,7 @@ static const struct snd_soc_component_driver fsl_spdif_component = { .name = "fsl-spdif", }; -/* - * ================ - * FSL SPDIF REGMAP - * ================ - */ +/* FSL SPDIF REGMAP */ static bool fsl_spdif_readable_reg(struct device *dev, unsigned int reg) { -- cgit From 53110a256a334c5e01db2d94c5306b4880a9180e Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Sun, 25 Aug 2013 23:36:23 -0700 Subject: ASoC: fsi: reserve prefetch period on DMA transferring Current FSI is supporting DMAEngine transfer, but, it needs to use work queue. Therefore, DMA transfer settings might be late if there is heavy task. This patch reserves next period beforehand on DMA transfer function. Android sound will be breaking up without this patch. Tested-by: Tomohito Esaki Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/fsi.c | 51 +++++++++++++++++++++++++++++++++------------------ 1 file changed, 33 insertions(+), 18 deletions(-) (limited to 'sound') diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c index 30390260bb67..b33ca7cd085b 100644 --- a/sound/soc/sh/fsi.c +++ b/sound/soc/sh/fsi.c @@ -235,6 +235,8 @@ struct fsi_stream { struct sh_dmae_slave slave; /* see fsi_handler_init() */ struct work_struct work; dma_addr_t dma; + int loop_cnt; + int additional_pos; }; struct fsi_clk { @@ -1289,6 +1291,8 @@ static int fsi_dma_init(struct fsi_priv *fsi, struct fsi_stream *io) io->bus_option = BUSOP_SET(24, PACKAGE_24BITBUS_BACK) | BUSOP_SET(16, PACKAGE_16BITBUS_STREAM); + io->loop_cnt = 2; /* push 1st, 2nd period first, then 3rd, 4th... */ + io->additional_pos = 0; io->dma = dma_map_single(dai->dev, runtime->dma_area, snd_pcm_lib_buffer_bytes(io->substream), dir); return 0; @@ -1305,11 +1309,15 @@ static int fsi_dma_quit(struct fsi_priv *fsi, struct fsi_stream *io) return 0; } -static dma_addr_t fsi_dma_get_area(struct fsi_stream *io) +static dma_addr_t fsi_dma_get_area(struct fsi_stream *io, int additional) { struct snd_pcm_runtime *runtime = io->substream->runtime; + int period = io->period_pos + additional; - return io->dma + samples_to_bytes(runtime, io->buff_sample_pos); + if (period >= runtime->periods) + period = 0; + + return io->dma + samples_to_bytes(runtime, period * io->period_samples); } static void fsi_dma_complete(void *data) @@ -1321,7 +1329,7 @@ static void fsi_dma_complete(void *data) enum dma_data_direction dir = fsi_stream_is_play(fsi, io) ? DMA_TO_DEVICE : DMA_FROM_DEVICE; - dma_sync_single_for_cpu(dai->dev, fsi_dma_get_area(io), + dma_sync_single_for_cpu(dai->dev, fsi_dma_get_area(io, 0), samples_to_bytes(runtime, io->period_samples), dir); io->buff_sample_pos += io->period_samples; @@ -1347,7 +1355,7 @@ static void fsi_dma_do_work(struct work_struct *work) struct snd_pcm_runtime *runtime; enum dma_data_direction dir; int is_play = fsi_stream_is_play(fsi, io); - int len; + int len, i; dma_addr_t buf; if (!fsi_stream_is_working(fsi, io)) @@ -1357,26 +1365,33 @@ static void fsi_dma_do_work(struct work_struct *work) runtime = io->substream->runtime; dir = is_play ? DMA_TO_DEVICE : DMA_FROM_DEVICE; len = samples_to_bytes(runtime, io->period_samples); - buf = fsi_dma_get_area(io); - dma_sync_single_for_device(dai->dev, buf, len, dir); + for (i = 0; i < io->loop_cnt; i++) { + buf = fsi_dma_get_area(io, io->additional_pos); - desc = dmaengine_prep_slave_single(io->chan, buf, len, dir, - DMA_PREP_INTERRUPT | DMA_CTRL_ACK); - if (!desc) { - dev_err(dai->dev, "dmaengine_prep_slave_sg() fail\n"); - return; - } + dma_sync_single_for_device(dai->dev, buf, len, dir); - desc->callback = fsi_dma_complete; - desc->callback_param = io; + desc = dmaengine_prep_slave_single(io->chan, buf, len, dir, + DMA_PREP_INTERRUPT | DMA_CTRL_ACK); + if (!desc) { + dev_err(dai->dev, "dmaengine_prep_slave_sg() fail\n"); + return; + } - if (dmaengine_submit(desc) < 0) { - dev_err(dai->dev, "tx_submit() fail\n"); - return; + desc->callback = fsi_dma_complete; + desc->callback_param = io; + + if (dmaengine_submit(desc) < 0) { + dev_err(dai->dev, "tx_submit() fail\n"); + return; + } + + dma_async_issue_pending(io->chan); + + io->additional_pos = 1; } - dma_async_issue_pending(io->chan); + io->loop_cnt = 1; /* * FIXME -- cgit From f61df384282dfd1ca845e73ca8b8a187b87eb38a Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Mon, 26 Aug 2013 09:25:13 -0300 Subject: ASoC: fsl_ssi: Remove unnecessary dev_set_drvdata() Driver core clears the driver data to NULL after device_release or on probe failure, so just remove it from here. Signed-off-by: Fabio Estevam Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_ssi.c | 1 - 1 file changed, 1 deletion(-) (limited to 'sound') diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index 5cf626c4dc96..c6b743978d5e 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c @@ -1114,7 +1114,6 @@ error_dai: snd_soc_unregister_component(&pdev->dev); error_dev: - dev_set_drvdata(&pdev->dev, NULL); device_remove_file(&pdev->dev, dev_attr); error_clk: -- cgit From a85f9da707366e856c0aad9e329db0cc59475290 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 27 Aug 2013 15:50:55 +0200 Subject: ASoC: dmic: Convert table based DAPM setup Let the core take care of instantiating the DAPM widgets and routes, this makes the code a bit shorter. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/codecs/dmic.c | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) (limited to 'sound') diff --git a/sound/soc/codecs/dmic.c b/sound/soc/codecs/dmic.c index 66967ba6f757..b2090b2a5e2d 100644 --- a/sound/soc/codecs/dmic.c +++ b/sound/soc/codecs/dmic.c @@ -50,20 +50,11 @@ static const struct snd_soc_dapm_route intercon[] = { {"DMIC AIF", NULL, "DMic"}, }; -static int dmic_probe(struct snd_soc_codec *codec) -{ - struct snd_soc_dapm_context *dapm = &codec->dapm; - - snd_soc_dapm_new_controls(dapm, dmic_dapm_widgets, - ARRAY_SIZE(dmic_dapm_widgets)); - snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon)); - snd_soc_dapm_new_widgets(dapm); - - return 0; -} - static struct snd_soc_codec_driver soc_dmic = { - .probe = dmic_probe, + .dapm_widgets = dmic_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(dmic_dapm_widgets), + .dapm_routes = intercon, + .num_dapm_routes = ARRAY_SIZE(intercon), }; static int dmic_dev_probe(struct platform_device *pdev) -- cgit From 34742cb02bd368c1af3349c041d3e4446f7ac6ef Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 27 Aug 2013 15:50:54 +0200 Subject: ASoC: dapm: Fix marking widgets dirty when a route is added The current calls to dapm_mark_dirty() in snd_soc_dapm_add_path() are on a path that is only reached if the sink widget is either a mixer or a mux. Move the calls further up so they are called for all widget types. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/soc-dapm.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'sound') diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index d84bd0f167b6..7e9afbc49ef2 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -2374,6 +2374,9 @@ static int snd_soc_dapm_add_path(struct snd_soc_dapm_context *dapm, wsource->ext = 1; } + dapm_mark_dirty(wsource, "Route added"); + dapm_mark_dirty(wsink, "Route added"); + /* connect static paths */ if (control == NULL) { list_add(&path->list, &dapm->card->paths); @@ -2436,9 +2439,6 @@ static int snd_soc_dapm_add_path(struct snd_soc_dapm_context *dapm, return 0; } - dapm_mark_dirty(wsource, "Route added"); - dapm_mark_dirty(wsink, "Route added"); - return 0; err: kfree(path); -- cgit From aac97b5fd9537b62a68830d189509297cdac5ad9 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 27 Aug 2013 15:50:56 +0200 Subject: ASoC: tlv320aic32x4: Convert table based control and DAPM setup Let the core take care of instantiating the controls and DAPM widgets and routes, this makes the code a bit shorter. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/codecs/tlv320aic32x4.c | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-) (limited to 'sound') diff --git a/sound/soc/codecs/tlv320aic32x4.c b/sound/soc/codecs/tlv320aic32x4.c index 17df4e32feac..2ed57d4aa445 100644 --- a/sound/soc/codecs/tlv320aic32x4.c +++ b/sound/soc/codecs/tlv320aic32x4.c @@ -338,18 +338,6 @@ static inline int aic32x4_get_divs(int mclk, int rate) return -EINVAL; } -static int aic32x4_add_widgets(struct snd_soc_codec *codec) -{ - snd_soc_dapm_new_controls(&codec->dapm, aic32x4_dapm_widgets, - ARRAY_SIZE(aic32x4_dapm_widgets)); - - snd_soc_dapm_add_routes(&codec->dapm, aic32x4_dapm_routes, - ARRAY_SIZE(aic32x4_dapm_routes)); - - snd_soc_dapm_new_widgets(&codec->dapm); - return 0; -} - static int aic32x4_set_dai_sysclk(struct snd_soc_dai *codec_dai, int clk_id, unsigned int freq, int dir) { @@ -683,9 +671,6 @@ static int aic32x4_probe(struct snd_soc_codec *codec) } aic32x4_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - snd_soc_add_codec_controls(codec, aic32x4_snd_controls, - ARRAY_SIZE(aic32x4_snd_controls)); - aic32x4_add_widgets(codec); /* * Workaround: for an unknown reason, the ADC needs to be powered up @@ -714,6 +699,13 @@ static struct snd_soc_codec_driver soc_codec_dev_aic32x4 = { .suspend = aic32x4_suspend, .resume = aic32x4_resume, .set_bias_level = aic32x4_set_bias_level, + + .controls = aic32x4_snd_controls, + .num_controls = ARRAY_SIZE(aic32x4_snd_controls), + .dapm_widgets = aic32x4_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(aic32x4_dapm_widgets), + .dapm_routes = aic32x4_dapm_routes, + .num_dapm_routes = ARRAY_SIZE(aic32x4_dapm_routes), }; static int aic32x4_i2c_probe(struct i2c_client *i2c, -- cgit From 318ee162c882526685be4f44d7b519cdcc45cbfe Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 27 Aug 2013 15:50:57 +0200 Subject: ASoC: wm8904: Remove unnecessary call to snd_soc_dapm_new_widgets() The core will call snd_soc_dapm_new_widgets() once all components of the card have been initialized, so there is no need to do this manually in the driver. Calling it earlier also might result in a partially instantiated system being powered up which cause undesired side effects. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/codecs/wm8904.c | 1 - 1 file changed, 1 deletion(-) (limited to 'sound') diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c index 91dfbfeda6f8..4dfa8dceeabf 100644 --- a/sound/soc/codecs/wm8904.c +++ b/sound/soc/codecs/wm8904.c @@ -1202,7 +1202,6 @@ static int wm8904_add_widgets(struct snd_soc_codec *codec) break; } - snd_soc_dapm_new_widgets(dapm); return 0; } -- cgit From 148663074c1778d88c9e9c5f5cc66493ed30fa25 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 27 Aug 2013 15:50:58 +0200 Subject: ASoC: jack: Remove unnecessary call to snd_soc_dapm_new_widgets() snd_soc_jack_add_pins() does not create any new DAPM widgets, so there is no need to call snd_soc_dapm_new_widgets(). Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/soc-jack.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'sound') diff --git a/sound/soc/soc-jack.c b/sound/soc/soc-jack.c index 7aa26b5178aa..71358e3b54d9 100644 --- a/sound/soc/soc-jack.c +++ b/sound/soc/soc-jack.c @@ -183,8 +183,6 @@ int snd_soc_jack_add_pins(struct snd_soc_jack *jack, int count, list_add(&(pins[i].list), &jack->pins); } - snd_soc_dapm_new_widgets(&jack->codec->card->dapm); - /* Update to reflect the last reported status; canned jack * implementations are likely to set their state before the * card has an opportunity to associate pins. -- cgit From 4b52fa211a7c65eab78acf3f434361d40de87688 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 27 Aug 2013 15:50:59 +0200 Subject: ASoC: Call snd_soc_dapm_new_widgets() only once during card initialization Each time snd_soc_dapm_new_widgets() is called it will instantiate all the widgets and routes that have been added so far and then power them. Doing this multiple times before the card is fully initialized and all widgets have been added can cause unnecessary and even invalid power state transitions which can result in extra register writes and and also might cause clicks and pops. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/soc-core.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'sound') diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index f46472d50c9b..85e2a8b8f288 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -1230,9 +1230,6 @@ static int soc_post_component_init(struct snd_soc_card *card, } rtd->card = card; - /* Make sure all DAPM widgets are instantiated */ - snd_soc_dapm_new_widgets(&codec->dapm); - /* machine controls, routes and widgets are not prefixed */ temp = codec->name_prefix; codec->name_prefix = NULL; @@ -1728,8 +1725,6 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card) snd_soc_dapm_add_routes(&card->dapm, card->dapm_routes, card->num_dapm_routes); - snd_soc_dapm_new_widgets(&card->dapm); - for (i = 0; i < card->num_links; i++) { dai_link = &card->dai_link[i]; dai_fmt = dai_link->dai_fmt; -- cgit From 8c193b8dce4f2a2474dc2bc39ec972454df9d439 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 27 Aug 2013 15:51:00 +0200 Subject: ASoC: Move call to snd_soc_dapm_new_widgets() after snd_soc_dapm_auto_nc_codec_pins() Call snd_soc_dapm_new_widgets() before the auto non-connected pins have been marked as not connected will power the system under the assumption that those pins are connected. Once the pins have been marked as disconnected the system there will be an additional power run. This can cause unnecessary power transitions. Calling snd_soc_dapm_new_widgets() only after the pins have been marked as non-connected avoids this. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/soc-core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sound') diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 85e2a8b8f288..9375012ccb21 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -1803,12 +1803,12 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card) } } - snd_soc_dapm_new_widgets(&card->dapm); - if (card->fully_routed) list_for_each_entry(codec, &card->codec_dev_list, card_list) snd_soc_dapm_auto_nc_codec_pins(codec); + snd_soc_dapm_new_widgets(&card->dapm); + ret = snd_card_register(card->snd_card); if (ret < 0) { dev_err(card->dev, "ASoC: failed to register soundcard %d\n", -- cgit From 824ef826f3c4d83d1925a5e351313bfd3e5ca6cb Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 27 Aug 2013 15:51:01 +0200 Subject: ASoC: Pass card instead of dapm context to snd_soc_dapm_new_widgets() snd_soc_dapm_new_widgets() works on the ASoC card as a whole not on a specific DAPM context. The DAPM context that is passed as the parameter is only used to look up the pointer to the card. This patch updates the signature of snd_soc_dapm_new_widgets() to take the card directly. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/soc-core.c | 2 +- sound/soc/soc-dapm.c | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) (limited to 'sound') diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index d476f752e3f1..ed3c253066b1 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -1807,7 +1807,7 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card) list_for_each_entry(codec, &card->codec_dev_list, card_list) snd_soc_dapm_auto_nc_codec_pins(codec); - snd_soc_dapm_new_widgets(&card->dapm); + snd_soc_dapm_new_widgets(card); ret = snd_card_register(card->snd_card); if (ret < 0) { diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 7e9afbc49ef2..548b1c9e875e 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -2712,9 +2712,8 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_weak_routes); * * Returns 0 for success. */ -int snd_soc_dapm_new_widgets(struct snd_soc_dapm_context *dapm) +int snd_soc_dapm_new_widgets(struct snd_soc_card *card) { - struct snd_soc_card *card = dapm->card; struct snd_soc_dapm_widget *w; unsigned int val; -- cgit From 446a3bd4329bcaf95d71c6717c2c424a0f97ff18 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Tue, 27 Aug 2013 20:27:11 +0200 Subject: ASoc: kirkwood: Use the Kirkwood audio driver in Dove boards This patch permits the generation of the Kirkwood audio driver which may be used in the Dove boards. Signed-off-by: Jean-Francois Moine Signed-off-by: Mark Brown --- sound/soc/kirkwood/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sound') diff --git a/sound/soc/kirkwood/Kconfig b/sound/soc/kirkwood/Kconfig index 9e1970c44e86..78ed4a42ad21 100644 --- a/sound/soc/kirkwood/Kconfig +++ b/sound/soc/kirkwood/Kconfig @@ -1,6 +1,6 @@ config SND_KIRKWOOD_SOC - tristate "SoC Audio for the Marvell Kirkwood chip" - depends on ARCH_KIRKWOOD || COMPILE_TEST + tristate "SoC Audio for the Marvell Kirkwood and Dove chips" + depends on ARCH_KIRKWOOD || ARCH_DOVE || COMPILE_TEST help Say Y or M if you want to add support for codecs attached to the Kirkwood I2S interface. You will also need to select the -- cgit From 2a956ec04b3703809b6cf500dbee450e44f3a70c Mon Sep 17 00:00:00 2001 From: Nicolin Chen Date: Wed, 28 Aug 2013 12:04:46 +0800 Subject: ASoC: fsl: Add S/PDIF machine driver This patch implements a device-tree-only machine driver for Freescale i.MX series Soc. It works with spdif_transmitter/spdif_receiver and fsl_spdif.c drivers. Signed-off-by: Nicolin Chen Acked-by: Stephen Warren Signed-off-by: Mark Brown --- sound/soc/fsl/Kconfig | 11 ++++ sound/soc/fsl/Makefile | 2 + sound/soc/fsl/imx-spdif.c | 148 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 161 insertions(+) create mode 100644 sound/soc/fsl/imx-spdif.c (limited to 'sound') diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig index cd088cc8c866..a70838034600 100644 --- a/sound/soc/fsl/Kconfig +++ b/sound/soc/fsl/Kconfig @@ -193,6 +193,17 @@ config SND_SOC_IMX_SGTL5000 Say Y if you want to add support for SoC audio on an i.MX board with a sgtl5000 codec. +config SND_SOC_IMX_SPDIF + tristate "SoC Audio support for i.MX boards with S/PDIF" + select SND_SOC_IMX_PCM_DMA + select SND_SOC_FSL_SPDIF + select SND_SOC_FSL_UTILS + select SND_SOC_SPDIF + help + SoC Audio support for i.MX boards with S/PDIF + Say Y if you want to add support for SoC audio on an i.MX board with + a S/DPDIF. + config SND_SOC_IMX_MC13783 tristate "SoC Audio support for I.MX boards with mc13783" depends on MFD_MC13783 && ARM diff --git a/sound/soc/fsl/Makefile b/sound/soc/fsl/Makefile index 4b5970e014dd..e2aaff717f8a 100644 --- a/sound/soc/fsl/Makefile +++ b/sound/soc/fsl/Makefile @@ -45,6 +45,7 @@ snd-soc-mx27vis-aic32x4-objs := mx27vis-aic32x4.o snd-soc-wm1133-ev1-objs := wm1133-ev1.o snd-soc-imx-sgtl5000-objs := imx-sgtl5000.o snd-soc-imx-wm8962-objs := imx-wm8962.o +snd-soc-imx-spdif-objs :=imx-spdif.o snd-soc-imx-mc13783-objs := imx-mc13783.o obj-$(CONFIG_SND_SOC_EUKREA_TLV320) += snd-soc-eukrea-tlv320.o @@ -53,4 +54,5 @@ obj-$(CONFIG_SND_SOC_MX27VIS_AIC32X4) += snd-soc-mx27vis-aic32x4.o obj-$(CONFIG_SND_MXC_SOC_WM1133_EV1) += snd-soc-wm1133-ev1.o obj-$(CONFIG_SND_SOC_IMX_SGTL5000) += snd-soc-imx-sgtl5000.o obj-$(CONFIG_SND_SOC_IMX_WM8962) += snd-soc-imx-wm8962.o +obj-$(CONFIG_SND_SOC_IMX_SPDIF) += snd-soc-imx-spdif.o obj-$(CONFIG_SND_SOC_IMX_MC13783) += snd-soc-imx-mc13783.o diff --git a/sound/soc/fsl/imx-spdif.c b/sound/soc/fsl/imx-spdif.c new file mode 100644 index 000000000000..816013b0ebba --- /dev/null +++ b/sound/soc/fsl/imx-spdif.c @@ -0,0 +1,148 @@ +/* + * Copyright (C) 2013 Freescale Semiconductor, Inc. + * + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +#include +#include +#include + +struct imx_spdif_data { + struct snd_soc_dai_link dai[2]; + struct snd_soc_card card; + struct platform_device *txdev; + struct platform_device *rxdev; +}; + +static int imx_spdif_audio_probe(struct platform_device *pdev) +{ + struct device_node *spdif_np, *np = pdev->dev.of_node; + struct imx_spdif_data *data; + int ret = 0, num_links = 0; + + spdif_np = of_parse_phandle(np, "spdif-controller", 0); + if (!spdif_np) { + dev_err(&pdev->dev, "failed to find spdif-controller\n"); + ret = -EINVAL; + goto end; + } + + data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); + if (!data) { + dev_err(&pdev->dev, "failed to allocate memory\n"); + ret = -ENOMEM; + goto end; + } + + if (of_property_read_bool(np, "spdif-out")) { + data->dai[num_links].name = "S/PDIF TX"; + data->dai[num_links].stream_name = "S/PDIF PCM Playback"; + data->dai[num_links].codec_dai_name = "dit-hifi"; + data->dai[num_links].codec_name = "spdif-dit"; + data->dai[num_links].cpu_of_node = spdif_np; + data->dai[num_links].platform_of_node = spdif_np; + num_links++; + + data->txdev = platform_device_register_simple("spdif-dit", -1, NULL, 0); + if (IS_ERR(data->txdev)) { + ret = PTR_ERR(data->txdev); + dev_err(&pdev->dev, "register dit failed: %d\n", ret); + goto end; + } + } + + if (of_property_read_bool(np, "spdif-in")) { + data->dai[num_links].name = "S/PDIF RX"; + data->dai[num_links].stream_name = "S/PDIF PCM Capture"; + data->dai[num_links].codec_dai_name = "dir-hifi"; + data->dai[num_links].codec_name = "spdif-dir"; + data->dai[num_links].cpu_of_node = spdif_np; + data->dai[num_links].platform_of_node = spdif_np; + num_links++; + + data->rxdev = platform_device_register_simple("spdif-dir", -1, NULL, 0); + if (IS_ERR(data->rxdev)) { + ret = PTR_ERR(data->rxdev); + dev_err(&pdev->dev, "register dir failed: %d\n", ret); + goto error_dit; + } + } + + if (!num_links) { + dev_err(&pdev->dev, "no enabled S/PDIF DAI link\n"); + goto error_dir; + } + + data->card.dev = &pdev->dev; + data->card.num_links = num_links; + data->card.dai_link = data->dai; + + ret = snd_soc_of_parse_card_name(&data->card, "model"); + if (ret) + goto error_dir; + + ret = snd_soc_register_card(&data->card); + if (ret) { + dev_err(&pdev->dev, "snd_soc_register_card failed: %d\n", ret); + goto error_dir; + } + + platform_set_drvdata(pdev, data); + + goto end; + +error_dir: + if (data->rxdev) + platform_device_unregister(data->rxdev); +error_dit: + if (data->txdev) + platform_device_unregister(data->txdev); +end: + if (spdif_np) + of_node_put(spdif_np); + + return ret; +} + +static int imx_spdif_audio_remove(struct platform_device *pdev) +{ + struct imx_spdif_data *data = platform_get_drvdata(pdev); + + if (data->rxdev) + platform_device_unregister(data->rxdev); + if (data->txdev) + platform_device_unregister(data->txdev); + + snd_soc_unregister_card(&data->card); + + return 0; +} + +static const struct of_device_id imx_spdif_dt_ids[] = { + { .compatible = "fsl,imx-audio-spdif", }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, imx_spdif_dt_ids); + +static struct platform_driver imx_spdif_driver = { + .driver = { + .name = "imx-spdif", + .owner = THIS_MODULE, + .of_match_table = imx_spdif_dt_ids, + }, + .probe = imx_spdif_audio_probe, + .remove = imx_spdif_audio_remove, +}; + +module_platform_driver(imx_spdif_driver); + +MODULE_AUTHOR("Freescale Semiconductor, Inc."); +MODULE_DESCRIPTION("Freescale i.MX S/PDIF machine driver"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:imx-spdif"); -- cgit From bfd7d1aa3b603cf43e6545f873de714b991d6a8a Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Thu, 29 Aug 2013 08:00:05 +0800 Subject: ASoC: fsl_spdif: remove redundant dev_err call in fsl_spdif_probe() There is a error message within devm_ioremap_resource already, so remove the dev_err call to avoid redundant error message. Signed-off-by: Wei Yongjun Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_spdif.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'sound') diff --git a/sound/soc/fsl/fsl_spdif.c b/sound/soc/fsl/fsl_spdif.c index a9798aa1cd8d..e93dc0dfb0d9 100644 --- a/sound/soc/fsl/fsl_spdif.c +++ b/sound/soc/fsl/fsl_spdif.c @@ -1113,10 +1113,8 @@ static int fsl_spdif_probe(struct platform_device *pdev) } regs = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(regs)) { - dev_err(&pdev->dev, "could not map device resources\n"); + if (IS_ERR(regs)) return PTR_ERR(regs); - } spdif_priv->regmap = devm_regmap_init_mmio_clk(&pdev->dev, "core", regs, &fsl_spdif_regmap_config); -- cgit From e925a6b1b6e7ddb43a71b31c0afa12ca9a6ec118 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Mon, 26 Aug 2013 09:25:15 -0300 Subject: ASoC: designware_i2s: Remove unnecessary dev_set_drvdata() Driver core clears the driver data to NULL after device_release or on probe failure, so just remove it from here. Signed-off-by: Fabio Estevam Signed-off-by: Mark Brown --- sound/soc/dwc/designware_i2s.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'sound') diff --git a/sound/soc/dwc/designware_i2s.c b/sound/soc/dwc/designware_i2s.c index 70eb37a5dd16..25c31f1655f6 100644 --- a/sound/soc/dwc/designware_i2s.c +++ b/sound/soc/dwc/designware_i2s.c @@ -421,13 +421,11 @@ static int dw_i2s_probe(struct platform_device *pdev) dw_i2s_dai, 1); if (ret != 0) { dev_err(&pdev->dev, "not able to register dai\n"); - goto err_set_drvdata; + goto err_clk_disable; } return 0; -err_set_drvdata: - dev_set_drvdata(&pdev->dev, NULL); err_clk_disable: clk_disable(dev->clk); err_clk_put: @@ -440,7 +438,6 @@ static int dw_i2s_remove(struct platform_device *pdev) struct dw_i2s_dev *dev = dev_get_drvdata(&pdev->dev); snd_soc_unregister_component(&pdev->dev); - dev_set_drvdata(&pdev->dev, NULL); clk_put(dev->clk); -- cgit From ba1fb69508615011eba225de1ed2615fa205be9a Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Mon, 26 Aug 2013 09:25:14 -0300 Subject: ASoC: ep93xx-i2s: Remove unnecessary dev_set_drvdata() Driver core clears the driver data to NULL after device_release or on probe failure, so just remove it from here. Signed-off-by: Fabio Estevam Signed-off-by: Mark Brown --- sound/soc/cirrus/ep93xx-i2s.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'sound') diff --git a/sound/soc/cirrus/ep93xx-i2s.c b/sound/soc/cirrus/ep93xx-i2s.c index f23f331e9a97..a57643d6402f 100644 --- a/sound/soc/cirrus/ep93xx-i2s.c +++ b/sound/soc/cirrus/ep93xx-i2s.c @@ -408,7 +408,6 @@ static int ep93xx_i2s_probe(struct platform_device *pdev) return 0; fail_put_lrclk: - dev_set_drvdata(&pdev->dev, NULL); clk_put(info->lrclk); fail_put_sclk: clk_put(info->sclk); @@ -423,7 +422,6 @@ static int ep93xx_i2s_remove(struct platform_device *pdev) struct ep93xx_i2s_info *info = dev_get_drvdata(&pdev->dev); snd_soc_unregister_component(&pdev->dev); - dev_set_drvdata(&pdev->dev, NULL); clk_put(info->lrclk); clk_put(info->sclk); clk_put(info->mclk); -- cgit From 9b9ae16a97e08bdc4fd5e726a4d17119dbae5d8a Mon Sep 17 00:00:00 2001 From: Tomasz Figa Date: Sun, 11 Aug 2013 19:59:21 +0200 Subject: ASoC: Samsung: Do not queue cyclic buffers multiple times The legacy S3C-DMA API required every period of a cyclic buffer to be queued separately. After conversion of Samsung ASoC to Samsung DMA wrappers somebody made an assumption that the same is needed for DMA engine API, which is not true. In effect, Samsung ASoC DMA code was queuing the whole cyclic buffer multiple times with a shift of one period per iteration, leading to: a) severe memory waste - up to 13x times more DMA transfer descriptors are allocated than needed, b) possible memory corruption, because further cyclic buffers were out of the original buffers, due to the offset. This patch fixes this problem by making the legacy S3C-DMA API use the same semantics as DMA engine (the whole cyclic buffer is enqueued at once) and modifying users of Samsung DMA wrappers in cyclic mode to behave appropriately. Signed-off-by: Tomasz Figa Acked-by: Linus Walleij Signed-off-by: Mark Brown --- sound/soc/samsung/dma.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'sound') diff --git a/sound/soc/samsung/dma.c b/sound/soc/samsung/dma.c index a0c67f60f594..9338d11e9216 100644 --- a/sound/soc/samsung/dma.c +++ b/sound/soc/samsung/dma.c @@ -90,6 +90,13 @@ static void dma_enqueue(struct snd_pcm_substream *substream) dma_info.period = prtd->dma_period; dma_info.len = prtd->dma_period*limit; + if (dma_info.cap == DMA_CYCLIC) { + dma_info.buf = pos; + prtd->params->ops->prepare(prtd->params->ch, &dma_info); + prtd->dma_loaded += limit; + return; + } + while (prtd->dma_loaded < limit) { pr_debug("dma_loaded: %d\n", prtd->dma_loaded); -- cgit From 2f82cdbafd53a01e3a3995a618b650653eed9c1a Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Thu, 29 Aug 2013 17:31:41 -0300 Subject: ASoC: fsl: Drop SND_SOC_FSL_UTILS from SND_SOC_IMX_SPDIF SND_SOC_FSL_UTILS is only used by PowerPC machines, so let's drop it in the i.mx case. Signed-off-by: Fabio Estevam Acked-by: Nicolin Chen Signed-off-by: Mark Brown --- sound/soc/fsl/Kconfig | 1 - 1 file changed, 1 deletion(-) (limited to 'sound') diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig index a70838034600..704e246f5b1e 100644 --- a/sound/soc/fsl/Kconfig +++ b/sound/soc/fsl/Kconfig @@ -197,7 +197,6 @@ config SND_SOC_IMX_SPDIF tristate "SoC Audio support for i.MX boards with S/PDIF" select SND_SOC_IMX_PCM_DMA select SND_SOC_FSL_SPDIF - select SND_SOC_FSL_UTILS select SND_SOC_SPDIF help SoC Audio support for i.MX boards with S/PDIF -- cgit