Skip to content

Commit

Permalink
Merge tag 'sound-3.13-rc5' of git://git.kernel.org/pub/scm/linux/kern…
Browse files Browse the repository at this point in the history
…el/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()
  • Loading branch information
Linus Torvalds committed Dec 19, 2013
2 parents 86fbf16 + 356f402 commit 9b1be0f
Show file tree
Hide file tree
Showing 16 changed files with 115 additions and 45 deletions.
2 changes: 2 additions & 0 deletions sound/core/pcm_lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -1937,6 +1937,8 @@ static int wait_for_avail(struct snd_pcm_substream *substream,
case SNDRV_PCM_STATE_DISCONNECTED:
err = -EBADFD;
goto _endloop;
case SNDRV_PCM_STATE_PAUSED:
continue;
}
if (!tout) {
snd_printd("%s write error (DMA or IRQ trouble?)\n",
Expand Down
4 changes: 4 additions & 0 deletions sound/pci/hda/hda_intel.c
Original file line number Diff line number Diff line change
Expand Up @@ -3433,6 +3433,10 @@ static void check_probe_mask(struct azx *chip, int dev)
* white/black-list for enable_msi
*/
static struct snd_pci_quirk msi_black_list[] = {
SND_PCI_QUIRK(0x103c, 0x2191, "HP", 0), /* AMD Hudson */
SND_PCI_QUIRK(0x103c, 0x2192, "HP", 0), /* AMD Hudson */
SND_PCI_QUIRK(0x103c, 0x21f7, "HP", 0), /* AMD Hudson */
SND_PCI_QUIRK(0x103c, 0x21fa, "HP", 0), /* AMD Hudson */
SND_PCI_QUIRK(0x1043, 0x81f2, "ASUS", 0), /* Athlon64 X2 + nvidia */
SND_PCI_QUIRK(0x1043, 0x81f6, "ASUS", 0), /* nvidia */
SND_PCI_QUIRK(0x1043, 0x822d, "ASUS", 0), /* Athlon64 X2 + nvidia MCP55 */
Expand Down
4 changes: 4 additions & 0 deletions sound/pci/hda/patch_realtek.c
Original file line number Diff line number Diff line change
Expand Up @@ -4247,12 +4247,16 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x1028, 0x0606, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x1028, 0x0608, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x1028, 0x0609, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x1028, 0x0610, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x1028, 0x0613, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x1028, 0x0614, "Dell Inspiron 3135", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x1028, 0x0616, "Dell Vostro 5470", ALC290_FIXUP_MONO_SPEAKERS),
SND_PCI_QUIRK(0x1028, 0x061f, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x1028, 0x0629, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x1028, 0x0638, "Dell Inspiron 5439", ALC290_FIXUP_MONO_SPEAKERS),
SND_PCI_QUIRK(0x1028, 0x063e, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x1028, 0x063f, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x1028, 0x0640, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x1028, 0x15cc, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x1028, 0x15cd, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2),
Expand Down
30 changes: 29 additions & 1 deletion sound/soc/atmel/atmel_ssc_dai.c
Original file line number Diff line number Diff line change
Expand Up @@ -648,7 +648,7 @@ static int atmel_ssc_prepare(struct snd_pcm_substream *substream,

dma_params = ssc_p->dma_params[dir];

ssc_writel(ssc_p->ssc->regs, CR, dma_params->mask->ssc_enable);
ssc_writel(ssc_p->ssc->regs, CR, dma_params->mask->ssc_disable);
ssc_writel(ssc_p->ssc->regs, IDR, dma_params->mask->ssc_error);

pr_debug("%s enabled SSC_SR=0x%08x\n",
Expand All @@ -657,6 +657,33 @@ static int atmel_ssc_prepare(struct snd_pcm_substream *substream,
return 0;
}

static int atmel_ssc_trigger(struct snd_pcm_substream *substream,
int cmd, struct snd_soc_dai *dai)
{
struct atmel_ssc_info *ssc_p = &ssc_info[dai->id];
struct atmel_pcm_dma_params *dma_params;
int dir;

if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
dir = 0;
else
dir = 1;

dma_params = ssc_p->dma_params[dir];

switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_RESUME:
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
ssc_writel(ssc_p->ssc->regs, CR, dma_params->mask->ssc_enable);
break;
default:
ssc_writel(ssc_p->ssc->regs, CR, dma_params->mask->ssc_disable);
break;
}

return 0;
}

#ifdef CONFIG_PM
static int atmel_ssc_suspend(struct snd_soc_dai *cpu_dai)
Expand Down Expand Up @@ -731,6 +758,7 @@ static const struct snd_soc_dai_ops atmel_ssc_dai_ops = {
.startup = atmel_ssc_startup,
.shutdown = atmel_ssc_shutdown,
.prepare = atmel_ssc_prepare,
.trigger = atmel_ssc_trigger,
.hw_params = atmel_ssc_hw_params,
.set_fmt = atmel_ssc_set_dai_fmt,
.set_clkdiv = atmel_ssc_set_dai_clkdiv,
Expand Down
2 changes: 1 addition & 1 deletion sound/soc/atmel/sam9x5_wm8731.c
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ static int sam9x5_wm8731_driver_probe(struct platform_device *pdev)
dai->stream_name = "WM8731 PCM";
dai->codec_dai_name = "wm8731-hifi";
dai->init = sam9x5_wm8731_init;
dai->dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
dai->dai_fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_NB_NF
| SND_SOC_DAIFMT_CBM_CFM;

ret = snd_soc_of_parse_card_name(card, "atmel,model");
Expand Down
2 changes: 1 addition & 1 deletion sound/soc/codecs/wm5110.c
Original file line number Diff line number Diff line change
Expand Up @@ -1012,7 +1012,7 @@ static const struct snd_soc_dapm_route wm5110_dapm_routes[] = {
{ "AEC Loopback", "HPOUT3L", "OUT3L" },
{ "AEC Loopback", "HPOUT3R", "OUT3R" },
{ "HPOUT3L", NULL, "OUT3L" },
{ "HPOUT3R", NULL, "OUT3L" },
{ "HPOUT3R", NULL, "OUT3R" },

{ "AEC Loopback", "SPKOUTL", "OUT4L" },
{ "SPKOUTLN", NULL, "OUT4L" },
Expand Down
2 changes: 1 addition & 1 deletion sound/soc/codecs/wm8904.c
Original file line number Diff line number Diff line change
Expand Up @@ -1444,7 +1444,7 @@ static int wm8904_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)

switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
case SND_SOC_DAIFMT_DSP_B:
aif1 |= WM8904_AIF_LRCLK_INV;
aif1 |= 0x3 | WM8904_AIF_LRCLK_INV;
case SND_SOC_DAIFMT_DSP_A:
aif1 |= 0x3;
break;
Expand Down
13 changes: 13 additions & 0 deletions sound/soc/codecs/wm8962.c
Original file line number Diff line number Diff line change
Expand Up @@ -2439,7 +2439,20 @@ static void wm8962_configure_bclk(struct snd_soc_codec *codec)
snd_soc_update_bits(codec, WM8962_CLOCKING_4,
WM8962_SYSCLK_RATE_MASK, clocking4);

/* DSPCLK_DIV can be only generated correctly after enabling SYSCLK.
* So we here provisionally enable it and then disable it afterward
* if current bias_level hasn't reached SND_SOC_BIAS_ON.
*/
if (codec->dapm.bias_level != SND_SOC_BIAS_ON)
snd_soc_update_bits(codec, WM8962_CLOCKING2,
WM8962_SYSCLK_ENA_MASK, WM8962_SYSCLK_ENA);

dspclk = snd_soc_read(codec, WM8962_CLOCKING1);

if (codec->dapm.bias_level != SND_SOC_BIAS_ON)
snd_soc_update_bits(codec, WM8962_CLOCKING2,
WM8962_SYSCLK_ENA_MASK, 0);

if (dspclk < 0) {
dev_err(codec->dev, "Failed to read DSPCLK: %d\n", dspclk);
return;
Expand Down
10 changes: 7 additions & 3 deletions sound/soc/codecs/wm_adsp.c
Original file line number Diff line number Diff line change
Expand Up @@ -1474,13 +1474,17 @@ static int wm_adsp2_ena(struct wm_adsp *dsp)
return ret;

/* Wait for the RAM to start, should be near instantaneous */
count = 0;
do {
for (count = 0; count < 10; ++count) {
ret = regmap_read(dsp->regmap, dsp->base + ADSP2_STATUS1,
&val);
if (ret != 0)
return ret;
} while (!(val & ADSP2_RAM_RDY) && ++count < 10);

if (val & ADSP2_RAM_RDY)
break;

msleep(1);
}

if (!(val & ADSP2_RAM_RDY)) {
adsp_err(dsp, "Failed to start DSP RAM\n");
Expand Down
2 changes: 0 additions & 2 deletions sound/soc/fsl/imx-wm8962.c
Original file line number Diff line number Diff line change
Expand Up @@ -130,8 +130,6 @@ static int imx_wm8962_set_bias_level(struct snd_soc_card *card,
break;
}

dapm->bias_level = level;

return 0;
}

Expand Down
24 changes: 12 additions & 12 deletions sound/soc/kirkwood/kirkwood-i2s.c
Original file line number Diff line number Diff line change
Expand Up @@ -473,17 +473,17 @@ static struct snd_soc_dai_driver kirkwood_i2s_dai_extclk[2] = {
.playback = {
.channels_min = 1,
.channels_max = 2,
.rates = SNDRV_PCM_RATE_8000_192000 |
SNDRV_PCM_RATE_CONTINUOUS |
SNDRV_PCM_RATE_KNOT,
.rates = SNDRV_PCM_RATE_CONTINUOUS,
.rate_min = 5512,
.rate_max = 192000,
.formats = KIRKWOOD_I2S_FORMATS,
},
.capture = {
.channels_min = 1,
.channels_max = 2,
.rates = SNDRV_PCM_RATE_8000_192000 |
SNDRV_PCM_RATE_CONTINUOUS |
SNDRV_PCM_RATE_KNOT,
.rates = SNDRV_PCM_RATE_CONTINUOUS,
.rate_min = 5512,
.rate_max = 192000,
.formats = KIRKWOOD_I2S_FORMATS,
},
.ops = &kirkwood_i2s_dai_ops,
Expand All @@ -494,17 +494,17 @@ static struct snd_soc_dai_driver kirkwood_i2s_dai_extclk[2] = {
.playback = {
.channels_min = 1,
.channels_max = 2,
.rates = SNDRV_PCM_RATE_8000_192000 |
SNDRV_PCM_RATE_CONTINUOUS |
SNDRV_PCM_RATE_KNOT,
.rates = SNDRV_PCM_RATE_CONTINUOUS,
.rate_min = 5512,
.rate_max = 192000,
.formats = KIRKWOOD_SPDIF_FORMATS,
},
.capture = {
.channels_min = 1,
.channels_max = 2,
.rates = SNDRV_PCM_RATE_8000_192000 |
SNDRV_PCM_RATE_CONTINUOUS |
SNDRV_PCM_RATE_KNOT,
.rates = SNDRV_PCM_RATE_CONTINUOUS,
.rate_min = 5512,
.rate_max = 192000,
.formats = KIRKWOOD_SPDIF_FORMATS,
},
.ops = &kirkwood_i2s_dai_ops,
Expand Down
38 changes: 27 additions & 11 deletions sound/soc/soc-generic-dmaengine-pcm.c
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,20 @@ static void dmaengine_pcm_request_chan_of(struct dmaengine_pcm *pcm,
}
}

static void dmaengine_pcm_release_chan(struct dmaengine_pcm *pcm)
{
unsigned int i;

for (i = SNDRV_PCM_STREAM_PLAYBACK; i <= SNDRV_PCM_STREAM_CAPTURE;
i++) {
if (!pcm->chan[i])
continue;
dma_release_channel(pcm->chan[i]);
if (pcm->flags & SND_DMAENGINE_PCM_FLAG_HALF_DUPLEX)
break;
}
}

/**
* snd_dmaengine_pcm_register - Register a dmaengine based PCM device
* @dev: The parent device for the PCM device
Expand All @@ -315,6 +329,7 @@ int snd_dmaengine_pcm_register(struct device *dev,
const struct snd_dmaengine_pcm_config *config, unsigned int flags)
{
struct dmaengine_pcm *pcm;
int ret;

pcm = kzalloc(sizeof(*pcm), GFP_KERNEL);
if (!pcm)
Expand All @@ -326,11 +341,20 @@ int snd_dmaengine_pcm_register(struct device *dev,
dmaengine_pcm_request_chan_of(pcm, dev);

if (flags & SND_DMAENGINE_PCM_FLAG_NO_RESIDUE)
return snd_soc_add_platform(dev, &pcm->platform,
ret = snd_soc_add_platform(dev, &pcm->platform,
&dmaengine_no_residue_pcm_platform);
else
return snd_soc_add_platform(dev, &pcm->platform,
ret = snd_soc_add_platform(dev, &pcm->platform,
&dmaengine_pcm_platform);
if (ret)
goto err_free_dma;

return 0;

err_free_dma:
dmaengine_pcm_release_chan(pcm);
kfree(pcm);
return ret;
}
EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_register);

Expand All @@ -345,23 +369,15 @@ void snd_dmaengine_pcm_unregister(struct device *dev)
{
struct snd_soc_platform *platform;
struct dmaengine_pcm *pcm;
unsigned int i;

platform = snd_soc_lookup_platform(dev);
if (!platform)
return;

pcm = soc_platform_to_pcm(platform);

for (i = SNDRV_PCM_STREAM_PLAYBACK; i <= SNDRV_PCM_STREAM_CAPTURE; i++) {
if (pcm->chan[i]) {
dma_release_channel(pcm->chan[i]);
if (pcm->flags & SND_DMAENGINE_PCM_FLAG_HALF_DUPLEX)
break;
}
}

snd_soc_remove_platform(platform);
dmaengine_pcm_release_chan(pcm);
kfree(pcm);
}
EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_unregister);
Expand Down
5 changes: 3 additions & 2 deletions sound/soc/soc-pcm.c
Original file line number Diff line number Diff line change
Expand Up @@ -600,12 +600,13 @@ static int soc_pcm_hw_free(struct snd_pcm_substream *substream)
struct snd_soc_platform *platform = rtd->platform;
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
struct snd_soc_dai *codec_dai = rtd->codec_dai;
struct snd_soc_codec *codec = rtd->codec;
bool playback = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;

mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);

/* apply codec digital mute */
if (!codec->active)
if ((playback && codec_dai->playback_active == 1) ||
(!playback && codec_dai->capture_active == 1))
snd_soc_dai_digital_mute(codec_dai, 1, substream->stream);

/* free any machine hw params */
Expand Down
6 changes: 3 additions & 3 deletions sound/soc/tegra/tegra20_i2s.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ static int tegra20_i2s_set_fmt(struct snd_soc_dai *dai,
unsigned int fmt)
{
struct tegra20_i2s *i2s = snd_soc_dai_get_drvdata(dai);
unsigned int mask, val;
unsigned int mask = 0, val = 0;

switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
case SND_SOC_DAIFMT_NB_NF:
Expand All @@ -83,10 +83,10 @@ static int tegra20_i2s_set_fmt(struct snd_soc_dai *dai,
return -EINVAL;
}

mask = TEGRA20_I2S_CTRL_MASTER_ENABLE;
mask |= TEGRA20_I2S_CTRL_MASTER_ENABLE;
switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
case SND_SOC_DAIFMT_CBS_CFS:
val = TEGRA20_I2S_CTRL_MASTER_ENABLE;
val |= TEGRA20_I2S_CTRL_MASTER_ENABLE;
break;
case SND_SOC_DAIFMT_CBM_CFM:
break;
Expand Down
10 changes: 5 additions & 5 deletions sound/soc/tegra/tegra20_spdif.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,15 +67,15 @@ static int tegra20_spdif_hw_params(struct snd_pcm_substream *substream,
{
struct device *dev = dai->dev;
struct tegra20_spdif *spdif = snd_soc_dai_get_drvdata(dai);
unsigned int mask, val;
unsigned int mask = 0, val = 0;
int ret, spdifclock;

mask = TEGRA20_SPDIF_CTRL_PACK |
TEGRA20_SPDIF_CTRL_BIT_MODE_MASK;
mask |= TEGRA20_SPDIF_CTRL_PACK |
TEGRA20_SPDIF_CTRL_BIT_MODE_MASK;
switch (params_format(params)) {
case SNDRV_PCM_FORMAT_S16_LE:
val = TEGRA20_SPDIF_CTRL_PACK |
TEGRA20_SPDIF_CTRL_BIT_MODE_16BIT;
val |= TEGRA20_SPDIF_CTRL_PACK |
TEGRA20_SPDIF_CTRL_BIT_MODE_16BIT;
break;
default:
return -EINVAL;
Expand Down
6 changes: 3 additions & 3 deletions sound/soc/tegra/tegra30_i2s.c
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ static int tegra30_i2s_set_fmt(struct snd_soc_dai *dai,
unsigned int fmt)
{
struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(dai);
unsigned int mask, val;
unsigned int mask = 0, val = 0;

switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
case SND_SOC_DAIFMT_NB_NF:
Expand All @@ -127,10 +127,10 @@ static int tegra30_i2s_set_fmt(struct snd_soc_dai *dai,
return -EINVAL;
}

mask = TEGRA30_I2S_CTRL_MASTER_ENABLE;
mask |= TEGRA30_I2S_CTRL_MASTER_ENABLE;
switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
case SND_SOC_DAIFMT_CBS_CFS:
val = TEGRA30_I2S_CTRL_MASTER_ENABLE;
val |= TEGRA30_I2S_CTRL_MASTER_ENABLE;
break;
case SND_SOC_DAIFMT_CBM_CFM:
break;
Expand Down

0 comments on commit 9b1be0f

Please sign in to comment.