From adc60298c80efef4c2d7a7860b91b450931a7cf8 Mon Sep 17 00:00:00 2001 From: Aurelien BOUIN Date: Mon, 29 Dec 2014 16:13:51 -0800 Subject: ASoC: fsl_esai: Fix incorrect xDC field width of xCCR registers The xDC field should have 5 bit width according to Reference Manual. Thus this patch fixes it. Signed-off-by: Aurelien BOUIN Signed-off-by: Nicolin Chen Signed-off-by: Mark Brown Cc: stable@vger.kernel.org --- sound/soc/fsl/fsl_esai.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound') diff --git a/sound/soc/fsl/fsl_esai.h b/sound/soc/fsl/fsl_esai.h index 91a550f..5e793bb 100644 --- a/sound/soc/fsl/fsl_esai.h +++ b/sound/soc/fsl/fsl_esai.h @@ -302,7 +302,7 @@ #define ESAI_xCCR_xFP_MASK (((1 << ESAI_xCCR_xFP_WIDTH) - 1) << ESAI_xCCR_xFP_SHIFT) #define ESAI_xCCR_xFP(v) ((((v) - 1) << ESAI_xCCR_xFP_SHIFT) & ESAI_xCCR_xFP_MASK) #define ESAI_xCCR_xDC_SHIFT 9 -#define ESAI_xCCR_xDC_WIDTH 4 +#define ESAI_xCCR_xDC_WIDTH 5 #define ESAI_xCCR_xDC_MASK (((1 << ESAI_xCCR_xDC_WIDTH) - 1) << ESAI_xCCR_xDC_SHIFT) #define ESAI_xCCR_xDC(v) ((((v) - 1) << ESAI_xCCR_xDC_SHIFT) & ESAI_xCCR_xDC_MASK) #define ESAI_xCCR_xPSR_SHIFT 8 -- cgit v1.1 From 8e3e36e87c9e624a30d31c576b839eed3ac8abf4 Mon Sep 17 00:00:00 2001 From: Cheng-Yi Chiang Date: Mon, 5 Jan 2015 19:26:59 +0800 Subject: ASoC: ts3a227e: Check and report jack status at probe ts3a227e does not trigger interrupt to report jack status when system boots from warm reset because ts3a227e's power remains on during warm reset. Read jack status at probe to get current jack status. Note that if system boots from EC reset, then this issue will not happen. Signed-off-by: Cheng-Yi Chiang Signed-off-by: Mark Brown --- sound/soc/codecs/ts3a227e.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'sound') diff --git a/sound/soc/codecs/ts3a227e.c b/sound/soc/codecs/ts3a227e.c index 1d12057..9f2dced 100644 --- a/sound/soc/codecs/ts3a227e.c +++ b/sound/soc/codecs/ts3a227e.c @@ -254,6 +254,7 @@ static int ts3a227e_i2c_probe(struct i2c_client *i2c, struct ts3a227e *ts3a227e; struct device *dev = &i2c->dev; int ret; + unsigned int acc_reg; ts3a227e = devm_kzalloc(&i2c->dev, sizeof(*ts3a227e), GFP_KERNEL); if (ts3a227e == NULL) @@ -283,6 +284,11 @@ static int ts3a227e_i2c_probe(struct i2c_client *i2c, INTB_DISABLE | ADC_COMPLETE_INT_DISABLE, ADC_COMPLETE_INT_DISABLE); + /* Read jack status because chip might not trigger interrupt at boot. */ + regmap_read(ts3a227e->regmap, TS3A227E_REG_ACCESSORY_STATUS, &acc_reg); + ts3a227e_new_jack_state(ts3a227e, acc_reg); + ts3a227e_jack_report(ts3a227e); + return 0; } -- cgit v1.1 From d83901e82010cb3b25e69a9bbe991e9fbd940725 Mon Sep 17 00:00:00 2001 From: Jie Yang Date: Sun, 4 Jan 2015 09:15:04 +0800 Subject: ASoC: Intel: Don't change offset of block allocator during fixed allocate The offset of block allocator, ba->offset, should not be changed during fixed address allocating, for the caller may treat it as the offset of allocated memory and use it. In the case that we allocate more than 1 blocks, we should make sure this offset is correct. Here introduces a temp allocator for the later continuous allocating. Signed-off-by: Jie Yang Signed-off-by: Mark Brown --- sound/soc/intel/sst-firmware.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'sound') diff --git a/sound/soc/intel/sst-firmware.c b/sound/soc/intel/sst-firmware.c index ef2e8b5..b3f9489 100644 --- a/sound/soc/intel/sst-firmware.c +++ b/sound/soc/intel/sst-firmware.c @@ -706,6 +706,7 @@ static int block_alloc_fixed(struct sst_dsp *dsp, struct sst_block_allocator *ba struct list_head *block_list) { struct sst_mem_block *block, *tmp; + struct sst_block_allocator ba_tmp = *ba; u32 end = ba->offset + ba->size, block_end; int err; @@ -730,9 +731,9 @@ static int block_alloc_fixed(struct sst_dsp *dsp, struct sst_block_allocator *ba if (ba->offset >= block->offset && ba->offset < block_end) { /* align ba to block boundary */ - ba->size -= block_end - ba->offset; - ba->offset = block_end; - err = block_alloc_contiguous(dsp, ba, block_list); + ba_tmp.size -= block_end - ba->offset; + ba_tmp.offset = block_end; + err = block_alloc_contiguous(dsp, &ba_tmp, block_list); if (err < 0) return -ENOMEM; @@ -767,10 +768,10 @@ static int block_alloc_fixed(struct sst_dsp *dsp, struct sst_block_allocator *ba list_move(&block->list, &dsp->used_block_list); list_add(&block->module_list, block_list); /* align ba to block boundary */ - ba->size -= block_end - ba->offset; - ba->offset = block_end; + ba_tmp.size -= block_end - ba->offset; + ba_tmp.offset = block_end; - err = block_alloc_contiguous(dsp, ba, block_list); + err = block_alloc_contiguous(dsp, &ba_tmp, block_list); if (err < 0) return -ENOMEM; -- cgit v1.1 From ae6f636b8b2ea9d297a07fc7ef8ae54707d67b36 Mon Sep 17 00:00:00 2001 From: Andrew Jackson Date: Wed, 31 Dec 2014 16:20:37 +0000 Subject: ASoC: adi: Add missing return statement. The probe routine was disabling the clock even if the system was configured successfully. Add a return statement to leave clocks enabled. Signed-off-by: Andrew Jackson Acked-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/adi/axi-i2s.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'sound') diff --git a/sound/soc/adi/axi-i2s.c b/sound/soc/adi/axi-i2s.c index 7752860..4c23381 100644 --- a/sound/soc/adi/axi-i2s.c +++ b/sound/soc/adi/axi-i2s.c @@ -240,6 +240,8 @@ static int axi_i2s_probe(struct platform_device *pdev) if (ret) goto err_clk_disable; + return 0; + err_clk_disable: clk_disable_unprepare(i2s->clk); return ret; -- cgit v1.1 From 22ee76daddb87f88d2336d1b4737ef27c4f307ac Mon Sep 17 00:00:00 2001 From: Zidan Wang Date: Wed, 31 Dec 2014 11:39:14 +0800 Subject: ASoC: wm8960: Fix capture sample rate from 11250 to 11025 wm8960 codec can't support sample rate 11250, it must be 11025. Signed-off-by: Zidan Wang Acked-by: Charles Keepax Signed-off-by: Mark Brown Cc: stable@vger.kernel.org --- sound/soc/codecs/wm8960.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound') diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c index 031a1ae..a96eb49 100644 --- a/sound/soc/codecs/wm8960.c +++ b/sound/soc/codecs/wm8960.c @@ -556,7 +556,7 @@ static struct { { 22050, 2 }, { 24000, 2 }, { 16000, 3 }, - { 11250, 4 }, + { 11025, 4 }, { 12000, 4 }, { 8000, 5 }, }; -- cgit v1.1 From f81677b4d1acc0e7cd74a43bfd9900d9512b90ae Mon Sep 17 00:00:00 2001 From: Jie Yang Date: Wed, 7 Jan 2015 22:07:05 +0800 Subject: ASoC: Intel: Add NULL checks for the stream pointer We should not send IPC stream commands to FW when the stream is NULL, dereference the NULL pointer may also occur without precheck. Here add NULL pointer checks for these stream APIs. Signed-off-by: Jie Yang Signed-off-by: Mark Brown --- sound/soc/intel/sst-haswell-ipc.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) (limited to 'sound') diff --git a/sound/soc/intel/sst-haswell-ipc.c b/sound/soc/intel/sst-haswell-ipc.c index 3f8c482..5bf1404 100644 --- a/sound/soc/intel/sst-haswell-ipc.c +++ b/sound/soc/intel/sst-haswell-ipc.c @@ -1228,6 +1228,11 @@ int sst_hsw_stream_free(struct sst_hsw *hsw, struct sst_hsw_stream *stream) struct sst_dsp *sst = hsw->dsp; unsigned long flags; + if (!stream) { + dev_warn(hsw->dev, "warning: stream is NULL, no stream to free, ignore it.\n"); + return 0; + } + /* dont free DSP streams that are not commited */ if (!stream->commited) goto out; @@ -1415,6 +1420,16 @@ int sst_hsw_stream_commit(struct sst_hsw *hsw, struct sst_hsw_stream *stream) u32 header; int ret; + if (!stream) { + dev_warn(hsw->dev, "warning: stream is NULL, no stream to commit, ignore it.\n"); + return 0; + } + + if (stream->commited) { + dev_warn(hsw->dev, "warning: stream is already committed, ignore it.\n"); + return 0; + } + trace_ipc_request("stream alloc", stream->host_id); header = IPC_GLB_TYPE(IPC_GLB_ALLOCATE_STREAM); @@ -1519,6 +1534,11 @@ int sst_hsw_stream_pause(struct sst_hsw *hsw, struct sst_hsw_stream *stream, { int ret; + if (!stream) { + dev_warn(hsw->dev, "warning: stream is NULL, no stream to pause, ignore it.\n"); + return 0; + } + trace_ipc_request("stream pause", stream->reply.stream_hw_id); ret = sst_hsw_stream_operations(hsw, IPC_STR_PAUSE, @@ -1535,6 +1555,11 @@ int sst_hsw_stream_resume(struct sst_hsw *hsw, struct sst_hsw_stream *stream, { int ret; + if (!stream) { + dev_warn(hsw->dev, "warning: stream is NULL, no stream to resume, ignore it.\n"); + return 0; + } + trace_ipc_request("stream resume", stream->reply.stream_hw_id); ret = sst_hsw_stream_operations(hsw, IPC_STR_RESUME, @@ -1550,6 +1575,11 @@ int sst_hsw_stream_reset(struct sst_hsw *hsw, struct sst_hsw_stream *stream) { int ret, tries = 10; + if (!stream) { + dev_warn(hsw->dev, "warning: stream is NULL, no stream to reset, ignore it.\n"); + return 0; + } + /* dont reset streams that are not commited */ if (!stream->commited) return 0; -- cgit v1.1 From a12d159d06317420c1a6941f5657b2918a02bf74 Mon Sep 17 00:00:00 2001 From: Jianqun Xu Date: Thu, 8 Jan 2015 10:49:59 +0800 Subject: ASoC: rockchip: i2s: applys rate symmetry for CPU DAI This patch applys rate symmetry for rockchip i2s DAI. Signed-off-by: Jianqun Xu Signed-off-by: Mark Brown --- sound/soc/rockchip/rockchip_i2s.c | 1 + 1 file changed, 1 insertion(+) (limited to 'sound') diff --git a/sound/soc/rockchip/rockchip_i2s.c b/sound/soc/rockchip/rockchip_i2s.c index 26ec511..deced0e 100644 --- a/sound/soc/rockchip/rockchip_i2s.c +++ b/sound/soc/rockchip/rockchip_i2s.c @@ -335,6 +335,7 @@ static struct snd_soc_dai_driver rockchip_i2s_dai = { SNDRV_PCM_FMTBIT_S24_LE), }, .ops = &rockchip_i2s_dai_ops, + .symmetric_rates = 1, }; static const struct snd_soc_component_driver rockchip_i2s_component = { -- cgit v1.1 From 64aa5f5843ab12455f6984928058a267f385a82c Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Wed, 7 Jan 2015 19:45:40 -0200 Subject: ASoC: fsl_ssi: Fix irq error check Commit 2ffa531078037a0 ("ASoC: fsl_ssi: Fix module unbound") changed the way to retrieve the irq number from irq_of_parse_and_map() to platform_get_irq(), but missed to updated the irq error check accordingly. We should test for negative irq number and propagate it in the case of error. Signed-off-by: Fabio Estevam Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_ssi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sound') diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index a65f17d..059496e 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c @@ -1362,9 +1362,9 @@ static int fsl_ssi_probe(struct platform_device *pdev) } ssi_private->irq = platform_get_irq(pdev, 0); - if (!ssi_private->irq) { + if (ssi_private->irq < 0) { dev_err(&pdev->dev, "no irq for node %s\n", np->full_name); - return -ENXIO; + return ssi_private->irq; } /* Are the RX and the TX clocks locked? */ -- cgit v1.1 From bdfbf2550d85b0e645a0bb9b3abd3b0a5448eacf Mon Sep 17 00:00:00 2001 From: Oder Chiou Date: Thu, 8 Jan 2015 10:31:05 +0800 Subject: ASoC: rt5677: Modify the behavior that updates the PLL parameter. The patch modified the behavior that updates the PLL parameter. It set the update bit before the PLL power up. Signed-off-by: Oder Chiou Signed-off-by: Mark Brown --- sound/soc/codecs/rt5677.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) (limited to 'sound') diff --git a/sound/soc/codecs/rt5677.c b/sound/soc/codecs/rt5677.c index 81fe146..8018c99 100644 --- a/sound/soc/codecs/rt5677.c +++ b/sound/soc/codecs/rt5677.c @@ -2082,10 +2082,14 @@ static int rt5677_set_pll1_event(struct snd_soc_dapm_widget *w, struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec); switch (event) { - case SND_SOC_DAPM_POST_PMU: + case SND_SOC_DAPM_PRE_PMU: regmap_update_bits(rt5677->regmap, RT5677_PLL1_CTRL2, 0x2, 0x2); + break; + + case SND_SOC_DAPM_POST_PMU: regmap_update_bits(rt5677->regmap, RT5677_PLL1_CTRL2, 0x2, 0x0); break; + default: return 0; } @@ -2100,10 +2104,14 @@ static int rt5677_set_pll2_event(struct snd_soc_dapm_widget *w, struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec); switch (event) { - case SND_SOC_DAPM_POST_PMU: + case SND_SOC_DAPM_PRE_PMU: regmap_update_bits(rt5677->regmap, RT5677_PLL2_CTRL2, 0x2, 0x2); + break; + + case SND_SOC_DAPM_POST_PMU: regmap_update_bits(rt5677->regmap, RT5677_PLL2_CTRL2, 0x2, 0x0); break; + default: return 0; } @@ -2211,9 +2219,11 @@ static int rt5677_vref_event(struct snd_soc_dapm_widget *w, static const struct snd_soc_dapm_widget rt5677_dapm_widgets[] = { SND_SOC_DAPM_SUPPLY("PLL1", RT5677_PWR_ANLG2, RT5677_PWR_PLL1_BIT, - 0, rt5677_set_pll1_event, SND_SOC_DAPM_POST_PMU), + 0, rt5677_set_pll1_event, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMU), SND_SOC_DAPM_SUPPLY("PLL2", RT5677_PWR_ANLG2, RT5677_PWR_PLL2_BIT, - 0, rt5677_set_pll2_event, SND_SOC_DAPM_POST_PMU), + 0, rt5677_set_pll2_event, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMU), /* Input Side */ /* micbias */ -- cgit v1.1 From 3a8e5019846736046c0af9dbee3f921c0456141a Mon Sep 17 00:00:00 2001 From: Peter Rosin Date: Thu, 8 Jan 2015 22:56:30 +0100 Subject: ASoC: pcm512x: Fix DSP program selection The DSP programs are listed out of order. Signed-off-by: Peter Rosin Signed-off-by: Mark Brown Cc: stable@vger.kernel.org --- sound/soc/codecs/pcm512x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound') diff --git a/sound/soc/codecs/pcm512x.c b/sound/soc/codecs/pcm512x.c index e5f2fb8..30c673c 100644 --- a/sound/soc/codecs/pcm512x.c +++ b/sound/soc/codecs/pcm512x.c @@ -188,8 +188,8 @@ static const DECLARE_TLV_DB_SCALE(boost_tlv, 0, 80, 0); static const char * const pcm512x_dsp_program_texts[] = { "FIR interpolation with de-emphasis", "Low latency IIR with de-emphasis", - "Fixed process flow", "High attenuation with de-emphasis", + "Fixed process flow", "Ringing-less low latency FIR", }; -- cgit v1.1 From 0984f3410089a773e408a0a76f719df109436cf1 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Wed, 14 Jan 2015 11:56:22 -0200 Subject: ASoC: fsl: imx-wm8962: Set the card owner field The following crash happens when trying to unload the snd_soc_imx_wm8962 module while playback is active: [ 208.666868] Unable to handle kernel paging request at virtc [ 208.674110] pgd = 80004000 [ 208.676867] [7f06541c] *pgd=4c334811, *pte=00000000, *ppte=00000000 [ 208.683211] Internal error: Oops: 80000007 [#1] SMP ARM [ 208.688445] Modules linked in: snd_soc_wm8962 snd_soc_fsl_ssi snd_soc_imx_audmux imx_pcm_fiq evbug] ... In order to avoid such problem, fill the card owner field as suggested by Lars-Peter Clausen: "But looking at the source it seems that this is a core feature of ALSA and at least for the card module itself it will do the ref-counting when a stream is started/stopped. And we even support setting the owner of a card in ASoC. It's just that pretty much no ASoC card driver bothers to set the owner field in the snd_soc_card struct. So this particular problem can be fixed by updating the imx-wm8962 driver to set the owner field." By doing as suggested, we no longer see the crash when attempting to unload the snd_soc_imx_wm8962 module while playback is active: $ modprobe -r snd_soc_imx_wm8962 modprobe: can't unload module snd_soc_imx_wm8962: Resource temporarily unavailable Reported-by: Jiada Wang Suggested-by: Lars-Peter Clausen Signed-off-by: Fabio Estevam Signed-off-by: Mark Brown --- sound/soc/fsl/imx-wm8962.c | 1 + 1 file changed, 1 insertion(+) (limited to 'sound') diff --git a/sound/soc/fsl/imx-wm8962.c b/sound/soc/fsl/imx-wm8962.c index 4caacb0..cd146d4 100644 --- a/sound/soc/fsl/imx-wm8962.c +++ b/sound/soc/fsl/imx-wm8962.c @@ -257,6 +257,7 @@ static int imx_wm8962_probe(struct platform_device *pdev) if (ret) goto clk_fail; data->card.num_links = 1; + data->card.owner = THIS_MODULE; data->card.dai_link = &data->dai; data->card.dapm_widgets = imx_wm8962_dapm_widgets; data->card.num_dapm_widgets = ARRAY_SIZE(imx_wm8962_dapm_widgets); -- cgit v1.1 From 7ddfdb5c5a5b51bdd2cb749d8341d763b079d520 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 13 Jan 2015 21:03:37 +0100 Subject: ASoC: simple-card: Fix crash in asoc_simple_card_unref() If asoc_simple_card_probe() fails, asoc_simple_card_unref() may be called before dev_set_drvdata(), causing a NULL pointer dereference in asoc_simple_card_unref(): Unable to handle kernel NULL pointer dereference at virtual address 000000d4 ... PC is at asoc_simple_card_unref+0x14/0x48 LR is at asoc_simple_card_probe+0x3d4/0x40c This typically happens because asoc_simple_card_parse_of() returns -EPROBE_DEFER, but other failure modes are possible. devm_snd_soc_register_card()/snd_soc_register_card() may fail either before or after dev_set_drvdata(). Pass a snd_soc_card pointer instead of a platform_device pointer to asoc_simple_card_unref() to fix this. Note that if CONFIG_OF_DYNAMIC=n, of_node_put() is a dummy, and gcc may optimize away the loop over card->dai_link, never actually dereferencing card, and thus avoiding the crash... Signed-off-by: Geert Uytterhoeven Fixes: e512e001dafa54e5 ("ASoC: simple-card: Fix the reference count of device nodes") Signed-off-by: Mark Brown Cc: stable@vger.kernel.org --- sound/soc/generic/simple-card.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'sound') diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c index fb9240f..7fe3009 100644 --- a/sound/soc/generic/simple-card.c +++ b/sound/soc/generic/simple-card.c @@ -452,9 +452,8 @@ static int asoc_simple_card_parse_of(struct device_node *node, } /* Decrease the reference count of the device nodes */ -static int asoc_simple_card_unref(struct platform_device *pdev) +static int asoc_simple_card_unref(struct snd_soc_card *card) { - struct snd_soc_card *card = platform_get_drvdata(pdev); struct snd_soc_dai_link *dai_link; int num_links; @@ -556,7 +555,7 @@ static int asoc_simple_card_probe(struct platform_device *pdev) return ret; err: - asoc_simple_card_unref(pdev); + asoc_simple_card_unref(&priv->snd_card); return ret; } @@ -572,7 +571,7 @@ static int asoc_simple_card_remove(struct platform_device *pdev) snd_soc_jack_free_gpios(&simple_card_mic_jack, 1, &simple_card_mic_jack_gpio); - return asoc_simple_card_unref(pdev); + return asoc_simple_card_unref(card); } static const struct of_device_id asoc_simple_of_match[] = { -- cgit v1.1 From a30c188b0d2e32b18509a386ab9f2142de841dca Mon Sep 17 00:00:00 2001 From: Bo Shen Date: Tue, 13 Jan 2015 18:05:31 +0800 Subject: ASoC: wm8904: fix runtime warning Correct the path name for mux to get rid of the following warning: --->8--- wm8904 1-001a: Control not supported for path ADCL -> [Left] -> AIFOUTL wm8904 1-001a: ASoC: no dapm match for ADCL --> Left --> AIFOUTL wm8904 1-001a: ASoC: Failed to add route ADCL -> Left -> AIFOUTL wm8904 1-001a: Control not supported for path ADCR -> [Right] -> AIFOUTL wm8904 1-001a: ASoC: no dapm match for ADCR --> Right --> AIFOUTL wm8904 1-001a: ASoC: Failed to add route ADCR -> Right -> AIFOUTL wm8904 1-001a: Control not supported for path ADCL -> [Left] -> AIFOUTR wm8904 1-001a: ASoC: no dapm match for ADCL --> Left --> AIFOUTR wm8904 1-001a: ASoC: Failed to add route ADCL -> Left -> AIFOUTR wm8904 1-001a: Control not supported for path ADCR -> [Right] -> AIFOUTR wm8904 1-001a: ASoC: no dapm match for ADCR --> Right --> AIFOUTR wm8904 1-001a: ASoC: Failed to add route ADCR -> Right -> AIFOUTR wm8904 1-001a: Control not supported for path AIFINR -> [Right] -> DACL wm8904 1-001a: ASoC: no dapm match for AIFINR --> Right --> DACL wm8904 1-001a: ASoC: Failed to add route AIFINR -> Right -> DACL wm8904 1-001a: Control not supported for path AIFINL -> [Left] -> DACL wm8904 1-001a: ASoC: no dapm match for AIFINL --> Left --> DACL wm8904 1-001a: ASoC: Failed to add route AIFINL -> Left -> DACL wm8904 1-001a: Control not supported for path AIFINR -> [Right] -> DACR wm8904 1-001a: ASoC: no dapm match for AIFINR --> Right --> DACR wm8904 1-001a: ASoC: Failed to add route AIFINR -> Right -> DACR wm8904 1-001a: Control not supported for path AIFINL -> [Left] -> DACR wm8904 1-001a: ASoC: no dapm match for AIFINL --> Left --> DACR wm8904 1-001a: ASoC: Failed to add route AIFINL -> Left -> DACR ---8<--- Signed-off-by: Bo Shen Acked-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/codecs/wm8904.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) (limited to 'sound') diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c index 4d2d2b1..75b87c5 100644 --- a/sound/soc/codecs/wm8904.c +++ b/sound/soc/codecs/wm8904.c @@ -1076,10 +1076,13 @@ static const struct snd_soc_dapm_route adc_intercon[] = { { "Right Capture PGA", NULL, "Right Capture Mux" }, { "Right Capture PGA", NULL, "Right Capture Inverting Mux" }, - { "AIFOUTL", "Left", "ADCL" }, - { "AIFOUTL", "Right", "ADCR" }, - { "AIFOUTR", "Left", "ADCL" }, - { "AIFOUTR", "Right", "ADCR" }, + { "AIFOUTL Mux", "Left", "ADCL" }, + { "AIFOUTL Mux", "Right", "ADCR" }, + { "AIFOUTR Mux", "Left", "ADCL" }, + { "AIFOUTR Mux", "Right", "ADCR" }, + + { "AIFOUTL", NULL, "AIFOUTL Mux" }, + { "AIFOUTR", NULL, "AIFOUTR Mux" }, { "ADCL", NULL, "CLK_DSP" }, { "ADCL", NULL, "Left Capture PGA" }, @@ -1089,12 +1092,16 @@ static const struct snd_soc_dapm_route adc_intercon[] = { }; static const struct snd_soc_dapm_route dac_intercon[] = { - { "DACL", "Right", "AIFINR" }, - { "DACL", "Left", "AIFINL" }, + { "DACL Mux", "Left", "AIFINL" }, + { "DACL Mux", "Right", "AIFINR" }, + + { "DACR Mux", "Left", "AIFINL" }, + { "DACR Mux", "Right", "AIFINR" }, + + { "DACL", NULL, "DACL Mux" }, { "DACL", NULL, "CLK_DSP" }, - { "DACR", "Right", "AIFINR" }, - { "DACR", "Left", "AIFINL" }, + { "DACR", NULL, "DACR Mux" }, { "DACR", NULL, "CLK_DSP" }, { "Charge pump", NULL, "SYSCLK" }, -- cgit v1.1 From 45437fa58587dd31523cb2d78183088fb69cdeec Mon Sep 17 00:00:00 2001 From: Bard Liao Date: Thu, 15 Jan 2015 10:49:25 +0800 Subject: ASoC: rt286: set the same format for dac and adc There is only one I2S I/F, AD/DA path must operate to the same format. Signed-off-by: Bard Liao Signed-off-by: Mark Brown --- sound/soc/codecs/rt286.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'sound') diff --git a/sound/soc/codecs/rt286.c b/sound/soc/codecs/rt286.c index 2cd4fe4..1d1c7f8 100644 --- a/sound/soc/codecs/rt286.c +++ b/sound/soc/codecs/rt286.c @@ -861,10 +861,8 @@ static int rt286_hw_params(struct snd_pcm_substream *substream, RT286_I2S_CTRL1, 0x0018, d_len_code << 3); dev_dbg(codec->dev, "format val = 0x%x\n", val); - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - snd_soc_update_bits(codec, RT286_DAC_FORMAT, 0x407f, val); - else - snd_soc_update_bits(codec, RT286_ADC_FORMAT, 0x407f, val); + snd_soc_update_bits(codec, RT286_DAC_FORMAT, 0x407f, val); + snd_soc_update_bits(codec, RT286_ADC_FORMAT, 0x407f, val); return 0; } -- cgit v1.1 From d3268a40d4b19ff7bee23f52eabbc4e96bb685e8 Mon Sep 17 00:00:00 2001 From: Qais Yousef Date: Wed, 14 Jan 2015 08:47:29 +0000 Subject: ASoC: soc-compress.c: fix NULL dereference In soc_new_compress() when rtd->dai_link->dynamic is set, we create the pcm substreams with this call: ret = snd_pcm_new_internal(rtd->card->snd_card, new_name, num, 1, 0, &be_pcm); which passes 0 as capture_count leading to be_pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream being NULL, hence when trying to set rtd a few lines below we get an oops. Fix by using rtd->dai_link->dpcm_playback and rtd->dai_link->dpcm_capture as playback_count and capture_count to snd_pcm_new_internal(). Signed-off-by: Qais Yousef Signed-off-by: Mark Brown Cc: stable@vger.kernel.org --- sound/soc/soc-compress.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'sound') diff --git a/sound/soc/soc-compress.c b/sound/soc/soc-compress.c index 590a82f..025c38f 100644 --- a/sound/soc/soc-compress.c +++ b/sound/soc/soc-compress.c @@ -659,7 +659,8 @@ int soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num) rtd->dai_link->stream_name); ret = snd_pcm_new_internal(rtd->card->snd_card, new_name, num, - 1, 0, &be_pcm); + rtd->dai_link->dpcm_playback, + rtd->dai_link->dpcm_capture, &be_pcm); if (ret < 0) { dev_err(rtd->card->dev, "ASoC: can't create compressed for %s\n", rtd->dai_link->name); @@ -668,8 +669,10 @@ int soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num) rtd->pcm = be_pcm; rtd->fe_compr = 1; - be_pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream->private_data = rtd; - be_pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream->private_data = rtd; + if (rtd->dai_link->dpcm_playback) + be_pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream->private_data = rtd; + else if (rtd->dai_link->dpcm_capture) + be_pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream->private_data = rtd; memcpy(compr->ops, &soc_compr_dyn_ops, sizeof(soc_compr_dyn_ops)); } else memcpy(compr->ops, &soc_compr_ops, sizeof(soc_compr_ops)); -- cgit v1.1 From 20602e34cd33dd452bc1836fa7c9b59978f75db0 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Fri, 16 Jan 2015 11:20:25 +0200 Subject: ASoC: omap-mcbsp: Correct CBM_CFS dai format configuration We should select FSR also to be driven by McBSP, not only FSX. Signed-off-by: Peter Ujfalusi Acked-by: Jarkko Nikula Signed-off-by: Mark Brown Cc: stable@vger.kernel.org --- sound/soc/omap/omap-mcbsp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound') diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c index 8b79cafa..c7eb9dd 100644 --- a/sound/soc/omap/omap-mcbsp.c +++ b/sound/soc/omap/omap-mcbsp.c @@ -434,7 +434,7 @@ static int omap_mcbsp_dai_set_dai_fmt(struct snd_soc_dai *cpu_dai, case SND_SOC_DAIFMT_CBM_CFS: /* McBSP slave. FS clock as output */ regs->srgr2 |= FSGM; - regs->pcr0 |= FSXM; + regs->pcr0 |= FSXM | FSRM; break; case SND_SOC_DAIFMT_CBM_CFM: /* McBSP slave */ -- cgit v1.1 From 5c697e5b46efea2c0a5da55208bc71db46698fd1 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Tue, 25 Nov 2014 22:52:24 +0100 Subject: ALSA: firewire-lib: remove rx_blocks_for_midi quirk There are several devices that expect to receive MIDI data only in the first eight data blocks of a packet. If the driver restricts the data rate to the allowed rate (as mandated by the specification, but not yet implemented by this driver), this happens naturally. Therefore, there is no reason to ever try to use more data packets with any device. Signed-off-by: Clemens Ladisch Reviewed-by: Takashi Sakamoto Tested-by: Takashi Sakamoto Signed-off-by: Takashi Iwai --- sound/firewire/amdtp.c | 12 ++++++++---- sound/firewire/amdtp.h | 3 --- sound/firewire/bebob/bebob_stream.c | 7 ------- sound/firewire/fireworks/fireworks_stream.c | 5 ----- 4 files changed, 8 insertions(+), 19 deletions(-) (limited to 'sound') diff --git a/sound/firewire/amdtp.c b/sound/firewire/amdtp.c index 3badc70..ef399ca 100644 --- a/sound/firewire/amdtp.c +++ b/sound/firewire/amdtp.c @@ -21,7 +21,13 @@ #define CYCLES_PER_SECOND 8000 #define TICKS_PER_SECOND (TICKS_PER_CYCLE * CYCLES_PER_SECOND) -#define TRANSFER_DELAY_TICKS 0x2e00 /* 479.17 µs */ +/* + * Several devices look only at the first eight data blocks. + * In any case, this is more than enough for the MIDI data rate. + */ +#define MAX_MIDI_RX_BLOCKS 8 + +#define TRANSFER_DELAY_TICKS 0x2e00 /* 479.17 µs */ /* isochronous header parameters */ #define ISO_DATA_LENGTH_SHIFT 16 @@ -78,8 +84,6 @@ int amdtp_stream_init(struct amdtp_stream *s, struct fw_unit *unit, s->callbacked = false; s->sync_slave = NULL; - s->rx_blocks_for_midi = UINT_MAX; - return 0; } EXPORT_SYMBOL(amdtp_stream_init); @@ -474,7 +478,7 @@ static void amdtp_fill_midi(struct amdtp_stream *s, b = (u8 *)&buffer[s->midi_position]; port = (s->data_block_counter + f) % 8; - if ((f >= s->rx_blocks_for_midi) || + if ((f >= MAX_MIDI_RX_BLOCKS) || (s->midi[port] == NULL) || (snd_rawmidi_transmit(s->midi[port], b + 1, 1) <= 0)) b[0] = 0x80; diff --git a/sound/firewire/amdtp.h b/sound/firewire/amdtp.h index e6e8926..cd4c4df 100644 --- a/sound/firewire/amdtp.h +++ b/sound/firewire/amdtp.h @@ -152,9 +152,6 @@ struct amdtp_stream { /* quirk: fixed interval of dbc between previos/current packets. */ unsigned int tx_dbc_interval; - /* quirk: the first count of data blocks in an rx packet for MIDI */ - unsigned int rx_blocks_for_midi; - bool callbacked; wait_queue_head_t callback_wait; struct amdtp_stream *sync_slave; diff --git a/sound/firewire/bebob/bebob_stream.c b/sound/firewire/bebob/bebob_stream.c index 1aab0a32..0ebcabf 100644 --- a/sound/firewire/bebob/bebob_stream.c +++ b/sound/firewire/bebob/bebob_stream.c @@ -484,13 +484,6 @@ int snd_bebob_stream_init_duplex(struct snd_bebob *bebob) amdtp_stream_destroy(&bebob->rx_stream); destroy_both_connections(bebob); } - /* - * The firmware for these devices ignore MIDI messages in more than - * first 8 data blocks of an received AMDTP packet. - */ - if (bebob->spec == &maudio_fw410_spec || - bebob->spec == &maudio_special_spec) - bebob->rx_stream.rx_blocks_for_midi = 8; end: return err; } diff --git a/sound/firewire/fireworks/fireworks_stream.c b/sound/firewire/fireworks/fireworks_stream.c index b985fc5..4f440e1 100644 --- a/sound/firewire/fireworks/fireworks_stream.c +++ b/sound/firewire/fireworks/fireworks_stream.c @@ -179,11 +179,6 @@ int snd_efw_stream_init_duplex(struct snd_efw *efw) destroy_stream(efw, &efw->tx_stream); goto end; } - /* - * Fireworks ignores MIDI messages in more than first 8 data - * blocks of an received AMDTP packet. - */ - efw->rx_stream.rx_blocks_for_midi = 8; /* set IEC61883 compliant mode (actually not fully compliant...) */ err = snd_efw_command_set_tx_mode(efw, SND_EFW_TRANSPORT_MODE_IEC61883); -- cgit v1.1 From 25ca917c0fcdd1d2c4a701905e11751275186310 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Tue, 25 Nov 2014 22:54:10 +0100 Subject: ALSA: firewire-lib: limit the MIDI data rate Do no send MIDI bytes at the full rate at which FireWire packets happen to be sent, but restrict them to the actual rate of a real MIDI port. This is required by the specification, and prevents data loss when the device's buffer overruns. Signed-off-by: Clemens Ladisch Reviewed-by: Takashi Sakamoto Tested-by: Takashi Sakamoto Signed-off-by: Takashi Iwai --- sound/firewire/amdtp.c | 61 +++++++++++++++++++++++++++++++++++++++++++++----- sound/firewire/amdtp.h | 2 ++ 2 files changed, 57 insertions(+), 6 deletions(-) (limited to 'sound') diff --git a/sound/firewire/amdtp.c b/sound/firewire/amdtp.c index ef399ca..0d58018 100644 --- a/sound/firewire/amdtp.c +++ b/sound/firewire/amdtp.c @@ -22,6 +22,12 @@ #define TICKS_PER_SECOND (TICKS_PER_CYCLE * CYCLES_PER_SECOND) /* + * Nominally 3125 bytes/second, but the MIDI port's clock might be + * 1% too slow, and the bus clock 100 ppm too fast. + */ +#define MIDI_BYTES_PER_SECOND 3093 + +/* * Several devices look only at the first eight data blocks. * In any case, this is more than enough for the MIDI data rate. */ @@ -226,6 +232,14 @@ sfc_found: for (i = 0; i < pcm_channels; i++) s->pcm_positions[i] = i; s->midi_position = s->pcm_channels; + + /* + * We do not know the actual MIDI FIFO size of most devices. Just + * assume two bytes, i.e., one byte can be received over the bus while + * the previous one is transmitted over MIDI. + * (The value here is adjusted for midi_ratelimit_per_packet().) + */ + s->midi_fifo_limit = rate - MIDI_BYTES_PER_SECOND * s->syt_interval + 1; } EXPORT_SYMBOL(amdtp_stream_set_parameters); @@ -467,6 +481,36 @@ static void amdtp_fill_pcm_silence(struct amdtp_stream *s, } } +/* + * To avoid sending MIDI bytes at too high a rate, assume that the receiving + * device has a FIFO, and track how much it is filled. This values increases + * by one whenever we send one byte in a packet, but the FIFO empties at + * a constant rate independent of our packet rate. One packet has syt_interval + * samples, so the number of bytes that empty out of the FIFO, per packet(!), + * is MIDI_BYTES_PER_SECOND * syt_interval / sample_rate. To avoid storing + * fractional values, the values in midi_fifo_used[] are measured in bytes + * multiplied by the sample rate. + */ +static bool midi_ratelimit_per_packet(struct amdtp_stream *s, unsigned int port) +{ + int used; + + used = s->midi_fifo_used[port]; + if (used == 0) /* common shortcut */ + return true; + + used -= MIDI_BYTES_PER_SECOND * s->syt_interval; + used = max(used, 0); + s->midi_fifo_used[port] = used; + + return used < s->midi_fifo_limit; +} + +static void midi_rate_use_one_byte(struct amdtp_stream *s, unsigned int port) +{ + s->midi_fifo_used[port] += amdtp_rate_table[s->sfc]; +} + static void amdtp_fill_midi(struct amdtp_stream *s, __be32 *buffer, unsigned int frames) { @@ -474,16 +518,21 @@ static void amdtp_fill_midi(struct amdtp_stream *s, u8 *b; for (f = 0; f < frames; f++) { - buffer[s->midi_position] = 0; b = (u8 *)&buffer[s->midi_position]; port = (s->data_block_counter + f) % 8; - if ((f >= MAX_MIDI_RX_BLOCKS) || - (s->midi[port] == NULL) || - (snd_rawmidi_transmit(s->midi[port], b + 1, 1) <= 0)) - b[0] = 0x80; - else + if (f < MAX_MIDI_RX_BLOCKS && + midi_ratelimit_per_packet(s, port) && + s->midi[port] != NULL && + snd_rawmidi_transmit(s->midi[port], &b[1], 1) == 1) { + midi_rate_use_one_byte(s, port); b[0] = 0x81; + } else { + b[0] = 0x80; + b[1] = 0; + } + b[2] = 0; + b[3] = 0; buffer += s->data_block_quadlets; } diff --git a/sound/firewire/amdtp.h b/sound/firewire/amdtp.h index cd4c4df..8a03a91 100644 --- a/sound/firewire/amdtp.h +++ b/sound/firewire/amdtp.h @@ -148,6 +148,8 @@ struct amdtp_stream { bool double_pcm_frames; struct snd_rawmidi_substream *midi[AMDTP_MAX_CHANNELS_FOR_MIDI * 8]; + int midi_fifo_limit; + int midi_fifo_used[AMDTP_MAX_CHANNELS_FOR_MIDI * 8]; /* quirk: fixed interval of dbc between previos/current packets. */ unsigned int tx_dbc_interval; -- cgit v1.1 From 6455931186bff407493135e74c5f32efd30860e2 Mon Sep 17 00:00:00 2001 From: Jason Lee Cragg Date: Sat, 17 Jan 2015 12:28:29 -0500 Subject: ALSA: usb-audio: Add mic volume fix quirk for Logitech Webcam C210 Signed-off-by: Jason Lee Cragg Cc: Signed-off-by: Takashi Iwai --- sound/usb/mixer.c | 1 + 1 file changed, 1 insertion(+) (limited to 'sound') diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c index 41650d5..3e2ef61 100644 --- a/sound/usb/mixer.c +++ b/sound/usb/mixer.c @@ -913,6 +913,7 @@ static void volume_control_quirks(struct usb_mixer_elem_info *cval, case USB_ID(0x046d, 0x0807): /* Logitech Webcam C500 */ case USB_ID(0x046d, 0x0808): case USB_ID(0x046d, 0x0809): + case USB_ID(0x046d, 0x0819): /* Logitech Webcam C210 */ case USB_ID(0x046d, 0x081b): /* HD Webcam c310 */ case USB_ID(0x046d, 0x081d): /* HD Webcam c510 */ case USB_ID(0x046d, 0x0825): /* HD Webcam c270 */ -- cgit v1.1 From 0767e95bb96d7fdddcd590fb809e6975d93aebc5 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Sun, 25 Jan 2015 14:34:29 +0100 Subject: ALSA: seq-dummy: remove deadlock-causing events on close When the last subscriber to a "Through" port has been removed, the subscribed destination ports might still be active, so it would be wrong to send "all sounds off" and "reset controller" events to them. The proper place for such a shutdown would be the closing of the actual MIDI port (and close_substream() in rawmidi.c already can do this). This also fixes a deadlock when dummy_unuse() tries to send events to its own port that is already locked because it is being freed. Reported-by: Peter Billam Cc: Signed-off-by: Clemens Ladisch Signed-off-by: Takashi Iwai --- sound/core/seq/seq_dummy.c | 31 ------------------------------- 1 file changed, 31 deletions(-) (limited to 'sound') diff --git a/sound/core/seq/seq_dummy.c b/sound/core/seq/seq_dummy.c index ec667f1..5d905d9 100644 --- a/sound/core/seq/seq_dummy.c +++ b/sound/core/seq/seq_dummy.c @@ -82,36 +82,6 @@ struct snd_seq_dummy_port { static int my_client = -1; /* - * unuse callback - send ALL_SOUNDS_OFF and RESET_CONTROLLERS events - * to subscribers. - * Note: this callback is called only after all subscribers are removed. - */ -static int -dummy_unuse(void *private_data, struct snd_seq_port_subscribe *info) -{ - struct snd_seq_dummy_port *p; - int i; - struct snd_seq_event ev; - - p = private_data; - memset(&ev, 0, sizeof(ev)); - if (p->duplex) - ev.source.port = p->connect; - else - ev.source.port = p->port; - ev.dest.client = SNDRV_SEQ_ADDRESS_SUBSCRIBERS; - ev.type = SNDRV_SEQ_EVENT_CONTROLLER; - for (i = 0; i < 16; i++) { - ev.data.control.channel = i; - ev.data.control.param = MIDI_CTL_ALL_SOUNDS_OFF; - snd_seq_kernel_client_dispatch(p->client, &ev, 0, 0); - ev.data.control.param = MIDI_CTL_RESET_CONTROLLERS; - snd_seq_kernel_client_dispatch(p->client, &ev, 0, 0); - } - return 0; -} - -/* * event input callback - just redirect events to subscribers */ static int @@ -175,7 +145,6 @@ create_port(int idx, int type) | SNDRV_SEQ_PORT_TYPE_PORT; memset(&pcb, 0, sizeof(pcb)); pcb.owner = THIS_MODULE; - pcb.unuse = dummy_unuse; pcb.event_input = dummy_input; pcb.private_free = dummy_free; pcb.private_data = rec; -- cgit v1.1