aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc
diff options
context:
space:
mode:
authorMark Brown <broonie@linaro.org>2014-08-15 07:51:26 -0400
committerMark Brown <broonie@linaro.org>2014-08-15 07:51:26 -0400
commit2fa4a285ddfd39cfa711da3f5e898ec2ce80ef87 (patch)
treef8099e682afb9ef30d3770700c28b8cc8a042711 /sound/soc
parent9c1810f9c3ff0a320d8d152884449d16b3a4d128 (diff)
parentd0ab92d63cd6df4c47d93940bd5e4e7737fa4909 (diff)
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/soc')
-rw-r--r--sound/soc/blackfin/bf5xx-i2s-pcm.c8
-rw-r--r--sound/soc/codecs/adau1701.c6
-rw-r--r--sound/soc/codecs/arizona.c25
-rw-r--r--sound/soc/codecs/arizona.h1
-rw-r--r--sound/soc/codecs/cs42l56.c4
-rw-r--r--sound/soc/codecs/max98090.c2
-rw-r--r--sound/soc/codecs/sgtl5000.c11
-rw-r--r--sound/soc/codecs/tlv320aic3x.c2
-rw-r--r--sound/soc/codecs/wm5110.c1
-rw-r--r--sound/soc/codecs/wm_adsp.c2
-rw-r--r--sound/soc/davinci/Kconfig1
-rw-r--r--sound/soc/davinci/davinci-mcasp.c12
-rw-r--r--sound/soc/fsl/fsl_sai.c9
-rw-r--r--sound/soc/generic/simple-card.c13
-rw-r--r--sound/soc/intel/byt-max98090.c19
-rw-r--r--sound/soc/intel/sst-baytrail-pcm.c2
-rw-r--r--sound/soc/intel/sst-haswell-dsp.c13
-rw-r--r--sound/soc/intel/sst-haswell-pcm.c27
-rw-r--r--sound/soc/s6000/s6000-i2s.c4
-rw-r--r--sound/soc/samsung/i2s.c29
-rw-r--r--sound/soc/sh/rcar/core.c4
-rw-r--r--sound/soc/sh/rcar/gen.c33
-rw-r--r--sound/soc/soc-core.c28
-rw-r--r--sound/soc/soc-pcm.c1
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,
290 unsigned int sample_size = runtime->sample_bits / 8; 290 unsigned int sample_size = runtime->sample_bits / 8;
291 void *buf = runtime->dma_area; 291 void *buf = runtime->dma_area;
292 struct bf5xx_i2s_pcm_data *dma_data; 292 struct bf5xx_i2s_pcm_data *dma_data;
293 unsigned int offset, size; 293 unsigned int offset, samples;
294 294
295 dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); 295 dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
296 296
297 if (dma_data->tdm_mode) { 297 if (dma_data->tdm_mode) {
298 offset = pos * 8 * sample_size; 298 offset = pos * 8 * sample_size;
299 size = count * 8 * sample_size; 299 samples = count * 8;
300 } else { 300 } else {
301 offset = frames_to_bytes(runtime, pos); 301 offset = frames_to_bytes(runtime, pos);
302 size = frames_to_bytes(runtime, count); 302 samples = count * runtime->channels;
303 } 303 }
304 304
305 snd_pcm_format_set_silence(runtime->format, buf + offset, size); 305 snd_pcm_format_set_silence(runtime->format, buf + offset, samples);
306 306
307 return 0; 307 return 0;
308} 308}
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,
230 230
231 *value = 0; 231 *value = 0;
232 232
233 for (i = 0; i < size; i++) 233 for (i = 0; i < size; i++) {
234 *value |= recv_buf[i] << (i * 8); 234 *value <<= 8;
235 *value |= recv_buf[i];
236 }
235 237
236 return 0; 238 return 0;
237} 239}
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)
243} 243}
244EXPORT_SYMBOL_GPL(arizona_init_spk); 244EXPORT_SYMBOL_GPL(arizona_init_spk);
245 245
246static const struct snd_soc_dapm_route arizona_mono_routes[] = {
247 { "OUT1R", NULL, "OUT1L" },
248 { "OUT2R", NULL, "OUT2L" },
249 { "OUT3R", NULL, "OUT3L" },
250 { "OUT4R", NULL, "OUT4L" },
251 { "OUT5R", NULL, "OUT5L" },
252 { "OUT6R", NULL, "OUT6L" },
253};
254
255int arizona_init_mono(struct snd_soc_codec *codec)
256{
257 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
258 struct arizona *arizona = priv->arizona;
259 int i;
260
261 for (i = 0; i < ARIZONA_MAX_OUTPUT; ++i) {
262 if (arizona->pdata.out_mono[i])
263 snd_soc_dapm_add_routes(&codec->dapm,
264 &arizona_mono_routes[i], 1);
265 }
266
267 return 0;
268}
269EXPORT_SYMBOL_GPL(arizona_init_mono);
270
246int arizona_init_gpio(struct snd_soc_codec *codec) 271int arizona_init_gpio(struct snd_soc_codec *codec)
247{ 272{
248 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec); 273 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,
249 249
250extern int arizona_init_spk(struct snd_soc_codec *codec); 250extern int arizona_init_spk(struct snd_soc_codec *codec);
251extern int arizona_init_gpio(struct snd_soc_codec *codec); 251extern int arizona_init_gpio(struct snd_soc_codec *codec);
252extern int arizona_init_mono(struct snd_soc_codec *codec);
252 253
253extern int arizona_init_dai(struct arizona_priv *priv, int dai); 254extern int arizona_init_dai(struct arizona_priv *priv, int dai);
254 255
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[] = {
445 SOC_DOUBLE("ADC Boost Switch", CS42L56_GAIN_BIAS_CTL, 3, 2, 1, 1), 445 SOC_DOUBLE("ADC Boost Switch", CS42L56_GAIN_BIAS_CTL, 3, 2, 1, 1),
446 446
447 SOC_DOUBLE_R_SX_TLV("Headphone Volume", CS42L56_HPA_VOLUME, 447 SOC_DOUBLE_R_SX_TLV("Headphone Volume", CS42L56_HPA_VOLUME,
448 CS42L56_HPA_VOLUME, 0, 0x44, 0x55, hl_tlv), 448 CS42L56_HPB_VOLUME, 0, 0x44, 0x55, hl_tlv),
449 SOC_DOUBLE_R_SX_TLV("LineOut Volume", CS42L56_LOA_VOLUME, 449 SOC_DOUBLE_R_SX_TLV("LineOut Volume", CS42L56_LOA_VOLUME,
450 CS42L56_LOA_VOLUME, 0, 0x44, 0x55, hl_tlv), 450 CS42L56_LOB_VOLUME, 0, 0x44, 0x55, hl_tlv),
451 451
452 SOC_SINGLE_TLV("Bass Shelving Volume", CS42L56_TONE_CTL, 452 SOC_SINGLE_TLV("Bass Shelving Volume", CS42L56_TONE_CTL,
453 0, 0x00, 1, tone_tlv), 453 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)
2284 /* Register for interrupts */ 2284 /* Register for interrupts */
2285 dev_dbg(codec->dev, "irq = %d\n", max98090->irq); 2285 dev_dbg(codec->dev, "irq = %d\n", max98090->irq);
2286 2286
2287 ret = request_threaded_irq(max98090->irq, NULL, 2287 ret = devm_request_threaded_irq(codec->dev, max98090->irq, NULL,
2288 max98090_interrupt, IRQF_TRIGGER_FALLING | IRQF_ONESHOT, 2288 max98090_interrupt, IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
2289 "max98090_interrupt", codec); 2289 "max98090_interrupt", codec);
2290 if (ret < 0) { 2290 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)
1277 return ret; 1277 return ret;
1278 } 1278 }
1279 1279
1280 ret = devm_regulator_bulk_get(codec->dev, ARRAY_SIZE(sgtl5000->supplies), 1280 ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(sgtl5000->supplies),
1281 sgtl5000->supplies); 1281 sgtl5000->supplies);
1282 if (ret) 1282 if (ret)
1283 goto err_ldo_remove; 1283 goto err_ldo_remove;
@@ -1285,13 +1285,16 @@ static int sgtl5000_enable_regulators(struct snd_soc_codec *codec)
1285 ret = regulator_bulk_enable(ARRAY_SIZE(sgtl5000->supplies), 1285 ret = regulator_bulk_enable(ARRAY_SIZE(sgtl5000->supplies),
1286 sgtl5000->supplies); 1286 sgtl5000->supplies);
1287 if (ret) 1287 if (ret)
1288 goto err_ldo_remove; 1288 goto err_regulator_free;
1289 1289
1290 /* wait for all power rails bring up */ 1290 /* wait for all power rails bring up */
1291 udelay(10); 1291 udelay(10);
1292 1292
1293 return 0; 1293 return 0;
1294 1294
1295err_regulator_free:
1296 regulator_bulk_free(ARRAY_SIZE(sgtl5000->supplies),
1297 sgtl5000->supplies);
1295err_ldo_remove: 1298err_ldo_remove:
1296 if (!external_vddd) 1299 if (!external_vddd)
1297 ldo_regulator_remove(codec); 1300 ldo_regulator_remove(codec);
@@ -1361,6 +1364,8 @@ static int sgtl5000_probe(struct snd_soc_codec *codec)
1361err: 1364err:
1362 regulator_bulk_disable(ARRAY_SIZE(sgtl5000->supplies), 1365 regulator_bulk_disable(ARRAY_SIZE(sgtl5000->supplies),
1363 sgtl5000->supplies); 1366 sgtl5000->supplies);
1367 regulator_bulk_free(ARRAY_SIZE(sgtl5000->supplies),
1368 sgtl5000->supplies);
1364 ldo_regulator_remove(codec); 1369 ldo_regulator_remove(codec);
1365 1370
1366 return ret; 1371 return ret;
@@ -1374,6 +1379,8 @@ static int sgtl5000_remove(struct snd_soc_codec *codec)
1374 1379
1375 regulator_bulk_disable(ARRAY_SIZE(sgtl5000->supplies), 1380 regulator_bulk_disable(ARRAY_SIZE(sgtl5000->supplies),
1376 sgtl5000->supplies); 1381 sgtl5000->supplies);
1382 regulator_bulk_free(ARRAY_SIZE(sgtl5000->supplies),
1383 sgtl5000->supplies);
1377 ldo_regulator_remove(codec); 1384 ldo_regulator_remove(codec);
1378 1385
1379 return 0; 1386 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,
879 case SNDRV_PCM_FORMAT_S20_3LE: 879 case SNDRV_PCM_FORMAT_S20_3LE:
880 data |= (0x01 << 4); 880 data |= (0x01 << 4);
881 break; 881 break;
882 case SNDRV_PCM_FORMAT_S24_LE: 882 case SNDRV_PCM_FORMAT_S24_3LE:
883 data |= (0x02 << 4); 883 data |= (0x02 << 4);
884 break; 884 break;
885 case SNDRV_PCM_FORMAT_S32_LE: 885 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)
1596 1596
1597 arizona_init_spk(codec); 1597 arizona_init_spk(codec);
1598 arizona_init_gpio(codec); 1598 arizona_init_gpio(codec);
1599 arizona_init_mono(codec);
1599 1600
1600 ret = snd_soc_add_codec_controls(codec, wm_adsp2_fw_controls, 8); 1601 ret = snd_soc_add_codec_controls(codec, wm_adsp2_fw_controls, 8);
1601 if (ret != 0) 1602 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)
1758 return 0; 1758 return 0;
1759} 1759}
1760EXPORT_SYMBOL_GPL(wm_adsp2_init); 1760EXPORT_SYMBOL_GPL(wm_adsp2_init);
1761
1762MODULE_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
6 tristate 6 tristate
7 7
8config SND_DAVINCI_SOC_MCASP 8config SND_DAVINCI_SOC_MCASP
9 depends on SND_DAVINCI_SOC || SND_OMAP_SOC
9 tristate 10 tristate
10 11
11config SND_DAVINCI_SOC_VCIF 12config 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,
720 720
721 case SNDRV_PCM_FORMAT_U24_LE: 721 case SNDRV_PCM_FORMAT_U24_LE:
722 case SNDRV_PCM_FORMAT_S24_LE: 722 case SNDRV_PCM_FORMAT_S24_LE:
723 dma_params->data_type = 4;
724 word_length = 24;
725 break;
726
723 case SNDRV_PCM_FORMAT_U32_LE: 727 case SNDRV_PCM_FORMAT_U32_LE:
724 case SNDRV_PCM_FORMAT_S32_LE: 728 case SNDRV_PCM_FORMAT_S32_LE:
725 dma_params->data_type = 4; 729 dma_params->data_type = 4;
@@ -1223,14 +1227,22 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
1223 goto err; 1227 goto err;
1224 1228
1225 switch (mcasp->version) { 1229 switch (mcasp->version) {
1230#if IS_BUILTIN(CONFIG_SND_DAVINCI_SOC) || \
1231 (IS_MODULE(CONFIG_SND_DAVINCI_SOC_MCASP) && \
1232 IS_MODULE(CONFIG_SND_DAVINCI_SOC))
1226 case MCASP_VERSION_1: 1233 case MCASP_VERSION_1:
1227 case MCASP_VERSION_2: 1234 case MCASP_VERSION_2:
1228 case MCASP_VERSION_3: 1235 case MCASP_VERSION_3:
1229 ret = davinci_soc_platform_register(&pdev->dev); 1236 ret = davinci_soc_platform_register(&pdev->dev);
1230 break; 1237 break;
1238#endif
1239#if IS_BUILTIN(CONFIG_SND_OMAP_SOC) || \
1240 (IS_MODULE(CONFIG_SND_DAVINCI_SOC_MCASP) && \
1241 IS_MODULE(CONFIG_SND_OMAP_SOC))
1231 case MCASP_VERSION_4: 1242 case MCASP_VERSION_4:
1232 ret = omap_pcm_platform_register(&pdev->dev); 1243 ret = omap_pcm_platform_register(&pdev->dev);
1233 break; 1244 break;
1245#endif
1234 default: 1246 default:
1235 dev_err(&pdev->dev, "Invalid McASP version: %d\n", 1247 dev_err(&pdev->dev, "Invalid McASP version: %d\n",
1236 mcasp->version); 1248 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:
106 xcsr &= ~FSL_SAI_CSR_xF_MASK; 106 xcsr &= ~FSL_SAI_CSR_xF_MASK;
107 107
108 if (flags) 108 if (flags)
109 regmap_write(sai->regmap, FSL_SAI_TCSR, flags | xcsr); 109 regmap_write(sai->regmap, FSL_SAI_RCSR, flags | xcsr);
110 110
111out: 111out:
112 if (irq_none) 112 if (irq_none)
@@ -371,10 +371,13 @@ static int fsl_sai_trigger(struct snd_pcm_substream *substream, int cmd,
371 371
372 /* Check if the opposite FRDE is also disabled */ 372 /* Check if the opposite FRDE is also disabled */
373 if (!(tx ? rcsr & FSL_SAI_CSR_FRDE : tcsr & FSL_SAI_CSR_FRDE)) { 373 if (!(tx ? rcsr & FSL_SAI_CSR_FRDE : tcsr & FSL_SAI_CSR_FRDE)) {
374 /* Disable both directions and reset their FIFOs */
374 regmap_update_bits(sai->regmap, FSL_SAI_TCSR, 375 regmap_update_bits(sai->regmap, FSL_SAI_TCSR,
375 FSL_SAI_CSR_TERE, 0); 376 FSL_SAI_CSR_TERE | FSL_SAI_CSR_FR,
377 FSL_SAI_CSR_FR);
376 regmap_update_bits(sai->regmap, FSL_SAI_RCSR, 378 regmap_update_bits(sai->regmap, FSL_SAI_RCSR,
377 FSL_SAI_CSR_TERE, 0); 379 FSL_SAI_CSR_TERE | FSL_SAI_CSR_FR,
380 FSL_SAI_CSR_FR);
378 } 381 }
379 break; 382 break;
380 default: 383 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,
116{ 116{
117 struct device_node *node; 117 struct device_node *node;
118 struct clk *clk; 118 struct clk *clk;
119 u32 val;
119 int ret; 120 int ret;
120 121
121 /* 122 /*
@@ -151,10 +152,8 @@ asoc_simple_card_sub_parse_of(struct device_node *np,
151 } 152 }
152 153
153 dai->sysclk = clk_get_rate(clk); 154 dai->sysclk = clk_get_rate(clk);
154 } else if (of_property_read_bool(np, "system-clock-frequency")) { 155 } else if (!of_property_read_u32(np, "system-clock-frequency", &val)) {
155 of_property_read_u32(np, 156 dai->sysclk = val;
156 "system-clock-frequency",
157 &dai->sysclk);
158 } else { 157 } else {
159 clk = of_clk_get(node, 0); 158 clk = of_clk_get(node, 0);
160 if (!IS_ERR(clk)) 159 if (!IS_ERR(clk))
@@ -303,6 +302,7 @@ static int asoc_simple_card_parse_of(struct device_node *node,
303{ 302{
304 struct snd_soc_dai_link *dai_link = priv->snd_card.dai_link; 303 struct snd_soc_dai_link *dai_link = priv->snd_card.dai_link;
305 struct simple_dai_props *dai_props = priv->dai_props; 304 struct simple_dai_props *dai_props = priv->dai_props;
305 u32 val;
306 int ret; 306 int ret;
307 307
308 /* parsing the card name from DT */ 308 /* parsing the card name from DT */
@@ -325,8 +325,9 @@ static int asoc_simple_card_parse_of(struct device_node *node,
325 } 325 }
326 326
327 /* Factor to mclk, used in hw_params() */ 327 /* Factor to mclk, used in hw_params() */
328 of_property_read_u32(node, "simple-audio-card,mclk-fs", 328 ret = of_property_read_u32(node, "simple-audio-card,mclk-fs", &val);
329 &priv->mclk_fs); 329 if (ret == 0)
330 priv->mclk_fs = val;
330 331
331 dev_dbg(dev, "New simple-card: %s\n", priv->snd_card.name ? 332 dev_dbg(dev, "New simple-card: %s\n", priv->snd_card.name ?
332 priv->snd_card.name : ""); 333 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[] = {
39 39
40static const struct snd_soc_dapm_route byt_max98090_audio_map[] = { 40static const struct snd_soc_dapm_route byt_max98090_audio_map[] = {
41 {"IN34", NULL, "Headset Mic"}, 41 {"IN34", NULL, "Headset Mic"},
42 {"IN34", NULL, "MICBIAS"}, 42 {"Headset Mic", NULL, "MICBIAS"},
43 {"MICBIAS", NULL, "Headset Mic"},
44 {"DMICL", NULL, "Int Mic"}, 43 {"DMICL", NULL, "Int Mic"},
45 {"Headphone", NULL, "HPL"}, 44 {"Headphone", NULL, "HPL"},
46 {"Headphone", NULL, "HPR"}, 45 {"Headphone", NULL, "HPR"},
@@ -84,7 +83,8 @@ static struct snd_soc_jack_gpio hs_jack_gpios[] = {
84 { 83 {
85 .name = "mic-gpio", 84 .name = "mic-gpio",
86 .idx = 1, 85 .idx = 1,
87 .report = SND_JACK_MICROPHONE | SND_JACK_LINEIN, 86 .invert = 1,
87 .report = SND_JACK_MICROPHONE,
88 .debounce_time = 200, 88 .debounce_time = 200,
89 }, 89 },
90}; 90};
@@ -108,7 +108,8 @@ static int byt_max98090_init(struct snd_soc_pcm_runtime *runtime)
108 } 108 }
109 109
110 /* Enable jack detection */ 110 /* Enable jack detection */
111 ret = snd_soc_jack_new(codec, "Headphone", SND_JACK_HEADPHONE, jack); 111 ret = snd_soc_jack_new(codec, "Headset",
112 SND_JACK_LINEOUT | SND_JACK_HEADSET, jack);
112 if (ret) 113 if (ret)
113 return ret; 114 return ret;
114 115
@@ -117,13 +118,9 @@ static int byt_max98090_init(struct snd_soc_pcm_runtime *runtime)
117 if (ret) 118 if (ret)
118 return ret; 119 return ret;
119 120
120 ret = snd_soc_jack_add_gpiods(card->dev->parent, jack, 121 return snd_soc_jack_add_gpiods(card->dev->parent, jack,
121 ARRAY_SIZE(hs_jack_gpios), 122 ARRAY_SIZE(hs_jack_gpios),
122 hs_jack_gpios); 123 hs_jack_gpios);
123 if (ret)
124 return ret;
125
126 return max98090_mic_detect(codec, jack);
127} 124}
128 125
129static struct snd_soc_dai_link byt_max98090_dais[] = { 126static 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 = {
32 SNDRV_PCM_INFO_PAUSE | 32 SNDRV_PCM_INFO_PAUSE |
33 SNDRV_PCM_INFO_RESUME, 33 SNDRV_PCM_INFO_RESUME,
34 .formats = SNDRV_PCM_FMTBIT_S16_LE | 34 .formats = SNDRV_PCM_FMTBIT_S16_LE |
35 SNDRV_PCM_FORMAT_S24_LE, 35 SNDRV_PCM_FMTBIT_S24_LE,
36 .period_bytes_min = 384, 36 .period_bytes_min = 384,
37 .period_bytes_max = 48000, 37 .period_bytes_max = 48000,
38 .periods_min = 2, 38 .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)
359 return bit; 359 return bit;
360} 360}
361 361
362/*dummy read a SRAM block.*/
363static void sst_mem_block_dummy_read(struct sst_mem_block *block)
364{
365 u32 size;
366 u8 tmp_buf[4];
367 struct sst_dsp *sst = block->dsp;
368
369 size = block->size > 4 ? 4 : block->size;
370 memcpy_fromio(tmp_buf, sst->addr.lpe + block->offset, size);
371}
372
362/* enable 32kB memory block - locks held by caller */ 373/* enable 32kB memory block - locks held by caller */
363static int hsw_block_enable(struct sst_mem_block *block) 374static int hsw_block_enable(struct sst_mem_block *block)
364{ 375{
@@ -378,6 +389,8 @@ static int hsw_block_enable(struct sst_mem_block *block)
378 /* wait 18 DSP clock ticks */ 389 /* wait 18 DSP clock ticks */
379 udelay(10); 390 udelay(10);
380 391
392 /*add a dummy read before the SRAM block is written, otherwise the writing may miss bytes sometimes.*/
393 sst_mem_block_dummy_read(block);
381 return 0; 394 return 0;
382} 395}
383 396
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 = {
80 SNDRV_PCM_INFO_PAUSE | 80 SNDRV_PCM_INFO_PAUSE |
81 SNDRV_PCM_INFO_RESUME | 81 SNDRV_PCM_INFO_RESUME |
82 SNDRV_PCM_INFO_NO_PERIOD_WAKEUP, 82 SNDRV_PCM_INFO_NO_PERIOD_WAKEUP,
83 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FORMAT_S24_LE | 83 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE |
84 SNDRV_PCM_FMTBIT_S32_LE, 84 SNDRV_PCM_FMTBIT_S32_LE,
85 .period_bytes_min = PAGE_SIZE, 85 .period_bytes_min = PAGE_SIZE,
86 .period_bytes_max = (HSW_PCM_PERIODS_MAX / HSW_PCM_PERIODS_MIN) * PAGE_SIZE, 86 .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,
400 sst_hsw_stream_set_valid(hsw, pcm_data->stream, 16); 400 sst_hsw_stream_set_valid(hsw, pcm_data->stream, 16);
401 break; 401 break;
402 case SNDRV_PCM_FORMAT_S24_LE: 402 case SNDRV_PCM_FORMAT_S24_LE:
403 bits = SST_HSW_DEPTH_24BIT; 403 bits = SST_HSW_DEPTH_32BIT;
404 sst_hsw_stream_set_valid(hsw, pcm_data->stream, 24);
405 break;
406 case SNDRV_PCM_FORMAT_S8:
407 bits = SST_HSW_DEPTH_8BIT;
408 sst_hsw_stream_set_valid(hsw, pcm_data->stream, 8);
409 break;
410 case SNDRV_PCM_FORMAT_S32_LE:
411 bits = SST_HSW_DEPTH_32BIT;
404 sst_hsw_stream_set_valid(hsw, pcm_data->stream, 32); 412 sst_hsw_stream_set_valid(hsw, pcm_data->stream, 32);
405 break; 413 break;
406 default: 414 default:
@@ -685,8 +693,9 @@ static int hsw_pcm_new(struct snd_soc_pcm_runtime *rtd)
685} 693}
686 694
687#define HSW_FORMATS \ 695#define HSW_FORMATS \
688 (SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S16_LE |\ 696 (SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S24_LE | \
689 SNDRV_PCM_FMTBIT_S32_LE) 697 SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S16_LE |\
698 SNDRV_PCM_FMTBIT_S8)
690 699
691static struct snd_soc_dai_driver hsw_dais[] = { 700static struct snd_soc_dai_driver hsw_dais[] = {
692 { 701 {
@@ -696,7 +705,7 @@ static struct snd_soc_dai_driver hsw_dais[] = {
696 .channels_min = 2, 705 .channels_min = 2,
697 .channels_max = 2, 706 .channels_max = 2,
698 .rates = SNDRV_PCM_RATE_48000, 707 .rates = SNDRV_PCM_RATE_48000,
699 .formats = SNDRV_PCM_FMTBIT_S16_LE, 708 .formats = SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE,
700 }, 709 },
701 }, 710 },
702 { 711 {
@@ -727,8 +736,8 @@ static struct snd_soc_dai_driver hsw_dais[] = {
727 .stream_name = "Loopback Capture", 736 .stream_name = "Loopback Capture",
728 .channels_min = 2, 737 .channels_min = 2,
729 .channels_max = 2, 738 .channels_max = 2,
730 .rates = SNDRV_PCM_RATE_8000_192000, 739 .rates = SNDRV_PCM_RATE_48000,
731 .formats = HSW_FORMATS, 740 .formats = SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE,
732 }, 741 },
733 }, 742 },
734 { 743 {
@@ -737,8 +746,8 @@ static struct snd_soc_dai_driver hsw_dais[] = {
737 .stream_name = "Analog Capture", 746 .stream_name = "Analog Capture",
738 .channels_min = 2, 747 .channels_min = 2,
739 .channels_max = 2, 748 .channels_max = 2,
740 .rates = SNDRV_PCM_RATE_8000_192000, 749 .rates = SNDRV_PCM_RATE_48000,
741 .formats = HSW_FORMATS, 750 .formats = SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE,
742 }, 751 },
743 }, 752 },
744}; 753};
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:
570 return ret; 570 return ret;
571} 571}
572 572
573static void s6000_i2s_remove(struct platform_device *pdev) 573static int s6000_i2s_remove(struct platform_device *pdev)
574{ 574{
575 struct s6000_i2s_dev *dev = dev_get_drvdata(&pdev->dev); 575 struct s6000_i2s_dev *dev = dev_get_drvdata(&pdev->dev);
576 struct resource *region; 576 struct resource *region;
@@ -597,6 +597,8 @@ static void s6000_i2s_remove(struct platform_device *pdev)
597 iounmap(mmio); 597 iounmap(mmio);
598 region = platform_get_resource(pdev, IORESOURCE_IO, 0); 598 region = platform_get_resource(pdev, IORESOURCE_IO, 0);
599 release_mem_region(region->start, resource_size(region)); 599 release_mem_region(region->start, resource_size(region));
600
601 return 0;
600} 602}
601 603
602static struct platform_driver s6000_i2s_driver = { 604static 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 {
68#define DAI_OPENED (1 << 0) /* Dai is opened */ 68#define DAI_OPENED (1 << 0) /* Dai is opened */
69#define DAI_MANAGER (1 << 1) /* Dai is the manager */ 69#define DAI_MANAGER (1 << 1) /* Dai is the manager */
70 unsigned mode; 70 unsigned mode;
71 /* CDCLK pin direction: 0 - input, 1 - output */
72 unsigned int cdclk_out:1;
71 /* Driver for this DAI */ 73 /* Driver for this DAI */
72 struct snd_soc_dai_driver i2s_dai_drv; 74 struct snd_soc_dai_driver i2s_dai_drv;
73 /* DMA parameters */ 75 /* DMA parameters */
@@ -737,6 +739,9 @@ static int i2s_startup(struct snd_pcm_substream *substream,
737 739
738 spin_unlock_irqrestore(&lock, flags); 740 spin_unlock_irqrestore(&lock, flags);
739 741
742 if (!is_opened(other) && i2s->cdclk_out)
743 i2s_set_sysclk(dai, SAMSUNG_I2S_CDCLK,
744 0, SND_SOC_CLOCK_OUT);
740 return 0; 745 return 0;
741} 746}
742 747
@@ -752,9 +757,13 @@ static void i2s_shutdown(struct snd_pcm_substream *substream,
752 i2s->mode &= ~DAI_OPENED; 757 i2s->mode &= ~DAI_OPENED;
753 i2s->mode &= ~DAI_MANAGER; 758 i2s->mode &= ~DAI_MANAGER;
754 759
755 if (is_opened(other)) 760 if (is_opened(other)) {
756 other->mode |= DAI_MANAGER; 761 other->mode |= DAI_MANAGER;
757 762 } else {
763 u32 mod = readl(i2s->addr + I2SMOD);
764 i2s->cdclk_out = !(mod & MOD_CDCLKCON);
765 other->cdclk_out = i2s->cdclk_out;
766 }
758 /* Reset any constraint on RFS and BFS */ 767 /* Reset any constraint on RFS and BFS */
759 i2s->rfs = 0; 768 i2s->rfs = 0;
760 i2s->bfs = 0; 769 i2s->bfs = 0;
@@ -920,11 +929,9 @@ static int i2s_suspend(struct snd_soc_dai *dai)
920{ 929{
921 struct i2s_dai *i2s = to_info(dai); 930 struct i2s_dai *i2s = to_info(dai);
922 931
923 if (dai->active) { 932 i2s->suspend_i2smod = readl(i2s->addr + I2SMOD);
924 i2s->suspend_i2smod = readl(i2s->addr + I2SMOD); 933 i2s->suspend_i2scon = readl(i2s->addr + I2SCON);
925 i2s->suspend_i2scon = readl(i2s->addr + I2SCON); 934 i2s->suspend_i2spsr = readl(i2s->addr + I2SPSR);
926 i2s->suspend_i2spsr = readl(i2s->addr + I2SPSR);
927 }
928 935
929 return 0; 936 return 0;
930} 937}
@@ -933,11 +940,9 @@ static int i2s_resume(struct snd_soc_dai *dai)
933{ 940{
934 struct i2s_dai *i2s = to_info(dai); 941 struct i2s_dai *i2s = to_info(dai);
935 942
936 if (dai->active) { 943 writel(i2s->suspend_i2scon, i2s->addr + I2SCON);
937 writel(i2s->suspend_i2scon, i2s->addr + I2SCON); 944 writel(i2s->suspend_i2smod, i2s->addr + I2SMOD);
938 writel(i2s->suspend_i2smod, i2s->addr + I2SMOD); 945 writel(i2s->suspend_i2spsr, i2s->addr + I2SPSR);
939 writel(i2s->suspend_i2spsr, i2s->addr + I2SPSR);
940 }
941 946
942 return 0; 947 return 0;
943} 948}
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,
297 for (i = 1; i < MOD_MAX; i++) { 297 for (i = 1; i < MOD_MAX; i++) {
298 if (!src) { 298 if (!src) {
299 mod[i] = ssi; 299 mod[i] = ssi;
300 break;
301 } else if (!dvc) { 300 } else if (!dvc) {
302 mod[i] = src; 301 mod[i] = src;
303 src = NULL; 302 src = NULL;
@@ -308,6 +307,9 @@ static void rsnd_dma_of_name(struct rsnd_dma *dma,
308 307
309 if (mod[i] == this) 308 if (mod[i] == this)
310 index = i; 309 index = i;
310
311 if (mod[i] == ssi)
312 break;
311 } 313 }
312 314
313 if (is_play) { 315 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,
184#define RDMA_CMD_O_N(addr, i) (addr ##_reg - 0x004f8000 + (0x400 * i)) 184#define RDMA_CMD_O_N(addr, i) (addr ##_reg - 0x004f8000 + (0x400 * i))
185#define RDMA_CMD_O_P(addr, i) (addr ##_reg - 0x001f8000 + (0x400 * i)) 185#define RDMA_CMD_O_P(addr, i) (addr ##_reg - 0x001f8000 + (0x400 * i))
186 186
187void rsnd_gen_dma_addr(struct rsnd_priv *priv, 187static void rsnd_gen2_dma_addr(struct rsnd_priv *priv,
188 struct rsnd_dma *dma, 188 struct rsnd_dma *dma,
189 struct dma_slave_config *cfg, 189 struct dma_slave_config *cfg,
190 int is_play, int slave_id) 190 int is_play, int slave_id)
@@ -226,17 +226,6 @@ void rsnd_gen_dma_addr(struct rsnd_priv *priv,
226 } 226 }
227 }; 227 };
228 228
229 cfg->slave_id = slave_id;
230 cfg->src_addr = 0;
231 cfg->dst_addr = 0;
232 cfg->direction = is_play ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM;
233
234 /*
235 * gen1 uses default DMA addr
236 */
237 if (rsnd_is_gen1(priv))
238 return;
239
240 /* it shouldn't happen */ 229 /* it shouldn't happen */
241 if (use_dvc & !use_src) { 230 if (use_dvc & !use_src) {
242 dev_err(dev, "DVC is selected without SRC\n"); 231 dev_err(dev, "DVC is selected without SRC\n");
@@ -250,6 +239,26 @@ void rsnd_gen_dma_addr(struct rsnd_priv *priv,
250 id, cfg->src_addr, cfg->dst_addr); 239 id, cfg->src_addr, cfg->dst_addr);
251} 240}
252 241
242void rsnd_gen_dma_addr(struct rsnd_priv *priv,
243 struct rsnd_dma *dma,
244 struct dma_slave_config *cfg,
245 int is_play, int slave_id)
246{
247 cfg->slave_id = slave_id;
248 cfg->src_addr = 0;
249 cfg->dst_addr = 0;
250 cfg->direction = is_play ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM;
251
252 /*
253 * gen1 uses default DMA addr
254 */
255 if (rsnd_is_gen1(priv))
256 return;
257
258 rsnd_gen2_dma_addr(priv, dma, cfg, is_play, slave_id);
259}
260
261
253/* 262/*
254 * Gen2 263 * Gen2
255 */ 264 */
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 = {
270 .llseek = default_llseek, 270 .llseek = default_llseek,
271}; 271};
272 272
273static struct dentry *soc_debugfs_create_dir(struct dentry *parent,
274 const char *fmt, ...)
275{
276 struct dentry *de;
277 va_list ap;
278 char *s;
279
280 va_start(ap, fmt);
281 s = kvasprintf(GFP_KERNEL, fmt, ap);
282 va_end(ap);
283
284 if (!s)
285 return NULL;
286
287 de = debugfs_create_dir(s, parent);
288 kfree(s);
289
290 return de;
291}
292
273static void soc_init_codec_debugfs(struct snd_soc_codec *codec) 293static void soc_init_codec_debugfs(struct snd_soc_codec *codec)
274{ 294{
275 struct dentry *debugfs_card_root = codec->card->debugfs_card_root; 295 struct dentry *debugfs_card_root = codec->card->debugfs_card_root;
276 296
277 codec->debugfs_codec_root = debugfs_create_dir(codec->name, 297 codec->debugfs_codec_root = soc_debugfs_create_dir(debugfs_card_root,
278 debugfs_card_root); 298 "codec:%s", codec->name);
279 if (!codec->debugfs_codec_root) { 299 if (!codec->debugfs_codec_root) {
280 dev_warn(codec->dev, 300 dev_warn(codec->dev,
281 "ASoC: Failed to create codec debugfs directory\n"); 301 "ASoC: Failed to create codec debugfs directory\n");
@@ -306,8 +326,8 @@ static void soc_init_platform_debugfs(struct snd_soc_platform *platform)
306{ 326{
307 struct dentry *debugfs_card_root = platform->card->debugfs_card_root; 327 struct dentry *debugfs_card_root = platform->card->debugfs_card_root;
308 328
309 platform->debugfs_platform_root = debugfs_create_dir(platform->name, 329 platform->debugfs_platform_root = soc_debugfs_create_dir(debugfs_card_root,
310 debugfs_card_root); 330 "platform:%s", platform->name);
311 if (!platform->debugfs_platform_root) { 331 if (!platform->debugfs_platform_root) {
312 dev_warn(platform->dev, 332 dev_warn(platform->dev,
313 "ASoC: Failed to create platform debugfs directory\n"); 333 "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)
2069 dpcm_be_disconnect(fe, SNDRV_PCM_STREAM_PLAYBACK); 2069 dpcm_be_disconnect(fe, SNDRV_PCM_STREAM_PLAYBACK);
2070 } 2070 }
2071 2071
2072 dpcm_path_put(&list);
2072capture: 2073capture:
2073 /* skip if FE doesn't have capture capability */ 2074 /* skip if FE doesn't have capture capability */
2074 if (!fe->cpu_dai->driver->capture.channels_min) 2075 if (!fe->cpu_dai->driver->capture.channels_min)