aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-12-19 12:10:10 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2013-12-19 12:10:10 -0500
commit9b1be0f976a158590b924ac8789afe69b06dd302 (patch)
treef9c91388676f9905cf5f92b1a1b62ddd7b426340
parent86fbf1617a6522379815d34b90fef2aa9068f89d (diff)
parent356f402da0f989b16e4b6849e88dba5df0e25944 (diff)
Merge tag 'sound-3.13-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
Pull sound fixes from Takashi Iwai: "We have a bit more changes than usual in ASoC here, as it was slipped from the previous update. There are one minr ASoC PCM code fix and ASoC dmaengine fix, in addition of a collection of small ASoC driver fixes. The rest are a couple of HD-audio stable fixups, and a long-standing fix for the paused stream handling. So, all commits look not scary (and hopefully won't give you disastrous holiday season)" * tag 'sound-3.13-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: ALSA: hda - Add Dell headset detection quirk for one more laptop model ASoC: wm8904: fix DSP mode B configuration ASoC: wm_adsp: Add small delay while polling DSP RAM start ALSA: Add SNDRV_PCM_STATE_PAUSED case in wait_for_avail function ASoC: kirkwood: Fix the CPU DAI rates ASoC: wm5110: Correct HPOUT3 DAPM route typo ALSA: hda - Add Dell headset detection quirk for three laptop models ALSA: hda - Add enable_msi=0 workaround for four HP machines ASoC: don't leak on error in snd_dmaengine_pcm_register ASoC: fsl: imx-wm8962: Don't update bias_level in machine driver ASoC: tegra: fix uninitialized variables in set_fmt ASoC: wm8962: Enable SYSCLK provisonally before fetching generated DSPCLK_DIV ASoC: sam9x5_wm8731: change to work in DSP A mode ASoC: atmel_ssc_dai: add dai trigger ops ASoC: soc-pcm: Use valid condition for snd_soc_dai_digital_mute() in hw_free()
-rw-r--r--sound/core/pcm_lib.c2
-rw-r--r--sound/pci/hda/hda_intel.c4
-rw-r--r--sound/pci/hda/patch_realtek.c4
-rw-r--r--sound/soc/atmel/atmel_ssc_dai.c30
-rw-r--r--sound/soc/atmel/sam9x5_wm8731.c2
-rw-r--r--sound/soc/codecs/wm5110.c2
-rw-r--r--sound/soc/codecs/wm8904.c2
-rw-r--r--sound/soc/codecs/wm8962.c13
-rw-r--r--sound/soc/codecs/wm_adsp.c10
-rw-r--r--sound/soc/fsl/imx-wm8962.c2
-rw-r--r--sound/soc/kirkwood/kirkwood-i2s.c24
-rw-r--r--sound/soc/soc-generic-dmaengine-pcm.c38
-rw-r--r--sound/soc/soc-pcm.c5
-rw-r--r--sound/soc/tegra/tegra20_i2s.c6
-rw-r--r--sound/soc/tegra/tegra20_spdif.c10
-rw-r--r--sound/soc/tegra/tegra30_i2s.c6
16 files changed, 115 insertions, 45 deletions
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
index 6e03b465e44e..a2104671f51d 100644
--- a/sound/core/pcm_lib.c
+++ b/sound/core/pcm_lib.c
@@ -1937,6 +1937,8 @@ static int wait_for_avail(struct snd_pcm_substream *substream,
1937 case SNDRV_PCM_STATE_DISCONNECTED: 1937 case SNDRV_PCM_STATE_DISCONNECTED:
1938 err = -EBADFD; 1938 err = -EBADFD;
1939 goto _endloop; 1939 goto _endloop;
1940 case SNDRV_PCM_STATE_PAUSED:
1941 continue;
1940 } 1942 }
1941 if (!tout) { 1943 if (!tout) {
1942 snd_printd("%s write error (DMA or IRQ trouble?)\n", 1944 snd_printd("%s write error (DMA or IRQ trouble?)\n",
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 27aa14007cbd..956871d8b3d2 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -3433,6 +3433,10 @@ static void check_probe_mask(struct azx *chip, int dev)
3433 * white/black-list for enable_msi 3433 * white/black-list for enable_msi
3434 */ 3434 */
3435static struct snd_pci_quirk msi_black_list[] = { 3435static struct snd_pci_quirk msi_black_list[] = {
3436 SND_PCI_QUIRK(0x103c, 0x2191, "HP", 0), /* AMD Hudson */
3437 SND_PCI_QUIRK(0x103c, 0x2192, "HP", 0), /* AMD Hudson */
3438 SND_PCI_QUIRK(0x103c, 0x21f7, "HP", 0), /* AMD Hudson */
3439 SND_PCI_QUIRK(0x103c, 0x21fa, "HP", 0), /* AMD Hudson */
3436 SND_PCI_QUIRK(0x1043, 0x81f2, "ASUS", 0), /* Athlon64 X2 + nvidia */ 3440 SND_PCI_QUIRK(0x1043, 0x81f2, "ASUS", 0), /* Athlon64 X2 + nvidia */
3437 SND_PCI_QUIRK(0x1043, 0x81f6, "ASUS", 0), /* nvidia */ 3441 SND_PCI_QUIRK(0x1043, 0x81f6, "ASUS", 0), /* nvidia */
3438 SND_PCI_QUIRK(0x1043, 0x822d, "ASUS", 0), /* Athlon64 X2 + nvidia MCP55 */ 3442 SND_PCI_QUIRK(0x1043, 0x822d, "ASUS", 0), /* Athlon64 X2 + nvidia MCP55 */
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 34de5dc2fe9b..c5646941539a 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -4247,12 +4247,16 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
4247 SND_PCI_QUIRK(0x1028, 0x0606, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), 4247 SND_PCI_QUIRK(0x1028, 0x0606, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
4248 SND_PCI_QUIRK(0x1028, 0x0608, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), 4248 SND_PCI_QUIRK(0x1028, 0x0608, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
4249 SND_PCI_QUIRK(0x1028, 0x0609, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), 4249 SND_PCI_QUIRK(0x1028, 0x0609, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
4250 SND_PCI_QUIRK(0x1028, 0x0610, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
4250 SND_PCI_QUIRK(0x1028, 0x0613, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), 4251 SND_PCI_QUIRK(0x1028, 0x0613, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
4251 SND_PCI_QUIRK(0x1028, 0x0614, "Dell Inspiron 3135", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), 4252 SND_PCI_QUIRK(0x1028, 0x0614, "Dell Inspiron 3135", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
4252 SND_PCI_QUIRK(0x1028, 0x0616, "Dell Vostro 5470", ALC290_FIXUP_MONO_SPEAKERS), 4253 SND_PCI_QUIRK(0x1028, 0x0616, "Dell Vostro 5470", ALC290_FIXUP_MONO_SPEAKERS),
4253 SND_PCI_QUIRK(0x1028, 0x061f, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), 4254 SND_PCI_QUIRK(0x1028, 0x061f, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
4255 SND_PCI_QUIRK(0x1028, 0x0629, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
4254 SND_PCI_QUIRK(0x1028, 0x0638, "Dell Inspiron 5439", ALC290_FIXUP_MONO_SPEAKERS), 4256 SND_PCI_QUIRK(0x1028, 0x0638, "Dell Inspiron 5439", ALC290_FIXUP_MONO_SPEAKERS),
4257 SND_PCI_QUIRK(0x1028, 0x063e, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
4255 SND_PCI_QUIRK(0x1028, 0x063f, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), 4258 SND_PCI_QUIRK(0x1028, 0x063f, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
4259 SND_PCI_QUIRK(0x1028, 0x0640, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
4256 SND_PCI_QUIRK(0x1028, 0x15cc, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), 4260 SND_PCI_QUIRK(0x1028, 0x15cc, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE),
4257 SND_PCI_QUIRK(0x1028, 0x15cd, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), 4261 SND_PCI_QUIRK(0x1028, 0x15cd, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE),
4258 SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2), 4262 SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2),
diff --git a/sound/soc/atmel/atmel_ssc_dai.c b/sound/soc/atmel/atmel_ssc_dai.c
index 8697cedccd21..1ead3c977a51 100644
--- a/sound/soc/atmel/atmel_ssc_dai.c
+++ b/sound/soc/atmel/atmel_ssc_dai.c
@@ -648,7 +648,7 @@ static int atmel_ssc_prepare(struct snd_pcm_substream *substream,
648 648
649 dma_params = ssc_p->dma_params[dir]; 649 dma_params = ssc_p->dma_params[dir];
650 650
651 ssc_writel(ssc_p->ssc->regs, CR, dma_params->mask->ssc_enable); 651 ssc_writel(ssc_p->ssc->regs, CR, dma_params->mask->ssc_disable);
652 ssc_writel(ssc_p->ssc->regs, IDR, dma_params->mask->ssc_error); 652 ssc_writel(ssc_p->ssc->regs, IDR, dma_params->mask->ssc_error);
653 653
654 pr_debug("%s enabled SSC_SR=0x%08x\n", 654 pr_debug("%s enabled SSC_SR=0x%08x\n",
@@ -657,6 +657,33 @@ static int atmel_ssc_prepare(struct snd_pcm_substream *substream,
657 return 0; 657 return 0;
658} 658}
659 659
660static int atmel_ssc_trigger(struct snd_pcm_substream *substream,
661 int cmd, struct snd_soc_dai *dai)
662{
663 struct atmel_ssc_info *ssc_p = &ssc_info[dai->id];
664 struct atmel_pcm_dma_params *dma_params;
665 int dir;
666
667 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
668 dir = 0;
669 else
670 dir = 1;
671
672 dma_params = ssc_p->dma_params[dir];
673
674 switch (cmd) {
675 case SNDRV_PCM_TRIGGER_START:
676 case SNDRV_PCM_TRIGGER_RESUME:
677 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
678 ssc_writel(ssc_p->ssc->regs, CR, dma_params->mask->ssc_enable);
679 break;
680 default:
681 ssc_writel(ssc_p->ssc->regs, CR, dma_params->mask->ssc_disable);
682 break;
683 }
684
685 return 0;
686}
660 687
661#ifdef CONFIG_PM 688#ifdef CONFIG_PM
662static int atmel_ssc_suspend(struct snd_soc_dai *cpu_dai) 689static int atmel_ssc_suspend(struct snd_soc_dai *cpu_dai)
@@ -731,6 +758,7 @@ static const struct snd_soc_dai_ops atmel_ssc_dai_ops = {
731 .startup = atmel_ssc_startup, 758 .startup = atmel_ssc_startup,
732 .shutdown = atmel_ssc_shutdown, 759 .shutdown = atmel_ssc_shutdown,
733 .prepare = atmel_ssc_prepare, 760 .prepare = atmel_ssc_prepare,
761 .trigger = atmel_ssc_trigger,
734 .hw_params = atmel_ssc_hw_params, 762 .hw_params = atmel_ssc_hw_params,
735 .set_fmt = atmel_ssc_set_dai_fmt, 763 .set_fmt = atmel_ssc_set_dai_fmt,
736 .set_clkdiv = atmel_ssc_set_dai_clkdiv, 764 .set_clkdiv = atmel_ssc_set_dai_clkdiv,
diff --git a/sound/soc/atmel/sam9x5_wm8731.c b/sound/soc/atmel/sam9x5_wm8731.c
index 1b372283bd01..7d6a9055874b 100644
--- a/sound/soc/atmel/sam9x5_wm8731.c
+++ b/sound/soc/atmel/sam9x5_wm8731.c
@@ -109,7 +109,7 @@ static int sam9x5_wm8731_driver_probe(struct platform_device *pdev)
109 dai->stream_name = "WM8731 PCM"; 109 dai->stream_name = "WM8731 PCM";
110 dai->codec_dai_name = "wm8731-hifi"; 110 dai->codec_dai_name = "wm8731-hifi";
111 dai->init = sam9x5_wm8731_init; 111 dai->init = sam9x5_wm8731_init;
112 dai->dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF 112 dai->dai_fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_NB_NF
113 | SND_SOC_DAIFMT_CBM_CFM; 113 | SND_SOC_DAIFMT_CBM_CFM;
114 114
115 ret = snd_soc_of_parse_card_name(card, "atmel,model"); 115 ret = snd_soc_of_parse_card_name(card, "atmel,model");
diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c
index 99b359e19d35..0ab2dc296474 100644
--- a/sound/soc/codecs/wm5110.c
+++ b/sound/soc/codecs/wm5110.c
@@ -1012,7 +1012,7 @@ static const struct snd_soc_dapm_route wm5110_dapm_routes[] = {
1012 { "AEC Loopback", "HPOUT3L", "OUT3L" }, 1012 { "AEC Loopback", "HPOUT3L", "OUT3L" },
1013 { "AEC Loopback", "HPOUT3R", "OUT3R" }, 1013 { "AEC Loopback", "HPOUT3R", "OUT3R" },
1014 { "HPOUT3L", NULL, "OUT3L" }, 1014 { "HPOUT3L", NULL, "OUT3L" },
1015 { "HPOUT3R", NULL, "OUT3L" }, 1015 { "HPOUT3R", NULL, "OUT3R" },
1016 1016
1017 { "AEC Loopback", "SPKOUTL", "OUT4L" }, 1017 { "AEC Loopback", "SPKOUTL", "OUT4L" },
1018 { "SPKOUTLN", NULL, "OUT4L" }, 1018 { "SPKOUTLN", NULL, "OUT4L" },
diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c
index 3938fb1c203e..53bbfac6a83a 100644
--- a/sound/soc/codecs/wm8904.c
+++ b/sound/soc/codecs/wm8904.c
@@ -1444,7 +1444,7 @@ static int wm8904_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
1444 1444
1445 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 1445 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1446 case SND_SOC_DAIFMT_DSP_B: 1446 case SND_SOC_DAIFMT_DSP_B:
1447 aif1 |= WM8904_AIF_LRCLK_INV; 1447 aif1 |= 0x3 | WM8904_AIF_LRCLK_INV;
1448 case SND_SOC_DAIFMT_DSP_A: 1448 case SND_SOC_DAIFMT_DSP_A:
1449 aif1 |= 0x3; 1449 aif1 |= 0x3;
1450 break; 1450 break;
diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c
index 543c5c2631b6..0f17ed3e29f4 100644
--- a/sound/soc/codecs/wm8962.c
+++ b/sound/soc/codecs/wm8962.c
@@ -2439,7 +2439,20 @@ static void wm8962_configure_bclk(struct snd_soc_codec *codec)
2439 snd_soc_update_bits(codec, WM8962_CLOCKING_4, 2439 snd_soc_update_bits(codec, WM8962_CLOCKING_4,
2440 WM8962_SYSCLK_RATE_MASK, clocking4); 2440 WM8962_SYSCLK_RATE_MASK, clocking4);
2441 2441
2442 /* DSPCLK_DIV can be only generated correctly after enabling SYSCLK.
2443 * So we here provisionally enable it and then disable it afterward
2444 * if current bias_level hasn't reached SND_SOC_BIAS_ON.
2445 */
2446 if (codec->dapm.bias_level != SND_SOC_BIAS_ON)
2447 snd_soc_update_bits(codec, WM8962_CLOCKING2,
2448 WM8962_SYSCLK_ENA_MASK, WM8962_SYSCLK_ENA);
2449
2442 dspclk = snd_soc_read(codec, WM8962_CLOCKING1); 2450 dspclk = snd_soc_read(codec, WM8962_CLOCKING1);
2451
2452 if (codec->dapm.bias_level != SND_SOC_BIAS_ON)
2453 snd_soc_update_bits(codec, WM8962_CLOCKING2,
2454 WM8962_SYSCLK_ENA_MASK, 0);
2455
2443 if (dspclk < 0) { 2456 if (dspclk < 0) {
2444 dev_err(codec->dev, "Failed to read DSPCLK: %d\n", dspclk); 2457 dev_err(codec->dev, "Failed to read DSPCLK: %d\n", dspclk);
2445 return; 2458 return;
diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c
index 46ec0e9744d4..4fbcab63e61f 100644
--- a/sound/soc/codecs/wm_adsp.c
+++ b/sound/soc/codecs/wm_adsp.c
@@ -1474,13 +1474,17 @@ static int wm_adsp2_ena(struct wm_adsp *dsp)
1474 return ret; 1474 return ret;
1475 1475
1476 /* Wait for the RAM to start, should be near instantaneous */ 1476 /* Wait for the RAM to start, should be near instantaneous */
1477 count = 0; 1477 for (count = 0; count < 10; ++count) {
1478 do {
1479 ret = regmap_read(dsp->regmap, dsp->base + ADSP2_STATUS1, 1478 ret = regmap_read(dsp->regmap, dsp->base + ADSP2_STATUS1,
1480 &val); 1479 &val);
1481 if (ret != 0) 1480 if (ret != 0)
1482 return ret; 1481 return ret;
1483 } while (!(val & ADSP2_RAM_RDY) && ++count < 10); 1482
1483 if (val & ADSP2_RAM_RDY)
1484 break;
1485
1486 msleep(1);
1487 }
1484 1488
1485 if (!(val & ADSP2_RAM_RDY)) { 1489 if (!(val & ADSP2_RAM_RDY)) {
1486 adsp_err(dsp, "Failed to start DSP RAM\n"); 1490 adsp_err(dsp, "Failed to start DSP RAM\n");
diff --git a/sound/soc/fsl/imx-wm8962.c b/sound/soc/fsl/imx-wm8962.c
index 61e48852b9e8..3fd76bc391de 100644
--- a/sound/soc/fsl/imx-wm8962.c
+++ b/sound/soc/fsl/imx-wm8962.c
@@ -130,8 +130,6 @@ static int imx_wm8962_set_bias_level(struct snd_soc_card *card,
130 break; 130 break;
131 } 131 }
132 132
133 dapm->bias_level = level;
134
135 return 0; 133 return 0;
136} 134}
137 135
diff --git a/sound/soc/kirkwood/kirkwood-i2s.c b/sound/soc/kirkwood/kirkwood-i2s.c
index 0b18f654b413..3920a5e8125f 100644
--- a/sound/soc/kirkwood/kirkwood-i2s.c
+++ b/sound/soc/kirkwood/kirkwood-i2s.c
@@ -473,17 +473,17 @@ static struct snd_soc_dai_driver kirkwood_i2s_dai_extclk[2] = {
473 .playback = { 473 .playback = {
474 .channels_min = 1, 474 .channels_min = 1,
475 .channels_max = 2, 475 .channels_max = 2,
476 .rates = SNDRV_PCM_RATE_8000_192000 | 476 .rates = SNDRV_PCM_RATE_CONTINUOUS,
477 SNDRV_PCM_RATE_CONTINUOUS | 477 .rate_min = 5512,
478 SNDRV_PCM_RATE_KNOT, 478 .rate_max = 192000,
479 .formats = KIRKWOOD_I2S_FORMATS, 479 .formats = KIRKWOOD_I2S_FORMATS,
480 }, 480 },
481 .capture = { 481 .capture = {
482 .channels_min = 1, 482 .channels_min = 1,
483 .channels_max = 2, 483 .channels_max = 2,
484 .rates = SNDRV_PCM_RATE_8000_192000 | 484 .rates = SNDRV_PCM_RATE_CONTINUOUS,
485 SNDRV_PCM_RATE_CONTINUOUS | 485 .rate_min = 5512,
486 SNDRV_PCM_RATE_KNOT, 486 .rate_max = 192000,
487 .formats = KIRKWOOD_I2S_FORMATS, 487 .formats = KIRKWOOD_I2S_FORMATS,
488 }, 488 },
489 .ops = &kirkwood_i2s_dai_ops, 489 .ops = &kirkwood_i2s_dai_ops,
@@ -494,17 +494,17 @@ static struct snd_soc_dai_driver kirkwood_i2s_dai_extclk[2] = {
494 .playback = { 494 .playback = {
495 .channels_min = 1, 495 .channels_min = 1,
496 .channels_max = 2, 496 .channels_max = 2,
497 .rates = SNDRV_PCM_RATE_8000_192000 | 497 .rates = SNDRV_PCM_RATE_CONTINUOUS,
498 SNDRV_PCM_RATE_CONTINUOUS | 498 .rate_min = 5512,
499 SNDRV_PCM_RATE_KNOT, 499 .rate_max = 192000,
500 .formats = KIRKWOOD_SPDIF_FORMATS, 500 .formats = KIRKWOOD_SPDIF_FORMATS,
501 }, 501 },
502 .capture = { 502 .capture = {
503 .channels_min = 1, 503 .channels_min = 1,
504 .channels_max = 2, 504 .channels_max = 2,
505 .rates = SNDRV_PCM_RATE_8000_192000 | 505 .rates = SNDRV_PCM_RATE_CONTINUOUS,
506 SNDRV_PCM_RATE_CONTINUOUS | 506 .rate_min = 5512,
507 SNDRV_PCM_RATE_KNOT, 507 .rate_max = 192000,
508 .formats = KIRKWOOD_SPDIF_FORMATS, 508 .formats = KIRKWOOD_SPDIF_FORMATS,
509 }, 509 },
510 .ops = &kirkwood_i2s_dai_ops, 510 .ops = &kirkwood_i2s_dai_ops,
diff --git a/sound/soc/soc-generic-dmaengine-pcm.c b/sound/soc/soc-generic-dmaengine-pcm.c
index cbc9c96ce1f4..41949af3baae 100644
--- a/sound/soc/soc-generic-dmaengine-pcm.c
+++ b/sound/soc/soc-generic-dmaengine-pcm.c
@@ -305,6 +305,20 @@ static void dmaengine_pcm_request_chan_of(struct dmaengine_pcm *pcm,
305 } 305 }
306} 306}
307 307
308static void dmaengine_pcm_release_chan(struct dmaengine_pcm *pcm)
309{
310 unsigned int i;
311
312 for (i = SNDRV_PCM_STREAM_PLAYBACK; i <= SNDRV_PCM_STREAM_CAPTURE;
313 i++) {
314 if (!pcm->chan[i])
315 continue;
316 dma_release_channel(pcm->chan[i]);
317 if (pcm->flags & SND_DMAENGINE_PCM_FLAG_HALF_DUPLEX)
318 break;
319 }
320}
321
308/** 322/**
309 * snd_dmaengine_pcm_register - Register a dmaengine based PCM device 323 * snd_dmaengine_pcm_register - Register a dmaengine based PCM device
310 * @dev: The parent device for the PCM device 324 * @dev: The parent device for the PCM device
@@ -315,6 +329,7 @@ int snd_dmaengine_pcm_register(struct device *dev,
315 const struct snd_dmaengine_pcm_config *config, unsigned int flags) 329 const struct snd_dmaengine_pcm_config *config, unsigned int flags)
316{ 330{
317 struct dmaengine_pcm *pcm; 331 struct dmaengine_pcm *pcm;
332 int ret;
318 333
319 pcm = kzalloc(sizeof(*pcm), GFP_KERNEL); 334 pcm = kzalloc(sizeof(*pcm), GFP_KERNEL);
320 if (!pcm) 335 if (!pcm)
@@ -326,11 +341,20 @@ int snd_dmaengine_pcm_register(struct device *dev,
326 dmaengine_pcm_request_chan_of(pcm, dev); 341 dmaengine_pcm_request_chan_of(pcm, dev);
327 342
328 if (flags & SND_DMAENGINE_PCM_FLAG_NO_RESIDUE) 343 if (flags & SND_DMAENGINE_PCM_FLAG_NO_RESIDUE)
329 return snd_soc_add_platform(dev, &pcm->platform, 344 ret = snd_soc_add_platform(dev, &pcm->platform,
330 &dmaengine_no_residue_pcm_platform); 345 &dmaengine_no_residue_pcm_platform);
331 else 346 else
332 return snd_soc_add_platform(dev, &pcm->platform, 347 ret = snd_soc_add_platform(dev, &pcm->platform,
333 &dmaengine_pcm_platform); 348 &dmaengine_pcm_platform);
349 if (ret)
350 goto err_free_dma;
351
352 return 0;
353
354err_free_dma:
355 dmaengine_pcm_release_chan(pcm);
356 kfree(pcm);
357 return ret;
334} 358}
335EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_register); 359EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_register);
336 360
@@ -345,7 +369,6 @@ void snd_dmaengine_pcm_unregister(struct device *dev)
345{ 369{
346 struct snd_soc_platform *platform; 370 struct snd_soc_platform *platform;
347 struct dmaengine_pcm *pcm; 371 struct dmaengine_pcm *pcm;
348 unsigned int i;
349 372
350 platform = snd_soc_lookup_platform(dev); 373 platform = snd_soc_lookup_platform(dev);
351 if (!platform) 374 if (!platform)
@@ -353,15 +376,8 @@ void snd_dmaengine_pcm_unregister(struct device *dev)
353 376
354 pcm = soc_platform_to_pcm(platform); 377 pcm = soc_platform_to_pcm(platform);
355 378
356 for (i = SNDRV_PCM_STREAM_PLAYBACK; i <= SNDRV_PCM_STREAM_CAPTURE; i++) {
357 if (pcm->chan[i]) {
358 dma_release_channel(pcm->chan[i]);
359 if (pcm->flags & SND_DMAENGINE_PCM_FLAG_HALF_DUPLEX)
360 break;
361 }
362 }
363
364 snd_soc_remove_platform(platform); 379 snd_soc_remove_platform(platform);
380 dmaengine_pcm_release_chan(pcm);
365 kfree(pcm); 381 kfree(pcm);
366} 382}
367EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_unregister); 383EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_unregister);
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
index 11a90cd027fa..891b9a9bcbf8 100644
--- a/sound/soc/soc-pcm.c
+++ b/sound/soc/soc-pcm.c
@@ -600,12 +600,13 @@ static int soc_pcm_hw_free(struct snd_pcm_substream *substream)
600 struct snd_soc_platform *platform = rtd->platform; 600 struct snd_soc_platform *platform = rtd->platform;
601 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 601 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
602 struct snd_soc_dai *codec_dai = rtd->codec_dai; 602 struct snd_soc_dai *codec_dai = rtd->codec_dai;
603 struct snd_soc_codec *codec = rtd->codec; 603 bool playback = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
604 604
605 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass); 605 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
606 606
607 /* apply codec digital mute */ 607 /* apply codec digital mute */
608 if (!codec->active) 608 if ((playback && codec_dai->playback_active == 1) ||
609 (!playback && codec_dai->capture_active == 1))
609 snd_soc_dai_digital_mute(codec_dai, 1, substream->stream); 610 snd_soc_dai_digital_mute(codec_dai, 1, substream->stream);
610 611
611 /* free any machine hw params */ 612 /* free any machine hw params */
diff --git a/sound/soc/tegra/tegra20_i2s.c b/sound/soc/tegra/tegra20_i2s.c
index 364bf6a907e1..8c819f811470 100644
--- a/sound/soc/tegra/tegra20_i2s.c
+++ b/sound/soc/tegra/tegra20_i2s.c
@@ -74,7 +74,7 @@ static int tegra20_i2s_set_fmt(struct snd_soc_dai *dai,
74 unsigned int fmt) 74 unsigned int fmt)
75{ 75{
76 struct tegra20_i2s *i2s = snd_soc_dai_get_drvdata(dai); 76 struct tegra20_i2s *i2s = snd_soc_dai_get_drvdata(dai);
77 unsigned int mask, val; 77 unsigned int mask = 0, val = 0;
78 78
79 switch (fmt & SND_SOC_DAIFMT_INV_MASK) { 79 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
80 case SND_SOC_DAIFMT_NB_NF: 80 case SND_SOC_DAIFMT_NB_NF:
@@ -83,10 +83,10 @@ static int tegra20_i2s_set_fmt(struct snd_soc_dai *dai,
83 return -EINVAL; 83 return -EINVAL;
84 } 84 }
85 85
86 mask = TEGRA20_I2S_CTRL_MASTER_ENABLE; 86 mask |= TEGRA20_I2S_CTRL_MASTER_ENABLE;
87 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 87 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
88 case SND_SOC_DAIFMT_CBS_CFS: 88 case SND_SOC_DAIFMT_CBS_CFS:
89 val = TEGRA20_I2S_CTRL_MASTER_ENABLE; 89 val |= TEGRA20_I2S_CTRL_MASTER_ENABLE;
90 break; 90 break;
91 case SND_SOC_DAIFMT_CBM_CFM: 91 case SND_SOC_DAIFMT_CBM_CFM:
92 break; 92 break;
diff --git a/sound/soc/tegra/tegra20_spdif.c b/sound/soc/tegra/tegra20_spdif.c
index 08bc6931c7c7..8c7c1028e579 100644
--- a/sound/soc/tegra/tegra20_spdif.c
+++ b/sound/soc/tegra/tegra20_spdif.c
@@ -67,15 +67,15 @@ static int tegra20_spdif_hw_params(struct snd_pcm_substream *substream,
67{ 67{
68 struct device *dev = dai->dev; 68 struct device *dev = dai->dev;
69 struct tegra20_spdif *spdif = snd_soc_dai_get_drvdata(dai); 69 struct tegra20_spdif *spdif = snd_soc_dai_get_drvdata(dai);
70 unsigned int mask, val; 70 unsigned int mask = 0, val = 0;
71 int ret, spdifclock; 71 int ret, spdifclock;
72 72
73 mask = TEGRA20_SPDIF_CTRL_PACK | 73 mask |= TEGRA20_SPDIF_CTRL_PACK |
74 TEGRA20_SPDIF_CTRL_BIT_MODE_MASK; 74 TEGRA20_SPDIF_CTRL_BIT_MODE_MASK;
75 switch (params_format(params)) { 75 switch (params_format(params)) {
76 case SNDRV_PCM_FORMAT_S16_LE: 76 case SNDRV_PCM_FORMAT_S16_LE:
77 val = TEGRA20_SPDIF_CTRL_PACK | 77 val |= TEGRA20_SPDIF_CTRL_PACK |
78 TEGRA20_SPDIF_CTRL_BIT_MODE_16BIT; 78 TEGRA20_SPDIF_CTRL_BIT_MODE_16BIT;
79 break; 79 break;
80 default: 80 default:
81 return -EINVAL; 81 return -EINVAL;
diff --git a/sound/soc/tegra/tegra30_i2s.c b/sound/soc/tegra/tegra30_i2s.c
index 231a785b3921..02247fee1cf7 100644
--- a/sound/soc/tegra/tegra30_i2s.c
+++ b/sound/soc/tegra/tegra30_i2s.c
@@ -118,7 +118,7 @@ static int tegra30_i2s_set_fmt(struct snd_soc_dai *dai,
118 unsigned int fmt) 118 unsigned int fmt)
119{ 119{
120 struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(dai); 120 struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(dai);
121 unsigned int mask, val; 121 unsigned int mask = 0, val = 0;
122 122
123 switch (fmt & SND_SOC_DAIFMT_INV_MASK) { 123 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
124 case SND_SOC_DAIFMT_NB_NF: 124 case SND_SOC_DAIFMT_NB_NF:
@@ -127,10 +127,10 @@ static int tegra30_i2s_set_fmt(struct snd_soc_dai *dai,
127 return -EINVAL; 127 return -EINVAL;
128 } 128 }
129 129
130 mask = TEGRA30_I2S_CTRL_MASTER_ENABLE; 130 mask |= TEGRA30_I2S_CTRL_MASTER_ENABLE;
131 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 131 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
132 case SND_SOC_DAIFMT_CBS_CFS: 132 case SND_SOC_DAIFMT_CBS_CFS:
133 val = TEGRA30_I2S_CTRL_MASTER_ENABLE; 133 val |= TEGRA30_I2S_CTRL_MASTER_ENABLE;
134 break; 134 break;
135 case SND_SOC_DAIFMT_CBM_CFM: 135 case SND_SOC_DAIFMT_CBM_CFM:
136 break; 136 break;