diff options
author | Mark Brown <broonie@linaro.org> | 2014-08-04 16:31:05 +0100 |
---|---|---|
committer | Mark Brown <broonie@linaro.org> | 2014-08-04 16:31:05 +0100 |
commit | f0d766adbcac4eff4a114844b56d64aef1b8f5cd (patch) | |
tree | f8099e682afb9ef30d3770700c28b8cc8a042711 /sound | |
parent | 4a226ec97d797f4be486aab93458fc56a7d4de8c (diff) | |
parent | d0ab92d63cd6df4c47d93940bd5e4e7737fa4909 (diff) | |
download | linux-f0d766adbcac4eff4a114844b56d64aef1b8f5cd.tar.bz2 |
Merge tag 'asoc-v3.16-rc5' into asoc-linus
ASoC: Fixes for v3.16
A bigger batch of changes than I would like as I didn't send any for a
few weeks without noticing how many had built up. They are almost all
driver specific though, larger changes are:
- Fixes to the newly added Baytrail/MAX98090 which look like some QA
was missed on the microphone detection.
- Deletion of some erroniously listed audio formats for Haswell.
- Fix debugfs creation in the core so that we don't try to generate
multiple directories with the same name, relatively large textually
but simple to inspect by eye and test.
- A couple of bugfixes for the rcar driver one of which which involves
a bit of code motion to move initailisation of some hardware out of
common paths into device specific ones.
- Ensure both channels are powered up for mono outputs on Arizona
devices, involving some simple data tables listing the outputs and a
loop over them.
- A couple of fixes to save and restore information on suspended and
idle Samsung I2S controllers.
# gpg: Signature made Tue 22 Jul 2014 00:52:53 BST using RSA key ID 7EA229BD
# gpg: Good signature from "Mark Brown <broonie@sirena.org.uk>"
# gpg: aka "Mark Brown <broonie@debian.org>"
# gpg: aka "Mark Brown <broonie@kernel.org>"
# gpg: aka "Mark Brown <broonie@tardis.ed.ac.uk>"
# gpg: aka "Mark Brown <broonie@linaro.org>"
# gpg: aka "Mark Brown <Mark.Brown@linaro.org>"
Diffstat (limited to 'sound')
-rw-r--r-- | sound/soc/blackfin/bf5xx-i2s-pcm.c | 8 | ||||
-rw-r--r-- | sound/soc/codecs/adau1701.c | 6 | ||||
-rw-r--r-- | sound/soc/codecs/arizona.c | 25 | ||||
-rw-r--r-- | sound/soc/codecs/arizona.h | 1 | ||||
-rw-r--r-- | sound/soc/codecs/cs42l56.c | 4 | ||||
-rw-r--r-- | sound/soc/codecs/max98090.c | 2 | ||||
-rw-r--r-- | sound/soc/codecs/sgtl5000.c | 11 | ||||
-rw-r--r-- | sound/soc/codecs/tlv320aic3x.c | 2 | ||||
-rw-r--r-- | sound/soc/codecs/wm5110.c | 1 | ||||
-rw-r--r-- | sound/soc/codecs/wm_adsp.c | 2 | ||||
-rw-r--r-- | sound/soc/davinci/Kconfig | 1 | ||||
-rw-r--r-- | sound/soc/davinci/davinci-mcasp.c | 12 | ||||
-rw-r--r-- | sound/soc/fsl/fsl_sai.c | 9 | ||||
-rw-r--r-- | sound/soc/generic/simple-card.c | 13 | ||||
-rw-r--r-- | sound/soc/intel/byt-max98090.c | 19 | ||||
-rw-r--r-- | sound/soc/intel/sst-baytrail-pcm.c | 2 | ||||
-rw-r--r-- | sound/soc/intel/sst-haswell-dsp.c | 13 | ||||
-rw-r--r-- | sound/soc/intel/sst-haswell-pcm.c | 27 | ||||
-rw-r--r-- | sound/soc/s6000/s6000-i2s.c | 4 | ||||
-rw-r--r-- | sound/soc/samsung/i2s.c | 29 | ||||
-rw-r--r-- | sound/soc/sh/rcar/core.c | 4 | ||||
-rw-r--r-- | sound/soc/sh/rcar/gen.c | 33 | ||||
-rw-r--r-- | sound/soc/soc-core.c | 28 | ||||
-rw-r--r-- | sound/soc/soc-pcm.c | 1 |
24 files changed, 185 insertions, 72 deletions
diff --git a/sound/soc/blackfin/bf5xx-i2s-pcm.c b/sound/soc/blackfin/bf5xx-i2s-pcm.c index a3881c4381c9..bcf591373a7a 100644 --- a/sound/soc/blackfin/bf5xx-i2s-pcm.c +++ b/sound/soc/blackfin/bf5xx-i2s-pcm.c @@ -290,19 +290,19 @@ static int bf5xx_pcm_silence(struct snd_pcm_substream *substream, unsigned int sample_size = runtime->sample_bits / 8; void *buf = runtime->dma_area; struct bf5xx_i2s_pcm_data *dma_data; - unsigned int offset, size; + unsigned int offset, samples; dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); if (dma_data->tdm_mode) { offset = pos * 8 * sample_size; - size = count * 8 * sample_size; + samples = count * 8; } else { offset = frames_to_bytes(runtime, pos); - size = frames_to_bytes(runtime, count); + samples = count * runtime->channels; } - snd_pcm_format_set_silence(runtime->format, buf + offset, size); + snd_pcm_format_set_silence(runtime->format, buf + offset, samples); return 0; } diff --git a/sound/soc/codecs/adau1701.c b/sound/soc/codecs/adau1701.c index d71c59cf7bdd..370b742117ef 100644 --- a/sound/soc/codecs/adau1701.c +++ b/sound/soc/codecs/adau1701.c @@ -230,8 +230,10 @@ static int adau1701_reg_read(void *context, unsigned int reg, *value = 0; - for (i = 0; i < size; i++) - *value |= recv_buf[i] << (i * 8); + for (i = 0; i < size; i++) { + *value <<= 8; + *value |= recv_buf[i]; + } return 0; } diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c index 29e198f57d4c..747c71e59c04 100644 --- a/sound/soc/codecs/arizona.c +++ b/sound/soc/codecs/arizona.c @@ -243,6 +243,31 @@ int arizona_init_spk(struct snd_soc_codec *codec) } EXPORT_SYMBOL_GPL(arizona_init_spk); +static const struct snd_soc_dapm_route arizona_mono_routes[] = { + { "OUT1R", NULL, "OUT1L" }, + { "OUT2R", NULL, "OUT2L" }, + { "OUT3R", NULL, "OUT3L" }, + { "OUT4R", NULL, "OUT4L" }, + { "OUT5R", NULL, "OUT5L" }, + { "OUT6R", NULL, "OUT6L" }, +}; + +int arizona_init_mono(struct snd_soc_codec *codec) +{ + struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec); + struct arizona *arizona = priv->arizona; + int i; + + for (i = 0; i < ARIZONA_MAX_OUTPUT; ++i) { + if (arizona->pdata.out_mono[i]) + snd_soc_dapm_add_routes(&codec->dapm, + &arizona_mono_routes[i], 1); + } + + return 0; +} +EXPORT_SYMBOL_GPL(arizona_init_mono); + int arizona_init_gpio(struct snd_soc_codec *codec) { struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec); diff --git a/sound/soc/codecs/arizona.h b/sound/soc/codecs/arizona.h index 05ae17f5bca3..942cfb197b6d 100644 --- a/sound/soc/codecs/arizona.h +++ b/sound/soc/codecs/arizona.h @@ -249,6 +249,7 @@ extern int arizona_set_fll(struct arizona_fll *fll, int source, extern int arizona_init_spk(struct snd_soc_codec *codec); extern int arizona_init_gpio(struct snd_soc_codec *codec); +extern int arizona_init_mono(struct snd_soc_codec *codec); extern int arizona_init_dai(struct arizona_priv *priv, int dai); diff --git a/sound/soc/codecs/cs42l56.c b/sound/soc/codecs/cs42l56.c index fdc4bd27b0df..8e68ef5de849 100644 --- a/sound/soc/codecs/cs42l56.c +++ b/sound/soc/codecs/cs42l56.c @@ -445,9 +445,9 @@ static const struct snd_kcontrol_new cs42l56_snd_controls[] = { SOC_DOUBLE("ADC Boost Switch", CS42L56_GAIN_BIAS_CTL, 3, 2, 1, 1), SOC_DOUBLE_R_SX_TLV("Headphone Volume", CS42L56_HPA_VOLUME, - CS42L56_HPA_VOLUME, 0, 0x44, 0x55, hl_tlv), + CS42L56_HPB_VOLUME, 0, 0x44, 0x55, hl_tlv), SOC_DOUBLE_R_SX_TLV("LineOut Volume", CS42L56_LOA_VOLUME, - CS42L56_LOA_VOLUME, 0, 0x44, 0x55, hl_tlv), + CS42L56_LOB_VOLUME, 0, 0x44, 0x55, hl_tlv), SOC_SINGLE_TLV("Bass Shelving Volume", CS42L56_TONE_CTL, 0, 0x00, 1, tone_tlv), diff --git a/sound/soc/codecs/max98090.c b/sound/soc/codecs/max98090.c index f5fccc7a8e89..d97f1ce7ff7d 100644 --- a/sound/soc/codecs/max98090.c +++ b/sound/soc/codecs/max98090.c @@ -2284,7 +2284,7 @@ static int max98090_probe(struct snd_soc_codec *codec) /* Register for interrupts */ dev_dbg(codec->dev, "irq = %d\n", max98090->irq); - ret = request_threaded_irq(max98090->irq, NULL, + ret = devm_request_threaded_irq(codec->dev, max98090->irq, NULL, max98090_interrupt, IRQF_TRIGGER_FALLING | IRQF_ONESHOT, "max98090_interrupt", codec); if (ret < 0) { diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c index 3d39f0b5b4a8..8f4c73d17c87 100644 --- a/sound/soc/codecs/sgtl5000.c +++ b/sound/soc/codecs/sgtl5000.c @@ -1277,7 +1277,7 @@ static int sgtl5000_enable_regulators(struct snd_soc_codec *codec) return ret; } - ret = devm_regulator_bulk_get(codec->dev, ARRAY_SIZE(sgtl5000->supplies), + ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(sgtl5000->supplies), sgtl5000->supplies); if (ret) goto err_ldo_remove; @@ -1285,13 +1285,16 @@ static int sgtl5000_enable_regulators(struct snd_soc_codec *codec) ret = regulator_bulk_enable(ARRAY_SIZE(sgtl5000->supplies), sgtl5000->supplies); if (ret) - goto err_ldo_remove; + goto err_regulator_free; /* wait for all power rails bring up */ udelay(10); return 0; +err_regulator_free: + regulator_bulk_free(ARRAY_SIZE(sgtl5000->supplies), + sgtl5000->supplies); err_ldo_remove: if (!external_vddd) ldo_regulator_remove(codec); @@ -1361,6 +1364,8 @@ static int sgtl5000_probe(struct snd_soc_codec *codec) err: regulator_bulk_disable(ARRAY_SIZE(sgtl5000->supplies), sgtl5000->supplies); + regulator_bulk_free(ARRAY_SIZE(sgtl5000->supplies), + sgtl5000->supplies); ldo_regulator_remove(codec); return ret; @@ -1374,6 +1379,8 @@ static int sgtl5000_remove(struct snd_soc_codec *codec) regulator_bulk_disable(ARRAY_SIZE(sgtl5000->supplies), sgtl5000->supplies); + regulator_bulk_free(ARRAY_SIZE(sgtl5000->supplies), + sgtl5000->supplies); ldo_regulator_remove(codec); return 0; diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c index e12fafbb1e09..5360772bc1ad 100644 --- a/sound/soc/codecs/tlv320aic3x.c +++ b/sound/soc/codecs/tlv320aic3x.c @@ -879,7 +879,7 @@ static int aic3x_hw_params(struct snd_pcm_substream *substream, case SNDRV_PCM_FORMAT_S20_3LE: data |= (0x01 << 4); break; - case SNDRV_PCM_FORMAT_S24_LE: + case SNDRV_PCM_FORMAT_S24_3LE: data |= (0x02 << 4); break; case SNDRV_PCM_FORMAT_S32_LE: diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c index 2e5fcb559e90..62ef54456499 100644 --- a/sound/soc/codecs/wm5110.c +++ b/sound/soc/codecs/wm5110.c @@ -1596,6 +1596,7 @@ static int wm5110_codec_probe(struct snd_soc_codec *codec) arizona_init_spk(codec); arizona_init_gpio(codec); + arizona_init_mono(codec); ret = snd_soc_add_codec_controls(codec, wm_adsp2_fw_controls, 8); if (ret != 0) diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c index 060027182dcb..2537725dd53f 100644 --- a/sound/soc/codecs/wm_adsp.c +++ b/sound/soc/codecs/wm_adsp.c @@ -1758,3 +1758,5 @@ int wm_adsp2_init(struct wm_adsp *adsp, bool dvfs) return 0; } EXPORT_SYMBOL_GPL(wm_adsp2_init); + +MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/davinci/Kconfig b/sound/soc/davinci/Kconfig index 50a098749b9e..fdbb16fffd30 100644 --- a/sound/soc/davinci/Kconfig +++ b/sound/soc/davinci/Kconfig @@ -6,6 +6,7 @@ config SND_DAVINCI_SOC_I2S tristate config SND_DAVINCI_SOC_MCASP + depends on SND_DAVINCI_SOC || SND_OMAP_SOC tristate config SND_DAVINCI_SOC_VCIF diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index 9afb14629a17..bfcc6c3dc2fd 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c @@ -720,6 +720,10 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream, case SNDRV_PCM_FORMAT_U24_LE: case SNDRV_PCM_FORMAT_S24_LE: + dma_params->data_type = 4; + word_length = 24; + break; + case SNDRV_PCM_FORMAT_U32_LE: case SNDRV_PCM_FORMAT_S32_LE: dma_params->data_type = 4; @@ -1223,14 +1227,22 @@ static int davinci_mcasp_probe(struct platform_device *pdev) goto err; switch (mcasp->version) { +#if IS_BUILTIN(CONFIG_SND_DAVINCI_SOC) || \ + (IS_MODULE(CONFIG_SND_DAVINCI_SOC_MCASP) && \ + IS_MODULE(CONFIG_SND_DAVINCI_SOC)) case MCASP_VERSION_1: case MCASP_VERSION_2: case MCASP_VERSION_3: ret = davinci_soc_platform_register(&pdev->dev); break; +#endif +#if IS_BUILTIN(CONFIG_SND_OMAP_SOC) || \ + (IS_MODULE(CONFIG_SND_DAVINCI_SOC_MCASP) && \ + IS_MODULE(CONFIG_SND_OMAP_SOC)) case MCASP_VERSION_4: ret = omap_pcm_platform_register(&pdev->dev); break; +#endif default: dev_err(&pdev->dev, "Invalid McASP version: %d\n", mcasp->version); diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c index c5a0e8af8226..1b6ee2ce849f 100644 --- a/sound/soc/fsl/fsl_sai.c +++ b/sound/soc/fsl/fsl_sai.c @@ -106,7 +106,7 @@ irq_rx: xcsr &= ~FSL_SAI_CSR_xF_MASK; if (flags) - regmap_write(sai->regmap, FSL_SAI_TCSR, flags | xcsr); + regmap_write(sai->regmap, FSL_SAI_RCSR, flags | xcsr); out: if (irq_none) @@ -371,10 +371,13 @@ static int fsl_sai_trigger(struct snd_pcm_substream *substream, int cmd, /* Check if the opposite FRDE is also disabled */ if (!(tx ? rcsr & FSL_SAI_CSR_FRDE : tcsr & FSL_SAI_CSR_FRDE)) { + /* Disable both directions and reset their FIFOs */ regmap_update_bits(sai->regmap, FSL_SAI_TCSR, - FSL_SAI_CSR_TERE, 0); + FSL_SAI_CSR_TERE | FSL_SAI_CSR_FR, + FSL_SAI_CSR_FR); regmap_update_bits(sai->regmap, FSL_SAI_RCSR, - FSL_SAI_CSR_TERE, 0); + FSL_SAI_CSR_TERE | FSL_SAI_CSR_FR, + FSL_SAI_CSR_FR); } break; default: diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c index 03a7fdcdf114..159e517fa09a 100644 --- a/sound/soc/generic/simple-card.c +++ b/sound/soc/generic/simple-card.c @@ -116,6 +116,7 @@ asoc_simple_card_sub_parse_of(struct device_node *np, { struct device_node *node; struct clk *clk; + u32 val; int ret; /* @@ -151,10 +152,8 @@ asoc_simple_card_sub_parse_of(struct device_node *np, } dai->sysclk = clk_get_rate(clk); - } else if (of_property_read_bool(np, "system-clock-frequency")) { - of_property_read_u32(np, - "system-clock-frequency", - &dai->sysclk); + } else if (!of_property_read_u32(np, "system-clock-frequency", &val)) { + dai->sysclk = val; } else { clk = of_clk_get(node, 0); if (!IS_ERR(clk)) @@ -303,6 +302,7 @@ static int asoc_simple_card_parse_of(struct device_node *node, { struct snd_soc_dai_link *dai_link = priv->snd_card.dai_link; struct simple_dai_props *dai_props = priv->dai_props; + u32 val; int ret; /* parsing the card name from DT */ @@ -325,8 +325,9 @@ static int asoc_simple_card_parse_of(struct device_node *node, } /* Factor to mclk, used in hw_params() */ - of_property_read_u32(node, "simple-audio-card,mclk-fs", - &priv->mclk_fs); + ret = of_property_read_u32(node, "simple-audio-card,mclk-fs", &val); + if (ret == 0) + priv->mclk_fs = val; dev_dbg(dev, "New simple-card: %s\n", priv->snd_card.name ? priv->snd_card.name : ""); diff --git a/sound/soc/intel/byt-max98090.c b/sound/soc/intel/byt-max98090.c index 5fc98c64a3f4..5cfb41ec3fab 100644 --- a/sound/soc/intel/byt-max98090.c +++ b/sound/soc/intel/byt-max98090.c @@ -39,8 +39,7 @@ static const struct snd_soc_dapm_widget byt_max98090_widgets[] = { static const struct snd_soc_dapm_route byt_max98090_audio_map[] = { {"IN34", NULL, "Headset Mic"}, - {"IN34", NULL, "MICBIAS"}, - {"MICBIAS", NULL, "Headset Mic"}, + {"Headset Mic", NULL, "MICBIAS"}, {"DMICL", NULL, "Int Mic"}, {"Headphone", NULL, "HPL"}, {"Headphone", NULL, "HPR"}, @@ -84,7 +83,8 @@ static struct snd_soc_jack_gpio hs_jack_gpios[] = { { .name = "mic-gpio", .idx = 1, - .report = SND_JACK_MICROPHONE | SND_JACK_LINEIN, + .invert = 1, + .report = SND_JACK_MICROPHONE, .debounce_time = 200, }, }; @@ -108,7 +108,8 @@ static int byt_max98090_init(struct snd_soc_pcm_runtime *runtime) } /* Enable jack detection */ - ret = snd_soc_jack_new(codec, "Headphone", SND_JACK_HEADPHONE, jack); + ret = snd_soc_jack_new(codec, "Headset", + SND_JACK_LINEOUT | SND_JACK_HEADSET, jack); if (ret) return ret; @@ -117,13 +118,9 @@ static int byt_max98090_init(struct snd_soc_pcm_runtime *runtime) if (ret) return ret; - ret = snd_soc_jack_add_gpiods(card->dev->parent, jack, - ARRAY_SIZE(hs_jack_gpios), - hs_jack_gpios); - if (ret) - return ret; - - return max98090_mic_detect(codec, jack); + return snd_soc_jack_add_gpiods(card->dev->parent, jack, + ARRAY_SIZE(hs_jack_gpios), + hs_jack_gpios); } static struct snd_soc_dai_link byt_max98090_dais[] = { diff --git a/sound/soc/intel/sst-baytrail-pcm.c b/sound/soc/intel/sst-baytrail-pcm.c index 8eab97368ea7..599401c0c655 100644 --- a/sound/soc/intel/sst-baytrail-pcm.c +++ b/sound/soc/intel/sst-baytrail-pcm.c @@ -32,7 +32,7 @@ static const struct snd_pcm_hardware sst_byt_pcm_hardware = { SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME, .formats = SNDRV_PCM_FMTBIT_S16_LE | - SNDRV_PCM_FORMAT_S24_LE, + SNDRV_PCM_FMTBIT_S24_LE, .period_bytes_min = 384, .period_bytes_max = 48000, .periods_min = 2, diff --git a/sound/soc/intel/sst-haswell-dsp.c b/sound/soc/intel/sst-haswell-dsp.c index 535f517629fd..a33b931181dc 100644 --- a/sound/soc/intel/sst-haswell-dsp.c +++ b/sound/soc/intel/sst-haswell-dsp.c @@ -359,6 +359,17 @@ static u32 hsw_block_get_bit(struct sst_mem_block *block) return bit; } +/*dummy read a SRAM block.*/ +static void sst_mem_block_dummy_read(struct sst_mem_block *block) +{ + u32 size; + u8 tmp_buf[4]; + struct sst_dsp *sst = block->dsp; + + size = block->size > 4 ? 4 : block->size; + memcpy_fromio(tmp_buf, sst->addr.lpe + block->offset, size); +} + /* enable 32kB memory block - locks held by caller */ static int hsw_block_enable(struct sst_mem_block *block) { @@ -378,6 +389,8 @@ static int hsw_block_enable(struct sst_mem_block *block) /* wait 18 DSP clock ticks */ udelay(10); + /*add a dummy read before the SRAM block is written, otherwise the writing may miss bytes sometimes.*/ + sst_mem_block_dummy_read(block); return 0; } diff --git a/sound/soc/intel/sst-haswell-pcm.c b/sound/soc/intel/sst-haswell-pcm.c index 058efb17c568..61bf6da4bb02 100644 --- a/sound/soc/intel/sst-haswell-pcm.c +++ b/sound/soc/intel/sst-haswell-pcm.c @@ -80,7 +80,7 @@ static const struct snd_pcm_hardware hsw_pcm_hardware = { SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME | SNDRV_PCM_INFO_NO_PERIOD_WAKEUP, - .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FORMAT_S24_LE | + .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, .period_bytes_min = PAGE_SIZE, .period_bytes_max = (HSW_PCM_PERIODS_MAX / HSW_PCM_PERIODS_MIN) * PAGE_SIZE, @@ -400,7 +400,15 @@ static int hsw_pcm_hw_params(struct snd_pcm_substream *substream, sst_hsw_stream_set_valid(hsw, pcm_data->stream, 16); break; case SNDRV_PCM_FORMAT_S24_LE: - bits = SST_HSW_DEPTH_24BIT; + bits = SST_HSW_DEPTH_32BIT; + sst_hsw_stream_set_valid(hsw, pcm_data->stream, 24); + break; + case SNDRV_PCM_FORMAT_S8: + bits = SST_HSW_DEPTH_8BIT; + sst_hsw_stream_set_valid(hsw, pcm_data->stream, 8); + break; + case SNDRV_PCM_FORMAT_S32_LE: + bits = SST_HSW_DEPTH_32BIT; sst_hsw_stream_set_valid(hsw, pcm_data->stream, 32); break; default: @@ -685,8 +693,9 @@ static int hsw_pcm_new(struct snd_soc_pcm_runtime *rtd) } #define HSW_FORMATS \ - (SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S16_LE |\ - SNDRV_PCM_FMTBIT_S32_LE) + (SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S24_LE | \ + SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S16_LE |\ + SNDRV_PCM_FMTBIT_S8) static struct snd_soc_dai_driver hsw_dais[] = { { @@ -696,7 +705,7 @@ static struct snd_soc_dai_driver hsw_dais[] = { .channels_min = 2, .channels_max = 2, .rates = SNDRV_PCM_RATE_48000, - .formats = SNDRV_PCM_FMTBIT_S16_LE, + .formats = SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE, }, }, { @@ -727,8 +736,8 @@ static struct snd_soc_dai_driver hsw_dais[] = { .stream_name = "Loopback Capture", .channels_min = 2, .channels_max = 2, - .rates = SNDRV_PCM_RATE_8000_192000, - .formats = HSW_FORMATS, + .rates = SNDRV_PCM_RATE_48000, + .formats = SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE, }, }, { @@ -737,8 +746,8 @@ static struct snd_soc_dai_driver hsw_dais[] = { .stream_name = "Analog Capture", .channels_min = 2, .channels_max = 2, - .rates = SNDRV_PCM_RATE_8000_192000, - .formats = HSW_FORMATS, + .rates = SNDRV_PCM_RATE_48000, + .formats = SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE, }, }, }; diff --git a/sound/soc/s6000/s6000-i2s.c b/sound/soc/s6000/s6000-i2s.c index 7eba7979b9af..1c8d01166e5b 100644 --- a/sound/soc/s6000/s6000-i2s.c +++ b/sound/soc/s6000/s6000-i2s.c @@ -570,7 +570,7 @@ err_release_none: return ret; } -static void s6000_i2s_remove(struct platform_device *pdev) +static int s6000_i2s_remove(struct platform_device *pdev) { struct s6000_i2s_dev *dev = dev_get_drvdata(&pdev->dev); struct resource *region; @@ -597,6 +597,8 @@ static void s6000_i2s_remove(struct platform_device *pdev) iounmap(mmio); region = platform_get_resource(pdev, IORESOURCE_IO, 0); release_mem_region(region->start, resource_size(region)); + + return 0; } static struct platform_driver s6000_i2s_driver = { diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c index 2ac76fa3e742..d2533dbc8399 100644 --- a/sound/soc/samsung/i2s.c +++ b/sound/soc/samsung/i2s.c @@ -68,6 +68,8 @@ struct i2s_dai { #define DAI_OPENED (1 << 0) /* Dai is opened */ #define DAI_MANAGER (1 << 1) /* Dai is the manager */ unsigned mode; + /* CDCLK pin direction: 0 - input, 1 - output */ + unsigned int cdclk_out:1; /* Driver for this DAI */ struct snd_soc_dai_driver i2s_dai_drv; /* DMA parameters */ @@ -737,6 +739,9 @@ static int i2s_startup(struct snd_pcm_substream *substream, spin_unlock_irqrestore(&lock, flags); + if (!is_opened(other) && i2s->cdclk_out) + i2s_set_sysclk(dai, SAMSUNG_I2S_CDCLK, + 0, SND_SOC_CLOCK_OUT); return 0; } @@ -752,9 +757,13 @@ static void i2s_shutdown(struct snd_pcm_substream *substream, i2s->mode &= ~DAI_OPENED; i2s->mode &= ~DAI_MANAGER; - if (is_opened(other)) + if (is_opened(other)) { other->mode |= DAI_MANAGER; - + } else { + u32 mod = readl(i2s->addr + I2SMOD); + i2s->cdclk_out = !(mod & MOD_CDCLKCON); + other->cdclk_out = i2s->cdclk_out; + } /* Reset any constraint on RFS and BFS */ i2s->rfs = 0; i2s->bfs = 0; @@ -920,11 +929,9 @@ static int i2s_suspend(struct snd_soc_dai *dai) { struct i2s_dai *i2s = to_info(dai); - if (dai->active) { - i2s->suspend_i2smod = readl(i2s->addr + I2SMOD); - i2s->suspend_i2scon = readl(i2s->addr + I2SCON); - i2s->suspend_i2spsr = readl(i2s->addr + I2SPSR); - } + i2s->suspend_i2smod = readl(i2s->addr + I2SMOD); + i2s->suspend_i2scon = readl(i2s->addr + I2SCON); + i2s->suspend_i2spsr = readl(i2s->addr + I2SPSR); return 0; } @@ -933,11 +940,9 @@ static int i2s_resume(struct snd_soc_dai *dai) { struct i2s_dai *i2s = to_info(dai); - if (dai->active) { - writel(i2s->suspend_i2scon, i2s->addr + I2SCON); - writel(i2s->suspend_i2smod, i2s->addr + I2SMOD); - writel(i2s->suspend_i2spsr, i2s->addr + I2SPSR); - } + writel(i2s->suspend_i2scon, i2s->addr + I2SCON); + writel(i2s->suspend_i2smod, i2s->addr + I2SMOD); + writel(i2s->suspend_i2spsr, i2s->addr + I2SPSR); return 0; } diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c index 4e86265f625c..ed76901f8202 100644 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c @@ -297,7 +297,6 @@ static void rsnd_dma_of_name(struct rsnd_dma *dma, for (i = 1; i < MOD_MAX; i++) { if (!src) { mod[i] = ssi; - break; } else if (!dvc) { mod[i] = src; src = NULL; @@ -308,6 +307,9 @@ static void rsnd_dma_of_name(struct rsnd_dma *dma, if (mod[i] == this) index = i; + + if (mod[i] == ssi) + break; } if (is_play) { diff --git a/sound/soc/sh/rcar/gen.c b/sound/soc/sh/rcar/gen.c index 1dd2b7d38c2c..0280a11c0899 100644 --- a/sound/soc/sh/rcar/gen.c +++ b/sound/soc/sh/rcar/gen.c @@ -184,7 +184,7 @@ static int rsnd_gen_regmap_init(struct rsnd_priv *priv, #define RDMA_CMD_O_N(addr, i) (addr ##_reg - 0x004f8000 + (0x400 * i)) #define RDMA_CMD_O_P(addr, i) (addr ##_reg - 0x001f8000 + (0x400 * i)) -void rsnd_gen_dma_addr(struct rsnd_priv *priv, +static void rsnd_gen2_dma_addr(struct rsnd_priv *priv, struct rsnd_dma *dma, struct dma_slave_config *cfg, int is_play, int slave_id) @@ -226,17 +226,6 @@ void rsnd_gen_dma_addr(struct rsnd_priv *priv, } }; - cfg->slave_id = slave_id; - cfg->src_addr = 0; - cfg->dst_addr = 0; - cfg->direction = is_play ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM; - - /* - * gen1 uses default DMA addr - */ - if (rsnd_is_gen1(priv)) - return; - /* it shouldn't happen */ if (use_dvc & !use_src) { dev_err(dev, "DVC is selected without SRC\n"); @@ -250,6 +239,26 @@ void rsnd_gen_dma_addr(struct rsnd_priv *priv, id, cfg->src_addr, cfg->dst_addr); } +void rsnd_gen_dma_addr(struct rsnd_priv *priv, + struct rsnd_dma *dma, + struct dma_slave_config *cfg, + int is_play, int slave_id) +{ + cfg->slave_id = slave_id; + cfg->src_addr = 0; + cfg->dst_addr = 0; + cfg->direction = is_play ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM; + + /* + * gen1 uses default DMA addr + */ + if (rsnd_is_gen1(priv)) + return; + + rsnd_gen2_dma_addr(priv, dma, cfg, is_play, slave_id); +} + + /* * Gen2 */ diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index b87d7d882e6d..91120b8e283e 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -270,12 +270,32 @@ static const struct file_operations codec_reg_fops = { .llseek = default_llseek, }; +static struct dentry *soc_debugfs_create_dir(struct dentry *parent, + const char *fmt, ...) +{ + struct dentry *de; + va_list ap; + char *s; + + va_start(ap, fmt); + s = kvasprintf(GFP_KERNEL, fmt, ap); + va_end(ap); + + if (!s) + return NULL; + + de = debugfs_create_dir(s, parent); + kfree(s); + + return de; +} + static void soc_init_codec_debugfs(struct snd_soc_codec *codec) { struct dentry *debugfs_card_root = codec->card->debugfs_card_root; - codec->debugfs_codec_root = debugfs_create_dir(codec->name, - debugfs_card_root); + codec->debugfs_codec_root = soc_debugfs_create_dir(debugfs_card_root, + "codec:%s", codec->name); if (!codec->debugfs_codec_root) { dev_warn(codec->dev, "ASoC: Failed to create codec debugfs directory\n"); @@ -306,8 +326,8 @@ static void soc_init_platform_debugfs(struct snd_soc_platform *platform) { struct dentry *debugfs_card_root = platform->card->debugfs_card_root; - platform->debugfs_platform_root = debugfs_create_dir(platform->name, - debugfs_card_root); + platform->debugfs_platform_root = soc_debugfs_create_dir(debugfs_card_root, + "platform:%s", platform->name); if (!platform->debugfs_platform_root) { dev_warn(platform->dev, "ASoC: Failed to create platform debugfs directory\n"); diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index 54d18f22a33e..4ea656770d65 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -2069,6 +2069,7 @@ int soc_dpcm_runtime_update(struct snd_soc_card *card) dpcm_be_disconnect(fe, SNDRV_PCM_STREAM_PLAYBACK); } + dpcm_path_put(&list); capture: /* skip if FE doesn't have capture capability */ if (!fe->cpu_dai->driver->capture.channels_min) |