aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc')
-rw-r--r--sound/soc/atmel/atmel-pcm-dma.c1
-rw-r--r--sound/soc/atmel/atmel-pcm-pdc.c1
-rw-r--r--sound/soc/bcm/Kconfig1
-rw-r--r--sound/soc/codecs/ad1836.c10
-rw-r--r--sound/soc/codecs/ad193x.c10
-rw-r--r--sound/soc/codecs/adau1373.c10
-rw-r--r--sound/soc/codecs/adau1701.c34
-rw-r--r--sound/soc/codecs/adav80x.c30
-rw-r--r--sound/soc/codecs/alc5623.c10
-rw-r--r--sound/soc/codecs/alc5632.c8
-rw-r--r--sound/soc/codecs/arizona.h17
-rw-r--r--sound/soc/codecs/cs42l51.c14
-rw-r--r--sound/soc/codecs/da7210.c10
-rw-r--r--sound/soc/codecs/da7213.c10
-rw-r--r--sound/soc/codecs/da732x.c10
-rw-r--r--sound/soc/codecs/da9055.c10
-rw-r--r--sound/soc/codecs/isabelle.c6
-rw-r--r--sound/soc/codecs/max98088.c6
-rw-r--r--sound/soc/codecs/max98090.c4
-rw-r--r--sound/soc/codecs/max98095.c6
-rw-r--r--sound/soc/codecs/max9850.c8
-rw-r--r--sound/soc/codecs/mc13783.c34
-rw-r--r--sound/soc/codecs/ssm2602.c14
-rw-r--r--sound/soc/codecs/twl4030.c376
-rw-r--r--sound/soc/codecs/wm_adsp.c199
-rw-r--r--sound/soc/codecs/wm_adsp.h12
-rw-r--r--sound/soc/fsl/Kconfig3
-rw-r--r--sound/soc/fsl/Makefile2
-rw-r--r--sound/soc/fsl/fsl_dma.c7
-rw-r--r--sound/soc/fsl/fsl_esai.c815
-rw-r--r--sound/soc/fsl/fsl_esai.h354
-rw-r--r--sound/soc/fsl/fsl_sai.c7
-rw-r--r--sound/soc/fsl/fsl_ssi.c583
-rw-r--r--sound/soc/fsl/imx-pcm-dma.c3
-rw-r--r--sound/soc/fsl/imx-pcm-fiq.c3
-rw-r--r--sound/soc/fsl/mpc5200_dma.c4
-rw-r--r--sound/soc/generic/simple-card.c70
-rw-r--r--sound/soc/intel/sst_platform.c10
-rw-r--r--sound/soc/intel/sst_platform.h4
-rw-r--r--sound/soc/kirkwood/kirkwood-dma.c16
-rw-r--r--sound/soc/mxs/mxs-pcm.c6
-rw-r--r--sound/soc/nuc900/nuc900-pcm.c3
-rw-r--r--sound/soc/sh/dma-sh7760.c17
-rw-r--r--sound/soc/sh/fsi.c6
-rw-r--r--sound/soc/sh/rcar/core.c6
-rw-r--r--sound/soc/ux500/mop500.c2
-rw-r--r--sound/soc/ux500/ux500_msp_dai.c146
-rw-r--r--sound/soc/ux500/ux500_msp_i2s.c56
-rw-r--r--sound/soc/ux500/ux500_msp_i2s.h2
-rw-r--r--sound/soc/ux500/ux500_pcm.c65
50 files changed, 2138 insertions, 903 deletions
diff --git a/sound/soc/atmel/atmel-pcm-dma.c b/sound/soc/atmel/atmel-pcm-dma.c
index 06082e5e5dcb..b79a2a864513 100644
--- a/sound/soc/atmel/atmel-pcm-dma.c
+++ b/sound/soc/atmel/atmel-pcm-dma.c
@@ -50,7 +50,6 @@ static const struct snd_pcm_hardware atmel_pcm_dma_hardware = {
50 SNDRV_PCM_INFO_INTERLEAVED | 50 SNDRV_PCM_INFO_INTERLEAVED |
51 SNDRV_PCM_INFO_RESUME | 51 SNDRV_PCM_INFO_RESUME |
52 SNDRV_PCM_INFO_PAUSE, 52 SNDRV_PCM_INFO_PAUSE,
53 .formats = SNDRV_PCM_FMTBIT_S16_LE,
54 .period_bytes_min = 256, /* lighting DMA overhead */ 53 .period_bytes_min = 256, /* lighting DMA overhead */
55 .period_bytes_max = 2 * 0xffff, /* if 2 bytes format */ 54 .period_bytes_max = 2 * 0xffff, /* if 2 bytes format */
56 .periods_min = 8, 55 .periods_min = 8,
diff --git a/sound/soc/atmel/atmel-pcm-pdc.c b/sound/soc/atmel/atmel-pcm-pdc.c
index 054ea4d9326a..33ec592ecd75 100644
--- a/sound/soc/atmel/atmel-pcm-pdc.c
+++ b/sound/soc/atmel/atmel-pcm-pdc.c
@@ -58,7 +58,6 @@ static const struct snd_pcm_hardware atmel_pcm_hardware = {
58 SNDRV_PCM_INFO_MMAP_VALID | 58 SNDRV_PCM_INFO_MMAP_VALID |
59 SNDRV_PCM_INFO_INTERLEAVED | 59 SNDRV_PCM_INFO_INTERLEAVED |
60 SNDRV_PCM_INFO_PAUSE, 60 SNDRV_PCM_INFO_PAUSE,
61 .formats = SNDRV_PCM_FMTBIT_S16_LE,
62 .period_bytes_min = 32, 61 .period_bytes_min = 32,
63 .period_bytes_max = 8192, 62 .period_bytes_max = 8192,
64 .periods_min = 2, 63 .periods_min = 2,
diff --git a/sound/soc/bcm/Kconfig b/sound/soc/bcm/Kconfig
index 3d82a29ce3a8..6a834e109f1d 100644
--- a/sound/soc/bcm/Kconfig
+++ b/sound/soc/bcm/Kconfig
@@ -1,7 +1,6 @@
1config SND_BCM2835_SOC_I2S 1config SND_BCM2835_SOC_I2S
2 tristate "SoC Audio support for the Broadcom BCM2835 I2S module" 2 tristate "SoC Audio support for the Broadcom BCM2835 I2S module"
3 depends on ARCH_BCM2835 || COMPILE_TEST 3 depends on ARCH_BCM2835 || COMPILE_TEST
4 select SND_SOC_DMAENGINE_PCM
5 select SND_SOC_GENERIC_DMAENGINE_PCM 4 select SND_SOC_GENERIC_DMAENGINE_PCM
6 select REGMAP_MMIO 5 select REGMAP_MMIO
7 help 6 help
diff --git a/sound/soc/codecs/ad1836.c b/sound/soc/codecs/ad1836.c
index d7c983862cf0..77f459868579 100644
--- a/sound/soc/codecs/ad1836.c
+++ b/sound/soc/codecs/ad1836.c
@@ -168,15 +168,15 @@ static int ad1836_hw_params(struct snd_pcm_substream *substream,
168 int word_len = 0; 168 int word_len = 0;
169 169
170 /* bit size */ 170 /* bit size */
171 switch (params_format(params)) { 171 switch (params_width(params)) {
172 case SNDRV_PCM_FORMAT_S16_LE: 172 case 16:
173 word_len = AD1836_WORD_LEN_16; 173 word_len = AD1836_WORD_LEN_16;
174 break; 174 break;
175 case SNDRV_PCM_FORMAT_S20_3LE: 175 case 20:
176 word_len = AD1836_WORD_LEN_20; 176 word_len = AD1836_WORD_LEN_20;
177 break; 177 break;
178 case SNDRV_PCM_FORMAT_S24_LE: 178 case 24:
179 case SNDRV_PCM_FORMAT_S32_LE: 179 case 32:
180 word_len = AD1836_WORD_LEN_24; 180 word_len = AD1836_WORD_LEN_24;
181 break; 181 break;
182 default: 182 default:
diff --git a/sound/soc/codecs/ad193x.c b/sound/soc/codecs/ad193x.c
index 12c27eb363dd..5a42dca535b7 100644
--- a/sound/soc/codecs/ad193x.c
+++ b/sound/soc/codecs/ad193x.c
@@ -249,15 +249,15 @@ static int ad193x_hw_params(struct snd_pcm_substream *substream,
249 struct ad193x_priv *ad193x = snd_soc_codec_get_drvdata(codec); 249 struct ad193x_priv *ad193x = snd_soc_codec_get_drvdata(codec);
250 250
251 /* bit size */ 251 /* bit size */
252 switch (params_format(params)) { 252 switch (params_width(params)) {
253 case SNDRV_PCM_FORMAT_S16_LE: 253 case 16:
254 word_len = 3; 254 word_len = 3;
255 break; 255 break;
256 case SNDRV_PCM_FORMAT_S20_3LE: 256 case 20:
257 word_len = 1; 257 word_len = 1;
258 break; 258 break;
259 case SNDRV_PCM_FORMAT_S24_LE: 259 case 24:
260 case SNDRV_PCM_FORMAT_S32_LE: 260 case 32:
261 word_len = 0; 261 word_len = 0;
262 break; 262 break;
263 } 263 }
diff --git a/sound/soc/codecs/adau1373.c b/sound/soc/codecs/adau1373.c
index 59654b1e7f3f..eb836ed5271f 100644
--- a/sound/soc/codecs/adau1373.c
+++ b/sound/soc/codecs/adau1373.c
@@ -1078,17 +1078,17 @@ static int adau1373_hw_params(struct snd_pcm_substream *substream,
1078 ADAU1373_BCLKDIV_SR_MASK | ADAU1373_BCLKDIV_BCLK_MASK, 1078 ADAU1373_BCLKDIV_SR_MASK | ADAU1373_BCLKDIV_BCLK_MASK,
1079 (div << 2) | ADAU1373_BCLKDIV_64); 1079 (div << 2) | ADAU1373_BCLKDIV_64);
1080 1080
1081 switch (params_format(params)) { 1081 switch (params_width(params)) {
1082 case SNDRV_PCM_FORMAT_S16_LE: 1082 case 16:
1083 ctrl = ADAU1373_DAI_WLEN_16; 1083 ctrl = ADAU1373_DAI_WLEN_16;
1084 break; 1084 break;
1085 case SNDRV_PCM_FORMAT_S20_3LE: 1085 case 20:
1086 ctrl = ADAU1373_DAI_WLEN_20; 1086 ctrl = ADAU1373_DAI_WLEN_20;
1087 break; 1087 break;
1088 case SNDRV_PCM_FORMAT_S24_LE: 1088 case 24:
1089 ctrl = ADAU1373_DAI_WLEN_24; 1089 ctrl = ADAU1373_DAI_WLEN_24;
1090 break; 1090 break;
1091 case SNDRV_PCM_FORMAT_S32_LE: 1091 case 32:
1092 ctrl = ADAU1373_DAI_WLEN_32; 1092 ctrl = ADAU1373_DAI_WLEN_32;
1093 break; 1093 break;
1094 default: 1094 default:
diff --git a/sound/soc/codecs/adau1701.c b/sound/soc/codecs/adau1701.c
index adee866f463f..d71c59cf7bdd 100644
--- a/sound/soc/codecs/adau1701.c
+++ b/sound/soc/codecs/adau1701.c
@@ -299,20 +299,20 @@ static int adau1701_reset(struct snd_soc_codec *codec, unsigned int clkdiv)
299} 299}
300 300
301static int adau1701_set_capture_pcm_format(struct snd_soc_codec *codec, 301static int adau1701_set_capture_pcm_format(struct snd_soc_codec *codec,
302 snd_pcm_format_t format) 302 struct snd_pcm_hw_params *params)
303{ 303{
304 struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec); 304 struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec);
305 unsigned int mask = ADAU1701_SEROCTL_WORD_LEN_MASK; 305 unsigned int mask = ADAU1701_SEROCTL_WORD_LEN_MASK;
306 unsigned int val; 306 unsigned int val;
307 307
308 switch (format) { 308 switch (params_width(params)) {
309 case SNDRV_PCM_FORMAT_S16_LE: 309 case 16:
310 val = ADAU1701_SEROCTL_WORD_LEN_16; 310 val = ADAU1701_SEROCTL_WORD_LEN_16;
311 break; 311 break;
312 case SNDRV_PCM_FORMAT_S20_3LE: 312 case 20:
313 val = ADAU1701_SEROCTL_WORD_LEN_20; 313 val = ADAU1701_SEROCTL_WORD_LEN_20;
314 break; 314 break;
315 case SNDRV_PCM_FORMAT_S24_LE: 315 case 24:
316 val = ADAU1701_SEROCTL_WORD_LEN_24; 316 val = ADAU1701_SEROCTL_WORD_LEN_24;
317 break; 317 break;
318 default: 318 default:
@@ -320,14 +320,14 @@ static int adau1701_set_capture_pcm_format(struct snd_soc_codec *codec,
320 } 320 }
321 321
322 if (adau1701->dai_fmt == SND_SOC_DAIFMT_RIGHT_J) { 322 if (adau1701->dai_fmt == SND_SOC_DAIFMT_RIGHT_J) {
323 switch (format) { 323 switch (params_width(params)) {
324 case SNDRV_PCM_FORMAT_S16_LE: 324 case 16:
325 val |= ADAU1701_SEROCTL_MSB_DEALY16; 325 val |= ADAU1701_SEROCTL_MSB_DEALY16;
326 break; 326 break;
327 case SNDRV_PCM_FORMAT_S20_3LE: 327 case 20:
328 val |= ADAU1701_SEROCTL_MSB_DEALY12; 328 val |= ADAU1701_SEROCTL_MSB_DEALY12;
329 break; 329 break;
330 case SNDRV_PCM_FORMAT_S24_LE: 330 case 24:
331 val |= ADAU1701_SEROCTL_MSB_DEALY8; 331 val |= ADAU1701_SEROCTL_MSB_DEALY8;
332 break; 332 break;
333 } 333 }
@@ -340,7 +340,7 @@ static int adau1701_set_capture_pcm_format(struct snd_soc_codec *codec,
340} 340}
341 341
342static int adau1701_set_playback_pcm_format(struct snd_soc_codec *codec, 342static int adau1701_set_playback_pcm_format(struct snd_soc_codec *codec,
343 snd_pcm_format_t format) 343 struct snd_pcm_hw_params *params)
344{ 344{
345 struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec); 345 struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec);
346 unsigned int val; 346 unsigned int val;
@@ -348,14 +348,14 @@ static int adau1701_set_playback_pcm_format(struct snd_soc_codec *codec,
348 if (adau1701->dai_fmt != SND_SOC_DAIFMT_RIGHT_J) 348 if (adau1701->dai_fmt != SND_SOC_DAIFMT_RIGHT_J)
349 return 0; 349 return 0;
350 350
351 switch (format) { 351 switch (params_width(params)) {
352 case SNDRV_PCM_FORMAT_S16_LE: 352 case 16:
353 val = ADAU1701_SERICTL_RIGHTJ_16; 353 val = ADAU1701_SERICTL_RIGHTJ_16;
354 break; 354 break;
355 case SNDRV_PCM_FORMAT_S20_3LE: 355 case 20:
356 val = ADAU1701_SERICTL_RIGHTJ_20; 356 val = ADAU1701_SERICTL_RIGHTJ_20;
357 break; 357 break;
358 case SNDRV_PCM_FORMAT_S24_LE: 358 case 24:
359 val = ADAU1701_SERICTL_RIGHTJ_24; 359 val = ADAU1701_SERICTL_RIGHTJ_24;
360 break; 360 break;
361 default: 361 default:
@@ -374,7 +374,6 @@ static int adau1701_hw_params(struct snd_pcm_substream *substream,
374 struct snd_soc_codec *codec = dai->codec; 374 struct snd_soc_codec *codec = dai->codec;
375 struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec); 375 struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec);
376 unsigned int clkdiv = adau1701->sysclk / params_rate(params); 376 unsigned int clkdiv = adau1701->sysclk / params_rate(params);
377 snd_pcm_format_t format;
378 unsigned int val; 377 unsigned int val;
379 int ret; 378 int ret;
380 379
@@ -406,11 +405,10 @@ static int adau1701_hw_params(struct snd_pcm_substream *substream,
406 regmap_update_bits(adau1701->regmap, ADAU1701_DSPCTRL, 405 regmap_update_bits(adau1701->regmap, ADAU1701_DSPCTRL,
407 ADAU1701_DSPCTRL_SR_MASK, val); 406 ADAU1701_DSPCTRL_SR_MASK, val);
408 407
409 format = params_format(params);
410 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 408 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
411 return adau1701_set_playback_pcm_format(codec, format); 409 return adau1701_set_playback_pcm_format(codec, params);
412 else 410 else
413 return adau1701_set_capture_pcm_format(codec, format); 411 return adau1701_set_capture_pcm_format(codec, params);
414} 412}
415 413
416static int adau1701_set_dai_fmt(struct snd_soc_dai *codec_dai, 414static int adau1701_set_dai_fmt(struct snd_soc_dai *codec_dai,
diff --git a/sound/soc/codecs/adav80x.c b/sound/soc/codecs/adav80x.c
index f7bf45552749..f78b27a7c461 100644
--- a/sound/soc/codecs/adav80x.c
+++ b/sound/soc/codecs/adav80x.c
@@ -453,22 +453,22 @@ static int adav80x_set_dac_clock(struct snd_soc_codec *codec,
453} 453}
454 454
455static int adav80x_set_capture_pcm_format(struct snd_soc_codec *codec, 455static int adav80x_set_capture_pcm_format(struct snd_soc_codec *codec,
456 struct snd_soc_dai *dai, snd_pcm_format_t format) 456 struct snd_soc_dai *dai, struct snd_pcm_hw_params *params)
457{ 457{
458 struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec); 458 struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
459 unsigned int val; 459 unsigned int val;
460 460
461 switch (format) { 461 switch (params_width(params)) {
462 case SNDRV_PCM_FORMAT_S16_LE: 462 case 16:
463 val = ADAV80X_CAPTURE_WORD_LEN16; 463 val = ADAV80X_CAPTURE_WORD_LEN16;
464 break; 464 break;
465 case SNDRV_PCM_FORMAT_S18_3LE: 465 case 18:
466 val = ADAV80X_CAPTRUE_WORD_LEN18; 466 val = ADAV80X_CAPTRUE_WORD_LEN18;
467 break; 467 break;
468 case SNDRV_PCM_FORMAT_S20_3LE: 468 case 20:
469 val = ADAV80X_CAPTURE_WORD_LEN20; 469 val = ADAV80X_CAPTURE_WORD_LEN20;
470 break; 470 break;
471 case SNDRV_PCM_FORMAT_S24_LE: 471 case 24:
472 val = ADAV80X_CAPTURE_WORD_LEN24; 472 val = ADAV80X_CAPTURE_WORD_LEN24;
473 break; 473 break;
474 default: 474 default:
@@ -482,7 +482,7 @@ static int adav80x_set_capture_pcm_format(struct snd_soc_codec *codec,
482} 482}
483 483
484static int adav80x_set_playback_pcm_format(struct snd_soc_codec *codec, 484static int adav80x_set_playback_pcm_format(struct snd_soc_codec *codec,
485 struct snd_soc_dai *dai, snd_pcm_format_t format) 485 struct snd_soc_dai *dai, struct snd_pcm_hw_params *params)
486{ 486{
487 struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec); 487 struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
488 unsigned int val; 488 unsigned int val;
@@ -490,17 +490,17 @@ static int adav80x_set_playback_pcm_format(struct snd_soc_codec *codec,
490 if (adav80x->dai_fmt[dai->id] != SND_SOC_DAIFMT_RIGHT_J) 490 if (adav80x->dai_fmt[dai->id] != SND_SOC_DAIFMT_RIGHT_J)
491 return 0; 491 return 0;
492 492
493 switch (format) { 493 switch (params_width(params)) {
494 case SNDRV_PCM_FORMAT_S16_LE: 494 case 16:
495 val = ADAV80X_PLAYBACK_MODE_RIGHT_J_16; 495 val = ADAV80X_PLAYBACK_MODE_RIGHT_J_16;
496 break; 496 break;
497 case SNDRV_PCM_FORMAT_S18_3LE: 497 case 18:
498 val = ADAV80X_PLAYBACK_MODE_RIGHT_J_18; 498 val = ADAV80X_PLAYBACK_MODE_RIGHT_J_18;
499 break; 499 break;
500 case SNDRV_PCM_FORMAT_S20_3LE: 500 case 20:
501 val = ADAV80X_PLAYBACK_MODE_RIGHT_J_20; 501 val = ADAV80X_PLAYBACK_MODE_RIGHT_J_20;
502 break; 502 break;
503 case SNDRV_PCM_FORMAT_S24_LE: 503 case 24:
504 val = ADAV80X_PLAYBACK_MODE_RIGHT_J_24; 504 val = ADAV80X_PLAYBACK_MODE_RIGHT_J_24;
505 break; 505 break;
506 default: 506 default:
@@ -524,12 +524,10 @@ static int adav80x_hw_params(struct snd_pcm_substream *substream,
524 return -EINVAL; 524 return -EINVAL;
525 525
526 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 526 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
527 adav80x_set_playback_pcm_format(codec, dai, 527 adav80x_set_playback_pcm_format(codec, dai, params);
528 params_format(params));
529 adav80x_set_dac_clock(codec, rate); 528 adav80x_set_dac_clock(codec, rate);
530 } else { 529 } else {
531 adav80x_set_capture_pcm_format(codec, dai, 530 adav80x_set_capture_pcm_format(codec, dai, params);
532 params_format(params));
533 adav80x_set_adc_clock(codec, rate); 531 adav80x_set_adc_clock(codec, rate);
534 } 532 }
535 adav80x->rate = rate; 533 adav80x->rate = rate;
diff --git a/sound/soc/codecs/alc5623.c b/sound/soc/codecs/alc5623.c
index 256c364193a5..d3036283482a 100644
--- a/sound/soc/codecs/alc5623.c
+++ b/sound/soc/codecs/alc5623.c
@@ -714,17 +714,17 @@ static int alc5623_pcm_hw_params(struct snd_pcm_substream *substream,
714 iface &= ~ALC5623_DAI_I2S_DL_MASK; 714 iface &= ~ALC5623_DAI_I2S_DL_MASK;
715 715
716 /* bit size */ 716 /* bit size */
717 switch (params_format(params)) { 717 switch (params_width(params)) {
718 case SNDRV_PCM_FORMAT_S16_LE: 718 case 16:
719 iface |= ALC5623_DAI_I2S_DL_16; 719 iface |= ALC5623_DAI_I2S_DL_16;
720 break; 720 break;
721 case SNDRV_PCM_FORMAT_S20_3LE: 721 case 20:
722 iface |= ALC5623_DAI_I2S_DL_20; 722 iface |= ALC5623_DAI_I2S_DL_20;
723 break; 723 break;
724 case SNDRV_PCM_FORMAT_S24_LE: 724 case 24:
725 iface |= ALC5623_DAI_I2S_DL_24; 725 iface |= ALC5623_DAI_I2S_DL_24;
726 break; 726 break;
727 case SNDRV_PCM_FORMAT_S32_LE: 727 case 32:
728 iface |= ALC5623_DAI_I2S_DL_32; 728 iface |= ALC5623_DAI_I2S_DL_32;
729 break; 729 break;
730 default: 730 default:
diff --git a/sound/soc/codecs/alc5632.c b/sound/soc/codecs/alc5632.c
index 19e9f222d09c..fb001c56cf8d 100644
--- a/sound/soc/codecs/alc5632.c
+++ b/sound/soc/codecs/alc5632.c
@@ -869,14 +869,14 @@ static int alc5632_pcm_hw_params(struct snd_pcm_substream *substream,
869 iface &= ~ALC5632_DAI_I2S_DL_MASK; 869 iface &= ~ALC5632_DAI_I2S_DL_MASK;
870 870
871 /* bit size */ 871 /* bit size */
872 switch (params_format(params)) { 872 switch (params_width(params)) {
873 case SNDRV_PCM_FORMAT_S16_LE: 873 case 16:
874 iface |= ALC5632_DAI_I2S_DL_16; 874 iface |= ALC5632_DAI_I2S_DL_16;
875 break; 875 break;
876 case SNDRV_PCM_FORMAT_S20_3LE: 876 case 20:
877 iface |= ALC5632_DAI_I2S_DL_20; 877 iface |= ALC5632_DAI_I2S_DL_20;
878 break; 878 break;
879 case SNDRV_PCM_FORMAT_S24_LE: 879 case 24:
880 iface |= ALC5632_DAI_I2S_DL_24; 880 iface |= ALC5632_DAI_I2S_DL_24;
881 break; 881 break;
882 default: 882 default:
diff --git a/sound/soc/codecs/arizona.h b/sound/soc/codecs/arizona.h
index 10b398477203..16df0f913353 100644
--- a/sound/soc/codecs/arizona.h
+++ b/sound/soc/codecs/arizona.h
@@ -166,20 +166,21 @@ extern int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS];
166 ARIZONA_MIXER_INPUT_ROUTES(name " Input 4") 166 ARIZONA_MIXER_INPUT_ROUTES(name " Input 4")
167 167
168#define ARIZONA_DSP_ROUTES(name) \ 168#define ARIZONA_DSP_ROUTES(name) \
169 { name, NULL, name " Aux 1" }, \ 169 { name, NULL, name " Preloader"}, \
170 { name, NULL, name " Aux 2" }, \ 170 { name " Preloader", NULL, name " Aux 1" }, \
171 { name, NULL, name " Aux 3" }, \ 171 { name " Preloader", NULL, name " Aux 2" }, \
172 { name, NULL, name " Aux 4" }, \ 172 { name " Preloader", NULL, name " Aux 3" }, \
173 { name, NULL, name " Aux 5" }, \ 173 { name " Preloader", NULL, name " Aux 4" }, \
174 { name, NULL, name " Aux 6" }, \ 174 { name " Preloader", NULL, name " Aux 5" }, \
175 { name " Preloader", NULL, name " Aux 6" }, \
175 ARIZONA_MIXER_INPUT_ROUTES(name " Aux 1"), \ 176 ARIZONA_MIXER_INPUT_ROUTES(name " Aux 1"), \
176 ARIZONA_MIXER_INPUT_ROUTES(name " Aux 2"), \ 177 ARIZONA_MIXER_INPUT_ROUTES(name " Aux 2"), \
177 ARIZONA_MIXER_INPUT_ROUTES(name " Aux 3"), \ 178 ARIZONA_MIXER_INPUT_ROUTES(name " Aux 3"), \
178 ARIZONA_MIXER_INPUT_ROUTES(name " Aux 4"), \ 179 ARIZONA_MIXER_INPUT_ROUTES(name " Aux 4"), \
179 ARIZONA_MIXER_INPUT_ROUTES(name " Aux 5"), \ 180 ARIZONA_MIXER_INPUT_ROUTES(name " Aux 5"), \
180 ARIZONA_MIXER_INPUT_ROUTES(name " Aux 6"), \ 181 ARIZONA_MIXER_INPUT_ROUTES(name " Aux 6"), \
181 ARIZONA_MIXER_ROUTES(name, name "L"), \ 182 ARIZONA_MIXER_ROUTES(name " Preloader", name "L"), \
182 ARIZONA_MIXER_ROUTES(name, name "R") 183 ARIZONA_MIXER_ROUTES(name " Preloader", name "R")
183 184
184#define ARIZONA_RATE_ENUM_SIZE 4 185#define ARIZONA_RATE_ENUM_SIZE 4
185extern const char *arizona_rate_text[ARIZONA_RATE_ENUM_SIZE]; 186extern const char *arizona_rate_text[ARIZONA_RATE_ENUM_SIZE];
diff --git a/sound/soc/codecs/cs42l51.c b/sound/soc/codecs/cs42l51.c
index 1e0fa3b5f79a..6e9ea8379a91 100644
--- a/sound/soc/codecs/cs42l51.c
+++ b/sound/soc/codecs/cs42l51.c
@@ -423,21 +423,17 @@ static int cs42l51_hw_params(struct snd_pcm_substream *substream,
423 intf_ctl |= CS42L51_INTF_CTL_DAC_FORMAT(CS42L51_DAC_DIF_LJ24); 423 intf_ctl |= CS42L51_INTF_CTL_DAC_FORMAT(CS42L51_DAC_DIF_LJ24);
424 break; 424 break;
425 case SND_SOC_DAIFMT_RIGHT_J: 425 case SND_SOC_DAIFMT_RIGHT_J:
426 switch (params_format(params)) { 426 switch (params_width(params)) {
427 case SNDRV_PCM_FORMAT_S16_LE: 427 case 16:
428 case SNDRV_PCM_FORMAT_S16_BE:
429 fmt = CS42L51_DAC_DIF_RJ16; 428 fmt = CS42L51_DAC_DIF_RJ16;
430 break; 429 break;
431 case SNDRV_PCM_FORMAT_S18_3LE: 430 case 18:
432 case SNDRV_PCM_FORMAT_S18_3BE:
433 fmt = CS42L51_DAC_DIF_RJ18; 431 fmt = CS42L51_DAC_DIF_RJ18;
434 break; 432 break;
435 case SNDRV_PCM_FORMAT_S20_3LE: 433 case 20:
436 case SNDRV_PCM_FORMAT_S20_3BE:
437 fmt = CS42L51_DAC_DIF_RJ20; 434 fmt = CS42L51_DAC_DIF_RJ20;
438 break; 435 break;
439 case SNDRV_PCM_FORMAT_S24_LE: 436 case 24:
440 case SNDRV_PCM_FORMAT_S24_BE:
441 fmt = CS42L51_DAC_DIF_RJ24; 437 fmt = CS42L51_DAC_DIF_RJ24;
442 break; 438 break;
443 default: 439 default:
diff --git a/sound/soc/codecs/da7210.c b/sound/soc/codecs/da7210.c
index 8166dcb2e4a3..e62e294a8033 100644
--- a/sound/soc/codecs/da7210.c
+++ b/sound/soc/codecs/da7210.c
@@ -778,17 +778,17 @@ static int da7210_hw_params(struct snd_pcm_substream *substream,
778 778
779 dai_cfg1 = 0xFC & snd_soc_read(codec, DA7210_DAI_CFG1); 779 dai_cfg1 = 0xFC & snd_soc_read(codec, DA7210_DAI_CFG1);
780 780
781 switch (params_format(params)) { 781 switch (params_width(params)) {
782 case SNDRV_PCM_FORMAT_S16_LE: 782 case 16:
783 dai_cfg1 |= DA7210_DAI_WORD_S16_LE; 783 dai_cfg1 |= DA7210_DAI_WORD_S16_LE;
784 break; 784 break;
785 case SNDRV_PCM_FORMAT_S20_3LE: 785 case 20:
786 dai_cfg1 |= DA7210_DAI_WORD_S20_3LE; 786 dai_cfg1 |= DA7210_DAI_WORD_S20_3LE;
787 break; 787 break;
788 case SNDRV_PCM_FORMAT_S24_LE: 788 case 24:
789 dai_cfg1 |= DA7210_DAI_WORD_S24_LE; 789 dai_cfg1 |= DA7210_DAI_WORD_S24_LE;
790 break; 790 break;
791 case SNDRV_PCM_FORMAT_S32_LE: 791 case 32:
792 dai_cfg1 |= DA7210_DAI_WORD_S32_LE; 792 dai_cfg1 |= DA7210_DAI_WORD_S32_LE;
793 break; 793 break;
794 default: 794 default:
diff --git a/sound/soc/codecs/da7213.c b/sound/soc/codecs/da7213.c
index 4a6f1daf911f..0c77e7ad7423 100644
--- a/sound/soc/codecs/da7213.c
+++ b/sound/soc/codecs/da7213.c
@@ -1067,17 +1067,17 @@ static int da7213_hw_params(struct snd_pcm_substream *substream,
1067 u8 fs; 1067 u8 fs;
1068 1068
1069 /* Set DAI format */ 1069 /* Set DAI format */
1070 switch (params_format(params)) { 1070 switch (params_width(params)) {
1071 case SNDRV_PCM_FORMAT_S16_LE: 1071 case 16:
1072 dai_ctrl |= DA7213_DAI_WORD_LENGTH_S16_LE; 1072 dai_ctrl |= DA7213_DAI_WORD_LENGTH_S16_LE;
1073 break; 1073 break;
1074 case SNDRV_PCM_FORMAT_S20_3LE: 1074 case 20:
1075 dai_ctrl |= DA7213_DAI_WORD_LENGTH_S20_LE; 1075 dai_ctrl |= DA7213_DAI_WORD_LENGTH_S20_LE;
1076 break; 1076 break;
1077 case SNDRV_PCM_FORMAT_S24_LE: 1077 case 24:
1078 dai_ctrl |= DA7213_DAI_WORD_LENGTH_S24_LE; 1078 dai_ctrl |= DA7213_DAI_WORD_LENGTH_S24_LE;
1079 break; 1079 break;
1080 case SNDRV_PCM_FORMAT_S32_LE: 1080 case 32:
1081 dai_ctrl |= DA7213_DAI_WORD_LENGTH_S32_LE; 1081 dai_ctrl |= DA7213_DAI_WORD_LENGTH_S32_LE;
1082 break; 1082 break;
1083 default: 1083 default:
diff --git a/sound/soc/codecs/da732x.c b/sound/soc/codecs/da732x.c
index dc0284dc9e6f..f295b6569910 100644
--- a/sound/soc/codecs/da732x.c
+++ b/sound/soc/codecs/da732x.c
@@ -973,17 +973,17 @@ static int da732x_hw_params(struct snd_pcm_substream *substream,
973 973
974 reg_aif = dai->driver->base; 974 reg_aif = dai->driver->base;
975 975
976 switch (params_format(params)) { 976 switch (params_width(params)) {
977 case SNDRV_PCM_FORMAT_S16_LE: 977 case 16:
978 aif |= DA732X_AIF_WORD_16; 978 aif |= DA732X_AIF_WORD_16;
979 break; 979 break;
980 case SNDRV_PCM_FORMAT_S20_3LE: 980 case 20:
981 aif |= DA732X_AIF_WORD_20; 981 aif |= DA732X_AIF_WORD_20;
982 break; 982 break;
983 case SNDRV_PCM_FORMAT_S24_LE: 983 case 24:
984 aif |= DA732X_AIF_WORD_24; 984 aif |= DA732X_AIF_WORD_24;
985 break; 985 break;
986 case SNDRV_PCM_FORMAT_S32_LE: 986 case 32:
987 aif |= DA732X_AIF_WORD_32; 987 aif |= DA732X_AIF_WORD_32;
988 break; 988 break;
989 default: 989 default:
diff --git a/sound/soc/codecs/da9055.c b/sound/soc/codecs/da9055.c
index fc9802d1281d..52b79a487ac7 100644
--- a/sound/soc/codecs/da9055.c
+++ b/sound/soc/codecs/da9055.c
@@ -1058,17 +1058,17 @@ static int da9055_hw_params(struct snd_pcm_substream *substream,
1058 u8 aif_ctrl, fs; 1058 u8 aif_ctrl, fs;
1059 u32 sysclk; 1059 u32 sysclk;
1060 1060
1061 switch (params_format(params)) { 1061 switch (params_width(params)) {
1062 case SNDRV_PCM_FORMAT_S16_LE: 1062 case 16:
1063 aif_ctrl = DA9055_AIF_WORD_S16_LE; 1063 aif_ctrl = DA9055_AIF_WORD_S16_LE;
1064 break; 1064 break;
1065 case SNDRV_PCM_FORMAT_S20_3LE: 1065 case 20:
1066 aif_ctrl = DA9055_AIF_WORD_S20_3LE; 1066 aif_ctrl = DA9055_AIF_WORD_S20_3LE;
1067 break; 1067 break;
1068 case SNDRV_PCM_FORMAT_S24_LE: 1068 case 24:
1069 aif_ctrl = DA9055_AIF_WORD_S24_LE; 1069 aif_ctrl = DA9055_AIF_WORD_S24_LE;
1070 break; 1070 break;
1071 case SNDRV_PCM_FORMAT_S32_LE: 1071 case 32:
1072 aif_ctrl = DA9055_AIF_WORD_S32_LE; 1072 aif_ctrl = DA9055_AIF_WORD_S32_LE;
1073 break; 1073 break;
1074 default: 1074 default:
diff --git a/sound/soc/codecs/isabelle.c b/sound/soc/codecs/isabelle.c
index 53b455b8c07a..5839048ec467 100644
--- a/sound/soc/codecs/isabelle.c
+++ b/sound/soc/codecs/isabelle.c
@@ -951,11 +951,11 @@ static int isabelle_hw_params(struct snd_pcm_substream *substream,
951 ISABELLE_FS_RATE_MASK, fs_val); 951 ISABELLE_FS_RATE_MASK, fs_val);
952 952
953 /* bit size */ 953 /* bit size */
954 switch (params_format(params)) { 954 switch (params_width(params)) {
955 case SNDRV_PCM_FORMAT_S20_3LE: 955 case 20:
956 aif |= ISABELLE_AIF_LENGTH_20; 956 aif |= ISABELLE_AIF_LENGTH_20;
957 break; 957 break;
958 case SNDRV_PCM_FORMAT_S32_LE: 958 case 32:
959 aif |= ISABELLE_AIF_LENGTH_32; 959 aif |= ISABELLE_AIF_LENGTH_32;
960 break; 960 break;
961 default: 961 default:
diff --git a/sound/soc/codecs/max98088.c b/sound/soc/codecs/max98088.c
index 53d7dab4e054..ee660e2d3df3 100644
--- a/sound/soc/codecs/max98088.c
+++ b/sound/soc/codecs/max98088.c
@@ -1233,12 +1233,12 @@ static int max98088_dai1_hw_params(struct snd_pcm_substream *substream,
1233 1233
1234 rate = params_rate(params); 1234 rate = params_rate(params);
1235 1235
1236 switch (params_format(params)) { 1236 switch (params_width(params)) {
1237 case SNDRV_PCM_FORMAT_S16_LE: 1237 case 16:
1238 snd_soc_update_bits(codec, M98088_REG_14_DAI1_FORMAT, 1238 snd_soc_update_bits(codec, M98088_REG_14_DAI1_FORMAT,
1239 M98088_DAI_WS, 0); 1239 M98088_DAI_WS, 0);
1240 break; 1240 break;
1241 case SNDRV_PCM_FORMAT_S24_LE: 1241 case 24:
1242 snd_soc_update_bits(codec, M98088_REG_14_DAI1_FORMAT, 1242 snd_soc_update_bits(codec, M98088_REG_14_DAI1_FORMAT,
1243 M98088_DAI_WS, M98088_DAI_WS); 1243 M98088_DAI_WS, M98088_DAI_WS);
1244 break; 1244 break;
diff --git a/sound/soc/codecs/max98090.c b/sound/soc/codecs/max98090.c
index 0569a4c3ae00..51f9b3d16b41 100644
--- a/sound/soc/codecs/max98090.c
+++ b/sound/soc/codecs/max98090.c
@@ -1840,8 +1840,8 @@ static int max98090_dai_hw_params(struct snd_pcm_substream *substream,
1840 1840
1841 max98090->lrclk = params_rate(params); 1841 max98090->lrclk = params_rate(params);
1842 1842
1843 switch (params_format(params)) { 1843 switch (params_width(params)) {
1844 case SNDRV_PCM_FORMAT_S16_LE: 1844 case 16:
1845 snd_soc_update_bits(codec, M98090_REG_INTERFACE_FORMAT, 1845 snd_soc_update_bits(codec, M98090_REG_INTERFACE_FORMAT,
1846 M98090_WS_MASK, 0); 1846 M98090_WS_MASK, 0);
1847 break; 1847 break;
diff --git a/sound/soc/codecs/max98095.c b/sound/soc/codecs/max98095.c
index 67244315c721..3ba1170ebb53 100644
--- a/sound/soc/codecs/max98095.c
+++ b/sound/soc/codecs/max98095.c
@@ -1213,12 +1213,12 @@ static int max98095_dai1_hw_params(struct snd_pcm_substream *substream,
1213 1213
1214 rate = params_rate(params); 1214 rate = params_rate(params);
1215 1215
1216 switch (params_format(params)) { 1216 switch (params_width(params)) {
1217 case SNDRV_PCM_FORMAT_S16_LE: 1217 case 16:
1218 snd_soc_update_bits(codec, M98095_02A_DAI1_FORMAT, 1218 snd_soc_update_bits(codec, M98095_02A_DAI1_FORMAT,
1219 M98095_DAI_WS, 0); 1219 M98095_DAI_WS, 0);
1220 break; 1220 break;
1221 case SNDRV_PCM_FORMAT_S24_LE: 1221 case 24:
1222 snd_soc_update_bits(codec, M98095_02A_DAI1_FORMAT, 1222 snd_soc_update_bits(codec, M98095_02A_DAI1_FORMAT,
1223 M98095_DAI_WS, M98095_DAI_WS); 1223 M98095_DAI_WS, M98095_DAI_WS);
1224 break; 1224 break;
diff --git a/sound/soc/codecs/max9850.c b/sound/soc/codecs/max9850.c
index c5dd61785f8d..82757ebf0301 100644
--- a/sound/soc/codecs/max9850.c
+++ b/sound/soc/codecs/max9850.c
@@ -149,14 +149,14 @@ static int max9850_hw_params(struct snd_pcm_substream *substream,
149 snd_soc_write(codec, MAX9850_LRCLK_MSB, (lrclk_div >> 8) & 0x7f); 149 snd_soc_write(codec, MAX9850_LRCLK_MSB, (lrclk_div >> 8) & 0x7f);
150 snd_soc_write(codec, MAX9850_LRCLK_LSB, lrclk_div & 0xff); 150 snd_soc_write(codec, MAX9850_LRCLK_LSB, lrclk_div & 0xff);
151 151
152 switch (params_format(params)) { 152 switch (params_width(params)) {
153 case SNDRV_PCM_FORMAT_S16_LE: 153 case 16:
154 da = 0; 154 da = 0;
155 break; 155 break;
156 case SNDRV_PCM_FORMAT_S20_3LE: 156 case 20:
157 da = 0x2; 157 da = 0x2;
158 break; 158 break;
159 case SNDRV_PCM_FORMAT_S24_LE: 159 case 24:
160 da = 0x3; 160 da = 0x3;
161 break; 161 break;
162 default: 162 default:
diff --git a/sound/soc/codecs/mc13783.c b/sound/soc/codecs/mc13783.c
index bae60164c7b7..582c2bbd42cb 100644
--- a/sound/soc/codecs/mc13783.c
+++ b/sound/soc/codecs/mc13783.c
@@ -750,30 +750,26 @@ static struct snd_soc_codec_driver soc_codec_dev_mc13783 = {
750 .num_dapm_routes = ARRAY_SIZE(mc13783_routes), 750 .num_dapm_routes = ARRAY_SIZE(mc13783_routes),
751}; 751};
752 752
753static int mc13783_codec_probe(struct platform_device *pdev) 753static int __init mc13783_codec_probe(struct platform_device *pdev)
754{ 754{
755 struct mc13xxx *mc13xxx;
756 struct mc13783_priv *priv; 755 struct mc13783_priv *priv;
757 struct mc13xxx_codec_platform_data *pdata = pdev->dev.platform_data; 756 struct mc13xxx_codec_platform_data *pdata = pdev->dev.platform_data;
758 int ret; 757 int ret;
759 758
760 mc13xxx = dev_get_drvdata(pdev->dev.parent);
761
762
763 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); 759 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
764 if (priv == NULL) 760 if (!priv)
765 return -ENOMEM; 761 return -ENOMEM;
766 762
767 dev_set_drvdata(&pdev->dev, priv);
768 priv->mc13xxx = mc13xxx;
769 if (pdata) { 763 if (pdata) {
770 priv->adc_ssi_port = pdata->adc_ssi_port; 764 priv->adc_ssi_port = pdata->adc_ssi_port;
771 priv->dac_ssi_port = pdata->dac_ssi_port; 765 priv->dac_ssi_port = pdata->dac_ssi_port;
772 } else { 766 } else {
773 priv->adc_ssi_port = MC13783_SSI1_PORT; 767 return -ENOSYS;
774 priv->dac_ssi_port = MC13783_SSI2_PORT;
775 } 768 }
776 769
770 dev_set_drvdata(&pdev->dev, priv);
771 priv->mc13xxx = dev_get_drvdata(pdev->dev.parent);
772
777 if (priv->adc_ssi_port == priv->dac_ssi_port) 773 if (priv->adc_ssi_port == priv->dac_ssi_port)
778 ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_mc13783, 774 ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_mc13783,
779 mc13783_dai_sync, ARRAY_SIZE(mc13783_dai_sync)); 775 mc13783_dai_sync, ARRAY_SIZE(mc13783_dai_sync));
@@ -781,14 +777,6 @@ static int mc13783_codec_probe(struct platform_device *pdev)
781 ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_mc13783, 777 ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_mc13783,
782 mc13783_dai_async, ARRAY_SIZE(mc13783_dai_async)); 778 mc13783_dai_async, ARRAY_SIZE(mc13783_dai_async));
783 779
784 if (ret)
785 goto err_register_codec;
786
787 return 0;
788
789err_register_codec:
790 dev_err(&pdev->dev, "register codec failed with %d\n", ret);
791
792 return ret; 780 return ret;
793} 781}
794 782
@@ -801,14 +789,12 @@ static int mc13783_codec_remove(struct platform_device *pdev)
801 789
802static struct platform_driver mc13783_codec_driver = { 790static struct platform_driver mc13783_codec_driver = {
803 .driver = { 791 .driver = {
804 .name = "mc13783-codec", 792 .name = "mc13783-codec",
805 .owner = THIS_MODULE, 793 .owner = THIS_MODULE,
806 }, 794 },
807 .probe = mc13783_codec_probe,
808 .remove = mc13783_codec_remove, 795 .remove = mc13783_codec_remove,
809}; 796};
810 797module_platform_driver_probe(mc13783_codec_driver, mc13783_codec_probe);
811module_platform_driver(mc13783_codec_driver);
812 798
813MODULE_DESCRIPTION("ASoC MC13783 driver"); 799MODULE_DESCRIPTION("ASoC MC13783 driver");
814MODULE_AUTHOR("Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>"); 800MODULE_AUTHOR("Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>");
diff --git a/sound/soc/codecs/ssm2602.c b/sound/soc/codecs/ssm2602.c
index c6dd48561884..af76bbd1b24f 100644
--- a/sound/soc/codecs/ssm2602.c
+++ b/sound/soc/codecs/ssm2602.c
@@ -194,7 +194,7 @@ static const struct snd_soc_dapm_route ssm2604_routes[] = {
194}; 194};
195 195
196static const unsigned int ssm2602_rates_12288000[] = { 196static const unsigned int ssm2602_rates_12288000[] = {
197 8000, 32000, 48000, 96000, 197 8000, 16000, 32000, 48000, 96000,
198}; 198};
199 199
200static struct snd_pcm_hw_constraint_list ssm2602_constraints_12288000 = { 200static struct snd_pcm_hw_constraint_list ssm2602_constraints_12288000 = {
@@ -231,6 +231,11 @@ static const struct ssm2602_coeff ssm2602_coeff_table[] = {
231 {18432000, 32000, SSM2602_COEFF_SRATE(0x6, 0x1, 0x0)}, 231 {18432000, 32000, SSM2602_COEFF_SRATE(0x6, 0x1, 0x0)},
232 {12000000, 32000, SSM2602_COEFF_SRATE(0x6, 0x0, 0x1)}, 232 {12000000, 32000, SSM2602_COEFF_SRATE(0x6, 0x0, 0x1)},
233 233
234 /* 16k */
235 {12288000, 16000, SSM2602_COEFF_SRATE(0x5, 0x0, 0x0)},
236 {18432000, 16000, SSM2602_COEFF_SRATE(0x5, 0x1, 0x0)},
237 {12000000, 16000, SSM2602_COEFF_SRATE(0xa, 0x0, 0x1)},
238
234 /* 8k */ 239 /* 8k */
235 {12288000, 8000, SSM2602_COEFF_SRATE(0x3, 0x0, 0x0)}, 240 {12288000, 8000, SSM2602_COEFF_SRATE(0x3, 0x0, 0x0)},
236 {18432000, 8000, SSM2602_COEFF_SRATE(0x3, 0x1, 0x0)}, 241 {18432000, 8000, SSM2602_COEFF_SRATE(0x3, 0x1, 0x0)},
@@ -473,9 +478,10 @@ static int ssm2602_set_bias_level(struct snd_soc_codec *codec,
473 return 0; 478 return 0;
474} 479}
475 480
476#define SSM2602_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_32000 |\ 481#define SSM2602_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
477 SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |\ 482 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\
478 SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000) 483 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |\
484 SNDRV_PCM_RATE_96000)
479 485
480#define SSM2602_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ 486#define SSM2602_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
481 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) 487 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c
index dfc51bb425da..00665ada23e2 100644
--- a/sound/soc/codecs/twl4030.c
+++ b/sound/soc/codecs/twl4030.c
@@ -48,86 +48,6 @@
48 48
49#define TWL4030_CACHEREGNUM (TWL4030_REG_MISC_SET_2 + 1) 49#define TWL4030_CACHEREGNUM (TWL4030_REG_MISC_SET_2 + 1)
50 50
51/*
52 * twl4030 register cache & default register settings
53 */
54static const u8 twl4030_reg[TWL4030_CACHEREGNUM] = {
55 0x00, /* this register not used */
56 0x00, /* REG_CODEC_MODE (0x1) */
57 0x00, /* REG_OPTION (0x2) */
58 0x00, /* REG_UNKNOWN (0x3) */
59 0x00, /* REG_MICBIAS_CTL (0x4) */
60 0x00, /* REG_ANAMICL (0x5) */
61 0x00, /* REG_ANAMICR (0x6) */
62 0x00, /* REG_AVADC_CTL (0x7) */
63 0x00, /* REG_ADCMICSEL (0x8) */
64 0x00, /* REG_DIGMIXING (0x9) */
65 0x0f, /* REG_ATXL1PGA (0xA) */
66 0x0f, /* REG_ATXR1PGA (0xB) */
67 0x0f, /* REG_AVTXL2PGA (0xC) */
68 0x0f, /* REG_AVTXR2PGA (0xD) */
69 0x00, /* REG_AUDIO_IF (0xE) */
70 0x00, /* REG_VOICE_IF (0xF) */
71 0x3f, /* REG_ARXR1PGA (0x10) */
72 0x3f, /* REG_ARXL1PGA (0x11) */
73 0x3f, /* REG_ARXR2PGA (0x12) */
74 0x3f, /* REG_ARXL2PGA (0x13) */
75 0x25, /* REG_VRXPGA (0x14) */
76 0x00, /* REG_VSTPGA (0x15) */
77 0x00, /* REG_VRX2ARXPGA (0x16) */
78 0x00, /* REG_AVDAC_CTL (0x17) */
79 0x00, /* REG_ARX2VTXPGA (0x18) */
80 0x32, /* REG_ARXL1_APGA_CTL (0x19) */
81 0x32, /* REG_ARXR1_APGA_CTL (0x1A) */
82 0x32, /* REG_ARXL2_APGA_CTL (0x1B) */
83 0x32, /* REG_ARXR2_APGA_CTL (0x1C) */
84 0x00, /* REG_ATX2ARXPGA (0x1D) */
85 0x00, /* REG_BT_IF (0x1E) */
86 0x55, /* REG_BTPGA (0x1F) */
87 0x00, /* REG_BTSTPGA (0x20) */
88 0x00, /* REG_EAR_CTL (0x21) */
89 0x00, /* REG_HS_SEL (0x22) */
90 0x00, /* REG_HS_GAIN_SET (0x23) */
91 0x00, /* REG_HS_POPN_SET (0x24) */
92 0x00, /* REG_PREDL_CTL (0x25) */
93 0x00, /* REG_PREDR_CTL (0x26) */
94 0x00, /* REG_PRECKL_CTL (0x27) */
95 0x00, /* REG_PRECKR_CTL (0x28) */
96 0x00, /* REG_HFL_CTL (0x29) */
97 0x00, /* REG_HFR_CTL (0x2A) */
98 0x05, /* REG_ALC_CTL (0x2B) */
99 0x00, /* REG_ALC_SET1 (0x2C) */
100 0x00, /* REG_ALC_SET2 (0x2D) */
101 0x00, /* REG_BOOST_CTL (0x2E) */
102 0x00, /* REG_SOFTVOL_CTL (0x2F) */
103 0x13, /* REG_DTMF_FREQSEL (0x30) */
104 0x00, /* REG_DTMF_TONEXT1H (0x31) */
105 0x00, /* REG_DTMF_TONEXT1L (0x32) */
106 0x00, /* REG_DTMF_TONEXT2H (0x33) */
107 0x00, /* REG_DTMF_TONEXT2L (0x34) */
108 0x79, /* REG_DTMF_TONOFF (0x35) */
109 0x11, /* REG_DTMF_WANONOFF (0x36) */
110 0x00, /* REG_I2S_RX_SCRAMBLE_H (0x37) */
111 0x00, /* REG_I2S_RX_SCRAMBLE_M (0x38) */
112 0x00, /* REG_I2S_RX_SCRAMBLE_L (0x39) */
113 0x06, /* REG_APLL_CTL (0x3A) */
114 0x00, /* REG_DTMF_CTL (0x3B) */
115 0x44, /* REG_DTMF_PGA_CTL2 (0x3C) */
116 0x69, /* REG_DTMF_PGA_CTL1 (0x3D) */
117 0x00, /* REG_MISC_SET_1 (0x3E) */
118 0x00, /* REG_PCMBTMUX (0x3F) */
119 0x00, /* not used (0x40) */
120 0x00, /* not used (0x41) */
121 0x00, /* not used (0x42) */
122 0x00, /* REG_RX_PATH_SEL (0x43) */
123 0x32, /* REG_VDL_APGA_CTL (0x44) */
124 0x00, /* REG_VIBRA_CTL (0x45) */
125 0x00, /* REG_VIBRA_SET (0x46) */
126 0x00, /* REG_VIBRA_PWM_SET (0x47) */
127 0x00, /* REG_ANAMIC_GAIN (0x48) */
128 0x00, /* REG_MISC_SET_2 (0x49) */
129};
130
131/* codec private data */ 51/* codec private data */
132struct twl4030_priv { 52struct twl4030_priv {
133 unsigned int codec_powered; 53 unsigned int codec_powered;
@@ -150,81 +70,108 @@ struct twl4030_priv {
150 u8 earpiece_enabled; 70 u8 earpiece_enabled;
151 u8 predrivel_enabled, predriver_enabled; 71 u8 predrivel_enabled, predriver_enabled;
152 u8 carkitl_enabled, carkitr_enabled; 72 u8 carkitl_enabled, carkitr_enabled;
73 u8 ctl_cache[TWL4030_REG_PRECKR_CTL - TWL4030_REG_EAR_CTL + 1];
153 74
154 struct twl4030_codec_data *pdata; 75 struct twl4030_codec_data *pdata;
155}; 76};
156 77
157/* 78static void tw4030_init_ctl_cache(struct twl4030_priv *twl4030)
158 * read twl4030 register cache
159 */
160static inline unsigned int twl4030_read_reg_cache(struct snd_soc_codec *codec,
161 unsigned int reg)
162{ 79{
163 u8 *cache = codec->reg_cache; 80 int i;
164 81 u8 byte;
165 if (reg >= TWL4030_CACHEREGNUM)
166 return -EIO;
167 82
168 return cache[reg]; 83 for (i = TWL4030_REG_EAR_CTL; i <= TWL4030_REG_PRECKR_CTL; i++) {
84 twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &byte, i);
85 twl4030->ctl_cache[i - TWL4030_REG_EAR_CTL] = byte;
86 }
169} 87}
170 88
171/* 89static unsigned int twl4030_read(struct snd_soc_codec *codec, unsigned int reg)
172 * write twl4030 register cache
173 */
174static inline void twl4030_write_reg_cache(struct snd_soc_codec *codec,
175 u8 reg, u8 value)
176{ 90{
177 u8 *cache = codec->reg_cache; 91 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
92 u8 value = 0;
178 93
179 if (reg >= TWL4030_CACHEREGNUM) 94 if (reg >= TWL4030_CACHEREGNUM)
180 return; 95 return -EIO;
181 cache[reg] = value; 96
97 switch (reg) {
98 case TWL4030_REG_EAR_CTL:
99 case TWL4030_REG_PREDL_CTL:
100 case TWL4030_REG_PREDR_CTL:
101 case TWL4030_REG_PRECKL_CTL:
102 case TWL4030_REG_PRECKR_CTL:
103 case TWL4030_REG_HS_GAIN_SET:
104 value = twl4030->ctl_cache[reg - TWL4030_REG_EAR_CTL];
105 break;
106 default:
107 twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &value, reg);
108 break;
109 }
110
111 return value;
182} 112}
183 113
184/* 114static bool twl4030_can_write_to_chip(struct twl4030_priv *twl4030,
185 * write to the twl4030 register space 115 unsigned int reg)
186 */
187static int twl4030_write(struct snd_soc_codec *codec,
188 unsigned int reg, unsigned int value)
189{ 116{
190 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); 117 bool write_to_reg = false;
191 int write_to_reg = 0;
192 118
193 twl4030_write_reg_cache(codec, reg, value);
194 /* Decide if the given register can be written */ 119 /* Decide if the given register can be written */
195 switch (reg) { 120 switch (reg) {
196 case TWL4030_REG_EAR_CTL: 121 case TWL4030_REG_EAR_CTL:
197 if (twl4030->earpiece_enabled) 122 if (twl4030->earpiece_enabled)
198 write_to_reg = 1; 123 write_to_reg = true;
199 break; 124 break;
200 case TWL4030_REG_PREDL_CTL: 125 case TWL4030_REG_PREDL_CTL:
201 if (twl4030->predrivel_enabled) 126 if (twl4030->predrivel_enabled)
202 write_to_reg = 1; 127 write_to_reg = true;
203 break; 128 break;
204 case TWL4030_REG_PREDR_CTL: 129 case TWL4030_REG_PREDR_CTL:
205 if (twl4030->predriver_enabled) 130 if (twl4030->predriver_enabled)
206 write_to_reg = 1; 131 write_to_reg = true;
207 break; 132 break;
208 case TWL4030_REG_PRECKL_CTL: 133 case TWL4030_REG_PRECKL_CTL:
209 if (twl4030->carkitl_enabled) 134 if (twl4030->carkitl_enabled)
210 write_to_reg = 1; 135 write_to_reg = true;
211 break; 136 break;
212 case TWL4030_REG_PRECKR_CTL: 137 case TWL4030_REG_PRECKR_CTL:
213 if (twl4030->carkitr_enabled) 138 if (twl4030->carkitr_enabled)
214 write_to_reg = 1; 139 write_to_reg = true;
215 break; 140 break;
216 case TWL4030_REG_HS_GAIN_SET: 141 case TWL4030_REG_HS_GAIN_SET:
217 if (twl4030->hsl_enabled || twl4030->hsr_enabled) 142 if (twl4030->hsl_enabled || twl4030->hsr_enabled)
218 write_to_reg = 1; 143 write_to_reg = true;
219 break; 144 break;
220 default: 145 default:
221 /* All other register can be written */ 146 /* All other register can be written */
222 write_to_reg = 1; 147 write_to_reg = true;
148 break;
149 }
150
151 return write_to_reg;
152}
153
154static int twl4030_write(struct snd_soc_codec *codec, unsigned int reg,
155 unsigned int value)
156{
157 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
158
159 /* Update the ctl cache */
160 switch (reg) {
161 case TWL4030_REG_EAR_CTL:
162 case TWL4030_REG_PREDL_CTL:
163 case TWL4030_REG_PREDR_CTL:
164 case TWL4030_REG_PRECKL_CTL:
165 case TWL4030_REG_PRECKR_CTL:
166 case TWL4030_REG_HS_GAIN_SET:
167 twl4030->ctl_cache[reg - TWL4030_REG_EAR_CTL] = value;
168 break;
169 default:
223 break; 170 break;
224 } 171 }
225 if (write_to_reg) 172
226 return twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, 173 if (twl4030_can_write_to_chip(twl4030, reg))
227 value, reg); 174 return twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, value, reg);
228 175
229 return 0; 176 return 0;
230} 177}
@@ -252,46 +199,14 @@ static void twl4030_codec_enable(struct snd_soc_codec *codec, int enable)
252 else 199 else
253 mode = twl4030_audio_disable_resource(TWL4030_AUDIO_RES_POWER); 200 mode = twl4030_audio_disable_resource(TWL4030_AUDIO_RES_POWER);
254 201
255 if (mode >= 0) { 202 if (mode >= 0)
256 twl4030_write_reg_cache(codec, TWL4030_REG_CODEC_MODE, mode);
257 twl4030->codec_powered = enable; 203 twl4030->codec_powered = enable;
258 }
259 204
260 /* REVISIT: this delay is present in TI sample drivers */ 205 /* REVISIT: this delay is present in TI sample drivers */
261 /* but there seems to be no TRM requirement for it */ 206 /* but there seems to be no TRM requirement for it */
262 udelay(10); 207 udelay(10);
263} 208}
264 209
265static inline void twl4030_check_defaults(struct snd_soc_codec *codec)
266{
267 int i, difference = 0;
268 u8 val;
269
270 dev_dbg(codec->dev, "Checking TWL audio default configuration\n");
271 for (i = 1; i <= TWL4030_REG_MISC_SET_2; i++) {
272 twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &val, i);
273 if (val != twl4030_reg[i]) {
274 difference++;
275 dev_dbg(codec->dev,
276 "Reg 0x%02x: chip: 0x%02x driver: 0x%02x\n",
277 i, val, twl4030_reg[i]);
278 }
279 }
280 dev_dbg(codec->dev, "Found %d non-matching registers. %s\n",
281 difference, difference ? "Not OK" : "OK");
282}
283
284static inline void twl4030_reset_registers(struct snd_soc_codec *codec)
285{
286 int i;
287
288 /* set all audio section registers to reasonable defaults */
289 for (i = TWL4030_REG_OPTION; i <= TWL4030_REG_MISC_SET_2; i++)
290 if (i != TWL4030_REG_APLL_CTL)
291 twl4030_write(codec, i, twl4030_reg[i]);
292
293}
294
295static void twl4030_setup_pdata_of(struct twl4030_codec_data *pdata, 210static void twl4030_setup_pdata_of(struct twl4030_codec_data *pdata,
296 struct device_node *node) 211 struct device_node *node)
297{ 212{
@@ -372,27 +287,17 @@ static void twl4030_init_chip(struct snd_soc_codec *codec)
372 } 287 }
373 } 288 }
374 289
375 /* Check defaults, if instructed before anything else */ 290 /* Initialize the local ctl register cache */
376 if (pdata && pdata->check_defaults) 291 tw4030_init_ctl_cache(twl4030);
377 twl4030_check_defaults(codec);
378
379 /* Reset registers, if no setup data or if instructed to do so */
380 if (!pdata || (pdata && pdata->reset_registers))
381 twl4030_reset_registers(codec);
382
383 /* Refresh APLL_CTL register from HW */
384 twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &byte,
385 TWL4030_REG_APLL_CTL);
386 twl4030_write_reg_cache(codec, TWL4030_REG_APLL_CTL, byte);
387 292
388 /* anti-pop when changing analog gain */ 293 /* anti-pop when changing analog gain */
389 reg = twl4030_read_reg_cache(codec, TWL4030_REG_MISC_SET_1); 294 reg = twl4030_read(codec, TWL4030_REG_MISC_SET_1);
390 twl4030_write(codec, TWL4030_REG_MISC_SET_1, 295 twl4030_write(codec, TWL4030_REG_MISC_SET_1,
391 reg | TWL4030_SMOOTH_ANAVOL_EN); 296 reg | TWL4030_SMOOTH_ANAVOL_EN);
392 297
393 twl4030_write(codec, TWL4030_REG_OPTION, 298 twl4030_write(codec, TWL4030_REG_OPTION,
394 TWL4030_ATXL1_EN | TWL4030_ATXR1_EN | 299 TWL4030_ATXL1_EN | TWL4030_ATXR1_EN |
395 TWL4030_ARXL2_EN | TWL4030_ARXR2_EN); 300 TWL4030_ARXL2_EN | TWL4030_ARXR2_EN);
396 301
397 /* REG_ARXR2_APGA_CTL reset according to the TRM: 0dB, DA_EN */ 302 /* REG_ARXR2_APGA_CTL reset according to the TRM: 0dB, DA_EN */
398 twl4030_write(codec, TWL4030_REG_ARXR2_APGA_CTL, 0x32); 303 twl4030_write(codec, TWL4030_REG_ARXR2_APGA_CTL, 0x32);
@@ -403,19 +308,19 @@ static void twl4030_init_chip(struct snd_soc_codec *codec)
403 308
404 twl4030->pdata = pdata; 309 twl4030->pdata = pdata;
405 310
406 reg = twl4030_read_reg_cache(codec, TWL4030_REG_HS_POPN_SET); 311 reg = twl4030_read(codec, TWL4030_REG_HS_POPN_SET);
407 reg &= ~TWL4030_RAMP_DELAY; 312 reg &= ~TWL4030_RAMP_DELAY;
408 reg |= (pdata->ramp_delay_value << 2); 313 reg |= (pdata->ramp_delay_value << 2);
409 twl4030_write_reg_cache(codec, TWL4030_REG_HS_POPN_SET, reg); 314 twl4030_write(codec, TWL4030_REG_HS_POPN_SET, reg);
410 315
411 /* initiate offset cancellation */ 316 /* initiate offset cancellation */
412 twl4030_codec_enable(codec, 1); 317 twl4030_codec_enable(codec, 1);
413 318
414 reg = twl4030_read_reg_cache(codec, TWL4030_REG_ANAMICL); 319 reg = twl4030_read(codec, TWL4030_REG_ANAMICL);
415 reg &= ~TWL4030_OFFSET_CNCL_SEL; 320 reg &= ~TWL4030_OFFSET_CNCL_SEL;
416 reg |= pdata->offset_cncl_path; 321 reg |= pdata->offset_cncl_path;
417 twl4030_write(codec, TWL4030_REG_ANAMICL, 322 twl4030_write(codec, TWL4030_REG_ANAMICL,
418 reg | TWL4030_CNCL_OFFSET_START); 323 reg | TWL4030_CNCL_OFFSET_START);
419 324
420 /* 325 /*
421 * Wait for offset cancellation to complete. 326 * Wait for offset cancellation to complete.
@@ -425,15 +330,14 @@ static void twl4030_init_chip(struct snd_soc_codec *codec)
425 msleep(20); 330 msleep(20);
426 do { 331 do {
427 usleep_range(1000, 2000); 332 usleep_range(1000, 2000);
333 twl_set_regcache_bypass(TWL4030_MODULE_AUDIO_VOICE, true);
428 twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &byte, 334 twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &byte,
429 TWL4030_REG_ANAMICL); 335 TWL4030_REG_ANAMICL);
336 twl_set_regcache_bypass(TWL4030_MODULE_AUDIO_VOICE, false);
430 } while ((i++ < 100) && 337 } while ((i++ < 100) &&
431 ((byte & TWL4030_CNCL_OFFSET_START) == 338 ((byte & TWL4030_CNCL_OFFSET_START) ==
432 TWL4030_CNCL_OFFSET_START)); 339 TWL4030_CNCL_OFFSET_START));
433 340
434 /* Make sure that the reg_cache has the same value as the HW */
435 twl4030_write_reg_cache(codec, TWL4030_REG_ANAMICL, byte);
436
437 twl4030_codec_enable(codec, 0); 341 twl4030_codec_enable(codec, 0);
438} 342}
439 343
@@ -453,9 +357,6 @@ static void twl4030_apll_enable(struct snd_soc_codec *codec, int enable)
453 status = twl4030_audio_disable_resource( 357 status = twl4030_audio_disable_resource(
454 TWL4030_AUDIO_RES_APLL); 358 TWL4030_AUDIO_RES_APLL);
455 } 359 }
456
457 if (status >= 0)
458 twl4030_write_reg_cache(codec, TWL4030_REG_APLL_CTL, status);
459} 360}
460 361
461/* Earpiece */ 362/* Earpiece */
@@ -671,20 +572,18 @@ static const struct snd_kcontrol_new twl4030_dapm_dbypassv_control =
671 */ 572 */
672#define TWL4030_OUTPUT_PGA(pin_name, reg, mask) \ 573#define TWL4030_OUTPUT_PGA(pin_name, reg, mask) \
673static int pin_name##pga_event(struct snd_soc_dapm_widget *w, \ 574static int pin_name##pga_event(struct snd_soc_dapm_widget *w, \
674 struct snd_kcontrol *kcontrol, int event) \ 575 struct snd_kcontrol *kcontrol, int event) \
675{ \ 576{ \
676 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(w->codec); \ 577 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(w->codec); \
677 \ 578 \
678 switch (event) { \ 579 switch (event) { \
679 case SND_SOC_DAPM_POST_PMU: \ 580 case SND_SOC_DAPM_POST_PMU: \
680 twl4030->pin_name##_enabled = 1; \ 581 twl4030->pin_name##_enabled = 1; \
681 twl4030_write(w->codec, reg, \ 582 twl4030_write(w->codec, reg, twl4030_read(w->codec, reg)); \
682 twl4030_read_reg_cache(w->codec, reg)); \
683 break; \ 583 break; \
684 case SND_SOC_DAPM_POST_PMD: \ 584 case SND_SOC_DAPM_POST_PMD: \
685 twl4030->pin_name##_enabled = 0; \ 585 twl4030->pin_name##_enabled = 0; \
686 twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, \ 586 twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, 0, reg); \
687 0, reg); \
688 break; \ 587 break; \
689 } \ 588 } \
690 return 0; \ 589 return 0; \
@@ -700,7 +599,7 @@ static void handsfree_ramp(struct snd_soc_codec *codec, int reg, int ramp)
700{ 599{
701 unsigned char hs_ctl; 600 unsigned char hs_ctl;
702 601
703 hs_ctl = twl4030_read_reg_cache(codec, reg); 602 hs_ctl = twl4030_read(codec, reg);
704 603
705 if (ramp) { 604 if (ramp) {
706 /* HF ramp-up */ 605 /* HF ramp-up */
@@ -727,7 +626,7 @@ static void handsfree_ramp(struct snd_soc_codec *codec, int reg, int ramp)
727} 626}
728 627
729static int handsfreelpga_event(struct snd_soc_dapm_widget *w, 628static int handsfreelpga_event(struct snd_soc_dapm_widget *w,
730 struct snd_kcontrol *kcontrol, int event) 629 struct snd_kcontrol *kcontrol, int event)
731{ 630{
732 switch (event) { 631 switch (event) {
733 case SND_SOC_DAPM_POST_PMU: 632 case SND_SOC_DAPM_POST_PMU:
@@ -741,7 +640,7 @@ static int handsfreelpga_event(struct snd_soc_dapm_widget *w,
741} 640}
742 641
743static int handsfreerpga_event(struct snd_soc_dapm_widget *w, 642static int handsfreerpga_event(struct snd_soc_dapm_widget *w,
744 struct snd_kcontrol *kcontrol, int event) 643 struct snd_kcontrol *kcontrol, int event)
745{ 644{
746 switch (event) { 645 switch (event) {
747 case SND_SOC_DAPM_POST_PMU: 646 case SND_SOC_DAPM_POST_PMU:
@@ -755,14 +654,14 @@ static int handsfreerpga_event(struct snd_soc_dapm_widget *w,
755} 654}
756 655
757static int vibramux_event(struct snd_soc_dapm_widget *w, 656static int vibramux_event(struct snd_soc_dapm_widget *w,
758 struct snd_kcontrol *kcontrol, int event) 657 struct snd_kcontrol *kcontrol, int event)
759{ 658{
760 twl4030_write(w->codec, TWL4030_REG_VIBRA_SET, 0xff); 659 twl4030_write(w->codec, TWL4030_REG_VIBRA_SET, 0xff);
761 return 0; 660 return 0;
762} 661}
763 662
764static int apll_event(struct snd_soc_dapm_widget *w, 663static int apll_event(struct snd_soc_dapm_widget *w,
765 struct snd_kcontrol *kcontrol, int event) 664 struct snd_kcontrol *kcontrol, int event)
766{ 665{
767 switch (event) { 666 switch (event) {
768 case SND_SOC_DAPM_PRE_PMU: 667 case SND_SOC_DAPM_PRE_PMU:
@@ -776,11 +675,11 @@ static int apll_event(struct snd_soc_dapm_widget *w,
776} 675}
777 676
778static int aif_event(struct snd_soc_dapm_widget *w, 677static int aif_event(struct snd_soc_dapm_widget *w,
779 struct snd_kcontrol *kcontrol, int event) 678 struct snd_kcontrol *kcontrol, int event)
780{ 679{
781 u8 audio_if; 680 u8 audio_if;
782 681
783 audio_if = twl4030_read_reg_cache(w->codec, TWL4030_REG_AUDIO_IF); 682 audio_if = twl4030_read(w->codec, TWL4030_REG_AUDIO_IF);
784 switch (event) { 683 switch (event) {
785 case SND_SOC_DAPM_PRE_PMU: 684 case SND_SOC_DAPM_PRE_PMU:
786 /* Enable AIF */ 685 /* Enable AIF */
@@ -788,12 +687,12 @@ static int aif_event(struct snd_soc_dapm_widget *w,
788 twl4030_apll_enable(w->codec, 1); 687 twl4030_apll_enable(w->codec, 1);
789 688
790 twl4030_write(w->codec, TWL4030_REG_AUDIO_IF, 689 twl4030_write(w->codec, TWL4030_REG_AUDIO_IF,
791 audio_if | TWL4030_AIF_EN); 690 audio_if | TWL4030_AIF_EN);
792 break; 691 break;
793 case SND_SOC_DAPM_POST_PMD: 692 case SND_SOC_DAPM_POST_PMD:
794 /* disable the DAI before we stop it's source PLL */ 693 /* disable the DAI before we stop it's source PLL */
795 twl4030_write(w->codec, TWL4030_REG_AUDIO_IF, 694 twl4030_write(w->codec, TWL4030_REG_AUDIO_IF,
796 audio_if & ~TWL4030_AIF_EN); 695 audio_if & ~TWL4030_AIF_EN);
797 twl4030_apll_enable(w->codec, 0); 696 twl4030_apll_enable(w->codec, 0);
798 break; 697 break;
799 } 698 }
@@ -810,8 +709,8 @@ static void headset_ramp(struct snd_soc_codec *codec, int ramp)
810 8388608, 16777216, 33554432, 67108864}; 709 8388608, 16777216, 33554432, 67108864};
811 unsigned int delay; 710 unsigned int delay;
812 711
813 hs_gain = twl4030_read_reg_cache(codec, TWL4030_REG_HS_GAIN_SET); 712 hs_gain = twl4030_read(codec, TWL4030_REG_HS_GAIN_SET);
814 hs_pop = twl4030_read_reg_cache(codec, TWL4030_REG_HS_POPN_SET); 713 hs_pop = twl4030_read(codec, TWL4030_REG_HS_POPN_SET);
815 delay = (ramp_base[(hs_pop & TWL4030_RAMP_DELAY) >> 2] / 714 delay = (ramp_base[(hs_pop & TWL4030_RAMP_DELAY) >> 2] /
816 twl4030->sysclk) + 1; 715 twl4030->sysclk) + 1;
817 716
@@ -831,9 +730,8 @@ static void headset_ramp(struct snd_soc_codec *codec, int ramp)
831 hs_pop |= TWL4030_VMID_EN; 730 hs_pop |= TWL4030_VMID_EN;
832 twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop); 731 twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop);
833 /* Actually write to the register */ 732 /* Actually write to the register */
834 twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, 733 twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, hs_gain,
835 hs_gain, 734 TWL4030_REG_HS_GAIN_SET);
836 TWL4030_REG_HS_GAIN_SET);
837 hs_pop |= TWL4030_RAMP_EN; 735 hs_pop |= TWL4030_RAMP_EN;
838 twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop); 736 twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop);
839 /* Wait ramp delay time + 1, so the VMID can settle */ 737 /* Wait ramp delay time + 1, so the VMID can settle */
@@ -846,9 +744,8 @@ static void headset_ramp(struct snd_soc_codec *codec, int ramp)
846 /* Wait ramp delay time + 1, so the VMID can settle */ 744 /* Wait ramp delay time + 1, so the VMID can settle */
847 twl4030_wait_ms(delay); 745 twl4030_wait_ms(delay);
848 /* Bypass the reg_cache to mute the headset */ 746 /* Bypass the reg_cache to mute the headset */
849 twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, 747 twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, hs_gain & (~0x0f),
850 hs_gain & (~0x0f), 748 TWL4030_REG_HS_GAIN_SET);
851 TWL4030_REG_HS_GAIN_SET);
852 749
853 hs_pop &= ~TWL4030_VMID_EN; 750 hs_pop &= ~TWL4030_VMID_EN;
854 twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop); 751 twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop);
@@ -866,7 +763,7 @@ static void headset_ramp(struct snd_soc_codec *codec, int ramp)
866} 763}
867 764
868static int headsetlpga_event(struct snd_soc_dapm_widget *w, 765static int headsetlpga_event(struct snd_soc_dapm_widget *w,
869 struct snd_kcontrol *kcontrol, int event) 766 struct snd_kcontrol *kcontrol, int event)
870{ 767{
871 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(w->codec); 768 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(w->codec);
872 769
@@ -890,7 +787,7 @@ static int headsetlpga_event(struct snd_soc_dapm_widget *w,
890} 787}
891 788
892static int headsetrpga_event(struct snd_soc_dapm_widget *w, 789static int headsetrpga_event(struct snd_soc_dapm_widget *w,
893 struct snd_kcontrol *kcontrol, int event) 790 struct snd_kcontrol *kcontrol, int event)
894{ 791{
895 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(w->codec); 792 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(w->codec);
896 793
@@ -914,7 +811,7 @@ static int headsetrpga_event(struct snd_soc_dapm_widget *w,
914} 811}
915 812
916static int digimic_event(struct snd_soc_dapm_widget *w, 813static int digimic_event(struct snd_soc_dapm_widget *w,
917 struct snd_kcontrol *kcontrol, int event) 814 struct snd_kcontrol *kcontrol, int event)
918{ 815{
919 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(w->codec); 816 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(w->codec);
920 struct twl4030_codec_data *pdata = twl4030->pdata; 817 struct twl4030_codec_data *pdata = twl4030->pdata;
@@ -935,7 +832,7 @@ static int digimic_event(struct snd_soc_dapm_widget *w,
935 * Custom volsw and volsw_2r get/put functions to handle these gain bits. 832 * Custom volsw and volsw_2r get/put functions to handle these gain bits.
936 */ 833 */
937static int snd_soc_get_volsw_twl4030(struct snd_kcontrol *kcontrol, 834static int snd_soc_get_volsw_twl4030(struct snd_kcontrol *kcontrol,
938 struct snd_ctl_elem_value *ucontrol) 835 struct snd_ctl_elem_value *ucontrol)
939{ 836{
940 struct soc_mixer_control *mc = 837 struct soc_mixer_control *mc =
941 (struct soc_mixer_control *)kcontrol->private_value; 838 (struct soc_mixer_control *)kcontrol->private_value;
@@ -964,7 +861,7 @@ static int snd_soc_get_volsw_twl4030(struct snd_kcontrol *kcontrol,
964} 861}
965 862
966static int snd_soc_put_volsw_twl4030(struct snd_kcontrol *kcontrol, 863static int snd_soc_put_volsw_twl4030(struct snd_kcontrol *kcontrol,
967 struct snd_ctl_elem_value *ucontrol) 864 struct snd_ctl_elem_value *ucontrol)
968{ 865{
969 struct soc_mixer_control *mc = 866 struct soc_mixer_control *mc =
970 (struct soc_mixer_control *)kcontrol->private_value; 867 (struct soc_mixer_control *)kcontrol->private_value;
@@ -993,7 +890,7 @@ static int snd_soc_put_volsw_twl4030(struct snd_kcontrol *kcontrol,
993} 890}
994 891
995static int snd_soc_get_volsw_r2_twl4030(struct snd_kcontrol *kcontrol, 892static int snd_soc_get_volsw_r2_twl4030(struct snd_kcontrol *kcontrol,
996 struct snd_ctl_elem_value *ucontrol) 893 struct snd_ctl_elem_value *ucontrol)
997{ 894{
998 struct soc_mixer_control *mc = 895 struct soc_mixer_control *mc =
999 (struct soc_mixer_control *)kcontrol->private_value; 896 (struct soc_mixer_control *)kcontrol->private_value;
@@ -1020,7 +917,7 @@ static int snd_soc_get_volsw_r2_twl4030(struct snd_kcontrol *kcontrol,
1020} 917}
1021 918
1022static int snd_soc_put_volsw_r2_twl4030(struct snd_kcontrol *kcontrol, 919static int snd_soc_put_volsw_r2_twl4030(struct snd_kcontrol *kcontrol,
1023 struct snd_ctl_elem_value *ucontrol) 920 struct snd_ctl_elem_value *ucontrol)
1024{ 921{
1025 struct soc_mixer_control *mc = 922 struct soc_mixer_control *mc =
1026 (struct soc_mixer_control *)kcontrol->private_value; 923 (struct soc_mixer_control *)kcontrol->private_value;
@@ -1751,11 +1648,11 @@ static void twl4030_constraints(struct twl4030_priv *twl4030,
1751/* In case of 4 channel mode, the RX1 L/R for playback and the TX2 L/R for 1648/* In case of 4 channel mode, the RX1 L/R for playback and the TX2 L/R for
1752 * capture has to be enabled/disabled. */ 1649 * capture has to be enabled/disabled. */
1753static void twl4030_tdm_enable(struct snd_soc_codec *codec, int direction, 1650static void twl4030_tdm_enable(struct snd_soc_codec *codec, int direction,
1754 int enable) 1651 int enable)
1755{ 1652{
1756 u8 reg, mask; 1653 u8 reg, mask;
1757 1654
1758 reg = twl4030_read_reg_cache(codec, TWL4030_REG_OPTION); 1655 reg = twl4030_read(codec, TWL4030_REG_OPTION);
1759 1656
1760 if (direction == SNDRV_PCM_STREAM_PLAYBACK) 1657 if (direction == SNDRV_PCM_STREAM_PLAYBACK)
1761 mask = TWL4030_ARXL1_VRX_EN | TWL4030_ARXR1_EN; 1658 mask = TWL4030_ARXL1_VRX_EN | TWL4030_ARXR1_EN;
@@ -1784,14 +1681,14 @@ static int twl4030_startup(struct snd_pcm_substream *substream,
1784 if (twl4030->configured) 1681 if (twl4030->configured)
1785 twl4030_constraints(twl4030, twl4030->master_substream); 1682 twl4030_constraints(twl4030, twl4030->master_substream);
1786 } else { 1683 } else {
1787 if (!(twl4030_read_reg_cache(codec, TWL4030_REG_CODEC_MODE) & 1684 if (!(twl4030_read(codec, TWL4030_REG_CODEC_MODE) &
1788 TWL4030_OPTION_1)) { 1685 TWL4030_OPTION_1)) {
1789 /* In option2 4 channel is not supported, set the 1686 /* In option2 4 channel is not supported, set the
1790 * constraint for the first stream for channels, the 1687 * constraint for the first stream for channels, the
1791 * second stream will 'inherit' this cosntraint */ 1688 * second stream will 'inherit' this cosntraint */
1792 snd_pcm_hw_constraint_minmax(substream->runtime, 1689 snd_pcm_hw_constraint_minmax(substream->runtime,
1793 SNDRV_PCM_HW_PARAM_CHANNELS, 1690 SNDRV_PCM_HW_PARAM_CHANNELS,
1794 2, 2); 1691 2, 2);
1795 } 1692 }
1796 twl4030->master_substream = substream; 1693 twl4030->master_substream = substream;
1797 } 1694 }
@@ -1823,8 +1720,8 @@ static void twl4030_shutdown(struct snd_pcm_substream *substream,
1823} 1720}
1824 1721
1825static int twl4030_hw_params(struct snd_pcm_substream *substream, 1722static int twl4030_hw_params(struct snd_pcm_substream *substream,
1826 struct snd_pcm_hw_params *params, 1723 struct snd_pcm_hw_params *params,
1827 struct snd_soc_dai *dai) 1724 struct snd_soc_dai *dai)
1828{ 1725{
1829 struct snd_soc_codec *codec = dai->codec; 1726 struct snd_soc_codec *codec = dai->codec;
1830 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); 1727 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
@@ -1832,8 +1729,8 @@ static int twl4030_hw_params(struct snd_pcm_substream *substream,
1832 1729
1833 /* If the substream has 4 channel, do the necessary setup */ 1730 /* If the substream has 4 channel, do the necessary setup */
1834 if (params_channels(params) == 4) { 1731 if (params_channels(params) == 4) {
1835 format = twl4030_read_reg_cache(codec, TWL4030_REG_AUDIO_IF); 1732 format = twl4030_read(codec, TWL4030_REG_AUDIO_IF);
1836 mode = twl4030_read_reg_cache(codec, TWL4030_REG_CODEC_MODE); 1733 mode = twl4030_read(codec, TWL4030_REG_CODEC_MODE);
1837 1734
1838 /* Safety check: are we in the correct operating mode and 1735 /* Safety check: are we in the correct operating mode and
1839 * the interface is in TDM mode? */ 1736 * the interface is in TDM mode? */
@@ -1849,8 +1746,8 @@ static int twl4030_hw_params(struct snd_pcm_substream *substream,
1849 return 0; 1746 return 0;
1850 1747
1851 /* bit rate */ 1748 /* bit rate */
1852 old_mode = twl4030_read_reg_cache(codec, 1749 old_mode = twl4030_read(codec,
1853 TWL4030_REG_CODEC_MODE) & ~TWL4030_CODECPDZ; 1750 TWL4030_REG_CODEC_MODE) & ~TWL4030_CODECPDZ;
1854 mode = old_mode & ~TWL4030_APLL_RATE; 1751 mode = old_mode & ~TWL4030_APLL_RATE;
1855 1752
1856 switch (params_rate(params)) { 1753 switch (params_rate(params)) {
@@ -1891,7 +1788,7 @@ static int twl4030_hw_params(struct snd_pcm_substream *substream,
1891 } 1788 }
1892 1789
1893 /* sample size */ 1790 /* sample size */
1894 old_format = twl4030_read_reg_cache(codec, TWL4030_REG_AUDIO_IF); 1791 old_format = twl4030_read(codec, TWL4030_REG_AUDIO_IF);
1895 format = old_format; 1792 format = old_format;
1896 format &= ~TWL4030_DATA_WIDTH; 1793 format &= ~TWL4030_DATA_WIDTH;
1897 switch (params_format(params)) { 1794 switch (params_format(params)) {
@@ -1940,8 +1837,8 @@ static int twl4030_hw_params(struct snd_pcm_substream *substream,
1940 return 0; 1837 return 0;
1941} 1838}
1942 1839
1943static int twl4030_set_dai_sysclk(struct snd_soc_dai *codec_dai, 1840static int twl4030_set_dai_sysclk(struct snd_soc_dai *codec_dai, int clk_id,
1944 int clk_id, unsigned int freq, int dir) 1841 unsigned int freq, int dir)
1945{ 1842{
1946 struct snd_soc_codec *codec = codec_dai->codec; 1843 struct snd_soc_codec *codec = codec_dai->codec;
1947 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); 1844 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
@@ -1966,15 +1863,14 @@ static int twl4030_set_dai_sysclk(struct snd_soc_dai *codec_dai,
1966 return 0; 1863 return 0;
1967} 1864}
1968 1865
1969static int twl4030_set_dai_fmt(struct snd_soc_dai *codec_dai, 1866static int twl4030_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
1970 unsigned int fmt)
1971{ 1867{
1972 struct snd_soc_codec *codec = codec_dai->codec; 1868 struct snd_soc_codec *codec = codec_dai->codec;
1973 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); 1869 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
1974 u8 old_format, format; 1870 u8 old_format, format;
1975 1871
1976 /* get format */ 1872 /* get format */
1977 old_format = twl4030_read_reg_cache(codec, TWL4030_REG_AUDIO_IF); 1873 old_format = twl4030_read(codec, TWL4030_REG_AUDIO_IF);
1978 format = old_format; 1874 format = old_format;
1979 1875
1980 /* set master/slave audio interface */ 1876 /* set master/slave audio interface */
@@ -2024,7 +1920,7 @@ static int twl4030_set_dai_fmt(struct snd_soc_dai *codec_dai,
2024static int twl4030_set_tristate(struct snd_soc_dai *dai, int tristate) 1920static int twl4030_set_tristate(struct snd_soc_dai *dai, int tristate)
2025{ 1921{
2026 struct snd_soc_codec *codec = dai->codec; 1922 struct snd_soc_codec *codec = dai->codec;
2027 u8 reg = twl4030_read_reg_cache(codec, TWL4030_REG_AUDIO_IF); 1923 u8 reg = twl4030_read(codec, TWL4030_REG_AUDIO_IF);
2028 1924
2029 if (tristate) 1925 if (tristate)
2030 reg |= TWL4030_AIF_TRI_EN; 1926 reg |= TWL4030_AIF_TRI_EN;
@@ -2037,11 +1933,11 @@ static int twl4030_set_tristate(struct snd_soc_dai *dai, int tristate)
2037/* In case of voice mode, the RX1 L(VRX) for downlink and the TX2 L/R 1933/* In case of voice mode, the RX1 L(VRX) for downlink and the TX2 L/R
2038 * (VTXL, VTXR) for uplink has to be enabled/disabled. */ 1934 * (VTXL, VTXR) for uplink has to be enabled/disabled. */
2039static void twl4030_voice_enable(struct snd_soc_codec *codec, int direction, 1935static void twl4030_voice_enable(struct snd_soc_codec *codec, int direction,
2040 int enable) 1936 int enable)
2041{ 1937{
2042 u8 reg, mask; 1938 u8 reg, mask;
2043 1939
2044 reg = twl4030_read_reg_cache(codec, TWL4030_REG_OPTION); 1940 reg = twl4030_read(codec, TWL4030_REG_OPTION);
2045 1941
2046 if (direction == SNDRV_PCM_STREAM_PLAYBACK) 1942 if (direction == SNDRV_PCM_STREAM_PLAYBACK)
2047 mask = TWL4030_ARXL1_VRX_EN; 1943 mask = TWL4030_ARXL1_VRX_EN;
@@ -2057,7 +1953,7 @@ static void twl4030_voice_enable(struct snd_soc_codec *codec, int direction,
2057} 1953}
2058 1954
2059static int twl4030_voice_startup(struct snd_pcm_substream *substream, 1955static int twl4030_voice_startup(struct snd_pcm_substream *substream,
2060 struct snd_soc_dai *dai) 1956 struct snd_soc_dai *dai)
2061{ 1957{
2062 struct snd_soc_codec *codec = dai->codec; 1958 struct snd_soc_codec *codec = dai->codec;
2063 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); 1959 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
@@ -2076,7 +1972,7 @@ static int twl4030_voice_startup(struct snd_pcm_substream *substream,
2076 /* If the codec mode is not option2, the voice PCM interface is not 1972 /* If the codec mode is not option2, the voice PCM interface is not
2077 * available. 1973 * available.
2078 */ 1974 */
2079 mode = twl4030_read_reg_cache(codec, TWL4030_REG_CODEC_MODE) 1975 mode = twl4030_read(codec, TWL4030_REG_CODEC_MODE)
2080 & TWL4030_OPT_MODE; 1976 & TWL4030_OPT_MODE;
2081 1977
2082 if (mode != TWL4030_OPTION_2) { 1978 if (mode != TWL4030_OPTION_2) {
@@ -2089,7 +1985,7 @@ static int twl4030_voice_startup(struct snd_pcm_substream *substream,
2089} 1985}
2090 1986
2091static void twl4030_voice_shutdown(struct snd_pcm_substream *substream, 1987static void twl4030_voice_shutdown(struct snd_pcm_substream *substream,
2092 struct snd_soc_dai *dai) 1988 struct snd_soc_dai *dai)
2093{ 1989{
2094 struct snd_soc_codec *codec = dai->codec; 1990 struct snd_soc_codec *codec = dai->codec;
2095 1991
@@ -2098,7 +1994,8 @@ static void twl4030_voice_shutdown(struct snd_pcm_substream *substream,
2098} 1994}
2099 1995
2100static int twl4030_voice_hw_params(struct snd_pcm_substream *substream, 1996static int twl4030_voice_hw_params(struct snd_pcm_substream *substream,
2101 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) 1997 struct snd_pcm_hw_params *params,
1998 struct snd_soc_dai *dai)
2102{ 1999{
2103 struct snd_soc_codec *codec = dai->codec; 2000 struct snd_soc_codec *codec = dai->codec;
2104 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); 2001 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
@@ -2108,8 +2005,8 @@ static int twl4030_voice_hw_params(struct snd_pcm_substream *substream,
2108 twl4030_voice_enable(codec, substream->stream, 1); 2005 twl4030_voice_enable(codec, substream->stream, 1);
2109 2006
2110 /* bit rate */ 2007 /* bit rate */
2111 old_mode = twl4030_read_reg_cache(codec, TWL4030_REG_CODEC_MODE) 2008 old_mode = twl4030_read(codec,
2112 & ~(TWL4030_CODECPDZ); 2009 TWL4030_REG_CODEC_MODE) & ~TWL4030_CODECPDZ;
2113 mode = old_mode; 2010 mode = old_mode;
2114 2011
2115 switch (params_rate(params)) { 2012 switch (params_rate(params)) {
@@ -2143,7 +2040,7 @@ static int twl4030_voice_hw_params(struct snd_pcm_substream *substream,
2143} 2040}
2144 2041
2145static int twl4030_voice_set_dai_sysclk(struct snd_soc_dai *codec_dai, 2042static int twl4030_voice_set_dai_sysclk(struct snd_soc_dai *codec_dai,
2146 int clk_id, unsigned int freq, int dir) 2043 int clk_id, unsigned int freq, int dir)
2147{ 2044{
2148 struct snd_soc_codec *codec = codec_dai->codec; 2045 struct snd_soc_codec *codec = codec_dai->codec;
2149 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); 2046 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
@@ -2164,14 +2061,14 @@ static int twl4030_voice_set_dai_sysclk(struct snd_soc_dai *codec_dai,
2164} 2061}
2165 2062
2166static int twl4030_voice_set_dai_fmt(struct snd_soc_dai *codec_dai, 2063static int twl4030_voice_set_dai_fmt(struct snd_soc_dai *codec_dai,
2167 unsigned int fmt) 2064 unsigned int fmt)
2168{ 2065{
2169 struct snd_soc_codec *codec = codec_dai->codec; 2066 struct snd_soc_codec *codec = codec_dai->codec;
2170 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); 2067 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
2171 u8 old_format, format; 2068 u8 old_format, format;
2172 2069
2173 /* get format */ 2070 /* get format */
2174 old_format = twl4030_read_reg_cache(codec, TWL4030_REG_VOICE_IF); 2071 old_format = twl4030_read(codec, TWL4030_REG_VOICE_IF);
2175 format = old_format; 2072 format = old_format;
2176 2073
2177 /* set master/slave audio interface */ 2074 /* set master/slave audio interface */
@@ -2218,7 +2115,7 @@ static int twl4030_voice_set_dai_fmt(struct snd_soc_dai *codec_dai,
2218static int twl4030_voice_set_tristate(struct snd_soc_dai *dai, int tristate) 2115static int twl4030_voice_set_tristate(struct snd_soc_dai *dai, int tristate)
2219{ 2116{
2220 struct snd_soc_codec *codec = dai->codec; 2117 struct snd_soc_codec *codec = dai->codec;
2221 u8 reg = twl4030_read_reg_cache(codec, TWL4030_REG_VOICE_IF); 2118 u8 reg = twl4030_read(codec, TWL4030_REG_VOICE_IF);
2222 2119
2223 if (tristate) 2120 if (tristate)
2224 reg |= TWL4030_VIF_TRI_EN; 2121 reg |= TWL4030_VIF_TRI_EN;
@@ -2310,8 +2207,6 @@ static int twl4030_soc_remove(struct snd_soc_codec *codec)
2310 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); 2207 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
2311 struct twl4030_codec_data *pdata = twl4030->pdata; 2208 struct twl4030_codec_data *pdata = twl4030->pdata;
2312 2209
2313 /* Reset registers to their chip default before leaving */
2314 twl4030_reset_registers(codec);
2315 twl4030_set_bias_level(codec, SND_SOC_BIAS_OFF); 2210 twl4030_set_bias_level(codec, SND_SOC_BIAS_OFF);
2316 2211
2317 if (pdata && pdata->hs_extmute && gpio_is_valid(pdata->hs_extmute_gpio)) 2212 if (pdata && pdata->hs_extmute && gpio_is_valid(pdata->hs_extmute_gpio))
@@ -2323,13 +2218,10 @@ static int twl4030_soc_remove(struct snd_soc_codec *codec)
2323static struct snd_soc_codec_driver soc_codec_dev_twl4030 = { 2218static struct snd_soc_codec_driver soc_codec_dev_twl4030 = {
2324 .probe = twl4030_soc_probe, 2219 .probe = twl4030_soc_probe,
2325 .remove = twl4030_soc_remove, 2220 .remove = twl4030_soc_remove,
2326 .read = twl4030_read_reg_cache, 2221 .read = twl4030_read,
2327 .write = twl4030_write, 2222 .write = twl4030_write,
2328 .set_bias_level = twl4030_set_bias_level, 2223 .set_bias_level = twl4030_set_bias_level,
2329 .idle_bias_off = true, 2224 .idle_bias_off = true,
2330 .reg_cache_size = sizeof(twl4030_reg),
2331 .reg_word_size = sizeof(u8),
2332 .reg_cache_default = twl4030_reg,
2333 2225
2334 .controls = twl4030_snd_controls, 2226 .controls = twl4030_snd_controls,
2335 .num_controls = ARRAY_SIZE(twl4030_snd_controls), 2227 .num_controls = ARRAY_SIZE(twl4030_snd_controls),
@@ -2342,7 +2234,7 @@ static struct snd_soc_codec_driver soc_codec_dev_twl4030 = {
2342static int twl4030_codec_probe(struct platform_device *pdev) 2234static int twl4030_codec_probe(struct platform_device *pdev)
2343{ 2235{
2344 return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_twl4030, 2236 return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_twl4030,
2345 twl4030_dai, ARRAY_SIZE(twl4030_dai)); 2237 twl4030_dai, ARRAY_SIZE(twl4030_dai));
2346} 2238}
2347 2239
2348static int twl4030_codec_remove(struct platform_device *pdev) 2240static int twl4030_codec_remove(struct platform_device *pdev)
diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c
index fb0c678939bf..444626fcab40 100644
--- a/sound/soc/codecs/wm_adsp.c
+++ b/sound/soc/codecs/wm_adsp.c
@@ -1497,107 +1497,149 @@ static int wm_adsp2_ena(struct wm_adsp *dsp)
1497 return 0; 1497 return 0;
1498} 1498}
1499 1499
1500int wm_adsp2_event(struct snd_soc_dapm_widget *w, 1500static void wm_adsp2_boot_work(struct work_struct *work)
1501 struct snd_kcontrol *kcontrol, int event)
1502{ 1501{
1503 struct snd_soc_codec *codec = w->codec; 1502 struct wm_adsp *dsp = container_of(work,
1504 struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec); 1503 struct wm_adsp,
1505 struct wm_adsp *dsp = &dsps[w->shift]; 1504 boot_work);
1506 struct wm_adsp_alg_region *alg_region;
1507 struct wm_coeff_ctl *ctl;
1508 unsigned int val;
1509 int ret; 1505 int ret;
1506 unsigned int val;
1510 1507
1511 dsp->card = codec->card; 1508 /*
1509 * For simplicity set the DSP clock rate to be the
1510 * SYSCLK rate rather than making it configurable.
1511 */
1512 ret = regmap_read(dsp->regmap, ARIZONA_SYSTEM_CLOCK_1, &val);
1513 if (ret != 0) {
1514 adsp_err(dsp, "Failed to read SYSCLK state: %d\n", ret);
1515 return;
1516 }
1517 val = (val & ARIZONA_SYSCLK_FREQ_MASK)
1518 >> ARIZONA_SYSCLK_FREQ_SHIFT;
1512 1519
1513 switch (event) { 1520 ret = regmap_update_bits_async(dsp->regmap,
1514 case SND_SOC_DAPM_POST_PMU: 1521 dsp->base + ADSP2_CLOCKING,
1515 /* 1522 ADSP2_CLK_SEL_MASK, val);
1516 * For simplicity set the DSP clock rate to be the 1523 if (ret != 0) {
1517 * SYSCLK rate rather than making it configurable. 1524 adsp_err(dsp, "Failed to set clock rate: %d\n", ret);
1518 */ 1525 return;
1519 ret = regmap_read(dsp->regmap, ARIZONA_SYSTEM_CLOCK_1, &val); 1526 }
1520 if (ret != 0) {
1521 adsp_err(dsp, "Failed to read SYSCLK state: %d\n",
1522 ret);
1523 return ret;
1524 }
1525 val = (val & ARIZONA_SYSCLK_FREQ_MASK)
1526 >> ARIZONA_SYSCLK_FREQ_SHIFT;
1527 1527
1528 ret = regmap_update_bits_async(dsp->regmap, 1528 if (dsp->dvfs) {
1529 dsp->base + ADSP2_CLOCKING, 1529 ret = regmap_read(dsp->regmap,
1530 ADSP2_CLK_SEL_MASK, val); 1530 dsp->base + ADSP2_CLOCKING, &val);
1531 if (ret != 0) { 1531 if (ret != 0) {
1532 adsp_err(dsp, "Failed to set clock rate: %d\n", 1532 dev_err(dsp->dev, "Failed to read clocking: %d\n", ret);
1533 ret); 1533 return;
1534 return ret;
1535 } 1534 }
1536 1535
1537 if (dsp->dvfs) { 1536 if ((val & ADSP2_CLK_SEL_MASK) >= 3) {
1538 ret = regmap_read(dsp->regmap, 1537 ret = regulator_enable(dsp->dvfs);
1539 dsp->base + ADSP2_CLOCKING, &val);
1540 if (ret != 0) { 1538 if (ret != 0) {
1541 dev_err(dsp->dev, 1539 dev_err(dsp->dev,
1542 "Failed to read clocking: %d\n", ret); 1540 "Failed to enable supply: %d\n",
1543 return ret; 1541 ret);
1542 return;
1544 } 1543 }
1545 1544
1546 if ((val & ADSP2_CLK_SEL_MASK) >= 3) { 1545 ret = regulator_set_voltage(dsp->dvfs,
1547 ret = regulator_enable(dsp->dvfs); 1546 1800000,
1548 if (ret != 0) { 1547 1800000);
1549 dev_err(dsp->dev, 1548 if (ret != 0) {
1550 "Failed to enable supply: %d\n", 1549 dev_err(dsp->dev,
1551 ret); 1550 "Failed to raise supply: %d\n",
1552 return ret; 1551 ret);
1553 } 1552 return;
1554
1555 ret = regulator_set_voltage(dsp->dvfs,
1556 1800000,
1557 1800000);
1558 if (ret != 0) {
1559 dev_err(dsp->dev,
1560 "Failed to raise supply: %d\n",
1561 ret);
1562 return ret;
1563 }
1564 } 1553 }
1565 } 1554 }
1555 }
1566 1556
1567 ret = wm_adsp2_ena(dsp); 1557 ret = wm_adsp2_ena(dsp);
1568 if (ret != 0) 1558 if (ret != 0)
1569 return ret; 1559 return;
1570 1560
1571 ret = wm_adsp_load(dsp); 1561 ret = wm_adsp_load(dsp);
1572 if (ret != 0) 1562 if (ret != 0)
1573 goto err; 1563 goto err;
1574 1564
1575 ret = wm_adsp_setup_algs(dsp); 1565 ret = wm_adsp_setup_algs(dsp);
1576 if (ret != 0) 1566 if (ret != 0)
1577 goto err; 1567 goto err;
1578 1568
1579 ret = wm_adsp_load_coeff(dsp); 1569 ret = wm_adsp_load_coeff(dsp);
1580 if (ret != 0) 1570 if (ret != 0)
1581 goto err; 1571 goto err;
1582 1572
1583 /* Initialize caches for enabled and unset controls */ 1573 /* Initialize caches for enabled and unset controls */
1584 ret = wm_coeff_init_control_caches(dsp); 1574 ret = wm_coeff_init_control_caches(dsp);
1585 if (ret != 0) 1575 if (ret != 0)
1586 goto err; 1576 goto err;
1587 1577
1588 /* Sync set controls */ 1578 /* Sync set controls */
1589 ret = wm_coeff_sync_controls(dsp); 1579 ret = wm_coeff_sync_controls(dsp);
1590 if (ret != 0) 1580 if (ret != 0)
1591 goto err; 1581 goto err;
1582
1583 ret = regmap_update_bits_async(dsp->regmap,
1584 dsp->base + ADSP2_CONTROL,
1585 ADSP2_CORE_ENA,
1586 ADSP2_CORE_ENA);
1587 if (ret != 0)
1588 goto err;
1589
1590 dsp->running = true;
1591
1592 return;
1593
1594err:
1595 regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL,
1596 ADSP2_SYS_ENA | ADSP2_CORE_ENA | ADSP2_START, 0);
1597}
1598
1599int wm_adsp2_early_event(struct snd_soc_dapm_widget *w,
1600 struct snd_kcontrol *kcontrol, int event)
1601{
1602 struct snd_soc_codec *codec = w->codec;
1603 struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec);
1604 struct wm_adsp *dsp = &dsps[w->shift];
1605
1606 dsp->card = codec->card;
1607
1608 switch (event) {
1609 case SND_SOC_DAPM_PRE_PMU:
1610 queue_work(system_unbound_wq, &dsp->boot_work);
1611 break;
1612 default:
1613 break;
1614 };
1615
1616 return 0;
1617}
1618EXPORT_SYMBOL_GPL(wm_adsp2_early_event);
1619
1620int wm_adsp2_event(struct snd_soc_dapm_widget *w,
1621 struct snd_kcontrol *kcontrol, int event)
1622{
1623 struct snd_soc_codec *codec = w->codec;
1624 struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec);
1625 struct wm_adsp *dsp = &dsps[w->shift];
1626 struct wm_adsp_alg_region *alg_region;
1627 struct wm_coeff_ctl *ctl;
1628 int ret;
1629
1630 switch (event) {
1631 case SND_SOC_DAPM_POST_PMU:
1632 flush_work(&dsp->boot_work);
1633
1634 if (!dsp->running)
1635 return -EIO;
1592 1636
1593 ret = regmap_update_bits_async(dsp->regmap, 1637 ret = regmap_update_bits(dsp->regmap,
1594 dsp->base + ADSP2_CONTROL, 1638 dsp->base + ADSP2_CONTROL,
1595 ADSP2_CORE_ENA | ADSP2_START, 1639 ADSP2_START,
1596 ADSP2_CORE_ENA | ADSP2_START); 1640 ADSP2_START);
1597 if (ret != 0) 1641 if (ret != 0)
1598 goto err; 1642 goto err;
1599
1600 dsp->running = true;
1601 break; 1643 break;
1602 1644
1603 case SND_SOC_DAPM_PRE_PMD: 1645 case SND_SOC_DAPM_PRE_PMD:
@@ -1668,6 +1710,7 @@ int wm_adsp2_init(struct wm_adsp *adsp, bool dvfs)
1668 1710
1669 INIT_LIST_HEAD(&adsp->alg_regions); 1711 INIT_LIST_HEAD(&adsp->alg_regions);
1670 INIT_LIST_HEAD(&adsp->ctl_list); 1712 INIT_LIST_HEAD(&adsp->ctl_list);
1713 INIT_WORK(&adsp->boot_work, wm_adsp2_boot_work);
1671 1714
1672 if (dvfs) { 1715 if (dvfs) {
1673 adsp->dvfs = devm_regulator_get(adsp->dev, "DCVDD"); 1716 adsp->dvfs = devm_regulator_get(adsp->dev, "DCVDD");
diff --git a/sound/soc/codecs/wm_adsp.h b/sound/soc/codecs/wm_adsp.h
index d018dea6254d..a4f6b64deb61 100644
--- a/sound/soc/codecs/wm_adsp.h
+++ b/sound/soc/codecs/wm_adsp.h
@@ -59,6 +59,8 @@ struct wm_adsp {
59 struct regulator *dvfs; 59 struct regulator *dvfs;
60 60
61 struct list_head ctl_list; 61 struct list_head ctl_list;
62
63 struct work_struct boot_work;
62}; 64};
63 65
64#define WM_ADSP1(wname, num) \ 66#define WM_ADSP1(wname, num) \
@@ -66,8 +68,12 @@ struct wm_adsp {
66 wm_adsp1_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD) 68 wm_adsp1_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD)
67 69
68#define WM_ADSP2(wname, num) \ 70#define WM_ADSP2(wname, num) \
69 SND_SOC_DAPM_PGA_E(wname, SND_SOC_NOPM, num, 0, NULL, 0, \ 71{ .id = snd_soc_dapm_dai_link, .name = wname " Preloader", \
70 wm_adsp2_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD) 72 .reg = SND_SOC_NOPM, .shift = num, .event = wm_adsp2_early_event, \
73 .event_flags = SND_SOC_DAPM_PRE_PMU }, \
74{ .id = snd_soc_dapm_out_drv, .name = wname, \
75 .reg = SND_SOC_NOPM, .shift = num, .event = wm_adsp2_event, \
76 .event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD }
71 77
72extern const struct snd_kcontrol_new wm_adsp1_fw_controls[]; 78extern const struct snd_kcontrol_new wm_adsp1_fw_controls[];
73extern const struct snd_kcontrol_new wm_adsp2_fw_controls[]; 79extern const struct snd_kcontrol_new wm_adsp2_fw_controls[];
@@ -76,6 +82,8 @@ int wm_adsp1_init(struct wm_adsp *adsp);
76int wm_adsp2_init(struct wm_adsp *adsp, bool dvfs); 82int wm_adsp2_init(struct wm_adsp *adsp, bool dvfs);
77int wm_adsp1_event(struct snd_soc_dapm_widget *w, 83int wm_adsp1_event(struct snd_soc_dapm_widget *w,
78 struct snd_kcontrol *kcontrol, int event); 84 struct snd_kcontrol *kcontrol, int event);
85int wm_adsp2_early_event(struct snd_soc_dapm_widget *w,
86 struct snd_kcontrol *kcontrol, int event);
79int wm_adsp2_event(struct snd_soc_dapm_widget *w, 87int wm_adsp2_event(struct snd_soc_dapm_widget *w,
80 struct snd_kcontrol *kcontrol, int event); 88 struct snd_kcontrol *kcontrol, int event);
81 89
diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig
index 514c275c6108..324988dea4bd 100644
--- a/sound/soc/fsl/Kconfig
+++ b/sound/soc/fsl/Kconfig
@@ -8,6 +8,9 @@ config SND_SOC_FSL_SSI
8config SND_SOC_FSL_SPDIF 8config SND_SOC_FSL_SPDIF
9 tristate 9 tristate
10 10
11config SND_SOC_FSL_ESAI
12 tristate
13
11config SND_SOC_FSL_UTILS 14config SND_SOC_FSL_UTILS
12 tristate 15 tristate
13 16
diff --git a/sound/soc/fsl/Makefile b/sound/soc/fsl/Makefile
index aaccbee17006..b12ad4b9b4da 100644
--- a/sound/soc/fsl/Makefile
+++ b/sound/soc/fsl/Makefile
@@ -14,11 +14,13 @@ obj-$(CONFIG_SND_SOC_P1022_RDK) += snd-soc-p1022-rdk.o
14snd-soc-fsl-sai-objs := fsl_sai.o 14snd-soc-fsl-sai-objs := fsl_sai.o
15snd-soc-fsl-ssi-objs := fsl_ssi.o 15snd-soc-fsl-ssi-objs := fsl_ssi.o
16snd-soc-fsl-spdif-objs := fsl_spdif.o 16snd-soc-fsl-spdif-objs := fsl_spdif.o
17snd-soc-fsl-esai-objs := fsl_esai.o
17snd-soc-fsl-utils-objs := fsl_utils.o 18snd-soc-fsl-utils-objs := fsl_utils.o
18snd-soc-fsl-dma-objs := fsl_dma.o 19snd-soc-fsl-dma-objs := fsl_dma.o
19obj-$(CONFIG_SND_SOC_FSL_SAI) += snd-soc-fsl-sai.o 20obj-$(CONFIG_SND_SOC_FSL_SAI) += snd-soc-fsl-sai.o
20obj-$(CONFIG_SND_SOC_FSL_SSI) += snd-soc-fsl-ssi.o 21obj-$(CONFIG_SND_SOC_FSL_SSI) += snd-soc-fsl-ssi.o
21obj-$(CONFIG_SND_SOC_FSL_SPDIF) += snd-soc-fsl-spdif.o 22obj-$(CONFIG_SND_SOC_FSL_SPDIF) += snd-soc-fsl-spdif.o
23obj-$(CONFIG_SND_SOC_FSL_ESAI) += snd-soc-fsl-esai.o
22obj-$(CONFIG_SND_SOC_FSL_UTILS) += snd-soc-fsl-utils.o 24obj-$(CONFIG_SND_SOC_FSL_UTILS) += snd-soc-fsl-utils.o
23obj-$(CONFIG_SND_SOC_POWERPC_DMA) += snd-soc-fsl-dma.o 25obj-$(CONFIG_SND_SOC_POWERPC_DMA) += snd-soc-fsl-dma.o
24 26
diff --git a/sound/soc/fsl/fsl_dma.c b/sound/soc/fsl/fsl_dma.c
index d570f8c81dc6..6bb0ea59284f 100644
--- a/sound/soc/fsl/fsl_dma.c
+++ b/sound/soc/fsl/fsl_dma.c
@@ -55,10 +55,6 @@
55 SNDRV_PCM_FMTBIT_S32_BE | \ 55 SNDRV_PCM_FMTBIT_S32_BE | \
56 SNDRV_PCM_FMTBIT_U32_LE | \ 56 SNDRV_PCM_FMTBIT_U32_LE | \
57 SNDRV_PCM_FMTBIT_U32_BE) 57 SNDRV_PCM_FMTBIT_U32_BE)
58
59#define FSLDMA_PCM_RATES (SNDRV_PCM_RATE_5512 | SNDRV_PCM_RATE_8000_192000 | \
60 SNDRV_PCM_RATE_CONTINUOUS)
61
62struct dma_object { 58struct dma_object {
63 struct snd_soc_platform_driver dai; 59 struct snd_soc_platform_driver dai;
64 dma_addr_t ssi_stx_phys; 60 dma_addr_t ssi_stx_phys;
@@ -140,9 +136,6 @@ static const struct snd_pcm_hardware fsl_dma_hardware = {
140 SNDRV_PCM_INFO_JOINT_DUPLEX | 136 SNDRV_PCM_INFO_JOINT_DUPLEX |
141 SNDRV_PCM_INFO_PAUSE, 137 SNDRV_PCM_INFO_PAUSE,
142 .formats = FSLDMA_PCM_FORMATS, 138 .formats = FSLDMA_PCM_FORMATS,
143 .rates = FSLDMA_PCM_RATES,
144 .rate_min = 5512,
145 .rate_max = 192000,
146 .period_bytes_min = 512, /* A reasonable limit */ 139 .period_bytes_min = 512, /* A reasonable limit */
147 .period_bytes_max = (u32) -1, 140 .period_bytes_max = (u32) -1,
148 .periods_min = NUM_DMA_LINKS, 141 .periods_min = NUM_DMA_LINKS,
diff --git a/sound/soc/fsl/fsl_esai.c b/sound/soc/fsl/fsl_esai.c
new file mode 100644
index 000000000000..d0c72ed261e7
--- /dev/null
+++ b/sound/soc/fsl/fsl_esai.c
@@ -0,0 +1,815 @@
1/*
2 * Freescale ESAI ALSA SoC Digital Audio Interface (DAI) driver
3 *
4 * Copyright (C) 2014 Freescale Semiconductor, Inc.
5 *
6 * This file is licensed under the terms of the GNU General Public License
7 * version 2. This program is licensed "as is" without any warranty of any
8 * kind, whether express or implied.
9 */
10
11#include <linux/clk.h>
12#include <linux/dmaengine.h>
13#include <linux/module.h>
14#include <linux/of_irq.h>
15#include <linux/of_platform.h>
16#include <sound/dmaengine_pcm.h>
17#include <sound/pcm_params.h>
18
19#include "fsl_esai.h"
20#include "imx-pcm.h"
21
22#define FSL_ESAI_RATES SNDRV_PCM_RATE_8000_192000
23#define FSL_ESAI_FORMATS (SNDRV_PCM_FMTBIT_S8 | \
24 SNDRV_PCM_FMTBIT_S16_LE | \
25 SNDRV_PCM_FMTBIT_S20_3LE | \
26 SNDRV_PCM_FMTBIT_S24_LE)
27
28/**
29 * fsl_esai: ESAI private data
30 *
31 * @dma_params_rx: DMA parameters for receive channel
32 * @dma_params_tx: DMA parameters for transmit channel
33 * @pdev: platform device pointer
34 * @regmap: regmap handler
35 * @coreclk: clock source to access register
36 * @extalclk: esai clock source to derive HCK, SCK and FS
37 * @fsysclk: system clock source to derive HCK, SCK and FS
38 * @fifo_depth: depth of tx/rx FIFO
39 * @slot_width: width of each DAI slot
40 * @hck_rate: clock rate of desired HCKx clock
41 * @sck_div: if using PSR/PM dividers for SCKx clock
42 * @slave_mode: if fully using DAI slave mode
43 * @synchronous: if using tx/rx synchronous mode
44 * @name: driver name
45 */
46struct fsl_esai {
47 struct snd_dmaengine_dai_dma_data dma_params_rx;
48 struct snd_dmaengine_dai_dma_data dma_params_tx;
49 struct platform_device *pdev;
50 struct regmap *regmap;
51 struct clk *coreclk;
52 struct clk *extalclk;
53 struct clk *fsysclk;
54 u32 fifo_depth;
55 u32 slot_width;
56 u32 hck_rate[2];
57 bool sck_div[2];
58 bool slave_mode;
59 bool synchronous;
60 char name[32];
61};
62
63static irqreturn_t esai_isr(int irq, void *devid)
64{
65 struct fsl_esai *esai_priv = (struct fsl_esai *)devid;
66 struct platform_device *pdev = esai_priv->pdev;
67 u32 esr;
68
69 regmap_read(esai_priv->regmap, REG_ESAI_ESR, &esr);
70
71 if (esr & ESAI_ESR_TINIT_MASK)
72 dev_dbg(&pdev->dev, "isr: Transmition Initialized\n");
73
74 if (esr & ESAI_ESR_RFF_MASK)
75 dev_warn(&pdev->dev, "isr: Receiving overrun\n");
76
77 if (esr & ESAI_ESR_TFE_MASK)
78 dev_warn(&pdev->dev, "isr: Transmition underrun\n");
79
80 if (esr & ESAI_ESR_TLS_MASK)
81 dev_dbg(&pdev->dev, "isr: Just transmitted the last slot\n");
82
83 if (esr & ESAI_ESR_TDE_MASK)
84 dev_dbg(&pdev->dev, "isr: Transmition data exception\n");
85
86 if (esr & ESAI_ESR_TED_MASK)
87 dev_dbg(&pdev->dev, "isr: Transmitting even slots\n");
88
89 if (esr & ESAI_ESR_TD_MASK)
90 dev_dbg(&pdev->dev, "isr: Transmitting data\n");
91
92 if (esr & ESAI_ESR_RLS_MASK)
93 dev_dbg(&pdev->dev, "isr: Just received the last slot\n");
94
95 if (esr & ESAI_ESR_RDE_MASK)
96 dev_dbg(&pdev->dev, "isr: Receiving data exception\n");
97
98 if (esr & ESAI_ESR_RED_MASK)
99 dev_dbg(&pdev->dev, "isr: Receiving even slots\n");
100
101 if (esr & ESAI_ESR_RD_MASK)
102 dev_dbg(&pdev->dev, "isr: Receiving data\n");
103
104 return IRQ_HANDLED;
105}
106
107/**
108 * This function is used to calculate the divisors of psr, pm, fp and it is
109 * supposed to be called in set_dai_sysclk() and set_bclk().
110 *
111 * @ratio: desired overall ratio for the paticipating dividers
112 * @usefp: for HCK setting, there is no need to set fp divider
113 * @fp: bypass other dividers by setting fp directly if fp != 0
114 * @tx: current setting is for playback or capture
115 */
116static int fsl_esai_divisor_cal(struct snd_soc_dai *dai, bool tx, u32 ratio,
117 bool usefp, u32 fp)
118{
119 struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai);
120 u32 psr, pm = 999, maxfp, prod, sub, savesub, i, j;
121
122 maxfp = usefp ? 16 : 1;
123
124 if (usefp && fp)
125 goto out_fp;
126
127 if (ratio > 2 * 8 * 256 * maxfp || ratio < 2) {
128 dev_err(dai->dev, "the ratio is out of range (2 ~ %d)\n",
129 2 * 8 * 256 * maxfp);
130 return -EINVAL;
131 } else if (ratio % 2) {
132 dev_err(dai->dev, "the raio must be even if using upper divider\n");
133 return -EINVAL;
134 }
135
136 ratio /= 2;
137
138 psr = ratio <= 256 * maxfp ? ESAI_xCCR_xPSR_BYPASS : ESAI_xCCR_xPSR_DIV8;
139
140 /* Set the max fluctuation -- 0.1% of the max devisor */
141 savesub = (psr ? 1 : 8) * 256 * maxfp / 1000;
142
143 /* Find the best value for PM */
144 for (i = 1; i <= 256; i++) {
145 for (j = 1; j <= maxfp; j++) {
146 /* PSR (1 or 8) * PM (1 ~ 256) * FP (1 ~ 16) */
147 prod = (psr ? 1 : 8) * i * j;
148
149 if (prod == ratio)
150 sub = 0;
151 else if (prod / ratio == 1)
152 sub = prod - ratio;
153 else if (ratio / prod == 1)
154 sub = ratio - prod;
155 else
156 continue;
157
158 /* Calculate the fraction */
159 sub = sub * 1000 / ratio;
160 if (sub < savesub) {
161 savesub = sub;
162 pm = i;
163 fp = j;
164 }
165
166 /* We are lucky */
167 if (savesub == 0)
168 goto out;
169 }
170 }
171
172 if (pm == 999) {
173 dev_err(dai->dev, "failed to calculate proper divisors\n");
174 return -EINVAL;
175 }
176
177out:
178 regmap_update_bits(esai_priv->regmap, REG_ESAI_xCCR(tx),
179 ESAI_xCCR_xPSR_MASK | ESAI_xCCR_xPM_MASK,
180 psr | ESAI_xCCR_xPM(pm));
181
182out_fp:
183 /* Bypass fp if not being required */
184 if (maxfp <= 1)
185 return 0;
186
187 regmap_update_bits(esai_priv->regmap, REG_ESAI_xCCR(tx),
188 ESAI_xCCR_xFP_MASK, ESAI_xCCR_xFP(fp));
189
190 return 0;
191}
192
193/**
194 * This function mainly configures the clock frequency of MCLK (HCKT/HCKR)
195 *
196 * @Parameters:
197 * clk_id: The clock source of HCKT/HCKR
198 * (Input from outside; output from inside, FSYS or EXTAL)
199 * freq: The required clock rate of HCKT/HCKR
200 * dir: The clock direction of HCKT/HCKR
201 *
202 * Note: If the direction is input, we do not care about clk_id.
203 */
204static int fsl_esai_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
205 unsigned int freq, int dir)
206{
207 struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai);
208 struct clk *clksrc = esai_priv->extalclk;
209 bool tx = clk_id <= ESAI_HCKT_EXTAL;
210 bool in = dir == SND_SOC_CLOCK_IN;
211 u32 ret, ratio, ecr = 0;
212 unsigned long clk_rate;
213
214 /* sck_div can be only bypassed if ETO/ERO=0 and SNC_SOC_CLOCK_OUT */
215 esai_priv->sck_div[tx] = true;
216
217 /* Set the direction of HCKT/HCKR pins */
218 regmap_update_bits(esai_priv->regmap, REG_ESAI_xCCR(tx),
219 ESAI_xCCR_xHCKD, in ? 0 : ESAI_xCCR_xHCKD);
220
221 if (in)
222 goto out;
223
224 switch (clk_id) {
225 case ESAI_HCKT_FSYS:
226 case ESAI_HCKR_FSYS:
227 clksrc = esai_priv->fsysclk;
228 break;
229 case ESAI_HCKT_EXTAL:
230 ecr |= ESAI_ECR_ETI;
231 case ESAI_HCKR_EXTAL:
232 ecr |= ESAI_ECR_ERI;
233 break;
234 default:
235 return -EINVAL;
236 }
237
238 if (IS_ERR(clksrc)) {
239 dev_err(dai->dev, "no assigned %s clock\n",
240 clk_id % 2 ? "extal" : "fsys");
241 return PTR_ERR(clksrc);
242 }
243 clk_rate = clk_get_rate(clksrc);
244
245 ratio = clk_rate / freq;
246 if (ratio * freq > clk_rate)
247 ret = ratio * freq - clk_rate;
248 else if (ratio * freq < clk_rate)
249 ret = clk_rate - ratio * freq;
250 else
251 ret = 0;
252
253 /* Block if clock source can not be divided into the required rate */
254 if (ret != 0 && clk_rate / ret < 1000) {
255 dev_err(dai->dev, "failed to derive required HCK%c rate\n",
256 tx ? 'T' : 'R');
257 return -EINVAL;
258 }
259
260 if (ratio == 1) {
261 /* Bypass all the dividers if not being needed */
262 ecr |= tx ? ESAI_ECR_ETO : ESAI_ECR_ERO;
263 goto out;
264 }
265
266 ret = fsl_esai_divisor_cal(dai, tx, ratio, false, 0);
267 if (ret)
268 return ret;
269
270 esai_priv->sck_div[tx] = false;
271
272out:
273 esai_priv->hck_rate[tx] = freq;
274
275 regmap_update_bits(esai_priv->regmap, REG_ESAI_ECR,
276 tx ? ESAI_ECR_ETI | ESAI_ECR_ETO :
277 ESAI_ECR_ERI | ESAI_ECR_ERO, ecr);
278
279 return 0;
280}
281
282/**
283 * This function configures the related dividers according to the bclk rate
284 */
285static int fsl_esai_set_bclk(struct snd_soc_dai *dai, bool tx, u32 freq)
286{
287 struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai);
288 u32 hck_rate = esai_priv->hck_rate[tx];
289 u32 sub, ratio = hck_rate / freq;
290
291 /* Don't apply for fully slave mode*/
292 if (esai_priv->slave_mode)
293 return 0;
294
295 if (ratio * freq > hck_rate)
296 sub = ratio * freq - hck_rate;
297 else if (ratio * freq < hck_rate)
298 sub = hck_rate - ratio * freq;
299 else
300 sub = 0;
301
302 /* Block if clock source can not be divided into the required rate */
303 if (sub != 0 && hck_rate / sub < 1000) {
304 dev_err(dai->dev, "failed to derive required SCK%c rate\n",
305 tx ? 'T' : 'R');
306 return -EINVAL;
307 }
308
309 if (esai_priv->sck_div[tx] && (ratio > 16 || ratio == 0)) {
310 dev_err(dai->dev, "the ratio is out of range (1 ~ 16)\n");
311 return -EINVAL;
312 }
313
314 return fsl_esai_divisor_cal(dai, tx, ratio, true,
315 esai_priv->sck_div[tx] ? 0 : ratio);
316}
317
318static int fsl_esai_set_dai_tdm_slot(struct snd_soc_dai *dai, u32 tx_mask,
319 u32 rx_mask, int slots, int slot_width)
320{
321 struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai);
322
323 regmap_update_bits(esai_priv->regmap, REG_ESAI_TCCR,
324 ESAI_xCCR_xDC_MASK, ESAI_xCCR_xDC(slots));
325
326 regmap_update_bits(esai_priv->regmap, REG_ESAI_TSMA,
327 ESAI_xSMA_xS_MASK, ESAI_xSMA_xS(tx_mask));
328 regmap_update_bits(esai_priv->regmap, REG_ESAI_TSMB,
329 ESAI_xSMA_xS_MASK, ESAI_xSMB_xS(tx_mask));
330
331 regmap_update_bits(esai_priv->regmap, REG_ESAI_RCCR,
332 ESAI_xCCR_xDC_MASK, ESAI_xCCR_xDC(slots));
333
334 regmap_update_bits(esai_priv->regmap, REG_ESAI_RSMA,
335 ESAI_xSMA_xS_MASK, ESAI_xSMA_xS(rx_mask));
336 regmap_update_bits(esai_priv->regmap, REG_ESAI_RSMB,
337 ESAI_xSMA_xS_MASK, ESAI_xSMB_xS(rx_mask));
338
339 esai_priv->slot_width = slot_width;
340
341 return 0;
342}
343
344static int fsl_esai_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
345{
346 struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai);
347 u32 xcr = 0, xccr = 0, mask;
348
349 /* DAI mode */
350 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
351 case SND_SOC_DAIFMT_I2S:
352 /* Data on rising edge of bclk, frame low, 1clk before data */
353 xcr |= ESAI_xCR_xFSR;
354 xccr |= ESAI_xCCR_xFSP | ESAI_xCCR_xCKP | ESAI_xCCR_xHCKP;
355 break;
356 case SND_SOC_DAIFMT_LEFT_J:
357 /* Data on rising edge of bclk, frame high */
358 xccr |= ESAI_xCCR_xCKP | ESAI_xCCR_xHCKP;
359 break;
360 case SND_SOC_DAIFMT_RIGHT_J:
361 /* Data on rising edge of bclk, frame high, right aligned */
362 xccr |= ESAI_xCCR_xCKP | ESAI_xCCR_xHCKP | ESAI_xCR_xWA;
363 break;
364 case SND_SOC_DAIFMT_DSP_A:
365 /* Data on rising edge of bclk, frame high, 1clk before data */
366 xcr |= ESAI_xCR_xFSL | ESAI_xCR_xFSR;
367 xccr |= ESAI_xCCR_xCKP | ESAI_xCCR_xHCKP;
368 break;
369 case SND_SOC_DAIFMT_DSP_B:
370 /* Data on rising edge of bclk, frame high */
371 xcr |= ESAI_xCR_xFSL;
372 xccr |= ESAI_xCCR_xCKP | ESAI_xCCR_xHCKP;
373 break;
374 default:
375 return -EINVAL;
376 }
377
378 /* DAI clock inversion */
379 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
380 case SND_SOC_DAIFMT_NB_NF:
381 /* Nothing to do for both normal cases */
382 break;
383 case SND_SOC_DAIFMT_IB_NF:
384 /* Invert bit clock */
385 xccr ^= ESAI_xCCR_xCKP | ESAI_xCCR_xHCKP;
386 break;
387 case SND_SOC_DAIFMT_NB_IF:
388 /* Invert frame clock */
389 xccr ^= ESAI_xCCR_xFSP;
390 break;
391 case SND_SOC_DAIFMT_IB_IF:
392 /* Invert both clocks */
393 xccr ^= ESAI_xCCR_xCKP | ESAI_xCCR_xHCKP | ESAI_xCCR_xFSP;
394 break;
395 default:
396 return -EINVAL;
397 }
398
399 esai_priv->slave_mode = false;
400
401 /* DAI clock master masks */
402 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
403 case SND_SOC_DAIFMT_CBM_CFM:
404 esai_priv->slave_mode = true;
405 break;
406 case SND_SOC_DAIFMT_CBS_CFM:
407 xccr |= ESAI_xCCR_xCKD;
408 break;
409 case SND_SOC_DAIFMT_CBM_CFS:
410 xccr |= ESAI_xCCR_xFSD;
411 break;
412 case SND_SOC_DAIFMT_CBS_CFS:
413 xccr |= ESAI_xCCR_xFSD | ESAI_xCCR_xCKD;
414 break;
415 default:
416 return -EINVAL;
417 }
418
419 mask = ESAI_xCR_xFSL | ESAI_xCR_xFSR;
420 regmap_update_bits(esai_priv->regmap, REG_ESAI_TCR, mask, xcr);
421 regmap_update_bits(esai_priv->regmap, REG_ESAI_RCR, mask, xcr);
422
423 mask = ESAI_xCCR_xCKP | ESAI_xCCR_xHCKP | ESAI_xCCR_xFSP |
424 ESAI_xCCR_xFSD | ESAI_xCCR_xCKD | ESAI_xCR_xWA;
425 regmap_update_bits(esai_priv->regmap, REG_ESAI_TCCR, mask, xccr);
426 regmap_update_bits(esai_priv->regmap, REG_ESAI_RCCR, mask, xccr);
427
428 return 0;
429}
430
431static int fsl_esai_startup(struct snd_pcm_substream *substream,
432 struct snd_soc_dai *dai)
433{
434 struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai);
435
436 /*
437 * Some platforms might use the same bit to gate all three or two of
438 * clocks, so keep all clocks open/close at the same time for safety
439 */
440 clk_prepare_enable(esai_priv->coreclk);
441 if (!IS_ERR(esai_priv->extalclk))
442 clk_prepare_enable(esai_priv->extalclk);
443 if (!IS_ERR(esai_priv->fsysclk))
444 clk_prepare_enable(esai_priv->fsysclk);
445
446 if (!dai->active) {
447 /* Reset Port C */
448 regmap_update_bits(esai_priv->regmap, REG_ESAI_PRRC,
449 ESAI_PRRC_PDC_MASK, ESAI_PRRC_PDC(ESAI_GPIO));
450 regmap_update_bits(esai_priv->regmap, REG_ESAI_PCRC,
451 ESAI_PCRC_PC_MASK, ESAI_PCRC_PC(ESAI_GPIO));
452
453 /* Set synchronous mode */
454 regmap_update_bits(esai_priv->regmap, REG_ESAI_SAICR,
455 ESAI_SAICR_SYNC, esai_priv->synchronous ?
456 ESAI_SAICR_SYNC : 0);
457
458 /* Set a default slot number -- 2 */
459 regmap_update_bits(esai_priv->regmap, REG_ESAI_TCCR,
460 ESAI_xCCR_xDC_MASK, ESAI_xCCR_xDC(2));
461 regmap_update_bits(esai_priv->regmap, REG_ESAI_RCCR,
462 ESAI_xCCR_xDC_MASK, ESAI_xCCR_xDC(2));
463 }
464
465 return 0;
466}
467
468static int fsl_esai_hw_params(struct snd_pcm_substream *substream,
469 struct snd_pcm_hw_params *params,
470 struct snd_soc_dai *dai)
471{
472 struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai);
473 bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
474 u32 width = snd_pcm_format_width(params_format(params));
475 u32 channels = params_channels(params);
476 u32 bclk, mask, val, ret;
477
478 bclk = params_rate(params) * esai_priv->slot_width * 2;
479
480 ret = fsl_esai_set_bclk(dai, tx, bclk);
481 if (ret)
482 return ret;
483
484 /* Use Normal mode to support monaural audio */
485 regmap_update_bits(esai_priv->regmap, REG_ESAI_xCR(tx),
486 ESAI_xCR_xMOD_MASK, params_channels(params) > 1 ?
487 ESAI_xCR_xMOD_NETWORK : 0);
488
489 regmap_update_bits(esai_priv->regmap, REG_ESAI_xFCR(tx),
490 ESAI_xFCR_xFR_MASK, ESAI_xFCR_xFR);
491
492 mask = ESAI_xFCR_xFR_MASK | ESAI_xFCR_xWA_MASK | ESAI_xFCR_xFWM_MASK |
493 (tx ? ESAI_xFCR_TE_MASK | ESAI_xFCR_TIEN : ESAI_xFCR_RE_MASK);
494 val = ESAI_xFCR_xWA(width) | ESAI_xFCR_xFWM(esai_priv->fifo_depth) |
495 (tx ? ESAI_xFCR_TE(channels) | ESAI_xFCR_TIEN : ESAI_xFCR_RE(channels));
496
497 regmap_update_bits(esai_priv->regmap, REG_ESAI_xFCR(tx), mask, val);
498
499 mask = ESAI_xCR_xSWS_MASK | (tx ? ESAI_xCR_PADC : 0);
500 val = ESAI_xCR_xSWS(esai_priv->slot_width, width) | (tx ? ESAI_xCR_PADC : 0);
501
502 regmap_update_bits(esai_priv->regmap, REG_ESAI_xCR(tx), mask, val);
503
504 return 0;
505}
506
507static void fsl_esai_shutdown(struct snd_pcm_substream *substream,
508 struct snd_soc_dai *dai)
509{
510 struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai);
511
512 if (!IS_ERR(esai_priv->fsysclk))
513 clk_disable_unprepare(esai_priv->fsysclk);
514 if (!IS_ERR(esai_priv->extalclk))
515 clk_disable_unprepare(esai_priv->extalclk);
516 clk_disable_unprepare(esai_priv->coreclk);
517}
518
519static int fsl_esai_trigger(struct snd_pcm_substream *substream, int cmd,
520 struct snd_soc_dai *dai)
521{
522 struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai);
523 bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
524 u8 i, channels = substream->runtime->channels;
525
526 switch (cmd) {
527 case SNDRV_PCM_TRIGGER_START:
528 case SNDRV_PCM_TRIGGER_RESUME:
529 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
530 regmap_update_bits(esai_priv->regmap, REG_ESAI_xFCR(tx),
531 ESAI_xFCR_xFEN_MASK, ESAI_xFCR_xFEN);
532
533 /* Write initial words reqiured by ESAI as normal procedure */
534 for (i = 0; tx && i < channels; i++)
535 regmap_write(esai_priv->regmap, REG_ESAI_ETDR, 0x0);
536
537 regmap_update_bits(esai_priv->regmap, REG_ESAI_xCR(tx),
538 tx ? ESAI_xCR_TE_MASK : ESAI_xCR_RE_MASK,
539 tx ? ESAI_xCR_TE(channels) : ESAI_xCR_RE(channels));
540 break;
541 case SNDRV_PCM_TRIGGER_SUSPEND:
542 case SNDRV_PCM_TRIGGER_STOP:
543 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
544 regmap_update_bits(esai_priv->regmap, REG_ESAI_xCR(tx),
545 tx ? ESAI_xCR_TE_MASK : ESAI_xCR_RE_MASK, 0);
546
547 /* Disable and reset FIFO */
548 regmap_update_bits(esai_priv->regmap, REG_ESAI_xFCR(tx),
549 ESAI_xFCR_xFR | ESAI_xFCR_xFEN, ESAI_xFCR_xFR);
550 regmap_update_bits(esai_priv->regmap, REG_ESAI_xFCR(tx),
551 ESAI_xFCR_xFR, 0);
552 break;
553 default:
554 return -EINVAL;
555 }
556
557 return 0;
558}
559
560static struct snd_soc_dai_ops fsl_esai_dai_ops = {
561 .startup = fsl_esai_startup,
562 .shutdown = fsl_esai_shutdown,
563 .trigger = fsl_esai_trigger,
564 .hw_params = fsl_esai_hw_params,
565 .set_sysclk = fsl_esai_set_dai_sysclk,
566 .set_fmt = fsl_esai_set_dai_fmt,
567 .set_tdm_slot = fsl_esai_set_dai_tdm_slot,
568};
569
570static int fsl_esai_dai_probe(struct snd_soc_dai *dai)
571{
572 struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai);
573
574 snd_soc_dai_init_dma_data(dai, &esai_priv->dma_params_tx,
575 &esai_priv->dma_params_rx);
576
577 return 0;
578}
579
580static struct snd_soc_dai_driver fsl_esai_dai = {
581 .probe = fsl_esai_dai_probe,
582 .playback = {
583 .channels_min = 1,
584 .channels_max = 12,
585 .rates = FSL_ESAI_RATES,
586 .formats = FSL_ESAI_FORMATS,
587 },
588 .capture = {
589 .channels_min = 1,
590 .channels_max = 8,
591 .rates = FSL_ESAI_RATES,
592 .formats = FSL_ESAI_FORMATS,
593 },
594 .ops = &fsl_esai_dai_ops,
595};
596
597static const struct snd_soc_component_driver fsl_esai_component = {
598 .name = "fsl-esai",
599};
600
601static bool fsl_esai_readable_reg(struct device *dev, unsigned int reg)
602{
603 switch (reg) {
604 case REG_ESAI_ERDR:
605 case REG_ESAI_ECR:
606 case REG_ESAI_ESR:
607 case REG_ESAI_TFCR:
608 case REG_ESAI_TFSR:
609 case REG_ESAI_RFCR:
610 case REG_ESAI_RFSR:
611 case REG_ESAI_RX0:
612 case REG_ESAI_RX1:
613 case REG_ESAI_RX2:
614 case REG_ESAI_RX3:
615 case REG_ESAI_SAISR:
616 case REG_ESAI_SAICR:
617 case REG_ESAI_TCR:
618 case REG_ESAI_TCCR:
619 case REG_ESAI_RCR:
620 case REG_ESAI_RCCR:
621 case REG_ESAI_TSMA:
622 case REG_ESAI_TSMB:
623 case REG_ESAI_RSMA:
624 case REG_ESAI_RSMB:
625 case REG_ESAI_PRRC:
626 case REG_ESAI_PCRC:
627 return true;
628 default:
629 return false;
630 }
631}
632
633static bool fsl_esai_writeable_reg(struct device *dev, unsigned int reg)
634{
635 switch (reg) {
636 case REG_ESAI_ETDR:
637 case REG_ESAI_ECR:
638 case REG_ESAI_TFCR:
639 case REG_ESAI_RFCR:
640 case REG_ESAI_TX0:
641 case REG_ESAI_TX1:
642 case REG_ESAI_TX2:
643 case REG_ESAI_TX3:
644 case REG_ESAI_TX4:
645 case REG_ESAI_TX5:
646 case REG_ESAI_TSR:
647 case REG_ESAI_SAICR:
648 case REG_ESAI_TCR:
649 case REG_ESAI_TCCR:
650 case REG_ESAI_RCR:
651 case REG_ESAI_RCCR:
652 case REG_ESAI_TSMA:
653 case REG_ESAI_TSMB:
654 case REG_ESAI_RSMA:
655 case REG_ESAI_RSMB:
656 case REG_ESAI_PRRC:
657 case REG_ESAI_PCRC:
658 return true;
659 default:
660 return false;
661 }
662}
663
664static const struct regmap_config fsl_esai_regmap_config = {
665 .reg_bits = 32,
666 .reg_stride = 4,
667 .val_bits = 32,
668
669 .max_register = REG_ESAI_PCRC,
670 .readable_reg = fsl_esai_readable_reg,
671 .writeable_reg = fsl_esai_writeable_reg,
672};
673
674static int fsl_esai_probe(struct platform_device *pdev)
675{
676 struct device_node *np = pdev->dev.of_node;
677 struct fsl_esai *esai_priv;
678 struct resource *res;
679 const uint32_t *iprop;
680 void __iomem *regs;
681 int irq, ret;
682
683 esai_priv = devm_kzalloc(&pdev->dev, sizeof(*esai_priv), GFP_KERNEL);
684 if (!esai_priv)
685 return -ENOMEM;
686
687 esai_priv->pdev = pdev;
688 strcpy(esai_priv->name, np->name);
689
690 /* Get the addresses and IRQ */
691 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
692 regs = devm_ioremap_resource(&pdev->dev, res);
693 if (IS_ERR(regs))
694 return PTR_ERR(regs);
695
696 esai_priv->regmap = devm_regmap_init_mmio_clk(&pdev->dev,
697 "core", regs, &fsl_esai_regmap_config);
698 if (IS_ERR(esai_priv->regmap)) {
699 dev_err(&pdev->dev, "failed to init regmap: %ld\n",
700 PTR_ERR(esai_priv->regmap));
701 return PTR_ERR(esai_priv->regmap);
702 }
703
704 esai_priv->coreclk = devm_clk_get(&pdev->dev, "core");
705 if (IS_ERR(esai_priv->coreclk)) {
706 dev_err(&pdev->dev, "failed to get core clock: %ld\n",
707 PTR_ERR(esai_priv->coreclk));
708 return PTR_ERR(esai_priv->coreclk);
709 }
710
711 esai_priv->extalclk = devm_clk_get(&pdev->dev, "extal");
712 if (IS_ERR(esai_priv->extalclk))
713 dev_warn(&pdev->dev, "failed to get extal clock: %ld\n",
714 PTR_ERR(esai_priv->extalclk));
715
716 esai_priv->fsysclk = devm_clk_get(&pdev->dev, "fsys");
717 if (IS_ERR(esai_priv->fsysclk))
718 dev_warn(&pdev->dev, "failed to get fsys clock: %ld\n",
719 PTR_ERR(esai_priv->fsysclk));
720
721 irq = platform_get_irq(pdev, 0);
722 if (irq < 0) {
723 dev_err(&pdev->dev, "no irq for node %s\n", np->full_name);
724 return irq;
725 }
726
727 ret = devm_request_irq(&pdev->dev, irq, esai_isr, 0,
728 esai_priv->name, esai_priv);
729 if (ret) {
730 dev_err(&pdev->dev, "failed to claim irq %u\n", irq);
731 return ret;
732 }
733
734 /* Set a default slot size */
735 esai_priv->slot_width = 32;
736
737 /* Set a default master/slave state */
738 esai_priv->slave_mode = true;
739
740 /* Determine the FIFO depth */
741 iprop = of_get_property(np, "fsl,fifo-depth", NULL);
742 if (iprop)
743 esai_priv->fifo_depth = be32_to_cpup(iprop);
744 else
745 esai_priv->fifo_depth = 64;
746
747 esai_priv->dma_params_tx.maxburst = 16;
748 esai_priv->dma_params_rx.maxburst = 16;
749 esai_priv->dma_params_tx.addr = res->start + REG_ESAI_ETDR;
750 esai_priv->dma_params_rx.addr = res->start + REG_ESAI_ERDR;
751
752 esai_priv->synchronous =
753 of_property_read_bool(np, "fsl,esai-synchronous");
754
755 /* Implement full symmetry for synchronous mode */
756 if (esai_priv->synchronous) {
757 fsl_esai_dai.symmetric_rates = 1;
758 fsl_esai_dai.symmetric_channels = 1;
759 fsl_esai_dai.symmetric_samplebits = 1;
760 }
761
762 dev_set_drvdata(&pdev->dev, esai_priv);
763
764 /* Reset ESAI unit */
765 ret = regmap_write(esai_priv->regmap, REG_ESAI_ECR, ESAI_ECR_ERST);
766 if (ret) {
767 dev_err(&pdev->dev, "failed to reset ESAI: %d\n", ret);
768 return ret;
769 }
770
771 /*
772 * We need to enable ESAI so as to access some of its registers.
773 * Otherwise, we would fail to dump regmap from user space.
774 */
775 ret = regmap_write(esai_priv->regmap, REG_ESAI_ECR, ESAI_ECR_ESAIEN);
776 if (ret) {
777 dev_err(&pdev->dev, "failed to enable ESAI: %d\n", ret);
778 return ret;
779 }
780
781 ret = devm_snd_soc_register_component(&pdev->dev, &fsl_esai_component,
782 &fsl_esai_dai, 1);
783 if (ret) {
784 dev_err(&pdev->dev, "failed to register DAI: %d\n", ret);
785 return ret;
786 }
787
788 ret = imx_pcm_dma_init(pdev);
789 if (ret)
790 dev_err(&pdev->dev, "failed to init imx pcm dma: %d\n", ret);
791
792 return ret;
793}
794
795static const struct of_device_id fsl_esai_dt_ids[] = {
796 { .compatible = "fsl,imx35-esai", },
797 {}
798};
799MODULE_DEVICE_TABLE(of, fsl_esai_dt_ids);
800
801static struct platform_driver fsl_esai_driver = {
802 .probe = fsl_esai_probe,
803 .driver = {
804 .name = "fsl-esai-dai",
805 .owner = THIS_MODULE,
806 .of_match_table = fsl_esai_dt_ids,
807 },
808};
809
810module_platform_driver(fsl_esai_driver);
811
812MODULE_AUTHOR("Freescale Semiconductor, Inc.");
813MODULE_DESCRIPTION("Freescale ESAI CPU DAI driver");
814MODULE_LICENSE("GPL v2");
815MODULE_ALIAS("platform:fsl-esai-dai");
diff --git a/sound/soc/fsl/fsl_esai.h b/sound/soc/fsl/fsl_esai.h
new file mode 100644
index 000000000000..9c9f957fcae1
--- /dev/null
+++ b/sound/soc/fsl/fsl_esai.h
@@ -0,0 +1,354 @@
1/*
2 * fsl_esai.h - ALSA ESAI interface for the Freescale i.MX SoC
3 *
4 * Copyright (C) 2014 Freescale Semiconductor, Inc.
5 *
6 * Author: Nicolin Chen <Guangyu.Chen@freescale.com>
7 *
8 * This file is licensed under the terms of the GNU General Public License
9 * version 2. This program is licensed "as is" without any warranty of any
10 * kind, whether express or implied.
11 */
12
13#ifndef _FSL_ESAI_DAI_H
14#define _FSL_ESAI_DAI_H
15
16/* ESAI Register Map */
17#define REG_ESAI_ETDR 0x00
18#define REG_ESAI_ERDR 0x04
19#define REG_ESAI_ECR 0x08
20#define REG_ESAI_ESR 0x0C
21#define REG_ESAI_TFCR 0x10
22#define REG_ESAI_TFSR 0x14
23#define REG_ESAI_RFCR 0x18
24#define REG_ESAI_RFSR 0x1C
25#define REG_ESAI_xFCR(tx) (tx ? REG_ESAI_TFCR : REG_ESAI_RFCR)
26#define REG_ESAI_xFSR(tx) (tx ? REG_ESAI_TFSR : REG_ESAI_RFSR)
27#define REG_ESAI_TX0 0x80
28#define REG_ESAI_TX1 0x84
29#define REG_ESAI_TX2 0x88
30#define REG_ESAI_TX3 0x8C
31#define REG_ESAI_TX4 0x90
32#define REG_ESAI_TX5 0x94
33#define REG_ESAI_TSR 0x98
34#define REG_ESAI_RX0 0xA0
35#define REG_ESAI_RX1 0xA4
36#define REG_ESAI_RX2 0xA8
37#define REG_ESAI_RX3 0xAC
38#define REG_ESAI_SAISR 0xCC
39#define REG_ESAI_SAICR 0xD0
40#define REG_ESAI_TCR 0xD4
41#define REG_ESAI_TCCR 0xD8
42#define REG_ESAI_RCR 0xDC
43#define REG_ESAI_RCCR 0xE0
44#define REG_ESAI_xCR(tx) (tx ? REG_ESAI_TCR : REG_ESAI_RCR)
45#define REG_ESAI_xCCR(tx) (tx ? REG_ESAI_TCCR : REG_ESAI_RCCR)
46#define REG_ESAI_TSMA 0xE4
47#define REG_ESAI_TSMB 0xE8
48#define REG_ESAI_RSMA 0xEC
49#define REG_ESAI_RSMB 0xF0
50#define REG_ESAI_xSMA(tx) (tx ? REG_ESAI_TSMA : REG_ESAI_RSMA)
51#define REG_ESAI_xSMB(tx) (tx ? REG_ESAI_TSMB : REG_ESAI_RSMB)
52#define REG_ESAI_PRRC 0xF8
53#define REG_ESAI_PCRC 0xFC
54
55/* ESAI Control Register -- REG_ESAI_ECR 0x8 */
56#define ESAI_ECR_ETI_SHIFT 19
57#define ESAI_ECR_ETI_MASK (1 << ESAI_ECR_ETI_SHIFT)
58#define ESAI_ECR_ETI (1 << ESAI_ECR_ETI_SHIFT)
59#define ESAI_ECR_ETO_SHIFT 18
60#define ESAI_ECR_ETO_MASK (1 << ESAI_ECR_ETO_SHIFT)
61#define ESAI_ECR_ETO (1 << ESAI_ECR_ETO_SHIFT)
62#define ESAI_ECR_ERI_SHIFT 17
63#define ESAI_ECR_ERI_MASK (1 << ESAI_ECR_ERI_SHIFT)
64#define ESAI_ECR_ERI (1 << ESAI_ECR_ERI_SHIFT)
65#define ESAI_ECR_ERO_SHIFT 16
66#define ESAI_ECR_ERO_MASK (1 << ESAI_ECR_ERO_SHIFT)
67#define ESAI_ECR_ERO (1 << ESAI_ECR_ERO_SHIFT)
68#define ESAI_ECR_ERST_SHIFT 1
69#define ESAI_ECR_ERST_MASK (1 << ESAI_ECR_ERST_SHIFT)
70#define ESAI_ECR_ERST (1 << ESAI_ECR_ERST_SHIFT)
71#define ESAI_ECR_ESAIEN_SHIFT 0
72#define ESAI_ECR_ESAIEN_MASK (1 << ESAI_ECR_ESAIEN_SHIFT)
73#define ESAI_ECR_ESAIEN (1 << ESAI_ECR_ESAIEN_SHIFT)
74
75/* ESAI Status Register -- REG_ESAI_ESR 0xC */
76#define ESAI_ESR_TINIT_SHIFT 10
77#define ESAI_ESR_TINIT_MASK (1 << ESAI_ESR_TINIT_SHIFT)
78#define ESAI_ESR_TINIT (1 << ESAI_ESR_TINIT_SHIFT)
79#define ESAI_ESR_RFF_SHIFT 9
80#define ESAI_ESR_RFF_MASK (1 << ESAI_ESR_RFF_SHIFT)
81#define ESAI_ESR_RFF (1 << ESAI_ESR_RFF_SHIFT)
82#define ESAI_ESR_TFE_SHIFT 8
83#define ESAI_ESR_TFE_MASK (1 << ESAI_ESR_TFE_SHIFT)
84#define ESAI_ESR_TFE (1 << ESAI_ESR_TFE_SHIFT)
85#define ESAI_ESR_TLS_SHIFT 7
86#define ESAI_ESR_TLS_MASK (1 << ESAI_ESR_TLS_SHIFT)
87#define ESAI_ESR_TLS (1 << ESAI_ESR_TLS_SHIFT)
88#define ESAI_ESR_TDE_SHIFT 6
89#define ESAI_ESR_TDE_MASK (1 << ESAI_ESR_TDE_SHIFT)
90#define ESAI_ESR_TDE (1 << ESAI_ESR_TDE_SHIFT)
91#define ESAI_ESR_TED_SHIFT 5
92#define ESAI_ESR_TED_MASK (1 << ESAI_ESR_TED_SHIFT)
93#define ESAI_ESR_TED (1 << ESAI_ESR_TED_SHIFT)
94#define ESAI_ESR_TD_SHIFT 4
95#define ESAI_ESR_TD_MASK (1 << ESAI_ESR_TD_SHIFT)
96#define ESAI_ESR_TD (1 << ESAI_ESR_TD_SHIFT)
97#define ESAI_ESR_RLS_SHIFT 3
98#define ESAI_ESR_RLS_MASK (1 << ESAI_ESR_RLS_SHIFT)
99#define ESAI_ESR_RLS (1 << ESAI_ESR_RLS_SHIFT)
100#define ESAI_ESR_RDE_SHIFT 2
101#define ESAI_ESR_RDE_MASK (1 << ESAI_ESR_RDE_SHIFT)
102#define ESAI_ESR_RDE (1 << ESAI_ESR_RDE_SHIFT)
103#define ESAI_ESR_RED_SHIFT 1
104#define ESAI_ESR_RED_MASK (1 << ESAI_ESR_RED_SHIFT)
105#define ESAI_ESR_RED (1 << ESAI_ESR_RED_SHIFT)
106#define ESAI_ESR_RD_SHIFT 0
107#define ESAI_ESR_RD_MASK (1 << ESAI_ESR_RD_SHIFT)
108#define ESAI_ESR_RD (1 << ESAI_ESR_RD_SHIFT)
109
110/*
111 * Transmit FIFO Configuration Register -- REG_ESAI_TFCR 0x10
112 * Receive FIFO Configuration Register -- REG_ESAI_RFCR 0x18
113 */
114#define ESAI_xFCR_TIEN_SHIFT 19
115#define ESAI_xFCR_TIEN_MASK (1 << ESAI_xFCR_TIEN_SHIFT)
116#define ESAI_xFCR_TIEN (1 << ESAI_xFCR_TIEN_SHIFT)
117#define ESAI_xFCR_REXT_SHIFT 19
118#define ESAI_xFCR_REXT_MASK (1 << ESAI_xFCR_REXT_SHIFT)
119#define ESAI_xFCR_REXT (1 << ESAI_xFCR_REXT_SHIFT)
120#define ESAI_xFCR_xWA_SHIFT 16
121#define ESAI_xFCR_xWA_WIDTH 3
122#define ESAI_xFCR_xWA_MASK (((1 << ESAI_xFCR_xWA_WIDTH) - 1) << ESAI_xFCR_xWA_SHIFT)
123#define ESAI_xFCR_xWA(v) (((8 - ((v) >> 2)) << ESAI_xFCR_xWA_SHIFT) & ESAI_xFCR_xWA_MASK)
124#define ESAI_xFCR_xFWM_SHIFT 8
125#define ESAI_xFCR_xFWM_WIDTH 8
126#define ESAI_xFCR_xFWM_MASK (((1 << ESAI_xFCR_xFWM_WIDTH) - 1) << ESAI_xFCR_xFWM_SHIFT)
127#define ESAI_xFCR_xFWM(v) ((((v) - 1) << ESAI_xFCR_xFWM_SHIFT) & ESAI_xFCR_xFWM_MASK)
128#define ESAI_xFCR_xE_SHIFT 2
129#define ESAI_xFCR_TE_WIDTH 6
130#define ESAI_xFCR_RE_WIDTH 4
131#define ESAI_xFCR_TE_MASK (((1 << ESAI_xFCR_TE_WIDTH) - 1) << ESAI_xFCR_xE_SHIFT)
132#define ESAI_xFCR_RE_MASK (((1 << ESAI_xFCR_RE_WIDTH) - 1) << ESAI_xFCR_xE_SHIFT)
133#define ESAI_xFCR_TE(x) ((ESAI_xFCR_TE_MASK >> (ESAI_xFCR_TE_WIDTH - ((x + 1) >> 1))) & ESAI_xFCR_TE_MASK)
134#define ESAI_xFCR_RE(x) ((ESAI_xFCR_RE_MASK >> (ESAI_xFCR_RE_WIDTH - ((x + 1) >> 1))) & ESAI_xFCR_RE_MASK)
135#define ESAI_xFCR_xFR_SHIFT 1
136#define ESAI_xFCR_xFR_MASK (1 << ESAI_xFCR_xFR_SHIFT)
137#define ESAI_xFCR_xFR (1 << ESAI_xFCR_xFR_SHIFT)
138#define ESAI_xFCR_xFEN_SHIFT 0
139#define ESAI_xFCR_xFEN_MASK (1 << ESAI_xFCR_xFEN_SHIFT)
140#define ESAI_xFCR_xFEN (1 << ESAI_xFCR_xFEN_SHIFT)
141
142/*
143 * Transmit FIFO Status Register -- REG_ESAI_TFSR 0x14
144 * Receive FIFO Status Register --REG_ESAI_RFSR 0x1C
145 */
146#define ESAI_xFSR_NTFO_SHIFT 12
147#define ESAI_xFSR_NRFI_SHIFT 12
148#define ESAI_xFSR_NTFI_SHIFT 8
149#define ESAI_xFSR_NRFO_SHIFT 8
150#define ESAI_xFSR_NTFx_WIDTH 3
151#define ESAI_xFSR_NRFx_WIDTH 2
152#define ESAI_xFSR_NTFO_MASK (((1 << ESAI_xFSR_NTFx_WIDTH) - 1) << ESAI_xFSR_NTFO_SHIFT)
153#define ESAI_xFSR_NTFI_MASK (((1 << ESAI_xFSR_NTFx_WIDTH) - 1) << ESAI_xFSR_NTFI_SHIFT)
154#define ESAI_xFSR_NRFO_MASK (((1 << ESAI_xFSR_NRFx_WIDTH) - 1) << ESAI_xFSR_NRFO_SHIFT)
155#define ESAI_xFSR_NRFI_MASK (((1 << ESAI_xFSR_NRFx_WIDTH) - 1) << ESAI_xFSR_NRFI_SHIFT)
156#define ESAI_xFSR_xFCNT_SHIFT 0
157#define ESAI_xFSR_xFCNT_WIDTH 8
158#define ESAI_xFSR_xFCNT_MASK (((1 << ESAI_xFSR_xFCNT_WIDTH) - 1) << ESAI_xFSR_xFCNT_SHIFT)
159
160/* ESAI Transmit Slot Register -- REG_ESAI_TSR 0x98 */
161#define ESAI_TSR_SHIFT 0
162#define ESAI_TSR_WIDTH 24
163#define ESAI_TSR_MASK (((1 << ESAI_TSR_WIDTH) - 1) << ESAI_TSR_SHIFT)
164
165/* Serial Audio Interface Status Register -- REG_ESAI_SAISR 0xCC */
166#define ESAI_SAISR_TODFE_SHIFT 17
167#define ESAI_SAISR_TODFE_MASK (1 << ESAI_SAISR_TODFE_SHIFT)
168#define ESAI_SAISR_TODFE (1 << ESAI_SAISR_TODFE_SHIFT)
169#define ESAI_SAISR_TEDE_SHIFT 16
170#define ESAI_SAISR_TEDE_MASK (1 << ESAI_SAISR_TEDE_SHIFT)
171#define ESAI_SAISR_TEDE (1 << ESAI_SAISR_TEDE_SHIFT)
172#define ESAI_SAISR_TDE_SHIFT 15
173#define ESAI_SAISR_TDE_MASK (1 << ESAI_SAISR_TDE_SHIFT)
174#define ESAI_SAISR_TDE (1 << ESAI_SAISR_TDE_SHIFT)
175#define ESAI_SAISR_TUE_SHIFT 14
176#define ESAI_SAISR_TUE_MASK (1 << ESAI_SAISR_TUE_SHIFT)
177#define ESAI_SAISR_TUE (1 << ESAI_SAISR_TUE_SHIFT)
178#define ESAI_SAISR_TFS_SHIFT 13
179#define ESAI_SAISR_TFS_MASK (1 << ESAI_SAISR_TFS_SHIFT)
180#define ESAI_SAISR_TFS (1 << ESAI_SAISR_TFS_SHIFT)
181#define ESAI_SAISR_RODF_SHIFT 10
182#define ESAI_SAISR_RODF_MASK (1 << ESAI_SAISR_RODF_SHIFT)
183#define ESAI_SAISR_RODF (1 << ESAI_SAISR_RODF_SHIFT)
184#define ESAI_SAISR_REDF_SHIFT 9
185#define ESAI_SAISR_REDF_MASK (1 << ESAI_SAISR_REDF_SHIFT)
186#define ESAI_SAISR_REDF (1 << ESAI_SAISR_REDF_SHIFT)
187#define ESAI_SAISR_RDF_SHIFT 8
188#define ESAI_SAISR_RDF_MASK (1 << ESAI_SAISR_RDF_SHIFT)
189#define ESAI_SAISR_RDF (1 << ESAI_SAISR_RDF_SHIFT)
190#define ESAI_SAISR_ROE_SHIFT 7
191#define ESAI_SAISR_ROE_MASK (1 << ESAI_SAISR_ROE_SHIFT)
192#define ESAI_SAISR_ROE (1 << ESAI_SAISR_ROE_SHIFT)
193#define ESAI_SAISR_RFS_SHIFT 6
194#define ESAI_SAISR_RFS_MASK (1 << ESAI_SAISR_RFS_SHIFT)
195#define ESAI_SAISR_RFS (1 << ESAI_SAISR_RFS_SHIFT)
196#define ESAI_SAISR_IF2_SHIFT 2
197#define ESAI_SAISR_IF2_MASK (1 << ESAI_SAISR_IF2_SHIFT)
198#define ESAI_SAISR_IF2 (1 << ESAI_SAISR_IF2_SHIFT)
199#define ESAI_SAISR_IF1_SHIFT 1
200#define ESAI_SAISR_IF1_MASK (1 << ESAI_SAISR_IF1_SHIFT)
201#define ESAI_SAISR_IF1 (1 << ESAI_SAISR_IF1_SHIFT)
202#define ESAI_SAISR_IF0_SHIFT 0
203#define ESAI_SAISR_IF0_MASK (1 << ESAI_SAISR_IF0_SHIFT)
204#define ESAI_SAISR_IF0 (1 << ESAI_SAISR_IF0_SHIFT)
205
206/* Serial Audio Interface Control Register -- REG_ESAI_SAICR 0xD0 */
207#define ESAI_SAICR_ALC_SHIFT 8
208#define ESAI_SAICR_ALC_MASK (1 << ESAI_SAICR_ALC_SHIFT)
209#define ESAI_SAICR_ALC (1 << ESAI_SAICR_ALC_SHIFT)
210#define ESAI_SAICR_TEBE_SHIFT 7
211#define ESAI_SAICR_TEBE_MASK (1 << ESAI_SAICR_TEBE_SHIFT)
212#define ESAI_SAICR_TEBE (1 << ESAI_SAICR_TEBE_SHIFT)
213#define ESAI_SAICR_SYNC_SHIFT 6
214#define ESAI_SAICR_SYNC_MASK (1 << ESAI_SAICR_SYNC_SHIFT)
215#define ESAI_SAICR_SYNC (1 << ESAI_SAICR_SYNC_SHIFT)
216#define ESAI_SAICR_OF2_SHIFT 2
217#define ESAI_SAICR_OF2_MASK (1 << ESAI_SAICR_OF2_SHIFT)
218#define ESAI_SAICR_OF2 (1 << ESAI_SAICR_OF2_SHIFT)
219#define ESAI_SAICR_OF1_SHIFT 1
220#define ESAI_SAICR_OF1_MASK (1 << ESAI_SAICR_OF1_SHIFT)
221#define ESAI_SAICR_OF1 (1 << ESAI_SAICR_OF1_SHIFT)
222#define ESAI_SAICR_OF0_SHIFT 0
223#define ESAI_SAICR_OF0_MASK (1 << ESAI_SAICR_OF0_SHIFT)
224#define ESAI_SAICR_OF0 (1 << ESAI_SAICR_OF0_SHIFT)
225
226/*
227 * Transmit Control Register -- REG_ESAI_TCR 0xD4
228 * Receive Control Register -- REG_ESAI_RCR 0xDC
229 */
230#define ESAI_xCR_xLIE_SHIFT 23
231#define ESAI_xCR_xLIE_MASK (1 << ESAI_xCR_xLIE_SHIFT)
232#define ESAI_xCR_xLIE (1 << ESAI_xCR_xLIE_SHIFT)
233#define ESAI_xCR_xIE_SHIFT 22
234#define ESAI_xCR_xIE_MASK (1 << ESAI_xCR_xIE_SHIFT)
235#define ESAI_xCR_xIE (1 << ESAI_xCR_xIE_SHIFT)
236#define ESAI_xCR_xEDIE_SHIFT 21
237#define ESAI_xCR_xEDIE_MASK (1 << ESAI_xCR_xEDIE_SHIFT)
238#define ESAI_xCR_xEDIE (1 << ESAI_xCR_xEDIE_SHIFT)
239#define ESAI_xCR_xEIE_SHIFT 20
240#define ESAI_xCR_xEIE_MASK (1 << ESAI_xCR_xEIE_SHIFT)
241#define ESAI_xCR_xEIE (1 << ESAI_xCR_xEIE_SHIFT)
242#define ESAI_xCR_xPR_SHIFT 19
243#define ESAI_xCR_xPR_MASK (1 << ESAI_xCR_xPR_SHIFT)
244#define ESAI_xCR_xPR (1 << ESAI_xCR_xPR_SHIFT)
245#define ESAI_xCR_PADC_SHIFT 17
246#define ESAI_xCR_PADC_MASK (1 << ESAI_xCR_PADC_SHIFT)
247#define ESAI_xCR_PADC (1 << ESAI_xCR_PADC_SHIFT)
248#define ESAI_xCR_xFSR_SHIFT 16
249#define ESAI_xCR_xFSR_MASK (1 << ESAI_xCR_xFSR_SHIFT)
250#define ESAI_xCR_xFSR (1 << ESAI_xCR_xFSR_SHIFT)
251#define ESAI_xCR_xFSL_SHIFT 15
252#define ESAI_xCR_xFSL_MASK (1 << ESAI_xCR_xFSL_SHIFT)
253#define ESAI_xCR_xFSL (1 << ESAI_xCR_xFSL_SHIFT)
254#define ESAI_xCR_xSWS_SHIFT 10
255#define ESAI_xCR_xSWS_WIDTH 5
256#define ESAI_xCR_xSWS_MASK (((1 << ESAI_xCR_xSWS_WIDTH) - 1) << ESAI_xCR_xSWS_SHIFT)
257#define ESAI_xCR_xSWS(s, w) ((w < 24 ? (s - w + ((w - 8) >> 2)) : (s < 32 ? 0x1e : 0x1f)) << ESAI_xCR_xSWS_SHIFT)
258#define ESAI_xCR_xMOD_SHIFT 8
259#define ESAI_xCR_xMOD_WIDTH 2
260#define ESAI_xCR_xMOD_MASK (((1 << ESAI_xCR_xMOD_WIDTH) - 1) << ESAI_xCR_xMOD_SHIFT)
261#define ESAI_xCR_xMOD_ONDEMAND (0x1 << ESAI_xCR_xMOD_SHIFT)
262#define ESAI_xCR_xMOD_NETWORK (0x1 << ESAI_xCR_xMOD_SHIFT)
263#define ESAI_xCR_xMOD_AC97 (0x3 << ESAI_xCR_xMOD_SHIFT)
264#define ESAI_xCR_xWA_SHIFT 7
265#define ESAI_xCR_xWA_MASK (1 << ESAI_xCR_xWA_SHIFT)
266#define ESAI_xCR_xWA (1 << ESAI_xCR_xWA_SHIFT)
267#define ESAI_xCR_xSHFD_SHIFT 6
268#define ESAI_xCR_xSHFD_MASK (1 << ESAI_xCR_xSHFD_SHIFT)
269#define ESAI_xCR_xSHFD (1 << ESAI_xCR_xSHFD_SHIFT)
270#define ESAI_xCR_xE_SHIFT 0
271#define ESAI_xCR_TE_WIDTH 6
272#define ESAI_xCR_RE_WIDTH 4
273#define ESAI_xCR_TE_MASK (((1 << ESAI_xCR_TE_WIDTH) - 1) << ESAI_xCR_xE_SHIFT)
274#define ESAI_xCR_RE_MASK (((1 << ESAI_xCR_RE_WIDTH) - 1) << ESAI_xCR_xE_SHIFT)
275#define ESAI_xCR_TE(x) ((ESAI_xCR_TE_MASK >> (ESAI_xCR_TE_WIDTH - ((x + 1) >> 1))) & ESAI_xCR_TE_MASK)
276#define ESAI_xCR_RE(x) ((ESAI_xCR_RE_MASK >> (ESAI_xCR_RE_WIDTH - ((x + 1) >> 1))) & ESAI_xCR_RE_MASK)
277
278/*
279 * Transmit Clock Control Register -- REG_ESAI_TCCR 0xD8
280 * Receive Clock Control Register -- REG_ESAI_RCCR 0xE0
281 */
282#define ESAI_xCCR_xHCKD_SHIFT 23
283#define ESAI_xCCR_xHCKD_MASK (1 << ESAI_xCCR_xHCKD_SHIFT)
284#define ESAI_xCCR_xHCKD (1 << ESAI_xCCR_xHCKD_SHIFT)
285#define ESAI_xCCR_xFSD_SHIFT 22
286#define ESAI_xCCR_xFSD_MASK (1 << ESAI_xCCR_xFSD_SHIFT)
287#define ESAI_xCCR_xFSD (1 << ESAI_xCCR_xFSD_SHIFT)
288#define ESAI_xCCR_xCKD_SHIFT 21
289#define ESAI_xCCR_xCKD_MASK (1 << ESAI_xCCR_xCKD_SHIFT)
290#define ESAI_xCCR_xCKD (1 << ESAI_xCCR_xCKD_SHIFT)
291#define ESAI_xCCR_xHCKP_SHIFT 20
292#define ESAI_xCCR_xHCKP_MASK (1 << ESAI_xCCR_xHCKP_SHIFT)
293#define ESAI_xCCR_xHCKP (1 << ESAI_xCCR_xHCKP_SHIFT)
294#define ESAI_xCCR_xFSP_SHIFT 19
295#define ESAI_xCCR_xFSP_MASK (1 << ESAI_xCCR_xFSP_SHIFT)
296#define ESAI_xCCR_xFSP (1 << ESAI_xCCR_xFSP_SHIFT)
297#define ESAI_xCCR_xCKP_SHIFT 18
298#define ESAI_xCCR_xCKP_MASK (1 << ESAI_xCCR_xCKP_SHIFT)
299#define ESAI_xCCR_xCKP (1 << ESAI_xCCR_xCKP_SHIFT)
300#define ESAI_xCCR_xFP_SHIFT 14
301#define ESAI_xCCR_xFP_WIDTH 4
302#define ESAI_xCCR_xFP_MASK (((1 << ESAI_xCCR_xFP_WIDTH) - 1) << ESAI_xCCR_xFP_SHIFT)
303#define ESAI_xCCR_xFP(v) ((((v) - 1) << ESAI_xCCR_xFP_SHIFT) & ESAI_xCCR_xFP_MASK)
304#define ESAI_xCCR_xDC_SHIFT 9
305#define ESAI_xCCR_xDC_WIDTH 4
306#define ESAI_xCCR_xDC_MASK (((1 << ESAI_xCCR_xDC_WIDTH) - 1) << ESAI_xCCR_xDC_SHIFT)
307#define ESAI_xCCR_xDC(v) ((((v) - 1) << ESAI_xCCR_xDC_SHIFT) & ESAI_xCCR_xDC_MASK)
308#define ESAI_xCCR_xPSR_SHIFT 8
309#define ESAI_xCCR_xPSR_MASK (1 << ESAI_xCCR_xPSR_SHIFT)
310#define ESAI_xCCR_xPSR_BYPASS (1 << ESAI_xCCR_xPSR_SHIFT)
311#define ESAI_xCCR_xPSR_DIV8 (0 << ESAI_xCCR_xPSR_SHIFT)
312#define ESAI_xCCR_xPM_SHIFT 0
313#define ESAI_xCCR_xPM_WIDTH 8
314#define ESAI_xCCR_xPM_MASK (((1 << ESAI_xCCR_xPM_WIDTH) - 1) << ESAI_xCCR_xPM_SHIFT)
315#define ESAI_xCCR_xPM(v) ((((v) - 1) << ESAI_xCCR_xPM_SHIFT) & ESAI_xCCR_xPM_MASK)
316
317/* Transmit Slot Mask Register A/B -- REG_ESAI_TSMA/B 0xE4 ~ 0xF0 */
318#define ESAI_xSMA_xS_SHIFT 0
319#define ESAI_xSMA_xS_WIDTH 16
320#define ESAI_xSMA_xS_MASK (((1 << ESAI_xSMA_xS_WIDTH) - 1) << ESAI_xSMA_xS_SHIFT)
321#define ESAI_xSMA_xS(v) ((v) & ESAI_xSMA_xS_MASK)
322#define ESAI_xSMB_xS_SHIFT 0
323#define ESAI_xSMB_xS_WIDTH 16
324#define ESAI_xSMB_xS_MASK (((1 << ESAI_xSMB_xS_WIDTH) - 1) << ESAI_xSMB_xS_SHIFT)
325#define ESAI_xSMB_xS(v) (((v) >> ESAI_xSMA_xS_WIDTH) & ESAI_xSMA_xS_MASK)
326
327/* Port C Direction Register -- REG_ESAI_PRRC 0xF8 */
328#define ESAI_PRRC_PDC_SHIFT 0
329#define ESAI_PRRC_PDC_WIDTH 12
330#define ESAI_PRRC_PDC_MASK (((1 << ESAI_PRRC_PDC_WIDTH) - 1) << ESAI_PRRC_PDC_SHIFT)
331#define ESAI_PRRC_PDC(v) ((v) & ESAI_PRRC_PDC_MASK)
332
333/* Port C Control Register -- REG_ESAI_PCRC 0xFC */
334#define ESAI_PCRC_PC_SHIFT 0
335#define ESAI_PCRC_PC_WIDTH 12
336#define ESAI_PCRC_PC_MASK (((1 << ESAI_PCRC_PC_WIDTH) - 1) << ESAI_PCRC_PC_SHIFT)
337#define ESAI_PCRC_PC(v) ((v) & ESAI_PCRC_PC_MASK)
338
339#define ESAI_GPIO 0xfff
340
341/* ESAI clock source */
342#define ESAI_HCKT_FSYS 0
343#define ESAI_HCKT_EXTAL 1
344#define ESAI_HCKR_FSYS 2
345#define ESAI_HCKR_EXTAL 3
346
347/* ESAI clock divider */
348#define ESAI_TX_DIV_PSR 0
349#define ESAI_TX_DIV_PM 1
350#define ESAI_TX_DIV_FP 2
351#define ESAI_RX_DIV_PSR 3
352#define ESAI_RX_DIV_PM 4
353#define ESAI_RX_DIV_FP 5
354#endif /* _FSL_ESAI_DAI_H */
diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c
index 5d38a6749b9f..cdd3fa830704 100644
--- a/sound/soc/fsl/fsl_sai.c
+++ b/sound/soc/fsl/fsl_sai.c
@@ -62,26 +62,25 @@ static int fsl_sai_set_dai_sysclk_tr(struct snd_soc_dai *cpu_dai,
62 reg_cr2 = FSL_SAI_RCR2; 62 reg_cr2 = FSL_SAI_RCR2;
63 63
64 val_cr2 = sai_readl(sai, sai->base + reg_cr2); 64 val_cr2 = sai_readl(sai, sai->base + reg_cr2);
65 val_cr2 &= ~FSL_SAI_CR2_MSEL_MASK;
66
65 switch (clk_id) { 67 switch (clk_id) {
66 case FSL_SAI_CLK_BUS: 68 case FSL_SAI_CLK_BUS:
67 val_cr2 &= ~FSL_SAI_CR2_MSEL_MASK;
68 val_cr2 |= FSL_SAI_CR2_MSEL_BUS; 69 val_cr2 |= FSL_SAI_CR2_MSEL_BUS;
69 break; 70 break;
70 case FSL_SAI_CLK_MAST1: 71 case FSL_SAI_CLK_MAST1:
71 val_cr2 &= ~FSL_SAI_CR2_MSEL_MASK;
72 val_cr2 |= FSL_SAI_CR2_MSEL_MCLK1; 72 val_cr2 |= FSL_SAI_CR2_MSEL_MCLK1;
73 break; 73 break;
74 case FSL_SAI_CLK_MAST2: 74 case FSL_SAI_CLK_MAST2:
75 val_cr2 &= ~FSL_SAI_CR2_MSEL_MASK;
76 val_cr2 |= FSL_SAI_CR2_MSEL_MCLK2; 75 val_cr2 |= FSL_SAI_CR2_MSEL_MCLK2;
77 break; 76 break;
78 case FSL_SAI_CLK_MAST3: 77 case FSL_SAI_CLK_MAST3:
79 val_cr2 &= ~FSL_SAI_CR2_MSEL_MASK;
80 val_cr2 |= FSL_SAI_CR2_MSEL_MCLK3; 78 val_cr2 |= FSL_SAI_CR2_MSEL_MCLK3;
81 break; 79 break;
82 default: 80 default:
83 return -EINVAL; 81 return -EINVAL;
84 } 82 }
83
85 sai_writel(sai, val_cr2, sai->base + reg_cr2); 84 sai_writel(sai, val_cr2, sai->base + reg_cr2);
86 85
87 return 0; 86 return 0;
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index 76e56b39db01..f9090b167ad7 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -35,6 +35,7 @@
35#include <linux/module.h> 35#include <linux/module.h>
36#include <linux/interrupt.h> 36#include <linux/interrupt.h>
37#include <linux/clk.h> 37#include <linux/clk.h>
38#include <linux/debugfs.h>
38#include <linux/device.h> 39#include <linux/device.h>
39#include <linux/delay.h> 40#include <linux/delay.h>
40#include <linux/slab.h> 41#include <linux/slab.h>
@@ -106,12 +107,33 @@ static inline void write_ssi_mask(u32 __iomem *addr, u32 clear, u32 set)
106 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_LE) 107 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_LE)
107#endif 108#endif
108 109
109/* SIER bitflag of interrupts to enable */ 110#define FSLSSI_SIER_DBG_RX_FLAGS (CCSR_SSI_SIER_RFF0_EN | \
110#define SIER_FLAGS (CCSR_SSI_SIER_TFRC_EN | CCSR_SSI_SIER_TDMAE | \ 111 CCSR_SSI_SIER_RLS_EN | CCSR_SSI_SIER_RFS_EN | \
111 CCSR_SSI_SIER_TIE | CCSR_SSI_SIER_TUE0_EN | \ 112 CCSR_SSI_SIER_ROE0_EN | CCSR_SSI_SIER_RFRC_EN)
112 CCSR_SSI_SIER_TUE1_EN | CCSR_SSI_SIER_RFRC_EN | \ 113#define FSLSSI_SIER_DBG_TX_FLAGS (CCSR_SSI_SIER_TFE0_EN | \
113 CCSR_SSI_SIER_RDMAE | CCSR_SSI_SIER_RIE | \ 114 CCSR_SSI_SIER_TLS_EN | CCSR_SSI_SIER_TFS_EN | \
114 CCSR_SSI_SIER_ROE0_EN | CCSR_SSI_SIER_ROE1_EN) 115 CCSR_SSI_SIER_TUE0_EN | CCSR_SSI_SIER_TFRC_EN)
116#define FSLSSI_SISR_MASK (FSLSSI_SIER_DBG_RX_FLAGS | FSLSSI_SIER_DBG_TX_FLAGS)
117
118
119enum fsl_ssi_type {
120 FSL_SSI_MCP8610,
121 FSL_SSI_MX21,
122 FSL_SSI_MX35,
123 FSL_SSI_MX51,
124};
125
126struct fsl_ssi_reg_val {
127 u32 sier;
128 u32 srcr;
129 u32 stcr;
130 u32 scr;
131};
132
133struct fsl_ssi_rxtx_reg_val {
134 struct fsl_ssi_reg_val rx;
135 struct fsl_ssi_reg_val tx;
136};
115 137
116/** 138/**
117 * fsl_ssi_private: per-SSI private data 139 * fsl_ssi_private: per-SSI private data
@@ -132,14 +154,16 @@ struct fsl_ssi_private {
132 unsigned int irq; 154 unsigned int irq;
133 unsigned int fifo_depth; 155 unsigned int fifo_depth;
134 struct snd_soc_dai_driver cpu_dai_drv; 156 struct snd_soc_dai_driver cpu_dai_drv;
135 struct device_attribute dev_attr;
136 struct platform_device *pdev; 157 struct platform_device *pdev;
137 158
159 enum fsl_ssi_type hw_type;
138 bool new_binding; 160 bool new_binding;
139 bool ssi_on_imx; 161 bool ssi_on_imx;
140 bool imx_ac97; 162 bool imx_ac97;
141 bool use_dma; 163 bool use_dma;
142 bool baudclk_locked; 164 bool baudclk_locked;
165 bool irq_stats;
166 bool offline_config;
143 u8 i2s_mode; 167 u8 i2s_mode;
144 spinlock_t baudclk_lock; 168 spinlock_t baudclk_lock;
145 struct clk *baudclk; 169 struct clk *baudclk;
@@ -149,6 +173,8 @@ struct fsl_ssi_private {
149 struct imx_dma_data filter_data_tx; 173 struct imx_dma_data filter_data_tx;
150 struct imx_dma_data filter_data_rx; 174 struct imx_dma_data filter_data_rx;
151 struct imx_pcm_fiq_params fiq_params; 175 struct imx_pcm_fiq_params fiq_params;
176 /* Register values for rx/tx configuration */
177 struct fsl_ssi_rxtx_reg_val rxtx_reg_val;
152 178
153 struct { 179 struct {
154 unsigned int rfrc; 180 unsigned int rfrc;
@@ -173,10 +199,21 @@ struct fsl_ssi_private {
173 unsigned int tfe1; 199 unsigned int tfe1;
174 unsigned int tfe0; 200 unsigned int tfe0;
175 } stats; 201 } stats;
202 struct dentry *dbg_dir;
203 struct dentry *dbg_stats;
176 204
177 char name[1]; 205 char name[1];
178}; 206};
179 207
208static const struct of_device_id fsl_ssi_ids[] = {
209 { .compatible = "fsl,mpc8610-ssi", .data = (void *) FSL_SSI_MCP8610},
210 { .compatible = "fsl,imx51-ssi", .data = (void *) FSL_SSI_MX51},
211 { .compatible = "fsl,imx35-ssi", .data = (void *) FSL_SSI_MX35},
212 { .compatible = "fsl,imx21-ssi", .data = (void *) FSL_SSI_MX21},
213 {}
214};
215MODULE_DEVICE_TABLE(of, fsl_ssi_ids);
216
180/** 217/**
181 * fsl_ssi_isr: SSI interrupt handler 218 * fsl_ssi_isr: SSI interrupt handler
182 * 219 *
@@ -195,23 +232,40 @@ static irqreturn_t fsl_ssi_isr(int irq, void *dev_id)
195 struct ccsr_ssi __iomem *ssi = ssi_private->ssi; 232 struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
196 irqreturn_t ret = IRQ_NONE; 233 irqreturn_t ret = IRQ_NONE;
197 __be32 sisr; 234 __be32 sisr;
198 __be32 sisr2 = 0; 235 __be32 sisr2;
236 __be32 sisr_write_mask = 0;
237
238 switch (ssi_private->hw_type) {
239 case FSL_SSI_MX21:
240 sisr_write_mask = 0;
241 break;
242
243 case FSL_SSI_MCP8610:
244 case FSL_SSI_MX35:
245 sisr_write_mask = CCSR_SSI_SISR_RFRC | CCSR_SSI_SISR_TFRC |
246 CCSR_SSI_SISR_ROE0 | CCSR_SSI_SISR_ROE1 |
247 CCSR_SSI_SISR_TUE0 | CCSR_SSI_SISR_TUE1;
248 break;
249
250 case FSL_SSI_MX51:
251 sisr_write_mask = CCSR_SSI_SISR_ROE0 | CCSR_SSI_SISR_ROE1 |
252 CCSR_SSI_SISR_TUE0 | CCSR_SSI_SISR_TUE1;
253 break;
254 }
199 255
200 /* We got an interrupt, so read the status register to see what we 256 /* We got an interrupt, so read the status register to see what we
201 were interrupted for. We mask it with the Interrupt Enable register 257 were interrupted for. We mask it with the Interrupt Enable register
202 so that we only check for events that we're interested in. 258 so that we only check for events that we're interested in.
203 */ 259 */
204 sisr = read_ssi(&ssi->sisr) & SIER_FLAGS; 260 sisr = read_ssi(&ssi->sisr) & FSLSSI_SISR_MASK;
205 261
206 if (sisr & CCSR_SSI_SISR_RFRC) { 262 if (sisr & CCSR_SSI_SISR_RFRC) {
207 ssi_private->stats.rfrc++; 263 ssi_private->stats.rfrc++;
208 sisr2 |= CCSR_SSI_SISR_RFRC;
209 ret = IRQ_HANDLED; 264 ret = IRQ_HANDLED;
210 } 265 }
211 266
212 if (sisr & CCSR_SSI_SISR_TFRC) { 267 if (sisr & CCSR_SSI_SISR_TFRC) {
213 ssi_private->stats.tfrc++; 268 ssi_private->stats.tfrc++;
214 sisr2 |= CCSR_SSI_SISR_TFRC;
215 ret = IRQ_HANDLED; 269 ret = IRQ_HANDLED;
216 } 270 }
217 271
@@ -252,25 +306,21 @@ static irqreturn_t fsl_ssi_isr(int irq, void *dev_id)
252 306
253 if (sisr & CCSR_SSI_SISR_ROE1) { 307 if (sisr & CCSR_SSI_SISR_ROE1) {
254 ssi_private->stats.roe1++; 308 ssi_private->stats.roe1++;
255 sisr2 |= CCSR_SSI_SISR_ROE1;
256 ret = IRQ_HANDLED; 309 ret = IRQ_HANDLED;
257 } 310 }
258 311
259 if (sisr & CCSR_SSI_SISR_ROE0) { 312 if (sisr & CCSR_SSI_SISR_ROE0) {
260 ssi_private->stats.roe0++; 313 ssi_private->stats.roe0++;
261 sisr2 |= CCSR_SSI_SISR_ROE0;
262 ret = IRQ_HANDLED; 314 ret = IRQ_HANDLED;
263 } 315 }
264 316
265 if (sisr & CCSR_SSI_SISR_TUE1) { 317 if (sisr & CCSR_SSI_SISR_TUE1) {
266 ssi_private->stats.tue1++; 318 ssi_private->stats.tue1++;
267 sisr2 |= CCSR_SSI_SISR_TUE1;
268 ret = IRQ_HANDLED; 319 ret = IRQ_HANDLED;
269 } 320 }
270 321
271 if (sisr & CCSR_SSI_SISR_TUE0) { 322 if (sisr & CCSR_SSI_SISR_TUE0) {
272 ssi_private->stats.tue0++; 323 ssi_private->stats.tue0++;
273 sisr2 |= CCSR_SSI_SISR_TUE0;
274 ret = IRQ_HANDLED; 324 ret = IRQ_HANDLED;
275 } 325 }
276 326
@@ -314,6 +364,7 @@ static irqreturn_t fsl_ssi_isr(int irq, void *dev_id)
314 ret = IRQ_HANDLED; 364 ret = IRQ_HANDLED;
315 } 365 }
316 366
367 sisr2 = sisr & sisr_write_mask;
317 /* Clear the bits that we set */ 368 /* Clear the bits that we set */
318 if (sisr2) 369 if (sisr2)
319 write_ssi(sisr2, &ssi->sisr); 370 write_ssi(sisr2, &ssi->sisr);
@@ -321,6 +372,245 @@ static irqreturn_t fsl_ssi_isr(int irq, void *dev_id)
321 return ret; 372 return ret;
322} 373}
323 374
375#if IS_ENABLED(CONFIG_DEBUG_FS)
376/* Show the statistics of a flag only if its interrupt is enabled. The
377 * compiler will optimze this code to a no-op if the interrupt is not
378 * enabled.
379 */
380#define SIER_SHOW(flag, name) \
381 do { \
382 if (FSLSSI_SISR_MASK & CCSR_SSI_SIER_##flag) \
383 seq_printf(s, #name "=%u\n", ssi_private->stats.name); \
384 } while (0)
385
386
387/**
388 * fsl_sysfs_ssi_show: display SSI statistics
389 *
390 * Display the statistics for the current SSI device. To avoid confusion,
391 * we only show those counts that are enabled.
392 */
393static int fsl_ssi_stats_show(struct seq_file *s, void *unused)
394{
395 struct fsl_ssi_private *ssi_private = s->private;
396
397 SIER_SHOW(RFRC_EN, rfrc);
398 SIER_SHOW(TFRC_EN, tfrc);
399 SIER_SHOW(CMDAU_EN, cmdau);
400 SIER_SHOW(CMDDU_EN, cmddu);
401 SIER_SHOW(RXT_EN, rxt);
402 SIER_SHOW(RDR1_EN, rdr1);
403 SIER_SHOW(RDR0_EN, rdr0);
404 SIER_SHOW(TDE1_EN, tde1);
405 SIER_SHOW(TDE0_EN, tde0);
406 SIER_SHOW(ROE1_EN, roe1);
407 SIER_SHOW(ROE0_EN, roe0);
408 SIER_SHOW(TUE1_EN, tue1);
409 SIER_SHOW(TUE0_EN, tue0);
410 SIER_SHOW(TFS_EN, tfs);
411 SIER_SHOW(RFS_EN, rfs);
412 SIER_SHOW(TLS_EN, tls);
413 SIER_SHOW(RLS_EN, rls);
414 SIER_SHOW(RFF1_EN, rff1);
415 SIER_SHOW(RFF0_EN, rff0);
416 SIER_SHOW(TFE1_EN, tfe1);
417 SIER_SHOW(TFE0_EN, tfe0);
418
419 return 0;
420}
421
422static int fsl_ssi_stats_open(struct inode *inode, struct file *file)
423{
424 return single_open(file, fsl_ssi_stats_show, inode->i_private);
425}
426
427static const struct file_operations fsl_ssi_stats_ops = {
428 .open = fsl_ssi_stats_open,
429 .read = seq_read,
430 .llseek = seq_lseek,
431 .release = single_release,
432};
433
434static int fsl_ssi_debugfs_create(struct fsl_ssi_private *ssi_private,
435 struct device *dev)
436{
437 ssi_private->dbg_dir = debugfs_create_dir(dev_name(dev), NULL);
438 if (!ssi_private->dbg_dir)
439 return -ENOMEM;
440
441 ssi_private->dbg_stats = debugfs_create_file("stats", S_IRUGO,
442 ssi_private->dbg_dir, ssi_private, &fsl_ssi_stats_ops);
443 if (!ssi_private->dbg_stats) {
444 debugfs_remove(ssi_private->dbg_dir);
445 return -ENOMEM;
446 }
447
448 return 0;
449}
450
451static void fsl_ssi_debugfs_remove(struct fsl_ssi_private *ssi_private)
452{
453 debugfs_remove(ssi_private->dbg_stats);
454 debugfs_remove(ssi_private->dbg_dir);
455}
456
457#else
458
459static int fsl_ssi_debugfs_create(struct fsl_ssi_private *ssi_private,
460 struct device *dev)
461{
462 return 0;
463}
464
465static void fsl_ssi_debugfs_remove(struct fsl_ssi_private *ssi_private)
466{
467}
468
469#endif /* IS_ENABLED(CONFIG_DEBUG_FS) */
470
471/*
472 * Enable/Disable all rx/tx config flags at once.
473 */
474static void fsl_ssi_rxtx_config(struct fsl_ssi_private *ssi_private,
475 bool enable)
476{
477 struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
478 struct fsl_ssi_rxtx_reg_val *vals = &ssi_private->rxtx_reg_val;
479
480 if (enable) {
481 write_ssi_mask(&ssi->sier, 0, vals->rx.sier | vals->tx.sier);
482 write_ssi_mask(&ssi->srcr, 0, vals->rx.srcr | vals->tx.srcr);
483 write_ssi_mask(&ssi->stcr, 0, vals->rx.stcr | vals->tx.stcr);
484 } else {
485 write_ssi_mask(&ssi->srcr, vals->rx.srcr | vals->tx.srcr, 0);
486 write_ssi_mask(&ssi->stcr, vals->rx.stcr | vals->tx.stcr, 0);
487 write_ssi_mask(&ssi->sier, vals->rx.sier | vals->tx.sier, 0);
488 }
489}
490
491/*
492 * Enable/Disable a ssi configuration. You have to pass either
493 * ssi_private->rxtx_reg_val.rx or tx as vals parameter.
494 */
495static void fsl_ssi_config(struct fsl_ssi_private *ssi_private, bool enable,
496 struct fsl_ssi_reg_val *vals)
497{
498 struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
499 struct fsl_ssi_reg_val *avals;
500 u32 scr_val = read_ssi(&ssi->scr);
501 int nr_active_streams = !!(scr_val & CCSR_SSI_SCR_TE) +
502 !!(scr_val & CCSR_SSI_SCR_RE);
503
504 /* Find the other direction values rx or tx which we do not want to
505 * modify */
506 if (&ssi_private->rxtx_reg_val.rx == vals)
507 avals = &ssi_private->rxtx_reg_val.tx;
508 else
509 avals = &ssi_private->rxtx_reg_val.rx;
510
511 /* If vals should be disabled, start with disabling the unit */
512 if (!enable) {
513 u32 scr = vals->scr & (vals->scr ^ avals->scr);
514 write_ssi_mask(&ssi->scr, scr, 0);
515 }
516
517 /*
518 * We are running on a SoC which does not support online SSI
519 * reconfiguration, so we have to enable all necessary flags at once
520 * even if we do not use them later (capture and playback configuration)
521 */
522 if (ssi_private->offline_config) {
523 if ((enable && !nr_active_streams) ||
524 (!enable && nr_active_streams == 1))
525 fsl_ssi_rxtx_config(ssi_private, enable);
526
527 goto config_done;
528 }
529
530 /*
531 * Configure single direction units while the SSI unit is running
532 * (online configuration)
533 */
534 if (enable) {
535 write_ssi_mask(&ssi->sier, 0, vals->sier);
536 write_ssi_mask(&ssi->srcr, 0, vals->srcr);
537 write_ssi_mask(&ssi->stcr, 0, vals->stcr);
538 } else {
539 u32 sier;
540 u32 srcr;
541 u32 stcr;
542
543 /*
544 * Disabling the necessary flags for one of rx/tx while the
545 * other stream is active is a little bit more difficult. We
546 * have to disable only those flags that differ between both
547 * streams (rx XOR tx) and that are set in the stream that is
548 * disabled now. Otherwise we could alter flags of the other
549 * stream
550 */
551
552 /* These assignments are simply vals without bits set in avals*/
553 sier = vals->sier & (vals->sier ^ avals->sier);
554 srcr = vals->srcr & (vals->srcr ^ avals->srcr);
555 stcr = vals->stcr & (vals->stcr ^ avals->stcr);
556
557 write_ssi_mask(&ssi->srcr, srcr, 0);
558 write_ssi_mask(&ssi->stcr, stcr, 0);
559 write_ssi_mask(&ssi->sier, sier, 0);
560 }
561
562config_done:
563 /* Enabling of subunits is done after configuration */
564 if (enable)
565 write_ssi_mask(&ssi->scr, 0, vals->scr);
566}
567
568
569static void fsl_ssi_rx_config(struct fsl_ssi_private *ssi_private, bool enable)
570{
571 fsl_ssi_config(ssi_private, enable, &ssi_private->rxtx_reg_val.rx);
572}
573
574static void fsl_ssi_tx_config(struct fsl_ssi_private *ssi_private, bool enable)
575{
576 fsl_ssi_config(ssi_private, enable, &ssi_private->rxtx_reg_val.tx);
577}
578
579/*
580 * Setup rx/tx register values used to enable/disable the streams. These will
581 * be used later in fsl_ssi_config to setup the streams without the need to
582 * check for all different SSI modes.
583 */
584static void fsl_ssi_setup_reg_vals(struct fsl_ssi_private *ssi_private)
585{
586 struct fsl_ssi_rxtx_reg_val *reg = &ssi_private->rxtx_reg_val;
587
588 reg->rx.sier = CCSR_SSI_SIER_RFF0_EN;
589 reg->rx.srcr = CCSR_SSI_SRCR_RFEN0;
590 reg->rx.scr = 0;
591 reg->tx.sier = CCSR_SSI_SIER_TFE0_EN;
592 reg->tx.stcr = CCSR_SSI_STCR_TFEN0;
593 reg->tx.scr = 0;
594
595 if (!ssi_private->imx_ac97) {
596 reg->rx.scr = CCSR_SSI_SCR_SSIEN | CCSR_SSI_SCR_RE;
597 reg->rx.sier |= CCSR_SSI_SIER_RFF0_EN;
598 reg->tx.scr = CCSR_SSI_SCR_SSIEN | CCSR_SSI_SCR_TE;
599 reg->tx.sier |= CCSR_SSI_SIER_TFE0_EN;
600 }
601
602 if (ssi_private->use_dma) {
603 reg->rx.sier |= CCSR_SSI_SIER_RDMAE;
604 reg->tx.sier |= CCSR_SSI_SIER_TDMAE;
605 } else {
606 reg->rx.sier |= CCSR_SSI_SIER_RIE;
607 reg->tx.sier |= CCSR_SSI_SIER_TIE;
608 }
609
610 reg->rx.sier |= FSLSSI_SIER_DBG_RX_FLAGS;
611 reg->tx.sier |= FSLSSI_SIER_DBG_TX_FLAGS;
612}
613
324static void fsl_ssi_setup_ac97(struct fsl_ssi_private *ssi_private) 614static void fsl_ssi_setup_ac97(struct fsl_ssi_private *ssi_private)
325{ 615{
326 struct ccsr_ssi __iomem *ssi = ssi_private->ssi; 616 struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
@@ -357,6 +647,8 @@ static int fsl_ssi_setup(struct fsl_ssi_private *ssi_private)
357 u8 wm; 647 u8 wm;
358 int synchronous = ssi_private->cpu_dai_drv.symmetric_rates; 648 int synchronous = ssi_private->cpu_dai_drv.symmetric_rates;
359 649
650 fsl_ssi_setup_reg_vals(ssi_private);
651
360 if (ssi_private->imx_ac97) 652 if (ssi_private->imx_ac97)
361 ssi_private->i2s_mode = CCSR_SSI_SCR_I2S_MODE_NORMAL | CCSR_SSI_SCR_NET; 653 ssi_private->i2s_mode = CCSR_SSI_SCR_I2S_MODE_NORMAL | CCSR_SSI_SCR_NET;
362 else 654 else
@@ -380,13 +672,12 @@ static int fsl_ssi_setup(struct fsl_ssi_private *ssi_private)
380 ssi_private->i2s_mode | 672 ssi_private->i2s_mode |
381 (synchronous ? CCSR_SSI_SCR_SYN : 0)); 673 (synchronous ? CCSR_SSI_SCR_SYN : 0));
382 674
383 write_ssi(CCSR_SSI_STCR_TXBIT0 | CCSR_SSI_STCR_TFEN0 | 675 write_ssi(CCSR_SSI_STCR_TXBIT0 | CCSR_SSI_STCR_TFSI |
384 CCSR_SSI_STCR_TFSI | CCSR_SSI_STCR_TEFS | 676 CCSR_SSI_STCR_TEFS | CCSR_SSI_STCR_TSCKP, &ssi->stcr);
385 CCSR_SSI_STCR_TSCKP, &ssi->stcr); 677
678 write_ssi(CCSR_SSI_SRCR_RXBIT0 | CCSR_SSI_SRCR_RFSI |
679 CCSR_SSI_SRCR_REFS | CCSR_SSI_SRCR_RSCKP, &ssi->srcr);
386 680
387 write_ssi(CCSR_SSI_SRCR_RXBIT0 | CCSR_SSI_SRCR_RFEN0 |
388 CCSR_SSI_SRCR_RFSI | CCSR_SSI_SRCR_REFS |
389 CCSR_SSI_SRCR_RSCKP, &ssi->srcr);
390 /* 681 /*
391 * The DC and PM bits are only used if the SSI is the clock master. 682 * The DC and PM bits are only used if the SSI is the clock master.
392 */ 683 */
@@ -419,6 +710,17 @@ static int fsl_ssi_setup(struct fsl_ssi_private *ssi_private)
419 if (ssi_private->imx_ac97) 710 if (ssi_private->imx_ac97)
420 fsl_ssi_setup_ac97(ssi_private); 711 fsl_ssi_setup_ac97(ssi_private);
421 712
713 /*
714 * Set a default slot number so that there is no need for those common
715 * cases like I2S mode to call the extra set_tdm_slot() any more.
716 */
717 if (!ssi_private->imx_ac97) {
718 write_ssi_mask(&ssi->stccr, CCSR_SSI_SxCCR_DC_MASK,
719 CCSR_SSI_SxCCR_DC(2));
720 write_ssi_mask(&ssi->srccr, CCSR_SSI_SxCCR_DC_MASK,
721 CCSR_SSI_SxCCR_DC(2));
722 }
723
422 return 0; 724 return 0;
423} 725}
424 726
@@ -761,50 +1063,26 @@ static int fsl_ssi_trigger(struct snd_pcm_substream *substream, int cmd,
761 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1063 struct snd_soc_pcm_runtime *rtd = substream->private_data;
762 struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(rtd->cpu_dai); 1064 struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(rtd->cpu_dai);
763 struct ccsr_ssi __iomem *ssi = ssi_private->ssi; 1065 struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
764 unsigned int sier_bits;
765 unsigned long flags; 1066 unsigned long flags;
766 1067
767 /*
768 * Enable only the interrupts and DMA requests
769 * that are needed for the channel. As the fiq
770 * is polling for this bits, we have to ensure
771 * that this are aligned with the preallocated
772 * buffers
773 */
774
775 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
776 if (ssi_private->use_dma)
777 sier_bits = SIER_FLAGS;
778 else
779 sier_bits = CCSR_SSI_SIER_TIE | CCSR_SSI_SIER_TFE0_EN;
780 } else {
781 if (ssi_private->use_dma)
782 sier_bits = SIER_FLAGS;
783 else
784 sier_bits = CCSR_SSI_SIER_RIE | CCSR_SSI_SIER_RFF0_EN;
785 }
786
787 switch (cmd) { 1068 switch (cmd) {
788 case SNDRV_PCM_TRIGGER_START: 1069 case SNDRV_PCM_TRIGGER_START:
789 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 1070 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
790 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 1071 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
791 write_ssi_mask(&ssi->scr, 0, 1072 fsl_ssi_tx_config(ssi_private, true);
792 CCSR_SSI_SCR_SSIEN | CCSR_SSI_SCR_TE);
793 else 1073 else
794 write_ssi_mask(&ssi->scr, 0, 1074 fsl_ssi_rx_config(ssi_private, true);
795 CCSR_SSI_SCR_SSIEN | CCSR_SSI_SCR_RE);
796 break; 1075 break;
797 1076
798 case SNDRV_PCM_TRIGGER_STOP: 1077 case SNDRV_PCM_TRIGGER_STOP:
799 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 1078 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
800 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 1079 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
801 write_ssi_mask(&ssi->scr, CCSR_SSI_SCR_TE, 0); 1080 fsl_ssi_tx_config(ssi_private, false);
802 else 1081 else
803 write_ssi_mask(&ssi->scr, CCSR_SSI_SCR_RE, 0); 1082 fsl_ssi_rx_config(ssi_private, false);
804 1083
805 if (!ssi_private->imx_ac97 && (read_ssi(&ssi->scr) & 1084 if (!ssi_private->imx_ac97 && (read_ssi(&ssi->scr) &
806 (CCSR_SSI_SCR_TE | CCSR_SSI_SCR_RE)) == 0) { 1085 (CCSR_SSI_SCR_TE | CCSR_SSI_SCR_RE)) == 0) {
807 write_ssi_mask(&ssi->scr, CCSR_SSI_SCR_SSIEN, 0);
808 spin_lock_irqsave(&ssi_private->baudclk_lock, flags); 1086 spin_lock_irqsave(&ssi_private->baudclk_lock, flags);
809 ssi_private->baudclk_locked = false; 1087 ssi_private->baudclk_locked = false;
810 spin_unlock_irqrestore(&ssi_private->baudclk_lock, flags); 1088 spin_unlock_irqrestore(&ssi_private->baudclk_lock, flags);
@@ -815,7 +1093,12 @@ static int fsl_ssi_trigger(struct snd_pcm_substream *substream, int cmd,
815 return -EINVAL; 1093 return -EINVAL;
816 } 1094 }
817 1095
818 write_ssi(sier_bits, &ssi->sier); 1096 if (ssi_private->imx_ac97) {
1097 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
1098 write_ssi(CCSR_SSI_SOR_TX_CLR, &ssi->sor);
1099 else
1100 write_ssi(CCSR_SSI_SOR_RX_CLR, &ssi->sor);
1101 }
819 1102
820 return 0; 1103 return 0;
821} 1104}
@@ -863,58 +1146,6 @@ static const struct snd_soc_component_driver fsl_ssi_component = {
863 .name = "fsl-ssi", 1146 .name = "fsl-ssi",
864}; 1147};
865 1148
866/**
867 * fsl_ssi_ac97_trigger: start and stop the AC97 receive/transmit.
868 *
869 * This function is called by ALSA to start, stop, pause, and resume the
870 * transfer of data.
871 */
872static int fsl_ssi_ac97_trigger(struct snd_pcm_substream *substream, int cmd,
873 struct snd_soc_dai *dai)
874{
875 struct snd_soc_pcm_runtime *rtd = substream->private_data;
876 struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(
877 rtd->cpu_dai);
878 struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
879
880 switch (cmd) {
881 case SNDRV_PCM_TRIGGER_START:
882 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
883 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
884 write_ssi_mask(&ssi->sier, 0, CCSR_SSI_SIER_TIE |
885 CCSR_SSI_SIER_TFE0_EN);
886 else
887 write_ssi_mask(&ssi->sier, 0, CCSR_SSI_SIER_RIE |
888 CCSR_SSI_SIER_RFF0_EN);
889 break;
890
891 case SNDRV_PCM_TRIGGER_STOP:
892 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
893 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
894 write_ssi_mask(&ssi->sier, CCSR_SSI_SIER_TIE |
895 CCSR_SSI_SIER_TFE0_EN, 0);
896 else
897 write_ssi_mask(&ssi->sier, CCSR_SSI_SIER_RIE |
898 CCSR_SSI_SIER_RFF0_EN, 0);
899 break;
900
901 default:
902 return -EINVAL;
903 }
904
905 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
906 write_ssi(CCSR_SSI_SOR_TX_CLR, &ssi->sor);
907 else
908 write_ssi(CCSR_SSI_SOR_RX_CLR, &ssi->sor);
909
910 return 0;
911}
912
913static const struct snd_soc_dai_ops fsl_ssi_ac97_dai_ops = {
914 .startup = fsl_ssi_startup,
915 .trigger = fsl_ssi_ac97_trigger,
916};
917
918static struct snd_soc_dai_driver fsl_ssi_ac97_dai = { 1149static struct snd_soc_dai_driver fsl_ssi_ac97_dai = {
919 .ac97_control = 1, 1150 .ac97_control = 1,
920 .playback = { 1151 .playback = {
@@ -931,7 +1162,7 @@ static struct snd_soc_dai_driver fsl_ssi_ac97_dai = {
931 .rates = SNDRV_PCM_RATE_48000, 1162 .rates = SNDRV_PCM_RATE_48000,
932 .formats = SNDRV_PCM_FMTBIT_S16_LE, 1163 .formats = SNDRV_PCM_FMTBIT_S16_LE,
933 }, 1164 },
934 .ops = &fsl_ssi_ac97_dai_ops, 1165 .ops = &fsl_ssi_dai_ops,
935}; 1166};
936 1167
937 1168
@@ -989,56 +1220,6 @@ static struct snd_ac97_bus_ops fsl_ssi_ac97_ops = {
989 .write = fsl_ssi_ac97_write, 1220 .write = fsl_ssi_ac97_write,
990}; 1221};
991 1222
992/* Show the statistics of a flag only if its interrupt is enabled. The
993 * compiler will optimze this code to a no-op if the interrupt is not
994 * enabled.
995 */
996#define SIER_SHOW(flag, name) \
997 do { \
998 if (SIER_FLAGS & CCSR_SSI_SIER_##flag) \
999 length += sprintf(buf + length, #name "=%u\n", \
1000 ssi_private->stats.name); \
1001 } while (0)
1002
1003
1004/**
1005 * fsl_sysfs_ssi_show: display SSI statistics
1006 *
1007 * Display the statistics for the current SSI device. To avoid confusion,
1008 * we only show those counts that are enabled.
1009 */
1010static ssize_t fsl_sysfs_ssi_show(struct device *dev,
1011 struct device_attribute *attr, char *buf)
1012{
1013 struct fsl_ssi_private *ssi_private =
1014 container_of(attr, struct fsl_ssi_private, dev_attr);
1015 ssize_t length = 0;
1016
1017 SIER_SHOW(RFRC_EN, rfrc);
1018 SIER_SHOW(TFRC_EN, tfrc);
1019 SIER_SHOW(CMDAU_EN, cmdau);
1020 SIER_SHOW(CMDDU_EN, cmddu);
1021 SIER_SHOW(RXT_EN, rxt);
1022 SIER_SHOW(RDR1_EN, rdr1);
1023 SIER_SHOW(RDR0_EN, rdr0);
1024 SIER_SHOW(TDE1_EN, tde1);
1025 SIER_SHOW(TDE0_EN, tde0);
1026 SIER_SHOW(ROE1_EN, roe1);
1027 SIER_SHOW(ROE0_EN, roe0);
1028 SIER_SHOW(TUE1_EN, tue1);
1029 SIER_SHOW(TUE0_EN, tue0);
1030 SIER_SHOW(TFS_EN, tfs);
1031 SIER_SHOW(RFS_EN, rfs);
1032 SIER_SHOW(TLS_EN, tls);
1033 SIER_SHOW(RLS_EN, rls);
1034 SIER_SHOW(RFF1_EN, rff1);
1035 SIER_SHOW(RFF0_EN, rff0);
1036 SIER_SHOW(TFE1_EN, tfe1);
1037 SIER_SHOW(TFE0_EN, tfe0);
1038
1039 return length;
1040}
1041
1042/** 1223/**
1043 * Make every character in a string lower-case 1224 * Make every character in a string lower-case
1044 */ 1225 */
@@ -1060,6 +1241,8 @@ static int fsl_ssi_probe(struct platform_device *pdev)
1060 int ret = 0; 1241 int ret = 0;
1061 struct device_attribute *dev_attr = NULL; 1242 struct device_attribute *dev_attr = NULL;
1062 struct device_node *np = pdev->dev.of_node; 1243 struct device_node *np = pdev->dev.of_node;
1244 const struct of_device_id *of_id;
1245 enum fsl_ssi_type hw_type;
1063 const char *p, *sprop; 1246 const char *p, *sprop;
1064 const uint32_t *iprop; 1247 const uint32_t *iprop;
1065 struct resource res; 1248 struct resource res;
@@ -1074,6 +1257,11 @@ static int fsl_ssi_probe(struct platform_device *pdev)
1074 if (!of_device_is_available(np)) 1257 if (!of_device_is_available(np))
1075 return -ENODEV; 1258 return -ENODEV;
1076 1259
1260 of_id = of_match_device(fsl_ssi_ids, &pdev->dev);
1261 if (!of_id)
1262 return -EINVAL;
1263 hw_type = (enum fsl_ssi_type) of_id->data;
1264
1077 /* We only support the SSI in "I2S Slave" mode */ 1265 /* We only support the SSI in "I2S Slave" mode */
1078 sprop = of_get_property(np, "fsl,mode", NULL); 1266 sprop = of_get_property(np, "fsl,mode", NULL);
1079 if (!sprop) { 1267 if (!sprop) {
@@ -1100,6 +1288,7 @@ static int fsl_ssi_probe(struct platform_device *pdev)
1100 1288
1101 ssi_private->use_dma = !of_property_read_bool(np, 1289 ssi_private->use_dma = !of_property_read_bool(np,
1102 "fsl,fiq-stream-filter"); 1290 "fsl,fiq-stream-filter");
1291 ssi_private->hw_type = hw_type;
1103 1292
1104 if (ac97) { 1293 if (ac97) {
1105 memcpy(&ssi_private->cpu_dai_drv, &fsl_ssi_ac97_dai, 1294 memcpy(&ssi_private->cpu_dai_drv, &fsl_ssi_ac97_dai,
@@ -1153,7 +1342,34 @@ static int fsl_ssi_probe(struct platform_device *pdev)
1153 ssi_private->baudclk_locked = false; 1342 ssi_private->baudclk_locked = false;
1154 spin_lock_init(&ssi_private->baudclk_lock); 1343 spin_lock_init(&ssi_private->baudclk_lock);
1155 1344
1156 if (of_device_is_compatible(pdev->dev.of_node, "fsl,imx21-ssi")) { 1345 /*
1346 * imx51 and later SoCs have a slightly different IP that allows the
1347 * SSI configuration while the SSI unit is running.
1348 *
1349 * More important, it is necessary on those SoCs to configure the
1350 * sperate TX/RX DMA bits just before starting the stream
1351 * (fsl_ssi_trigger). The SDMA unit has to be configured before fsl_ssi
1352 * sends any DMA requests to the SDMA unit, otherwise it is not defined
1353 * how the SDMA unit handles the DMA request.
1354 *
1355 * SDMA units are present on devices starting at imx35 but the imx35
1356 * reference manual states that the DMA bits should not be changed
1357 * while the SSI unit is running (SSIEN). So we support the necessary
1358 * online configuration of fsl-ssi starting at imx51.
1359 */
1360 switch (hw_type) {
1361 case FSL_SSI_MCP8610:
1362 case FSL_SSI_MX21:
1363 case FSL_SSI_MX35:
1364 ssi_private->offline_config = true;
1365 break;
1366 case FSL_SSI_MX51:
1367 ssi_private->offline_config = false;
1368 break;
1369 }
1370
1371 if (hw_type == FSL_SSI_MX21 || hw_type == FSL_SSI_MX51 ||
1372 hw_type == FSL_SSI_MX35) {
1157 u32 dma_events[2]; 1373 u32 dma_events[2];
1158 ssi_private->ssi_on_imx = true; 1374 ssi_private->ssi_on_imx = true;
1159 1375
@@ -1175,7 +1391,8 @@ static int fsl_ssi_probe(struct platform_device *pdev)
1175 */ 1391 */
1176 ssi_private->baudclk = devm_clk_get(&pdev->dev, "baud"); 1392 ssi_private->baudclk = devm_clk_get(&pdev->dev, "baud");
1177 if (IS_ERR(ssi_private->baudclk)) 1393 if (IS_ERR(ssi_private->baudclk))
1178 dev_warn(&pdev->dev, "could not get baud clock: %d\n", ret); 1394 dev_warn(&pdev->dev, "could not get baud clock: %ld\n",
1395 PTR_ERR(ssi_private->baudclk));
1179 else 1396 else
1180 clk_prepare_enable(ssi_private->baudclk); 1397 clk_prepare_enable(ssi_private->baudclk);
1181 1398
@@ -1217,32 +1434,25 @@ static int fsl_ssi_probe(struct platform_device *pdev)
1217 dma_events[0], shared ? IMX_DMATYPE_SSI_SP : IMX_DMATYPE_SSI); 1434 dma_events[0], shared ? IMX_DMATYPE_SSI_SP : IMX_DMATYPE_SSI);
1218 imx_pcm_dma_params_init_data(&ssi_private->filter_data_rx, 1435 imx_pcm_dma_params_init_data(&ssi_private->filter_data_rx,
1219 dma_events[1], shared ? IMX_DMATYPE_SSI_SP : IMX_DMATYPE_SSI); 1436 dma_events[1], shared ? IMX_DMATYPE_SSI_SP : IMX_DMATYPE_SSI);
1220 } else if (ssi_private->use_dma) { 1437 }
1438
1439 /*
1440 * Enable interrupts only for MCP8610 and MX51. The other MXs have
1441 * different writeable interrupt status registers.
1442 */
1443 if (ssi_private->use_dma) {
1221 /* The 'name' should not have any slashes in it. */ 1444 /* The 'name' should not have any slashes in it. */
1222 ret = devm_request_irq(&pdev->dev, ssi_private->irq, 1445 ret = devm_request_irq(&pdev->dev, ssi_private->irq,
1223 fsl_ssi_isr, 0, ssi_private->name, 1446 fsl_ssi_isr, 0, ssi_private->name,
1224 ssi_private); 1447 ssi_private);
1448 ssi_private->irq_stats = true;
1225 if (ret < 0) { 1449 if (ret < 0) {
1226 dev_err(&pdev->dev, "could not claim irq %u\n", 1450 dev_err(&pdev->dev, "could not claim irq %u\n",
1227 ssi_private->irq); 1451 ssi_private->irq);
1228 goto error_irqmap; 1452 goto error_clk;
1229 } 1453 }
1230 } 1454 }
1231 1455
1232 /* Initialize the the device_attribute structure */
1233 dev_attr = &ssi_private->dev_attr;
1234 sysfs_attr_init(&dev_attr->attr);
1235 dev_attr->attr.name = "statistics";
1236 dev_attr->attr.mode = S_IRUGO;
1237 dev_attr->show = fsl_sysfs_ssi_show;
1238
1239 ret = device_create_file(&pdev->dev, dev_attr);
1240 if (ret) {
1241 dev_err(&pdev->dev, "could not create sysfs %s file\n",
1242 ssi_private->dev_attr.attr.name);
1243 goto error_clk;
1244 }
1245
1246 /* Register with ASoC */ 1456 /* Register with ASoC */
1247 dev_set_drvdata(&pdev->dev, ssi_private); 1457 dev_set_drvdata(&pdev->dev, ssi_private);
1248 1458
@@ -1253,6 +1463,10 @@ static int fsl_ssi_probe(struct platform_device *pdev)
1253 goto error_dev; 1463 goto error_dev;
1254 } 1464 }
1255 1465
1466 ret = fsl_ssi_debugfs_create(ssi_private, &pdev->dev);
1467 if (ret)
1468 goto error_dbgfs;
1469
1256 if (ssi_private->ssi_on_imx) { 1470 if (ssi_private->ssi_on_imx) {
1257 if (!ssi_private->use_dma) { 1471 if (!ssi_private->use_dma) {
1258 1472
@@ -1272,11 +1486,11 @@ static int fsl_ssi_probe(struct platform_device *pdev)
1272 1486
1273 ret = imx_pcm_fiq_init(pdev, &ssi_private->fiq_params); 1487 ret = imx_pcm_fiq_init(pdev, &ssi_private->fiq_params);
1274 if (ret) 1488 if (ret)
1275 goto error_dev; 1489 goto error_pcm;
1276 } else { 1490 } else {
1277 ret = imx_pcm_dma_init(pdev); 1491 ret = imx_pcm_dma_init(pdev);
1278 if (ret) 1492 if (ret)
1279 goto error_dev; 1493 goto error_pcm;
1280 } 1494 }
1281 } 1495 }
1282 1496
@@ -1318,6 +1532,13 @@ done:
1318 return 0; 1532 return 0;
1319 1533
1320error_dai: 1534error_dai:
1535 if (ssi_private->ssi_on_imx && !ssi_private->use_dma)
1536 imx_pcm_fiq_exit(pdev);
1537
1538error_pcm:
1539 fsl_ssi_debugfs_remove(ssi_private);
1540
1541error_dbgfs:
1321 snd_soc_unregister_component(&pdev->dev); 1542 snd_soc_unregister_component(&pdev->dev);
1322 1543
1323error_dev: 1544error_dev:
@@ -1331,7 +1552,8 @@ error_clk:
1331 } 1552 }
1332 1553
1333error_irqmap: 1554error_irqmap:
1334 irq_dispose_mapping(ssi_private->irq); 1555 if (ssi_private->irq_stats)
1556 irq_dispose_mapping(ssi_private->irq);
1335 1557
1336 return ret; 1558 return ret;
1337} 1559}
@@ -1340,27 +1562,22 @@ static int fsl_ssi_remove(struct platform_device *pdev)
1340{ 1562{
1341 struct fsl_ssi_private *ssi_private = dev_get_drvdata(&pdev->dev); 1563 struct fsl_ssi_private *ssi_private = dev_get_drvdata(&pdev->dev);
1342 1564
1565 fsl_ssi_debugfs_remove(ssi_private);
1566
1343 if (!ssi_private->new_binding) 1567 if (!ssi_private->new_binding)
1344 platform_device_unregister(ssi_private->pdev); 1568 platform_device_unregister(ssi_private->pdev);
1345 snd_soc_unregister_component(&pdev->dev); 1569 snd_soc_unregister_component(&pdev->dev);
1346 device_remove_file(&pdev->dev, &ssi_private->dev_attr);
1347 if (ssi_private->ssi_on_imx) { 1570 if (ssi_private->ssi_on_imx) {
1348 if (!IS_ERR(ssi_private->baudclk)) 1571 if (!IS_ERR(ssi_private->baudclk))
1349 clk_disable_unprepare(ssi_private->baudclk); 1572 clk_disable_unprepare(ssi_private->baudclk);
1350 clk_disable_unprepare(ssi_private->clk); 1573 clk_disable_unprepare(ssi_private->clk);
1351 } 1574 }
1352 irq_dispose_mapping(ssi_private->irq); 1575 if (ssi_private->irq_stats)
1576 irq_dispose_mapping(ssi_private->irq);
1353 1577
1354 return 0; 1578 return 0;
1355} 1579}
1356 1580
1357static const struct of_device_id fsl_ssi_ids[] = {
1358 { .compatible = "fsl,mpc8610-ssi", },
1359 { .compatible = "fsl,imx21-ssi", },
1360 {}
1361};
1362MODULE_DEVICE_TABLE(of, fsl_ssi_ids);
1363
1364static struct platform_driver fsl_ssi_driver = { 1581static struct platform_driver fsl_ssi_driver = {
1365 .driver = { 1582 .driver = {
1366 .name = "fsl-ssi-dai", 1583 .name = "fsl-ssi-dai",
diff --git a/sound/soc/fsl/imx-pcm-dma.c b/sound/soc/fsl/imx-pcm-dma.c
index c5e47f866b4b..2585ae44e634 100644
--- a/sound/soc/fsl/imx-pcm-dma.c
+++ b/sound/soc/fsl/imx-pcm-dma.c
@@ -41,9 +41,6 @@ static const struct snd_pcm_hardware imx_pcm_hardware = {
41 SNDRV_PCM_INFO_PAUSE | 41 SNDRV_PCM_INFO_PAUSE |
42 SNDRV_PCM_INFO_RESUME, 42 SNDRV_PCM_INFO_RESUME,
43 .formats = SNDRV_PCM_FMTBIT_S16_LE, 43 .formats = SNDRV_PCM_FMTBIT_S16_LE,
44 .rate_min = 8000,
45 .channels_min = 2,
46 .channels_max = 2,
47 .buffer_bytes_max = IMX_SSI_DMABUF_SIZE, 44 .buffer_bytes_max = IMX_SSI_DMABUF_SIZE,
48 .period_bytes_min = 128, 45 .period_bytes_min = 128,
49 .period_bytes_max = 65535, /* Limited by SDMA engine */ 46 .period_bytes_max = 65535, /* Limited by SDMA engine */
diff --git a/sound/soc/fsl/imx-pcm-fiq.c b/sound/soc/fsl/imx-pcm-fiq.c
index c75d43bb2e92..6553202dd48c 100644
--- a/sound/soc/fsl/imx-pcm-fiq.c
+++ b/sound/soc/fsl/imx-pcm-fiq.c
@@ -162,9 +162,6 @@ static struct snd_pcm_hardware snd_imx_hardware = {
162 SNDRV_PCM_INFO_PAUSE | 162 SNDRV_PCM_INFO_PAUSE |
163 SNDRV_PCM_INFO_RESUME, 163 SNDRV_PCM_INFO_RESUME,
164 .formats = SNDRV_PCM_FMTBIT_S16_LE, 164 .formats = SNDRV_PCM_FMTBIT_S16_LE,
165 .rate_min = 8000,
166 .channels_min = 2,
167 .channels_max = 2,
168 .buffer_bytes_max = IMX_SSI_DMABUF_SIZE, 165 .buffer_bytes_max = IMX_SSI_DMABUF_SIZE,
169 .period_bytes_min = 128, 166 .period_bytes_min = 128,
170 .period_bytes_max = 16 * 1024, 167 .period_bytes_max = 16 * 1024,
diff --git a/sound/soc/fsl/mpc5200_dma.c b/sound/soc/fsl/mpc5200_dma.c
index 71bf2f248cd4..f2b5d756b1f3 100644
--- a/sound/soc/fsl/mpc5200_dma.c
+++ b/sound/soc/fsl/mpc5200_dma.c
@@ -200,10 +200,6 @@ static const struct snd_pcm_hardware psc_dma_hardware = {
200 SNDRV_PCM_INFO_BATCH, 200 SNDRV_PCM_INFO_BATCH,
201 .formats = SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_BE | 201 .formats = SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_BE |
202 SNDRV_PCM_FMTBIT_S24_BE | SNDRV_PCM_FMTBIT_S32_BE, 202 SNDRV_PCM_FMTBIT_S24_BE | SNDRV_PCM_FMTBIT_S32_BE,
203 .rate_min = 8000,
204 .rate_max = 48000,
205 .channels_min = 1,
206 .channels_max = 2,
207 .period_bytes_max = 1024 * 1024, 203 .period_bytes_max = 1024 * 1024,
208 .period_bytes_min = 32, 204 .period_bytes_min = 32,
209 .periods_min = 2, 205 .periods_min = 2,
diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c
index c0d928138c88..2a1b1b5b5221 100644
--- a/sound/soc/generic/simple-card.c
+++ b/sound/soc/generic/simple-card.c
@@ -9,14 +9,12 @@
9 * published by the Free Software Foundation. 9 * published by the Free Software Foundation.
10 */ 10 */
11#include <linux/clk.h> 11#include <linux/clk.h>
12#include <linux/module.h>
12#include <linux/of.h> 13#include <linux/of.h>
13#include <linux/platform_device.h> 14#include <linux/platform_device.h>
14#include <linux/module.h> 15#include <linux/string.h>
15#include <sound/simple_card.h> 16#include <sound/simple_card.h>
16 17
17#define asoc_simple_get_card_info(p) \
18 container_of(p->dai_link, struct asoc_simple_card_info, snd_link)
19
20static int __asoc_simple_card_dai_init(struct snd_soc_dai *dai, 18static int __asoc_simple_card_dai_init(struct snd_soc_dai *dai,
21 struct asoc_simple_dai *set, 19 struct asoc_simple_dai *set,
22 unsigned int daifmt) 20 unsigned int daifmt)
@@ -41,7 +39,8 @@ static int __asoc_simple_card_dai_init(struct snd_soc_dai *dai,
41 39
42static int asoc_simple_card_dai_init(struct snd_soc_pcm_runtime *rtd) 40static int asoc_simple_card_dai_init(struct snd_soc_pcm_runtime *rtd)
43{ 41{
44 struct asoc_simple_card_info *info = asoc_simple_get_card_info(rtd); 42 struct asoc_simple_card_info *info =
43 snd_soc_card_get_drvdata(rtd->card);
45 struct snd_soc_dai *codec = rtd->codec_dai; 44 struct snd_soc_dai *codec = rtd->codec_dai;
46 struct snd_soc_dai *cpu = rtd->cpu_dai; 45 struct snd_soc_dai *cpu = rtd->cpu_dai;
47 unsigned int daifmt = info->daifmt; 46 unsigned int daifmt = info->daifmt;
@@ -106,12 +105,8 @@ asoc_simple_card_sub_parse_of(struct device_node *np,
106 &dai->sysclk); 105 &dai->sysclk);
107 } else { 106 } else {
108 clk = of_clk_get(*node, 0); 107 clk = of_clk_get(*node, 0);
109 if (IS_ERR(clk)) { 108 if (!IS_ERR(clk))
110 ret = PTR_ERR(clk); 109 dai->sysclk = clk_get_rate(clk);
111 goto parse_error;
112 }
113
114 dai->sysclk = clk_get_rate(clk);
115 } 110 }
116 111
117 ret = 0; 112 ret = 0;
@@ -138,10 +133,12 @@ static int asoc_simple_card_parse_of(struct device_node *node,
138 (SND_SOC_DAIFMT_FORMAT_MASK | SND_SOC_DAIFMT_INV_MASK); 133 (SND_SOC_DAIFMT_FORMAT_MASK | SND_SOC_DAIFMT_INV_MASK);
139 134
140 /* DAPM routes */ 135 /* DAPM routes */
141 ret = snd_soc_of_parse_audio_routing(&info->snd_card, 136 if (of_property_read_bool(node, "simple-audio-card,routing")) {
142 "simple-audio-routing"); 137 ret = snd_soc_of_parse_audio_routing(&info->snd_card,
143 if (ret) 138 "simple-audio-card,routing");
144 return ret; 139 if (ret)
140 return ret;
141 }
145 142
146 /* CPU sub-node */ 143 /* CPU sub-node */
147 ret = -EINVAL; 144 ret = -EINVAL;
@@ -197,34 +194,37 @@ static int asoc_simple_card_probe(struct platform_device *pdev)
197 struct device_node *np = pdev->dev.of_node; 194 struct device_node *np = pdev->dev.of_node;
198 struct device_node *of_cpu, *of_codec, *of_platform; 195 struct device_node *of_cpu, *of_codec, *of_platform;
199 struct device *dev = &pdev->dev; 196 struct device *dev = &pdev->dev;
197 int ret;
200 198
201 cinfo = NULL; 199 cinfo = NULL;
202 of_cpu = NULL; 200 of_cpu = NULL;
203 of_codec = NULL; 201 of_codec = NULL;
204 of_platform = NULL; 202 of_platform = NULL;
203
204 cinfo = devm_kzalloc(dev, sizeof(*cinfo), GFP_KERNEL);
205 if (!cinfo)
206 return -ENOMEM;
207
205 if (np && of_device_is_available(np)) { 208 if (np && of_device_is_available(np)) {
206 cinfo = devm_kzalloc(dev, sizeof(*cinfo), GFP_KERNEL); 209 cinfo->snd_card.dev = dev;
207 if (cinfo) { 210
208 int ret; 211 ret = asoc_simple_card_parse_of(np, cinfo, dev,
209 cinfo->snd_card.dev = &pdev->dev; 212 &of_cpu,
210 ret = asoc_simple_card_parse_of(np, cinfo, dev, 213 &of_codec,
211 &of_cpu, 214 &of_platform);
212 &of_codec, 215 if (ret < 0) {
213 &of_platform); 216 if (ret != -EPROBE_DEFER)
214 if (ret < 0) { 217 dev_err(dev, "parse error %d\n", ret);
215 if (ret != -EPROBE_DEFER) 218 return ret;
216 dev_err(dev, "parse error %d\n", ret);
217 return ret;
218 }
219 } 219 }
220 } else { 220 } else {
221 cinfo->snd_card.dev = &pdev->dev; 221 if (!dev->platform_data) {
222 cinfo = pdev->dev.platform_data; 222 dev_err(dev, "no info for asoc-simple-card\n");
223 } 223 return -EINVAL;
224 }
224 225
225 if (!cinfo) { 226 memcpy(cinfo, dev->platform_data, sizeof(*cinfo));
226 dev_err(dev, "no info for asoc-simple-card\n"); 227 cinfo->snd_card.dev = dev;
227 return -EINVAL;
228 } 228 }
229 229
230 if (!cinfo->name || 230 if (!cinfo->name ||
@@ -259,6 +259,8 @@ static int asoc_simple_card_probe(struct platform_device *pdev)
259 cinfo->snd_card.dai_link = &cinfo->snd_link; 259 cinfo->snd_card.dai_link = &cinfo->snd_link;
260 cinfo->snd_card.num_links = 1; 260 cinfo->snd_card.num_links = 1;
261 261
262 snd_soc_card_set_drvdata(&cinfo->snd_card, cinfo);
263
262 return devm_snd_soc_register_card(&pdev->dev, &cinfo->snd_card); 264 return devm_snd_soc_register_card(&pdev->dev, &cinfo->snd_card);
263} 265}
264 266
diff --git a/sound/soc/intel/sst_platform.c b/sound/soc/intel/sst_platform.c
index b6b5eb698d33..f465a8180863 100644
--- a/sound/soc/intel/sst_platform.c
+++ b/sound/soc/intel/sst_platform.c
@@ -89,16 +89,6 @@ static struct snd_pcm_hardware sst_platform_pcm_hw = {
89 SNDRV_PCM_INFO_MMAP_VALID | 89 SNDRV_PCM_INFO_MMAP_VALID |
90 SNDRV_PCM_INFO_BLOCK_TRANSFER | 90 SNDRV_PCM_INFO_BLOCK_TRANSFER |
91 SNDRV_PCM_INFO_SYNC_START), 91 SNDRV_PCM_INFO_SYNC_START),
92 .formats = (SNDRV_PCM_FMTBIT_S16 | SNDRV_PCM_FMTBIT_U16 |
93 SNDRV_PCM_FMTBIT_S24 | SNDRV_PCM_FMTBIT_U24 |
94 SNDRV_PCM_FMTBIT_S32 | SNDRV_PCM_FMTBIT_U32),
95 .rates = (SNDRV_PCM_RATE_8000|
96 SNDRV_PCM_RATE_44100 |
97 SNDRV_PCM_RATE_48000),
98 .rate_min = SST_MIN_RATE,
99 .rate_max = SST_MAX_RATE,
100 .channels_min = SST_MIN_CHANNEL,
101 .channels_max = SST_MAX_CHANNEL,
102 .buffer_bytes_max = SST_MAX_BUFFER, 92 .buffer_bytes_max = SST_MAX_BUFFER,
103 .period_bytes_min = SST_MIN_PERIOD_BYTES, 93 .period_bytes_min = SST_MIN_PERIOD_BYTES,
104 .period_bytes_max = SST_MAX_PERIOD_BYTES, 94 .period_bytes_max = SST_MAX_PERIOD_BYTES,
diff --git a/sound/soc/intel/sst_platform.h b/sound/soc/intel/sst_platform.h
index cacc9066ec52..bee64fb7d2ef 100644
--- a/sound/soc/intel/sst_platform.h
+++ b/sound/soc/intel/sst_platform.h
@@ -33,10 +33,6 @@
33#define SST_STEREO 2 33#define SST_STEREO 2
34#define SST_MAX_CAP 5 34#define SST_MAX_CAP 5
35 35
36#define SST_MIN_RATE 8000
37#define SST_MAX_RATE 48000
38#define SST_MIN_CHANNEL 1
39#define SST_MAX_CHANNEL 5
40#define SST_MAX_BUFFER (800*1024) 36#define SST_MAX_BUFFER (800*1024)
41#define SST_MIN_BUFFER (800*1024) 37#define SST_MIN_BUFFER (800*1024)
42#define SST_MIN_PERIOD_BYTES 32 38#define SST_MIN_PERIOD_BYTES 32
diff --git a/sound/soc/kirkwood/kirkwood-dma.c b/sound/soc/kirkwood/kirkwood-dma.c
index 4af1936cf0f4..aac22fccdcdc 100644
--- a/sound/soc/kirkwood/kirkwood-dma.c
+++ b/sound/soc/kirkwood/kirkwood-dma.c
@@ -21,16 +21,6 @@
21#include <sound/soc.h> 21#include <sound/soc.h>
22#include "kirkwood.h" 22#include "kirkwood.h"
23 23
24#define KIRKWOOD_RATES \
25 (SNDRV_PCM_RATE_8000_192000 | \
26 SNDRV_PCM_RATE_CONTINUOUS | \
27 SNDRV_PCM_RATE_KNOT)
28
29#define KIRKWOOD_FORMATS \
30 (SNDRV_PCM_FMTBIT_S16_LE | \
31 SNDRV_PCM_FMTBIT_S24_LE | \
32 SNDRV_PCM_FMTBIT_S32_LE)
33
34static struct kirkwood_dma_data *kirkwood_priv(struct snd_pcm_substream *subs) 24static struct kirkwood_dma_data *kirkwood_priv(struct snd_pcm_substream *subs)
35{ 25{
36 struct snd_soc_pcm_runtime *soc_runtime = subs->private_data; 26 struct snd_soc_pcm_runtime *soc_runtime = subs->private_data;
@@ -43,12 +33,6 @@ static struct snd_pcm_hardware kirkwood_dma_snd_hw = {
43 SNDRV_PCM_INFO_MMAP_VALID | 33 SNDRV_PCM_INFO_MMAP_VALID |
44 SNDRV_PCM_INFO_BLOCK_TRANSFER | 34 SNDRV_PCM_INFO_BLOCK_TRANSFER |
45 SNDRV_PCM_INFO_PAUSE), 35 SNDRV_PCM_INFO_PAUSE),
46 .formats = KIRKWOOD_FORMATS,
47 .rates = KIRKWOOD_RATES,
48 .rate_min = 8000,
49 .rate_max = 384000,
50 .channels_min = 1,
51 .channels_max = 8,
52 .buffer_bytes_max = KIRKWOOD_SND_MAX_BUFFER_BYTES, 36 .buffer_bytes_max = KIRKWOOD_SND_MAX_BUFFER_BYTES,
53 .period_bytes_min = KIRKWOOD_SND_MIN_PERIOD_BYTES, 37 .period_bytes_min = KIRKWOOD_SND_MIN_PERIOD_BYTES,
54 .period_bytes_max = KIRKWOOD_SND_MAX_PERIOD_BYTES, 38 .period_bytes_max = KIRKWOOD_SND_MAX_PERIOD_BYTES,
diff --git a/sound/soc/mxs/mxs-pcm.c b/sound/soc/mxs/mxs-pcm.c
index 04a6b0d60944..a371b4f91c53 100644
--- a/sound/soc/mxs/mxs-pcm.c
+++ b/sound/soc/mxs/mxs-pcm.c
@@ -36,11 +36,6 @@ static const struct snd_pcm_hardware snd_mxs_hardware = {
36 SNDRV_PCM_INFO_RESUME | 36 SNDRV_PCM_INFO_RESUME |
37 SNDRV_PCM_INFO_INTERLEAVED | 37 SNDRV_PCM_INFO_INTERLEAVED |
38 SNDRV_PCM_INFO_HALF_DUPLEX, 38 SNDRV_PCM_INFO_HALF_DUPLEX,
39 .formats = SNDRV_PCM_FMTBIT_S16_LE |
40 SNDRV_PCM_FMTBIT_S20_3LE |
41 SNDRV_PCM_FMTBIT_S24_LE,
42 .channels_min = 2,
43 .channels_max = 2,
44 .period_bytes_min = 32, 39 .period_bytes_min = 32,
45 .period_bytes_max = 8192, 40 .period_bytes_max = 8192,
46 .periods_min = 1, 41 .periods_min = 1,
@@ -57,7 +52,6 @@ static const struct snd_dmaengine_pcm_config mxs_dmaengine_pcm_config = {
57int mxs_pcm_platform_register(struct device *dev) 52int mxs_pcm_platform_register(struct device *dev)
58{ 53{
59 return devm_snd_dmaengine_pcm_register(dev, &mxs_dmaengine_pcm_config, 54 return devm_snd_dmaengine_pcm_register(dev, &mxs_dmaengine_pcm_config,
60 SND_DMAENGINE_PCM_FLAG_NO_RESIDUE |
61 SND_DMAENGINE_PCM_FLAG_HALF_DUPLEX); 55 SND_DMAENGINE_PCM_FLAG_HALF_DUPLEX);
62} 56}
63EXPORT_SYMBOL_GPL(mxs_pcm_platform_register); 57EXPORT_SYMBOL_GPL(mxs_pcm_platform_register);
diff --git a/sound/soc/nuc900/nuc900-pcm.c b/sound/soc/nuc900/nuc900-pcm.c
index f588ee45b4fd..f434ed79d1b6 100644
--- a/sound/soc/nuc900/nuc900-pcm.c
+++ b/sound/soc/nuc900/nuc900-pcm.c
@@ -32,9 +32,6 @@ static const struct snd_pcm_hardware nuc900_pcm_hardware = {
32 SNDRV_PCM_INFO_MMAP_VALID | 32 SNDRV_PCM_INFO_MMAP_VALID |
33 SNDRV_PCM_INFO_PAUSE | 33 SNDRV_PCM_INFO_PAUSE |
34 SNDRV_PCM_INFO_RESUME, 34 SNDRV_PCM_INFO_RESUME,
35 .formats = SNDRV_PCM_FMTBIT_S16_LE,
36 .channels_min = 1,
37 .channels_max = 2,
38 .buffer_bytes_max = 4*1024, 35 .buffer_bytes_max = 4*1024,
39 .period_bytes_min = 1*1024, 36 .period_bytes_min = 1*1024,
40 .period_bytes_max = 4*1024, 37 .period_bytes_max = 4*1024,
diff --git a/sound/soc/sh/dma-sh7760.c b/sound/soc/sh/dma-sh7760.c
index 1a8b03e4b41b..c85f8eb66c97 100644
--- a/sound/soc/sh/dma-sh7760.c
+++ b/sound/soc/sh/dma-sh7760.c
@@ -89,29 +89,12 @@ struct camelot_pcm {
89#define DMABRG_PREALLOC_BUFFER 32 * 1024 89#define DMABRG_PREALLOC_BUFFER 32 * 1024
90#define DMABRG_PREALLOC_BUFFER_MAX 32 * 1024 90#define DMABRG_PREALLOC_BUFFER_MAX 32 * 1024
91 91
92/* support everything the SSI supports */
93#define DMABRG_RATES \
94 SNDRV_PCM_RATE_8000_192000
95
96#define DMABRG_FMTS \
97 (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U8 | \
98 SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_LE | \
99 SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_U20_3LE | \
100 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_U24_3LE | \
101 SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_U32_LE)
102
103static struct snd_pcm_hardware camelot_pcm_hardware = { 92static struct snd_pcm_hardware camelot_pcm_hardware = {
104 .info = (SNDRV_PCM_INFO_MMAP | 93 .info = (SNDRV_PCM_INFO_MMAP |
105 SNDRV_PCM_INFO_INTERLEAVED | 94 SNDRV_PCM_INFO_INTERLEAVED |
106 SNDRV_PCM_INFO_BLOCK_TRANSFER | 95 SNDRV_PCM_INFO_BLOCK_TRANSFER |
107 SNDRV_PCM_INFO_MMAP_VALID | 96 SNDRV_PCM_INFO_MMAP_VALID |
108 SNDRV_PCM_INFO_BATCH), 97 SNDRV_PCM_INFO_BATCH),
109 .formats = DMABRG_FMTS,
110 .rates = DMABRG_RATES,
111 .rate_min = 8000,
112 .rate_max = 192000,
113 .channels_min = 2,
114 .channels_max = 8, /* max of the SSI */
115 .buffer_bytes_max = DMABRG_PERIOD_MAX, 98 .buffer_bytes_max = DMABRG_PERIOD_MAX,
116 .period_bytes_min = DMABRG_PERIOD_MIN, 99 .period_bytes_min = DMABRG_PERIOD_MIN,
117 .period_bytes_max = DMABRG_PERIOD_MAX / 2, 100 .period_bytes_max = DMABRG_PERIOD_MAX / 2,
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
index 6101055aae1d..1967f44e7cd4 100644
--- a/sound/soc/sh/fsi.c
+++ b/sound/soc/sh/fsi.c
@@ -1787,12 +1787,6 @@ static struct snd_pcm_hardware fsi_pcm_hardware = {
1787 SNDRV_PCM_INFO_MMAP | 1787 SNDRV_PCM_INFO_MMAP |
1788 SNDRV_PCM_INFO_MMAP_VALID | 1788 SNDRV_PCM_INFO_MMAP_VALID |
1789 SNDRV_PCM_INFO_PAUSE, 1789 SNDRV_PCM_INFO_PAUSE,
1790 .formats = FSI_FMTS,
1791 .rates = FSI_RATES,
1792 .rate_min = 8000,
1793 .rate_max = 192000,
1794 .channels_min = 2,
1795 .channels_max = 2,
1796 .buffer_bytes_max = 64 * 1024, 1790 .buffer_bytes_max = 64 * 1024,
1797 .period_bytes_min = 32, 1791 .period_bytes_min = 32,
1798 .period_bytes_max = 8192, 1792 .period_bytes_max = 8192,
diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c
index b3653d37f75f..743de5e3b1e1 100644
--- a/sound/soc/sh/rcar/core.c
+++ b/sound/soc/sh/rcar/core.c
@@ -628,12 +628,6 @@ static struct snd_pcm_hardware rsnd_pcm_hardware = {
628 SNDRV_PCM_INFO_MMAP | 628 SNDRV_PCM_INFO_MMAP |
629 SNDRV_PCM_INFO_MMAP_VALID | 629 SNDRV_PCM_INFO_MMAP_VALID |
630 SNDRV_PCM_INFO_PAUSE, 630 SNDRV_PCM_INFO_PAUSE,
631 .formats = RSND_FMTS,
632 .rates = RSND_RATES,
633 .rate_min = 8000,
634 .rate_max = 192000,
635 .channels_min = 2,
636 .channels_max = 2,
637 .buffer_bytes_max = 64 * 1024, 631 .buffer_bytes_max = 64 * 1024,
638 .period_bytes_min = 32, 632 .period_bytes_min = 32,
639 .period_bytes_max = 8192, 633 .period_bytes_max = 8192,
diff --git a/sound/soc/ux500/mop500.c b/sound/soc/ux500/mop500.c
index 178d1bad6259..b3b66aa98dce 100644
--- a/sound/soc/ux500/mop500.c
+++ b/sound/soc/ux500/mop500.c
@@ -91,6 +91,8 @@ static int mop500_of_probe(struct platform_device *pdev,
91 for (i = 0; i < 2; i++) { 91 for (i = 0; i < 2; i++) {
92 mop500_dai_links[i].cpu_of_node = msp_np[i]; 92 mop500_dai_links[i].cpu_of_node = msp_np[i];
93 mop500_dai_links[i].cpu_dai_name = NULL; 93 mop500_dai_links[i].cpu_dai_name = NULL;
94 mop500_dai_links[i].platform_of_node = msp_np[i];
95 mop500_dai_links[i].platform_name = NULL;
94 mop500_dai_links[i].codec_of_node = codec_np; 96 mop500_dai_links[i].codec_of_node = codec_np;
95 mop500_dai_links[i].codec_name = NULL; 97 mop500_dai_links[i].codec_name = NULL;
96 } 98 }
diff --git a/sound/soc/ux500/ux500_msp_dai.c b/sound/soc/ux500/ux500_msp_dai.c
index c6fb5cce980e..5f4807b2c007 100644
--- a/sound/soc/ux500/ux500_msp_dai.c
+++ b/sound/soc/ux500/ux500_msp_dai.c
@@ -17,12 +17,14 @@
17#include <linux/bitops.h> 17#include <linux/bitops.h>
18#include <linux/platform_device.h> 18#include <linux/platform_device.h>
19#include <linux/clk.h> 19#include <linux/clk.h>
20#include <linux/of.h>
20#include <linux/regulator/consumer.h> 21#include <linux/regulator/consumer.h>
21#include <linux/mfd/dbx500-prcmu.h> 22#include <linux/mfd/dbx500-prcmu.h>
22#include <linux/platform_data/asoc-ux500-msp.h> 23#include <linux/platform_data/asoc-ux500-msp.h>
23 24
24#include <sound/soc.h> 25#include <sound/soc.h>
25#include <sound/soc-dai.h> 26#include <sound/soc-dai.h>
27#include <sound/dmaengine_pcm.h>
26 28
27#include "ux500_msp_i2s.h" 29#include "ux500_msp_i2s.h"
28#include "ux500_msp_dai.h" 30#include "ux500_msp_dai.h"
@@ -654,16 +656,52 @@ static int ux500_msp_dai_trigger(struct snd_pcm_substream *substream,
654 return ret; 656 return ret;
655} 657}
656 658
659static int ux500_msp_dai_of_probe(struct snd_soc_dai *dai)
660{
661 struct ux500_msp_i2s_drvdata *drvdata = dev_get_drvdata(dai->dev);
662 struct snd_dmaengine_dai_dma_data *playback_dma_data;
663 struct snd_dmaengine_dai_dma_data *capture_dma_data;
664
665 playback_dma_data = devm_kzalloc(dai->dev,
666 sizeof(*playback_dma_data),
667 GFP_KERNEL);
668 if (!playback_dma_data)
669 return -ENOMEM;
670
671 capture_dma_data = devm_kzalloc(dai->dev,
672 sizeof(*capture_dma_data),
673 GFP_KERNEL);
674 if (!capture_dma_data)
675 return -ENOMEM;
676
677 playback_dma_data->addr = drvdata->msp->playback_dma_data.tx_rx_addr;
678 capture_dma_data->addr = drvdata->msp->capture_dma_data.tx_rx_addr;
679
680 playback_dma_data->maxburst = 4;
681 capture_dma_data->maxburst = 4;
682
683 snd_soc_dai_init_dma_data(dai, playback_dma_data, capture_dma_data);
684
685 return 0;
686}
687
657static int ux500_msp_dai_probe(struct snd_soc_dai *dai) 688static int ux500_msp_dai_probe(struct snd_soc_dai *dai)
658{ 689{
659 struct ux500_msp_i2s_drvdata *drvdata = dev_get_drvdata(dai->dev); 690 struct ux500_msp_i2s_drvdata *drvdata = dev_get_drvdata(dai->dev);
691 struct msp_i2s_platform_data *pdata = dai->dev->platform_data;
692 int ret;
660 693
661 dai->playback_dma_data = &drvdata->msp->playback_dma_data; 694 if (!pdata) {
662 dai->capture_dma_data = &drvdata->msp->capture_dma_data; 695 ret = ux500_msp_dai_of_probe(dai);
696 return ret;
697 }
663 698
664 drvdata->msp->playback_dma_data.data_size = drvdata->slot_width; 699 drvdata->msp->playback_dma_data.data_size = drvdata->slot_width;
665 drvdata->msp->capture_dma_data.data_size = drvdata->slot_width; 700 drvdata->msp->capture_dma_data.data_size = drvdata->slot_width;
666 701
702 snd_soc_dai_init_dma_data(dai,
703 &drvdata->msp->playback_dma_data,
704 &drvdata->msp->capture_dma_data);
667 return 0; 705 return 0;
668} 706}
669 707
@@ -680,87 +718,19 @@ static struct snd_soc_dai_ops ux500_msp_dai_ops[] = {
680 } 718 }
681}; 719};
682 720
683static struct snd_soc_dai_driver ux500_msp_dai_drv[UX500_NBR_OF_DAI] = { 721static struct snd_soc_dai_driver ux500_msp_dai_drv = {
684 { 722 .probe = ux500_msp_dai_probe,
685 .name = "ux500-msp-i2s.0", 723 .suspend = NULL,
686 .probe = ux500_msp_dai_probe, 724 .resume = NULL,
687 .id = 0, 725 .playback.channels_min = UX500_MSP_MIN_CHANNELS,
688 .suspend = NULL, 726 .playback.channels_max = UX500_MSP_MAX_CHANNELS,
689 .resume = NULL, 727 .playback.rates = UX500_I2S_RATES,
690 .playback = { 728 .playback.formats = UX500_I2S_FORMATS,
691 .channels_min = UX500_MSP_MIN_CHANNELS, 729 .capture.channels_min = UX500_MSP_MIN_CHANNELS,
692 .channels_max = UX500_MSP_MAX_CHANNELS, 730 .capture.channels_max = UX500_MSP_MAX_CHANNELS,
693 .rates = UX500_I2S_RATES, 731 .capture.rates = UX500_I2S_RATES,
694 .formats = UX500_I2S_FORMATS, 732 .capture.formats = UX500_I2S_FORMATS,
695 }, 733 .ops = ux500_msp_dai_ops,
696 .capture = {
697 .channels_min = UX500_MSP_MIN_CHANNELS,
698 .channels_max = UX500_MSP_MAX_CHANNELS,
699 .rates = UX500_I2S_RATES,
700 .formats = UX500_I2S_FORMATS,
701 },
702 .ops = ux500_msp_dai_ops,
703 },
704 {
705 .name = "ux500-msp-i2s.1",
706 .probe = ux500_msp_dai_probe,
707 .id = 1,
708 .suspend = NULL,
709 .resume = NULL,
710 .playback = {
711 .channels_min = UX500_MSP_MIN_CHANNELS,
712 .channels_max = UX500_MSP_MAX_CHANNELS,
713 .rates = UX500_I2S_RATES,
714 .formats = UX500_I2S_FORMATS,
715 },
716 .capture = {
717 .channels_min = UX500_MSP_MIN_CHANNELS,
718 .channels_max = UX500_MSP_MAX_CHANNELS,
719 .rates = UX500_I2S_RATES,
720 .formats = UX500_I2S_FORMATS,
721 },
722 .ops = ux500_msp_dai_ops,
723 },
724 {
725 .name = "ux500-msp-i2s.2",
726 .id = 2,
727 .probe = ux500_msp_dai_probe,
728 .suspend = NULL,
729 .resume = NULL,
730 .playback = {
731 .channels_min = UX500_MSP_MIN_CHANNELS,
732 .channels_max = UX500_MSP_MAX_CHANNELS,
733 .rates = UX500_I2S_RATES,
734 .formats = UX500_I2S_FORMATS,
735 },
736 .capture = {
737 .channels_min = UX500_MSP_MIN_CHANNELS,
738 .channels_max = UX500_MSP_MAX_CHANNELS,
739 .rates = UX500_I2S_RATES,
740 .formats = UX500_I2S_FORMATS,
741 },
742 .ops = ux500_msp_dai_ops,
743 },
744 {
745 .name = "ux500-msp-i2s.3",
746 .probe = ux500_msp_dai_probe,
747 .id = 3,
748 .suspend = NULL,
749 .resume = NULL,
750 .playback = {
751 .channels_min = UX500_MSP_MIN_CHANNELS,
752 .channels_max = UX500_MSP_MAX_CHANNELS,
753 .rates = UX500_I2S_RATES,
754 .formats = UX500_I2S_FORMATS,
755 },
756 .capture = {
757 .channels_min = UX500_MSP_MIN_CHANNELS,
758 .channels_max = UX500_MSP_MAX_CHANNELS,
759 .rates = UX500_I2S_RATES,
760 .formats = UX500_I2S_FORMATS,
761 },
762 .ops = ux500_msp_dai_ops,
763 },
764}; 734};
765 735
766static const struct snd_soc_component_driver ux500_msp_component = { 736static const struct snd_soc_component_driver ux500_msp_component = {
@@ -771,10 +741,14 @@ static const struct snd_soc_component_driver ux500_msp_component = {
771static int ux500_msp_drv_probe(struct platform_device *pdev) 741static int ux500_msp_drv_probe(struct platform_device *pdev)
772{ 742{
773 struct ux500_msp_i2s_drvdata *drvdata; 743 struct ux500_msp_i2s_drvdata *drvdata;
744 struct msp_i2s_platform_data *pdata = pdev->dev.platform_data;
745 struct device_node *np = pdev->dev.of_node;
774 int ret = 0; 746 int ret = 0;
775 747
776 dev_dbg(&pdev->dev, "%s: Enter (pdev->name = %s).\n", __func__, 748 if (!pdata && !np) {
777 pdev->name); 749 dev_err(&pdev->dev, "No platform data or Device Tree found\n");
750 return -ENODEV;
751 }
778 752
779 drvdata = devm_kzalloc(&pdev->dev, 753 drvdata = devm_kzalloc(&pdev->dev,
780 sizeof(struct ux500_msp_i2s_drvdata), 754 sizeof(struct ux500_msp_i2s_drvdata),
@@ -826,7 +800,7 @@ static int ux500_msp_drv_probe(struct platform_device *pdev)
826 dev_set_drvdata(&pdev->dev, drvdata); 800 dev_set_drvdata(&pdev->dev, drvdata);
827 801
828 ret = snd_soc_register_component(&pdev->dev, &ux500_msp_component, 802 ret = snd_soc_register_component(&pdev->dev, &ux500_msp_component,
829 &ux500_msp_dai_drv[drvdata->msp->id], 1); 803 &ux500_msp_dai_drv, 1);
830 if (ret < 0) { 804 if (ret < 0) {
831 dev_err(&pdev->dev, "Error: %s: Failed to register MSP%d!\n", 805 dev_err(&pdev->dev, "Error: %s: Failed to register MSP%d!\n",
832 __func__, drvdata->msp->id); 806 __func__, drvdata->msp->id);
diff --git a/sound/soc/ux500/ux500_msp_i2s.c b/sound/soc/ux500/ux500_msp_i2s.c
index 1ca8b08ae993..959d7b4edf56 100644
--- a/sound/soc/ux500/ux500_msp_i2s.c
+++ b/sound/soc/ux500/ux500_msp_i2s.c
@@ -646,6 +646,34 @@ int ux500_msp_i2s_close(struct ux500_msp *msp, unsigned int dir)
646 646
647} 647}
648 648
649static int ux500_msp_i2s_of_init_msp(struct platform_device *pdev,
650 struct ux500_msp *msp,
651 struct msp_i2s_platform_data **platform_data)
652{
653 struct msp_i2s_platform_data *pdata;
654
655 *platform_data = devm_kzalloc(&pdev->dev,
656 sizeof(struct msp_i2s_platform_data),
657 GFP_KERNEL);
658 pdata = *platform_data;
659 if (!pdata)
660 return -ENOMEM;
661
662 msp->playback_dma_data.dma_cfg = devm_kzalloc(&pdev->dev,
663 sizeof(struct stedma40_chan_cfg),
664 GFP_KERNEL);
665 if (!msp->playback_dma_data.dma_cfg)
666 return -ENOMEM;
667
668 msp->capture_dma_data.dma_cfg = devm_kzalloc(&pdev->dev,
669 sizeof(struct stedma40_chan_cfg),
670 GFP_KERNEL);
671 if (!msp->capture_dma_data.dma_cfg)
672 return -ENOMEM;
673
674 return 0;
675}
676
649int ux500_msp_i2s_init_msp(struct platform_device *pdev, 677int ux500_msp_i2s_init_msp(struct platform_device *pdev,
650 struct ux500_msp **msp_p, 678 struct ux500_msp **msp_p,
651 struct msp_i2s_platform_data *platform_data) 679 struct msp_i2s_platform_data *platform_data)
@@ -653,30 +681,28 @@ int ux500_msp_i2s_init_msp(struct platform_device *pdev,
653 struct resource *res = NULL; 681 struct resource *res = NULL;
654 struct device_node *np = pdev->dev.of_node; 682 struct device_node *np = pdev->dev.of_node;
655 struct ux500_msp *msp; 683 struct ux500_msp *msp;
684 int ret;
656 685
657 *msp_p = devm_kzalloc(&pdev->dev, sizeof(struct ux500_msp), GFP_KERNEL); 686 *msp_p = devm_kzalloc(&pdev->dev, sizeof(struct ux500_msp), GFP_KERNEL);
658 msp = *msp_p; 687 msp = *msp_p;
659 if (!msp) 688 if (!msp)
660 return -ENOMEM; 689 return -ENOMEM;
661 690
662 if (np) { 691 if (!platform_data) {
663 if (!platform_data) { 692 if (np) {
664 platform_data = devm_kzalloc(&pdev->dev, 693 ret = ux500_msp_i2s_of_init_msp(pdev, msp,
665 sizeof(struct msp_i2s_platform_data), GFP_KERNEL); 694 &platform_data);
666 if (!platform_data) 695 if (ret)
667 return -ENOMEM; 696 return ret;
668 } 697 } else
669 } else
670 if (!platform_data)
671 return -EINVAL; 698 return -EINVAL;
699 } else {
700 msp->playback_dma_data.dma_cfg = platform_data->msp_i2s_dma_tx;
701 msp->capture_dma_data.dma_cfg = platform_data->msp_i2s_dma_rx;
702 msp->id = platform_data->id;
703 }
672 704
673 dev_dbg(&pdev->dev, "%s: Enter (name: %s, id: %d).\n", __func__,
674 pdev->name, platform_data->id);
675
676 msp->id = platform_data->id;
677 msp->dev = &pdev->dev; 705 msp->dev = &pdev->dev;
678 msp->playback_dma_data.dma_cfg = platform_data->msp_i2s_dma_tx;
679 msp->capture_dma_data.dma_cfg = platform_data->msp_i2s_dma_rx;
680 706
681 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 707 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
682 if (res == NULL) { 708 if (res == NULL) {
diff --git a/sound/soc/ux500/ux500_msp_i2s.h b/sound/soc/ux500/ux500_msp_i2s.h
index 258d0bcee0bd..875de0f68b85 100644
--- a/sound/soc/ux500/ux500_msp_i2s.h
+++ b/sound/soc/ux500/ux500_msp_i2s.h
@@ -475,7 +475,7 @@ struct ux500_msp_dma_params {
475}; 475};
476 476
477struct ux500_msp { 477struct ux500_msp {
478 enum msp_i2s_id id; 478 int id;
479 void __iomem *registers; 479 void __iomem *registers;
480 struct device *dev; 480 struct device *dev;
481 struct ux500_msp_dma_params playback_dma_data; 481 struct ux500_msp_dma_params playback_dma_data;
diff --git a/sound/soc/ux500/ux500_pcm.c b/sound/soc/ux500/ux500_pcm.c
index ce554de5d9dc..51a66a87305a 100644
--- a/sound/soc/ux500/ux500_pcm.c
+++ b/sound/soc/ux500/ux500_pcm.c
@@ -28,12 +28,6 @@
28#include "ux500_msp_i2s.h" 28#include "ux500_msp_i2s.h"
29#include "ux500_pcm.h" 29#include "ux500_pcm.h"
30 30
31#define UX500_PLATFORM_MIN_RATE 8000
32#define UX500_PLATFORM_MAX_RATE 48000
33
34#define UX500_PLATFORM_MIN_CHANNELS 1
35#define UX500_PLATFORM_MAX_CHANNELS 8
36
37#define UX500_PLATFORM_PERIODS_BYTES_MIN 128 31#define UX500_PLATFORM_PERIODS_BYTES_MIN 128
38#define UX500_PLATFORM_PERIODS_BYTES_MAX (64 * PAGE_SIZE) 32#define UX500_PLATFORM_PERIODS_BYTES_MAX (64 * PAGE_SIZE)
39#define UX500_PLATFORM_PERIODS_MIN 2 33#define UX500_PLATFORM_PERIODS_MIN 2
@@ -45,15 +39,6 @@ static const struct snd_pcm_hardware ux500_pcm_hw = {
45 SNDRV_PCM_INFO_MMAP | 39 SNDRV_PCM_INFO_MMAP |
46 SNDRV_PCM_INFO_RESUME | 40 SNDRV_PCM_INFO_RESUME |
47 SNDRV_PCM_INFO_PAUSE, 41 SNDRV_PCM_INFO_PAUSE,
48 .formats = SNDRV_PCM_FMTBIT_S16_LE |
49 SNDRV_PCM_FMTBIT_U16_LE |
50 SNDRV_PCM_FMTBIT_S16_BE |
51 SNDRV_PCM_FMTBIT_U16_BE,
52 .rates = SNDRV_PCM_RATE_KNOT,
53 .rate_min = UX500_PLATFORM_MIN_RATE,
54 .rate_max = UX500_PLATFORM_MAX_RATE,
55 .channels_min = UX500_PLATFORM_MIN_CHANNELS,
56 .channels_max = UX500_PLATFORM_MAX_CHANNELS,
57 .buffer_bytes_max = UX500_PLATFORM_BUFFER_BYTES_MAX, 42 .buffer_bytes_max = UX500_PLATFORM_BUFFER_BYTES_MAX,
58 .period_bytes_min = UX500_PLATFORM_PERIODS_BYTES_MIN, 43 .period_bytes_min = UX500_PLATFORM_PERIODS_BYTES_MIN,
59 .period_bytes_max = UX500_PLATFORM_PERIODS_BYTES_MAX, 44 .period_bytes_max = UX500_PLATFORM_PERIODS_BYTES_MAX,
@@ -65,14 +50,10 @@ static struct dma_chan *ux500_pcm_request_chan(struct snd_soc_pcm_runtime *rtd,
65 struct snd_pcm_substream *substream) 50 struct snd_pcm_substream *substream)
66{ 51{
67 struct snd_soc_dai *dai = rtd->cpu_dai; 52 struct snd_soc_dai *dai = rtd->cpu_dai;
68 struct device *dev = dai->dev;
69 u16 per_data_width, mem_data_width; 53 u16 per_data_width, mem_data_width;
70 struct stedma40_chan_cfg *dma_cfg; 54 struct stedma40_chan_cfg *dma_cfg;
71 struct ux500_msp_dma_params *dma_params; 55 struct ux500_msp_dma_params *dma_params;
72 56
73 dev_dbg(dev, "%s: MSP %d (%s): Enter.\n", __func__, dai->id,
74 snd_pcm_stream_str(substream));
75
76 dma_params = snd_soc_dai_get_dma_data(dai, substream); 57 dma_params = snd_soc_dai_get_dma_data(dai, substream);
77 dma_cfg = dma_params->dma_cfg; 58 dma_cfg = dma_params->dma_cfg;
78 59
@@ -108,26 +89,36 @@ static int ux500_pcm_prepare_slave_config(struct snd_pcm_substream *substream,
108 struct dma_slave_config *slave_config) 89 struct dma_slave_config *slave_config)
109{ 90{
110 struct snd_soc_pcm_runtime *rtd = substream->private_data; 91 struct snd_soc_pcm_runtime *rtd = substream->private_data;
111 struct ux500_msp_dma_params *dma_params; 92 struct msp_i2s_platform_data *pdata = rtd->cpu_dai->dev->platform_data;
112 struct stedma40_chan_cfg *dma_cfg; 93 struct snd_dmaengine_dai_dma_data *snd_dma_params;
94 struct ux500_msp_dma_params *ste_dma_params;
95 dma_addr_t dma_addr;
113 int ret; 96 int ret;
114 97
115 dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); 98 if (pdata) {
116 dma_cfg = dma_params->dma_cfg; 99 ste_dma_params =
100 snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
101 dma_addr = ste_dma_params->tx_rx_addr;
102 } else {
103 snd_dma_params =
104 snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
105 dma_addr = snd_dma_params->addr;
106 }
117 107
118 ret = snd_hwparams_to_dma_slave_config(substream, params, slave_config); 108 ret = snd_hwparams_to_dma_slave_config(substream, params, slave_config);
119 if (ret) 109 if (ret)
120 return ret; 110 return ret;
121 111
122 slave_config->dst_maxburst = 4; 112 slave_config->dst_maxburst = 4;
123 slave_config->dst_addr_width = dma_cfg->dst_info.data_width;
124 slave_config->src_maxburst = 4; 113 slave_config->src_maxburst = 4;
125 slave_config->src_addr_width = dma_cfg->src_info.data_width; 114
115 slave_config->src_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
116 slave_config->dst_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
126 117
127 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 118 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
128 slave_config->dst_addr = dma_params->tx_rx_addr; 119 slave_config->dst_addr = dma_addr;
129 else 120 else
130 slave_config->src_addr = dma_params->tx_rx_addr; 121 slave_config->src_addr = dma_addr;
131 122
132 return 0; 123 return 0;
133} 124}
@@ -139,15 +130,25 @@ static const struct snd_dmaengine_pcm_config ux500_dmaengine_pcm_config = {
139 .prepare_slave_config = ux500_pcm_prepare_slave_config, 130 .prepare_slave_config = ux500_pcm_prepare_slave_config,
140}; 131};
141 132
133static const struct snd_dmaengine_pcm_config ux500_dmaengine_of_pcm_config = {
134 .compat_request_channel = ux500_pcm_request_chan,
135 .prepare_slave_config = ux500_pcm_prepare_slave_config,
136};
137
142int ux500_pcm_register_platform(struct platform_device *pdev) 138int ux500_pcm_register_platform(struct platform_device *pdev)
143{ 139{
140 const struct snd_dmaengine_pcm_config *pcm_config;
141 struct device_node *np = pdev->dev.of_node;
144 int ret; 142 int ret;
145 143
146 ret = snd_dmaengine_pcm_register(&pdev->dev, 144 if (np)
147 &ux500_dmaengine_pcm_config, 145 pcm_config = &ux500_dmaengine_of_pcm_config;
148 SND_DMAENGINE_PCM_FLAG_NO_RESIDUE | 146 else
149 SND_DMAENGINE_PCM_FLAG_COMPAT | 147 pcm_config = &ux500_dmaengine_pcm_config;
150 SND_DMAENGINE_PCM_FLAG_NO_DT); 148
149 ret = snd_dmaengine_pcm_register(&pdev->dev, pcm_config,
150 SND_DMAENGINE_PCM_FLAG_NO_RESIDUE |
151 SND_DMAENGINE_PCM_FLAG_COMPAT);
151 if (ret < 0) { 152 if (ret < 0) {
152 dev_err(&pdev->dev, 153 dev_err(&pdev->dev,
153 "%s: ERROR: Failed to register platform '%s' (%d)!\n", 154 "%s: ERROR: Failed to register platform '%s' (%d)!\n",