diff options
Diffstat (limited to 'sound/soc')
184 files changed, 5206 insertions, 2843 deletions
diff --git a/sound/soc/adi/axi-i2s.c b/sound/soc/adi/axi-i2s.c index 7752860f7230..4c23381727a1 100644 --- a/sound/soc/adi/axi-i2s.c +++ b/sound/soc/adi/axi-i2s.c | |||
@@ -240,6 +240,8 @@ static int axi_i2s_probe(struct platform_device *pdev) | |||
240 | if (ret) | 240 | if (ret) |
241 | goto err_clk_disable; | 241 | goto err_clk_disable; |
242 | 242 | ||
243 | return 0; | ||
244 | |||
243 | err_clk_disable: | 245 | err_clk_disable: |
244 | clk_disable_unprepare(i2s->clk); | 246 | clk_disable_unprepare(i2s->clk); |
245 | return ret; | 247 | return ret; |
diff --git a/sound/soc/atmel/Kconfig b/sound/soc/atmel/Kconfig index fb3878312bf8..1579e994acf8 100644 --- a/sound/soc/atmel/Kconfig +++ b/sound/soc/atmel/Kconfig | |||
@@ -45,7 +45,7 @@ config SND_ATMEL_SOC_WM8904 | |||
45 | 45 | ||
46 | config SND_AT91_SOC_SAM9X5_WM8731 | 46 | config SND_AT91_SOC_SAM9X5_WM8731 |
47 | tristate "SoC Audio support for WM8731-based at91sam9x5 board" | 47 | tristate "SoC Audio support for WM8731-based at91sam9x5 board" |
48 | depends on ATMEL_SSC && SND_ATMEL_SOC && SOC_AT91SAM9X5 | 48 | depends on ARCH_AT91 && ATMEL_SSC && SND_ATMEL_SOC |
49 | select SND_ATMEL_SOC_SSC | 49 | select SND_ATMEL_SOC_SSC |
50 | select SND_ATMEL_SOC_DMA | 50 | select SND_ATMEL_SOC_DMA |
51 | select SND_SOC_WM8731 | 51 | select SND_SOC_WM8731 |
diff --git a/sound/soc/atmel/atmel-pcm-dma.c b/sound/soc/atmel/atmel-pcm-dma.c index 33fb3bb133df..b8e7bad05eb1 100644 --- a/sound/soc/atmel/atmel-pcm-dma.c +++ b/sound/soc/atmel/atmel-pcm-dma.c | |||
@@ -105,13 +105,11 @@ static int atmel_pcm_configure_dma(struct snd_pcm_substream *substream, | |||
105 | return ret; | 105 | return ret; |
106 | } | 106 | } |
107 | 107 | ||
108 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { | 108 | slave_config->dst_addr = ssc->phybase + SSC_THR; |
109 | slave_config->dst_addr = ssc->phybase + SSC_THR; | 109 | slave_config->dst_maxburst = 1; |
110 | slave_config->dst_maxburst = 1; | 110 | |
111 | } else { | 111 | slave_config->src_addr = ssc->phybase + SSC_RHR; |
112 | slave_config->src_addr = ssc->phybase + SSC_RHR; | 112 | slave_config->src_maxburst = 1; |
113 | slave_config->src_maxburst = 1; | ||
114 | } | ||
115 | 113 | ||
116 | prtd->dma_intr_handler = atmel_pcm_dma_irq; | 114 | prtd->dma_intr_handler = atmel_pcm_dma_irq; |
117 | 115 | ||
diff --git a/sound/soc/atmel/atmel_ssc_dai.c b/sound/soc/atmel/atmel_ssc_dai.c index 99ff35e2a25d..fb0b7e8b08ff 100644 --- a/sound/soc/atmel/atmel_ssc_dai.c +++ b/sound/soc/atmel/atmel_ssc_dai.c | |||
@@ -204,6 +204,13 @@ static int atmel_ssc_startup(struct snd_pcm_substream *substream, | |||
204 | pr_debug("atmel_ssc_startup: SSC_SR=0x%u\n", | 204 | pr_debug("atmel_ssc_startup: SSC_SR=0x%u\n", |
205 | ssc_readl(ssc_p->ssc->regs, SR)); | 205 | ssc_readl(ssc_p->ssc->regs, SR)); |
206 | 206 | ||
207 | /* Enable PMC peripheral clock for this SSC */ | ||
208 | pr_debug("atmel_ssc_dai: Starting clock\n"); | ||
209 | clk_enable(ssc_p->ssc->clk); | ||
210 | |||
211 | /* Reset the SSC to keep it at a clean status */ | ||
212 | ssc_writel(ssc_p->ssc->regs, CR, SSC_BIT(CR_SWRST)); | ||
213 | |||
207 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { | 214 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { |
208 | dir = 0; | 215 | dir = 0; |
209 | dir_mask = SSC_DIR_MASK_PLAYBACK; | 216 | dir_mask = SSC_DIR_MASK_PLAYBACK; |
@@ -250,11 +257,6 @@ static void atmel_ssc_shutdown(struct snd_pcm_substream *substream, | |||
250 | dma_params = ssc_p->dma_params[dir]; | 257 | dma_params = ssc_p->dma_params[dir]; |
251 | 258 | ||
252 | if (dma_params != NULL) { | 259 | if (dma_params != NULL) { |
253 | ssc_writel(ssc_p->ssc->regs, CR, dma_params->mask->ssc_disable); | ||
254 | pr_debug("atmel_ssc_shutdown: %s disabled SSC_SR=0x%08x\n", | ||
255 | (dir ? "receive" : "transmit"), | ||
256 | ssc_readl(ssc_p->ssc->regs, SR)); | ||
257 | |||
258 | dma_params->ssc = NULL; | 260 | dma_params->ssc = NULL; |
259 | dma_params->substream = NULL; | 261 | dma_params->substream = NULL; |
260 | ssc_p->dma_params[dir] = NULL; | 262 | ssc_p->dma_params[dir] = NULL; |
@@ -266,10 +268,6 @@ static void atmel_ssc_shutdown(struct snd_pcm_substream *substream, | |||
266 | ssc_p->dir_mask &= ~dir_mask; | 268 | ssc_p->dir_mask &= ~dir_mask; |
267 | if (!ssc_p->dir_mask) { | 269 | if (!ssc_p->dir_mask) { |
268 | if (ssc_p->initialized) { | 270 | if (ssc_p->initialized) { |
269 | /* Shutdown the SSC clock. */ | ||
270 | pr_debug("atmel_ssc_dai: Stopping clock\n"); | ||
271 | clk_disable(ssc_p->ssc->clk); | ||
272 | |||
273 | free_irq(ssc_p->ssc->irq, ssc_p); | 271 | free_irq(ssc_p->ssc->irq, ssc_p); |
274 | ssc_p->initialized = 0; | 272 | ssc_p->initialized = 0; |
275 | } | 273 | } |
@@ -280,6 +278,10 @@ static void atmel_ssc_shutdown(struct snd_pcm_substream *substream, | |||
280 | ssc_p->cmr_div = ssc_p->tcmr_period = ssc_p->rcmr_period = 0; | 278 | ssc_p->cmr_div = ssc_p->tcmr_period = ssc_p->rcmr_period = 0; |
281 | } | 279 | } |
282 | spin_unlock_irq(&ssc_p->lock); | 280 | spin_unlock_irq(&ssc_p->lock); |
281 | |||
282 | /* Shutdown the SSC clock. */ | ||
283 | pr_debug("atmel_ssc_dai: Stopping clock\n"); | ||
284 | clk_disable(ssc_p->ssc->clk); | ||
283 | } | 285 | } |
284 | 286 | ||
285 | 287 | ||
@@ -348,7 +350,6 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream, | |||
348 | struct atmel_pcm_dma_params *dma_params; | 350 | struct atmel_pcm_dma_params *dma_params; |
349 | int dir, channels, bits; | 351 | int dir, channels, bits; |
350 | u32 tfmr, rfmr, tcmr, rcmr; | 352 | u32 tfmr, rfmr, tcmr, rcmr; |
351 | int start_event; | ||
352 | int ret; | 353 | int ret; |
353 | int fslen, fslen_ext; | 354 | int fslen, fslen_ext; |
354 | 355 | ||
@@ -451,25 +452,10 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream, | |||
451 | break; | 452 | break; |
452 | 453 | ||
453 | case SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM: | 454 | case SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM: |
454 | /* | 455 | /* I2S format, CODEC supplies BCLK and LRC clocks. */ |
455 | * I2S format, CODEC supplies BCLK and LRC clocks. | ||
456 | * | ||
457 | * The SSC transmit clock is obtained from the BCLK signal on | ||
458 | * on the TK line, and the SSC receive clock is | ||
459 | * generated from the transmit clock. | ||
460 | * | ||
461 | * For single channel data, one sample is transferred | ||
462 | * on the falling edge of the LRC clock. | ||
463 | * For two channel data, one sample is | ||
464 | * transferred on both edges of the LRC clock. | ||
465 | */ | ||
466 | start_event = ((channels == 1) | ||
467 | ? SSC_START_FALLING_RF | ||
468 | : SSC_START_EDGE_RF); | ||
469 | |||
470 | rcmr = SSC_BF(RCMR_PERIOD, 0) | 456 | rcmr = SSC_BF(RCMR_PERIOD, 0) |
471 | | SSC_BF(RCMR_STTDLY, START_DELAY) | 457 | | SSC_BF(RCMR_STTDLY, START_DELAY) |
472 | | SSC_BF(RCMR_START, start_event) | 458 | | SSC_BF(RCMR_START, SSC_START_FALLING_RF) |
473 | | SSC_BF(RCMR_CKI, SSC_CKI_RISING) | 459 | | SSC_BF(RCMR_CKI, SSC_CKI_RISING) |
474 | | SSC_BF(RCMR_CKO, SSC_CKO_NONE) | 460 | | SSC_BF(RCMR_CKO, SSC_CKO_NONE) |
475 | | SSC_BF(RCMR_CKS, ssc->clk_from_rk_pin ? | 461 | | SSC_BF(RCMR_CKS, ssc->clk_from_rk_pin ? |
@@ -478,14 +464,14 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream, | |||
478 | rfmr = SSC_BF(RFMR_FSEDGE, SSC_FSEDGE_POSITIVE) | 464 | rfmr = SSC_BF(RFMR_FSEDGE, SSC_FSEDGE_POSITIVE) |
479 | | SSC_BF(RFMR_FSOS, SSC_FSOS_NONE) | 465 | | SSC_BF(RFMR_FSOS, SSC_FSOS_NONE) |
480 | | SSC_BF(RFMR_FSLEN, 0) | 466 | | SSC_BF(RFMR_FSLEN, 0) |
481 | | SSC_BF(RFMR_DATNB, 0) | 467 | | SSC_BF(RFMR_DATNB, (channels - 1)) |
482 | | SSC_BIT(RFMR_MSBF) | 468 | | SSC_BIT(RFMR_MSBF) |
483 | | SSC_BF(RFMR_LOOP, 0) | 469 | | SSC_BF(RFMR_LOOP, 0) |
484 | | SSC_BF(RFMR_DATLEN, (bits - 1)); | 470 | | SSC_BF(RFMR_DATLEN, (bits - 1)); |
485 | 471 | ||
486 | tcmr = SSC_BF(TCMR_PERIOD, 0) | 472 | tcmr = SSC_BF(TCMR_PERIOD, 0) |
487 | | SSC_BF(TCMR_STTDLY, START_DELAY) | 473 | | SSC_BF(TCMR_STTDLY, START_DELAY) |
488 | | SSC_BF(TCMR_START, start_event) | 474 | | SSC_BF(TCMR_START, SSC_START_FALLING_RF) |
489 | | SSC_BF(TCMR_CKI, SSC_CKI_FALLING) | 475 | | SSC_BF(TCMR_CKI, SSC_CKI_FALLING) |
490 | | SSC_BF(TCMR_CKO, SSC_CKO_NONE) | 476 | | SSC_BF(TCMR_CKO, SSC_CKO_NONE) |
491 | | SSC_BF(TCMR_CKS, ssc->clk_from_rk_pin ? | 477 | | SSC_BF(TCMR_CKS, ssc->clk_from_rk_pin ? |
@@ -495,7 +481,55 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream, | |||
495 | | SSC_BF(TFMR_FSDEN, 0) | 481 | | SSC_BF(TFMR_FSDEN, 0) |
496 | | SSC_BF(TFMR_FSOS, SSC_FSOS_NONE) | 482 | | SSC_BF(TFMR_FSOS, SSC_FSOS_NONE) |
497 | | SSC_BF(TFMR_FSLEN, 0) | 483 | | SSC_BF(TFMR_FSLEN, 0) |
498 | | SSC_BF(TFMR_DATNB, 0) | 484 | | SSC_BF(TFMR_DATNB, (channels - 1)) |
485 | | SSC_BIT(TFMR_MSBF) | ||
486 | | SSC_BF(TFMR_DATDEF, 0) | ||
487 | | SSC_BF(TFMR_DATLEN, (bits - 1)); | ||
488 | break; | ||
489 | |||
490 | case SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFS: | ||
491 | /* I2S format, CODEC supplies BCLK, SSC supplies LRCLK. */ | ||
492 | if (bits > 16 && !ssc->pdata->has_fslen_ext) { | ||
493 | dev_err(dai->dev, | ||
494 | "sample size %d is too large for SSC device\n", | ||
495 | bits); | ||
496 | return -EINVAL; | ||
497 | } | ||
498 | |||
499 | fslen_ext = (bits - 1) / 16; | ||
500 | fslen = (bits - 1) % 16; | ||
501 | |||
502 | rcmr = SSC_BF(RCMR_PERIOD, ssc_p->rcmr_period) | ||
503 | | SSC_BF(RCMR_STTDLY, START_DELAY) | ||
504 | | SSC_BF(RCMR_START, SSC_START_FALLING_RF) | ||
505 | | SSC_BF(RCMR_CKI, SSC_CKI_RISING) | ||
506 | | SSC_BF(RCMR_CKO, SSC_CKO_NONE) | ||
507 | | SSC_BF(RCMR_CKS, ssc->clk_from_rk_pin ? | ||
508 | SSC_CKS_PIN : SSC_CKS_CLOCK); | ||
509 | |||
510 | rfmr = SSC_BF(RFMR_FSLEN_EXT, fslen_ext) | ||
511 | | SSC_BF(RFMR_FSEDGE, SSC_FSEDGE_POSITIVE) | ||
512 | | SSC_BF(RFMR_FSOS, SSC_FSOS_NEGATIVE) | ||
513 | | SSC_BF(RFMR_FSLEN, fslen) | ||
514 | | SSC_BF(RFMR_DATNB, (channels - 1)) | ||
515 | | SSC_BIT(RFMR_MSBF) | ||
516 | | SSC_BF(RFMR_LOOP, 0) | ||
517 | | SSC_BF(RFMR_DATLEN, (bits - 1)); | ||
518 | |||
519 | tcmr = SSC_BF(TCMR_PERIOD, ssc_p->tcmr_period) | ||
520 | | SSC_BF(TCMR_STTDLY, START_DELAY) | ||
521 | | SSC_BF(TCMR_START, SSC_START_FALLING_RF) | ||
522 | | SSC_BF(TCMR_CKI, SSC_CKI_FALLING) | ||
523 | | SSC_BF(TCMR_CKO, SSC_CKO_NONE) | ||
524 | | SSC_BF(TCMR_CKS, ssc->clk_from_rk_pin ? | ||
525 | SSC_CKS_CLOCK : SSC_CKS_PIN); | ||
526 | |||
527 | tfmr = SSC_BF(TFMR_FSLEN_EXT, fslen_ext) | ||
528 | | SSC_BF(TFMR_FSEDGE, SSC_FSEDGE_NEGATIVE) | ||
529 | | SSC_BF(TFMR_FSDEN, 0) | ||
530 | | SSC_BF(TFMR_FSOS, SSC_FSOS_NEGATIVE) | ||
531 | | SSC_BF(TFMR_FSLEN, fslen) | ||
532 | | SSC_BF(TFMR_DATNB, (channels - 1)) | ||
499 | | SSC_BIT(TFMR_MSBF) | 533 | | SSC_BIT(TFMR_MSBF) |
500 | | SSC_BF(TFMR_DATDEF, 0) | 534 | | SSC_BF(TFMR_DATDEF, 0) |
501 | | SSC_BF(TFMR_DATLEN, (bits - 1)); | 535 | | SSC_BF(TFMR_DATLEN, (bits - 1)); |
@@ -512,7 +546,7 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream, | |||
512 | rcmr = SSC_BF(RCMR_PERIOD, ssc_p->rcmr_period) | 546 | rcmr = SSC_BF(RCMR_PERIOD, ssc_p->rcmr_period) |
513 | | SSC_BF(RCMR_STTDLY, 1) | 547 | | SSC_BF(RCMR_STTDLY, 1) |
514 | | SSC_BF(RCMR_START, SSC_START_RISING_RF) | 548 | | SSC_BF(RCMR_START, SSC_START_RISING_RF) |
515 | | SSC_BF(RCMR_CKI, SSC_CKI_RISING) | 549 | | SSC_BF(RCMR_CKI, SSC_CKI_FALLING) |
516 | | SSC_BF(RCMR_CKO, SSC_CKO_NONE) | 550 | | SSC_BF(RCMR_CKO, SSC_CKO_NONE) |
517 | | SSC_BF(RCMR_CKS, SSC_CKS_DIV); | 551 | | SSC_BF(RCMR_CKS, SSC_CKS_DIV); |
518 | 552 | ||
@@ -527,7 +561,7 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream, | |||
527 | tcmr = SSC_BF(TCMR_PERIOD, ssc_p->tcmr_period) | 561 | tcmr = SSC_BF(TCMR_PERIOD, ssc_p->tcmr_period) |
528 | | SSC_BF(TCMR_STTDLY, 1) | 562 | | SSC_BF(TCMR_STTDLY, 1) |
529 | | SSC_BF(TCMR_START, SSC_START_RISING_RF) | 563 | | SSC_BF(TCMR_START, SSC_START_RISING_RF) |
530 | | SSC_BF(TCMR_CKI, SSC_CKI_RISING) | 564 | | SSC_BF(TCMR_CKI, SSC_CKI_FALLING) |
531 | | SSC_BF(TCMR_CKO, SSC_CKO_CONTINUOUS) | 565 | | SSC_BF(TCMR_CKO, SSC_CKO_CONTINUOUS) |
532 | | SSC_BF(TCMR_CKS, SSC_CKS_DIV); | 566 | | SSC_BF(TCMR_CKS, SSC_CKS_DIV); |
533 | 567 | ||
@@ -545,10 +579,6 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream, | |||
545 | /* | 579 | /* |
546 | * DSP/PCM Mode A format, CODEC supplies BCLK and LRC clocks. | 580 | * DSP/PCM Mode A format, CODEC supplies BCLK and LRC clocks. |
547 | * | 581 | * |
548 | * The SSC transmit clock is obtained from the BCLK signal on | ||
549 | * on the TK line, and the SSC receive clock is | ||
550 | * generated from the transmit clock. | ||
551 | * | ||
552 | * Data is transferred on first BCLK after LRC pulse rising | 582 | * Data is transferred on first BCLK after LRC pulse rising |
553 | * edge.If stereo, the right channel data is contiguous with | 583 | * edge.If stereo, the right channel data is contiguous with |
554 | * the left channel data. | 584 | * the left channel data. |
@@ -556,7 +586,7 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream, | |||
556 | rcmr = SSC_BF(RCMR_PERIOD, 0) | 586 | rcmr = SSC_BF(RCMR_PERIOD, 0) |
557 | | SSC_BF(RCMR_STTDLY, START_DELAY) | 587 | | SSC_BF(RCMR_STTDLY, START_DELAY) |
558 | | SSC_BF(RCMR_START, SSC_START_RISING_RF) | 588 | | SSC_BF(RCMR_START, SSC_START_RISING_RF) |
559 | | SSC_BF(RCMR_CKI, SSC_CKI_RISING) | 589 | | SSC_BF(RCMR_CKI, SSC_CKI_FALLING) |
560 | | SSC_BF(RCMR_CKO, SSC_CKO_NONE) | 590 | | SSC_BF(RCMR_CKO, SSC_CKO_NONE) |
561 | | SSC_BF(RCMR_CKS, ssc->clk_from_rk_pin ? | 591 | | SSC_BF(RCMR_CKS, ssc->clk_from_rk_pin ? |
562 | SSC_CKS_PIN : SSC_CKS_CLOCK); | 592 | SSC_CKS_PIN : SSC_CKS_CLOCK); |
@@ -597,23 +627,17 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream, | |||
597 | rcmr, rfmr, tcmr, tfmr); | 627 | rcmr, rfmr, tcmr, tfmr); |
598 | 628 | ||
599 | if (!ssc_p->initialized) { | 629 | if (!ssc_p->initialized) { |
600 | 630 | if (!ssc_p->ssc->pdata->use_dma) { | |
601 | /* Enable PMC peripheral clock for this SSC */ | 631 | ssc_writel(ssc_p->ssc->regs, PDC_RPR, 0); |
602 | pr_debug("atmel_ssc_dai: Starting clock\n"); | 632 | ssc_writel(ssc_p->ssc->regs, PDC_RCR, 0); |
603 | clk_enable(ssc_p->ssc->clk); | 633 | ssc_writel(ssc_p->ssc->regs, PDC_RNPR, 0); |
604 | 634 | ssc_writel(ssc_p->ssc->regs, PDC_RNCR, 0); | |
605 | /* Reset the SSC and its PDC registers */ | 635 | |
606 | ssc_writel(ssc_p->ssc->regs, CR, SSC_BIT(CR_SWRST)); | 636 | ssc_writel(ssc_p->ssc->regs, PDC_TPR, 0); |
607 | 637 | ssc_writel(ssc_p->ssc->regs, PDC_TCR, 0); | |
608 | ssc_writel(ssc_p->ssc->regs, PDC_RPR, 0); | 638 | ssc_writel(ssc_p->ssc->regs, PDC_TNPR, 0); |
609 | ssc_writel(ssc_p->ssc->regs, PDC_RCR, 0); | 639 | ssc_writel(ssc_p->ssc->regs, PDC_TNCR, 0); |
610 | ssc_writel(ssc_p->ssc->regs, PDC_RNPR, 0); | 640 | } |
611 | ssc_writel(ssc_p->ssc->regs, PDC_RNCR, 0); | ||
612 | |||
613 | ssc_writel(ssc_p->ssc->regs, PDC_TPR, 0); | ||
614 | ssc_writel(ssc_p->ssc->regs, PDC_TCR, 0); | ||
615 | ssc_writel(ssc_p->ssc->regs, PDC_TNPR, 0); | ||
616 | ssc_writel(ssc_p->ssc->regs, PDC_TNCR, 0); | ||
617 | 641 | ||
618 | ret = request_irq(ssc_p->ssc->irq, atmel_ssc_interrupt, 0, | 642 | ret = request_irq(ssc_p->ssc->irq, atmel_ssc_interrupt, 0, |
619 | ssc_p->name, ssc_p); | 643 | ssc_p->name, ssc_p); |
diff --git a/sound/soc/atmel/sam9g20_wm8731.c b/sound/soc/atmel/sam9g20_wm8731.c index 66b66d0e7514..f5ad214663f9 100644 --- a/sound/soc/atmel/sam9g20_wm8731.c +++ b/sound/soc/atmel/sam9g20_wm8731.c | |||
@@ -47,7 +47,6 @@ | |||
47 | #include <sound/soc.h> | 47 | #include <sound/soc.h> |
48 | 48 | ||
49 | #include <asm/mach-types.h> | 49 | #include <asm/mach-types.h> |
50 | #include <mach/hardware.h> | ||
51 | 50 | ||
52 | #include "../codecs/wm8731.h" | 51 | #include "../codecs/wm8731.h" |
53 | #include "atmel-pcm.h" | 52 | #include "atmel-pcm.h" |
@@ -64,33 +63,6 @@ | |||
64 | 63 | ||
65 | static struct clk *mclk; | 64 | static struct clk *mclk; |
66 | 65 | ||
67 | static int at91sam9g20ek_hw_params(struct snd_pcm_substream *substream, | ||
68 | struct snd_pcm_hw_params *params) | ||
69 | { | ||
70 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
71 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | ||
72 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | ||
73 | int ret; | ||
74 | |||
75 | /* set codec DAI configuration */ | ||
76 | ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | | ||
77 | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM); | ||
78 | if (ret < 0) | ||
79 | return ret; | ||
80 | |||
81 | /* set cpu DAI configuration */ | ||
82 | ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | | ||
83 | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM); | ||
84 | if (ret < 0) | ||
85 | return ret; | ||
86 | |||
87 | return 0; | ||
88 | } | ||
89 | |||
90 | static struct snd_soc_ops at91sam9g20ek_ops = { | ||
91 | .hw_params = at91sam9g20ek_hw_params, | ||
92 | }; | ||
93 | |||
94 | static int at91sam9g20ek_set_bias_level(struct snd_soc_card *card, | 66 | static int at91sam9g20ek_set_bias_level(struct snd_soc_card *card, |
95 | struct snd_soc_dapm_context *dapm, | 67 | struct snd_soc_dapm_context *dapm, |
96 | enum snd_soc_bias_level level) | 68 | enum snd_soc_bias_level level) |
@@ -173,7 +145,8 @@ static struct snd_soc_dai_link at91sam9g20ek_dai = { | |||
173 | .init = at91sam9g20ek_wm8731_init, | 145 | .init = at91sam9g20ek_wm8731_init, |
174 | .platform_name = "at91rm9200_ssc.0", | 146 | .platform_name = "at91rm9200_ssc.0", |
175 | .codec_name = "wm8731.0-001b", | 147 | .codec_name = "wm8731.0-001b", |
176 | .ops = &at91sam9g20ek_ops, | 148 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | |
149 | SND_SOC_DAIFMT_CBM_CFM, | ||
177 | }; | 150 | }; |
178 | 151 | ||
179 | static struct snd_soc_card snd_soc_at91sam9g20ek = { | 152 | static struct snd_soc_card snd_soc_at91sam9g20ek = { |
diff --git a/sound/soc/au1x/db1200.c b/sound/soc/au1x/db1200.c index a747ac0b399f..c75995f2779c 100644 --- a/sound/soc/au1x/db1200.c +++ b/sound/soc/au1x/db1200.c | |||
@@ -91,27 +91,12 @@ static int db1200_i2s_startup(struct snd_pcm_substream *substream) | |||
91 | { | 91 | { |
92 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 92 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
93 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | 93 | struct snd_soc_dai *codec_dai = rtd->codec_dai; |
94 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | ||
95 | int ret; | ||
96 | 94 | ||
97 | /* WM8731 has its own 12MHz crystal */ | 95 | /* WM8731 has its own 12MHz crystal */ |
98 | snd_soc_dai_set_sysclk(codec_dai, WM8731_SYSCLK_XTAL, | 96 | snd_soc_dai_set_sysclk(codec_dai, WM8731_SYSCLK_XTAL, |
99 | 12000000, SND_SOC_CLOCK_IN); | 97 | 12000000, SND_SOC_CLOCK_IN); |
100 | 98 | ||
101 | /* codec is bitclock and lrclk master */ | 99 | return 0; |
102 | ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_LEFT_J | | ||
103 | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM); | ||
104 | if (ret < 0) | ||
105 | goto out; | ||
106 | |||
107 | ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_LEFT_J | | ||
108 | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM); | ||
109 | if (ret < 0) | ||
110 | goto out; | ||
111 | |||
112 | ret = 0; | ||
113 | out: | ||
114 | return ret; | ||
115 | } | 100 | } |
116 | 101 | ||
117 | static struct snd_soc_ops db1200_i2s_wm8731_ops = { | 102 | static struct snd_soc_ops db1200_i2s_wm8731_ops = { |
@@ -125,6 +110,8 @@ static struct snd_soc_dai_link db1200_i2s_dai = { | |||
125 | .cpu_dai_name = "au1xpsc_i2s.1", | 110 | .cpu_dai_name = "au1xpsc_i2s.1", |
126 | .platform_name = "au1xpsc-pcm.1", | 111 | .platform_name = "au1xpsc-pcm.1", |
127 | .codec_name = "wm8731.0-001b", | 112 | .codec_name = "wm8731.0-001b", |
113 | .dai_fmt = SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_NB_NF | | ||
114 | SND_SOC_DAIFMT_CBM_CFM, | ||
128 | .ops = &db1200_i2s_wm8731_ops, | 115 | .ops = &db1200_i2s_wm8731_ops, |
129 | }; | 116 | }; |
130 | 117 | ||
diff --git a/sound/soc/au1x/dbdma2.c b/sound/soc/au1x/dbdma2.c index b06b8d8128c6..dd94fea72d5d 100644 --- a/sound/soc/au1x/dbdma2.c +++ b/sound/soc/au1x/dbdma2.c | |||
@@ -315,11 +315,6 @@ static struct snd_pcm_ops au1xpsc_pcm_ops = { | |||
315 | .pointer = au1xpsc_pcm_pointer, | 315 | .pointer = au1xpsc_pcm_pointer, |
316 | }; | 316 | }; |
317 | 317 | ||
318 | static void au1xpsc_pcm_free_dma_buffers(struct snd_pcm *pcm) | ||
319 | { | ||
320 | snd_pcm_lib_preallocate_free_for_all(pcm); | ||
321 | } | ||
322 | |||
323 | static int au1xpsc_pcm_new(struct snd_soc_pcm_runtime *rtd) | 318 | static int au1xpsc_pcm_new(struct snd_soc_pcm_runtime *rtd) |
324 | { | 319 | { |
325 | struct snd_card *card = rtd->card->snd_card; | 320 | struct snd_card *card = rtd->card->snd_card; |
@@ -335,7 +330,6 @@ static int au1xpsc_pcm_new(struct snd_soc_pcm_runtime *rtd) | |||
335 | static struct snd_soc_platform_driver au1xpsc_soc_platform = { | 330 | static struct snd_soc_platform_driver au1xpsc_soc_platform = { |
336 | .ops = &au1xpsc_pcm_ops, | 331 | .ops = &au1xpsc_pcm_ops, |
337 | .pcm_new = au1xpsc_pcm_new, | 332 | .pcm_new = au1xpsc_pcm_new, |
338 | .pcm_free = au1xpsc_pcm_free_dma_buffers, | ||
339 | }; | 333 | }; |
340 | 334 | ||
341 | static int au1xpsc_pcm_drvprobe(struct platform_device *pdev) | 335 | static int au1xpsc_pcm_drvprobe(struct platform_device *pdev) |
diff --git a/sound/soc/au1x/dma.c b/sound/soc/au1x/dma.c index 6ffaaff469c7..24cc7f40d87a 100644 --- a/sound/soc/au1x/dma.c +++ b/sound/soc/au1x/dma.c | |||
@@ -287,11 +287,6 @@ static struct snd_pcm_ops alchemy_pcm_ops = { | |||
287 | .pointer = alchemy_pcm_pointer, | 287 | .pointer = alchemy_pcm_pointer, |
288 | }; | 288 | }; |
289 | 289 | ||
290 | static void alchemy_pcm_free_dma_buffers(struct snd_pcm *pcm) | ||
291 | { | ||
292 | snd_pcm_lib_preallocate_free_for_all(pcm); | ||
293 | } | ||
294 | |||
295 | static int alchemy_pcm_new(struct snd_soc_pcm_runtime *rtd) | 290 | static int alchemy_pcm_new(struct snd_soc_pcm_runtime *rtd) |
296 | { | 291 | { |
297 | struct snd_pcm *pcm = rtd->pcm; | 292 | struct snd_pcm *pcm = rtd->pcm; |
@@ -305,7 +300,6 @@ static int alchemy_pcm_new(struct snd_soc_pcm_runtime *rtd) | |||
305 | static struct snd_soc_platform_driver alchemy_pcm_soc_platform = { | 300 | static struct snd_soc_platform_driver alchemy_pcm_soc_platform = { |
306 | .ops = &alchemy_pcm_ops, | 301 | .ops = &alchemy_pcm_ops, |
307 | .pcm_new = alchemy_pcm_new, | 302 | .pcm_new = alchemy_pcm_new, |
308 | .pcm_free = alchemy_pcm_free_dma_buffers, | ||
309 | }; | 303 | }; |
310 | 304 | ||
311 | static int alchemy_pcm_drvprobe(struct platform_device *pdev) | 305 | static int alchemy_pcm_drvprobe(struct platform_device *pdev) |
diff --git a/sound/soc/codecs/88pm860x-codec.c b/sound/soc/codecs/88pm860x-codec.c index a2bf27f4baab..a0f265327fdf 100644 --- a/sound/soc/codecs/88pm860x-codec.c +++ b/sound/soc/codecs/88pm860x-codec.c | |||
@@ -386,7 +386,7 @@ static int snd_soc_put_volsw_2r_out(struct snd_kcontrol *kcontrol, | |||
386 | static int pm860x_rsync_event(struct snd_soc_dapm_widget *w, | 386 | static int pm860x_rsync_event(struct snd_soc_dapm_widget *w, |
387 | struct snd_kcontrol *kcontrol, int event) | 387 | struct snd_kcontrol *kcontrol, int event) |
388 | { | 388 | { |
389 | struct snd_soc_codec *codec = w->codec; | 389 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
390 | 390 | ||
391 | /* | 391 | /* |
392 | * In order to avoid current on the load, mute power-on and power-off | 392 | * In order to avoid current on the load, mute power-on and power-off |
@@ -403,7 +403,7 @@ static int pm860x_rsync_event(struct snd_soc_dapm_widget *w, | |||
403 | static int pm860x_dac_event(struct snd_soc_dapm_widget *w, | 403 | static int pm860x_dac_event(struct snd_soc_dapm_widget *w, |
404 | struct snd_kcontrol *kcontrol, int event) | 404 | struct snd_kcontrol *kcontrol, int event) |
405 | { | 405 | { |
406 | struct snd_soc_codec *codec = w->codec; | 406 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
407 | unsigned int dac = 0; | 407 | unsigned int dac = 0; |
408 | int data; | 408 | int data; |
409 | 409 | ||
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 8349f982a586..064e6c18e109 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig | |||
@@ -69,6 +69,7 @@ config SND_SOC_ALL_CODECS | |||
69 | select SND_SOC_MAX98088 if I2C | 69 | select SND_SOC_MAX98088 if I2C |
70 | select SND_SOC_MAX98090 if I2C | 70 | select SND_SOC_MAX98090 if I2C |
71 | select SND_SOC_MAX98095 if I2C | 71 | select SND_SOC_MAX98095 if I2C |
72 | select SND_SOC_MAX98357A | ||
72 | select SND_SOC_MAX9850 if I2C | 73 | select SND_SOC_MAX9850 if I2C |
73 | select SND_SOC_MAX9768 if I2C | 74 | select SND_SOC_MAX9768 if I2C |
74 | select SND_SOC_MAX9877 if I2C | 75 | select SND_SOC_MAX9877 if I2C |
@@ -456,6 +457,9 @@ config SND_SOC_MAX98090 | |||
456 | config SND_SOC_MAX98095 | 457 | config SND_SOC_MAX98095 |
457 | tristate | 458 | tristate |
458 | 459 | ||
460 | config SND_SOC_MAX98357A | ||
461 | tristate | ||
462 | |||
459 | config SND_SOC_MAX9850 | 463 | config SND_SOC_MAX9850 |
460 | tristate | 464 | tristate |
461 | 465 | ||
@@ -525,7 +529,7 @@ config SND_SOC_RT5677 | |||
525 | 529 | ||
526 | config SND_SOC_RT5677_SPI | 530 | config SND_SOC_RT5677_SPI |
527 | tristate | 531 | tristate |
528 | default SND_SOC_RT5677 | 532 | default SND_SOC_RT5677 && SPI |
529 | 533 | ||
530 | #Freescale sgtl5000 codec | 534 | #Freescale sgtl5000 codec |
531 | config SND_SOC_SGTL5000 | 535 | config SND_SOC_SGTL5000 |
@@ -580,7 +584,9 @@ config SND_SOC_SSM4567 | |||
580 | depends on I2C | 584 | depends on I2C |
581 | 585 | ||
582 | config SND_SOC_STA32X | 586 | config SND_SOC_STA32X |
583 | tristate | 587 | tristate "STA326, STA328 and STA329 speaker amplifier" |
588 | depends on I2C | ||
589 | select REGMAP_I2C | ||
584 | 590 | ||
585 | config SND_SOC_STA350 | 591 | config SND_SOC_STA350 |
586 | tristate "STA350 speaker amplifier" | 592 | tristate "STA350 speaker amplifier" |
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index bbdfd1e1c182..69b8666d187a 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile | |||
@@ -64,6 +64,7 @@ snd-soc-max9768-objs := max9768.o | |||
64 | snd-soc-max98088-objs := max98088.o | 64 | snd-soc-max98088-objs := max98088.o |
65 | snd-soc-max98090-objs := max98090.o | 65 | snd-soc-max98090-objs := max98090.o |
66 | snd-soc-max98095-objs := max98095.o | 66 | snd-soc-max98095-objs := max98095.o |
67 | snd-soc-max98357a-objs := max98357a.o | ||
67 | snd-soc-max9850-objs := max9850.o | 68 | snd-soc-max9850-objs := max9850.o |
68 | snd-soc-mc13783-objs := mc13783.o | 69 | snd-soc-mc13783-objs := mc13783.o |
69 | snd-soc-ml26124-objs := ml26124.o | 70 | snd-soc-ml26124-objs := ml26124.o |
@@ -245,6 +246,7 @@ obj-$(CONFIG_SND_SOC_MAX9768) += snd-soc-max9768.o | |||
245 | obj-$(CONFIG_SND_SOC_MAX98088) += snd-soc-max98088.o | 246 | obj-$(CONFIG_SND_SOC_MAX98088) += snd-soc-max98088.o |
246 | obj-$(CONFIG_SND_SOC_MAX98090) += snd-soc-max98090.o | 247 | obj-$(CONFIG_SND_SOC_MAX98090) += snd-soc-max98090.o |
247 | obj-$(CONFIG_SND_SOC_MAX98095) += snd-soc-max98095.o | 248 | obj-$(CONFIG_SND_SOC_MAX98095) += snd-soc-max98095.o |
249 | obj-$(CONFIG_SND_SOC_MAX98357A) += snd-soc-max98357a.o | ||
248 | obj-$(CONFIG_SND_SOC_MAX9850) += snd-soc-max9850.o | 250 | obj-$(CONFIG_SND_SOC_MAX9850) += snd-soc-max9850.o |
249 | obj-$(CONFIG_SND_SOC_MC13783) += snd-soc-mc13783.o | 251 | obj-$(CONFIG_SND_SOC_MC13783) += snd-soc-mc13783.o |
250 | obj-$(CONFIG_SND_SOC_ML26124) += snd-soc-ml26124.o | 252 | obj-$(CONFIG_SND_SOC_ML26124) += snd-soc-ml26124.o |
diff --git a/sound/soc/codecs/ad193x.c b/sound/soc/codecs/ad193x.c index 387530b0b0fd..17c953595660 100644 --- a/sound/soc/codecs/ad193x.c +++ b/sound/soc/codecs/ad193x.c | |||
@@ -333,8 +333,8 @@ static int ad193x_codec_probe(struct snd_soc_codec *codec) | |||
333 | regmap_write(ad193x->regmap, AD193X_DAC_CHNL_MUTE, 0x0); | 333 | regmap_write(ad193x->regmap, AD193X_DAC_CHNL_MUTE, 0x0); |
334 | /* de-emphasis: 48kHz, powedown dac */ | 334 | /* de-emphasis: 48kHz, powedown dac */ |
335 | regmap_write(ad193x->regmap, AD193X_DAC_CTRL2, 0x1A); | 335 | regmap_write(ad193x->regmap, AD193X_DAC_CTRL2, 0x1A); |
336 | /* powerdown dac, dac in tdm mode */ | 336 | /* dac in tdm mode */ |
337 | regmap_write(ad193x->regmap, AD193X_DAC_CTRL0, 0x41); | 337 | regmap_write(ad193x->regmap, AD193X_DAC_CTRL0, 0x40); |
338 | /* high-pass filter enable */ | 338 | /* high-pass filter enable */ |
339 | regmap_write(ad193x->regmap, AD193X_ADC_CTRL0, 0x3); | 339 | regmap_write(ad193x->regmap, AD193X_ADC_CTRL0, 0x3); |
340 | /* sata delay=1, adc aux mode */ | 340 | /* sata delay=1, adc aux mode */ |
diff --git a/sound/soc/codecs/ak4671.c b/sound/soc/codecs/ak4671.c index 686cacb0e835..632e89f793a7 100644 --- a/sound/soc/codecs/ak4671.c +++ b/sound/soc/codecs/ak4671.c | |||
@@ -163,7 +163,7 @@ static const struct snd_kcontrol_new ak4671_snd_controls[] = { | |||
163 | static int ak4671_out2_event(struct snd_soc_dapm_widget *w, | 163 | static int ak4671_out2_event(struct snd_soc_dapm_widget *w, |
164 | struct snd_kcontrol *kcontrol, int event) | 164 | struct snd_kcontrol *kcontrol, int event) |
165 | { | 165 | { |
166 | struct snd_soc_codec *codec = w->codec; | 166 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
167 | 167 | ||
168 | switch (event) { | 168 | switch (event) { |
169 | case SND_SOC_DAPM_POST_PMU: | 169 | case SND_SOC_DAPM_POST_PMU: |
diff --git a/sound/soc/codecs/alc5623.c b/sound/soc/codecs/alc5623.c index bdf8c5ac8ca4..0e357996864b 100644 --- a/sound/soc/codecs/alc5623.c +++ b/sound/soc/codecs/alc5623.c | |||
@@ -55,18 +55,20 @@ static inline int alc5623_reset(struct snd_soc_codec *codec) | |||
55 | static int amp_mixer_event(struct snd_soc_dapm_widget *w, | 55 | static int amp_mixer_event(struct snd_soc_dapm_widget *w, |
56 | struct snd_kcontrol *kcontrol, int event) | 56 | struct snd_kcontrol *kcontrol, int event) |
57 | { | 57 | { |
58 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); | ||
59 | |||
58 | /* to power-on/off class-d amp generators/speaker */ | 60 | /* to power-on/off class-d amp generators/speaker */ |
59 | /* need to write to 'index-46h' register : */ | 61 | /* need to write to 'index-46h' register : */ |
60 | /* so write index num (here 0x46) to reg 0x6a */ | 62 | /* so write index num (here 0x46) to reg 0x6a */ |
61 | /* and then 0xffff/0 to reg 0x6c */ | 63 | /* and then 0xffff/0 to reg 0x6c */ |
62 | snd_soc_write(w->codec, ALC5623_HID_CTRL_INDEX, 0x46); | 64 | snd_soc_write(codec, ALC5623_HID_CTRL_INDEX, 0x46); |
63 | 65 | ||
64 | switch (event) { | 66 | switch (event) { |
65 | case SND_SOC_DAPM_PRE_PMU: | 67 | case SND_SOC_DAPM_PRE_PMU: |
66 | snd_soc_write(w->codec, ALC5623_HID_CTRL_DATA, 0xFFFF); | 68 | snd_soc_write(codec, ALC5623_HID_CTRL_DATA, 0xFFFF); |
67 | break; | 69 | break; |
68 | case SND_SOC_DAPM_POST_PMD: | 70 | case SND_SOC_DAPM_POST_PMD: |
69 | snd_soc_write(w->codec, ALC5623_HID_CTRL_DATA, 0); | 71 | snd_soc_write(codec, ALC5623_HID_CTRL_DATA, 0); |
70 | break; | 72 | break; |
71 | } | 73 | } |
72 | 74 | ||
diff --git a/sound/soc/codecs/alc5632.c b/sound/soc/codecs/alc5632.c index d1fdbc266631..db3283abbe18 100644 --- a/sound/soc/codecs/alc5632.c +++ b/sound/soc/codecs/alc5632.c | |||
@@ -116,18 +116,20 @@ static inline int alc5632_reset(struct regmap *map) | |||
116 | static int amp_mixer_event(struct snd_soc_dapm_widget *w, | 116 | static int amp_mixer_event(struct snd_soc_dapm_widget *w, |
117 | struct snd_kcontrol *kcontrol, int event) | 117 | struct snd_kcontrol *kcontrol, int event) |
118 | { | 118 | { |
119 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); | ||
120 | |||
119 | /* to power-on/off class-d amp generators/speaker */ | 121 | /* to power-on/off class-d amp generators/speaker */ |
120 | /* need to write to 'index-46h' register : */ | 122 | /* need to write to 'index-46h' register : */ |
121 | /* so write index num (here 0x46) to reg 0x6a */ | 123 | /* so write index num (here 0x46) to reg 0x6a */ |
122 | /* and then 0xffff/0 to reg 0x6c */ | 124 | /* and then 0xffff/0 to reg 0x6c */ |
123 | snd_soc_write(w->codec, ALC5632_HID_CTRL_INDEX, 0x46); | 125 | snd_soc_write(codec, ALC5632_HID_CTRL_INDEX, 0x46); |
124 | 126 | ||
125 | switch (event) { | 127 | switch (event) { |
126 | case SND_SOC_DAPM_PRE_PMU: | 128 | case SND_SOC_DAPM_PRE_PMU: |
127 | snd_soc_write(w->codec, ALC5632_HID_CTRL_DATA, 0xFFFF); | 129 | snd_soc_write(codec, ALC5632_HID_CTRL_DATA, 0xFFFF); |
128 | break; | 130 | break; |
129 | case SND_SOC_DAPM_POST_PMD: | 131 | case SND_SOC_DAPM_POST_PMD: |
130 | snd_soc_write(w->codec, ALC5632_HID_CTRL_DATA, 0); | 132 | snd_soc_write(codec, ALC5632_HID_CTRL_DATA, 0); |
131 | break; | 133 | break; |
132 | } | 134 | } |
133 | 135 | ||
@@ -1066,7 +1068,7 @@ static int alc5632_probe(struct snd_soc_codec *codec) | |||
1066 | return 0; | 1068 | return 0; |
1067 | } | 1069 | } |
1068 | 1070 | ||
1069 | static struct snd_soc_codec_driver soc_codec_device_alc5632 = { | 1071 | static const struct snd_soc_codec_driver soc_codec_device_alc5632 = { |
1070 | .probe = alc5632_probe, | 1072 | .probe = alc5632_probe, |
1071 | .resume = alc5632_resume, | 1073 | .resume = alc5632_resume, |
1072 | .set_bias_level = alc5632_set_bias_level, | 1074 | .set_bias_level = alc5632_set_bias_level, |
@@ -1080,7 +1082,7 @@ static struct snd_soc_codec_driver soc_codec_device_alc5632 = { | |||
1080 | .num_dapm_routes = ARRAY_SIZE(alc5632_dapm_routes), | 1082 | .num_dapm_routes = ARRAY_SIZE(alc5632_dapm_routes), |
1081 | }; | 1083 | }; |
1082 | 1084 | ||
1083 | static struct regmap_config alc5632_regmap = { | 1085 | static const struct regmap_config alc5632_regmap = { |
1084 | .reg_bits = 8, | 1086 | .reg_bits = 8, |
1085 | .val_bits = 16, | 1087 | .val_bits = 16, |
1086 | 1088 | ||
diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c index 9550d7433ad0..29202610dd0d 100644 --- a/sound/soc/codecs/arizona.c +++ b/sound/soc/codecs/arizona.c | |||
@@ -84,7 +84,7 @@ static int arizona_spk_ev(struct snd_soc_dapm_widget *w, | |||
84 | struct snd_kcontrol *kcontrol, | 84 | struct snd_kcontrol *kcontrol, |
85 | int event) | 85 | int event) |
86 | { | 86 | { |
87 | struct snd_soc_codec *codec = w->codec; | 87 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
88 | struct arizona *arizona = dev_get_drvdata(codec->dev->parent); | 88 | struct arizona *arizona = dev_get_drvdata(codec->dev->parent); |
89 | struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec); | 89 | struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec); |
90 | bool manual_ena = false; | 90 | bool manual_ena = false; |
@@ -692,7 +692,8 @@ static void arizona_in_set_vu(struct snd_soc_codec *codec, int ena) | |||
692 | int arizona_in_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, | 692 | int arizona_in_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, |
693 | int event) | 693 | int event) |
694 | { | 694 | { |
695 | struct arizona_priv *priv = snd_soc_codec_get_drvdata(w->codec); | 695 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
696 | struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec); | ||
696 | unsigned int reg; | 697 | unsigned int reg; |
697 | 698 | ||
698 | if (w->shift % 2) | 699 | if (w->shift % 2) |
@@ -705,25 +706,25 @@ int arizona_in_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, | |||
705 | priv->in_pending++; | 706 | priv->in_pending++; |
706 | break; | 707 | break; |
707 | case SND_SOC_DAPM_POST_PMU: | 708 | case SND_SOC_DAPM_POST_PMU: |
708 | snd_soc_update_bits(w->codec, reg, ARIZONA_IN1L_MUTE, 0); | 709 | snd_soc_update_bits(codec, reg, ARIZONA_IN1L_MUTE, 0); |
709 | 710 | ||
710 | /* If this is the last input pending then allow VU */ | 711 | /* If this is the last input pending then allow VU */ |
711 | priv->in_pending--; | 712 | priv->in_pending--; |
712 | if (priv->in_pending == 0) { | 713 | if (priv->in_pending == 0) { |
713 | msleep(1); | 714 | msleep(1); |
714 | arizona_in_set_vu(w->codec, 1); | 715 | arizona_in_set_vu(codec, 1); |
715 | } | 716 | } |
716 | break; | 717 | break; |
717 | case SND_SOC_DAPM_PRE_PMD: | 718 | case SND_SOC_DAPM_PRE_PMD: |
718 | snd_soc_update_bits(w->codec, reg, | 719 | snd_soc_update_bits(codec, reg, |
719 | ARIZONA_IN1L_MUTE | ARIZONA_IN_VU, | 720 | ARIZONA_IN1L_MUTE | ARIZONA_IN_VU, |
720 | ARIZONA_IN1L_MUTE | ARIZONA_IN_VU); | 721 | ARIZONA_IN1L_MUTE | ARIZONA_IN_VU); |
721 | break; | 722 | break; |
722 | case SND_SOC_DAPM_POST_PMD: | 723 | case SND_SOC_DAPM_POST_PMD: |
723 | /* Disable volume updates if no inputs are enabled */ | 724 | /* Disable volume updates if no inputs are enabled */ |
724 | reg = snd_soc_read(w->codec, ARIZONA_INPUT_ENABLES); | 725 | reg = snd_soc_read(codec, ARIZONA_INPUT_ENABLES); |
725 | if (reg == 0) | 726 | if (reg == 0) |
726 | arizona_in_set_vu(w->codec, 0); | 727 | arizona_in_set_vu(codec, 0); |
727 | } | 728 | } |
728 | 729 | ||
729 | return 0; | 730 | return 0; |
@@ -734,7 +735,25 @@ int arizona_out_ev(struct snd_soc_dapm_widget *w, | |||
734 | struct snd_kcontrol *kcontrol, | 735 | struct snd_kcontrol *kcontrol, |
735 | int event) | 736 | int event) |
736 | { | 737 | { |
738 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); | ||
739 | struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec); | ||
740 | |||
737 | switch (event) { | 741 | switch (event) { |
742 | case SND_SOC_DAPM_PRE_PMU: | ||
743 | switch (w->shift) { | ||
744 | case ARIZONA_OUT1L_ENA_SHIFT: | ||
745 | case ARIZONA_OUT1R_ENA_SHIFT: | ||
746 | case ARIZONA_OUT2L_ENA_SHIFT: | ||
747 | case ARIZONA_OUT2R_ENA_SHIFT: | ||
748 | case ARIZONA_OUT3L_ENA_SHIFT: | ||
749 | case ARIZONA_OUT3R_ENA_SHIFT: | ||
750 | priv->out_up_pending++; | ||
751 | priv->out_up_delay += 17; | ||
752 | break; | ||
753 | default: | ||
754 | break; | ||
755 | } | ||
756 | break; | ||
738 | case SND_SOC_DAPM_POST_PMU: | 757 | case SND_SOC_DAPM_POST_PMU: |
739 | switch (w->shift) { | 758 | switch (w->shift) { |
740 | case ARIZONA_OUT1L_ENA_SHIFT: | 759 | case ARIZONA_OUT1L_ENA_SHIFT: |
@@ -743,13 +762,50 @@ int arizona_out_ev(struct snd_soc_dapm_widget *w, | |||
743 | case ARIZONA_OUT2R_ENA_SHIFT: | 762 | case ARIZONA_OUT2R_ENA_SHIFT: |
744 | case ARIZONA_OUT3L_ENA_SHIFT: | 763 | case ARIZONA_OUT3L_ENA_SHIFT: |
745 | case ARIZONA_OUT3R_ENA_SHIFT: | 764 | case ARIZONA_OUT3R_ENA_SHIFT: |
746 | msleep(17); | 765 | priv->out_up_pending--; |
766 | if (!priv->out_up_pending) { | ||
767 | msleep(priv->out_up_delay); | ||
768 | priv->out_up_delay = 0; | ||
769 | } | ||
747 | break; | 770 | break; |
748 | 771 | ||
749 | default: | 772 | default: |
750 | break; | 773 | break; |
751 | } | 774 | } |
752 | break; | 775 | break; |
776 | case SND_SOC_DAPM_PRE_PMD: | ||
777 | switch (w->shift) { | ||
778 | case ARIZONA_OUT1L_ENA_SHIFT: | ||
779 | case ARIZONA_OUT1R_ENA_SHIFT: | ||
780 | case ARIZONA_OUT2L_ENA_SHIFT: | ||
781 | case ARIZONA_OUT2R_ENA_SHIFT: | ||
782 | case ARIZONA_OUT3L_ENA_SHIFT: | ||
783 | case ARIZONA_OUT3R_ENA_SHIFT: | ||
784 | priv->out_down_pending++; | ||
785 | priv->out_down_delay++; | ||
786 | break; | ||
787 | default: | ||
788 | break; | ||
789 | } | ||
790 | break; | ||
791 | case SND_SOC_DAPM_POST_PMD: | ||
792 | switch (w->shift) { | ||
793 | case ARIZONA_OUT1L_ENA_SHIFT: | ||
794 | case ARIZONA_OUT1R_ENA_SHIFT: | ||
795 | case ARIZONA_OUT2L_ENA_SHIFT: | ||
796 | case ARIZONA_OUT2R_ENA_SHIFT: | ||
797 | case ARIZONA_OUT3L_ENA_SHIFT: | ||
798 | case ARIZONA_OUT3R_ENA_SHIFT: | ||
799 | priv->out_down_pending--; | ||
800 | if (!priv->out_down_pending) { | ||
801 | msleep(priv->out_down_delay); | ||
802 | priv->out_down_delay = 0; | ||
803 | } | ||
804 | break; | ||
805 | default: | ||
806 | break; | ||
807 | } | ||
808 | break; | ||
753 | } | 809 | } |
754 | 810 | ||
755 | return 0; | 811 | return 0; |
@@ -760,7 +816,8 @@ int arizona_hp_ev(struct snd_soc_dapm_widget *w, | |||
760 | struct snd_kcontrol *kcontrol, | 816 | struct snd_kcontrol *kcontrol, |
761 | int event) | 817 | int event) |
762 | { | 818 | { |
763 | struct arizona_priv *priv = snd_soc_codec_get_drvdata(w->codec); | 819 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
820 | struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec); | ||
764 | struct arizona *arizona = priv->arizona; | 821 | struct arizona *arizona = priv->arizona; |
765 | unsigned int mask = 1 << w->shift; | 822 | unsigned int mask = 1 << w->shift; |
766 | unsigned int val; | 823 | unsigned int val; |
@@ -772,6 +829,9 @@ int arizona_hp_ev(struct snd_soc_dapm_widget *w, | |||
772 | case SND_SOC_DAPM_PRE_PMD: | 829 | case SND_SOC_DAPM_PRE_PMD: |
773 | val = 0; | 830 | val = 0; |
774 | break; | 831 | break; |
832 | case SND_SOC_DAPM_PRE_PMU: | ||
833 | case SND_SOC_DAPM_POST_PMD: | ||
834 | return arizona_out_ev(w, kcontrol, event); | ||
775 | default: | 835 | default: |
776 | return -EINVAL; | 836 | return -EINVAL; |
777 | } | 837 | } |
diff --git a/sound/soc/codecs/arizona.h b/sound/soc/codecs/arizona.h index 942cfb197b6d..11ff899b0272 100644 --- a/sound/soc/codecs/arizona.h +++ b/sound/soc/codecs/arizona.h | |||
@@ -77,6 +77,11 @@ struct arizona_priv { | |||
77 | int num_inputs; | 77 | int num_inputs; |
78 | unsigned int in_pending; | 78 | unsigned int in_pending; |
79 | 79 | ||
80 | unsigned int out_up_pending; | ||
81 | unsigned int out_up_delay; | ||
82 | unsigned int out_down_pending; | ||
83 | unsigned int out_down_delay; | ||
84 | |||
80 | unsigned int spk_ena:2; | 85 | unsigned int spk_ena:2; |
81 | unsigned int spk_ena_pending:1; | 86 | unsigned int spk_ena_pending:1; |
82 | }; | 87 | }; |
diff --git a/sound/soc/codecs/bt-sco.c b/sound/soc/codecs/bt-sco.c index 5075bf0a7276..e7238b8904bc 100644 --- a/sound/soc/codecs/bt-sco.c +++ b/sound/soc/codecs/bt-sco.c | |||
@@ -86,5 +86,5 @@ static struct platform_driver bt_sco_driver = { | |||
86 | module_platform_driver(bt_sco_driver); | 86 | module_platform_driver(bt_sco_driver); |
87 | 87 | ||
88 | MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); | 88 | MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); |
89 | MODULE_DESCRIPTION("ASoC generic bluethooth sco link driver"); | 89 | MODULE_DESCRIPTION("ASoC generic bluetooth sco link driver"); |
90 | MODULE_LICENSE("GPL"); | 90 | MODULE_LICENSE("GPL"); |
diff --git a/sound/soc/codecs/cs35l32.c b/sound/soc/codecs/cs35l32.c index ec55c590afd0..f2b8aad21274 100644 --- a/sound/soc/codecs/cs35l32.c +++ b/sound/soc/codecs/cs35l32.c | |||
@@ -264,7 +264,7 @@ static int cs35l32_codec_set_sysclk(struct snd_soc_codec *codec, | |||
264 | CS35L32_MCLK_DIV2_MASK | CS35L32_MCLK_RATIO_MASK, val); | 264 | CS35L32_MCLK_DIV2_MASK | CS35L32_MCLK_RATIO_MASK, val); |
265 | } | 265 | } |
266 | 266 | ||
267 | static struct snd_soc_codec_driver soc_codec_dev_cs35l32 = { | 267 | static const struct snd_soc_codec_driver soc_codec_dev_cs35l32 = { |
268 | .set_sysclk = cs35l32_codec_set_sysclk, | 268 | .set_sysclk = cs35l32_codec_set_sysclk, |
269 | 269 | ||
270 | .dapm_widgets = cs35l32_dapm_widgets, | 270 | .dapm_widgets = cs35l32_dapm_widgets, |
@@ -288,7 +288,7 @@ static const struct reg_default cs35l32_monitor_patch[] = { | |||
288 | { 0x00, 0x00 }, | 288 | { 0x00, 0x00 }, |
289 | }; | 289 | }; |
290 | 290 | ||
291 | static struct regmap_config cs35l32_regmap = { | 291 | static const struct regmap_config cs35l32_regmap = { |
292 | .reg_bits = 8, | 292 | .reg_bits = 8, |
293 | .val_bits = 8, | 293 | .val_bits = 8, |
294 | 294 | ||
diff --git a/sound/soc/codecs/cs42l52.c b/sound/soc/codecs/cs42l52.c index 35fbef743fbe..1589e7a881d8 100644 --- a/sound/soc/codecs/cs42l52.c +++ b/sound/soc/codecs/cs42l52.c | |||
@@ -1103,7 +1103,7 @@ static int cs42l52_remove(struct snd_soc_codec *codec) | |||
1103 | return 0; | 1103 | return 0; |
1104 | } | 1104 | } |
1105 | 1105 | ||
1106 | static struct snd_soc_codec_driver soc_codec_dev_cs42l52 = { | 1106 | static const struct snd_soc_codec_driver soc_codec_dev_cs42l52 = { |
1107 | .probe = cs42l52_probe, | 1107 | .probe = cs42l52_probe, |
1108 | .remove = cs42l52_remove, | 1108 | .remove = cs42l52_remove, |
1109 | .set_bias_level = cs42l52_set_bias_level, | 1109 | .set_bias_level = cs42l52_set_bias_level, |
@@ -1130,7 +1130,7 @@ static const struct reg_default cs42l52_threshold_patch[] = { | |||
1130 | 1130 | ||
1131 | }; | 1131 | }; |
1132 | 1132 | ||
1133 | static struct regmap_config cs42l52_regmap = { | 1133 | static const struct regmap_config cs42l52_regmap = { |
1134 | .reg_bits = 8, | 1134 | .reg_bits = 8, |
1135 | .val_bits = 8, | 1135 | .val_bits = 8, |
1136 | 1136 | ||
diff --git a/sound/soc/codecs/cs42l56.c b/sound/soc/codecs/cs42l56.c index 2ddc7ac10ad7..cbc654fe48c7 100644 --- a/sound/soc/codecs/cs42l56.c +++ b/sound/soc/codecs/cs42l56.c | |||
@@ -1164,7 +1164,7 @@ static int cs42l56_remove(struct snd_soc_codec *codec) | |||
1164 | return 0; | 1164 | return 0; |
1165 | } | 1165 | } |
1166 | 1166 | ||
1167 | static struct snd_soc_codec_driver soc_codec_dev_cs42l56 = { | 1167 | static const struct snd_soc_codec_driver soc_codec_dev_cs42l56 = { |
1168 | .probe = cs42l56_probe, | 1168 | .probe = cs42l56_probe, |
1169 | .remove = cs42l56_remove, | 1169 | .remove = cs42l56_remove, |
1170 | .set_bias_level = cs42l56_set_bias_level, | 1170 | .set_bias_level = cs42l56_set_bias_level, |
@@ -1179,7 +1179,7 @@ static struct snd_soc_codec_driver soc_codec_dev_cs42l56 = { | |||
1179 | .num_controls = ARRAY_SIZE(cs42l56_snd_controls), | 1179 | .num_controls = ARRAY_SIZE(cs42l56_snd_controls), |
1180 | }; | 1180 | }; |
1181 | 1181 | ||
1182 | static struct regmap_config cs42l56_regmap = { | 1182 | static const struct regmap_config cs42l56_regmap = { |
1183 | .reg_bits = 8, | 1183 | .reg_bits = 8, |
1184 | .val_bits = 8, | 1184 | .val_bits = 8, |
1185 | 1185 | ||
diff --git a/sound/soc/codecs/cs42l73.c b/sound/soc/codecs/cs42l73.c index 7c55537c69cf..8ecedba79606 100644 --- a/sound/soc/codecs/cs42l73.c +++ b/sound/soc/codecs/cs42l73.c | |||
@@ -1347,7 +1347,7 @@ static int cs42l73_probe(struct snd_soc_codec *codec) | |||
1347 | return 0; | 1347 | return 0; |
1348 | } | 1348 | } |
1349 | 1349 | ||
1350 | static struct snd_soc_codec_driver soc_codec_dev_cs42l73 = { | 1350 | static const struct snd_soc_codec_driver soc_codec_dev_cs42l73 = { |
1351 | .probe = cs42l73_probe, | 1351 | .probe = cs42l73_probe, |
1352 | .set_bias_level = cs42l73_set_bias_level, | 1352 | .set_bias_level = cs42l73_set_bias_level, |
1353 | .suspend_bias_off = true, | 1353 | .suspend_bias_off = true, |
@@ -1361,7 +1361,7 @@ static struct snd_soc_codec_driver soc_codec_dev_cs42l73 = { | |||
1361 | .num_controls = ARRAY_SIZE(cs42l73_snd_controls), | 1361 | .num_controls = ARRAY_SIZE(cs42l73_snd_controls), |
1362 | }; | 1362 | }; |
1363 | 1363 | ||
1364 | static struct regmap_config cs42l73_regmap = { | 1364 | static const struct regmap_config cs42l73_regmap = { |
1365 | .reg_bits = 8, | 1365 | .reg_bits = 8, |
1366 | .val_bits = 8, | 1366 | .val_bits = 8, |
1367 | 1367 | ||
diff --git a/sound/soc/codecs/da732x.c b/sound/soc/codecs/da732x.c index 61b2f9a2eef1..ffe96175a8a5 100644 --- a/sound/soc/codecs/da732x.c +++ b/sound/soc/codecs/da732x.c | |||
@@ -609,7 +609,7 @@ static const struct snd_kcontrol_new da732x_snd_controls[] = { | |||
609 | static int da732x_adc_event(struct snd_soc_dapm_widget *w, | 609 | static int da732x_adc_event(struct snd_soc_dapm_widget *w, |
610 | struct snd_kcontrol *kcontrol, int event) | 610 | struct snd_kcontrol *kcontrol, int event) |
611 | { | 611 | { |
612 | struct snd_soc_codec *codec = w->codec; | 612 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
613 | 613 | ||
614 | switch (event) { | 614 | switch (event) { |
615 | case SND_SOC_DAPM_POST_PMU: | 615 | case SND_SOC_DAPM_POST_PMU: |
@@ -663,7 +663,7 @@ static int da732x_adc_event(struct snd_soc_dapm_widget *w, | |||
663 | static int da732x_out_pga_event(struct snd_soc_dapm_widget *w, | 663 | static int da732x_out_pga_event(struct snd_soc_dapm_widget *w, |
664 | struct snd_kcontrol *kcontrol, int event) | 664 | struct snd_kcontrol *kcontrol, int event) |
665 | { | 665 | { |
666 | struct snd_soc_codec *codec = w->codec; | 666 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
667 | 667 | ||
668 | switch (event) { | 668 | switch (event) { |
669 | case SND_SOC_DAPM_POST_PMU: | 669 | case SND_SOC_DAPM_POST_PMU: |
diff --git a/sound/soc/codecs/max98357a.c b/sound/soc/codecs/max98357a.c new file mode 100644 index 000000000000..1806333ea29e --- /dev/null +++ b/sound/soc/codecs/max98357a.c | |||
@@ -0,0 +1,138 @@ | |||
1 | /* Copyright (c) 2010-2011,2013-2015 The Linux Foundation. All rights reserved. | ||
2 | * | ||
3 | * This program is free software; you can redistribute it and/or modify | ||
4 | * it under the terms of the GNU General Public License version 2 and | ||
5 | * only version 2 as published by the Free Software Foundation. | ||
6 | * | ||
7 | * This program is distributed in the hope that it will be useful, | ||
8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
10 | * GNU General Public License for more details. | ||
11 | * | ||
12 | * max98357a.c -- MAX98357A ALSA SoC Codec driver | ||
13 | */ | ||
14 | |||
15 | #include <linux/module.h> | ||
16 | #include <linux/gpio.h> | ||
17 | #include <sound/soc.h> | ||
18 | |||
19 | #define DRV_NAME "max98357a" | ||
20 | |||
21 | static int max98357a_daiops_trigger(struct snd_pcm_substream *substream, | ||
22 | int cmd, struct snd_soc_dai *dai) | ||
23 | { | ||
24 | struct gpio_desc *sdmode = snd_soc_dai_get_drvdata(dai); | ||
25 | |||
26 | switch (cmd) { | ||
27 | case SNDRV_PCM_TRIGGER_START: | ||
28 | case SNDRV_PCM_TRIGGER_RESUME: | ||
29 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | ||
30 | gpiod_set_value(sdmode, 1); | ||
31 | break; | ||
32 | case SNDRV_PCM_TRIGGER_STOP: | ||
33 | case SNDRV_PCM_TRIGGER_SUSPEND: | ||
34 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: | ||
35 | gpiod_set_value(sdmode, 0); | ||
36 | break; | ||
37 | } | ||
38 | |||
39 | return 0; | ||
40 | } | ||
41 | |||
42 | static const struct snd_soc_dapm_widget max98357a_dapm_widgets[] = { | ||
43 | SND_SOC_DAPM_DAC("SDMode", NULL, SND_SOC_NOPM, 0, 0), | ||
44 | SND_SOC_DAPM_OUTPUT("Speaker"), | ||
45 | }; | ||
46 | |||
47 | static const struct snd_soc_dapm_route max98357a_dapm_routes[] = { | ||
48 | {"Speaker", NULL, "SDMode"}, | ||
49 | }; | ||
50 | |||
51 | static int max98357a_codec_probe(struct snd_soc_codec *codec) | ||
52 | { | ||
53 | struct gpio_desc *sdmode; | ||
54 | |||
55 | sdmode = devm_gpiod_get(codec->dev, "sdmode"); | ||
56 | if (IS_ERR(sdmode)) { | ||
57 | dev_err(codec->dev, "%s() unable to get sdmode GPIO: %ld\n", | ||
58 | __func__, PTR_ERR(sdmode)); | ||
59 | return PTR_ERR(sdmode); | ||
60 | } | ||
61 | gpiod_direction_output(sdmode, 0); | ||
62 | snd_soc_codec_set_drvdata(codec, sdmode); | ||
63 | |||
64 | return 0; | ||
65 | } | ||
66 | |||
67 | static struct snd_soc_codec_driver max98357a_codec_driver = { | ||
68 | .probe = max98357a_codec_probe, | ||
69 | .dapm_widgets = max98357a_dapm_widgets, | ||
70 | .num_dapm_widgets = ARRAY_SIZE(max98357a_dapm_widgets), | ||
71 | .dapm_routes = max98357a_dapm_routes, | ||
72 | .num_dapm_routes = ARRAY_SIZE(max98357a_dapm_routes), | ||
73 | }; | ||
74 | |||
75 | static struct snd_soc_dai_ops max98357a_dai_ops = { | ||
76 | .trigger = max98357a_daiops_trigger, | ||
77 | }; | ||
78 | |||
79 | static struct snd_soc_dai_driver max98357a_dai_driver = { | ||
80 | .name = DRV_NAME, | ||
81 | .playback = { | ||
82 | .stream_name = DRV_NAME "-playback", | ||
83 | .formats = SNDRV_PCM_FMTBIT_S16 | | ||
84 | SNDRV_PCM_FMTBIT_S24 | | ||
85 | SNDRV_PCM_FMTBIT_S32, | ||
86 | .rates = SNDRV_PCM_RATE_8000 | | ||
87 | SNDRV_PCM_RATE_16000 | | ||
88 | SNDRV_PCM_RATE_48000 | | ||
89 | SNDRV_PCM_RATE_96000, | ||
90 | .rate_min = 8000, | ||
91 | .rate_max = 96000, | ||
92 | .channels_min = 1, | ||
93 | .channels_max = 2, | ||
94 | }, | ||
95 | .ops = &max98357a_dai_ops, | ||
96 | }; | ||
97 | |||
98 | static int max98357a_platform_probe(struct platform_device *pdev) | ||
99 | { | ||
100 | int ret; | ||
101 | |||
102 | ret = snd_soc_register_codec(&pdev->dev, &max98357a_codec_driver, | ||
103 | &max98357a_dai_driver, 1); | ||
104 | if (ret) | ||
105 | dev_err(&pdev->dev, "%s() error registering codec driver: %d\n", | ||
106 | __func__, ret); | ||
107 | |||
108 | return ret; | ||
109 | } | ||
110 | |||
111 | static int max98357a_platform_remove(struct platform_device *pdev) | ||
112 | { | ||
113 | snd_soc_unregister_codec(&pdev->dev); | ||
114 | |||
115 | return 0; | ||
116 | } | ||
117 | |||
118 | #ifdef CONFIG_OF | ||
119 | static const struct of_device_id max98357a_device_id[] = { | ||
120 | { .compatible = "maxim," DRV_NAME, }, | ||
121 | {} | ||
122 | }; | ||
123 | MODULE_DEVICE_TABLE(of, max98357a_device_id); | ||
124 | #endif | ||
125 | |||
126 | static struct platform_driver max98357a_platform_driver = { | ||
127 | .driver = { | ||
128 | .name = DRV_NAME, | ||
129 | .of_match_table = of_match_ptr(max98357a_device_id), | ||
130 | }, | ||
131 | .probe = max98357a_platform_probe, | ||
132 | .remove = max98357a_platform_remove, | ||
133 | }; | ||
134 | module_platform_driver(max98357a_platform_driver); | ||
135 | |||
136 | MODULE_DESCRIPTION("Maxim MAX98357A Codec Driver"); | ||
137 | MODULE_LICENSE("GPL v2"); | ||
138 | MODULE_ALIAS("platform:" DRV_NAME); | ||
diff --git a/sound/soc/codecs/mc13783.c b/sound/soc/codecs/mc13783.c index c1e441c2c8af..2ffb9a0570dc 100644 --- a/sound/soc/codecs/mc13783.c +++ b/sound/soc/codecs/mc13783.c | |||
@@ -328,16 +328,16 @@ static int mc13783_set_tdm_slot_dac(struct snd_soc_dai *dai, | |||
328 | } | 328 | } |
329 | 329 | ||
330 | switch (rx_mask) { | 330 | switch (rx_mask) { |
331 | case 0xfffffffc: | 331 | case 0x03: |
332 | val |= SSI_NETWORK_DAC_RXSLOT_0_1; | 332 | val |= SSI_NETWORK_DAC_RXSLOT_0_1; |
333 | break; | 333 | break; |
334 | case 0xfffffff3: | 334 | case 0x0c: |
335 | val |= SSI_NETWORK_DAC_RXSLOT_2_3; | 335 | val |= SSI_NETWORK_DAC_RXSLOT_2_3; |
336 | break; | 336 | break; |
337 | case 0xffffffcf: | 337 | case 0x30: |
338 | val |= SSI_NETWORK_DAC_RXSLOT_4_5; | 338 | val |= SSI_NETWORK_DAC_RXSLOT_4_5; |
339 | break; | 339 | break; |
340 | case 0xffffff3f: | 340 | case 0xc0: |
341 | val |= SSI_NETWORK_DAC_RXSLOT_6_7; | 341 | val |= SSI_NETWORK_DAC_RXSLOT_6_7; |
342 | break; | 342 | break; |
343 | default: | 343 | default: |
@@ -360,7 +360,7 @@ static int mc13783_set_tdm_slot_codec(struct snd_soc_dai *dai, | |||
360 | if (slots != 4) | 360 | if (slots != 4) |
361 | return -EINVAL; | 361 | return -EINVAL; |
362 | 362 | ||
363 | if (tx_mask != 0xfffffffc) | 363 | if (tx_mask != 0x3) |
364 | return -EINVAL; | 364 | return -EINVAL; |
365 | 365 | ||
366 | val |= (0x00 << 2); /* primary timeslot RX/TX(?) is 0 */ | 366 | val |= (0x00 << 2); /* primary timeslot RX/TX(?) is 0 */ |
diff --git a/sound/soc/codecs/pcm3008.c b/sound/soc/codecs/pcm3008.c index 7e73fa4b3183..8fb445f33f6f 100644 --- a/sound/soc/codecs/pcm3008.c +++ b/sound/soc/codecs/pcm3008.c | |||
@@ -32,7 +32,7 @@ static int pcm3008_dac_ev(struct snd_soc_dapm_widget *w, | |||
32 | struct snd_kcontrol *kcontrol, | 32 | struct snd_kcontrol *kcontrol, |
33 | int event) | 33 | int event) |
34 | { | 34 | { |
35 | struct snd_soc_codec *codec = w->codec; | 35 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
36 | struct pcm3008_setup_data *setup = codec->dev->platform_data; | 36 | struct pcm3008_setup_data *setup = codec->dev->platform_data; |
37 | 37 | ||
38 | gpio_set_value_cansleep(setup->pdda_pin, | 38 | gpio_set_value_cansleep(setup->pdda_pin, |
@@ -45,7 +45,7 @@ static int pcm3008_adc_ev(struct snd_soc_dapm_widget *w, | |||
45 | struct snd_kcontrol *kcontrol, | 45 | struct snd_kcontrol *kcontrol, |
46 | int event) | 46 | int event) |
47 | { | 47 | { |
48 | struct snd_soc_codec *codec = w->codec; | 48 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
49 | struct pcm3008_setup_data *setup = codec->dev->platform_data; | 49 | struct pcm3008_setup_data *setup = codec->dev->platform_data; |
50 | 50 | ||
51 | gpio_set_value_cansleep(setup->pdad_pin, | 51 | gpio_set_value_cansleep(setup->pdad_pin, |
diff --git a/sound/soc/codecs/pcm512x-i2c.c b/sound/soc/codecs/pcm512x-i2c.c index d0547fa275fc..dcdfac0ffeb1 100644 --- a/sound/soc/codecs/pcm512x-i2c.c +++ b/sound/soc/codecs/pcm512x-i2c.c | |||
@@ -46,6 +46,8 @@ static int pcm512x_i2c_remove(struct i2c_client *i2c) | |||
46 | static const struct i2c_device_id pcm512x_i2c_id[] = { | 46 | static const struct i2c_device_id pcm512x_i2c_id[] = { |
47 | { "pcm5121", }, | 47 | { "pcm5121", }, |
48 | { "pcm5122", }, | 48 | { "pcm5122", }, |
49 | { "pcm5141", }, | ||
50 | { "pcm5142", }, | ||
49 | { } | 51 | { } |
50 | }; | 52 | }; |
51 | MODULE_DEVICE_TABLE(i2c, pcm512x_i2c_id); | 53 | MODULE_DEVICE_TABLE(i2c, pcm512x_i2c_id); |
@@ -53,6 +55,8 @@ MODULE_DEVICE_TABLE(i2c, pcm512x_i2c_id); | |||
53 | static const struct of_device_id pcm512x_of_match[] = { | 55 | static const struct of_device_id pcm512x_of_match[] = { |
54 | { .compatible = "ti,pcm5121", }, | 56 | { .compatible = "ti,pcm5121", }, |
55 | { .compatible = "ti,pcm5122", }, | 57 | { .compatible = "ti,pcm5122", }, |
58 | { .compatible = "ti,pcm5141", }, | ||
59 | { .compatible = "ti,pcm5142", }, | ||
56 | { } | 60 | { } |
57 | }; | 61 | }; |
58 | MODULE_DEVICE_TABLE(of, pcm512x_of_match); | 62 | MODULE_DEVICE_TABLE(of, pcm512x_of_match); |
diff --git a/sound/soc/codecs/pcm512x-spi.c b/sound/soc/codecs/pcm512x-spi.c index f297058c0038..7b64a9cef704 100644 --- a/sound/soc/codecs/pcm512x-spi.c +++ b/sound/soc/codecs/pcm512x-spi.c | |||
@@ -43,6 +43,8 @@ static int pcm512x_spi_remove(struct spi_device *spi) | |||
43 | static const struct spi_device_id pcm512x_spi_id[] = { | 43 | static const struct spi_device_id pcm512x_spi_id[] = { |
44 | { "pcm5121", }, | 44 | { "pcm5121", }, |
45 | { "pcm5122", }, | 45 | { "pcm5122", }, |
46 | { "pcm5141", }, | ||
47 | { "pcm5142", }, | ||
46 | { }, | 48 | { }, |
47 | }; | 49 | }; |
48 | MODULE_DEVICE_TABLE(spi, pcm512x_spi_id); | 50 | MODULE_DEVICE_TABLE(spi, pcm512x_spi_id); |
@@ -50,6 +52,8 @@ MODULE_DEVICE_TABLE(spi, pcm512x_spi_id); | |||
50 | static const struct of_device_id pcm512x_of_match[] = { | 52 | static const struct of_device_id pcm512x_of_match[] = { |
51 | { .compatible = "ti,pcm5121", }, | 53 | { .compatible = "ti,pcm5121", }, |
52 | { .compatible = "ti,pcm5122", }, | 54 | { .compatible = "ti,pcm5122", }, |
55 | { .compatible = "ti,pcm5141", }, | ||
56 | { .compatible = "ti,pcm5142", }, | ||
53 | { } | 57 | { } |
54 | }; | 58 | }; |
55 | MODULE_DEVICE_TABLE(of, pcm512x_of_match); | 59 | MODULE_DEVICE_TABLE(of, pcm512x_of_match); |
diff --git a/sound/soc/codecs/pcm512x.c b/sound/soc/codecs/pcm512x.c index e5f2fb884bf3..9974f201a08f 100644 --- a/sound/soc/codecs/pcm512x.c +++ b/sound/soc/codecs/pcm512x.c | |||
@@ -21,12 +21,19 @@ | |||
21 | #include <linux/pm_runtime.h> | 21 | #include <linux/pm_runtime.h> |
22 | #include <linux/regmap.h> | 22 | #include <linux/regmap.h> |
23 | #include <linux/regulator/consumer.h> | 23 | #include <linux/regulator/consumer.h> |
24 | #include <linux/gcd.h> | ||
24 | #include <sound/soc.h> | 25 | #include <sound/soc.h> |
25 | #include <sound/soc-dapm.h> | 26 | #include <sound/soc-dapm.h> |
27 | #include <sound/pcm_params.h> | ||
26 | #include <sound/tlv.h> | 28 | #include <sound/tlv.h> |
27 | 29 | ||
28 | #include "pcm512x.h" | 30 | #include "pcm512x.h" |
29 | 31 | ||
32 | #define DIV_ROUND_DOWN_ULL(ll, d) \ | ||
33 | ({ unsigned long long _tmp = (ll); do_div(_tmp, d); _tmp; }) | ||
34 | #define DIV_ROUND_CLOSEST_ULL(ll, d) \ | ||
35 | ({ unsigned long long _tmp = (ll)+(d)/2; do_div(_tmp, d); _tmp; }) | ||
36 | |||
30 | #define PCM512x_NUM_SUPPLIES 3 | 37 | #define PCM512x_NUM_SUPPLIES 3 |
31 | static const char * const pcm512x_supply_names[PCM512x_NUM_SUPPLIES] = { | 38 | static const char * const pcm512x_supply_names[PCM512x_NUM_SUPPLIES] = { |
32 | "AVDD", | 39 | "AVDD", |
@@ -39,6 +46,14 @@ struct pcm512x_priv { | |||
39 | struct clk *sclk; | 46 | struct clk *sclk; |
40 | struct regulator_bulk_data supplies[PCM512x_NUM_SUPPLIES]; | 47 | struct regulator_bulk_data supplies[PCM512x_NUM_SUPPLIES]; |
41 | struct notifier_block supply_nb[PCM512x_NUM_SUPPLIES]; | 48 | struct notifier_block supply_nb[PCM512x_NUM_SUPPLIES]; |
49 | int fmt; | ||
50 | int pll_in; | ||
51 | int pll_out; | ||
52 | int pll_r; | ||
53 | int pll_j; | ||
54 | int pll_d; | ||
55 | int pll_p; | ||
56 | unsigned long real_pll; | ||
42 | }; | 57 | }; |
43 | 58 | ||
44 | /* | 59 | /* |
@@ -69,6 +84,7 @@ static const struct reg_default pcm512x_reg_defaults[] = { | |||
69 | { PCM512x_MUTE, 0x00 }, | 84 | { PCM512x_MUTE, 0x00 }, |
70 | { PCM512x_DSP, 0x00 }, | 85 | { PCM512x_DSP, 0x00 }, |
71 | { PCM512x_PLL_REF, 0x00 }, | 86 | { PCM512x_PLL_REF, 0x00 }, |
87 | { PCM512x_DAC_REF, 0x00 }, | ||
72 | { PCM512x_DAC_ROUTING, 0x11 }, | 88 | { PCM512x_DAC_ROUTING, 0x11 }, |
73 | { PCM512x_DSP_PROGRAM, 0x01 }, | 89 | { PCM512x_DSP_PROGRAM, 0x01 }, |
74 | { PCM512x_CLKDET, 0x00 }, | 90 | { PCM512x_CLKDET, 0x00 }, |
@@ -87,6 +103,25 @@ static const struct reg_default pcm512x_reg_defaults[] = { | |||
87 | { PCM512x_ANALOG_GAIN_BOOST, 0x00 }, | 103 | { PCM512x_ANALOG_GAIN_BOOST, 0x00 }, |
88 | { PCM512x_VCOM_CTRL_1, 0x00 }, | 104 | { PCM512x_VCOM_CTRL_1, 0x00 }, |
89 | { PCM512x_VCOM_CTRL_2, 0x01 }, | 105 | { PCM512x_VCOM_CTRL_2, 0x01 }, |
106 | { PCM512x_BCLK_LRCLK_CFG, 0x00 }, | ||
107 | { PCM512x_MASTER_MODE, 0x7c }, | ||
108 | { PCM512x_GPIO_DACIN, 0x00 }, | ||
109 | { PCM512x_GPIO_PLLIN, 0x00 }, | ||
110 | { PCM512x_SYNCHRONIZE, 0x10 }, | ||
111 | { PCM512x_PLL_COEFF_0, 0x00 }, | ||
112 | { PCM512x_PLL_COEFF_1, 0x00 }, | ||
113 | { PCM512x_PLL_COEFF_2, 0x00 }, | ||
114 | { PCM512x_PLL_COEFF_3, 0x00 }, | ||
115 | { PCM512x_PLL_COEFF_4, 0x00 }, | ||
116 | { PCM512x_DSP_CLKDIV, 0x00 }, | ||
117 | { PCM512x_DAC_CLKDIV, 0x00 }, | ||
118 | { PCM512x_NCP_CLKDIV, 0x00 }, | ||
119 | { PCM512x_OSR_CLKDIV, 0x00 }, | ||
120 | { PCM512x_MASTER_CLKDIV_1, 0x00 }, | ||
121 | { PCM512x_MASTER_CLKDIV_2, 0x00 }, | ||
122 | { PCM512x_FS_SPEED_MODE, 0x00 }, | ||
123 | { PCM512x_IDAC_1, 0x01 }, | ||
124 | { PCM512x_IDAC_2, 0x00 }, | ||
90 | }; | 125 | }; |
91 | 126 | ||
92 | static bool pcm512x_readable(struct device *dev, unsigned int reg) | 127 | static bool pcm512x_readable(struct device *dev, unsigned int reg) |
@@ -103,6 +138,10 @@ static bool pcm512x_readable(struct device *dev, unsigned int reg) | |||
103 | case PCM512x_DSP_GPIO_INPUT: | 138 | case PCM512x_DSP_GPIO_INPUT: |
104 | case PCM512x_MASTER_MODE: | 139 | case PCM512x_MASTER_MODE: |
105 | case PCM512x_PLL_REF: | 140 | case PCM512x_PLL_REF: |
141 | case PCM512x_DAC_REF: | ||
142 | case PCM512x_GPIO_DACIN: | ||
143 | case PCM512x_GPIO_PLLIN: | ||
144 | case PCM512x_SYNCHRONIZE: | ||
106 | case PCM512x_PLL_COEFF_0: | 145 | case PCM512x_PLL_COEFF_0: |
107 | case PCM512x_PLL_COEFF_1: | 146 | case PCM512x_PLL_COEFF_1: |
108 | case PCM512x_PLL_COEFF_2: | 147 | case PCM512x_PLL_COEFF_2: |
@@ -143,6 +182,7 @@ static bool pcm512x_readable(struct device *dev, unsigned int reg) | |||
143 | case PCM512x_RATE_DET_2: | 182 | case PCM512x_RATE_DET_2: |
144 | case PCM512x_RATE_DET_3: | 183 | case PCM512x_RATE_DET_3: |
145 | case PCM512x_RATE_DET_4: | 184 | case PCM512x_RATE_DET_4: |
185 | case PCM512x_CLOCK_STATUS: | ||
146 | case PCM512x_ANALOG_MUTE_DET: | 186 | case PCM512x_ANALOG_MUTE_DET: |
147 | case PCM512x_GPIN: | 187 | case PCM512x_GPIN: |
148 | case PCM512x_DIGITAL_MUTE_DET: | 188 | case PCM512x_DIGITAL_MUTE_DET: |
@@ -154,6 +194,8 @@ static bool pcm512x_readable(struct device *dev, unsigned int reg) | |||
154 | case PCM512x_VCOM_CTRL_1: | 194 | case PCM512x_VCOM_CTRL_1: |
155 | case PCM512x_VCOM_CTRL_2: | 195 | case PCM512x_VCOM_CTRL_2: |
156 | case PCM512x_CRAM_CTRL: | 196 | case PCM512x_CRAM_CTRL: |
197 | case PCM512x_FLEX_A: | ||
198 | case PCM512x_FLEX_B: | ||
157 | return true; | 199 | return true; |
158 | default: | 200 | default: |
159 | /* There are 256 raw register addresses */ | 201 | /* There are 256 raw register addresses */ |
@@ -170,6 +212,7 @@ static bool pcm512x_volatile(struct device *dev, unsigned int reg) | |||
170 | case PCM512x_RATE_DET_2: | 212 | case PCM512x_RATE_DET_2: |
171 | case PCM512x_RATE_DET_3: | 213 | case PCM512x_RATE_DET_3: |
172 | case PCM512x_RATE_DET_4: | 214 | case PCM512x_RATE_DET_4: |
215 | case PCM512x_CLOCK_STATUS: | ||
173 | case PCM512x_ANALOG_MUTE_DET: | 216 | case PCM512x_ANALOG_MUTE_DET: |
174 | case PCM512x_GPIN: | 217 | case PCM512x_GPIN: |
175 | case PCM512x_DIGITAL_MUTE_DET: | 218 | case PCM512x_DIGITAL_MUTE_DET: |
@@ -188,8 +231,8 @@ static const DECLARE_TLV_DB_SCALE(boost_tlv, 0, 80, 0); | |||
188 | static const char * const pcm512x_dsp_program_texts[] = { | 231 | static const char * const pcm512x_dsp_program_texts[] = { |
189 | "FIR interpolation with de-emphasis", | 232 | "FIR interpolation with de-emphasis", |
190 | "Low latency IIR with de-emphasis", | 233 | "Low latency IIR with de-emphasis", |
191 | "Fixed process flow", | ||
192 | "High attenuation with de-emphasis", | 234 | "High attenuation with de-emphasis", |
235 | "Fixed process flow", | ||
193 | "Ringing-less low latency FIR", | 236 | "Ringing-less low latency FIR", |
194 | }; | 237 | }; |
195 | 238 | ||
@@ -277,7 +320,7 @@ SOC_ENUM("Auto Mute Time Right", pcm512x_autom_r), | |||
277 | SOC_SINGLE("Auto Mute Mono Switch", PCM512x_DIGITAL_MUTE_3, | 320 | SOC_SINGLE("Auto Mute Mono Switch", PCM512x_DIGITAL_MUTE_3, |
278 | PCM512x_ACTL_SHIFT, 1, 0), | 321 | PCM512x_ACTL_SHIFT, 1, 0), |
279 | SOC_DOUBLE("Auto Mute Switch", PCM512x_DIGITAL_MUTE_3, PCM512x_AMLE_SHIFT, | 322 | SOC_DOUBLE("Auto Mute Switch", PCM512x_DIGITAL_MUTE_3, PCM512x_AMLE_SHIFT, |
280 | PCM512x_AMLR_SHIFT, 1, 0), | 323 | PCM512x_AMRE_SHIFT, 1, 0), |
281 | 324 | ||
282 | SOC_ENUM("Volume Ramp Down Rate", pcm512x_vndf), | 325 | SOC_ENUM("Volume Ramp Down Rate", pcm512x_vndf), |
283 | SOC_ENUM("Volume Ramp Down Step", pcm512x_vnds), | 326 | SOC_ENUM("Volume Ramp Down Step", pcm512x_vnds), |
@@ -303,6 +346,136 @@ static const struct snd_soc_dapm_route pcm512x_dapm_routes[] = { | |||
303 | { "OUTR", NULL, "DACR" }, | 346 | { "OUTR", NULL, "DACR" }, |
304 | }; | 347 | }; |
305 | 348 | ||
349 | static const u32 pcm512x_dai_rates[] = { | ||
350 | 8000, 11025, 16000, 22050, 32000, 44100, 48000, 64000, | ||
351 | 88200, 96000, 176400, 192000, 384000, | ||
352 | }; | ||
353 | |||
354 | static const struct snd_pcm_hw_constraint_list constraints_slave = { | ||
355 | .count = ARRAY_SIZE(pcm512x_dai_rates), | ||
356 | .list = pcm512x_dai_rates, | ||
357 | }; | ||
358 | |||
359 | static int pcm512x_hw_rule_rate(struct snd_pcm_hw_params *params, | ||
360 | struct snd_pcm_hw_rule *rule) | ||
361 | { | ||
362 | struct snd_interval ranges[2]; | ||
363 | int frame_size; | ||
364 | |||
365 | frame_size = snd_soc_params_to_frame_size(params); | ||
366 | if (frame_size < 0) | ||
367 | return frame_size; | ||
368 | |||
369 | switch (frame_size) { | ||
370 | case 32: | ||
371 | /* No hole when the frame size is 32. */ | ||
372 | return 0; | ||
373 | case 48: | ||
374 | case 64: | ||
375 | /* There is only one hole in the range of supported | ||
376 | * rates, but it moves with the frame size. | ||
377 | */ | ||
378 | memset(ranges, 0, sizeof(ranges)); | ||
379 | ranges[0].min = 8000; | ||
380 | ranges[0].max = 25000000 / frame_size / 2; | ||
381 | ranges[1].min = DIV_ROUND_UP(16000000, frame_size); | ||
382 | ranges[1].max = 384000; | ||
383 | break; | ||
384 | default: | ||
385 | return -EINVAL; | ||
386 | } | ||
387 | |||
388 | return snd_interval_ranges(hw_param_interval(params, rule->var), | ||
389 | ARRAY_SIZE(ranges), ranges, 0); | ||
390 | } | ||
391 | |||
392 | static int pcm512x_dai_startup_master(struct snd_pcm_substream *substream, | ||
393 | struct snd_soc_dai *dai) | ||
394 | { | ||
395 | struct snd_soc_codec *codec = dai->codec; | ||
396 | struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec); | ||
397 | struct device *dev = dai->dev; | ||
398 | struct snd_pcm_hw_constraint_ratnums *constraints_no_pll; | ||
399 | struct snd_ratnum *rats_no_pll; | ||
400 | |||
401 | if (IS_ERR(pcm512x->sclk)) { | ||
402 | dev_err(dev, "Need SCLK for master mode: %ld\n", | ||
403 | PTR_ERR(pcm512x->sclk)); | ||
404 | return PTR_ERR(pcm512x->sclk); | ||
405 | } | ||
406 | |||
407 | if (pcm512x->pll_out) | ||
408 | return snd_pcm_hw_rule_add(substream->runtime, 0, | ||
409 | SNDRV_PCM_HW_PARAM_RATE, | ||
410 | pcm512x_hw_rule_rate, | ||
411 | NULL, | ||
412 | SNDRV_PCM_HW_PARAM_FRAME_BITS, | ||
413 | SNDRV_PCM_HW_PARAM_CHANNELS, -1); | ||
414 | |||
415 | constraints_no_pll = devm_kzalloc(dev, sizeof(*constraints_no_pll), | ||
416 | GFP_KERNEL); | ||
417 | if (!constraints_no_pll) | ||
418 | return -ENOMEM; | ||
419 | constraints_no_pll->nrats = 1; | ||
420 | rats_no_pll = devm_kzalloc(dev, sizeof(*rats_no_pll), GFP_KERNEL); | ||
421 | if (!rats_no_pll) | ||
422 | return -ENOMEM; | ||
423 | constraints_no_pll->rats = rats_no_pll; | ||
424 | rats_no_pll->num = clk_get_rate(pcm512x->sclk) / 64; | ||
425 | rats_no_pll->den_min = 1; | ||
426 | rats_no_pll->den_max = 128; | ||
427 | rats_no_pll->den_step = 1; | ||
428 | |||
429 | return snd_pcm_hw_constraint_ratnums(substream->runtime, 0, | ||
430 | SNDRV_PCM_HW_PARAM_RATE, | ||
431 | constraints_no_pll); | ||
432 | } | ||
433 | |||
434 | static int pcm512x_dai_startup_slave(struct snd_pcm_substream *substream, | ||
435 | struct snd_soc_dai *dai) | ||
436 | { | ||
437 | struct snd_soc_codec *codec = dai->codec; | ||
438 | struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec); | ||
439 | struct device *dev = dai->dev; | ||
440 | struct regmap *regmap = pcm512x->regmap; | ||
441 | |||
442 | if (IS_ERR(pcm512x->sclk)) { | ||
443 | dev_info(dev, "No SCLK, using BCLK: %ld\n", | ||
444 | PTR_ERR(pcm512x->sclk)); | ||
445 | |||
446 | /* Disable reporting of missing SCLK as an error */ | ||
447 | regmap_update_bits(regmap, PCM512x_ERROR_DETECT, | ||
448 | PCM512x_IDCH, PCM512x_IDCH); | ||
449 | |||
450 | /* Switch PLL input to BCLK */ | ||
451 | regmap_update_bits(regmap, PCM512x_PLL_REF, | ||
452 | PCM512x_SREF, PCM512x_SREF_BCK); | ||
453 | } | ||
454 | |||
455 | return snd_pcm_hw_constraint_list(substream->runtime, 0, | ||
456 | SNDRV_PCM_HW_PARAM_RATE, | ||
457 | &constraints_slave); | ||
458 | } | ||
459 | |||
460 | static int pcm512x_dai_startup(struct snd_pcm_substream *substream, | ||
461 | struct snd_soc_dai *dai) | ||
462 | { | ||
463 | struct snd_soc_codec *codec = dai->codec; | ||
464 | struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec); | ||
465 | |||
466 | switch (pcm512x->fmt & SND_SOC_DAIFMT_MASTER_MASK) { | ||
467 | case SND_SOC_DAIFMT_CBM_CFM: | ||
468 | case SND_SOC_DAIFMT_CBM_CFS: | ||
469 | return pcm512x_dai_startup_master(substream, dai); | ||
470 | |||
471 | case SND_SOC_DAIFMT_CBS_CFS: | ||
472 | return pcm512x_dai_startup_slave(substream, dai); | ||
473 | |||
474 | default: | ||
475 | return -EINVAL; | ||
476 | } | ||
477 | } | ||
478 | |||
306 | static int pcm512x_set_bias_level(struct snd_soc_codec *codec, | 479 | static int pcm512x_set_bias_level(struct snd_soc_codec *codec, |
307 | enum snd_soc_bias_level level) | 480 | enum snd_soc_bias_level level) |
308 | { | 481 | { |
@@ -340,17 +513,717 @@ static int pcm512x_set_bias_level(struct snd_soc_codec *codec, | |||
340 | return 0; | 513 | return 0; |
341 | } | 514 | } |
342 | 515 | ||
516 | static unsigned long pcm512x_find_sck(struct snd_soc_dai *dai, | ||
517 | unsigned long bclk_rate) | ||
518 | { | ||
519 | struct device *dev = dai->dev; | ||
520 | unsigned long sck_rate; | ||
521 | int pow2; | ||
522 | |||
523 | /* 64 MHz <= pll_rate <= 100 MHz, VREF mode */ | ||
524 | /* 16 MHz <= sck_rate <= 25 MHz, VREF mode */ | ||
525 | |||
526 | /* select sck_rate as a multiple of bclk_rate but still with | ||
527 | * as many factors of 2 as possible, as that makes it easier | ||
528 | * to find a fast DAC rate | ||
529 | */ | ||
530 | pow2 = 1 << fls((25000000 - 16000000) / bclk_rate); | ||
531 | for (; pow2; pow2 >>= 1) { | ||
532 | sck_rate = rounddown(25000000, bclk_rate * pow2); | ||
533 | if (sck_rate >= 16000000) | ||
534 | break; | ||
535 | } | ||
536 | if (!pow2) { | ||
537 | dev_err(dev, "Impossible to generate a suitable SCK\n"); | ||
538 | return 0; | ||
539 | } | ||
540 | |||
541 | dev_dbg(dev, "sck_rate %lu\n", sck_rate); | ||
542 | return sck_rate; | ||
543 | } | ||
544 | |||
545 | /* pll_rate = pllin_rate * R * J.D / P | ||
546 | * 1 <= R <= 16 | ||
547 | * 1 <= J <= 63 | ||
548 | * 0 <= D <= 9999 | ||
549 | * 1 <= P <= 15 | ||
550 | * 64 MHz <= pll_rate <= 100 MHz | ||
551 | * if D == 0 | ||
552 | * 1 MHz <= pllin_rate / P <= 20 MHz | ||
553 | * else if D > 0 | ||
554 | * 6.667 MHz <= pllin_rate / P <= 20 MHz | ||
555 | * 4 <= J <= 11 | ||
556 | * R = 1 | ||
557 | */ | ||
558 | static int pcm512x_find_pll_coeff(struct snd_soc_dai *dai, | ||
559 | unsigned long pllin_rate, | ||
560 | unsigned long pll_rate) | ||
561 | { | ||
562 | struct device *dev = dai->dev; | ||
563 | struct snd_soc_codec *codec = dai->codec; | ||
564 | struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec); | ||
565 | unsigned long common; | ||
566 | int R, J, D, P; | ||
567 | unsigned long K; /* 10000 * J.D */ | ||
568 | unsigned long num; | ||
569 | unsigned long den; | ||
570 | |||
571 | common = gcd(pll_rate, pllin_rate); | ||
572 | dev_dbg(dev, "pll %lu pllin %lu common %lu\n", | ||
573 | pll_rate, pllin_rate, common); | ||
574 | num = pll_rate / common; | ||
575 | den = pllin_rate / common; | ||
576 | |||
577 | /* pllin_rate / P (or here, den) cannot be greater than 20 MHz */ | ||
578 | if (pllin_rate / den > 20000000 && num < 8) { | ||
579 | num *= 20000000 / (pllin_rate / den); | ||
580 | den *= 20000000 / (pllin_rate / den); | ||
581 | } | ||
582 | dev_dbg(dev, "num / den = %lu / %lu\n", num, den); | ||
583 | |||
584 | P = den; | ||
585 | if (den <= 15 && num <= 16 * 63 | ||
586 | && 1000000 <= pllin_rate / P && pllin_rate / P <= 20000000) { | ||
587 | /* Try the case with D = 0 */ | ||
588 | D = 0; | ||
589 | /* factor 'num' into J and R, such that R <= 16 and J <= 63 */ | ||
590 | for (R = 16; R; R--) { | ||
591 | if (num % R) | ||
592 | continue; | ||
593 | J = num / R; | ||
594 | if (J == 0 || J > 63) | ||
595 | continue; | ||
596 | |||
597 | dev_dbg(dev, "R * J / P = %d * %d / %d\n", R, J, P); | ||
598 | pcm512x->real_pll = pll_rate; | ||
599 | goto done; | ||
600 | } | ||
601 | /* no luck */ | ||
602 | } | ||
603 | |||
604 | R = 1; | ||
605 | |||
606 | if (num > 0xffffffffUL / 10000) | ||
607 | goto fallback; | ||
608 | |||
609 | /* Try to find an exact pll_rate using the D > 0 case */ | ||
610 | common = gcd(10000 * num, den); | ||
611 | num = 10000 * num / common; | ||
612 | den /= common; | ||
613 | dev_dbg(dev, "num %lu den %lu common %lu\n", num, den, common); | ||
614 | |||
615 | for (P = den; P <= 15; P++) { | ||
616 | if (pllin_rate / P < 6667000 || 200000000 < pllin_rate / P) | ||
617 | continue; | ||
618 | if (num * P % den) | ||
619 | continue; | ||
620 | K = num * P / den; | ||
621 | /* J == 12 is ok if D == 0 */ | ||
622 | if (K < 40000 || K > 120000) | ||
623 | continue; | ||
624 | |||
625 | J = K / 10000; | ||
626 | D = K % 10000; | ||
627 | dev_dbg(dev, "J.D / P = %d.%04d / %d\n", J, D, P); | ||
628 | pcm512x->real_pll = pll_rate; | ||
629 | goto done; | ||
630 | } | ||
631 | |||
632 | /* Fall back to an approximate pll_rate */ | ||
633 | |||
634 | fallback: | ||
635 | /* find smallest possible P */ | ||
636 | P = DIV_ROUND_UP(pllin_rate, 20000000); | ||
637 | if (!P) | ||
638 | P = 1; | ||
639 | else if (P > 15) { | ||
640 | dev_err(dev, "Need a slower clock as pll-input\n"); | ||
641 | return -EINVAL; | ||
642 | } | ||
643 | if (pllin_rate / P < 6667000) { | ||
644 | dev_err(dev, "Need a faster clock as pll-input\n"); | ||
645 | return -EINVAL; | ||
646 | } | ||
647 | K = DIV_ROUND_CLOSEST_ULL(10000ULL * pll_rate * P, pllin_rate); | ||
648 | if (K < 40000) | ||
649 | K = 40000; | ||
650 | /* J == 12 is ok if D == 0 */ | ||
651 | if (K > 120000) | ||
652 | K = 120000; | ||
653 | J = K / 10000; | ||
654 | D = K % 10000; | ||
655 | dev_dbg(dev, "J.D / P ~ %d.%04d / %d\n", J, D, P); | ||
656 | pcm512x->real_pll = DIV_ROUND_DOWN_ULL((u64)K * pllin_rate, 10000 * P); | ||
657 | |||
658 | done: | ||
659 | pcm512x->pll_r = R; | ||
660 | pcm512x->pll_j = J; | ||
661 | pcm512x->pll_d = D; | ||
662 | pcm512x->pll_p = P; | ||
663 | return 0; | ||
664 | } | ||
665 | |||
666 | static unsigned long pcm512x_pllin_dac_rate(struct snd_soc_dai *dai, | ||
667 | unsigned long osr_rate, | ||
668 | unsigned long pllin_rate) | ||
669 | { | ||
670 | struct snd_soc_codec *codec = dai->codec; | ||
671 | struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec); | ||
672 | unsigned long dac_rate; | ||
673 | |||
674 | if (!pcm512x->pll_out) | ||
675 | return 0; /* no PLL to bypass, force SCK as DAC input */ | ||
676 | |||
677 | if (pllin_rate % osr_rate) | ||
678 | return 0; /* futile, quit early */ | ||
679 | |||
680 | /* run DAC no faster than 6144000 Hz */ | ||
681 | for (dac_rate = rounddown(6144000, osr_rate); | ||
682 | dac_rate; | ||
683 | dac_rate -= osr_rate) { | ||
684 | |||
685 | if (pllin_rate / dac_rate > 128) | ||
686 | return 0; /* DAC divider would be too big */ | ||
687 | |||
688 | if (!(pllin_rate % dac_rate)) | ||
689 | return dac_rate; | ||
690 | |||
691 | dac_rate -= osr_rate; | ||
692 | } | ||
693 | |||
694 | return 0; | ||
695 | } | ||
696 | |||
697 | static int pcm512x_set_dividers(struct snd_soc_dai *dai, | ||
698 | struct snd_pcm_hw_params *params) | ||
699 | { | ||
700 | struct device *dev = dai->dev; | ||
701 | struct snd_soc_codec *codec = dai->codec; | ||
702 | struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec); | ||
703 | unsigned long pllin_rate = 0; | ||
704 | unsigned long pll_rate; | ||
705 | unsigned long sck_rate; | ||
706 | unsigned long mck_rate; | ||
707 | unsigned long bclk_rate; | ||
708 | unsigned long sample_rate; | ||
709 | unsigned long osr_rate; | ||
710 | unsigned long dacsrc_rate; | ||
711 | int bclk_div; | ||
712 | int lrclk_div; | ||
713 | int dsp_div; | ||
714 | int dac_div; | ||
715 | unsigned long dac_rate; | ||
716 | int ncp_div; | ||
717 | int osr_div; | ||
718 | int ret; | ||
719 | int idac; | ||
720 | int fssp; | ||
721 | int gpio; | ||
722 | |||
723 | lrclk_div = snd_soc_params_to_frame_size(params); | ||
724 | if (lrclk_div == 0) { | ||
725 | dev_err(dev, "No LRCLK?\n"); | ||
726 | return -EINVAL; | ||
727 | } | ||
728 | |||
729 | if (!pcm512x->pll_out) { | ||
730 | sck_rate = clk_get_rate(pcm512x->sclk); | ||
731 | bclk_div = params->rate_den * 64 / lrclk_div; | ||
732 | bclk_rate = DIV_ROUND_CLOSEST(sck_rate, bclk_div); | ||
733 | |||
734 | mck_rate = sck_rate; | ||
735 | } else { | ||
736 | ret = snd_soc_params_to_bclk(params); | ||
737 | if (ret < 0) { | ||
738 | dev_err(dev, "Failed to find suitable BCLK: %d\n", ret); | ||
739 | return ret; | ||
740 | } | ||
741 | if (ret == 0) { | ||
742 | dev_err(dev, "No BCLK?\n"); | ||
743 | return -EINVAL; | ||
744 | } | ||
745 | bclk_rate = ret; | ||
746 | |||
747 | pllin_rate = clk_get_rate(pcm512x->sclk); | ||
748 | |||
749 | sck_rate = pcm512x_find_sck(dai, bclk_rate); | ||
750 | if (!sck_rate) | ||
751 | return -EINVAL; | ||
752 | pll_rate = 4 * sck_rate; | ||
753 | |||
754 | ret = pcm512x_find_pll_coeff(dai, pllin_rate, pll_rate); | ||
755 | if (ret != 0) | ||
756 | return ret; | ||
757 | |||
758 | ret = regmap_write(pcm512x->regmap, | ||
759 | PCM512x_PLL_COEFF_0, pcm512x->pll_p - 1); | ||
760 | if (ret != 0) { | ||
761 | dev_err(dev, "Failed to write PLL P: %d\n", ret); | ||
762 | return ret; | ||
763 | } | ||
764 | |||
765 | ret = regmap_write(pcm512x->regmap, | ||
766 | PCM512x_PLL_COEFF_1, pcm512x->pll_j); | ||
767 | if (ret != 0) { | ||
768 | dev_err(dev, "Failed to write PLL J: %d\n", ret); | ||
769 | return ret; | ||
770 | } | ||
771 | |||
772 | ret = regmap_write(pcm512x->regmap, | ||
773 | PCM512x_PLL_COEFF_2, pcm512x->pll_d >> 8); | ||
774 | if (ret != 0) { | ||
775 | dev_err(dev, "Failed to write PLL D msb: %d\n", ret); | ||
776 | return ret; | ||
777 | } | ||
778 | |||
779 | ret = regmap_write(pcm512x->regmap, | ||
780 | PCM512x_PLL_COEFF_3, pcm512x->pll_d & 0xff); | ||
781 | if (ret != 0) { | ||
782 | dev_err(dev, "Failed to write PLL D lsb: %d\n", ret); | ||
783 | return ret; | ||
784 | } | ||
785 | |||
786 | ret = regmap_write(pcm512x->regmap, | ||
787 | PCM512x_PLL_COEFF_4, pcm512x->pll_r - 1); | ||
788 | if (ret != 0) { | ||
789 | dev_err(dev, "Failed to write PLL R: %d\n", ret); | ||
790 | return ret; | ||
791 | } | ||
792 | |||
793 | mck_rate = pcm512x->real_pll; | ||
794 | |||
795 | bclk_div = DIV_ROUND_CLOSEST(sck_rate, bclk_rate); | ||
796 | } | ||
797 | |||
798 | if (bclk_div > 128) { | ||
799 | dev_err(dev, "Failed to find BCLK divider\n"); | ||
800 | return -EINVAL; | ||
801 | } | ||
802 | |||
803 | /* the actual rate */ | ||
804 | sample_rate = sck_rate / bclk_div / lrclk_div; | ||
805 | osr_rate = 16 * sample_rate; | ||
806 | |||
807 | /* run DSP no faster than 50 MHz */ | ||
808 | dsp_div = mck_rate > 50000000 ? 2 : 1; | ||
809 | |||
810 | dac_rate = pcm512x_pllin_dac_rate(dai, osr_rate, pllin_rate); | ||
811 | if (dac_rate) { | ||
812 | /* the desired clock rate is "compatible" with the pll input | ||
813 | * clock, so use that clock as dac input instead of the pll | ||
814 | * output clock since the pll will introduce jitter and thus | ||
815 | * noise. | ||
816 | */ | ||
817 | dev_dbg(dev, "using pll input as dac input\n"); | ||
818 | ret = regmap_update_bits(pcm512x->regmap, PCM512x_DAC_REF, | ||
819 | PCM512x_SDAC, PCM512x_SDAC_GPIO); | ||
820 | if (ret != 0) { | ||
821 | dev_err(codec->dev, | ||
822 | "Failed to set gpio as dacref: %d\n", ret); | ||
823 | return ret; | ||
824 | } | ||
825 | |||
826 | gpio = PCM512x_GREF_GPIO1 + pcm512x->pll_in - 1; | ||
827 | ret = regmap_update_bits(pcm512x->regmap, PCM512x_GPIO_DACIN, | ||
828 | PCM512x_GREF, gpio); | ||
829 | if (ret != 0) { | ||
830 | dev_err(codec->dev, | ||
831 | "Failed to set gpio %d as dacin: %d\n", | ||
832 | pcm512x->pll_in, ret); | ||
833 | return ret; | ||
834 | } | ||
835 | |||
836 | dacsrc_rate = pllin_rate; | ||
837 | } else { | ||
838 | /* run DAC no faster than 6144000 Hz */ | ||
839 | unsigned long dac_mul = 6144000 / osr_rate; | ||
840 | unsigned long sck_mul = sck_rate / osr_rate; | ||
841 | |||
842 | for (; dac_mul; dac_mul--) { | ||
843 | if (!(sck_mul % dac_mul)) | ||
844 | break; | ||
845 | } | ||
846 | if (!dac_mul) { | ||
847 | dev_err(dev, "Failed to find DAC rate\n"); | ||
848 | return -EINVAL; | ||
849 | } | ||
850 | |||
851 | dac_rate = dac_mul * osr_rate; | ||
852 | dev_dbg(dev, "dac_rate %lu sample_rate %lu\n", | ||
853 | dac_rate, sample_rate); | ||
854 | |||
855 | ret = regmap_update_bits(pcm512x->regmap, PCM512x_DAC_REF, | ||
856 | PCM512x_SDAC, PCM512x_SDAC_SCK); | ||
857 | if (ret != 0) { | ||
858 | dev_err(codec->dev, | ||
859 | "Failed to set sck as dacref: %d\n", ret); | ||
860 | return ret; | ||
861 | } | ||
862 | |||
863 | dacsrc_rate = sck_rate; | ||
864 | } | ||
865 | |||
866 | dac_div = DIV_ROUND_CLOSEST(dacsrc_rate, dac_rate); | ||
867 | if (dac_div > 128) { | ||
868 | dev_err(dev, "Failed to find DAC divider\n"); | ||
869 | return -EINVAL; | ||
870 | } | ||
871 | |||
872 | ncp_div = DIV_ROUND_CLOSEST(dacsrc_rate / dac_div, 1536000); | ||
873 | if (ncp_div > 128 || dacsrc_rate / dac_div / ncp_div > 2048000) { | ||
874 | /* run NCP no faster than 2048000 Hz, but why? */ | ||
875 | ncp_div = DIV_ROUND_UP(dacsrc_rate / dac_div, 2048000); | ||
876 | if (ncp_div > 128) { | ||
877 | dev_err(dev, "Failed to find NCP divider\n"); | ||
878 | return -EINVAL; | ||
879 | } | ||
880 | } | ||
881 | |||
882 | osr_div = DIV_ROUND_CLOSEST(dac_rate, osr_rate); | ||
883 | if (osr_div > 128) { | ||
884 | dev_err(dev, "Failed to find OSR divider\n"); | ||
885 | return -EINVAL; | ||
886 | } | ||
887 | |||
888 | idac = mck_rate / (dsp_div * sample_rate); | ||
889 | |||
890 | ret = regmap_write(pcm512x->regmap, PCM512x_DSP_CLKDIV, dsp_div - 1); | ||
891 | if (ret != 0) { | ||
892 | dev_err(dev, "Failed to write DSP divider: %d\n", ret); | ||
893 | return ret; | ||
894 | } | ||
895 | |||
896 | ret = regmap_write(pcm512x->regmap, PCM512x_DAC_CLKDIV, dac_div - 1); | ||
897 | if (ret != 0) { | ||
898 | dev_err(dev, "Failed to write DAC divider: %d\n", ret); | ||
899 | return ret; | ||
900 | } | ||
901 | |||
902 | ret = regmap_write(pcm512x->regmap, PCM512x_NCP_CLKDIV, ncp_div - 1); | ||
903 | if (ret != 0) { | ||
904 | dev_err(dev, "Failed to write NCP divider: %d\n", ret); | ||
905 | return ret; | ||
906 | } | ||
907 | |||
908 | ret = regmap_write(pcm512x->regmap, PCM512x_OSR_CLKDIV, osr_div - 1); | ||
909 | if (ret != 0) { | ||
910 | dev_err(dev, "Failed to write OSR divider: %d\n", ret); | ||
911 | return ret; | ||
912 | } | ||
913 | |||
914 | ret = regmap_write(pcm512x->regmap, | ||
915 | PCM512x_MASTER_CLKDIV_1, bclk_div - 1); | ||
916 | if (ret != 0) { | ||
917 | dev_err(dev, "Failed to write BCLK divider: %d\n", ret); | ||
918 | return ret; | ||
919 | } | ||
920 | |||
921 | ret = regmap_write(pcm512x->regmap, | ||
922 | PCM512x_MASTER_CLKDIV_2, lrclk_div - 1); | ||
923 | if (ret != 0) { | ||
924 | dev_err(dev, "Failed to write LRCLK divider: %d\n", ret); | ||
925 | return ret; | ||
926 | } | ||
927 | |||
928 | ret = regmap_write(pcm512x->regmap, PCM512x_IDAC_1, idac >> 8); | ||
929 | if (ret != 0) { | ||
930 | dev_err(dev, "Failed to write IDAC msb divider: %d\n", ret); | ||
931 | return ret; | ||
932 | } | ||
933 | |||
934 | ret = regmap_write(pcm512x->regmap, PCM512x_IDAC_2, idac & 0xff); | ||
935 | if (ret != 0) { | ||
936 | dev_err(dev, "Failed to write IDAC lsb divider: %d\n", ret); | ||
937 | return ret; | ||
938 | } | ||
939 | |||
940 | if (sample_rate <= 48000) | ||
941 | fssp = PCM512x_FSSP_48KHZ; | ||
942 | else if (sample_rate <= 96000) | ||
943 | fssp = PCM512x_FSSP_96KHZ; | ||
944 | else if (sample_rate <= 192000) | ||
945 | fssp = PCM512x_FSSP_192KHZ; | ||
946 | else | ||
947 | fssp = PCM512x_FSSP_384KHZ; | ||
948 | ret = regmap_update_bits(pcm512x->regmap, PCM512x_FS_SPEED_MODE, | ||
949 | PCM512x_FSSP, fssp); | ||
950 | if (ret != 0) { | ||
951 | dev_err(codec->dev, "Failed to set fs speed: %d\n", ret); | ||
952 | return ret; | ||
953 | } | ||
954 | |||
955 | dev_dbg(codec->dev, "DSP divider %d\n", dsp_div); | ||
956 | dev_dbg(codec->dev, "DAC divider %d\n", dac_div); | ||
957 | dev_dbg(codec->dev, "NCP divider %d\n", ncp_div); | ||
958 | dev_dbg(codec->dev, "OSR divider %d\n", osr_div); | ||
959 | dev_dbg(codec->dev, "BCK divider %d\n", bclk_div); | ||
960 | dev_dbg(codec->dev, "LRCK divider %d\n", lrclk_div); | ||
961 | dev_dbg(codec->dev, "IDAC %d\n", idac); | ||
962 | dev_dbg(codec->dev, "1<<FSSP %d\n", 1 << fssp); | ||
963 | |||
964 | return 0; | ||
965 | } | ||
966 | |||
967 | static int pcm512x_hw_params(struct snd_pcm_substream *substream, | ||
968 | struct snd_pcm_hw_params *params, | ||
969 | struct snd_soc_dai *dai) | ||
970 | { | ||
971 | struct snd_soc_codec *codec = dai->codec; | ||
972 | struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec); | ||
973 | int alen; | ||
974 | int gpio; | ||
975 | int clock_output; | ||
976 | int master_mode; | ||
977 | int ret; | ||
978 | |||
979 | dev_dbg(codec->dev, "hw_params %u Hz, %u channels\n", | ||
980 | params_rate(params), | ||
981 | params_channels(params)); | ||
982 | |||
983 | switch (snd_pcm_format_width(params_format(params))) { | ||
984 | case 16: | ||
985 | alen = PCM512x_ALEN_16; | ||
986 | break; | ||
987 | case 20: | ||
988 | alen = PCM512x_ALEN_20; | ||
989 | break; | ||
990 | case 24: | ||
991 | alen = PCM512x_ALEN_24; | ||
992 | break; | ||
993 | case 32: | ||
994 | alen = PCM512x_ALEN_32; | ||
995 | break; | ||
996 | default: | ||
997 | dev_err(codec->dev, "Bad frame size: %d\n", | ||
998 | snd_pcm_format_width(params_format(params))); | ||
999 | return -EINVAL; | ||
1000 | } | ||
1001 | |||
1002 | switch (pcm512x->fmt & SND_SOC_DAIFMT_MASTER_MASK) { | ||
1003 | case SND_SOC_DAIFMT_CBS_CFS: | ||
1004 | ret = regmap_update_bits(pcm512x->regmap, | ||
1005 | PCM512x_BCLK_LRCLK_CFG, | ||
1006 | PCM512x_BCKP | ||
1007 | | PCM512x_BCKO | PCM512x_LRKO, | ||
1008 | 0); | ||
1009 | if (ret != 0) { | ||
1010 | dev_err(codec->dev, | ||
1011 | "Failed to enable slave mode: %d\n", ret); | ||
1012 | return ret; | ||
1013 | } | ||
1014 | |||
1015 | ret = regmap_update_bits(pcm512x->regmap, PCM512x_ERROR_DETECT, | ||
1016 | PCM512x_DCAS, 0); | ||
1017 | if (ret != 0) { | ||
1018 | dev_err(codec->dev, | ||
1019 | "Failed to enable clock divider autoset: %d\n", | ||
1020 | ret); | ||
1021 | return ret; | ||
1022 | } | ||
1023 | return 0; | ||
1024 | case SND_SOC_DAIFMT_CBM_CFM: | ||
1025 | clock_output = PCM512x_BCKO | PCM512x_LRKO; | ||
1026 | master_mode = PCM512x_RLRK | PCM512x_RBCK; | ||
1027 | break; | ||
1028 | case SND_SOC_DAIFMT_CBM_CFS: | ||
1029 | clock_output = PCM512x_BCKO; | ||
1030 | master_mode = PCM512x_RBCK; | ||
1031 | break; | ||
1032 | default: | ||
1033 | return -EINVAL; | ||
1034 | } | ||
1035 | |||
1036 | ret = regmap_update_bits(pcm512x->regmap, PCM512x_I2S_1, | ||
1037 | PCM512x_ALEN, alen); | ||
1038 | if (ret != 0) { | ||
1039 | dev_err(codec->dev, "Failed to set frame size: %d\n", ret); | ||
1040 | return ret; | ||
1041 | } | ||
1042 | |||
1043 | if (pcm512x->pll_out) { | ||
1044 | ret = regmap_write(pcm512x->regmap, PCM512x_FLEX_A, 0x11); | ||
1045 | if (ret != 0) { | ||
1046 | dev_err(codec->dev, "Failed to set FLEX_A: %d\n", ret); | ||
1047 | return ret; | ||
1048 | } | ||
1049 | |||
1050 | ret = regmap_write(pcm512x->regmap, PCM512x_FLEX_B, 0xff); | ||
1051 | if (ret != 0) { | ||
1052 | dev_err(codec->dev, "Failed to set FLEX_B: %d\n", ret); | ||
1053 | return ret; | ||
1054 | } | ||
1055 | |||
1056 | ret = regmap_update_bits(pcm512x->regmap, PCM512x_ERROR_DETECT, | ||
1057 | PCM512x_IDFS | PCM512x_IDBK | ||
1058 | | PCM512x_IDSK | PCM512x_IDCH | ||
1059 | | PCM512x_IDCM | PCM512x_DCAS | ||
1060 | | PCM512x_IPLK, | ||
1061 | PCM512x_IDFS | PCM512x_IDBK | ||
1062 | | PCM512x_IDSK | PCM512x_IDCH | ||
1063 | | PCM512x_DCAS); | ||
1064 | if (ret != 0) { | ||
1065 | dev_err(codec->dev, | ||
1066 | "Failed to ignore auto-clock failures: %d\n", | ||
1067 | ret); | ||
1068 | return ret; | ||
1069 | } | ||
1070 | } else { | ||
1071 | ret = regmap_update_bits(pcm512x->regmap, PCM512x_ERROR_DETECT, | ||
1072 | PCM512x_IDFS | PCM512x_IDBK | ||
1073 | | PCM512x_IDSK | PCM512x_IDCH | ||
1074 | | PCM512x_IDCM | PCM512x_DCAS | ||
1075 | | PCM512x_IPLK, | ||
1076 | PCM512x_IDFS | PCM512x_IDBK | ||
1077 | | PCM512x_IDSK | PCM512x_IDCH | ||
1078 | | PCM512x_DCAS | PCM512x_IPLK); | ||
1079 | if (ret != 0) { | ||
1080 | dev_err(codec->dev, | ||
1081 | "Failed to ignore auto-clock failures: %d\n", | ||
1082 | ret); | ||
1083 | return ret; | ||
1084 | } | ||
1085 | |||
1086 | ret = regmap_update_bits(pcm512x->regmap, PCM512x_PLL_EN, | ||
1087 | PCM512x_PLLE, 0); | ||
1088 | if (ret != 0) { | ||
1089 | dev_err(codec->dev, "Failed to disable pll: %d\n", ret); | ||
1090 | return ret; | ||
1091 | } | ||
1092 | } | ||
1093 | |||
1094 | ret = pcm512x_set_dividers(dai, params); | ||
1095 | if (ret != 0) | ||
1096 | return ret; | ||
1097 | |||
1098 | if (pcm512x->pll_out) { | ||
1099 | ret = regmap_update_bits(pcm512x->regmap, PCM512x_PLL_REF, | ||
1100 | PCM512x_SREF, PCM512x_SREF_GPIO); | ||
1101 | if (ret != 0) { | ||
1102 | dev_err(codec->dev, | ||
1103 | "Failed to set gpio as pllref: %d\n", ret); | ||
1104 | return ret; | ||
1105 | } | ||
1106 | |||
1107 | gpio = PCM512x_GREF_GPIO1 + pcm512x->pll_in - 1; | ||
1108 | ret = regmap_update_bits(pcm512x->regmap, PCM512x_GPIO_PLLIN, | ||
1109 | PCM512x_GREF, gpio); | ||
1110 | if (ret != 0) { | ||
1111 | dev_err(codec->dev, | ||
1112 | "Failed to set gpio %d as pllin: %d\n", | ||
1113 | pcm512x->pll_in, ret); | ||
1114 | return ret; | ||
1115 | } | ||
1116 | |||
1117 | ret = regmap_update_bits(pcm512x->regmap, PCM512x_PLL_EN, | ||
1118 | PCM512x_PLLE, PCM512x_PLLE); | ||
1119 | if (ret != 0) { | ||
1120 | dev_err(codec->dev, "Failed to enable pll: %d\n", ret); | ||
1121 | return ret; | ||
1122 | } | ||
1123 | } | ||
1124 | |||
1125 | ret = regmap_update_bits(pcm512x->regmap, PCM512x_BCLK_LRCLK_CFG, | ||
1126 | PCM512x_BCKP | PCM512x_BCKO | PCM512x_LRKO, | ||
1127 | clock_output); | ||
1128 | if (ret != 0) { | ||
1129 | dev_err(codec->dev, "Failed to enable clock output: %d\n", ret); | ||
1130 | return ret; | ||
1131 | } | ||
1132 | |||
1133 | ret = regmap_update_bits(pcm512x->regmap, PCM512x_MASTER_MODE, | ||
1134 | PCM512x_RLRK | PCM512x_RBCK, | ||
1135 | master_mode); | ||
1136 | if (ret != 0) { | ||
1137 | dev_err(codec->dev, "Failed to enable master mode: %d\n", ret); | ||
1138 | return ret; | ||
1139 | } | ||
1140 | |||
1141 | if (pcm512x->pll_out) { | ||
1142 | gpio = PCM512x_G1OE << (pcm512x->pll_out - 1); | ||
1143 | ret = regmap_update_bits(pcm512x->regmap, PCM512x_GPIO_EN, | ||
1144 | gpio, gpio); | ||
1145 | if (ret != 0) { | ||
1146 | dev_err(codec->dev, "Failed to enable gpio %d: %d\n", | ||
1147 | pcm512x->pll_out, ret); | ||
1148 | return ret; | ||
1149 | } | ||
1150 | |||
1151 | gpio = PCM512x_GPIO_OUTPUT_1 + pcm512x->pll_out - 1; | ||
1152 | ret = regmap_update_bits(pcm512x->regmap, gpio, | ||
1153 | PCM512x_GxSL, PCM512x_GxSL_PLLCK); | ||
1154 | if (ret != 0) { | ||
1155 | dev_err(codec->dev, "Failed to output pll on %d: %d\n", | ||
1156 | ret, pcm512x->pll_out); | ||
1157 | return ret; | ||
1158 | } | ||
1159 | |||
1160 | gpio = PCM512x_G1OE << (4 - 1); | ||
1161 | ret = regmap_update_bits(pcm512x->regmap, PCM512x_GPIO_EN, | ||
1162 | gpio, gpio); | ||
1163 | if (ret != 0) { | ||
1164 | dev_err(codec->dev, "Failed to enable gpio %d: %d\n", | ||
1165 | 4, ret); | ||
1166 | return ret; | ||
1167 | } | ||
1168 | |||
1169 | gpio = PCM512x_GPIO_OUTPUT_1 + 4 - 1; | ||
1170 | ret = regmap_update_bits(pcm512x->regmap, gpio, | ||
1171 | PCM512x_GxSL, PCM512x_GxSL_PLLLK); | ||
1172 | if (ret != 0) { | ||
1173 | dev_err(codec->dev, | ||
1174 | "Failed to output pll lock on %d: %d\n", | ||
1175 | ret, 4); | ||
1176 | return ret; | ||
1177 | } | ||
1178 | } | ||
1179 | |||
1180 | ret = regmap_update_bits(pcm512x->regmap, PCM512x_SYNCHRONIZE, | ||
1181 | PCM512x_RQSY, PCM512x_RQSY_HALT); | ||
1182 | if (ret != 0) { | ||
1183 | dev_err(codec->dev, "Failed to halt clocks: %d\n", ret); | ||
1184 | return ret; | ||
1185 | } | ||
1186 | |||
1187 | ret = regmap_update_bits(pcm512x->regmap, PCM512x_SYNCHRONIZE, | ||
1188 | PCM512x_RQSY, PCM512x_RQSY_RESUME); | ||
1189 | if (ret != 0) { | ||
1190 | dev_err(codec->dev, "Failed to resume clocks: %d\n", ret); | ||
1191 | return ret; | ||
1192 | } | ||
1193 | |||
1194 | return 0; | ||
1195 | } | ||
1196 | |||
1197 | static int pcm512x_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) | ||
1198 | { | ||
1199 | struct snd_soc_codec *codec = dai->codec; | ||
1200 | struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec); | ||
1201 | |||
1202 | pcm512x->fmt = fmt; | ||
1203 | |||
1204 | return 0; | ||
1205 | } | ||
1206 | |||
1207 | static const struct snd_soc_dai_ops pcm512x_dai_ops = { | ||
1208 | .startup = pcm512x_dai_startup, | ||
1209 | .hw_params = pcm512x_hw_params, | ||
1210 | .set_fmt = pcm512x_set_fmt, | ||
1211 | }; | ||
1212 | |||
343 | static struct snd_soc_dai_driver pcm512x_dai = { | 1213 | static struct snd_soc_dai_driver pcm512x_dai = { |
344 | .name = "pcm512x-hifi", | 1214 | .name = "pcm512x-hifi", |
345 | .playback = { | 1215 | .playback = { |
346 | .stream_name = "Playback", | 1216 | .stream_name = "Playback", |
347 | .channels_min = 2, | 1217 | .channels_min = 2, |
348 | .channels_max = 2, | 1218 | .channels_max = 2, |
349 | .rates = SNDRV_PCM_RATE_8000_192000, | 1219 | .rates = SNDRV_PCM_RATE_CONTINUOUS, |
1220 | .rate_min = 8000, | ||
1221 | .rate_max = 384000, | ||
350 | .formats = SNDRV_PCM_FMTBIT_S16_LE | | 1222 | .formats = SNDRV_PCM_FMTBIT_S16_LE | |
351 | SNDRV_PCM_FMTBIT_S24_LE | | 1223 | SNDRV_PCM_FMTBIT_S24_LE | |
352 | SNDRV_PCM_FMTBIT_S32_LE | 1224 | SNDRV_PCM_FMTBIT_S32_LE |
353 | }, | 1225 | }, |
1226 | .ops = &pcm512x_dai_ops, | ||
354 | }; | 1227 | }; |
355 | 1228 | ||
356 | static struct snd_soc_codec_driver pcm512x_codec_driver = { | 1229 | static struct snd_soc_codec_driver pcm512x_codec_driver = { |
@@ -448,21 +1321,9 @@ int pcm512x_probe(struct device *dev, struct regmap *regmap) | |||
448 | } | 1321 | } |
449 | 1322 | ||
450 | pcm512x->sclk = devm_clk_get(dev, NULL); | 1323 | pcm512x->sclk = devm_clk_get(dev, NULL); |
451 | if (IS_ERR(pcm512x->sclk)) { | 1324 | if (PTR_ERR(pcm512x->sclk) == -EPROBE_DEFER) |
452 | if (PTR_ERR(pcm512x->sclk) == -EPROBE_DEFER) | 1325 | return -EPROBE_DEFER; |
453 | return -EPROBE_DEFER; | 1326 | if (!IS_ERR(pcm512x->sclk)) { |
454 | |||
455 | dev_info(dev, "No SCLK, using BCLK: %ld\n", | ||
456 | PTR_ERR(pcm512x->sclk)); | ||
457 | |||
458 | /* Disable reporting of missing SCLK as an error */ | ||
459 | regmap_update_bits(regmap, PCM512x_ERROR_DETECT, | ||
460 | PCM512x_IDCH, PCM512x_IDCH); | ||
461 | |||
462 | /* Switch PLL input to BCLK */ | ||
463 | regmap_update_bits(regmap, PCM512x_PLL_REF, | ||
464 | PCM512x_SREF, PCM512x_SREF); | ||
465 | } else { | ||
466 | ret = clk_prepare_enable(pcm512x->sclk); | 1327 | ret = clk_prepare_enable(pcm512x->sclk); |
467 | if (ret != 0) { | 1328 | if (ret != 0) { |
468 | dev_err(dev, "Failed to enable SCLK: %d\n", ret); | 1329 | dev_err(dev, "Failed to enable SCLK: %d\n", ret); |
@@ -483,6 +1344,43 @@ int pcm512x_probe(struct device *dev, struct regmap *regmap) | |||
483 | pm_runtime_enable(dev); | 1344 | pm_runtime_enable(dev); |
484 | pm_runtime_idle(dev); | 1345 | pm_runtime_idle(dev); |
485 | 1346 | ||
1347 | #ifdef CONFIG_OF | ||
1348 | if (dev->of_node) { | ||
1349 | const struct device_node *np = dev->of_node; | ||
1350 | u32 val; | ||
1351 | |||
1352 | if (of_property_read_u32(np, "pll-in", &val) >= 0) { | ||
1353 | if (val > 6) { | ||
1354 | dev_err(dev, "Invalid pll-in\n"); | ||
1355 | ret = -EINVAL; | ||
1356 | goto err_clk; | ||
1357 | } | ||
1358 | pcm512x->pll_in = val; | ||
1359 | } | ||
1360 | |||
1361 | if (of_property_read_u32(np, "pll-out", &val) >= 0) { | ||
1362 | if (val > 6) { | ||
1363 | dev_err(dev, "Invalid pll-out\n"); | ||
1364 | ret = -EINVAL; | ||
1365 | goto err_clk; | ||
1366 | } | ||
1367 | pcm512x->pll_out = val; | ||
1368 | } | ||
1369 | |||
1370 | if (!pcm512x->pll_in != !pcm512x->pll_out) { | ||
1371 | dev_err(dev, | ||
1372 | "Error: both pll-in and pll-out, or none\n"); | ||
1373 | ret = -EINVAL; | ||
1374 | goto err_clk; | ||
1375 | } | ||
1376 | if (pcm512x->pll_in && pcm512x->pll_in == pcm512x->pll_out) { | ||
1377 | dev_err(dev, "Error: pll-in == pll-out\n"); | ||
1378 | ret = -EINVAL; | ||
1379 | goto err_clk; | ||
1380 | } | ||
1381 | } | ||
1382 | #endif | ||
1383 | |||
486 | ret = snd_soc_register_codec(dev, &pcm512x_codec_driver, | 1384 | ret = snd_soc_register_codec(dev, &pcm512x_codec_driver, |
487 | &pcm512x_dai, 1); | 1385 | &pcm512x_dai, 1); |
488 | if (ret != 0) { | 1386 | if (ret != 0) { |
diff --git a/sound/soc/codecs/pcm512x.h b/sound/soc/codecs/pcm512x.h index 6ee76aaca09a..b7c310207223 100644 --- a/sound/soc/codecs/pcm512x.h +++ b/sound/soc/codecs/pcm512x.h | |||
@@ -37,6 +37,10 @@ | |||
37 | #define PCM512x_DSP_GPIO_INPUT (PCM512x_PAGE_BASE(0) + 10) | 37 | #define PCM512x_DSP_GPIO_INPUT (PCM512x_PAGE_BASE(0) + 10) |
38 | #define PCM512x_MASTER_MODE (PCM512x_PAGE_BASE(0) + 12) | 38 | #define PCM512x_MASTER_MODE (PCM512x_PAGE_BASE(0) + 12) |
39 | #define PCM512x_PLL_REF (PCM512x_PAGE_BASE(0) + 13) | 39 | #define PCM512x_PLL_REF (PCM512x_PAGE_BASE(0) + 13) |
40 | #define PCM512x_DAC_REF (PCM512x_PAGE_BASE(0) + 14) | ||
41 | #define PCM512x_GPIO_DACIN (PCM512x_PAGE_BASE(0) + 16) | ||
42 | #define PCM512x_GPIO_PLLIN (PCM512x_PAGE_BASE(0) + 18) | ||
43 | #define PCM512x_SYNCHRONIZE (PCM512x_PAGE_BASE(0) + 19) | ||
40 | #define PCM512x_PLL_COEFF_0 (PCM512x_PAGE_BASE(0) + 20) | 44 | #define PCM512x_PLL_COEFF_0 (PCM512x_PAGE_BASE(0) + 20) |
41 | #define PCM512x_PLL_COEFF_1 (PCM512x_PAGE_BASE(0) + 21) | 45 | #define PCM512x_PLL_COEFF_1 (PCM512x_PAGE_BASE(0) + 21) |
42 | #define PCM512x_PLL_COEFF_2 (PCM512x_PAGE_BASE(0) + 22) | 46 | #define PCM512x_PLL_COEFF_2 (PCM512x_PAGE_BASE(0) + 22) |
@@ -77,6 +81,7 @@ | |||
77 | #define PCM512x_RATE_DET_2 (PCM512x_PAGE_BASE(0) + 92) | 81 | #define PCM512x_RATE_DET_2 (PCM512x_PAGE_BASE(0) + 92) |
78 | #define PCM512x_RATE_DET_3 (PCM512x_PAGE_BASE(0) + 93) | 82 | #define PCM512x_RATE_DET_3 (PCM512x_PAGE_BASE(0) + 93) |
79 | #define PCM512x_RATE_DET_4 (PCM512x_PAGE_BASE(0) + 94) | 83 | #define PCM512x_RATE_DET_4 (PCM512x_PAGE_BASE(0) + 94) |
84 | #define PCM512x_CLOCK_STATUS (PCM512x_PAGE_BASE(0) + 95) | ||
80 | #define PCM512x_ANALOG_MUTE_DET (PCM512x_PAGE_BASE(0) + 108) | 85 | #define PCM512x_ANALOG_MUTE_DET (PCM512x_PAGE_BASE(0) + 108) |
81 | #define PCM512x_GPIN (PCM512x_PAGE_BASE(0) + 119) | 86 | #define PCM512x_GPIN (PCM512x_PAGE_BASE(0) + 119) |
82 | #define PCM512x_DIGITAL_MUTE_DET (PCM512x_PAGE_BASE(0) + 120) | 87 | #define PCM512x_DIGITAL_MUTE_DET (PCM512x_PAGE_BASE(0) + 120) |
@@ -91,7 +96,10 @@ | |||
91 | 96 | ||
92 | #define PCM512x_CRAM_CTRL (PCM512x_PAGE_BASE(44) + 1) | 97 | #define PCM512x_CRAM_CTRL (PCM512x_PAGE_BASE(44) + 1) |
93 | 98 | ||
94 | #define PCM512x_MAX_REGISTER (PCM512x_PAGE_BASE(44) + 1) | 99 | #define PCM512x_FLEX_A (PCM512x_PAGE_BASE(253) + 63) |
100 | #define PCM512x_FLEX_B (PCM512x_PAGE_BASE(253) + 64) | ||
101 | |||
102 | #define PCM512x_MAX_REGISTER (PCM512x_PAGE_BASE(253) + 64) | ||
95 | 103 | ||
96 | /* Page 0, Register 1 - reset */ | 104 | /* Page 0, Register 1 - reset */ |
97 | #define PCM512x_RSTR (1 << 0) | 105 | #define PCM512x_RSTR (1 << 0) |
@@ -108,8 +116,8 @@ | |||
108 | #define PCM512x_RQML_SHIFT 4 | 116 | #define PCM512x_RQML_SHIFT 4 |
109 | 117 | ||
110 | /* Page 0, Register 4 - PLL */ | 118 | /* Page 0, Register 4 - PLL */ |
111 | #define PCM512x_PLCE (1 << 0) | 119 | #define PCM512x_PLLE (1 << 0) |
112 | #define PCM512x_RLCE_SHIFT 0 | 120 | #define PCM512x_PLLE_SHIFT 0 |
113 | #define PCM512x_PLCK (1 << 4) | 121 | #define PCM512x_PLCK (1 << 4) |
114 | #define PCM512x_PLCK_SHIFT 4 | 122 | #define PCM512x_PLCK_SHIFT 4 |
115 | 123 | ||
@@ -119,8 +127,66 @@ | |||
119 | #define PCM512x_DEMP (1 << 4) | 127 | #define PCM512x_DEMP (1 << 4) |
120 | #define PCM512x_DEMP_SHIFT 4 | 128 | #define PCM512x_DEMP_SHIFT 4 |
121 | 129 | ||
130 | /* Page 0, Register 8 - GPIO output enable */ | ||
131 | #define PCM512x_G1OE (1 << 0) | ||
132 | #define PCM512x_G2OE (1 << 1) | ||
133 | #define PCM512x_G3OE (1 << 2) | ||
134 | #define PCM512x_G4OE (1 << 3) | ||
135 | #define PCM512x_G5OE (1 << 4) | ||
136 | #define PCM512x_G6OE (1 << 5) | ||
137 | |||
138 | /* Page 0, Register 9 - BCK, LRCLK configuration */ | ||
139 | #define PCM512x_LRKO (1 << 0) | ||
140 | #define PCM512x_LRKO_SHIFT 0 | ||
141 | #define PCM512x_BCKO (1 << 4) | ||
142 | #define PCM512x_BCKO_SHIFT 4 | ||
143 | #define PCM512x_BCKP (1 << 5) | ||
144 | #define PCM512x_BCKP_SHIFT 5 | ||
145 | |||
146 | /* Page 0, Register 12 - Master mode BCK, LRCLK reset */ | ||
147 | #define PCM512x_RLRK (1 << 0) | ||
148 | #define PCM512x_RLRK_SHIFT 0 | ||
149 | #define PCM512x_RBCK (1 << 1) | ||
150 | #define PCM512x_RBCK_SHIFT 1 | ||
151 | |||
122 | /* Page 0, Register 13 - PLL reference */ | 152 | /* Page 0, Register 13 - PLL reference */ |
123 | #define PCM512x_SREF (1 << 4) | 153 | #define PCM512x_SREF (7 << 4) |
154 | #define PCM512x_SREF_SHIFT 4 | ||
155 | #define PCM512x_SREF_SCK (0 << 4) | ||
156 | #define PCM512x_SREF_BCK (1 << 4) | ||
157 | #define PCM512x_SREF_GPIO (3 << 4) | ||
158 | |||
159 | /* Page 0, Register 14 - DAC reference */ | ||
160 | #define PCM512x_SDAC (7 << 4) | ||
161 | #define PCM512x_SDAC_SHIFT 4 | ||
162 | #define PCM512x_SDAC_MCK (0 << 4) | ||
163 | #define PCM512x_SDAC_PLL (1 << 4) | ||
164 | #define PCM512x_SDAC_SCK (3 << 4) | ||
165 | #define PCM512x_SDAC_BCK (4 << 4) | ||
166 | #define PCM512x_SDAC_GPIO (5 << 4) | ||
167 | |||
168 | /* Page 0, Register 16, 18 - GPIO source for DAC, PLL */ | ||
169 | #define PCM512x_GREF (7 << 0) | ||
170 | #define PCM512x_GREF_SHIFT 0 | ||
171 | #define PCM512x_GREF_GPIO1 (0 << 0) | ||
172 | #define PCM512x_GREF_GPIO2 (1 << 0) | ||
173 | #define PCM512x_GREF_GPIO3 (2 << 0) | ||
174 | #define PCM512x_GREF_GPIO4 (3 << 0) | ||
175 | #define PCM512x_GREF_GPIO5 (4 << 0) | ||
176 | #define PCM512x_GREF_GPIO6 (5 << 0) | ||
177 | |||
178 | /* Page 0, Register 19 - synchronize */ | ||
179 | #define PCM512x_RQSY (1 << 0) | ||
180 | #define PCM512x_RQSY_RESUME (0 << 0) | ||
181 | #define PCM512x_RQSY_HALT (1 << 0) | ||
182 | |||
183 | /* Page 0, Register 34 - fs speed mode */ | ||
184 | #define PCM512x_FSSP (3 << 0) | ||
185 | #define PCM512x_FSSP_SHIFT 0 | ||
186 | #define PCM512x_FSSP_48KHZ (0 << 0) | ||
187 | #define PCM512x_FSSP_96KHZ (1 << 0) | ||
188 | #define PCM512x_FSSP_192KHZ (2 << 0) | ||
189 | #define PCM512x_FSSP_384KHZ (3 << 0) | ||
124 | 190 | ||
125 | /* Page 0, Register 37 - Error detection */ | 191 | /* Page 0, Register 37 - Error detection */ |
126 | #define PCM512x_IPLK (1 << 0) | 192 | #define PCM512x_IPLK (1 << 0) |
@@ -131,6 +197,20 @@ | |||
131 | #define PCM512x_IDBK (1 << 5) | 197 | #define PCM512x_IDBK (1 << 5) |
132 | #define PCM512x_IDFS (1 << 6) | 198 | #define PCM512x_IDFS (1 << 6) |
133 | 199 | ||
200 | /* Page 0, Register 40 - I2S configuration */ | ||
201 | #define PCM512x_ALEN (3 << 0) | ||
202 | #define PCM512x_ALEN_SHIFT 0 | ||
203 | #define PCM512x_ALEN_16 (0 << 0) | ||
204 | #define PCM512x_ALEN_20 (1 << 0) | ||
205 | #define PCM512x_ALEN_24 (2 << 0) | ||
206 | #define PCM512x_ALEN_32 (3 << 0) | ||
207 | #define PCM512x_AFMT (3 << 4) | ||
208 | #define PCM512x_AFMT_SHIFT 4 | ||
209 | #define PCM512x_AFMT_I2S (0 << 4) | ||
210 | #define PCM512x_AFMT_DSP (1 << 4) | ||
211 | #define PCM512x_AFMT_RTJ (2 << 4) | ||
212 | #define PCM512x_AFMT_LTJ (3 << 4) | ||
213 | |||
134 | /* Page 0, Register 42 - DAC routing */ | 214 | /* Page 0, Register 42 - DAC routing */ |
135 | #define PCM512x_AUPR_SHIFT 0 | 215 | #define PCM512x_AUPR_SHIFT 0 |
136 | #define PCM512x_AUPL_SHIFT 4 | 216 | #define PCM512x_AUPL_SHIFT 4 |
@@ -152,7 +232,26 @@ | |||
152 | /* Page 0, Register 65 - Digital mute enables */ | 232 | /* Page 0, Register 65 - Digital mute enables */ |
153 | #define PCM512x_ACTL_SHIFT 2 | 233 | #define PCM512x_ACTL_SHIFT 2 |
154 | #define PCM512x_AMLE_SHIFT 1 | 234 | #define PCM512x_AMLE_SHIFT 1 |
155 | #define PCM512x_AMLR_SHIFT 0 | 235 | #define PCM512x_AMRE_SHIFT 0 |
236 | |||
237 | /* Page 0, Register 80-85, GPIO output selection */ | ||
238 | #define PCM512x_GxSL (31 << 0) | ||
239 | #define PCM512x_GxSL_SHIFT 0 | ||
240 | #define PCM512x_GxSL_OFF (0 << 0) | ||
241 | #define PCM512x_GxSL_DSP (1 << 0) | ||
242 | #define PCM512x_GxSL_REG (2 << 0) | ||
243 | #define PCM512x_GxSL_AMUTB (3 << 0) | ||
244 | #define PCM512x_GxSL_AMUTL (4 << 0) | ||
245 | #define PCM512x_GxSL_AMUTR (5 << 0) | ||
246 | #define PCM512x_GxSL_CLKI (6 << 0) | ||
247 | #define PCM512x_GxSL_SDOUT (7 << 0) | ||
248 | #define PCM512x_GxSL_ANMUL (8 << 0) | ||
249 | #define PCM512x_GxSL_ANMUR (9 << 0) | ||
250 | #define PCM512x_GxSL_PLLLK (10 << 0) | ||
251 | #define PCM512x_GxSL_CPCLK (11 << 0) | ||
252 | #define PCM512x_GxSL_UV0_7 (14 << 0) | ||
253 | #define PCM512x_GxSL_UV0_3 (15 << 0) | ||
254 | #define PCM512x_GxSL_PLLCK (16 << 0) | ||
156 | 255 | ||
157 | /* Page 1, Register 2 - analog volume control */ | 256 | /* Page 1, Register 2 - analog volume control */ |
158 | #define PCM512x_RAGN_SHIFT 0 | 257 | #define PCM512x_RAGN_SHIFT 0 |
diff --git a/sound/soc/codecs/rt286.c b/sound/soc/codecs/rt286.c index 2cd4fe463102..f374840a5a7c 100644 --- a/sound/soc/codecs/rt286.c +++ b/sound/soc/codecs/rt286.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include "rt286.h" | 34 | #include "rt286.h" |
35 | 35 | ||
36 | #define RT286_VENDOR_ID 0x10ec0286 | 36 | #define RT286_VENDOR_ID 0x10ec0286 |
37 | #define RT288_VENDOR_ID 0x10ec0288 | ||
37 | 38 | ||
38 | struct rt286_priv { | 39 | struct rt286_priv { |
39 | struct regmap *regmap; | 40 | struct regmap *regmap; |
@@ -305,6 +306,8 @@ static int rt286_jack_detect(struct rt286_priv *rt286, bool *hp, bool *mic) | |||
305 | *hp = false; | 306 | *hp = false; |
306 | *mic = false; | 307 | *mic = false; |
307 | 308 | ||
309 | if (!rt286->codec) | ||
310 | return -EINVAL; | ||
308 | if (rt286->pdata.cbj_en) { | 311 | if (rt286->pdata.cbj_en) { |
309 | regmap_read(rt286->regmap, RT286_GET_HP_SENSE, &buf); | 312 | regmap_read(rt286->regmap, RT286_GET_HP_SENSE, &buf); |
310 | *hp = buf & 0x80000000; | 313 | *hp = buf & 0x80000000; |
@@ -403,7 +406,8 @@ EXPORT_SYMBOL_GPL(rt286_mic_detect); | |||
403 | static int is_mclk_mode(struct snd_soc_dapm_widget *source, | 406 | static int is_mclk_mode(struct snd_soc_dapm_widget *source, |
404 | struct snd_soc_dapm_widget *sink) | 407 | struct snd_soc_dapm_widget *sink) |
405 | { | 408 | { |
406 | struct rt286_priv *rt286 = snd_soc_codec_get_drvdata(source->codec); | 409 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm); |
410 | struct rt286_priv *rt286 = snd_soc_codec_get_drvdata(codec); | ||
407 | 411 | ||
408 | if (rt286->clk_id == RT286_SCLK_S_MCLK) | 412 | if (rt286->clk_id == RT286_SCLK_S_MCLK) |
409 | return 1; | 413 | return 1; |
@@ -417,6 +421,8 @@ static const DECLARE_TLV_DB_SCALE(mic_vol_tlv, 0, 1000, 0); | |||
417 | static const struct snd_kcontrol_new rt286_snd_controls[] = { | 421 | static const struct snd_kcontrol_new rt286_snd_controls[] = { |
418 | SOC_DOUBLE_R_TLV("DAC0 Playback Volume", RT286_DACL_GAIN, | 422 | SOC_DOUBLE_R_TLV("DAC0 Playback Volume", RT286_DACL_GAIN, |
419 | RT286_DACR_GAIN, 0, 0x7f, 0, out_vol_tlv), | 423 | RT286_DACR_GAIN, 0, 0x7f, 0, out_vol_tlv), |
424 | SOC_DOUBLE_R("ADC0 Capture Switch", RT286_ADCL_GAIN, | ||
425 | RT286_ADCR_GAIN, 7, 1, 1), | ||
420 | SOC_DOUBLE_R_TLV("ADC0 Capture Volume", RT286_ADCL_GAIN, | 426 | SOC_DOUBLE_R_TLV("ADC0 Capture Volume", RT286_ADCL_GAIN, |
421 | RT286_ADCR_GAIN, 0, 0x7f, 0, out_vol_tlv), | 427 | RT286_ADCR_GAIN, 0, 0x7f, 0, out_vol_tlv), |
422 | SOC_SINGLE_TLV("AMIC Volume", RT286_MIC_GAIN, | 428 | SOC_SINGLE_TLV("AMIC Volume", RT286_MIC_GAIN, |
@@ -500,7 +506,7 @@ SOC_DAPM_ENUM("SPO source", rt286_spo_enum); | |||
500 | static int rt286_spk_event(struct snd_soc_dapm_widget *w, | 506 | static int rt286_spk_event(struct snd_soc_dapm_widget *w, |
501 | struct snd_kcontrol *kcontrol, int event) | 507 | struct snd_kcontrol *kcontrol, int event) |
502 | { | 508 | { |
503 | struct snd_soc_codec *codec = w->codec; | 509 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
504 | 510 | ||
505 | switch (event) { | 511 | switch (event) { |
506 | case SND_SOC_DAPM_POST_PMU: | 512 | case SND_SOC_DAPM_POST_PMU: |
@@ -522,7 +528,7 @@ static int rt286_spk_event(struct snd_soc_dapm_widget *w, | |||
522 | static int rt286_set_dmic1_event(struct snd_soc_dapm_widget *w, | 528 | static int rt286_set_dmic1_event(struct snd_soc_dapm_widget *w, |
523 | struct snd_kcontrol *kcontrol, int event) | 529 | struct snd_kcontrol *kcontrol, int event) |
524 | { | 530 | { |
525 | struct snd_soc_codec *codec = w->codec; | 531 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
526 | 532 | ||
527 | switch (event) { | 533 | switch (event) { |
528 | case SND_SOC_DAPM_POST_PMU: | 534 | case SND_SOC_DAPM_POST_PMU: |
@@ -538,36 +544,10 @@ static int rt286_set_dmic1_event(struct snd_soc_dapm_widget *w, | |||
538 | return 0; | 544 | return 0; |
539 | } | 545 | } |
540 | 546 | ||
541 | static int rt286_adc_event(struct snd_soc_dapm_widget *w, | ||
542 | struct snd_kcontrol *kcontrol, int event) | ||
543 | { | ||
544 | struct snd_soc_codec *codec = w->codec; | ||
545 | unsigned int nid; | ||
546 | |||
547 | nid = (w->reg >> 20) & 0xff; | ||
548 | |||
549 | switch (event) { | ||
550 | case SND_SOC_DAPM_POST_PMU: | ||
551 | snd_soc_update_bits(codec, | ||
552 | VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, nid, 0), | ||
553 | 0x7080, 0x7000); | ||
554 | break; | ||
555 | case SND_SOC_DAPM_PRE_PMD: | ||
556 | snd_soc_update_bits(codec, | ||
557 | VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, nid, 0), | ||
558 | 0x7080, 0x7080); | ||
559 | break; | ||
560 | default: | ||
561 | return 0; | ||
562 | } | ||
563 | |||
564 | return 0; | ||
565 | } | ||
566 | |||
567 | static int rt286_vref_event(struct snd_soc_dapm_widget *w, | 547 | static int rt286_vref_event(struct snd_soc_dapm_widget *w, |
568 | struct snd_kcontrol *kcontrol, int event) | 548 | struct snd_kcontrol *kcontrol, int event) |
569 | { | 549 | { |
570 | struct snd_soc_codec *codec = w->codec; | 550 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
571 | 551 | ||
572 | switch (event) { | 552 | switch (event) { |
573 | case SND_SOC_DAPM_PRE_PMU: | 553 | case SND_SOC_DAPM_PRE_PMU: |
@@ -585,7 +565,7 @@ static int rt286_vref_event(struct snd_soc_dapm_widget *w, | |||
585 | static int rt286_ldo2_event(struct snd_soc_dapm_widget *w, | 565 | static int rt286_ldo2_event(struct snd_soc_dapm_widget *w, |
586 | struct snd_kcontrol *kcontrol, int event) | 566 | struct snd_kcontrol *kcontrol, int event) |
587 | { | 567 | { |
588 | struct snd_soc_codec *codec = w->codec; | 568 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
589 | 569 | ||
590 | switch (event) { | 570 | switch (event) { |
591 | case SND_SOC_DAPM_POST_PMU: | 571 | case SND_SOC_DAPM_POST_PMU: |
@@ -604,7 +584,7 @@ static int rt286_ldo2_event(struct snd_soc_dapm_widget *w, | |||
604 | static int rt286_mic1_event(struct snd_soc_dapm_widget *w, | 584 | static int rt286_mic1_event(struct snd_soc_dapm_widget *w, |
605 | struct snd_kcontrol *kcontrol, int event) | 585 | struct snd_kcontrol *kcontrol, int event) |
606 | { | 586 | { |
607 | struct snd_soc_codec *codec = w->codec; | 587 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
608 | 588 | ||
609 | switch (event) { | 589 | switch (event) { |
610 | case SND_SOC_DAPM_PRE_PMU: | 590 | case SND_SOC_DAPM_PRE_PMU: |
@@ -667,12 +647,10 @@ static const struct snd_soc_dapm_widget rt286_dapm_widgets[] = { | |||
667 | SND_SOC_DAPM_ADC("ADC 1", NULL, SND_SOC_NOPM, 0, 0), | 647 | SND_SOC_DAPM_ADC("ADC 1", NULL, SND_SOC_NOPM, 0, 0), |
668 | 648 | ||
669 | /* ADC Mux */ | 649 | /* ADC Mux */ |
670 | SND_SOC_DAPM_MUX_E("ADC 0 Mux", RT286_SET_POWER(RT286_ADC_IN1), 0, 1, | 650 | SND_SOC_DAPM_MUX("ADC 0 Mux", RT286_SET_POWER(RT286_ADC_IN1), 0, 1, |
671 | &rt286_adc0_mux, rt286_adc_event, SND_SOC_DAPM_PRE_PMD | | 651 | &rt286_adc0_mux), |
672 | SND_SOC_DAPM_POST_PMU), | 652 | SND_SOC_DAPM_MUX("ADC 1 Mux", RT286_SET_POWER(RT286_ADC_IN2), 0, 1, |
673 | SND_SOC_DAPM_MUX_E("ADC 1 Mux", RT286_SET_POWER(RT286_ADC_IN2), 0, 1, | 653 | &rt286_adc1_mux), |
674 | &rt286_adc1_mux, rt286_adc_event, SND_SOC_DAPM_PRE_PMD | | ||
675 | SND_SOC_DAPM_POST_PMU), | ||
676 | 654 | ||
677 | /* Audio Interface */ | 655 | /* Audio Interface */ |
678 | SND_SOC_DAPM_AIF_IN("AIF1RX", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0), | 656 | SND_SOC_DAPM_AIF_IN("AIF1RX", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0), |
@@ -861,10 +839,8 @@ static int rt286_hw_params(struct snd_pcm_substream *substream, | |||
861 | RT286_I2S_CTRL1, 0x0018, d_len_code << 3); | 839 | RT286_I2S_CTRL1, 0x0018, d_len_code << 3); |
862 | dev_dbg(codec->dev, "format val = 0x%x\n", val); | 840 | dev_dbg(codec->dev, "format val = 0x%x\n", val); |
863 | 841 | ||
864 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | 842 | snd_soc_update_bits(codec, RT286_DAC_FORMAT, 0x407f, val); |
865 | snd_soc_update_bits(codec, RT286_DAC_FORMAT, 0x407f, val); | 843 | snd_soc_update_bits(codec, RT286_ADC_FORMAT, 0x407f, val); |
866 | else | ||
867 | snd_soc_update_bits(codec, RT286_ADC_FORMAT, 0x407f, val); | ||
868 | 844 | ||
869 | return 0; | 845 | return 0; |
870 | } | 846 | } |
@@ -1196,6 +1172,7 @@ static const struct regmap_config rt286_regmap = { | |||
1196 | 1172 | ||
1197 | static const struct i2c_device_id rt286_i2c_id[] = { | 1173 | static const struct i2c_device_id rt286_i2c_id[] = { |
1198 | {"rt286", 0}, | 1174 | {"rt286", 0}, |
1175 | {"rt288", 0}, | ||
1199 | {} | 1176 | {} |
1200 | }; | 1177 | }; |
1201 | MODULE_DEVICE_TABLE(i2c, rt286_i2c_id); | 1178 | MODULE_DEVICE_TABLE(i2c, rt286_i2c_id); |
@@ -1216,6 +1193,17 @@ static struct dmi_system_id force_combo_jack_table[] = { | |||
1216 | { } | 1193 | { } |
1217 | }; | 1194 | }; |
1218 | 1195 | ||
1196 | static struct dmi_system_id dmi_dell_dino[] = { | ||
1197 | { | ||
1198 | .ident = "Dell Dino", | ||
1199 | .matches = { | ||
1200 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
1201 | DMI_MATCH(DMI_BOARD_NAME, "0144P8") | ||
1202 | } | ||
1203 | }, | ||
1204 | { } | ||
1205 | }; | ||
1206 | |||
1219 | static int rt286_i2c_probe(struct i2c_client *i2c, | 1207 | static int rt286_i2c_probe(struct i2c_client *i2c, |
1220 | const struct i2c_device_id *id) | 1208 | const struct i2c_device_id *id) |
1221 | { | 1209 | { |
@@ -1238,7 +1226,7 @@ static int rt286_i2c_probe(struct i2c_client *i2c, | |||
1238 | 1226 | ||
1239 | regmap_read(rt286->regmap, | 1227 | regmap_read(rt286->regmap, |
1240 | RT286_GET_PARAM(AC_NODE_ROOT, AC_PAR_VENDOR_ID), &ret); | 1228 | RT286_GET_PARAM(AC_NODE_ROOT, AC_PAR_VENDOR_ID), &ret); |
1241 | if (ret != RT286_VENDOR_ID) { | 1229 | if (ret != RT286_VENDOR_ID && ret != RT288_VENDOR_ID) { |
1242 | dev_err(&i2c->dev, | 1230 | dev_err(&i2c->dev, |
1243 | "Device with ID register %x is not rt286\n", ret); | 1231 | "Device with ID register %x is not rt286\n", ret); |
1244 | return -ENODEV; | 1232 | return -ENODEV; |
@@ -1251,7 +1239,8 @@ static int rt286_i2c_probe(struct i2c_client *i2c, | |||
1251 | if (pdata) | 1239 | if (pdata) |
1252 | rt286->pdata = *pdata; | 1240 | rt286->pdata = *pdata; |
1253 | 1241 | ||
1254 | if (dmi_check_system(force_combo_jack_table)) | 1242 | if (dmi_check_system(force_combo_jack_table) || |
1243 | dmi_check_system(dmi_dell_dino)) | ||
1255 | rt286->pdata.cbj_en = true; | 1244 | rt286->pdata.cbj_en = true; |
1256 | 1245 | ||
1257 | regmap_write(rt286->regmap, RT286_SET_AUDIO_POWER, AC_PWRST_D3); | 1246 | regmap_write(rt286->regmap, RT286_SET_AUDIO_POWER, AC_PWRST_D3); |
@@ -1290,6 +1279,17 @@ static int rt286_i2c_probe(struct i2c_client *i2c, | |||
1290 | regmap_update_bits(rt286->regmap, RT286_DEPOP_CTRL3, 0xf777, 0x4737); | 1279 | regmap_update_bits(rt286->regmap, RT286_DEPOP_CTRL3, 0xf777, 0x4737); |
1291 | regmap_update_bits(rt286->regmap, RT286_DEPOP_CTRL4, 0x00ff, 0x003f); | 1280 | regmap_update_bits(rt286->regmap, RT286_DEPOP_CTRL4, 0x00ff, 0x003f); |
1292 | 1281 | ||
1282 | if (dmi_check_system(dmi_dell_dino)) { | ||
1283 | regmap_update_bits(rt286->regmap, | ||
1284 | RT286_SET_GPIO_MASK, 0x40, 0x40); | ||
1285 | regmap_update_bits(rt286->regmap, | ||
1286 | RT286_SET_GPIO_DIRECTION, 0x40, 0x40); | ||
1287 | regmap_update_bits(rt286->regmap, | ||
1288 | RT286_SET_GPIO_DATA, 0x40, 0x40); | ||
1289 | regmap_update_bits(rt286->regmap, | ||
1290 | RT286_GPIO_CTRL, 0xc, 0x8); | ||
1291 | } | ||
1292 | |||
1293 | if (rt286->i2c->irq) { | 1293 | if (rt286->i2c->irq) { |
1294 | ret = request_threaded_irq(rt286->i2c->irq, NULL, rt286_irq, | 1294 | ret = request_threaded_irq(rt286->i2c->irq, NULL, rt286_irq, |
1295 | IRQF_TRIGGER_HIGH | IRQF_ONESHOT, "rt286", rt286); | 1295 | IRQF_TRIGGER_HIGH | IRQF_ONESHOT, "rt286", rt286); |
diff --git a/sound/soc/codecs/rt286.h b/sound/soc/codecs/rt286.h index b539b7320a79..7130edb152ef 100644 --- a/sound/soc/codecs/rt286.h +++ b/sound/soc/codecs/rt286.h | |||
@@ -117,6 +117,12 @@ | |||
117 | VERB_CMD(AC_VERB_SET_COEF_INDEX, RT286_VENDOR_REGISTERS, 0) | 117 | VERB_CMD(AC_VERB_SET_COEF_INDEX, RT286_VENDOR_REGISTERS, 0) |
118 | #define RT286_PROC_COEF\ | 118 | #define RT286_PROC_COEF\ |
119 | VERB_CMD(AC_VERB_SET_PROC_COEF, RT286_VENDOR_REGISTERS, 0) | 119 | VERB_CMD(AC_VERB_SET_PROC_COEF, RT286_VENDOR_REGISTERS, 0) |
120 | #define RT286_SET_GPIO_MASK\ | ||
121 | VERB_CMD(AC_VERB_SET_GPIO_MASK, RT286_AUDIO_FUNCTION_GROUP, 0) | ||
122 | #define RT286_SET_GPIO_DIRECTION\ | ||
123 | VERB_CMD(AC_VERB_SET_GPIO_DIRECTION, RT286_AUDIO_FUNCTION_GROUP, 0) | ||
124 | #define RT286_SET_GPIO_DATA\ | ||
125 | VERB_CMD(AC_VERB_SET_GPIO_DATA, RT286_AUDIO_FUNCTION_GROUP, 0) | ||
120 | 126 | ||
121 | /* Index registers */ | 127 | /* Index registers */ |
122 | #define RT286_A_BIAS_CTRL1 0x01 | 128 | #define RT286_A_BIAS_CTRL1 0x01 |
@@ -131,6 +137,7 @@ | |||
131 | #define RT286_POWER_CTRL3 0x0f | 137 | #define RT286_POWER_CTRL3 0x0f |
132 | #define RT286_MIC1_DET_CTRL 0x19 | 138 | #define RT286_MIC1_DET_CTRL 0x19 |
133 | #define RT286_MISC_CTRL1 0x20 | 139 | #define RT286_MISC_CTRL1 0x20 |
140 | #define RT286_GPIO_CTRL 0x29 | ||
134 | #define RT286_IRQ_CTRL 0x33 | 141 | #define RT286_IRQ_CTRL 0x33 |
135 | #define RT286_PLL_CTRL1 0x49 | 142 | #define RT286_PLL_CTRL1 0x49 |
136 | #define RT286_CBJ_CTRL1 0x4f | 143 | #define RT286_CBJ_CTRL1 0x4f |
diff --git a/sound/soc/codecs/rt5631.c b/sound/soc/codecs/rt5631.c index 6d7b7ca7d530..c61852742ee3 100644 --- a/sound/soc/codecs/rt5631.c +++ b/sound/soc/codecs/rt5631.c | |||
@@ -287,70 +287,78 @@ static const struct snd_kcontrol_new rt5631_snd_controls[] = { | |||
287 | static int check_sysclk1_source(struct snd_soc_dapm_widget *source, | 287 | static int check_sysclk1_source(struct snd_soc_dapm_widget *source, |
288 | struct snd_soc_dapm_widget *sink) | 288 | struct snd_soc_dapm_widget *sink) |
289 | { | 289 | { |
290 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm); | ||
290 | unsigned int reg; | 291 | unsigned int reg; |
291 | 292 | ||
292 | reg = snd_soc_read(source->codec, RT5631_GLOBAL_CLK_CTRL); | 293 | reg = snd_soc_read(codec, RT5631_GLOBAL_CLK_CTRL); |
293 | return reg & RT5631_SYSCLK_SOUR_SEL_PLL; | 294 | return reg & RT5631_SYSCLK_SOUR_SEL_PLL; |
294 | } | 295 | } |
295 | 296 | ||
296 | static int check_dmic_used(struct snd_soc_dapm_widget *source, | 297 | static int check_dmic_used(struct snd_soc_dapm_widget *source, |
297 | struct snd_soc_dapm_widget *sink) | 298 | struct snd_soc_dapm_widget *sink) |
298 | { | 299 | { |
299 | struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(source->codec); | 300 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm); |
301 | struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec); | ||
300 | return rt5631->dmic_used_flag; | 302 | return rt5631->dmic_used_flag; |
301 | } | 303 | } |
302 | 304 | ||
303 | static int check_dacl_to_outmixl(struct snd_soc_dapm_widget *source, | 305 | static int check_dacl_to_outmixl(struct snd_soc_dapm_widget *source, |
304 | struct snd_soc_dapm_widget *sink) | 306 | struct snd_soc_dapm_widget *sink) |
305 | { | 307 | { |
308 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm); | ||
306 | unsigned int reg; | 309 | unsigned int reg; |
307 | 310 | ||
308 | reg = snd_soc_read(source->codec, RT5631_OUTMIXER_L_CTRL); | 311 | reg = snd_soc_read(codec, RT5631_OUTMIXER_L_CTRL); |
309 | return !(reg & RT5631_M_DAC_L_TO_OUTMIXER_L); | 312 | return !(reg & RT5631_M_DAC_L_TO_OUTMIXER_L); |
310 | } | 313 | } |
311 | 314 | ||
312 | static int check_dacr_to_outmixr(struct snd_soc_dapm_widget *source, | 315 | static int check_dacr_to_outmixr(struct snd_soc_dapm_widget *source, |
313 | struct snd_soc_dapm_widget *sink) | 316 | struct snd_soc_dapm_widget *sink) |
314 | { | 317 | { |
318 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm); | ||
315 | unsigned int reg; | 319 | unsigned int reg; |
316 | 320 | ||
317 | reg = snd_soc_read(source->codec, RT5631_OUTMIXER_R_CTRL); | 321 | reg = snd_soc_read(codec, RT5631_OUTMIXER_R_CTRL); |
318 | return !(reg & RT5631_M_DAC_R_TO_OUTMIXER_R); | 322 | return !(reg & RT5631_M_DAC_R_TO_OUTMIXER_R); |
319 | } | 323 | } |
320 | 324 | ||
321 | static int check_dacl_to_spkmixl(struct snd_soc_dapm_widget *source, | 325 | static int check_dacl_to_spkmixl(struct snd_soc_dapm_widget *source, |
322 | struct snd_soc_dapm_widget *sink) | 326 | struct snd_soc_dapm_widget *sink) |
323 | { | 327 | { |
328 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm); | ||
324 | unsigned int reg; | 329 | unsigned int reg; |
325 | 330 | ||
326 | reg = snd_soc_read(source->codec, RT5631_SPK_MIXER_CTRL); | 331 | reg = snd_soc_read(codec, RT5631_SPK_MIXER_CTRL); |
327 | return !(reg & RT5631_M_DAC_L_TO_SPKMIXER_L); | 332 | return !(reg & RT5631_M_DAC_L_TO_SPKMIXER_L); |
328 | } | 333 | } |
329 | 334 | ||
330 | static int check_dacr_to_spkmixr(struct snd_soc_dapm_widget *source, | 335 | static int check_dacr_to_spkmixr(struct snd_soc_dapm_widget *source, |
331 | struct snd_soc_dapm_widget *sink) | 336 | struct snd_soc_dapm_widget *sink) |
332 | { | 337 | { |
338 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm); | ||
333 | unsigned int reg; | 339 | unsigned int reg; |
334 | 340 | ||
335 | reg = snd_soc_read(source->codec, RT5631_SPK_MIXER_CTRL); | 341 | reg = snd_soc_read(codec, RT5631_SPK_MIXER_CTRL); |
336 | return !(reg & RT5631_M_DAC_R_TO_SPKMIXER_R); | 342 | return !(reg & RT5631_M_DAC_R_TO_SPKMIXER_R); |
337 | } | 343 | } |
338 | 344 | ||
339 | static int check_adcl_select(struct snd_soc_dapm_widget *source, | 345 | static int check_adcl_select(struct snd_soc_dapm_widget *source, |
340 | struct snd_soc_dapm_widget *sink) | 346 | struct snd_soc_dapm_widget *sink) |
341 | { | 347 | { |
348 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm); | ||
342 | unsigned int reg; | 349 | unsigned int reg; |
343 | 350 | ||
344 | reg = snd_soc_read(source->codec, RT5631_ADC_REC_MIXER); | 351 | reg = snd_soc_read(codec, RT5631_ADC_REC_MIXER); |
345 | return !(reg & RT5631_M_MIC1_TO_RECMIXER_L); | 352 | return !(reg & RT5631_M_MIC1_TO_RECMIXER_L); |
346 | } | 353 | } |
347 | 354 | ||
348 | static int check_adcr_select(struct snd_soc_dapm_widget *source, | 355 | static int check_adcr_select(struct snd_soc_dapm_widget *source, |
349 | struct snd_soc_dapm_widget *sink) | 356 | struct snd_soc_dapm_widget *sink) |
350 | { | 357 | { |
358 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm); | ||
351 | unsigned int reg; | 359 | unsigned int reg; |
352 | 360 | ||
353 | reg = snd_soc_read(source->codec, RT5631_ADC_REC_MIXER); | 361 | reg = snd_soc_read(codec, RT5631_ADC_REC_MIXER); |
354 | return !(reg & RT5631_M_MIC2_TO_RECMIXER_R); | 362 | return !(reg & RT5631_M_MIC2_TO_RECMIXER_R); |
355 | } | 363 | } |
356 | 364 | ||
@@ -556,7 +564,7 @@ static void depop_seq_mute_stage(struct snd_soc_codec *codec, int enable) | |||
556 | static int hp_event(struct snd_soc_dapm_widget *w, | 564 | static int hp_event(struct snd_soc_dapm_widget *w, |
557 | struct snd_kcontrol *kcontrol, int event) | 565 | struct snd_kcontrol *kcontrol, int event) |
558 | { | 566 | { |
559 | struct snd_soc_codec *codec = w->codec; | 567 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
560 | struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec); | 568 | struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec); |
561 | 569 | ||
562 | switch (event) { | 570 | switch (event) { |
@@ -590,7 +598,7 @@ static int hp_event(struct snd_soc_dapm_widget *w, | |||
590 | static int set_dmic_params(struct snd_soc_dapm_widget *w, | 598 | static int set_dmic_params(struct snd_soc_dapm_widget *w, |
591 | struct snd_kcontrol *kcontrol, int event) | 599 | struct snd_kcontrol *kcontrol, int event) |
592 | { | 600 | { |
593 | struct snd_soc_codec *codec = w->codec; | 601 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
594 | struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec); | 602 | struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec); |
595 | 603 | ||
596 | switch (rt5631->rx_rate) { | 604 | switch (rt5631->rx_rate) { |
diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c index c3f2decd643c..178e55d4d481 100644 --- a/sound/soc/codecs/rt5640.c +++ b/sound/soc/codecs/rt5640.c | |||
@@ -458,7 +458,7 @@ static const struct snd_kcontrol_new rt5640_specific_snd_controls[] = { | |||
458 | static int set_dmic_clk(struct snd_soc_dapm_widget *w, | 458 | static int set_dmic_clk(struct snd_soc_dapm_widget *w, |
459 | struct snd_kcontrol *kcontrol, int event) | 459 | struct snd_kcontrol *kcontrol, int event) |
460 | { | 460 | { |
461 | struct snd_soc_codec *codec = w->codec; | 461 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
462 | struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec); | 462 | struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec); |
463 | int idx = -EINVAL; | 463 | int idx = -EINVAL; |
464 | 464 | ||
@@ -475,9 +475,10 @@ static int set_dmic_clk(struct snd_soc_dapm_widget *w, | |||
475 | static int is_sys_clk_from_pll(struct snd_soc_dapm_widget *source, | 475 | static int is_sys_clk_from_pll(struct snd_soc_dapm_widget *source, |
476 | struct snd_soc_dapm_widget *sink) | 476 | struct snd_soc_dapm_widget *sink) |
477 | { | 477 | { |
478 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm); | ||
478 | unsigned int val; | 479 | unsigned int val; |
479 | 480 | ||
480 | val = snd_soc_read(source->codec, RT5640_GLB_CLK); | 481 | val = snd_soc_read(codec, RT5640_GLB_CLK); |
481 | val &= RT5640_SCLK_SRC_MASK; | 482 | val &= RT5640_SCLK_SRC_MASK; |
482 | if (val == RT5640_SCLK_SRC_PLL1) | 483 | if (val == RT5640_SCLK_SRC_PLL1) |
483 | return 1; | 484 | return 1; |
@@ -963,7 +964,7 @@ static void rt5640_pmu_depop(struct snd_soc_codec *codec) | |||
963 | static int rt5640_hp_event(struct snd_soc_dapm_widget *w, | 964 | static int rt5640_hp_event(struct snd_soc_dapm_widget *w, |
964 | struct snd_kcontrol *kcontrol, int event) | 965 | struct snd_kcontrol *kcontrol, int event) |
965 | { | 966 | { |
966 | struct snd_soc_codec *codec = w->codec; | 967 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
967 | struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec); | 968 | struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec); |
968 | 969 | ||
969 | switch (event) { | 970 | switch (event) { |
@@ -987,7 +988,7 @@ static int rt5640_hp_event(struct snd_soc_dapm_widget *w, | |||
987 | static int rt5640_hp_power_event(struct snd_soc_dapm_widget *w, | 988 | static int rt5640_hp_power_event(struct snd_soc_dapm_widget *w, |
988 | struct snd_kcontrol *kcontrol, int event) | 989 | struct snd_kcontrol *kcontrol, int event) |
989 | { | 990 | { |
990 | struct snd_soc_codec *codec = w->codec; | 991 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
991 | 992 | ||
992 | switch (event) { | 993 | switch (event) { |
993 | case SND_SOC_DAPM_POST_PMU: | 994 | case SND_SOC_DAPM_POST_PMU: |
@@ -1003,7 +1004,7 @@ static int rt5640_hp_power_event(struct snd_soc_dapm_widget *w, | |||
1003 | static int rt5640_hp_post_event(struct snd_soc_dapm_widget *w, | 1004 | static int rt5640_hp_post_event(struct snd_soc_dapm_widget *w, |
1004 | struct snd_kcontrol *kcontrol, int event) | 1005 | struct snd_kcontrol *kcontrol, int event) |
1005 | { | 1006 | { |
1006 | struct snd_soc_codec *codec = w->codec; | 1007 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
1007 | struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec); | 1008 | struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec); |
1008 | 1009 | ||
1009 | switch (event) { | 1010 | switch (event) { |
@@ -2124,6 +2125,7 @@ MODULE_DEVICE_TABLE(of, rt5640_of_match); | |||
2124 | static struct acpi_device_id rt5640_acpi_match[] = { | 2125 | static struct acpi_device_id rt5640_acpi_match[] = { |
2125 | { "INT33CA", 0 }, | 2126 | { "INT33CA", 0 }, |
2126 | { "10EC5640", 0 }, | 2127 | { "10EC5640", 0 }, |
2128 | { "10EC5642", 0 }, | ||
2127 | { }, | 2129 | { }, |
2128 | }; | 2130 | }; |
2129 | MODULE_DEVICE_TABLE(acpi, rt5640_acpi_match); | 2131 | MODULE_DEVICE_TABLE(acpi, rt5640_acpi_match); |
diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c index 27141e2df878..c9a4c5be083b 100644 --- a/sound/soc/codecs/rt5645.c +++ b/sound/soc/codecs/rt5645.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include "rt5645.h" | 31 | #include "rt5645.h" |
32 | 32 | ||
33 | #define RT5645_DEVICE_ID 0x6308 | 33 | #define RT5645_DEVICE_ID 0x6308 |
34 | #define RT5650_DEVICE_ID 0x6419 | ||
34 | 35 | ||
35 | #define RT5645_PR_RANGE_BASE (0xff + 1) | 36 | #define RT5645_PR_RANGE_BASE (0xff + 1) |
36 | #define RT5645_PR_SPACING 0x100 | 37 | #define RT5645_PR_SPACING 0x100 |
@@ -59,6 +60,10 @@ static const struct reg_default init_list[] = { | |||
59 | }; | 60 | }; |
60 | #define RT5645_INIT_REG_LEN ARRAY_SIZE(init_list) | 61 | #define RT5645_INIT_REG_LEN ARRAY_SIZE(init_list) |
61 | 62 | ||
63 | static const struct reg_default rt5650_init_list[] = { | ||
64 | {0xf6, 0x0100}, | ||
65 | }; | ||
66 | |||
62 | static const struct reg_default rt5645_reg[] = { | 67 | static const struct reg_default rt5645_reg[] = { |
63 | { 0x00, 0x0000 }, | 68 | { 0x00, 0x0000 }, |
64 | { 0x01, 0xc8c8 }, | 69 | { 0x01, 0xc8c8 }, |
@@ -86,6 +91,7 @@ static const struct reg_default rt5645_reg[] = { | |||
86 | { 0x2a, 0x5656 }, | 91 | { 0x2a, 0x5656 }, |
87 | { 0x2b, 0x5454 }, | 92 | { 0x2b, 0x5454 }, |
88 | { 0x2c, 0xaaa0 }, | 93 | { 0x2c, 0xaaa0 }, |
94 | { 0x2d, 0x0000 }, | ||
89 | { 0x2f, 0x1002 }, | 95 | { 0x2f, 0x1002 }, |
90 | { 0x31, 0x5000 }, | 96 | { 0x31, 0x5000 }, |
91 | { 0x32, 0x0000 }, | 97 | { 0x32, 0x0000 }, |
@@ -193,6 +199,8 @@ static const struct reg_default rt5645_reg[] = { | |||
193 | { 0xdb, 0x0003 }, | 199 | { 0xdb, 0x0003 }, |
194 | { 0xdc, 0x0049 }, | 200 | { 0xdc, 0x0049 }, |
195 | { 0xdd, 0x001b }, | 201 | { 0xdd, 0x001b }, |
202 | { 0xdf, 0x0008 }, | ||
203 | { 0xe0, 0x4000 }, | ||
196 | { 0xe6, 0x8000 }, | 204 | { 0xe6, 0x8000 }, |
197 | { 0xe7, 0x0200 }, | 205 | { 0xe7, 0x0200 }, |
198 | { 0xec, 0xb300 }, | 206 | { 0xec, 0xb300 }, |
@@ -242,6 +250,7 @@ static bool rt5645_volatile_register(struct device *dev, unsigned int reg) | |||
242 | case RT5645_IRQ_CTRL3: | 250 | case RT5645_IRQ_CTRL3: |
243 | case RT5645_INT_IRQ_ST: | 251 | case RT5645_INT_IRQ_ST: |
244 | case RT5645_IL_CMD: | 252 | case RT5645_IL_CMD: |
253 | case RT5650_4BTN_IL_CMD1: | ||
245 | case RT5645_VENDOR_ID: | 254 | case RT5645_VENDOR_ID: |
246 | case RT5645_VENDOR_ID1: | 255 | case RT5645_VENDOR_ID1: |
247 | case RT5645_VENDOR_ID2: | 256 | case RT5645_VENDOR_ID2: |
@@ -287,6 +296,7 @@ static bool rt5645_readable_register(struct device *dev, unsigned int reg) | |||
287 | case RT5645_STO_DAC_MIXER: | 296 | case RT5645_STO_DAC_MIXER: |
288 | case RT5645_MONO_DAC_MIXER: | 297 | case RT5645_MONO_DAC_MIXER: |
289 | case RT5645_DIG_MIXER: | 298 | case RT5645_DIG_MIXER: |
299 | case RT5650_A_DAC_SOUR: | ||
290 | case RT5645_DIG_INF1_DATA: | 300 | case RT5645_DIG_INF1_DATA: |
291 | case RT5645_PDM_OUT_CTRL: | 301 | case RT5645_PDM_OUT_CTRL: |
292 | case RT5645_REC_L1_MIXER: | 302 | case RT5645_REC_L1_MIXER: |
@@ -378,6 +388,8 @@ static bool rt5645_readable_register(struct device *dev, unsigned int reg) | |||
378 | case RT5645_IL_CMD: | 388 | case RT5645_IL_CMD: |
379 | case RT5645_IL_CMD2: | 389 | case RT5645_IL_CMD2: |
380 | case RT5645_IL_CMD3: | 390 | case RT5645_IL_CMD3: |
391 | case RT5650_4BTN_IL_CMD1: | ||
392 | case RT5650_4BTN_IL_CMD2: | ||
381 | case RT5645_DRC1_HL_CTRL1: | 393 | case RT5645_DRC1_HL_CTRL1: |
382 | case RT5645_DRC2_HL_CTRL1: | 394 | case RT5645_DRC2_HL_CTRL1: |
383 | case RT5645_ADC_MONO_HP_CTRL1: | 395 | case RT5645_ADC_MONO_HP_CTRL1: |
@@ -527,7 +539,7 @@ static const struct snd_kcontrol_new rt5645_snd_controls[] = { | |||
527 | static int set_dmic_clk(struct snd_soc_dapm_widget *w, | 539 | static int set_dmic_clk(struct snd_soc_dapm_widget *w, |
528 | struct snd_kcontrol *kcontrol, int event) | 540 | struct snd_kcontrol *kcontrol, int event) |
529 | { | 541 | { |
530 | struct snd_soc_codec *codec = w->codec; | 542 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
531 | struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec); | 543 | struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec); |
532 | int idx = -EINVAL; | 544 | int idx = -EINVAL; |
533 | 545 | ||
@@ -544,9 +556,10 @@ static int set_dmic_clk(struct snd_soc_dapm_widget *w, | |||
544 | static int is_sys_clk_from_pll(struct snd_soc_dapm_widget *source, | 556 | static int is_sys_clk_from_pll(struct snd_soc_dapm_widget *source, |
545 | struct snd_soc_dapm_widget *sink) | 557 | struct snd_soc_dapm_widget *sink) |
546 | { | 558 | { |
559 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm); | ||
547 | unsigned int val; | 560 | unsigned int val; |
548 | 561 | ||
549 | val = snd_soc_read(source->codec, RT5645_GLB_CLK); | 562 | val = snd_soc_read(codec, RT5645_GLB_CLK); |
550 | val &= RT5645_SCLK_SRC_MASK; | 563 | val &= RT5645_SCLK_SRC_MASK; |
551 | if (val == RT5645_SCLK_SRC_PLL1) | 564 | if (val == RT5645_SCLK_SRC_PLL1) |
552 | return 1; | 565 | return 1; |
@@ -557,6 +570,7 @@ static int is_sys_clk_from_pll(struct snd_soc_dapm_widget *source, | |||
557 | static int is_using_asrc(struct snd_soc_dapm_widget *source, | 570 | static int is_using_asrc(struct snd_soc_dapm_widget *source, |
558 | struct snd_soc_dapm_widget *sink) | 571 | struct snd_soc_dapm_widget *sink) |
559 | { | 572 | { |
573 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm); | ||
560 | unsigned int reg, shift, val; | 574 | unsigned int reg, shift, val; |
561 | 575 | ||
562 | switch (source->shift) { | 576 | switch (source->shift) { |
@@ -588,7 +602,7 @@ static int is_using_asrc(struct snd_soc_dapm_widget *source, | |||
588 | return 0; | 602 | return 0; |
589 | } | 603 | } |
590 | 604 | ||
591 | val = (snd_soc_read(source->codec, reg) >> shift) & 0xf; | 605 | val = (snd_soc_read(codec, reg) >> shift) & 0xf; |
592 | switch (val) { | 606 | switch (val) { |
593 | case 1: | 607 | case 1: |
594 | case 2: | 608 | case 2: |
@@ -601,6 +615,87 @@ static int is_using_asrc(struct snd_soc_dapm_widget *source, | |||
601 | 615 | ||
602 | } | 616 | } |
603 | 617 | ||
618 | /** | ||
619 | * rt5645_sel_asrc_clk_src - select ASRC clock source for a set of filters | ||
620 | * @codec: SoC audio codec device. | ||
621 | * @filter_mask: mask of filters. | ||
622 | * @clk_src: clock source | ||
623 | * | ||
624 | * The ASRC function is for asynchronous MCLK and LRCK. Also, since RT5645 can | ||
625 | * only support standard 32fs or 64fs i2s format, ASRC should be enabled to | ||
626 | * support special i2s clock format such as Intel's 100fs(100 * sampling rate). | ||
627 | * ASRC function will track i2s clock and generate a corresponding system clock | ||
628 | * for codec. This function provides an API to select the clock source for a | ||
629 | * set of filters specified by the mask. And the codec driver will turn on ASRC | ||
630 | * for these filters if ASRC is selected as their clock source. | ||
631 | */ | ||
632 | int rt5645_sel_asrc_clk_src(struct snd_soc_codec *codec, | ||
633 | unsigned int filter_mask, unsigned int clk_src) | ||
634 | { | ||
635 | unsigned int asrc2_mask = 0; | ||
636 | unsigned int asrc2_value = 0; | ||
637 | unsigned int asrc3_mask = 0; | ||
638 | unsigned int asrc3_value = 0; | ||
639 | |||
640 | switch (clk_src) { | ||
641 | case RT5645_CLK_SEL_SYS: | ||
642 | case RT5645_CLK_SEL_I2S1_ASRC: | ||
643 | case RT5645_CLK_SEL_I2S2_ASRC: | ||
644 | case RT5645_CLK_SEL_SYS2: | ||
645 | break; | ||
646 | |||
647 | default: | ||
648 | return -EINVAL; | ||
649 | } | ||
650 | |||
651 | if (filter_mask & RT5645_DA_STEREO_FILTER) { | ||
652 | asrc2_mask |= RT5645_DA_STO_CLK_SEL_MASK; | ||
653 | asrc2_value = (asrc2_value & ~RT5645_DA_STO_CLK_SEL_MASK) | ||
654 | | (clk_src << RT5645_DA_STO_CLK_SEL_SFT); | ||
655 | } | ||
656 | |||
657 | if (filter_mask & RT5645_DA_MONO_L_FILTER) { | ||
658 | asrc2_mask |= RT5645_DA_MONOL_CLK_SEL_MASK; | ||
659 | asrc2_value = (asrc2_value & ~RT5645_DA_MONOL_CLK_SEL_MASK) | ||
660 | | (clk_src << RT5645_DA_MONOL_CLK_SEL_SFT); | ||
661 | } | ||
662 | |||
663 | if (filter_mask & RT5645_DA_MONO_R_FILTER) { | ||
664 | asrc2_mask |= RT5645_DA_MONOR_CLK_SEL_MASK; | ||
665 | asrc2_value = (asrc2_value & ~RT5645_DA_MONOR_CLK_SEL_MASK) | ||
666 | | (clk_src << RT5645_DA_MONOR_CLK_SEL_SFT); | ||
667 | } | ||
668 | |||
669 | if (filter_mask & RT5645_AD_STEREO_FILTER) { | ||
670 | asrc2_mask |= RT5645_AD_STO1_CLK_SEL_MASK; | ||
671 | asrc2_value = (asrc2_value & ~RT5645_AD_STO1_CLK_SEL_MASK) | ||
672 | | (clk_src << RT5645_AD_STO1_CLK_SEL_SFT); | ||
673 | } | ||
674 | |||
675 | if (filter_mask & RT5645_AD_MONO_L_FILTER) { | ||
676 | asrc3_mask |= RT5645_AD_MONOL_CLK_SEL_MASK; | ||
677 | asrc3_value = (asrc3_value & ~RT5645_AD_MONOL_CLK_SEL_MASK) | ||
678 | | (clk_src << RT5645_AD_MONOL_CLK_SEL_SFT); | ||
679 | } | ||
680 | |||
681 | if (filter_mask & RT5645_AD_MONO_R_FILTER) { | ||
682 | asrc3_mask |= RT5645_AD_MONOR_CLK_SEL_MASK; | ||
683 | asrc3_value = (asrc3_value & ~RT5645_AD_MONOR_CLK_SEL_MASK) | ||
684 | | (clk_src << RT5645_AD_MONOR_CLK_SEL_SFT); | ||
685 | } | ||
686 | |||
687 | if (asrc2_mask) | ||
688 | snd_soc_update_bits(codec, RT5645_ASRC_2, | ||
689 | asrc2_mask, asrc2_value); | ||
690 | |||
691 | if (asrc3_mask) | ||
692 | snd_soc_update_bits(codec, RT5645_ASRC_3, | ||
693 | asrc3_mask, asrc3_value); | ||
694 | |||
695 | return 0; | ||
696 | } | ||
697 | EXPORT_SYMBOL_GPL(rt5645_sel_asrc_clk_src); | ||
698 | |||
604 | /* Digital Mixer */ | 699 | /* Digital Mixer */ |
605 | static const struct snd_kcontrol_new rt5645_sto1_adc_l_mix[] = { | 700 | static const struct snd_kcontrol_new rt5645_sto1_adc_l_mix[] = { |
606 | SOC_DAPM_SINGLE("ADC1 Switch", RT5645_STO1_ADC_MIXER, | 701 | SOC_DAPM_SINGLE("ADC1 Switch", RT5645_STO1_ADC_MIXER, |
@@ -1007,6 +1102,44 @@ static SOC_ENUM_SINGLE_DECL( | |||
1007 | static const struct snd_kcontrol_new rt5645_if1_adc_in_mux = | 1102 | static const struct snd_kcontrol_new rt5645_if1_adc_in_mux = |
1008 | SOC_DAPM_ENUM("IF1 ADC IN source", rt5645_if1_adc_in_enum); | 1103 | SOC_DAPM_ENUM("IF1 ADC IN source", rt5645_if1_adc_in_enum); |
1009 | 1104 | ||
1105 | /* MX-2d [3] [2] */ | ||
1106 | static const char * const rt5650_a_dac1_src[] = { | ||
1107 | "DAC1", "Stereo DAC Mixer" | ||
1108 | }; | ||
1109 | |||
1110 | static SOC_ENUM_SINGLE_DECL( | ||
1111 | rt5650_a_dac1_l_enum, RT5650_A_DAC_SOUR, | ||
1112 | RT5650_A_DAC1_L_IN_SFT, rt5650_a_dac1_src); | ||
1113 | |||
1114 | static const struct snd_kcontrol_new rt5650_a_dac1_l_mux = | ||
1115 | SOC_DAPM_ENUM("A DAC1 L source", rt5650_a_dac1_l_enum); | ||
1116 | |||
1117 | static SOC_ENUM_SINGLE_DECL( | ||
1118 | rt5650_a_dac1_r_enum, RT5650_A_DAC_SOUR, | ||
1119 | RT5650_A_DAC1_R_IN_SFT, rt5650_a_dac1_src); | ||
1120 | |||
1121 | static const struct snd_kcontrol_new rt5650_a_dac1_r_mux = | ||
1122 | SOC_DAPM_ENUM("A DAC1 R source", rt5650_a_dac1_r_enum); | ||
1123 | |||
1124 | /* MX-2d [1] [0] */ | ||
1125 | static const char * const rt5650_a_dac2_src[] = { | ||
1126 | "Stereo DAC Mixer", "Mono DAC Mixer" | ||
1127 | }; | ||
1128 | |||
1129 | static SOC_ENUM_SINGLE_DECL( | ||
1130 | rt5650_a_dac2_l_enum, RT5650_A_DAC_SOUR, | ||
1131 | RT5650_A_DAC2_L_IN_SFT, rt5650_a_dac2_src); | ||
1132 | |||
1133 | static const struct snd_kcontrol_new rt5650_a_dac2_l_mux = | ||
1134 | SOC_DAPM_ENUM("A DAC2 L source", rt5650_a_dac2_l_enum); | ||
1135 | |||
1136 | static SOC_ENUM_SINGLE_DECL( | ||
1137 | rt5650_a_dac2_r_enum, RT5650_A_DAC_SOUR, | ||
1138 | RT5650_A_DAC2_R_IN_SFT, rt5650_a_dac2_src); | ||
1139 | |||
1140 | static const struct snd_kcontrol_new rt5650_a_dac2_r_mux = | ||
1141 | SOC_DAPM_ENUM("A DAC2 R source", rt5650_a_dac2_r_enum); | ||
1142 | |||
1010 | /* MX-2F [13:12] */ | 1143 | /* MX-2F [13:12] */ |
1011 | static const char * const rt5645_if2_adc_in_src[] = { | 1144 | static const char * const rt5645_if2_adc_in_src[] = { |
1012 | "IF_ADC1", "IF_ADC2", "VAD_ADC" | 1145 | "IF_ADC1", "IF_ADC2", "VAD_ADC" |
@@ -1144,18 +1277,23 @@ static void hp_amp_power(struct snd_soc_codec *codec, int on) | |||
1144 | static int rt5645_hp_event(struct snd_soc_dapm_widget *w, | 1277 | static int rt5645_hp_event(struct snd_soc_dapm_widget *w, |
1145 | struct snd_kcontrol *kcontrol, int event) | 1278 | struct snd_kcontrol *kcontrol, int event) |
1146 | { | 1279 | { |
1147 | struct snd_soc_codec *codec = w->codec; | 1280 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
1148 | struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec); | 1281 | struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec); |
1149 | 1282 | ||
1150 | switch (event) { | 1283 | switch (event) { |
1151 | case SND_SOC_DAPM_POST_PMU: | 1284 | case SND_SOC_DAPM_POST_PMU: |
1152 | hp_amp_power(codec, 1); | 1285 | hp_amp_power(codec, 1); |
1153 | /* headphone unmute sequence */ | 1286 | /* headphone unmute sequence */ |
1154 | snd_soc_update_bits(codec, RT5645_DEPOP_M3, RT5645_CP_FQ1_MASK | | 1287 | if (rt5645->codec_type == CODEC_TYPE_RT5650) { |
1155 | RT5645_CP_FQ2_MASK | RT5645_CP_FQ3_MASK, | 1288 | snd_soc_write(codec, RT5645_DEPOP_M3, 0x0737); |
1156 | (RT5645_CP_FQ_192_KHZ << RT5645_CP_FQ1_SFT) | | 1289 | } else { |
1157 | (RT5645_CP_FQ_12_KHZ << RT5645_CP_FQ2_SFT) | | 1290 | snd_soc_update_bits(codec, RT5645_DEPOP_M3, |
1158 | (RT5645_CP_FQ_192_KHZ << RT5645_CP_FQ3_SFT)); | 1291 | RT5645_CP_FQ1_MASK | RT5645_CP_FQ2_MASK | |
1292 | RT5645_CP_FQ3_MASK, | ||
1293 | (RT5645_CP_FQ_192_KHZ << RT5645_CP_FQ1_SFT) | | ||
1294 | (RT5645_CP_FQ_12_KHZ << RT5645_CP_FQ2_SFT) | | ||
1295 | (RT5645_CP_FQ_192_KHZ << RT5645_CP_FQ3_SFT)); | ||
1296 | } | ||
1159 | regmap_write(rt5645->regmap, | 1297 | regmap_write(rt5645->regmap, |
1160 | RT5645_PR_BASE + RT5645_MAMP_INT_REG2, 0xfc00); | 1298 | RT5645_PR_BASE + RT5645_MAMP_INT_REG2, 0xfc00); |
1161 | snd_soc_update_bits(codec, RT5645_DEPOP_M1, | 1299 | snd_soc_update_bits(codec, RT5645_DEPOP_M1, |
@@ -1175,12 +1313,16 @@ static int rt5645_hp_event(struct snd_soc_dapm_widget *w, | |||
1175 | 1313 | ||
1176 | case SND_SOC_DAPM_PRE_PMD: | 1314 | case SND_SOC_DAPM_PRE_PMD: |
1177 | /* headphone mute sequence */ | 1315 | /* headphone mute sequence */ |
1178 | snd_soc_update_bits(codec, RT5645_DEPOP_M3, | 1316 | if (rt5645->codec_type == CODEC_TYPE_RT5650) { |
1179 | RT5645_CP_FQ1_MASK | RT5645_CP_FQ2_MASK | | 1317 | snd_soc_write(codec, RT5645_DEPOP_M3, 0x0737); |
1180 | RT5645_CP_FQ3_MASK, | 1318 | } else { |
1181 | (RT5645_CP_FQ_96_KHZ << RT5645_CP_FQ1_SFT) | | 1319 | snd_soc_update_bits(codec, RT5645_DEPOP_M3, |
1182 | (RT5645_CP_FQ_12_KHZ << RT5645_CP_FQ2_SFT) | | 1320 | RT5645_CP_FQ1_MASK | RT5645_CP_FQ2_MASK | |
1183 | (RT5645_CP_FQ_96_KHZ << RT5645_CP_FQ3_SFT)); | 1321 | RT5645_CP_FQ3_MASK, |
1322 | (RT5645_CP_FQ_96_KHZ << RT5645_CP_FQ1_SFT) | | ||
1323 | (RT5645_CP_FQ_12_KHZ << RT5645_CP_FQ2_SFT) | | ||
1324 | (RT5645_CP_FQ_96_KHZ << RT5645_CP_FQ3_SFT)); | ||
1325 | } | ||
1184 | regmap_write(rt5645->regmap, | 1326 | regmap_write(rt5645->regmap, |
1185 | RT5645_PR_BASE + RT5645_MAMP_INT_REG2, 0xfc00); | 1327 | RT5645_PR_BASE + RT5645_MAMP_INT_REG2, 0xfc00); |
1186 | snd_soc_update_bits(codec, RT5645_DEPOP_M1, | 1328 | snd_soc_update_bits(codec, RT5645_DEPOP_M1, |
@@ -1205,7 +1347,7 @@ static int rt5645_hp_event(struct snd_soc_dapm_widget *w, | |||
1205 | static int rt5645_spk_event(struct snd_soc_dapm_widget *w, | 1347 | static int rt5645_spk_event(struct snd_soc_dapm_widget *w, |
1206 | struct snd_kcontrol *kcontrol, int event) | 1348 | struct snd_kcontrol *kcontrol, int event) |
1207 | { | 1349 | { |
1208 | struct snd_soc_codec *codec = w->codec; | 1350 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
1209 | 1351 | ||
1210 | switch (event) { | 1352 | switch (event) { |
1211 | case SND_SOC_DAPM_POST_PMU: | 1353 | case SND_SOC_DAPM_POST_PMU: |
@@ -1232,7 +1374,7 @@ static int rt5645_spk_event(struct snd_soc_dapm_widget *w, | |||
1232 | static int rt5645_lout_event(struct snd_soc_dapm_widget *w, | 1374 | static int rt5645_lout_event(struct snd_soc_dapm_widget *w, |
1233 | struct snd_kcontrol *kcontrol, int event) | 1375 | struct snd_kcontrol *kcontrol, int event) |
1234 | { | 1376 | { |
1235 | struct snd_soc_codec *codec = w->codec; | 1377 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
1236 | 1378 | ||
1237 | switch (event) { | 1379 | switch (event) { |
1238 | case SND_SOC_DAPM_POST_PMU: | 1380 | case SND_SOC_DAPM_POST_PMU: |
@@ -1262,7 +1404,7 @@ static int rt5645_lout_event(struct snd_soc_dapm_widget *w, | |||
1262 | static int rt5645_bst2_event(struct snd_soc_dapm_widget *w, | 1404 | static int rt5645_bst2_event(struct snd_soc_dapm_widget *w, |
1263 | struct snd_kcontrol *kcontrol, int event) | 1405 | struct snd_kcontrol *kcontrol, int event) |
1264 | { | 1406 | { |
1265 | struct snd_soc_codec *codec = w->codec; | 1407 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
1266 | 1408 | ||
1267 | switch (event) { | 1409 | switch (event) { |
1268 | case SND_SOC_DAPM_POST_PMU: | 1410 | case SND_SOC_DAPM_POST_PMU: |
@@ -1574,6 +1716,17 @@ static const struct snd_soc_dapm_widget rt5645_dapm_widgets[] = { | |||
1574 | SND_SOC_DAPM_OUTPUT("SPOR"), | 1716 | SND_SOC_DAPM_OUTPUT("SPOR"), |
1575 | }; | 1717 | }; |
1576 | 1718 | ||
1719 | static const struct snd_soc_dapm_widget rt5650_specific_dapm_widgets[] = { | ||
1720 | SND_SOC_DAPM_MUX("A DAC1 L Mux", SND_SOC_NOPM, | ||
1721 | 0, 0, &rt5650_a_dac1_l_mux), | ||
1722 | SND_SOC_DAPM_MUX("A DAC1 R Mux", SND_SOC_NOPM, | ||
1723 | 0, 0, &rt5650_a_dac1_r_mux), | ||
1724 | SND_SOC_DAPM_MUX("A DAC2 L Mux", SND_SOC_NOPM, | ||
1725 | 0, 0, &rt5650_a_dac2_l_mux), | ||
1726 | SND_SOC_DAPM_MUX("A DAC2 R Mux", SND_SOC_NOPM, | ||
1727 | 0, 0, &rt5650_a_dac2_r_mux), | ||
1728 | }; | ||
1729 | |||
1577 | static const struct snd_soc_dapm_route rt5645_dapm_routes[] = { | 1730 | static const struct snd_soc_dapm_route rt5645_dapm_routes[] = { |
1578 | { "adc stereo1 filter", NULL, "ADC STO1 ASRC", is_using_asrc }, | 1731 | { "adc stereo1 filter", NULL, "ADC STO1 ASRC", is_using_asrc }, |
1579 | { "adc stereo2 filter", NULL, "ADC STO2 ASRC", is_using_asrc }, | 1732 | { "adc stereo2 filter", NULL, "ADC STO2 ASRC", is_using_asrc }, |
@@ -1779,13 +1932,9 @@ static const struct snd_soc_dapm_route rt5645_dapm_routes[] = { | |||
1779 | { "DAC MIXR", "DAC R2 Switch", "DAC R2 Volume" }, | 1932 | { "DAC MIXR", "DAC R2 Switch", "DAC R2 Volume" }, |
1780 | { "DAC MIXR", "DAC L2 Switch", "DAC L2 Volume" }, | 1933 | { "DAC MIXR", "DAC L2 Switch", "DAC L2 Volume" }, |
1781 | 1934 | ||
1782 | { "DAC L1", NULL, "Stereo DAC MIXL" }, | ||
1783 | { "DAC L1", NULL, "PLL1", is_sys_clk_from_pll }, | 1935 | { "DAC L1", NULL, "PLL1", is_sys_clk_from_pll }, |
1784 | { "DAC R1", NULL, "Stereo DAC MIXR" }, | ||
1785 | { "DAC R1", NULL, "PLL1", is_sys_clk_from_pll }, | 1936 | { "DAC R1", NULL, "PLL1", is_sys_clk_from_pll }, |
1786 | { "DAC L2", NULL, "Mono DAC MIXL" }, | ||
1787 | { "DAC L2", NULL, "PLL1", is_sys_clk_from_pll }, | 1937 | { "DAC L2", NULL, "PLL1", is_sys_clk_from_pll }, |
1788 | { "DAC R2", NULL, "Mono DAC MIXR" }, | ||
1789 | { "DAC R2", NULL, "PLL1", is_sys_clk_from_pll }, | 1938 | { "DAC R2", NULL, "PLL1", is_sys_clk_from_pll }, |
1790 | 1939 | ||
1791 | { "SPK MIXL", "BST1 Switch", "BST1" }, | 1940 | { "SPK MIXL", "BST1 Switch", "BST1" }, |
@@ -1874,6 +2023,30 @@ static const struct snd_soc_dapm_route rt5645_dapm_routes[] = { | |||
1874 | { "SPOR", NULL, "SPK amp" }, | 2023 | { "SPOR", NULL, "SPK amp" }, |
1875 | }; | 2024 | }; |
1876 | 2025 | ||
2026 | static const struct snd_soc_dapm_route rt5650_specific_dapm_routes[] = { | ||
2027 | { "A DAC1 L Mux", "DAC1", "DAC1 MIXL"}, | ||
2028 | { "A DAC1 L Mux", "Stereo DAC Mixer", "Stereo DAC MIXL"}, | ||
2029 | { "A DAC1 R Mux", "DAC1", "DAC1 MIXR"}, | ||
2030 | { "A DAC1 R Mux", "Stereo DAC Mixer", "Stereo DAC MIXR"}, | ||
2031 | |||
2032 | { "A DAC2 L Mux", "Stereo DAC Mixer", "Stereo DAC MIXL"}, | ||
2033 | { "A DAC2 L Mux", "Mono DAC Mixer", "Mono DAC MIXL"}, | ||
2034 | { "A DAC2 R Mux", "Stereo DAC Mixer", "Stereo DAC MIXR"}, | ||
2035 | { "A DAC2 R Mux", "Mono DAC Mixer", "Mono DAC MIXR"}, | ||
2036 | |||
2037 | { "DAC L1", NULL, "A DAC1 L Mux" }, | ||
2038 | { "DAC R1", NULL, "A DAC1 R Mux" }, | ||
2039 | { "DAC L2", NULL, "A DAC2 L Mux" }, | ||
2040 | { "DAC R2", NULL, "A DAC2 R Mux" }, | ||
2041 | }; | ||
2042 | |||
2043 | static const struct snd_soc_dapm_route rt5645_specific_dapm_routes[] = { | ||
2044 | { "DAC L1", NULL, "Stereo DAC MIXL" }, | ||
2045 | { "DAC R1", NULL, "Stereo DAC MIXR" }, | ||
2046 | { "DAC L2", NULL, "Mono DAC MIXL" }, | ||
2047 | { "DAC R2", NULL, "Mono DAC MIXR" }, | ||
2048 | }; | ||
2049 | |||
1877 | static int rt5645_hw_params(struct snd_pcm_substream *substream, | 2050 | static int rt5645_hw_params(struct snd_pcm_substream *substream, |
1878 | struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) | 2051 | struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) |
1879 | { | 2052 | { |
@@ -2293,6 +2466,22 @@ static int rt5645_probe(struct snd_soc_codec *codec) | |||
2293 | 2466 | ||
2294 | rt5645->codec = codec; | 2467 | rt5645->codec = codec; |
2295 | 2468 | ||
2469 | switch (rt5645->codec_type) { | ||
2470 | case CODEC_TYPE_RT5645: | ||
2471 | snd_soc_dapm_add_routes(&codec->dapm, | ||
2472 | rt5645_specific_dapm_routes, | ||
2473 | ARRAY_SIZE(rt5645_specific_dapm_routes)); | ||
2474 | break; | ||
2475 | case CODEC_TYPE_RT5650: | ||
2476 | snd_soc_dapm_new_controls(&codec->dapm, | ||
2477 | rt5650_specific_dapm_widgets, | ||
2478 | ARRAY_SIZE(rt5650_specific_dapm_widgets)); | ||
2479 | snd_soc_dapm_add_routes(&codec->dapm, | ||
2480 | rt5650_specific_dapm_routes, | ||
2481 | ARRAY_SIZE(rt5650_specific_dapm_routes)); | ||
2482 | break; | ||
2483 | } | ||
2484 | |||
2296 | rt5645_set_bias_level(codec, SND_SOC_BIAS_OFF); | 2485 | rt5645_set_bias_level(codec, SND_SOC_BIAS_OFF); |
2297 | 2486 | ||
2298 | snd_soc_update_bits(codec, RT5645_CHARGE_PUMP, 0x0300, 0x0200); | 2487 | snd_soc_update_bits(codec, RT5645_CHARGE_PUMP, 0x0300, 0x0200); |
@@ -2424,6 +2613,7 @@ static const struct regmap_config rt5645_regmap = { | |||
2424 | 2613 | ||
2425 | static const struct i2c_device_id rt5645_i2c_id[] = { | 2614 | static const struct i2c_device_id rt5645_i2c_id[] = { |
2426 | { "rt5645", 0 }, | 2615 | { "rt5645", 0 }, |
2616 | { "rt5650", 0 }, | ||
2427 | { } | 2617 | { } |
2428 | }; | 2618 | }; |
2429 | MODULE_DEVICE_TABLE(i2c, rt5645_i2c_id); | 2619 | MODULE_DEVICE_TABLE(i2c, rt5645_i2c_id); |
@@ -2456,9 +2646,18 @@ static int rt5645_i2c_probe(struct i2c_client *i2c, | |||
2456 | } | 2646 | } |
2457 | 2647 | ||
2458 | regmap_read(rt5645->regmap, RT5645_VENDOR_ID2, &val); | 2648 | regmap_read(rt5645->regmap, RT5645_VENDOR_ID2, &val); |
2459 | if (val != RT5645_DEVICE_ID) { | 2649 | |
2650 | switch (val) { | ||
2651 | case RT5645_DEVICE_ID: | ||
2652 | rt5645->codec_type = CODEC_TYPE_RT5645; | ||
2653 | break; | ||
2654 | case RT5650_DEVICE_ID: | ||
2655 | rt5645->codec_type = CODEC_TYPE_RT5650; | ||
2656 | break; | ||
2657 | default: | ||
2460 | dev_err(&i2c->dev, | 2658 | dev_err(&i2c->dev, |
2461 | "Device with ID register %x is not rt5645\n", val); | 2659 | "Device with ID register %x is not rt5645 or rt5650\n", |
2660 | val); | ||
2462 | return -ENODEV; | 2661 | return -ENODEV; |
2463 | } | 2662 | } |
2464 | 2663 | ||
@@ -2469,6 +2668,14 @@ static int rt5645_i2c_probe(struct i2c_client *i2c, | |||
2469 | if (ret != 0) | 2668 | if (ret != 0) |
2470 | dev_warn(&i2c->dev, "Failed to apply regmap patch: %d\n", ret); | 2669 | dev_warn(&i2c->dev, "Failed to apply regmap patch: %d\n", ret); |
2471 | 2670 | ||
2671 | if (rt5645->codec_type == CODEC_TYPE_RT5650) { | ||
2672 | ret = regmap_register_patch(rt5645->regmap, rt5650_init_list, | ||
2673 | ARRAY_SIZE(rt5650_init_list)); | ||
2674 | if (ret != 0) | ||
2675 | dev_warn(&i2c->dev, "Apply rt5650 patch failed: %d\n", | ||
2676 | ret); | ||
2677 | } | ||
2678 | |||
2472 | if (rt5645->pdata.in2_diff) | 2679 | if (rt5645->pdata.in2_diff) |
2473 | regmap_update_bits(rt5645->regmap, RT5645_IN2_CTRL, | 2680 | regmap_update_bits(rt5645->regmap, RT5645_IN2_CTRL, |
2474 | RT5645_IN_DF2, RT5645_IN_DF2); | 2681 | RT5645_IN_DF2, RT5645_IN_DF2); |
diff --git a/sound/soc/codecs/rt5645.h b/sound/soc/codecs/rt5645.h index a815e36a2bdb..dbfd98c22f4d 100644 --- a/sound/soc/codecs/rt5645.h +++ b/sound/soc/codecs/rt5645.h | |||
@@ -47,6 +47,7 @@ | |||
47 | #define RT5645_STO_DAC_MIXER 0x2a | 47 | #define RT5645_STO_DAC_MIXER 0x2a |
48 | #define RT5645_MONO_DAC_MIXER 0x2b | 48 | #define RT5645_MONO_DAC_MIXER 0x2b |
49 | #define RT5645_DIG_MIXER 0x2c | 49 | #define RT5645_DIG_MIXER 0x2c |
50 | #define RT5650_A_DAC_SOUR 0x2d | ||
50 | #define RT5645_DIG_INF1_DATA 0x2f | 51 | #define RT5645_DIG_INF1_DATA 0x2f |
51 | /* Mixer - PDM */ | 52 | /* Mixer - PDM */ |
52 | #define RT5645_PDM_OUT_CTRL 0x31 | 53 | #define RT5645_PDM_OUT_CTRL 0x31 |
@@ -150,6 +151,8 @@ | |||
150 | #define RT5645_IL_CMD 0xdb | 151 | #define RT5645_IL_CMD 0xdb |
151 | #define RT5645_IL_CMD2 0xdc | 152 | #define RT5645_IL_CMD2 0xdc |
152 | #define RT5645_IL_CMD3 0xdd | 153 | #define RT5645_IL_CMD3 0xdd |
154 | #define RT5650_4BTN_IL_CMD1 0xdf | ||
155 | #define RT5650_4BTN_IL_CMD2 0xe0 | ||
153 | #define RT5645_DRC1_HL_CTRL1 0xe7 | 156 | #define RT5645_DRC1_HL_CTRL1 0xe7 |
154 | #define RT5645_DRC2_HL_CTRL1 0xe9 | 157 | #define RT5645_DRC2_HL_CTRL1 0xe9 |
155 | #define RT5645_MUTI_DRC_CTRL1 0xea | 158 | #define RT5645_MUTI_DRC_CTRL1 0xea |
@@ -472,6 +475,12 @@ | |||
472 | #define RT5645_DAC_L2_DAC_R_VOL_MASK (0x1 << 4) | 475 | #define RT5645_DAC_L2_DAC_R_VOL_MASK (0x1 << 4) |
473 | #define RT5645_DAC_L2_DAC_R_VOL_SFT 4 | 476 | #define RT5645_DAC_L2_DAC_R_VOL_SFT 4 |
474 | 477 | ||
478 | /* Analog DAC1/2 Input Source Control (0x2d) */ | ||
479 | #define RT5650_A_DAC1_L_IN_SFT 3 | ||
480 | #define RT5650_A_DAC1_R_IN_SFT 2 | ||
481 | #define RT5650_A_DAC2_L_IN_SFT 1 | ||
482 | #define RT5650_A_DAC2_R_IN_SFT 0 | ||
483 | |||
475 | /* Digital Interface Data Control (0x2f) */ | 484 | /* Digital Interface Data Control (0x2f) */ |
476 | #define RT5645_IF1_ADC2_IN_SEL (0x1 << 15) | 485 | #define RT5645_IF1_ADC2_IN_SEL (0x1 << 15) |
477 | #define RT5645_IF1_ADC2_IN_SFT 15 | 486 | #define RT5645_IF1_ADC2_IN_SFT 15 |
@@ -1111,50 +1120,27 @@ | |||
1111 | #define RT5645_DMIC_2_M_NOR (0x0 << 8) | 1120 | #define RT5645_DMIC_2_M_NOR (0x0 << 8) |
1112 | #define RT5645_DMIC_2_M_ASYN (0x1 << 8) | 1121 | #define RT5645_DMIC_2_M_ASYN (0x1 << 8) |
1113 | 1122 | ||
1123 | /* ASRC clock source selection (0x84, 0x85) */ | ||
1124 | #define RT5645_CLK_SEL_SYS (0x0) | ||
1125 | #define RT5645_CLK_SEL_I2S1_ASRC (0x1) | ||
1126 | #define RT5645_CLK_SEL_I2S2_ASRC (0x2) | ||
1127 | #define RT5645_CLK_SEL_SYS2 (0x5) | ||
1128 | |||
1114 | /* ASRC Control 2 (0x84) */ | 1129 | /* ASRC Control 2 (0x84) */ |
1115 | #define RT5645_MDA_L_M_MASK (0x1 << 15) | 1130 | #define RT5645_DA_STO_CLK_SEL_MASK (0xf << 12) |
1116 | #define RT5645_MDA_L_M_SFT 15 | 1131 | #define RT5645_DA_STO_CLK_SEL_SFT 12 |
1117 | #define RT5645_MDA_L_M_NOR (0x0 << 15) | 1132 | #define RT5645_DA_MONOL_CLK_SEL_MASK (0xf << 8) |
1118 | #define RT5645_MDA_L_M_ASYN (0x1 << 15) | 1133 | #define RT5645_DA_MONOL_CLK_SEL_SFT 8 |
1119 | #define RT5645_MDA_R_M_MASK (0x1 << 14) | 1134 | #define RT5645_DA_MONOR_CLK_SEL_MASK (0xf << 4) |
1120 | #define RT5645_MDA_R_M_SFT 14 | 1135 | #define RT5645_DA_MONOR_CLK_SEL_SFT 4 |
1121 | #define RT5645_MDA_R_M_NOR (0x0 << 14) | 1136 | #define RT5645_AD_STO1_CLK_SEL_MASK (0xf << 0) |
1122 | #define RT5645_MDA_R_M_ASYN (0x1 << 14) | 1137 | #define RT5645_AD_STO1_CLK_SEL_SFT 0 |
1123 | #define RT5645_MAD_L_M_MASK (0x1 << 13) | ||
1124 | #define RT5645_MAD_L_M_SFT 13 | ||
1125 | #define RT5645_MAD_L_M_NOR (0x0 << 13) | ||
1126 | #define RT5645_MAD_L_M_ASYN (0x1 << 13) | ||
1127 | #define RT5645_MAD_R_M_MASK (0x1 << 12) | ||
1128 | #define RT5645_MAD_R_M_SFT 12 | ||
1129 | #define RT5645_MAD_R_M_NOR (0x0 << 12) | ||
1130 | #define RT5645_MAD_R_M_ASYN (0x1 << 12) | ||
1131 | #define RT5645_ADC_M_MASK (0x1 << 11) | ||
1132 | #define RT5645_ADC_M_SFT 11 | ||
1133 | #define RT5645_ADC_M_NOR (0x0 << 11) | ||
1134 | #define RT5645_ADC_M_ASYN (0x1 << 11) | ||
1135 | #define RT5645_STO_DAC_M_MASK (0x1 << 5) | ||
1136 | #define RT5645_STO_DAC_M_SFT 5 | ||
1137 | #define RT5645_STO_DAC_M_NOR (0x0 << 5) | ||
1138 | #define RT5645_STO_DAC_M_ASYN (0x1 << 5) | ||
1139 | #define RT5645_I2S1_R_D_MASK (0x1 << 4) | ||
1140 | #define RT5645_I2S1_R_D_SFT 4 | ||
1141 | #define RT5645_I2S1_R_D_DIS (0x0 << 4) | ||
1142 | #define RT5645_I2S1_R_D_EN (0x1 << 4) | ||
1143 | #define RT5645_I2S2_R_D_MASK (0x1 << 3) | ||
1144 | #define RT5645_I2S2_R_D_SFT 3 | ||
1145 | #define RT5645_I2S2_R_D_DIS (0x0 << 3) | ||
1146 | #define RT5645_I2S2_R_D_EN (0x1 << 3) | ||
1147 | #define RT5645_PRE_SCLK_MASK (0x3) | ||
1148 | #define RT5645_PRE_SCLK_SFT 0 | ||
1149 | #define RT5645_PRE_SCLK_512 (0x0) | ||
1150 | #define RT5645_PRE_SCLK_1024 (0x1) | ||
1151 | #define RT5645_PRE_SCLK_2048 (0x2) | ||
1152 | 1138 | ||
1153 | /* ASRC Control 3 (0x85) */ | 1139 | /* ASRC Control 3 (0x85) */ |
1154 | #define RT5645_I2S1_RATE_MASK (0xf << 12) | 1140 | #define RT5645_AD_MONOL_CLK_SEL_MASK (0xf << 4) |
1155 | #define RT5645_I2S1_RATE_SFT 12 | 1141 | #define RT5645_AD_MONOL_CLK_SEL_SFT 4 |
1156 | #define RT5645_I2S2_RATE_MASK (0xf << 8) | 1142 | #define RT5645_AD_MONOR_CLK_SEL_MASK (0xf << 0) |
1157 | #define RT5645_I2S2_RATE_SFT 8 | 1143 | #define RT5645_AD_MONOR_CLK_SEL_SFT 0 |
1158 | 1144 | ||
1159 | /* ASRC Control 4 (0x89) */ | 1145 | /* ASRC Control 4 (0x89) */ |
1160 | #define RT5645_I2S1_PD_MASK (0x7 << 12) | 1146 | #define RT5645_I2S1_PD_MASK (0x7 << 12) |
@@ -2175,6 +2161,24 @@ enum { | |||
2175 | RT5645_DMIC_DATA_GPIO11, | 2161 | RT5645_DMIC_DATA_GPIO11, |
2176 | }; | 2162 | }; |
2177 | 2163 | ||
2164 | enum { | ||
2165 | CODEC_TYPE_RT5645, | ||
2166 | CODEC_TYPE_RT5650, | ||
2167 | }; | ||
2168 | |||
2169 | /* filter mask */ | ||
2170 | enum { | ||
2171 | RT5645_DA_STEREO_FILTER = 0x1, | ||
2172 | RT5645_DA_MONO_L_FILTER = (0x1 << 1), | ||
2173 | RT5645_DA_MONO_R_FILTER = (0x1 << 2), | ||
2174 | RT5645_AD_STEREO_FILTER = (0x1 << 3), | ||
2175 | RT5645_AD_MONO_L_FILTER = (0x1 << 4), | ||
2176 | RT5645_AD_MONO_R_FILTER = (0x1 << 5), | ||
2177 | }; | ||
2178 | |||
2179 | int rt5645_sel_asrc_clk_src(struct snd_soc_codec *codec, | ||
2180 | unsigned int filter_mask, unsigned int clk_src); | ||
2181 | |||
2178 | struct rt5645_priv { | 2182 | struct rt5645_priv { |
2179 | struct snd_soc_codec *codec; | 2183 | struct snd_soc_codec *codec; |
2180 | struct rt5645_platform_data pdata; | 2184 | struct rt5645_platform_data pdata; |
@@ -2184,6 +2188,7 @@ struct rt5645_priv { | |||
2184 | struct snd_soc_jack *mic_jack; | 2188 | struct snd_soc_jack *mic_jack; |
2185 | struct delayed_work jack_detect_work; | 2189 | struct delayed_work jack_detect_work; |
2186 | 2190 | ||
2191 | int codec_type; | ||
2187 | int sysclk; | 2192 | int sysclk; |
2188 | int sysclk_src; | 2193 | int sysclk_src; |
2189 | int lrck[RT5645_AIFS]; | 2194 | int lrck[RT5645_AIFS]; |
diff --git a/sound/soc/codecs/rt5651.c b/sound/soc/codecs/rt5651.c index bb0a3ab5416c..9f4c7be6d798 100644 --- a/sound/soc/codecs/rt5651.c +++ b/sound/soc/codecs/rt5651.c | |||
@@ -376,7 +376,7 @@ static const struct snd_kcontrol_new rt5651_snd_controls[] = { | |||
376 | static int set_dmic_clk(struct snd_soc_dapm_widget *w, | 376 | static int set_dmic_clk(struct snd_soc_dapm_widget *w, |
377 | struct snd_kcontrol *kcontrol, int event) | 377 | struct snd_kcontrol *kcontrol, int event) |
378 | { | 378 | { |
379 | struct snd_soc_codec *codec = w->codec; | 379 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
380 | struct rt5651_priv *rt5651 = snd_soc_codec_get_drvdata(codec); | 380 | struct rt5651_priv *rt5651 = snd_soc_codec_get_drvdata(codec); |
381 | int idx = -EINVAL; | 381 | int idx = -EINVAL; |
382 | 382 | ||
@@ -394,9 +394,10 @@ static int set_dmic_clk(struct snd_soc_dapm_widget *w, | |||
394 | static int is_sysclk_from_pll(struct snd_soc_dapm_widget *source, | 394 | static int is_sysclk_from_pll(struct snd_soc_dapm_widget *source, |
395 | struct snd_soc_dapm_widget *sink) | 395 | struct snd_soc_dapm_widget *sink) |
396 | { | 396 | { |
397 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm); | ||
397 | unsigned int val; | 398 | unsigned int val; |
398 | 399 | ||
399 | val = snd_soc_read(source->codec, RT5651_GLB_CLK); | 400 | val = snd_soc_read(codec, RT5651_GLB_CLK); |
400 | val &= RT5651_SCLK_SRC_MASK; | 401 | val &= RT5651_SCLK_SRC_MASK; |
401 | if (val == RT5651_SCLK_SRC_PLL1) | 402 | if (val == RT5651_SCLK_SRC_PLL1) |
402 | return 1; | 403 | return 1; |
@@ -731,7 +732,7 @@ static const struct snd_kcontrol_new rt5651_pdm_r_mux = | |||
731 | static int rt5651_amp_power_event(struct snd_soc_dapm_widget *w, | 732 | static int rt5651_amp_power_event(struct snd_soc_dapm_widget *w, |
732 | struct snd_kcontrol *kcontrol, int event) | 733 | struct snd_kcontrol *kcontrol, int event) |
733 | { | 734 | { |
734 | struct snd_soc_codec *codec = w->codec; | 735 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
735 | struct rt5651_priv *rt5651 = snd_soc_codec_get_drvdata(codec); | 736 | struct rt5651_priv *rt5651 = snd_soc_codec_get_drvdata(codec); |
736 | 737 | ||
737 | switch (event) { | 738 | switch (event) { |
@@ -769,7 +770,7 @@ static int rt5651_amp_power_event(struct snd_soc_dapm_widget *w, | |||
769 | static int rt5651_hp_event(struct snd_soc_dapm_widget *w, | 770 | static int rt5651_hp_event(struct snd_soc_dapm_widget *w, |
770 | struct snd_kcontrol *kcontrol, int event) | 771 | struct snd_kcontrol *kcontrol, int event) |
771 | { | 772 | { |
772 | struct snd_soc_codec *codec = w->codec; | 773 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
773 | struct rt5651_priv *rt5651 = snd_soc_codec_get_drvdata(codec); | 774 | struct rt5651_priv *rt5651 = snd_soc_codec_get_drvdata(codec); |
774 | 775 | ||
775 | switch (event) { | 776 | switch (event) { |
@@ -813,7 +814,8 @@ static int rt5651_hp_event(struct snd_soc_dapm_widget *w, | |||
813 | static int rt5651_hp_post_event(struct snd_soc_dapm_widget *w, | 814 | static int rt5651_hp_post_event(struct snd_soc_dapm_widget *w, |
814 | struct snd_kcontrol *kcontrol, int event) | 815 | struct snd_kcontrol *kcontrol, int event) |
815 | { | 816 | { |
816 | struct snd_soc_codec *codec = w->codec; | 817 | |
818 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); | ||
817 | struct rt5651_priv *rt5651 = snd_soc_codec_get_drvdata(codec); | 819 | struct rt5651_priv *rt5651 = snd_soc_codec_get_drvdata(codec); |
818 | 820 | ||
819 | switch (event) { | 821 | switch (event) { |
@@ -833,7 +835,7 @@ static int rt5651_hp_post_event(struct snd_soc_dapm_widget *w, | |||
833 | static int rt5651_bst1_event(struct snd_soc_dapm_widget *w, | 835 | static int rt5651_bst1_event(struct snd_soc_dapm_widget *w, |
834 | struct snd_kcontrol *kcontrol, int event) | 836 | struct snd_kcontrol *kcontrol, int event) |
835 | { | 837 | { |
836 | struct snd_soc_codec *codec = w->codec; | 838 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
837 | 839 | ||
838 | switch (event) { | 840 | switch (event) { |
839 | case SND_SOC_DAPM_POST_PMU: | 841 | case SND_SOC_DAPM_POST_PMU: |
@@ -856,7 +858,7 @@ static int rt5651_bst1_event(struct snd_soc_dapm_widget *w, | |||
856 | static int rt5651_bst2_event(struct snd_soc_dapm_widget *w, | 858 | static int rt5651_bst2_event(struct snd_soc_dapm_widget *w, |
857 | struct snd_kcontrol *kcontrol, int event) | 859 | struct snd_kcontrol *kcontrol, int event) |
858 | { | 860 | { |
859 | struct snd_soc_codec *codec = w->codec; | 861 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
860 | 862 | ||
861 | switch (event) { | 863 | switch (event) { |
862 | case SND_SOC_DAPM_POST_PMU: | 864 | case SND_SOC_DAPM_POST_PMU: |
@@ -879,7 +881,7 @@ static int rt5651_bst2_event(struct snd_soc_dapm_widget *w, | |||
879 | static int rt5651_bst3_event(struct snd_soc_dapm_widget *w, | 881 | static int rt5651_bst3_event(struct snd_soc_dapm_widget *w, |
880 | struct snd_kcontrol *kcontrol, int event) | 882 | struct snd_kcontrol *kcontrol, int event) |
881 | { | 883 | { |
882 | struct snd_soc_codec *codec = w->codec; | 884 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
883 | 885 | ||
884 | switch (event) { | 886 | switch (event) { |
885 | case SND_SOC_DAPM_POST_PMU: | 887 | case SND_SOC_DAPM_POST_PMU: |
diff --git a/sound/soc/codecs/rt5670.c b/sound/soc/codecs/rt5670.c index 8a0833de1665..e1a4a45c57e2 100644 --- a/sound/soc/codecs/rt5670.c +++ b/sound/soc/codecs/rt5670.c | |||
@@ -14,10 +14,12 @@ | |||
14 | #include <linux/init.h> | 14 | #include <linux/init.h> |
15 | #include <linux/delay.h> | 15 | #include <linux/delay.h> |
16 | #include <linux/pm.h> | 16 | #include <linux/pm.h> |
17 | #include <linux/pm_runtime.h> | ||
17 | #include <linux/i2c.h> | 18 | #include <linux/i2c.h> |
18 | #include <linux/platform_device.h> | 19 | #include <linux/platform_device.h> |
19 | #include <linux/acpi.h> | 20 | #include <linux/acpi.h> |
20 | #include <linux/spi/spi.h> | 21 | #include <linux/spi/spi.h> |
22 | #include <linux/dmi.h> | ||
21 | #include <sound/core.h> | 23 | #include <sound/core.h> |
22 | #include <sound/pcm.h> | 24 | #include <sound/pcm.h> |
23 | #include <sound/pcm_params.h> | 25 | #include <sound/pcm_params.h> |
@@ -498,7 +500,7 @@ static const struct snd_kcontrol_new rt5670_snd_controls[] = { | |||
498 | static int set_dmic_clk(struct snd_soc_dapm_widget *w, | 500 | static int set_dmic_clk(struct snd_soc_dapm_widget *w, |
499 | struct snd_kcontrol *kcontrol, int event) | 501 | struct snd_kcontrol *kcontrol, int event) |
500 | { | 502 | { |
501 | struct snd_soc_codec *codec = w->codec; | 503 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
502 | struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec); | 504 | struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec); |
503 | int idx = -EINVAL; | 505 | int idx = -EINVAL; |
504 | 506 | ||
@@ -515,9 +517,10 @@ static int set_dmic_clk(struct snd_soc_dapm_widget *w, | |||
515 | static int is_sys_clk_from_pll(struct snd_soc_dapm_widget *source, | 517 | static int is_sys_clk_from_pll(struct snd_soc_dapm_widget *source, |
516 | struct snd_soc_dapm_widget *sink) | 518 | struct snd_soc_dapm_widget *sink) |
517 | { | 519 | { |
520 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm); | ||
518 | unsigned int val; | 521 | unsigned int val; |
519 | 522 | ||
520 | val = snd_soc_read(source->codec, RT5670_GLB_CLK); | 523 | val = snd_soc_read(codec, RT5670_GLB_CLK); |
521 | val &= RT5670_SCLK_SRC_MASK; | 524 | val &= RT5670_SCLK_SRC_MASK; |
522 | if (val == RT5670_SCLK_SRC_PLL1) | 525 | if (val == RT5670_SCLK_SRC_PLL1) |
523 | return 1; | 526 | return 1; |
@@ -528,6 +531,7 @@ static int is_sys_clk_from_pll(struct snd_soc_dapm_widget *source, | |||
528 | static int is_using_asrc(struct snd_soc_dapm_widget *source, | 531 | static int is_using_asrc(struct snd_soc_dapm_widget *source, |
529 | struct snd_soc_dapm_widget *sink) | 532 | struct snd_soc_dapm_widget *sink) |
530 | { | 533 | { |
534 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm); | ||
531 | unsigned int reg, shift, val; | 535 | unsigned int reg, shift, val; |
532 | 536 | ||
533 | switch (source->shift) { | 537 | switch (source->shift) { |
@@ -563,7 +567,7 @@ static int is_using_asrc(struct snd_soc_dapm_widget *source, | |||
563 | return 0; | 567 | return 0; |
564 | } | 568 | } |
565 | 569 | ||
566 | val = (snd_soc_read(source->codec, reg) >> shift) & 0xf; | 570 | val = (snd_soc_read(codec, reg) >> shift) & 0xf; |
567 | switch (val) { | 571 | switch (val) { |
568 | case 1: | 572 | case 1: |
569 | case 2: | 573 | case 2: |
@@ -588,6 +592,89 @@ static int can_use_asrc(struct snd_soc_dapm_widget *source, | |||
588 | return 0; | 592 | return 0; |
589 | } | 593 | } |
590 | 594 | ||
595 | |||
596 | /** | ||
597 | * rt5670_sel_asrc_clk_src - select ASRC clock source for a set of filters | ||
598 | * @codec: SoC audio codec device. | ||
599 | * @filter_mask: mask of filters. | ||
600 | * @clk_src: clock source | ||
601 | * | ||
602 | * The ASRC function is for asynchronous MCLK and LRCK. Also, since RT5670 can | ||
603 | * only support standard 32fs or 64fs i2s format, ASRC should be enabled to | ||
604 | * support special i2s clock format such as Intel's 100fs(100 * sampling rate). | ||
605 | * ASRC function will track i2s clock and generate a corresponding system clock | ||
606 | * for codec. This function provides an API to select the clock source for a | ||
607 | * set of filters specified by the mask. And the codec driver will turn on ASRC | ||
608 | * for these filters if ASRC is selected as their clock source. | ||
609 | */ | ||
610 | int rt5670_sel_asrc_clk_src(struct snd_soc_codec *codec, | ||
611 | unsigned int filter_mask, unsigned int clk_src) | ||
612 | { | ||
613 | unsigned int asrc2_mask = 0, asrc2_value = 0; | ||
614 | unsigned int asrc3_mask = 0, asrc3_value = 0; | ||
615 | |||
616 | if (clk_src > RT5670_CLK_SEL_SYS3) | ||
617 | return -EINVAL; | ||
618 | |||
619 | if (filter_mask & RT5670_DA_STEREO_FILTER) { | ||
620 | asrc2_mask |= RT5670_DA_STO_CLK_SEL_MASK; | ||
621 | asrc2_value = (asrc2_value & ~RT5670_DA_STO_CLK_SEL_MASK) | ||
622 | | (clk_src << RT5670_DA_STO_CLK_SEL_SFT); | ||
623 | } | ||
624 | |||
625 | if (filter_mask & RT5670_DA_MONO_L_FILTER) { | ||
626 | asrc2_mask |= RT5670_DA_MONOL_CLK_SEL_MASK; | ||
627 | asrc2_value = (asrc2_value & ~RT5670_DA_MONOL_CLK_SEL_MASK) | ||
628 | | (clk_src << RT5670_DA_MONOL_CLK_SEL_SFT); | ||
629 | } | ||
630 | |||
631 | if (filter_mask & RT5670_DA_MONO_R_FILTER) { | ||
632 | asrc2_mask |= RT5670_DA_MONOR_CLK_SEL_MASK; | ||
633 | asrc2_value = (asrc2_value & ~RT5670_DA_MONOR_CLK_SEL_MASK) | ||
634 | | (clk_src << RT5670_DA_MONOR_CLK_SEL_SFT); | ||
635 | } | ||
636 | |||
637 | if (filter_mask & RT5670_AD_STEREO_FILTER) { | ||
638 | asrc2_mask |= RT5670_AD_STO1_CLK_SEL_MASK; | ||
639 | asrc2_value = (asrc2_value & ~RT5670_AD_STO1_CLK_SEL_MASK) | ||
640 | | (clk_src << RT5670_AD_STO1_CLK_SEL_SFT); | ||
641 | } | ||
642 | |||
643 | if (filter_mask & RT5670_AD_MONO_L_FILTER) { | ||
644 | asrc3_mask |= RT5670_AD_MONOL_CLK_SEL_MASK; | ||
645 | asrc3_value = (asrc3_value & ~RT5670_AD_MONOL_CLK_SEL_MASK) | ||
646 | | (clk_src << RT5670_AD_MONOL_CLK_SEL_SFT); | ||
647 | } | ||
648 | |||
649 | if (filter_mask & RT5670_AD_MONO_R_FILTER) { | ||
650 | asrc3_mask |= RT5670_AD_MONOR_CLK_SEL_MASK; | ||
651 | asrc3_value = (asrc3_value & ~RT5670_AD_MONOR_CLK_SEL_MASK) | ||
652 | | (clk_src << RT5670_AD_MONOR_CLK_SEL_SFT); | ||
653 | } | ||
654 | |||
655 | if (filter_mask & RT5670_UP_RATE_FILTER) { | ||
656 | asrc3_mask |= RT5670_UP_CLK_SEL_MASK; | ||
657 | asrc3_value = (asrc3_value & ~RT5670_UP_CLK_SEL_MASK) | ||
658 | | (clk_src << RT5670_UP_CLK_SEL_SFT); | ||
659 | } | ||
660 | |||
661 | if (filter_mask & RT5670_DOWN_RATE_FILTER) { | ||
662 | asrc3_mask |= RT5670_DOWN_CLK_SEL_MASK; | ||
663 | asrc3_value = (asrc3_value & ~RT5670_DOWN_CLK_SEL_MASK) | ||
664 | | (clk_src << RT5670_DOWN_CLK_SEL_SFT); | ||
665 | } | ||
666 | |||
667 | if (asrc2_mask) | ||
668 | snd_soc_update_bits(codec, RT5670_ASRC_2, | ||
669 | asrc2_mask, asrc2_value); | ||
670 | |||
671 | if (asrc3_mask) | ||
672 | snd_soc_update_bits(codec, RT5670_ASRC_3, | ||
673 | asrc3_mask, asrc3_value); | ||
674 | return 0; | ||
675 | } | ||
676 | EXPORT_SYMBOL_GPL(rt5670_sel_asrc_clk_src); | ||
677 | |||
591 | /* Digital Mixer */ | 678 | /* Digital Mixer */ |
592 | static const struct snd_kcontrol_new rt5670_sto1_adc_l_mix[] = { | 679 | static const struct snd_kcontrol_new rt5670_sto1_adc_l_mix[] = { |
593 | SOC_DAPM_SINGLE("ADC1 Switch", RT5670_STO1_ADC_MIXER, | 680 | SOC_DAPM_SINGLE("ADC1 Switch", RT5670_STO1_ADC_MIXER, |
@@ -1146,7 +1233,7 @@ static const struct snd_kcontrol_new rt5670_vad_adc_mux = | |||
1146 | static int rt5670_hp_power_event(struct snd_soc_dapm_widget *w, | 1233 | static int rt5670_hp_power_event(struct snd_soc_dapm_widget *w, |
1147 | struct snd_kcontrol *kcontrol, int event) | 1234 | struct snd_kcontrol *kcontrol, int event) |
1148 | { | 1235 | { |
1149 | struct snd_soc_codec *codec = w->codec; | 1236 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
1150 | struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec); | 1237 | struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec); |
1151 | 1238 | ||
1152 | switch (event) { | 1239 | switch (event) { |
@@ -1182,7 +1269,7 @@ static int rt5670_hp_power_event(struct snd_soc_dapm_widget *w, | |||
1182 | static int rt5670_hp_event(struct snd_soc_dapm_widget *w, | 1269 | static int rt5670_hp_event(struct snd_soc_dapm_widget *w, |
1183 | struct snd_kcontrol *kcontrol, int event) | 1270 | struct snd_kcontrol *kcontrol, int event) |
1184 | { | 1271 | { |
1185 | struct snd_soc_codec *codec = w->codec; | 1272 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
1186 | struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec); | 1273 | struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec); |
1187 | 1274 | ||
1188 | switch (event) { | 1275 | switch (event) { |
@@ -1232,7 +1319,7 @@ static int rt5670_hp_event(struct snd_soc_dapm_widget *w, | |||
1232 | static int rt5670_bst1_event(struct snd_soc_dapm_widget *w, | 1319 | static int rt5670_bst1_event(struct snd_soc_dapm_widget *w, |
1233 | struct snd_kcontrol *kcontrol, int event) | 1320 | struct snd_kcontrol *kcontrol, int event) |
1234 | { | 1321 | { |
1235 | struct snd_soc_codec *codec = w->codec; | 1322 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
1236 | 1323 | ||
1237 | switch (event) { | 1324 | switch (event) { |
1238 | case SND_SOC_DAPM_POST_PMU: | 1325 | case SND_SOC_DAPM_POST_PMU: |
@@ -1255,7 +1342,7 @@ static int rt5670_bst1_event(struct snd_soc_dapm_widget *w, | |||
1255 | static int rt5670_bst2_event(struct snd_soc_dapm_widget *w, | 1342 | static int rt5670_bst2_event(struct snd_soc_dapm_widget *w, |
1256 | struct snd_kcontrol *kcontrol, int event) | 1343 | struct snd_kcontrol *kcontrol, int event) |
1257 | { | 1344 | { |
1258 | struct snd_soc_codec *codec = w->codec; | 1345 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
1259 | 1346 | ||
1260 | switch (event) { | 1347 | switch (event) { |
1261 | case SND_SOC_DAPM_POST_PMU: | 1348 | case SND_SOC_DAPM_POST_PMU: |
@@ -2188,6 +2275,13 @@ static int rt5670_set_dai_sysclk(struct snd_soc_dai *dai, | |||
2188 | if (freq == rt5670->sysclk && clk_id == rt5670->sysclk_src) | 2275 | if (freq == rt5670->sysclk && clk_id == rt5670->sysclk_src) |
2189 | return 0; | 2276 | return 0; |
2190 | 2277 | ||
2278 | if (rt5670->pdata.jd_mode) { | ||
2279 | if (clk_id == RT5670_SCLK_S_PLL1) | ||
2280 | snd_soc_dapm_force_enable_pin(&codec->dapm, "PLL1"); | ||
2281 | else | ||
2282 | snd_soc_dapm_disable_pin(&codec->dapm, "PLL1"); | ||
2283 | snd_soc_dapm_sync(&codec->dapm); | ||
2284 | } | ||
2191 | switch (clk_id) { | 2285 | switch (clk_id) { |
2192 | case RT5670_SCLK_S_MCLK: | 2286 | case RT5670_SCLK_S_MCLK: |
2193 | reg_val |= RT5670_SCLK_SRC_MCLK; | 2287 | reg_val |= RT5670_SCLK_SRC_MCLK; |
@@ -2522,6 +2616,7 @@ static struct snd_soc_codec_driver soc_codec_dev_rt5670 = { | |||
2522 | static const struct regmap_config rt5670_regmap = { | 2616 | static const struct regmap_config rt5670_regmap = { |
2523 | .reg_bits = 8, | 2617 | .reg_bits = 8, |
2524 | .val_bits = 16, | 2618 | .val_bits = 16, |
2619 | .use_single_rw = true, | ||
2525 | .max_register = RT5670_VENDOR_ID2 + 1 + (ARRAY_SIZE(rt5670_ranges) * | 2620 | .max_register = RT5670_VENDOR_ID2 + 1 + (ARRAY_SIZE(rt5670_ranges) * |
2526 | RT5670_PR_SPACING), | 2621 | RT5670_PR_SPACING), |
2527 | .volatile_reg = rt5670_volatile_register, | 2622 | .volatile_reg = rt5670_volatile_register, |
@@ -2549,6 +2644,17 @@ static struct acpi_device_id rt5670_acpi_match[] = { | |||
2549 | MODULE_DEVICE_TABLE(acpi, rt5670_acpi_match); | 2644 | MODULE_DEVICE_TABLE(acpi, rt5670_acpi_match); |
2550 | #endif | 2645 | #endif |
2551 | 2646 | ||
2647 | static const struct dmi_system_id dmi_platform_intel_braswell[] = { | ||
2648 | { | ||
2649 | .ident = "Intel Braswell", | ||
2650 | .matches = { | ||
2651 | DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"), | ||
2652 | DMI_MATCH(DMI_BOARD_NAME, "Braswell CRB"), | ||
2653 | }, | ||
2654 | }, | ||
2655 | {} | ||
2656 | }; | ||
2657 | |||
2552 | static int rt5670_i2c_probe(struct i2c_client *i2c, | 2658 | static int rt5670_i2c_probe(struct i2c_client *i2c, |
2553 | const struct i2c_device_id *id) | 2659 | const struct i2c_device_id *id) |
2554 | { | 2660 | { |
@@ -2568,6 +2674,12 @@ static int rt5670_i2c_probe(struct i2c_client *i2c, | |||
2568 | if (pdata) | 2674 | if (pdata) |
2569 | rt5670->pdata = *pdata; | 2675 | rt5670->pdata = *pdata; |
2570 | 2676 | ||
2677 | if (dmi_check_system(dmi_platform_intel_braswell)) { | ||
2678 | rt5670->pdata.dmic_en = true; | ||
2679 | rt5670->pdata.dmic1_data_pin = RT5670_DMIC_DATA_IN2P; | ||
2680 | rt5670->pdata.jd_mode = 1; | ||
2681 | } | ||
2682 | |||
2571 | rt5670->regmap = devm_regmap_init_i2c(i2c, &rt5670_regmap); | 2683 | rt5670->regmap = devm_regmap_init_i2c(i2c, &rt5670_regmap); |
2572 | if (IS_ERR(rt5670->regmap)) { | 2684 | if (IS_ERR(rt5670->regmap)) { |
2573 | ret = PTR_ERR(rt5670->regmap); | 2685 | ret = PTR_ERR(rt5670->regmap); |
@@ -2609,6 +2721,10 @@ static int rt5670_i2c_probe(struct i2c_client *i2c, | |||
2609 | } | 2721 | } |
2610 | 2722 | ||
2611 | if (rt5670->pdata.jd_mode) { | 2723 | if (rt5670->pdata.jd_mode) { |
2724 | regmap_update_bits(rt5670->regmap, RT5670_GLB_CLK, | ||
2725 | RT5670_SCLK_SRC_MASK, RT5670_SCLK_SRC_RCCLK); | ||
2726 | rt5670->sysclk = 0; | ||
2727 | rt5670->sysclk_src = RT5670_SCLK_S_RCCLK; | ||
2612 | regmap_update_bits(rt5670->regmap, RT5670_PWR_ANLG1, | 2728 | regmap_update_bits(rt5670->regmap, RT5670_PWR_ANLG1, |
2613 | RT5670_PWR_MB, RT5670_PWR_MB); | 2729 | RT5670_PWR_MB, RT5670_PWR_MB); |
2614 | regmap_update_bits(rt5670->regmap, RT5670_PWR_ANLG2, | 2730 | regmap_update_bits(rt5670->regmap, RT5670_PWR_ANLG2, |
@@ -2716,18 +2832,26 @@ static int rt5670_i2c_probe(struct i2c_client *i2c, | |||
2716 | 2832 | ||
2717 | } | 2833 | } |
2718 | 2834 | ||
2835 | pm_runtime_enable(&i2c->dev); | ||
2836 | pm_request_idle(&i2c->dev); | ||
2837 | |||
2719 | ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5670, | 2838 | ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5670, |
2720 | rt5670_dai, ARRAY_SIZE(rt5670_dai)); | 2839 | rt5670_dai, ARRAY_SIZE(rt5670_dai)); |
2721 | if (ret < 0) | 2840 | if (ret < 0) |
2722 | goto err; | 2841 | goto err; |
2723 | 2842 | ||
2843 | pm_runtime_put(&i2c->dev); | ||
2844 | |||
2724 | return 0; | 2845 | return 0; |
2725 | err: | 2846 | err: |
2847 | pm_runtime_disable(&i2c->dev); | ||
2848 | |||
2726 | return ret; | 2849 | return ret; |
2727 | } | 2850 | } |
2728 | 2851 | ||
2729 | static int rt5670_i2c_remove(struct i2c_client *i2c) | 2852 | static int rt5670_i2c_remove(struct i2c_client *i2c) |
2730 | { | 2853 | { |
2854 | pm_runtime_disable(&i2c->dev); | ||
2731 | snd_soc_unregister_codec(&i2c->dev); | 2855 | snd_soc_unregister_codec(&i2c->dev); |
2732 | 2856 | ||
2733 | return 0; | 2857 | return 0; |
diff --git a/sound/soc/codecs/rt5670.h b/sound/soc/codecs/rt5670.h index d11b9c207e26..21f8e18c13c4 100644 --- a/sound/soc/codecs/rt5670.h +++ b/sound/soc/codecs/rt5670.h | |||
@@ -1023,50 +1023,33 @@ | |||
1023 | #define RT5670_DMIC_2_M_NOR (0x0 << 8) | 1023 | #define RT5670_DMIC_2_M_NOR (0x0 << 8) |
1024 | #define RT5670_DMIC_2_M_ASYN (0x1 << 8) | 1024 | #define RT5670_DMIC_2_M_ASYN (0x1 << 8) |
1025 | 1025 | ||
1026 | /* ASRC clock source selection (0x84, 0x85) */ | ||
1027 | #define RT5670_CLK_SEL_SYS (0x0) | ||
1028 | #define RT5670_CLK_SEL_I2S1_ASRC (0x1) | ||
1029 | #define RT5670_CLK_SEL_I2S2_ASRC (0x2) | ||
1030 | #define RT5670_CLK_SEL_I2S3_ASRC (0x3) | ||
1031 | #define RT5670_CLK_SEL_SYS2 (0x5) | ||
1032 | #define RT5670_CLK_SEL_SYS3 (0x6) | ||
1033 | |||
1026 | /* ASRC Control 2 (0x84) */ | 1034 | /* ASRC Control 2 (0x84) */ |
1027 | #define RT5670_MDA_L_M_MASK (0x1 << 15) | 1035 | #define RT5670_DA_STO_CLK_SEL_MASK (0xf << 12) |
1028 | #define RT5670_MDA_L_M_SFT 15 | 1036 | #define RT5670_DA_STO_CLK_SEL_SFT 12 |
1029 | #define RT5670_MDA_L_M_NOR (0x0 << 15) | 1037 | #define RT5670_DA_MONOL_CLK_SEL_MASK (0xf << 8) |
1030 | #define RT5670_MDA_L_M_ASYN (0x1 << 15) | 1038 | #define RT5670_DA_MONOL_CLK_SEL_SFT 8 |
1031 | #define RT5670_MDA_R_M_MASK (0x1 << 14) | 1039 | #define RT5670_DA_MONOR_CLK_SEL_MASK (0xf << 4) |
1032 | #define RT5670_MDA_R_M_SFT 14 | 1040 | #define RT5670_DA_MONOR_CLK_SEL_SFT 4 |
1033 | #define RT5670_MDA_R_M_NOR (0x0 << 14) | 1041 | #define RT5670_AD_STO1_CLK_SEL_MASK (0xf << 0) |
1034 | #define RT5670_MDA_R_M_ASYN (0x1 << 14) | 1042 | #define RT5670_AD_STO1_CLK_SEL_SFT 0 |
1035 | #define RT5670_MAD_L_M_MASK (0x1 << 13) | ||
1036 | #define RT5670_MAD_L_M_SFT 13 | ||
1037 | #define RT5670_MAD_L_M_NOR (0x0 << 13) | ||
1038 | #define RT5670_MAD_L_M_ASYN (0x1 << 13) | ||
1039 | #define RT5670_MAD_R_M_MASK (0x1 << 12) | ||
1040 | #define RT5670_MAD_R_M_SFT 12 | ||
1041 | #define RT5670_MAD_R_M_NOR (0x0 << 12) | ||
1042 | #define RT5670_MAD_R_M_ASYN (0x1 << 12) | ||
1043 | #define RT5670_ADC_M_MASK (0x1 << 11) | ||
1044 | #define RT5670_ADC_M_SFT 11 | ||
1045 | #define RT5670_ADC_M_NOR (0x0 << 11) | ||
1046 | #define RT5670_ADC_M_ASYN (0x1 << 11) | ||
1047 | #define RT5670_STO_DAC_M_MASK (0x1 << 5) | ||
1048 | #define RT5670_STO_DAC_M_SFT 5 | ||
1049 | #define RT5670_STO_DAC_M_NOR (0x0 << 5) | ||
1050 | #define RT5670_STO_DAC_M_ASYN (0x1 << 5) | ||
1051 | #define RT5670_I2S1_R_D_MASK (0x1 << 4) | ||
1052 | #define RT5670_I2S1_R_D_SFT 4 | ||
1053 | #define RT5670_I2S1_R_D_DIS (0x0 << 4) | ||
1054 | #define RT5670_I2S1_R_D_EN (0x1 << 4) | ||
1055 | #define RT5670_I2S2_R_D_MASK (0x1 << 3) | ||
1056 | #define RT5670_I2S2_R_D_SFT 3 | ||
1057 | #define RT5670_I2S2_R_D_DIS (0x0 << 3) | ||
1058 | #define RT5670_I2S2_R_D_EN (0x1 << 3) | ||
1059 | #define RT5670_PRE_SCLK_MASK (0x3) | ||
1060 | #define RT5670_PRE_SCLK_SFT 0 | ||
1061 | #define RT5670_PRE_SCLK_512 (0x0) | ||
1062 | #define RT5670_PRE_SCLK_1024 (0x1) | ||
1063 | #define RT5670_PRE_SCLK_2048 (0x2) | ||
1064 | 1043 | ||
1065 | /* ASRC Control 3 (0x85) */ | 1044 | /* ASRC Control 3 (0x85) */ |
1066 | #define RT5670_I2S1_RATE_MASK (0xf << 12) | 1045 | #define RT5670_UP_CLK_SEL_MASK (0xf << 12) |
1067 | #define RT5670_I2S1_RATE_SFT 12 | 1046 | #define RT5670_UP_CLK_SEL_SFT 12 |
1068 | #define RT5670_I2S2_RATE_MASK (0xf << 8) | 1047 | #define RT5670_DOWN_CLK_SEL_MASK (0xf << 8) |
1069 | #define RT5670_I2S2_RATE_SFT 8 | 1048 | #define RT5670_DOWN_CLK_SEL_SFT 8 |
1049 | #define RT5670_AD_MONOL_CLK_SEL_MASK (0xf << 4) | ||
1050 | #define RT5670_AD_MONOL_CLK_SEL_SFT 4 | ||
1051 | #define RT5670_AD_MONOR_CLK_SEL_MASK (0xf << 0) | ||
1052 | #define RT5670_AD_MONOR_CLK_SEL_SFT 0 | ||
1070 | 1053 | ||
1071 | /* ASRC Control 4 (0x89) */ | 1054 | /* ASRC Control 4 (0x89) */ |
1072 | #define RT5670_I2S1_PD_MASK (0x7 << 12) | 1055 | #define RT5670_I2S1_PD_MASK (0x7 << 12) |
@@ -1983,6 +1966,21 @@ enum { | |||
1983 | RT5670_DMIC_DATA_GPIO5, | 1966 | RT5670_DMIC_DATA_GPIO5, |
1984 | }; | 1967 | }; |
1985 | 1968 | ||
1969 | /* filter mask */ | ||
1970 | enum { | ||
1971 | RT5670_DA_STEREO_FILTER = 0x1, | ||
1972 | RT5670_DA_MONO_L_FILTER = (0x1 << 1), | ||
1973 | RT5670_DA_MONO_R_FILTER = (0x1 << 2), | ||
1974 | RT5670_AD_STEREO_FILTER = (0x1 << 3), | ||
1975 | RT5670_AD_MONO_L_FILTER = (0x1 << 4), | ||
1976 | RT5670_AD_MONO_R_FILTER = (0x1 << 5), | ||
1977 | RT5670_UP_RATE_FILTER = (0x1 << 6), | ||
1978 | RT5670_DOWN_RATE_FILTER = (0x1 << 7), | ||
1979 | }; | ||
1980 | |||
1981 | int rt5670_sel_asrc_clk_src(struct snd_soc_codec *codec, | ||
1982 | unsigned int filter_mask, unsigned int clk_src); | ||
1983 | |||
1986 | struct rt5670_priv { | 1984 | struct rt5670_priv { |
1987 | struct snd_soc_codec *codec; | 1985 | struct snd_soc_codec *codec; |
1988 | struct rt5670_platform_data pdata; | 1986 | struct rt5670_platform_data pdata; |
diff --git a/sound/soc/codecs/rt5677.c b/sound/soc/codecs/rt5677.c index 81fe1464d268..5d0bb8748dd1 100644 --- a/sound/soc/codecs/rt5677.c +++ b/sound/soc/codecs/rt5677.c | |||
@@ -702,6 +702,9 @@ static int rt5677_set_dsp_vad(struct snd_soc_codec *codec, bool on) | |||
702 | static bool activity; | 702 | static bool activity; |
703 | int ret; | 703 | int ret; |
704 | 704 | ||
705 | if (!IS_ENABLED(CONFIG_SND_SOC_RT5677_SPI)) | ||
706 | return -ENXIO; | ||
707 | |||
705 | if (on && !activity) { | 708 | if (on && !activity) { |
706 | activity = true; | 709 | activity = true; |
707 | 710 | ||
@@ -784,8 +787,8 @@ static unsigned int bst_tlv[] = { | |||
784 | static int rt5677_dsp_vad_get(struct snd_kcontrol *kcontrol, | 787 | static int rt5677_dsp_vad_get(struct snd_kcontrol *kcontrol, |
785 | struct snd_ctl_elem_value *ucontrol) | 788 | struct snd_ctl_elem_value *ucontrol) |
786 | { | 789 | { |
787 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 790 | struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); |
788 | struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec); | 791 | struct rt5677_priv *rt5677 = snd_soc_component_get_drvdata(component); |
789 | 792 | ||
790 | ucontrol->value.integer.value[0] = rt5677->dsp_vad_en; | 793 | ucontrol->value.integer.value[0] = rt5677->dsp_vad_en; |
791 | 794 | ||
@@ -795,8 +798,9 @@ static int rt5677_dsp_vad_get(struct snd_kcontrol *kcontrol, | |||
795 | static int rt5677_dsp_vad_put(struct snd_kcontrol *kcontrol, | 798 | static int rt5677_dsp_vad_put(struct snd_kcontrol *kcontrol, |
796 | struct snd_ctl_elem_value *ucontrol) | 799 | struct snd_ctl_elem_value *ucontrol) |
797 | { | 800 | { |
798 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 801 | struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); |
799 | struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec); | 802 | struct rt5677_priv *rt5677 = snd_soc_component_get_drvdata(component); |
803 | struct snd_soc_codec *codec = snd_soc_component_to_codec(component); | ||
800 | 804 | ||
801 | rt5677->dsp_vad_en = !!ucontrol->value.integer.value[0]; | 805 | rt5677->dsp_vad_en = !!ucontrol->value.integer.value[0]; |
802 | 806 | ||
@@ -895,7 +899,7 @@ static const struct snd_kcontrol_new rt5677_snd_controls[] = { | |||
895 | static int set_dmic_clk(struct snd_soc_dapm_widget *w, | 899 | static int set_dmic_clk(struct snd_soc_dapm_widget *w, |
896 | struct snd_kcontrol *kcontrol, int event) | 900 | struct snd_kcontrol *kcontrol, int event) |
897 | { | 901 | { |
898 | struct snd_soc_codec *codec = w->codec; | 902 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
899 | struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec); | 903 | struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec); |
900 | int idx = rl6231_calc_dmic_clk(rt5677->sysclk); | 904 | int idx = rl6231_calc_dmic_clk(rt5677->sysclk); |
901 | 905 | ||
@@ -910,7 +914,8 @@ static int set_dmic_clk(struct snd_soc_dapm_widget *w, | |||
910 | static int is_sys_clk_from_pll(struct snd_soc_dapm_widget *source, | 914 | static int is_sys_clk_from_pll(struct snd_soc_dapm_widget *source, |
911 | struct snd_soc_dapm_widget *sink) | 915 | struct snd_soc_dapm_widget *sink) |
912 | { | 916 | { |
913 | struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(source->codec); | 917 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm); |
918 | struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec); | ||
914 | unsigned int val; | 919 | unsigned int val; |
915 | 920 | ||
916 | regmap_read(rt5677->regmap, RT5677_GLB_CLK1, &val); | 921 | regmap_read(rt5677->regmap, RT5677_GLB_CLK1, &val); |
@@ -921,6 +926,101 @@ static int is_sys_clk_from_pll(struct snd_soc_dapm_widget *source, | |||
921 | return 0; | 926 | return 0; |
922 | } | 927 | } |
923 | 928 | ||
929 | static int is_using_asrc(struct snd_soc_dapm_widget *source, | ||
930 | struct snd_soc_dapm_widget *sink) | ||
931 | { | ||
932 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm); | ||
933 | struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec); | ||
934 | unsigned int reg, shift, val; | ||
935 | |||
936 | if (source->reg == RT5677_ASRC_1) { | ||
937 | switch (source->shift) { | ||
938 | case 12: | ||
939 | reg = RT5677_ASRC_4; | ||
940 | shift = 0; | ||
941 | break; | ||
942 | case 13: | ||
943 | reg = RT5677_ASRC_4; | ||
944 | shift = 4; | ||
945 | break; | ||
946 | case 14: | ||
947 | reg = RT5677_ASRC_4; | ||
948 | shift = 8; | ||
949 | break; | ||
950 | case 15: | ||
951 | reg = RT5677_ASRC_4; | ||
952 | shift = 12; | ||
953 | break; | ||
954 | default: | ||
955 | return 0; | ||
956 | } | ||
957 | } else { | ||
958 | switch (source->shift) { | ||
959 | case 0: | ||
960 | reg = RT5677_ASRC_6; | ||
961 | shift = 8; | ||
962 | break; | ||
963 | case 1: | ||
964 | reg = RT5677_ASRC_6; | ||
965 | shift = 12; | ||
966 | break; | ||
967 | case 2: | ||
968 | reg = RT5677_ASRC_5; | ||
969 | shift = 0; | ||
970 | break; | ||
971 | case 3: | ||
972 | reg = RT5677_ASRC_5; | ||
973 | shift = 4; | ||
974 | break; | ||
975 | case 4: | ||
976 | reg = RT5677_ASRC_5; | ||
977 | shift = 8; | ||
978 | break; | ||
979 | case 5: | ||
980 | reg = RT5677_ASRC_5; | ||
981 | shift = 12; | ||
982 | break; | ||
983 | case 12: | ||
984 | reg = RT5677_ASRC_3; | ||
985 | shift = 0; | ||
986 | break; | ||
987 | case 13: | ||
988 | reg = RT5677_ASRC_3; | ||
989 | shift = 4; | ||
990 | break; | ||
991 | case 14: | ||
992 | reg = RT5677_ASRC_3; | ||
993 | shift = 12; | ||
994 | break; | ||
995 | default: | ||
996 | return 0; | ||
997 | } | ||
998 | } | ||
999 | |||
1000 | regmap_read(rt5677->regmap, reg, &val); | ||
1001 | val = (val >> shift) & 0xf; | ||
1002 | |||
1003 | switch (val) { | ||
1004 | case 1 ... 6: | ||
1005 | return 1; | ||
1006 | default: | ||
1007 | return 0; | ||
1008 | } | ||
1009 | |||
1010 | } | ||
1011 | |||
1012 | static int can_use_asrc(struct snd_soc_dapm_widget *source, | ||
1013 | struct snd_soc_dapm_widget *sink) | ||
1014 | { | ||
1015 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm); | ||
1016 | struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec); | ||
1017 | |||
1018 | if (rt5677->sysclk > rt5677->lrck[RT5677_AIF1] * 384) | ||
1019 | return 1; | ||
1020 | |||
1021 | return 0; | ||
1022 | } | ||
1023 | |||
924 | /* Digital Mixer */ | 1024 | /* Digital Mixer */ |
925 | static const struct snd_kcontrol_new rt5677_sto1_adc_l_mix[] = { | 1025 | static const struct snd_kcontrol_new rt5677_sto1_adc_l_mix[] = { |
926 | SOC_DAPM_SINGLE("ADC1 Switch", RT5677_STO1_ADC_MIXER, | 1026 | SOC_DAPM_SINGLE("ADC1 Switch", RT5677_STO1_ADC_MIXER, |
@@ -2030,7 +2130,7 @@ static const struct snd_kcontrol_new rt5677_if2_dac7_tdm_sel_mux = | |||
2030 | static int rt5677_bst1_event(struct snd_soc_dapm_widget *w, | 2130 | static int rt5677_bst1_event(struct snd_soc_dapm_widget *w, |
2031 | struct snd_kcontrol *kcontrol, int event) | 2131 | struct snd_kcontrol *kcontrol, int event) |
2032 | { | 2132 | { |
2033 | struct snd_soc_codec *codec = w->codec; | 2133 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
2034 | struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec); | 2134 | struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec); |
2035 | 2135 | ||
2036 | switch (event) { | 2136 | switch (event) { |
@@ -2054,7 +2154,7 @@ static int rt5677_bst1_event(struct snd_soc_dapm_widget *w, | |||
2054 | static int rt5677_bst2_event(struct snd_soc_dapm_widget *w, | 2154 | static int rt5677_bst2_event(struct snd_soc_dapm_widget *w, |
2055 | struct snd_kcontrol *kcontrol, int event) | 2155 | struct snd_kcontrol *kcontrol, int event) |
2056 | { | 2156 | { |
2057 | struct snd_soc_codec *codec = w->codec; | 2157 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
2058 | struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec); | 2158 | struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec); |
2059 | 2159 | ||
2060 | switch (event) { | 2160 | switch (event) { |
@@ -2078,14 +2178,18 @@ static int rt5677_bst2_event(struct snd_soc_dapm_widget *w, | |||
2078 | static int rt5677_set_pll1_event(struct snd_soc_dapm_widget *w, | 2178 | static int rt5677_set_pll1_event(struct snd_soc_dapm_widget *w, |
2079 | struct snd_kcontrol *kcontrol, int event) | 2179 | struct snd_kcontrol *kcontrol, int event) |
2080 | { | 2180 | { |
2081 | struct snd_soc_codec *codec = w->codec; | 2181 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
2082 | struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec); | 2182 | struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec); |
2083 | 2183 | ||
2084 | switch (event) { | 2184 | switch (event) { |
2085 | case SND_SOC_DAPM_POST_PMU: | 2185 | case SND_SOC_DAPM_PRE_PMU: |
2086 | regmap_update_bits(rt5677->regmap, RT5677_PLL1_CTRL2, 0x2, 0x2); | 2186 | regmap_update_bits(rt5677->regmap, RT5677_PLL1_CTRL2, 0x2, 0x2); |
2187 | break; | ||
2188 | |||
2189 | case SND_SOC_DAPM_POST_PMU: | ||
2087 | regmap_update_bits(rt5677->regmap, RT5677_PLL1_CTRL2, 0x2, 0x0); | 2190 | regmap_update_bits(rt5677->regmap, RT5677_PLL1_CTRL2, 0x2, 0x0); |
2088 | break; | 2191 | break; |
2192 | |||
2089 | default: | 2193 | default: |
2090 | return 0; | 2194 | return 0; |
2091 | } | 2195 | } |
@@ -2096,14 +2200,18 @@ static int rt5677_set_pll1_event(struct snd_soc_dapm_widget *w, | |||
2096 | static int rt5677_set_pll2_event(struct snd_soc_dapm_widget *w, | 2200 | static int rt5677_set_pll2_event(struct snd_soc_dapm_widget *w, |
2097 | struct snd_kcontrol *kcontrol, int event) | 2201 | struct snd_kcontrol *kcontrol, int event) |
2098 | { | 2202 | { |
2099 | struct snd_soc_codec *codec = w->codec; | 2203 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
2100 | struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec); | 2204 | struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec); |
2101 | 2205 | ||
2102 | switch (event) { | 2206 | switch (event) { |
2103 | case SND_SOC_DAPM_POST_PMU: | 2207 | case SND_SOC_DAPM_PRE_PMU: |
2104 | regmap_update_bits(rt5677->regmap, RT5677_PLL2_CTRL2, 0x2, 0x2); | 2208 | regmap_update_bits(rt5677->regmap, RT5677_PLL2_CTRL2, 0x2, 0x2); |
2209 | break; | ||
2210 | |||
2211 | case SND_SOC_DAPM_POST_PMU: | ||
2105 | regmap_update_bits(rt5677->regmap, RT5677_PLL2_CTRL2, 0x2, 0x0); | 2212 | regmap_update_bits(rt5677->regmap, RT5677_PLL2_CTRL2, 0x2, 0x0); |
2106 | break; | 2213 | break; |
2214 | |||
2107 | default: | 2215 | default: |
2108 | return 0; | 2216 | return 0; |
2109 | } | 2217 | } |
@@ -2114,7 +2222,7 @@ static int rt5677_set_pll2_event(struct snd_soc_dapm_widget *w, | |||
2114 | static int rt5677_set_micbias1_event(struct snd_soc_dapm_widget *w, | 2222 | static int rt5677_set_micbias1_event(struct snd_soc_dapm_widget *w, |
2115 | struct snd_kcontrol *kcontrol, int event) | 2223 | struct snd_kcontrol *kcontrol, int event) |
2116 | { | 2224 | { |
2117 | struct snd_soc_codec *codec = w->codec; | 2225 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
2118 | struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec); | 2226 | struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec); |
2119 | 2227 | ||
2120 | switch (event) { | 2228 | switch (event) { |
@@ -2141,7 +2249,7 @@ static int rt5677_set_micbias1_event(struct snd_soc_dapm_widget *w, | |||
2141 | static int rt5677_if1_adc_tdm_event(struct snd_soc_dapm_widget *w, | 2249 | static int rt5677_if1_adc_tdm_event(struct snd_soc_dapm_widget *w, |
2142 | struct snd_kcontrol *kcontrol, int event) | 2250 | struct snd_kcontrol *kcontrol, int event) |
2143 | { | 2251 | { |
2144 | struct snd_soc_codec *codec = w->codec; | 2252 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
2145 | struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec); | 2253 | struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec); |
2146 | unsigned int value; | 2254 | unsigned int value; |
2147 | 2255 | ||
@@ -2164,7 +2272,7 @@ static int rt5677_if1_adc_tdm_event(struct snd_soc_dapm_widget *w, | |||
2164 | static int rt5677_if2_adc_tdm_event(struct snd_soc_dapm_widget *w, | 2272 | static int rt5677_if2_adc_tdm_event(struct snd_soc_dapm_widget *w, |
2165 | struct snd_kcontrol *kcontrol, int event) | 2273 | struct snd_kcontrol *kcontrol, int event) |
2166 | { | 2274 | { |
2167 | struct snd_soc_codec *codec = w->codec; | 2275 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
2168 | struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec); | 2276 | struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec); |
2169 | unsigned int value; | 2277 | unsigned int value; |
2170 | 2278 | ||
@@ -2187,7 +2295,7 @@ static int rt5677_if2_adc_tdm_event(struct snd_soc_dapm_widget *w, | |||
2187 | static int rt5677_vref_event(struct snd_soc_dapm_widget *w, | 2295 | static int rt5677_vref_event(struct snd_soc_dapm_widget *w, |
2188 | struct snd_kcontrol *kcontrol, int event) | 2296 | struct snd_kcontrol *kcontrol, int event) |
2189 | { | 2297 | { |
2190 | struct snd_soc_codec *codec = w->codec; | 2298 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
2191 | struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec); | 2299 | struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec); |
2192 | 2300 | ||
2193 | switch (event) { | 2301 | switch (event) { |
@@ -2211,9 +2319,50 @@ static int rt5677_vref_event(struct snd_soc_dapm_widget *w, | |||
2211 | 2319 | ||
2212 | static const struct snd_soc_dapm_widget rt5677_dapm_widgets[] = { | 2320 | static const struct snd_soc_dapm_widget rt5677_dapm_widgets[] = { |
2213 | SND_SOC_DAPM_SUPPLY("PLL1", RT5677_PWR_ANLG2, RT5677_PWR_PLL1_BIT, | 2321 | SND_SOC_DAPM_SUPPLY("PLL1", RT5677_PWR_ANLG2, RT5677_PWR_PLL1_BIT, |
2214 | 0, rt5677_set_pll1_event, SND_SOC_DAPM_POST_PMU), | 2322 | 0, rt5677_set_pll1_event, SND_SOC_DAPM_PRE_PMU | |
2323 | SND_SOC_DAPM_POST_PMU), | ||
2215 | SND_SOC_DAPM_SUPPLY("PLL2", RT5677_PWR_ANLG2, RT5677_PWR_PLL2_BIT, | 2324 | SND_SOC_DAPM_SUPPLY("PLL2", RT5677_PWR_ANLG2, RT5677_PWR_PLL2_BIT, |
2216 | 0, rt5677_set_pll2_event, SND_SOC_DAPM_POST_PMU), | 2325 | 0, rt5677_set_pll2_event, SND_SOC_DAPM_PRE_PMU | |
2326 | SND_SOC_DAPM_POST_PMU), | ||
2327 | |||
2328 | /* ASRC */ | ||
2329 | SND_SOC_DAPM_SUPPLY_S("I2S1 ASRC", 1, RT5677_ASRC_1, 0, 0, NULL, 0), | ||
2330 | SND_SOC_DAPM_SUPPLY_S("I2S2 ASRC", 1, RT5677_ASRC_1, 1, 0, NULL, 0), | ||
2331 | SND_SOC_DAPM_SUPPLY_S("I2S3 ASRC", 1, RT5677_ASRC_1, 2, 0, NULL, 0), | ||
2332 | SND_SOC_DAPM_SUPPLY_S("I2S4 ASRC", 1, RT5677_ASRC_1, 3, 0, NULL, 0), | ||
2333 | SND_SOC_DAPM_SUPPLY_S("DAC STO ASRC", 1, RT5677_ASRC_2, 14, 0, NULL, 0), | ||
2334 | SND_SOC_DAPM_SUPPLY_S("DAC MONO2 L ASRC", 1, RT5677_ASRC_2, 13, 0, NULL, | ||
2335 | 0), | ||
2336 | SND_SOC_DAPM_SUPPLY_S("DAC MONO2 R ASRC", 1, RT5677_ASRC_2, 12, 0, NULL, | ||
2337 | 0), | ||
2338 | SND_SOC_DAPM_SUPPLY_S("DAC MONO3 L ASRC", 1, RT5677_ASRC_1, 15, 0, NULL, | ||
2339 | 0), | ||
2340 | SND_SOC_DAPM_SUPPLY_S("DAC MONO3 R ASRC", 1, RT5677_ASRC_1, 14, 0, NULL, | ||
2341 | 0), | ||
2342 | SND_SOC_DAPM_SUPPLY_S("DAC MONO4 L ASRC", 1, RT5677_ASRC_1, 13, 0, NULL, | ||
2343 | 0), | ||
2344 | SND_SOC_DAPM_SUPPLY_S("DAC MONO4 R ASRC", 1, RT5677_ASRC_1, 12, 0, NULL, | ||
2345 | 0), | ||
2346 | SND_SOC_DAPM_SUPPLY_S("DMIC STO1 ASRC", 1, RT5677_ASRC_2, 11, 0, NULL, | ||
2347 | 0), | ||
2348 | SND_SOC_DAPM_SUPPLY_S("DMIC STO2 ASRC", 1, RT5677_ASRC_2, 10, 0, NULL, | ||
2349 | 0), | ||
2350 | SND_SOC_DAPM_SUPPLY_S("DMIC STO3 ASRC", 1, RT5677_ASRC_2, 9, 0, NULL, | ||
2351 | 0), | ||
2352 | SND_SOC_DAPM_SUPPLY_S("DMIC STO4 ASRC", 1, RT5677_ASRC_2, 8, 0, NULL, | ||
2353 | 0), | ||
2354 | SND_SOC_DAPM_SUPPLY_S("DMIC MONO L ASRC", 1, RT5677_ASRC_2, 7, 0, NULL, | ||
2355 | 0), | ||
2356 | SND_SOC_DAPM_SUPPLY_S("DMIC MONO R ASRC", 1, RT5677_ASRC_2, 6, 0, NULL, | ||
2357 | 0), | ||
2358 | SND_SOC_DAPM_SUPPLY_S("ADC STO1 ASRC", 1, RT5677_ASRC_2, 5, 0, NULL, 0), | ||
2359 | SND_SOC_DAPM_SUPPLY_S("ADC STO2 ASRC", 1, RT5677_ASRC_2, 4, 0, NULL, 0), | ||
2360 | SND_SOC_DAPM_SUPPLY_S("ADC STO3 ASRC", 1, RT5677_ASRC_2, 3, 0, NULL, 0), | ||
2361 | SND_SOC_DAPM_SUPPLY_S("ADC STO4 ASRC", 1, RT5677_ASRC_2, 2, 0, NULL, 0), | ||
2362 | SND_SOC_DAPM_SUPPLY_S("ADC MONO L ASRC", 1, RT5677_ASRC_2, 1, 0, NULL, | ||
2363 | 0), | ||
2364 | SND_SOC_DAPM_SUPPLY_S("ADC MONO R ASRC", 1, RT5677_ASRC_2, 0, 0, NULL, | ||
2365 | 0), | ||
2217 | 2366 | ||
2218 | /* Input Side */ | 2367 | /* Input Side */ |
2219 | /* micbias */ | 2368 | /* micbias */ |
@@ -2645,10 +2794,18 @@ static const struct snd_soc_dapm_widget rt5677_dapm_widgets[] = { | |||
2645 | /* DAC Mixer */ | 2794 | /* DAC Mixer */ |
2646 | SND_SOC_DAPM_SUPPLY("dac stereo1 filter", RT5677_PWR_DIG2, | 2795 | SND_SOC_DAPM_SUPPLY("dac stereo1 filter", RT5677_PWR_DIG2, |
2647 | RT5677_PWR_DAC_S1F_BIT, 0, NULL, 0), | 2796 | RT5677_PWR_DAC_S1F_BIT, 0, NULL, 0), |
2648 | SND_SOC_DAPM_SUPPLY("dac mono left filter", RT5677_PWR_DIG2, | 2797 | SND_SOC_DAPM_SUPPLY("dac mono2 left filter", RT5677_PWR_DIG2, |
2649 | RT5677_PWR_DAC_M2F_L_BIT, 0, NULL, 0), | 2798 | RT5677_PWR_DAC_M2F_L_BIT, 0, NULL, 0), |
2650 | SND_SOC_DAPM_SUPPLY("dac mono right filter", RT5677_PWR_DIG2, | 2799 | SND_SOC_DAPM_SUPPLY("dac mono2 right filter", RT5677_PWR_DIG2, |
2651 | RT5677_PWR_DAC_M2F_R_BIT, 0, NULL, 0), | 2800 | RT5677_PWR_DAC_M2F_R_BIT, 0, NULL, 0), |
2801 | SND_SOC_DAPM_SUPPLY("dac mono3 left filter", RT5677_PWR_DIG2, | ||
2802 | RT5677_PWR_DAC_M3F_L_BIT, 0, NULL, 0), | ||
2803 | SND_SOC_DAPM_SUPPLY("dac mono3 right filter", RT5677_PWR_DIG2, | ||
2804 | RT5677_PWR_DAC_M3F_R_BIT, 0, NULL, 0), | ||
2805 | SND_SOC_DAPM_SUPPLY("dac mono4 left filter", RT5677_PWR_DIG2, | ||
2806 | RT5677_PWR_DAC_M4F_L_BIT, 0, NULL, 0), | ||
2807 | SND_SOC_DAPM_SUPPLY("dac mono4 right filter", RT5677_PWR_DIG2, | ||
2808 | RT5677_PWR_DAC_M4F_R_BIT, 0, NULL, 0), | ||
2652 | 2809 | ||
2653 | SND_SOC_DAPM_MIXER("Stereo DAC MIXL", SND_SOC_NOPM, 0, 0, | 2810 | SND_SOC_DAPM_MIXER("Stereo DAC MIXL", SND_SOC_NOPM, 0, 0, |
2654 | rt5677_sto1_dac_l_mix, ARRAY_SIZE(rt5677_sto1_dac_l_mix)), | 2811 | rt5677_sto1_dac_l_mix, ARRAY_SIZE(rt5677_sto1_dac_l_mix)), |
@@ -2721,6 +2878,31 @@ static const struct snd_soc_dapm_widget rt5677_dapm_widgets[] = { | |||
2721 | }; | 2878 | }; |
2722 | 2879 | ||
2723 | static const struct snd_soc_dapm_route rt5677_dapm_routes[] = { | 2880 | static const struct snd_soc_dapm_route rt5677_dapm_routes[] = { |
2881 | { "Stereo1 DMIC Mux", NULL, "DMIC STO1 ASRC", can_use_asrc }, | ||
2882 | { "Stereo2 DMIC Mux", NULL, "DMIC STO2 ASRC", can_use_asrc }, | ||
2883 | { "Stereo3 DMIC Mux", NULL, "DMIC STO3 ASRC", can_use_asrc }, | ||
2884 | { "Stereo4 DMIC Mux", NULL, "DMIC STO4 ASRC", can_use_asrc }, | ||
2885 | { "Mono DMIC L Mux", NULL, "DMIC MONO L ASRC", can_use_asrc }, | ||
2886 | { "Mono DMIC R Mux", NULL, "DMIC MONO R ASRC", can_use_asrc }, | ||
2887 | { "I2S1", NULL, "I2S1 ASRC", can_use_asrc}, | ||
2888 | { "I2S2", NULL, "I2S2 ASRC", can_use_asrc}, | ||
2889 | { "I2S3", NULL, "I2S3 ASRC", can_use_asrc}, | ||
2890 | { "I2S4", NULL, "I2S4 ASRC", can_use_asrc}, | ||
2891 | |||
2892 | { "dac stereo1 filter", NULL, "DAC STO ASRC", is_using_asrc }, | ||
2893 | { "dac mono2 left filter", NULL, "DAC MONO2 L ASRC", is_using_asrc }, | ||
2894 | { "dac mono2 right filter", NULL, "DAC MONO2 R ASRC", is_using_asrc }, | ||
2895 | { "dac mono3 left filter", NULL, "DAC MONO3 L ASRC", is_using_asrc }, | ||
2896 | { "dac mono3 right filter", NULL, "DAC MONO3 R ASRC", is_using_asrc }, | ||
2897 | { "dac mono4 left filter", NULL, "DAC MONO4 L ASRC", is_using_asrc }, | ||
2898 | { "dac mono4 right filter", NULL, "DAC MONO4 R ASRC", is_using_asrc }, | ||
2899 | { "adc stereo1 filter", NULL, "ADC STO1 ASRC", is_using_asrc }, | ||
2900 | { "adc stereo2 filter", NULL, "ADC STO2 ASRC", is_using_asrc }, | ||
2901 | { "adc stereo3 filter", NULL, "ADC STO3 ASRC", is_using_asrc }, | ||
2902 | { "adc stereo4 filter", NULL, "ADC STO4 ASRC", is_using_asrc }, | ||
2903 | { "adc mono left filter", NULL, "ADC MONO L ASRC", is_using_asrc }, | ||
2904 | { "adc mono right filter", NULL, "ADC MONO R ASRC", is_using_asrc }, | ||
2905 | |||
2724 | { "DMIC1", NULL, "DMIC L1" }, | 2906 | { "DMIC1", NULL, "DMIC L1" }, |
2725 | { "DMIC1", NULL, "DMIC R1" }, | 2907 | { "DMIC1", NULL, "DMIC R1" }, |
2726 | { "DMIC2", NULL, "DMIC L2" }, | 2908 | { "DMIC2", NULL, "DMIC L2" }, |
@@ -2851,8 +3033,6 @@ static const struct snd_soc_dapm_route rt5677_dapm_routes[] = { | |||
2851 | 3033 | ||
2852 | { "Stereo1 ADC MIXL", NULL, "Sto1 ADC MIXL" }, | 3034 | { "Stereo1 ADC MIXL", NULL, "Sto1 ADC MIXL" }, |
2853 | { "Stereo1 ADC MIXL", NULL, "adc stereo1 filter" }, | 3035 | { "Stereo1 ADC MIXL", NULL, "adc stereo1 filter" }, |
2854 | { "adc stereo1 filter", NULL, "PLL1", is_sys_clk_from_pll }, | ||
2855 | |||
2856 | { "Stereo1 ADC MIXR", NULL, "Sto1 ADC MIXR" }, | 3036 | { "Stereo1 ADC MIXR", NULL, "Sto1 ADC MIXR" }, |
2857 | { "Stereo1 ADC MIXR", NULL, "adc stereo1 filter" }, | 3037 | { "Stereo1 ADC MIXR", NULL, "adc stereo1 filter" }, |
2858 | { "adc stereo1 filter", NULL, "PLL1", is_sys_clk_from_pll }, | 3038 | { "adc stereo1 filter", NULL, "PLL1", is_sys_clk_from_pll }, |
@@ -2873,8 +3053,6 @@ static const struct snd_soc_dapm_route rt5677_dapm_routes[] = { | |||
2873 | 3053 | ||
2874 | { "Stereo2 ADC MIXL", NULL, "Stereo2 ADC LR Mux" }, | 3054 | { "Stereo2 ADC MIXL", NULL, "Stereo2 ADC LR Mux" }, |
2875 | { "Stereo2 ADC MIXL", NULL, "adc stereo2 filter" }, | 3055 | { "Stereo2 ADC MIXL", NULL, "adc stereo2 filter" }, |
2876 | { "adc stereo2 filter", NULL, "PLL1", is_sys_clk_from_pll }, | ||
2877 | |||
2878 | { "Stereo2 ADC MIXR", NULL, "Sto2 ADC MIXR" }, | 3056 | { "Stereo2 ADC MIXR", NULL, "Sto2 ADC MIXR" }, |
2879 | { "Stereo2 ADC MIXR", NULL, "adc stereo2 filter" }, | 3057 | { "Stereo2 ADC MIXR", NULL, "adc stereo2 filter" }, |
2880 | { "adc stereo2 filter", NULL, "PLL1", is_sys_clk_from_pll }, | 3058 | { "adc stereo2 filter", NULL, "PLL1", is_sys_clk_from_pll }, |
@@ -2889,8 +3067,6 @@ static const struct snd_soc_dapm_route rt5677_dapm_routes[] = { | |||
2889 | 3067 | ||
2890 | { "Stereo3 ADC MIXL", NULL, "Sto3 ADC MIXL" }, | 3068 | { "Stereo3 ADC MIXL", NULL, "Sto3 ADC MIXL" }, |
2891 | { "Stereo3 ADC MIXL", NULL, "adc stereo3 filter" }, | 3069 | { "Stereo3 ADC MIXL", NULL, "adc stereo3 filter" }, |
2892 | { "adc stereo3 filter", NULL, "PLL1", is_sys_clk_from_pll }, | ||
2893 | |||
2894 | { "Stereo3 ADC MIXR", NULL, "Sto3 ADC MIXR" }, | 3070 | { "Stereo3 ADC MIXR", NULL, "Sto3 ADC MIXR" }, |
2895 | { "Stereo3 ADC MIXR", NULL, "adc stereo3 filter" }, | 3071 | { "Stereo3 ADC MIXR", NULL, "adc stereo3 filter" }, |
2896 | { "adc stereo3 filter", NULL, "PLL1", is_sys_clk_from_pll }, | 3072 | { "adc stereo3 filter", NULL, "PLL1", is_sys_clk_from_pll }, |
@@ -2905,8 +3081,6 @@ static const struct snd_soc_dapm_route rt5677_dapm_routes[] = { | |||
2905 | 3081 | ||
2906 | { "Stereo4 ADC MIXL", NULL, "Sto4 ADC MIXL" }, | 3082 | { "Stereo4 ADC MIXL", NULL, "Sto4 ADC MIXL" }, |
2907 | { "Stereo4 ADC MIXL", NULL, "adc stereo4 filter" }, | 3083 | { "Stereo4 ADC MIXL", NULL, "adc stereo4 filter" }, |
2908 | { "adc stereo4 filter", NULL, "PLL1", is_sys_clk_from_pll }, | ||
2909 | |||
2910 | { "Stereo4 ADC MIXR", NULL, "Sto4 ADC MIXR" }, | 3084 | { "Stereo4 ADC MIXR", NULL, "Sto4 ADC MIXR" }, |
2911 | { "Stereo4 ADC MIXR", NULL, "adc stereo4 filter" }, | 3085 | { "Stereo4 ADC MIXR", NULL, "adc stereo4 filter" }, |
2912 | { "adc stereo4 filter", NULL, "PLL1", is_sys_clk_from_pll }, | 3086 | { "adc stereo4 filter", NULL, "PLL1", is_sys_clk_from_pll }, |
@@ -3455,10 +3629,8 @@ static const struct snd_soc_dapm_route rt5677_dapm_routes[] = { | |||
3455 | 3629 | ||
3456 | { "DAC1 MIXL", "Stereo ADC Switch", "ADDA1 Mux" }, | 3630 | { "DAC1 MIXL", "Stereo ADC Switch", "ADDA1 Mux" }, |
3457 | { "DAC1 MIXL", "DAC1 Switch", "DAC1 Mux" }, | 3631 | { "DAC1 MIXL", "DAC1 Switch", "DAC1 Mux" }, |
3458 | { "DAC1 MIXL", NULL, "dac stereo1 filter" }, | ||
3459 | { "DAC1 MIXR", "Stereo ADC Switch", "ADDA1 Mux" }, | 3632 | { "DAC1 MIXR", "Stereo ADC Switch", "ADDA1 Mux" }, |
3460 | { "DAC1 MIXR", "DAC1 Switch", "DAC1 Mux" }, | 3633 | { "DAC1 MIXR", "DAC1 Switch", "DAC1 Mux" }, |
3461 | { "DAC1 MIXR", NULL, "dac stereo1 filter" }, | ||
3462 | 3634 | ||
3463 | { "DAC1 FS", NULL, "DAC1 MIXL" }, | 3635 | { "DAC1 FS", NULL, "DAC1 MIXL" }, |
3464 | { "DAC1 FS", NULL, "DAC1 MIXR" }, | 3636 | { "DAC1 FS", NULL, "DAC1 MIXR" }, |
@@ -3525,35 +3697,46 @@ static const struct snd_soc_dapm_route rt5677_dapm_routes[] = { | |||
3525 | { "Stereo DAC MIXR", "DAC2 R Switch", "DAC2 R Mux" }, | 3697 | { "Stereo DAC MIXR", "DAC2 R Switch", "DAC2 R Mux" }, |
3526 | { "Stereo DAC MIXR", "DAC1 L Switch", "DAC1 MIXL" }, | 3698 | { "Stereo DAC MIXR", "DAC1 L Switch", "DAC1 MIXL" }, |
3527 | { "Stereo DAC MIXR", NULL, "dac stereo1 filter" }, | 3699 | { "Stereo DAC MIXR", NULL, "dac stereo1 filter" }, |
3700 | { "dac stereo1 filter", NULL, "PLL1", is_sys_clk_from_pll }, | ||
3528 | 3701 | ||
3529 | { "Mono DAC MIXL", "ST L Switch", "Sidetone Mux" }, | 3702 | { "Mono DAC MIXL", "ST L Switch", "Sidetone Mux" }, |
3530 | { "Mono DAC MIXL", "DAC1 L Switch", "DAC1 MIXL" }, | 3703 | { "Mono DAC MIXL", "DAC1 L Switch", "DAC1 MIXL" }, |
3531 | { "Mono DAC MIXL", "DAC2 L Switch", "DAC2 L Mux" }, | 3704 | { "Mono DAC MIXL", "DAC2 L Switch", "DAC2 L Mux" }, |
3532 | { "Mono DAC MIXL", "DAC2 R Switch", "DAC2 R Mux" }, | 3705 | { "Mono DAC MIXL", "DAC2 R Switch", "DAC2 R Mux" }, |
3533 | { "Mono DAC MIXL", NULL, "dac mono left filter" }, | 3706 | { "Mono DAC MIXL", NULL, "dac mono2 left filter" }, |
3707 | { "dac mono2 left filter", NULL, "PLL1", is_sys_clk_from_pll }, | ||
3534 | { "Mono DAC MIXR", "ST R Switch", "Sidetone Mux" }, | 3708 | { "Mono DAC MIXR", "ST R Switch", "Sidetone Mux" }, |
3535 | { "Mono DAC MIXR", "DAC1 R Switch", "DAC1 MIXR" }, | 3709 | { "Mono DAC MIXR", "DAC1 R Switch", "DAC1 MIXR" }, |
3536 | { "Mono DAC MIXR", "DAC2 R Switch", "DAC2 R Mux" }, | 3710 | { "Mono DAC MIXR", "DAC2 R Switch", "DAC2 R Mux" }, |
3537 | { "Mono DAC MIXR", "DAC2 L Switch", "DAC2 L Mux" }, | 3711 | { "Mono DAC MIXR", "DAC2 L Switch", "DAC2 L Mux" }, |
3538 | { "Mono DAC MIXR", NULL, "dac mono right filter" }, | 3712 | { "Mono DAC MIXR", NULL, "dac mono2 right filter" }, |
3713 | { "dac mono2 right filter", NULL, "PLL1", is_sys_clk_from_pll }, | ||
3539 | 3714 | ||
3540 | { "DD1 MIXL", "Sto DAC Mix L Switch", "Stereo DAC MIXL" }, | 3715 | { "DD1 MIXL", "Sto DAC Mix L Switch", "Stereo DAC MIXL" }, |
3541 | { "DD1 MIXL", "Mono DAC Mix L Switch", "Mono DAC MIXL" }, | 3716 | { "DD1 MIXL", "Mono DAC Mix L Switch", "Mono DAC MIXL" }, |
3542 | { "DD1 MIXL", "DAC3 L Switch", "DAC3 L Mux" }, | 3717 | { "DD1 MIXL", "DAC3 L Switch", "DAC3 L Mux" }, |
3543 | { "DD1 MIXL", "DAC3 R Switch", "DAC3 R Mux" }, | 3718 | { "DD1 MIXL", "DAC3 R Switch", "DAC3 R Mux" }, |
3719 | { "DD1 MIXL", NULL, "dac mono3 left filter" }, | ||
3720 | { "dac mono3 left filter", NULL, "PLL1", is_sys_clk_from_pll }, | ||
3544 | { "DD1 MIXR", "Sto DAC Mix R Switch", "Stereo DAC MIXR" }, | 3721 | { "DD1 MIXR", "Sto DAC Mix R Switch", "Stereo DAC MIXR" }, |
3545 | { "DD1 MIXR", "Mono DAC Mix R Switch", "Mono DAC MIXR" }, | 3722 | { "DD1 MIXR", "Mono DAC Mix R Switch", "Mono DAC MIXR" }, |
3546 | { "DD1 MIXR", "DAC3 L Switch", "DAC3 L Mux" }, | 3723 | { "DD1 MIXR", "DAC3 L Switch", "DAC3 L Mux" }, |
3547 | { "DD1 MIXR", "DAC3 R Switch", "DAC3 R Mux" }, | 3724 | { "DD1 MIXR", "DAC3 R Switch", "DAC3 R Mux" }, |
3725 | { "DD1 MIXR", NULL, "dac mono3 right filter" }, | ||
3726 | { "dac mono3 right filter", NULL, "PLL1", is_sys_clk_from_pll }, | ||
3548 | 3727 | ||
3549 | { "DD2 MIXL", "Sto DAC Mix L Switch", "Stereo DAC MIXL" }, | 3728 | { "DD2 MIXL", "Sto DAC Mix L Switch", "Stereo DAC MIXL" }, |
3550 | { "DD2 MIXL", "Mono DAC Mix L Switch", "Mono DAC MIXL" }, | 3729 | { "DD2 MIXL", "Mono DAC Mix L Switch", "Mono DAC MIXL" }, |
3551 | { "DD2 MIXL", "DAC4 L Switch", "DAC4 L Mux" }, | 3730 | { "DD2 MIXL", "DAC4 L Switch", "DAC4 L Mux" }, |
3552 | { "DD2 MIXL", "DAC4 R Switch", "DAC4 R Mux" }, | 3731 | { "DD2 MIXL", "DAC4 R Switch", "DAC4 R Mux" }, |
3732 | { "DD2 MIXL", NULL, "dac mono4 left filter" }, | ||
3733 | { "dac mono4 left filter", NULL, "PLL1", is_sys_clk_from_pll }, | ||
3553 | { "DD2 MIXR", "Sto DAC Mix R Switch", "Stereo DAC MIXR" }, | 3734 | { "DD2 MIXR", "Sto DAC Mix R Switch", "Stereo DAC MIXR" }, |
3554 | { "DD2 MIXR", "Mono DAC Mix R Switch", "Mono DAC MIXR" }, | 3735 | { "DD2 MIXR", "Mono DAC Mix R Switch", "Mono DAC MIXR" }, |
3555 | { "DD2 MIXR", "DAC4 L Switch", "DAC4 L Mux" }, | 3736 | { "DD2 MIXR", "DAC4 L Switch", "DAC4 L Mux" }, |
3556 | { "DD2 MIXR", "DAC4 R Switch", "DAC4 R Mux" }, | 3737 | { "DD2 MIXR", "DAC4 R Switch", "DAC4 R Mux" }, |
3738 | { "DD2 MIXR", NULL, "dac mono4 right filter" }, | ||
3739 | { "dac mono4 right filter", NULL, "PLL1", is_sys_clk_from_pll }, | ||
3557 | 3740 | ||
3558 | { "Stereo DAC MIX", NULL, "Stereo DAC MIXL" }, | 3741 | { "Stereo DAC MIX", NULL, "Stereo DAC MIXL" }, |
3559 | { "Stereo DAC MIX", NULL, "Stereo DAC MIXR" }, | 3742 | { "Stereo DAC MIX", NULL, "Stereo DAC MIXR" }, |
@@ -3575,11 +3758,8 @@ static const struct snd_soc_dapm_route rt5677_dapm_routes[] = { | |||
3575 | { "DAC3 SRC Mux", "DD MIX2L", "DD2 MIXL" }, | 3758 | { "DAC3 SRC Mux", "DD MIX2L", "DD2 MIXL" }, |
3576 | 3759 | ||
3577 | { "DAC 1", NULL, "DAC12 SRC Mux" }, | 3760 | { "DAC 1", NULL, "DAC12 SRC Mux" }, |
3578 | { "DAC 1", NULL, "PLL1", is_sys_clk_from_pll }, | ||
3579 | { "DAC 2", NULL, "DAC12 SRC Mux" }, | 3761 | { "DAC 2", NULL, "DAC12 SRC Mux" }, |
3580 | { "DAC 2", NULL, "PLL1", is_sys_clk_from_pll }, | ||
3581 | { "DAC 3", NULL, "DAC3 SRC Mux" }, | 3762 | { "DAC 3", NULL, "DAC3 SRC Mux" }, |
3582 | { "DAC 3", NULL, "PLL1", is_sys_clk_from_pll }, | ||
3583 | 3763 | ||
3584 | { "PDM1 L Mux", "STO1 DAC MIX", "Stereo DAC MIXL" }, | 3764 | { "PDM1 L Mux", "STO1 DAC MIX", "Stereo DAC MIXL" }, |
3585 | { "PDM1 L Mux", "MONO DAC MIX", "Mono DAC MIXL" }, | 3765 | { "PDM1 L Mux", "MONO DAC MIX", "Mono DAC MIXL" }, |
@@ -3926,7 +4106,8 @@ static int rt5677_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask, | |||
3926 | unsigned int rx_mask, int slots, int slot_width) | 4106 | unsigned int rx_mask, int slots, int slot_width) |
3927 | { | 4107 | { |
3928 | struct snd_soc_codec *codec = dai->codec; | 4108 | struct snd_soc_codec *codec = dai->codec; |
3929 | unsigned int val = 0; | 4109 | struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec); |
4110 | unsigned int val = 0, slot_width_25 = 0; | ||
3930 | 4111 | ||
3931 | if (rx_mask || tx_mask) | 4112 | if (rx_mask || tx_mask) |
3932 | val |= (1 << 12); | 4113 | val |= (1 << 12); |
@@ -3950,6 +4131,8 @@ static int rt5677_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask, | |||
3950 | case 20: | 4131 | case 20: |
3951 | val |= (1 << 8); | 4132 | val |= (1 << 8); |
3952 | break; | 4133 | break; |
4134 | case 25: | ||
4135 | slot_width_25 = 0x8080; | ||
3953 | case 24: | 4136 | case 24: |
3954 | val |= (2 << 8); | 4137 | val |= (2 << 8); |
3955 | break; | 4138 | break; |
@@ -3963,10 +4146,16 @@ static int rt5677_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask, | |||
3963 | 4146 | ||
3964 | switch (dai->id) { | 4147 | switch (dai->id) { |
3965 | case RT5677_AIF1: | 4148 | case RT5677_AIF1: |
3966 | snd_soc_update_bits(codec, RT5677_TDM1_CTRL1, 0x1f00, val); | 4149 | regmap_update_bits(rt5677->regmap, RT5677_TDM1_CTRL1, 0x1f00, |
4150 | val); | ||
4151 | regmap_update_bits(rt5677->regmap, RT5677_DIG_MISC, 0x8000, | ||
4152 | slot_width_25); | ||
3967 | break; | 4153 | break; |
3968 | case RT5677_AIF2: | 4154 | case RT5677_AIF2: |
3969 | snd_soc_update_bits(codec, RT5677_TDM2_CTRL1, 0x1f00, val); | 4155 | regmap_update_bits(rt5677->regmap, RT5677_TDM2_CTRL1, 0x1f00, |
4156 | val); | ||
4157 | regmap_update_bits(rt5677->regmap, RT5677_DIG_MISC, 0x80, | ||
4158 | slot_width_25); | ||
3970 | break; | 4159 | break; |
3971 | default: | 4160 | default: |
3972 | break; | 4161 | break; |
@@ -4751,6 +4940,11 @@ static int rt5677_i2c_probe(struct i2c_client *i2c, | |||
4751 | RT5677_GPIO5_DIR_OUT); | 4940 | RT5677_GPIO5_DIR_OUT); |
4752 | } | 4941 | } |
4753 | 4942 | ||
4943 | if (rt5677->pdata.micbias1_vdd_3v3) | ||
4944 | regmap_update_bits(rt5677->regmap, RT5677_MICBIAS, | ||
4945 | RT5677_MICBIAS1_CTRL_VDD_MASK, | ||
4946 | RT5677_MICBIAS1_CTRL_VDD_3_3V); | ||
4947 | |||
4754 | rt5677_init_gpio(i2c); | 4948 | rt5677_init_gpio(i2c); |
4755 | rt5677_init_irq(i2c); | 4949 | rt5677_init_irq(i2c); |
4756 | 4950 | ||
diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c index 29cf7ce610f4..e182e6569bbd 100644 --- a/sound/soc/codecs/sgtl5000.c +++ b/sound/soc/codecs/sgtl5000.c | |||
@@ -155,18 +155,19 @@ struct sgtl5000_priv { | |||
155 | static int mic_bias_event(struct snd_soc_dapm_widget *w, | 155 | static int mic_bias_event(struct snd_soc_dapm_widget *w, |
156 | struct snd_kcontrol *kcontrol, int event) | 156 | struct snd_kcontrol *kcontrol, int event) |
157 | { | 157 | { |
158 | struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(w->codec); | 158 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
159 | struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec); | ||
159 | 160 | ||
160 | switch (event) { | 161 | switch (event) { |
161 | case SND_SOC_DAPM_POST_PMU: | 162 | case SND_SOC_DAPM_POST_PMU: |
162 | /* change mic bias resistor */ | 163 | /* change mic bias resistor */ |
163 | snd_soc_update_bits(w->codec, SGTL5000_CHIP_MIC_CTRL, | 164 | snd_soc_update_bits(codec, SGTL5000_CHIP_MIC_CTRL, |
164 | SGTL5000_BIAS_R_MASK, | 165 | SGTL5000_BIAS_R_MASK, |
165 | sgtl5000->micbias_resistor << SGTL5000_BIAS_R_SHIFT); | 166 | sgtl5000->micbias_resistor << SGTL5000_BIAS_R_SHIFT); |
166 | break; | 167 | break; |
167 | 168 | ||
168 | case SND_SOC_DAPM_PRE_PMD: | 169 | case SND_SOC_DAPM_PRE_PMD: |
169 | snd_soc_update_bits(w->codec, SGTL5000_CHIP_MIC_CTRL, | 170 | snd_soc_update_bits(codec, SGTL5000_CHIP_MIC_CTRL, |
170 | SGTL5000_BIAS_R_MASK, 0); | 171 | SGTL5000_BIAS_R_MASK, 0); |
171 | break; | 172 | break; |
172 | } | 173 | } |
@@ -181,11 +182,12 @@ static int mic_bias_event(struct snd_soc_dapm_widget *w, | |||
181 | static int power_vag_event(struct snd_soc_dapm_widget *w, | 182 | static int power_vag_event(struct snd_soc_dapm_widget *w, |
182 | struct snd_kcontrol *kcontrol, int event) | 183 | struct snd_kcontrol *kcontrol, int event) |
183 | { | 184 | { |
185 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); | ||
184 | const u32 mask = SGTL5000_DAC_POWERUP | SGTL5000_ADC_POWERUP; | 186 | const u32 mask = SGTL5000_DAC_POWERUP | SGTL5000_ADC_POWERUP; |
185 | 187 | ||
186 | switch (event) { | 188 | switch (event) { |
187 | case SND_SOC_DAPM_POST_PMU: | 189 | case SND_SOC_DAPM_POST_PMU: |
188 | snd_soc_update_bits(w->codec, SGTL5000_CHIP_ANA_POWER, | 190 | snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER, |
189 | SGTL5000_VAG_POWERUP, SGTL5000_VAG_POWERUP); | 191 | SGTL5000_VAG_POWERUP, SGTL5000_VAG_POWERUP); |
190 | break; | 192 | break; |
191 | 193 | ||
@@ -195,9 +197,9 @@ static int power_vag_event(struct snd_soc_dapm_widget *w, | |||
195 | * operational to prevent inadvertently starving the | 197 | * operational to prevent inadvertently starving the |
196 | * other one of them. | 198 | * other one of them. |
197 | */ | 199 | */ |
198 | if ((snd_soc_read(w->codec, SGTL5000_CHIP_ANA_POWER) & | 200 | if ((snd_soc_read(codec, SGTL5000_CHIP_ANA_POWER) & |
199 | mask) != mask) { | 201 | mask) != mask) { |
200 | snd_soc_update_bits(w->codec, SGTL5000_CHIP_ANA_POWER, | 202 | snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER, |
201 | SGTL5000_VAG_POWERUP, 0); | 203 | SGTL5000_VAG_POWERUP, 0); |
202 | msleep(400); | 204 | msleep(400); |
203 | } | 205 | } |
@@ -483,21 +485,21 @@ static int sgtl5000_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) | |||
483 | /* setting i2s data format */ | 485 | /* setting i2s data format */ |
484 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { | 486 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { |
485 | case SND_SOC_DAIFMT_DSP_A: | 487 | case SND_SOC_DAIFMT_DSP_A: |
486 | i2sctl |= SGTL5000_I2S_MODE_PCM; | 488 | i2sctl |= SGTL5000_I2S_MODE_PCM << SGTL5000_I2S_MODE_SHIFT; |
487 | break; | 489 | break; |
488 | case SND_SOC_DAIFMT_DSP_B: | 490 | case SND_SOC_DAIFMT_DSP_B: |
489 | i2sctl |= SGTL5000_I2S_MODE_PCM; | 491 | i2sctl |= SGTL5000_I2S_MODE_PCM << SGTL5000_I2S_MODE_SHIFT; |
490 | i2sctl |= SGTL5000_I2S_LRALIGN; | 492 | i2sctl |= SGTL5000_I2S_LRALIGN; |
491 | break; | 493 | break; |
492 | case SND_SOC_DAIFMT_I2S: | 494 | case SND_SOC_DAIFMT_I2S: |
493 | i2sctl |= SGTL5000_I2S_MODE_I2S_LJ; | 495 | i2sctl |= SGTL5000_I2S_MODE_I2S_LJ << SGTL5000_I2S_MODE_SHIFT; |
494 | break; | 496 | break; |
495 | case SND_SOC_DAIFMT_RIGHT_J: | 497 | case SND_SOC_DAIFMT_RIGHT_J: |
496 | i2sctl |= SGTL5000_I2S_MODE_RJ; | 498 | i2sctl |= SGTL5000_I2S_MODE_RJ << SGTL5000_I2S_MODE_SHIFT; |
497 | i2sctl |= SGTL5000_I2S_LRPOL; | 499 | i2sctl |= SGTL5000_I2S_LRPOL; |
498 | break; | 500 | break; |
499 | case SND_SOC_DAIFMT_LEFT_J: | 501 | case SND_SOC_DAIFMT_LEFT_J: |
500 | i2sctl |= SGTL5000_I2S_MODE_I2S_LJ; | 502 | i2sctl |= SGTL5000_I2S_MODE_I2S_LJ << SGTL5000_I2S_MODE_SHIFT; |
501 | i2sctl |= SGTL5000_I2S_LRALIGN; | 503 | i2sctl |= SGTL5000_I2S_LRALIGN; |
502 | break; | 504 | break; |
503 | default: | 505 | default: |
@@ -1462,6 +1464,9 @@ static int sgtl5000_i2c_probe(struct i2c_client *client, | |||
1462 | if (ret) | 1464 | if (ret) |
1463 | return ret; | 1465 | return ret; |
1464 | 1466 | ||
1467 | /* Need 8 clocks before I2C accesses */ | ||
1468 | udelay(1); | ||
1469 | |||
1465 | /* read chip information */ | 1470 | /* read chip information */ |
1466 | ret = regmap_read(sgtl5000->regmap, SGTL5000_CHIP_ID, ®); | 1471 | ret = regmap_read(sgtl5000->regmap, SGTL5000_CHIP_ID, ®); |
1467 | if (ret) | 1472 | if (ret) |
diff --git a/sound/soc/codecs/sn95031.c b/sound/soc/codecs/sn95031.c index 1f451a1946eb..47b257e41809 100644 --- a/sound/soc/codecs/sn95031.c +++ b/sound/soc/codecs/sn95031.c | |||
@@ -233,16 +233,18 @@ static int sn95031_set_vaud_bias(struct snd_soc_codec *codec, | |||
233 | static int sn95031_vhs_event(struct snd_soc_dapm_widget *w, | 233 | static int sn95031_vhs_event(struct snd_soc_dapm_widget *w, |
234 | struct snd_kcontrol *kcontrol, int event) | 234 | struct snd_kcontrol *kcontrol, int event) |
235 | { | 235 | { |
236 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); | ||
237 | |||
236 | if (SND_SOC_DAPM_EVENT_ON(event)) { | 238 | if (SND_SOC_DAPM_EVENT_ON(event)) { |
237 | pr_debug("VHS SND_SOC_DAPM_EVENT_ON doing rail startup now\n"); | 239 | pr_debug("VHS SND_SOC_DAPM_EVENT_ON doing rail startup now\n"); |
238 | /* power up the rail */ | 240 | /* power up the rail */ |
239 | snd_soc_write(w->codec, SN95031_VHSP, 0x3D); | 241 | snd_soc_write(codec, SN95031_VHSP, 0x3D); |
240 | snd_soc_write(w->codec, SN95031_VHSN, 0x3F); | 242 | snd_soc_write(codec, SN95031_VHSN, 0x3F); |
241 | msleep(1); | 243 | msleep(1); |
242 | } else if (SND_SOC_DAPM_EVENT_OFF(event)) { | 244 | } else if (SND_SOC_DAPM_EVENT_OFF(event)) { |
243 | pr_debug("VHS SND_SOC_DAPM_EVENT_OFF doing rail shutdown\n"); | 245 | pr_debug("VHS SND_SOC_DAPM_EVENT_OFF doing rail shutdown\n"); |
244 | snd_soc_write(w->codec, SN95031_VHSP, 0xC4); | 246 | snd_soc_write(codec, SN95031_VHSP, 0xC4); |
245 | snd_soc_write(w->codec, SN95031_VHSN, 0x04); | 247 | snd_soc_write(codec, SN95031_VHSN, 0x04); |
246 | } | 248 | } |
247 | return 0; | 249 | return 0; |
248 | } | 250 | } |
@@ -250,14 +252,16 @@ static int sn95031_vhs_event(struct snd_soc_dapm_widget *w, | |||
250 | static int sn95031_vihf_event(struct snd_soc_dapm_widget *w, | 252 | static int sn95031_vihf_event(struct snd_soc_dapm_widget *w, |
251 | struct snd_kcontrol *kcontrol, int event) | 253 | struct snd_kcontrol *kcontrol, int event) |
252 | { | 254 | { |
255 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); | ||
256 | |||
253 | if (SND_SOC_DAPM_EVENT_ON(event)) { | 257 | if (SND_SOC_DAPM_EVENT_ON(event)) { |
254 | pr_debug("VIHF SND_SOC_DAPM_EVENT_ON doing rail startup now\n"); | 258 | pr_debug("VIHF SND_SOC_DAPM_EVENT_ON doing rail startup now\n"); |
255 | /* power up the rail */ | 259 | /* power up the rail */ |
256 | snd_soc_write(w->codec, SN95031_VIHF, 0x27); | 260 | snd_soc_write(codec, SN95031_VIHF, 0x27); |
257 | msleep(1); | 261 | msleep(1); |
258 | } else if (SND_SOC_DAPM_EVENT_OFF(event)) { | 262 | } else if (SND_SOC_DAPM_EVENT_OFF(event)) { |
259 | pr_debug("VIHF SND_SOC_DAPM_EVENT_OFF doing rail shutdown\n"); | 263 | pr_debug("VIHF SND_SOC_DAPM_EVENT_OFF doing rail shutdown\n"); |
260 | snd_soc_write(w->codec, SN95031_VIHF, 0x24); | 264 | snd_soc_write(codec, SN95031_VIHF, 0x24); |
261 | } | 265 | } |
262 | return 0; | 266 | return 0; |
263 | } | 267 | } |
@@ -265,6 +269,7 @@ static int sn95031_vihf_event(struct snd_soc_dapm_widget *w, | |||
265 | static int sn95031_dmic12_event(struct snd_soc_dapm_widget *w, | 269 | static int sn95031_dmic12_event(struct snd_soc_dapm_widget *w, |
266 | struct snd_kcontrol *k, int event) | 270 | struct snd_kcontrol *k, int event) |
267 | { | 271 | { |
272 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); | ||
268 | unsigned int ldo = 0, clk_dir = 0, data_dir = 0; | 273 | unsigned int ldo = 0, clk_dir = 0, data_dir = 0; |
269 | 274 | ||
270 | if (SND_SOC_DAPM_EVENT_ON(event)) { | 275 | if (SND_SOC_DAPM_EVENT_ON(event)) { |
@@ -273,15 +278,16 @@ static int sn95031_dmic12_event(struct snd_soc_dapm_widget *w, | |||
273 | data_dir = BIT(7); | 278 | data_dir = BIT(7); |
274 | } | 279 | } |
275 | /* program DMIC LDO, clock and set clock */ | 280 | /* program DMIC LDO, clock and set clock */ |
276 | snd_soc_update_bits(w->codec, SN95031_MICBIAS, BIT(5)|BIT(4), ldo); | 281 | snd_soc_update_bits(codec, SN95031_MICBIAS, BIT(5)|BIT(4), ldo); |
277 | snd_soc_update_bits(w->codec, SN95031_DMICBUF0123, BIT(0), clk_dir); | 282 | snd_soc_update_bits(codec, SN95031_DMICBUF0123, BIT(0), clk_dir); |
278 | snd_soc_update_bits(w->codec, SN95031_DMICBUF0123, BIT(7), data_dir); | 283 | snd_soc_update_bits(codec, SN95031_DMICBUF0123, BIT(7), data_dir); |
279 | return 0; | 284 | return 0; |
280 | } | 285 | } |
281 | 286 | ||
282 | static int sn95031_dmic34_event(struct snd_soc_dapm_widget *w, | 287 | static int sn95031_dmic34_event(struct snd_soc_dapm_widget *w, |
283 | struct snd_kcontrol *k, int event) | 288 | struct snd_kcontrol *k, int event) |
284 | { | 289 | { |
290 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); | ||
285 | unsigned int ldo = 0, clk_dir = 0, data_dir = 0; | 291 | unsigned int ldo = 0, clk_dir = 0, data_dir = 0; |
286 | 292 | ||
287 | if (SND_SOC_DAPM_EVENT_ON(event)) { | 293 | if (SND_SOC_DAPM_EVENT_ON(event)) { |
@@ -290,22 +296,23 @@ static int sn95031_dmic34_event(struct snd_soc_dapm_widget *w, | |||
290 | data_dir = BIT(1); | 296 | data_dir = BIT(1); |
291 | } | 297 | } |
292 | /* program DMIC LDO, clock and set clock */ | 298 | /* program DMIC LDO, clock and set clock */ |
293 | snd_soc_update_bits(w->codec, SN95031_MICBIAS, BIT(5)|BIT(4), ldo); | 299 | snd_soc_update_bits(codec, SN95031_MICBIAS, BIT(5)|BIT(4), ldo); |
294 | snd_soc_update_bits(w->codec, SN95031_DMICBUF0123, BIT(2), clk_dir); | 300 | snd_soc_update_bits(codec, SN95031_DMICBUF0123, BIT(2), clk_dir); |
295 | snd_soc_update_bits(w->codec, SN95031_DMICBUF45, BIT(1), data_dir); | 301 | snd_soc_update_bits(codec, SN95031_DMICBUF45, BIT(1), data_dir); |
296 | return 0; | 302 | return 0; |
297 | } | 303 | } |
298 | 304 | ||
299 | static int sn95031_dmic56_event(struct snd_soc_dapm_widget *w, | 305 | static int sn95031_dmic56_event(struct snd_soc_dapm_widget *w, |
300 | struct snd_kcontrol *k, int event) | 306 | struct snd_kcontrol *k, int event) |
301 | { | 307 | { |
308 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); | ||
302 | unsigned int ldo = 0; | 309 | unsigned int ldo = 0; |
303 | 310 | ||
304 | if (SND_SOC_DAPM_EVENT_ON(event)) | 311 | if (SND_SOC_DAPM_EVENT_ON(event)) |
305 | ldo = BIT(7)|BIT(6); | 312 | ldo = BIT(7)|BIT(6); |
306 | 313 | ||
307 | /* program DMIC LDO */ | 314 | /* program DMIC LDO */ |
308 | snd_soc_update_bits(w->codec, SN95031_MICBIAS, BIT(7)|BIT(6), ldo); | 315 | snd_soc_update_bits(codec, SN95031_MICBIAS, BIT(7)|BIT(6), ldo); |
309 | return 0; | 316 | return 0; |
310 | } | 317 | } |
311 | 318 | ||
diff --git a/sound/soc/codecs/sta32x.c b/sound/soc/codecs/sta32x.c index 7e18200dd6a9..3a1343fa109b 100644 --- a/sound/soc/codecs/sta32x.c +++ b/sound/soc/codecs/sta32x.c | |||
@@ -24,8 +24,11 @@ | |||
24 | #include <linux/delay.h> | 24 | #include <linux/delay.h> |
25 | #include <linux/pm.h> | 25 | #include <linux/pm.h> |
26 | #include <linux/i2c.h> | 26 | #include <linux/i2c.h> |
27 | #include <linux/of_device.h> | ||
28 | #include <linux/of_gpio.h> | ||
27 | #include <linux/regmap.h> | 29 | #include <linux/regmap.h> |
28 | #include <linux/regulator/consumer.h> | 30 | #include <linux/regulator/consumer.h> |
31 | #include <linux/gpio/consumer.h> | ||
29 | #include <linux/slab.h> | 32 | #include <linux/slab.h> |
30 | #include <linux/workqueue.h> | 33 | #include <linux/workqueue.h> |
31 | #include <sound/core.h> | 34 | #include <sound/core.h> |
@@ -102,6 +105,35 @@ static const struct reg_default sta32x_regs[] = { | |||
102 | { 0x2c, 0x0c }, | 105 | { 0x2c, 0x0c }, |
103 | }; | 106 | }; |
104 | 107 | ||
108 | static const struct regmap_range sta32x_write_regs_range[] = { | ||
109 | regmap_reg_range(STA32X_CONFA, STA32X_AUTO2), | ||
110 | regmap_reg_range(STA32X_C1CFG, STA32X_FDRC2), | ||
111 | }; | ||
112 | |||
113 | static const struct regmap_range sta32x_read_regs_range[] = { | ||
114 | regmap_reg_range(STA32X_CONFA, STA32X_AUTO2), | ||
115 | regmap_reg_range(STA32X_C1CFG, STA32X_FDRC2), | ||
116 | }; | ||
117 | |||
118 | static const struct regmap_range sta32x_volatile_regs_range[] = { | ||
119 | regmap_reg_range(STA32X_CFADDR2, STA32X_CFUD), | ||
120 | }; | ||
121 | |||
122 | static const struct regmap_access_table sta32x_write_regs = { | ||
123 | .yes_ranges = sta32x_write_regs_range, | ||
124 | .n_yes_ranges = ARRAY_SIZE(sta32x_write_regs_range), | ||
125 | }; | ||
126 | |||
127 | static const struct regmap_access_table sta32x_read_regs = { | ||
128 | .yes_ranges = sta32x_read_regs_range, | ||
129 | .n_yes_ranges = ARRAY_SIZE(sta32x_read_regs_range), | ||
130 | }; | ||
131 | |||
132 | static const struct regmap_access_table sta32x_volatile_regs = { | ||
133 | .yes_ranges = sta32x_volatile_regs_range, | ||
134 | .n_yes_ranges = ARRAY_SIZE(sta32x_volatile_regs_range), | ||
135 | }; | ||
136 | |||
105 | /* regulator power supply names */ | 137 | /* regulator power supply names */ |
106 | static const char *sta32x_supply_names[] = { | 138 | static const char *sta32x_supply_names[] = { |
107 | "Vdda", /* analog supply, 3.3VV */ | 139 | "Vdda", /* analog supply, 3.3VV */ |
@@ -122,6 +154,8 @@ struct sta32x_priv { | |||
122 | u32 coef_shadow[STA32X_COEF_COUNT]; | 154 | u32 coef_shadow[STA32X_COEF_COUNT]; |
123 | struct delayed_work watchdog_work; | 155 | struct delayed_work watchdog_work; |
124 | int shutdown; | 156 | int shutdown; |
157 | struct gpio_desc *gpiod_nreset; | ||
158 | struct mutex coeff_lock; | ||
125 | }; | 159 | }; |
126 | 160 | ||
127 | static const DECLARE_TLV_DB_SCALE(mvol_tlv, -12700, 50, 1); | 161 | static const DECLARE_TLV_DB_SCALE(mvol_tlv, -12700, 50, 1); |
@@ -155,37 +189,32 @@ static const char *sta32x_limiter_release_rate[] = { | |||
155 | "0.5116", "0.1370", "0.0744", "0.0499", "0.0360", "0.0299", | 189 | "0.5116", "0.1370", "0.0744", "0.0499", "0.0360", "0.0299", |
156 | "0.0264", "0.0208", "0.0198", "0.0172", "0.0147", "0.0137", | 190 | "0.0264", "0.0208", "0.0198", "0.0172", "0.0147", "0.0137", |
157 | "0.0134", "0.0117", "0.0110", "0.0104" }; | 191 | "0.0134", "0.0117", "0.0110", "0.0104" }; |
158 | 192 | static DECLARE_TLV_DB_RANGE(sta32x_limiter_ac_attack_tlv, | |
159 | static const unsigned int sta32x_limiter_ac_attack_tlv[] = { | ||
160 | TLV_DB_RANGE_HEAD(2), | ||
161 | 0, 7, TLV_DB_SCALE_ITEM(-1200, 200, 0), | 193 | 0, 7, TLV_DB_SCALE_ITEM(-1200, 200, 0), |
162 | 8, 16, TLV_DB_SCALE_ITEM(300, 100, 0), | 194 | 8, 16, TLV_DB_SCALE_ITEM(300, 100, 0), |
163 | }; | 195 | ); |
164 | 196 | ||
165 | static const unsigned int sta32x_limiter_ac_release_tlv[] = { | 197 | static DECLARE_TLV_DB_RANGE(sta32x_limiter_ac_release_tlv, |
166 | TLV_DB_RANGE_HEAD(5), | ||
167 | 0, 0, TLV_DB_SCALE_ITEM(TLV_DB_GAIN_MUTE, 0, 0), | 198 | 0, 0, TLV_DB_SCALE_ITEM(TLV_DB_GAIN_MUTE, 0, 0), |
168 | 1, 1, TLV_DB_SCALE_ITEM(-2900, 0, 0), | 199 | 1, 1, TLV_DB_SCALE_ITEM(-2900, 0, 0), |
169 | 2, 2, TLV_DB_SCALE_ITEM(-2000, 0, 0), | 200 | 2, 2, TLV_DB_SCALE_ITEM(-2000, 0, 0), |
170 | 3, 8, TLV_DB_SCALE_ITEM(-1400, 200, 0), | 201 | 3, 8, TLV_DB_SCALE_ITEM(-1400, 200, 0), |
171 | 8, 16, TLV_DB_SCALE_ITEM(-700, 100, 0), | 202 | 8, 16, TLV_DB_SCALE_ITEM(-700, 100, 0), |
172 | }; | 203 | ); |
173 | 204 | ||
174 | static const unsigned int sta32x_limiter_drc_attack_tlv[] = { | 205 | static DECLARE_TLV_DB_RANGE(sta32x_limiter_drc_attack_tlv, |
175 | TLV_DB_RANGE_HEAD(3), | ||
176 | 0, 7, TLV_DB_SCALE_ITEM(-3100, 200, 0), | 206 | 0, 7, TLV_DB_SCALE_ITEM(-3100, 200, 0), |
177 | 8, 13, TLV_DB_SCALE_ITEM(-1600, 100, 0), | 207 | 8, 13, TLV_DB_SCALE_ITEM(-1600, 100, 0), |
178 | 14, 16, TLV_DB_SCALE_ITEM(-1000, 300, 0), | 208 | 14, 16, TLV_DB_SCALE_ITEM(-1000, 300, 0), |
179 | }; | 209 | ); |
180 | 210 | ||
181 | static const unsigned int sta32x_limiter_drc_release_tlv[] = { | 211 | static DECLARE_TLV_DB_RANGE(sta32x_limiter_drc_release_tlv, |
182 | TLV_DB_RANGE_HEAD(5), | ||
183 | 0, 0, TLV_DB_SCALE_ITEM(TLV_DB_GAIN_MUTE, 0, 0), | 212 | 0, 0, TLV_DB_SCALE_ITEM(TLV_DB_GAIN_MUTE, 0, 0), |
184 | 1, 2, TLV_DB_SCALE_ITEM(-3800, 200, 0), | 213 | 1, 2, TLV_DB_SCALE_ITEM(-3800, 200, 0), |
185 | 3, 4, TLV_DB_SCALE_ITEM(-3300, 200, 0), | 214 | 3, 4, TLV_DB_SCALE_ITEM(-3300, 200, 0), |
186 | 5, 12, TLV_DB_SCALE_ITEM(-3000, 200, 0), | 215 | 5, 12, TLV_DB_SCALE_ITEM(-3000, 200, 0), |
187 | 13, 16, TLV_DB_SCALE_ITEM(-1500, 300, 0), | 216 | 13, 16, TLV_DB_SCALE_ITEM(-1500, 300, 0), |
188 | }; | 217 | ); |
189 | 218 | ||
190 | static SOC_ENUM_SINGLE_DECL(sta32x_drc_ac_enum, | 219 | static SOC_ENUM_SINGLE_DECL(sta32x_drc_ac_enum, |
191 | STA32X_CONFD, STA32X_CONFD_DRC_SHIFT, | 220 | STA32X_CONFD, STA32X_CONFD_DRC_SHIFT, |
@@ -244,29 +273,42 @@ static int sta32x_coefficient_get(struct snd_kcontrol *kcontrol, | |||
244 | struct snd_ctl_elem_value *ucontrol) | 273 | struct snd_ctl_elem_value *ucontrol) |
245 | { | 274 | { |
246 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); | 275 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
276 | struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec); | ||
247 | int numcoef = kcontrol->private_value >> 16; | 277 | int numcoef = kcontrol->private_value >> 16; |
248 | int index = kcontrol->private_value & 0xffff; | 278 | int index = kcontrol->private_value & 0xffff; |
249 | unsigned int cfud; | 279 | unsigned int cfud, val; |
250 | int i; | 280 | int i, ret = 0; |
281 | |||
282 | mutex_lock(&sta32x->coeff_lock); | ||
251 | 283 | ||
252 | /* preserve reserved bits in STA32X_CFUD */ | 284 | /* preserve reserved bits in STA32X_CFUD */ |
253 | cfud = snd_soc_read(codec, STA32X_CFUD) & 0xf0; | 285 | regmap_read(sta32x->regmap, STA32X_CFUD, &cfud); |
254 | /* chip documentation does not say if the bits are self clearing, | 286 | cfud &= 0xf0; |
255 | * so do it explicitly */ | 287 | /* |
256 | snd_soc_write(codec, STA32X_CFUD, cfud); | 288 | * chip documentation does not say if the bits are self clearing, |
289 | * so do it explicitly | ||
290 | */ | ||
291 | regmap_write(sta32x->regmap, STA32X_CFUD, cfud); | ||
257 | 292 | ||
258 | snd_soc_write(codec, STA32X_CFADDR2, index); | 293 | regmap_write(sta32x->regmap, STA32X_CFADDR2, index); |
259 | if (numcoef == 1) | 294 | if (numcoef == 1) { |
260 | snd_soc_write(codec, STA32X_CFUD, cfud | 0x04); | 295 | regmap_write(sta32x->regmap, STA32X_CFUD, cfud | 0x04); |
261 | else if (numcoef == 5) | 296 | } else if (numcoef == 5) { |
262 | snd_soc_write(codec, STA32X_CFUD, cfud | 0x08); | 297 | regmap_write(sta32x->regmap, STA32X_CFUD, cfud | 0x08); |
263 | else | 298 | } else { |
264 | return -EINVAL; | 299 | ret = -EINVAL; |
265 | for (i = 0; i < 3 * numcoef; i++) | 300 | goto exit_unlock; |
266 | ucontrol->value.bytes.data[i] = | 301 | } |
267 | snd_soc_read(codec, STA32X_B1CF1 + i); | ||
268 | 302 | ||
269 | return 0; | 303 | for (i = 0; i < 3 * numcoef; i++) { |
304 | regmap_read(sta32x->regmap, STA32X_B1CF1 + i, &val); | ||
305 | ucontrol->value.bytes.data[i] = val; | ||
306 | } | ||
307 | |||
308 | exit_unlock: | ||
309 | mutex_unlock(&sta32x->coeff_lock); | ||
310 | |||
311 | return ret; | ||
270 | } | 312 | } |
271 | 313 | ||
272 | static int sta32x_coefficient_put(struct snd_kcontrol *kcontrol, | 314 | static int sta32x_coefficient_put(struct snd_kcontrol *kcontrol, |
@@ -280,24 +322,27 @@ static int sta32x_coefficient_put(struct snd_kcontrol *kcontrol, | |||
280 | int i; | 322 | int i; |
281 | 323 | ||
282 | /* preserve reserved bits in STA32X_CFUD */ | 324 | /* preserve reserved bits in STA32X_CFUD */ |
283 | cfud = snd_soc_read(codec, STA32X_CFUD) & 0xf0; | 325 | regmap_read(sta32x->regmap, STA32X_CFUD, &cfud); |
284 | /* chip documentation does not say if the bits are self clearing, | 326 | cfud &= 0xf0; |
285 | * so do it explicitly */ | 327 | /* |
286 | snd_soc_write(codec, STA32X_CFUD, cfud); | 328 | * chip documentation does not say if the bits are self clearing, |
329 | * so do it explicitly | ||
330 | */ | ||
331 | regmap_write(sta32x->regmap, STA32X_CFUD, cfud); | ||
287 | 332 | ||
288 | snd_soc_write(codec, STA32X_CFADDR2, index); | 333 | regmap_write(sta32x->regmap, STA32X_CFADDR2, index); |
289 | for (i = 0; i < numcoef && (index + i < STA32X_COEF_COUNT); i++) | 334 | for (i = 0; i < numcoef && (index + i < STA32X_COEF_COUNT); i++) |
290 | sta32x->coef_shadow[index + i] = | 335 | sta32x->coef_shadow[index + i] = |
291 | (ucontrol->value.bytes.data[3 * i] << 16) | 336 | (ucontrol->value.bytes.data[3 * i] << 16) |
292 | | (ucontrol->value.bytes.data[3 * i + 1] << 8) | 337 | | (ucontrol->value.bytes.data[3 * i + 1] << 8) |
293 | | (ucontrol->value.bytes.data[3 * i + 2]); | 338 | | (ucontrol->value.bytes.data[3 * i + 2]); |
294 | for (i = 0; i < 3 * numcoef; i++) | 339 | for (i = 0; i < 3 * numcoef; i++) |
295 | snd_soc_write(codec, STA32X_B1CF1 + i, | 340 | regmap_write(sta32x->regmap, STA32X_B1CF1 + i, |
296 | ucontrol->value.bytes.data[i]); | 341 | ucontrol->value.bytes.data[i]); |
297 | if (numcoef == 1) | 342 | if (numcoef == 1) |
298 | snd_soc_write(codec, STA32X_CFUD, cfud | 0x01); | 343 | regmap_write(sta32x->regmap, STA32X_CFUD, cfud | 0x01); |
299 | else if (numcoef == 5) | 344 | else if (numcoef == 5) |
300 | snd_soc_write(codec, STA32X_CFUD, cfud | 0x02); | 345 | regmap_write(sta32x->regmap, STA32X_CFUD, cfud | 0x02); |
301 | else | 346 | else |
302 | return -EINVAL; | 347 | return -EINVAL; |
303 | 348 | ||
@@ -311,20 +356,23 @@ static int sta32x_sync_coef_shadow(struct snd_soc_codec *codec) | |||
311 | int i; | 356 | int i; |
312 | 357 | ||
313 | /* preserve reserved bits in STA32X_CFUD */ | 358 | /* preserve reserved bits in STA32X_CFUD */ |
314 | cfud = snd_soc_read(codec, STA32X_CFUD) & 0xf0; | 359 | regmap_read(sta32x->regmap, STA32X_CFUD, &cfud); |
360 | cfud &= 0xf0; | ||
315 | 361 | ||
316 | for (i = 0; i < STA32X_COEF_COUNT; i++) { | 362 | for (i = 0; i < STA32X_COEF_COUNT; i++) { |
317 | snd_soc_write(codec, STA32X_CFADDR2, i); | 363 | regmap_write(sta32x->regmap, STA32X_CFADDR2, i); |
318 | snd_soc_write(codec, STA32X_B1CF1, | 364 | regmap_write(sta32x->regmap, STA32X_B1CF1, |
319 | (sta32x->coef_shadow[i] >> 16) & 0xff); | 365 | (sta32x->coef_shadow[i] >> 16) & 0xff); |
320 | snd_soc_write(codec, STA32X_B1CF2, | 366 | regmap_write(sta32x->regmap, STA32X_B1CF2, |
321 | (sta32x->coef_shadow[i] >> 8) & 0xff); | 367 | (sta32x->coef_shadow[i] >> 8) & 0xff); |
322 | snd_soc_write(codec, STA32X_B1CF3, | 368 | regmap_write(sta32x->regmap, STA32X_B1CF3, |
323 | (sta32x->coef_shadow[i]) & 0xff); | 369 | (sta32x->coef_shadow[i]) & 0xff); |
324 | /* chip documentation does not say if the bits are | 370 | /* |
325 | * self-clearing, so do it explicitly */ | 371 | * chip documentation does not say if the bits are |
326 | snd_soc_write(codec, STA32X_CFUD, cfud); | 372 | * self-clearing, so do it explicitly |
327 | snd_soc_write(codec, STA32X_CFUD, cfud | 0x01); | 373 | */ |
374 | regmap_write(sta32x->regmap, STA32X_CFUD, cfud); | ||
375 | regmap_write(sta32x->regmap, STA32X_CFUD, cfud | 0x01); | ||
328 | } | 376 | } |
329 | return 0; | 377 | return 0; |
330 | } | 378 | } |
@@ -336,11 +384,11 @@ static int sta32x_cache_sync(struct snd_soc_codec *codec) | |||
336 | int rc; | 384 | int rc; |
337 | 385 | ||
338 | /* mute during register sync */ | 386 | /* mute during register sync */ |
339 | mute = snd_soc_read(codec, STA32X_MMUTE); | 387 | regmap_read(sta32x->regmap, STA32X_MMUTE, &mute); |
340 | snd_soc_write(codec, STA32X_MMUTE, mute | STA32X_MMUTE_MMUTE); | 388 | regmap_write(sta32x->regmap, STA32X_MMUTE, mute | STA32X_MMUTE_MMUTE); |
341 | sta32x_sync_coef_shadow(codec); | 389 | sta32x_sync_coef_shadow(codec); |
342 | rc = regcache_sync(sta32x->regmap); | 390 | rc = regcache_sync(sta32x->regmap); |
343 | snd_soc_write(codec, STA32X_MMUTE, mute); | 391 | regmap_write(sta32x->regmap, STA32X_MMUTE, mute); |
344 | return rc; | 392 | return rc; |
345 | } | 393 | } |
346 | 394 | ||
@@ -508,17 +556,12 @@ static struct { | |||
508 | }; | 556 | }; |
509 | 557 | ||
510 | /* MCLK to fs clock ratios */ | 558 | /* MCLK to fs clock ratios */ |
511 | static struct { | 559 | static int mcs_ratio_table[3][7] = { |
512 | int ratio; | 560 | { 768, 512, 384, 256, 128, 576, 0 }, |
513 | int mcs; | 561 | { 384, 256, 192, 128, 64, 0 }, |
514 | } mclk_ratios[3][7] = { | 562 | { 384, 256, 192, 128, 64, 0 }, |
515 | { { 768, 0 }, { 512, 1 }, { 384, 2 }, { 256, 3 }, | ||
516 | { 128, 4 }, { 576, 5 }, { 0, 0 } }, | ||
517 | { { 384, 2 }, { 256, 3 }, { 192, 4 }, { 128, 5 }, {64, 0 }, { 0, 0 } }, | ||
518 | { { 384, 2 }, { 256, 3 }, { 192, 4 }, { 128, 5 }, {64, 0 }, { 0, 0 } }, | ||
519 | }; | 563 | }; |
520 | 564 | ||
521 | |||
522 | /** | 565 | /** |
523 | * sta32x_set_dai_sysclk - configure MCLK | 566 | * sta32x_set_dai_sysclk - configure MCLK |
524 | * @codec_dai: the codec DAI | 567 | * @codec_dai: the codec DAI |
@@ -543,46 +586,10 @@ static int sta32x_set_dai_sysclk(struct snd_soc_dai *codec_dai, | |||
543 | { | 586 | { |
544 | struct snd_soc_codec *codec = codec_dai->codec; | 587 | struct snd_soc_codec *codec = codec_dai->codec; |
545 | struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec); | 588 | struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec); |
546 | int i, j, ir, fs; | ||
547 | unsigned int rates = 0; | ||
548 | unsigned int rate_min = -1; | ||
549 | unsigned int rate_max = 0; | ||
550 | 589 | ||
551 | pr_debug("mclk=%u\n", freq); | 590 | dev_dbg(codec->dev, "mclk=%u\n", freq); |
552 | sta32x->mclk = freq; | 591 | sta32x->mclk = freq; |
553 | 592 | ||
554 | if (sta32x->mclk) { | ||
555 | for (i = 0; i < ARRAY_SIZE(interpolation_ratios); i++) { | ||
556 | ir = interpolation_ratios[i].ir; | ||
557 | fs = interpolation_ratios[i].fs; | ||
558 | for (j = 0; mclk_ratios[ir][j].ratio; j++) { | ||
559 | if (mclk_ratios[ir][j].ratio * fs == freq) { | ||
560 | rates |= snd_pcm_rate_to_rate_bit(fs); | ||
561 | if (fs < rate_min) | ||
562 | rate_min = fs; | ||
563 | if (fs > rate_max) | ||
564 | rate_max = fs; | ||
565 | break; | ||
566 | } | ||
567 | } | ||
568 | } | ||
569 | /* FIXME: soc should support a rate list */ | ||
570 | rates &= ~SNDRV_PCM_RATE_KNOT; | ||
571 | |||
572 | if (!rates) { | ||
573 | dev_err(codec->dev, "could not find a valid sample rate\n"); | ||
574 | return -EINVAL; | ||
575 | } | ||
576 | } else { | ||
577 | /* enable all possible rates */ | ||
578 | rates = STA32X_RATES; | ||
579 | rate_min = 32000; | ||
580 | rate_max = 192000; | ||
581 | } | ||
582 | |||
583 | codec_dai->driver->playback.rates = rates; | ||
584 | codec_dai->driver->playback.rate_min = rate_min; | ||
585 | codec_dai->driver->playback.rate_max = rate_max; | ||
586 | return 0; | 593 | return 0; |
587 | } | 594 | } |
588 | 595 | ||
@@ -599,10 +606,7 @@ static int sta32x_set_dai_fmt(struct snd_soc_dai *codec_dai, | |||
599 | { | 606 | { |
600 | struct snd_soc_codec *codec = codec_dai->codec; | 607 | struct snd_soc_codec *codec = codec_dai->codec; |
601 | struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec); | 608 | struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec); |
602 | u8 confb = snd_soc_read(codec, STA32X_CONFB); | 609 | u8 confb = 0; |
603 | |||
604 | pr_debug("\n"); | ||
605 | confb &= ~(STA32X_CONFB_C1IM | STA32X_CONFB_C2IM); | ||
606 | 610 | ||
607 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { | 611 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { |
608 | case SND_SOC_DAIFMT_CBS_CFS: | 612 | case SND_SOC_DAIFMT_CBS_CFS: |
@@ -632,8 +636,8 @@ static int sta32x_set_dai_fmt(struct snd_soc_dai *codec_dai, | |||
632 | return -EINVAL; | 636 | return -EINVAL; |
633 | } | 637 | } |
634 | 638 | ||
635 | snd_soc_write(codec, STA32X_CONFB, confb); | 639 | return regmap_update_bits(sta32x->regmap, STA32X_CONFB, |
636 | return 0; | 640 | STA32X_CONFB_C1IM | STA32X_CONFB_C2IM, confb); |
637 | } | 641 | } |
638 | 642 | ||
639 | /** | 643 | /** |
@@ -651,39 +655,55 @@ static int sta32x_hw_params(struct snd_pcm_substream *substream, | |||
651 | { | 655 | { |
652 | struct snd_soc_codec *codec = dai->codec; | 656 | struct snd_soc_codec *codec = dai->codec; |
653 | struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec); | 657 | struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec); |
654 | unsigned int rate; | 658 | int i, mcs = -EINVAL, ir = -EINVAL; |
655 | int i, mcs = -1, ir = -1; | 659 | unsigned int confa, confb; |
656 | u8 confa, confb; | 660 | unsigned int rate, ratio; |
661 | int ret; | ||
662 | |||
663 | if (!sta32x->mclk) { | ||
664 | dev_err(codec->dev, | ||
665 | "sta32x->mclk is unset. Unable to determine ratio\n"); | ||
666 | return -EIO; | ||
667 | } | ||
657 | 668 | ||
658 | rate = params_rate(params); | 669 | rate = params_rate(params); |
659 | pr_debug("rate: %u\n", rate); | 670 | ratio = sta32x->mclk / rate; |
660 | for (i = 0; i < ARRAY_SIZE(interpolation_ratios); i++) | 671 | dev_dbg(codec->dev, "rate: %u, ratio: %u\n", rate, ratio); |
672 | |||
673 | for (i = 0; i < ARRAY_SIZE(interpolation_ratios); i++) { | ||
661 | if (interpolation_ratios[i].fs == rate) { | 674 | if (interpolation_ratios[i].fs == rate) { |
662 | ir = interpolation_ratios[i].ir; | 675 | ir = interpolation_ratios[i].ir; |
663 | break; | 676 | break; |
664 | } | 677 | } |
665 | if (ir < 0) | 678 | } |
679 | |||
680 | if (ir < 0) { | ||
681 | dev_err(codec->dev, "Unsupported samplerate: %u\n", rate); | ||
666 | return -EINVAL; | 682 | return -EINVAL; |
667 | for (i = 0; mclk_ratios[ir][i].ratio; i++) | 683 | } |
668 | if (mclk_ratios[ir][i].ratio * rate == sta32x->mclk) { | 684 | |
669 | mcs = mclk_ratios[ir][i].mcs; | 685 | for (i = 0; i < 6; i++) { |
686 | if (mcs_ratio_table[ir][i] == ratio) { | ||
687 | mcs = i; | ||
670 | break; | 688 | break; |
671 | } | 689 | } |
672 | if (mcs < 0) | 690 | } |
691 | |||
692 | if (mcs < 0) { | ||
693 | dev_err(codec->dev, "Unresolvable ratio: %u\n", ratio); | ||
673 | return -EINVAL; | 694 | return -EINVAL; |
695 | } | ||
674 | 696 | ||
675 | confa = snd_soc_read(codec, STA32X_CONFA); | 697 | confa = (ir << STA32X_CONFA_IR_SHIFT) | |
676 | confa &= ~(STA32X_CONFA_MCS_MASK | STA32X_CONFA_IR_MASK); | 698 | (mcs << STA32X_CONFA_MCS_SHIFT); |
677 | confa |= (ir << STA32X_CONFA_IR_SHIFT) | (mcs << STA32X_CONFA_MCS_SHIFT); | 699 | confb = 0; |
678 | 700 | ||
679 | confb = snd_soc_read(codec, STA32X_CONFB); | ||
680 | confb &= ~(STA32X_CONFB_SAI_MASK | STA32X_CONFB_SAIFB); | ||
681 | switch (params_width(params)) { | 701 | switch (params_width(params)) { |
682 | case 24: | 702 | case 24: |
683 | pr_debug("24bit\n"); | 703 | dev_dbg(codec->dev, "24bit\n"); |
684 | /* fall through */ | 704 | /* fall through */ |
685 | case 32: | 705 | case 32: |
686 | pr_debug("24bit or 32bit\n"); | 706 | dev_dbg(codec->dev, "24bit or 32bit\n"); |
687 | switch (sta32x->format) { | 707 | switch (sta32x->format) { |
688 | case SND_SOC_DAIFMT_I2S: | 708 | case SND_SOC_DAIFMT_I2S: |
689 | confb |= 0x0; | 709 | confb |= 0x0; |
@@ -698,7 +718,7 @@ static int sta32x_hw_params(struct snd_pcm_substream *substream, | |||
698 | 718 | ||
699 | break; | 719 | break; |
700 | case 20: | 720 | case 20: |
701 | pr_debug("20bit\n"); | 721 | dev_dbg(codec->dev, "20bit\n"); |
702 | switch (sta32x->format) { | 722 | switch (sta32x->format) { |
703 | case SND_SOC_DAIFMT_I2S: | 723 | case SND_SOC_DAIFMT_I2S: |
704 | confb |= 0x4; | 724 | confb |= 0x4; |
@@ -713,7 +733,7 @@ static int sta32x_hw_params(struct snd_pcm_substream *substream, | |||
713 | 733 | ||
714 | break; | 734 | break; |
715 | case 18: | 735 | case 18: |
716 | pr_debug("18bit\n"); | 736 | dev_dbg(codec->dev, "18bit\n"); |
717 | switch (sta32x->format) { | 737 | switch (sta32x->format) { |
718 | case SND_SOC_DAIFMT_I2S: | 738 | case SND_SOC_DAIFMT_I2S: |
719 | confb |= 0x8; | 739 | confb |= 0x8; |
@@ -728,7 +748,7 @@ static int sta32x_hw_params(struct snd_pcm_substream *substream, | |||
728 | 748 | ||
729 | break; | 749 | break; |
730 | case 16: | 750 | case 16: |
731 | pr_debug("16bit\n"); | 751 | dev_dbg(codec->dev, "16bit\n"); |
732 | switch (sta32x->format) { | 752 | switch (sta32x->format) { |
733 | case SND_SOC_DAIFMT_I2S: | 753 | case SND_SOC_DAIFMT_I2S: |
734 | confb |= 0x0; | 754 | confb |= 0x0; |
@@ -746,8 +766,30 @@ static int sta32x_hw_params(struct snd_pcm_substream *substream, | |||
746 | return -EINVAL; | 766 | return -EINVAL; |
747 | } | 767 | } |
748 | 768 | ||
749 | snd_soc_write(codec, STA32X_CONFA, confa); | 769 | ret = regmap_update_bits(sta32x->regmap, STA32X_CONFA, |
750 | snd_soc_write(codec, STA32X_CONFB, confb); | 770 | STA32X_CONFA_MCS_MASK | STA32X_CONFA_IR_MASK, |
771 | confa); | ||
772 | if (ret < 0) | ||
773 | return ret; | ||
774 | |||
775 | ret = regmap_update_bits(sta32x->regmap, STA32X_CONFB, | ||
776 | STA32X_CONFB_SAI_MASK | STA32X_CONFB_SAIFB, | ||
777 | confb); | ||
778 | if (ret < 0) | ||
779 | return ret; | ||
780 | |||
781 | return 0; | ||
782 | } | ||
783 | |||
784 | static int sta32x_startup_sequence(struct sta32x_priv *sta32x) | ||
785 | { | ||
786 | if (sta32x->gpiod_nreset) { | ||
787 | gpiod_set_value(sta32x->gpiod_nreset, 0); | ||
788 | mdelay(1); | ||
789 | gpiod_set_value(sta32x->gpiod_nreset, 1); | ||
790 | mdelay(1); | ||
791 | } | ||
792 | |||
751 | return 0; | 793 | return 0; |
752 | } | 794 | } |
753 | 795 | ||
@@ -766,14 +808,14 @@ static int sta32x_set_bias_level(struct snd_soc_codec *codec, | |||
766 | int ret; | 808 | int ret; |
767 | struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec); | 809 | struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec); |
768 | 810 | ||
769 | pr_debug("level = %d\n", level); | 811 | dev_dbg(codec->dev, "level = %d\n", level); |
770 | switch (level) { | 812 | switch (level) { |
771 | case SND_SOC_BIAS_ON: | 813 | case SND_SOC_BIAS_ON: |
772 | break; | 814 | break; |
773 | 815 | ||
774 | case SND_SOC_BIAS_PREPARE: | 816 | case SND_SOC_BIAS_PREPARE: |
775 | /* Full power on */ | 817 | /* Full power on */ |
776 | snd_soc_update_bits(codec, STA32X_CONFF, | 818 | regmap_update_bits(sta32x->regmap, STA32X_CONFF, |
777 | STA32X_CONFF_PWDN | STA32X_CONFF_EAPD, | 819 | STA32X_CONFF_PWDN | STA32X_CONFF_EAPD, |
778 | STA32X_CONFF_PWDN | STA32X_CONFF_EAPD); | 820 | STA32X_CONFF_PWDN | STA32X_CONFF_EAPD); |
779 | break; | 821 | break; |
@@ -788,25 +830,28 @@ static int sta32x_set_bias_level(struct snd_soc_codec *codec, | |||
788 | return ret; | 830 | return ret; |
789 | } | 831 | } |
790 | 832 | ||
833 | sta32x_startup_sequence(sta32x); | ||
791 | sta32x_cache_sync(codec); | 834 | sta32x_cache_sync(codec); |
792 | sta32x_watchdog_start(sta32x); | 835 | sta32x_watchdog_start(sta32x); |
793 | } | 836 | } |
794 | 837 | ||
795 | /* Power up to mute */ | 838 | /* Power down */ |
796 | /* FIXME */ | 839 | regmap_update_bits(sta32x->regmap, STA32X_CONFF, |
797 | snd_soc_update_bits(codec, STA32X_CONFF, | 840 | STA32X_CONFF_PWDN | STA32X_CONFF_EAPD, |
798 | STA32X_CONFF_PWDN | STA32X_CONFF_EAPD, | 841 | 0); |
799 | STA32X_CONFF_PWDN | STA32X_CONFF_EAPD); | ||
800 | 842 | ||
801 | break; | 843 | break; |
802 | 844 | ||
803 | case SND_SOC_BIAS_OFF: | 845 | case SND_SOC_BIAS_OFF: |
804 | /* The chip runs through the power down sequence for us. */ | 846 | /* The chip runs through the power down sequence for us. */ |
805 | snd_soc_update_bits(codec, STA32X_CONFF, | 847 | regmap_update_bits(sta32x->regmap, STA32X_CONFF, |
806 | STA32X_CONFF_PWDN | STA32X_CONFF_EAPD, | 848 | STA32X_CONFF_PWDN | STA32X_CONFF_EAPD, 0); |
807 | STA32X_CONFF_PWDN); | ||
808 | msleep(300); | 849 | msleep(300); |
809 | sta32x_watchdog_stop(sta32x); | 850 | sta32x_watchdog_stop(sta32x); |
851 | |||
852 | if (sta32x->gpiod_nreset) | ||
853 | gpiod_set_value(sta32x->gpiod_nreset, 0); | ||
854 | |||
810 | regulator_bulk_disable(ARRAY_SIZE(sta32x->supplies), | 855 | regulator_bulk_disable(ARRAY_SIZE(sta32x->supplies), |
811 | sta32x->supplies); | 856 | sta32x->supplies); |
812 | break; | 857 | break; |
@@ -822,7 +867,7 @@ static const struct snd_soc_dai_ops sta32x_dai_ops = { | |||
822 | }; | 867 | }; |
823 | 868 | ||
824 | static struct snd_soc_dai_driver sta32x_dai = { | 869 | static struct snd_soc_dai_driver sta32x_dai = { |
825 | .name = "STA32X", | 870 | .name = "sta32x-hifi", |
826 | .playback = { | 871 | .playback = { |
827 | .stream_name = "Playback", | 872 | .stream_name = "Playback", |
828 | .channels_min = 2, | 873 | .channels_min = 2, |
@@ -836,11 +881,8 @@ static struct snd_soc_dai_driver sta32x_dai = { | |||
836 | static int sta32x_probe(struct snd_soc_codec *codec) | 881 | static int sta32x_probe(struct snd_soc_codec *codec) |
837 | { | 882 | { |
838 | struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec); | 883 | struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec); |
884 | struct sta32x_platform_data *pdata = sta32x->pdata; | ||
839 | int i, ret = 0, thermal = 0; | 885 | int i, ret = 0, thermal = 0; |
840 | |||
841 | sta32x->codec = codec; | ||
842 | sta32x->pdata = dev_get_platdata(codec->dev); | ||
843 | |||
844 | ret = regulator_bulk_enable(ARRAY_SIZE(sta32x->supplies), | 886 | ret = regulator_bulk_enable(ARRAY_SIZE(sta32x->supplies), |
845 | sta32x->supplies); | 887 | sta32x->supplies); |
846 | if (ret != 0) { | 888 | if (ret != 0) { |
@@ -848,50 +890,73 @@ static int sta32x_probe(struct snd_soc_codec *codec) | |||
848 | return ret; | 890 | return ret; |
849 | } | 891 | } |
850 | 892 | ||
851 | /* Chip documentation explicitly requires that the reset values | 893 | ret = sta32x_startup_sequence(sta32x); |
852 | * of reserved register bits are left untouched. | 894 | if (ret < 0) { |
853 | * Write the register default value to cache for reserved registers, | 895 | dev_err(codec->dev, "Failed to startup device\n"); |
854 | * so the write to the these registers are suppressed by the cache | 896 | return ret; |
855 | * restore code when it skips writes of default registers. | 897 | } |
856 | */ | 898 | |
857 | regcache_cache_only(sta32x->regmap, true); | 899 | /* CONFA */ |
858 | snd_soc_write(codec, STA32X_CONFC, 0xc2); | 900 | if (!pdata->thermal_warning_recovery) |
859 | snd_soc_write(codec, STA32X_CONFE, 0xc2); | ||
860 | snd_soc_write(codec, STA32X_CONFF, 0x5c); | ||
861 | snd_soc_write(codec, STA32X_MMUTE, 0x10); | ||
862 | snd_soc_write(codec, STA32X_AUTO1, 0x60); | ||
863 | snd_soc_write(codec, STA32X_AUTO3, 0x00); | ||
864 | snd_soc_write(codec, STA32X_C3CFG, 0x40); | ||
865 | regcache_cache_only(sta32x->regmap, false); | ||
866 | |||
867 | /* set thermal warning adjustment and recovery */ | ||
868 | if (!(sta32x->pdata->thermal_conf & STA32X_THERMAL_ADJUSTMENT_ENABLE)) | ||
869 | thermal |= STA32X_CONFA_TWAB; | 901 | thermal |= STA32X_CONFA_TWAB; |
870 | if (!(sta32x->pdata->thermal_conf & STA32X_THERMAL_RECOVERY_ENABLE)) | 902 | if (!pdata->thermal_warning_adjustment) |
871 | thermal |= STA32X_CONFA_TWRB; | 903 | thermal |= STA32X_CONFA_TWRB; |
872 | snd_soc_update_bits(codec, STA32X_CONFA, | 904 | if (!pdata->fault_detect_recovery) |
873 | STA32X_CONFA_TWAB | STA32X_CONFA_TWRB, | 905 | thermal |= STA32X_CONFA_FDRB; |
874 | thermal); | 906 | regmap_update_bits(sta32x->regmap, STA32X_CONFA, |
907 | STA32X_CONFA_TWAB | STA32X_CONFA_TWRB | | ||
908 | STA32X_CONFA_FDRB, | ||
909 | thermal); | ||
910 | |||
911 | /* CONFC */ | ||
912 | regmap_update_bits(sta32x->regmap, STA32X_CONFC, | ||
913 | STA32X_CONFC_CSZ_MASK, | ||
914 | pdata->drop_compensation_ns | ||
915 | << STA32X_CONFC_CSZ_SHIFT); | ||
916 | |||
917 | /* CONFE */ | ||
918 | regmap_update_bits(sta32x->regmap, STA32X_CONFE, | ||
919 | STA32X_CONFE_MPCV, | ||
920 | pdata->max_power_use_mpcc ? | ||
921 | STA32X_CONFE_MPCV : 0); | ||
922 | regmap_update_bits(sta32x->regmap, STA32X_CONFE, | ||
923 | STA32X_CONFE_MPC, | ||
924 | pdata->max_power_correction ? | ||
925 | STA32X_CONFE_MPC : 0); | ||
926 | regmap_update_bits(sta32x->regmap, STA32X_CONFE, | ||
927 | STA32X_CONFE_AME, | ||
928 | pdata->am_reduction_mode ? | ||
929 | STA32X_CONFE_AME : 0); | ||
930 | regmap_update_bits(sta32x->regmap, STA32X_CONFE, | ||
931 | STA32X_CONFE_PWMS, | ||
932 | pdata->odd_pwm_speed_mode ? | ||
933 | STA32X_CONFE_PWMS : 0); | ||
934 | |||
935 | /* CONFF */ | ||
936 | regmap_update_bits(sta32x->regmap, STA32X_CONFF, | ||
937 | STA32X_CONFF_IDE, | ||
938 | pdata->invalid_input_detect_mute ? | ||
939 | STA32X_CONFF_IDE : 0); | ||
875 | 940 | ||
876 | /* select output configuration */ | 941 | /* select output configuration */ |
877 | snd_soc_update_bits(codec, STA32X_CONFF, | 942 | regmap_update_bits(sta32x->regmap, STA32X_CONFF, |
878 | STA32X_CONFF_OCFG_MASK, | 943 | STA32X_CONFF_OCFG_MASK, |
879 | sta32x->pdata->output_conf | 944 | pdata->output_conf |
880 | << STA32X_CONFF_OCFG_SHIFT); | 945 | << STA32X_CONFF_OCFG_SHIFT); |
881 | 946 | ||
882 | /* channel to output mapping */ | 947 | /* channel to output mapping */ |
883 | snd_soc_update_bits(codec, STA32X_C1CFG, | 948 | regmap_update_bits(sta32x->regmap, STA32X_C1CFG, |
884 | STA32X_CxCFG_OM_MASK, | 949 | STA32X_CxCFG_OM_MASK, |
885 | sta32x->pdata->ch1_output_mapping | 950 | pdata->ch1_output_mapping |
886 | << STA32X_CxCFG_OM_SHIFT); | 951 | << STA32X_CxCFG_OM_SHIFT); |
887 | snd_soc_update_bits(codec, STA32X_C2CFG, | 952 | regmap_update_bits(sta32x->regmap, STA32X_C2CFG, |
888 | STA32X_CxCFG_OM_MASK, | 953 | STA32X_CxCFG_OM_MASK, |
889 | sta32x->pdata->ch2_output_mapping | 954 | pdata->ch2_output_mapping |
890 | << STA32X_CxCFG_OM_SHIFT); | 955 | << STA32X_CxCFG_OM_SHIFT); |
891 | snd_soc_update_bits(codec, STA32X_C3CFG, | 956 | regmap_update_bits(sta32x->regmap, STA32X_C3CFG, |
892 | STA32X_CxCFG_OM_MASK, | 957 | STA32X_CxCFG_OM_MASK, |
893 | sta32x->pdata->ch3_output_mapping | 958 | pdata->ch3_output_mapping |
894 | << STA32X_CxCFG_OM_SHIFT); | 959 | << STA32X_CxCFG_OM_SHIFT); |
895 | 960 | ||
896 | /* initialize coefficient shadow RAM with reset values */ | 961 | /* initialize coefficient shadow RAM with reset values */ |
897 | for (i = 4; i <= 49; i += 5) | 962 | for (i = 4; i <= 49; i += 5) |
@@ -924,16 +989,6 @@ static int sta32x_remove(struct snd_soc_codec *codec) | |||
924 | return 0; | 989 | return 0; |
925 | } | 990 | } |
926 | 991 | ||
927 | static bool sta32x_reg_is_volatile(struct device *dev, unsigned int reg) | ||
928 | { | ||
929 | switch (reg) { | ||
930 | case STA32X_CONFA ... STA32X_L2ATRT: | ||
931 | case STA32X_MPCC1 ... STA32X_FDRC2: | ||
932 | return 0; | ||
933 | } | ||
934 | return 1; | ||
935 | } | ||
936 | |||
937 | static const struct snd_soc_codec_driver sta32x_codec = { | 992 | static const struct snd_soc_codec_driver sta32x_codec = { |
938 | .probe = sta32x_probe, | 993 | .probe = sta32x_probe, |
939 | .remove = sta32x_remove, | 994 | .remove = sta32x_remove, |
@@ -954,12 +1009,75 @@ static const struct regmap_config sta32x_regmap = { | |||
954 | .reg_defaults = sta32x_regs, | 1009 | .reg_defaults = sta32x_regs, |
955 | .num_reg_defaults = ARRAY_SIZE(sta32x_regs), | 1010 | .num_reg_defaults = ARRAY_SIZE(sta32x_regs), |
956 | .cache_type = REGCACHE_RBTREE, | 1011 | .cache_type = REGCACHE_RBTREE, |
957 | .volatile_reg = sta32x_reg_is_volatile, | 1012 | .wr_table = &sta32x_write_regs, |
1013 | .rd_table = &sta32x_read_regs, | ||
1014 | .volatile_table = &sta32x_volatile_regs, | ||
958 | }; | 1015 | }; |
959 | 1016 | ||
1017 | #ifdef CONFIG_OF | ||
1018 | static const struct of_device_id st32x_dt_ids[] = { | ||
1019 | { .compatible = "st,sta32x", }, | ||
1020 | { } | ||
1021 | }; | ||
1022 | MODULE_DEVICE_TABLE(of, st32x_dt_ids); | ||
1023 | |||
1024 | static int sta32x_probe_dt(struct device *dev, struct sta32x_priv *sta32x) | ||
1025 | { | ||
1026 | struct device_node *np = dev->of_node; | ||
1027 | struct sta32x_platform_data *pdata; | ||
1028 | u16 tmp; | ||
1029 | |||
1030 | pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); | ||
1031 | if (!pdata) | ||
1032 | return -ENOMEM; | ||
1033 | |||
1034 | of_property_read_u8(np, "st,output-conf", | ||
1035 | &pdata->output_conf); | ||
1036 | of_property_read_u8(np, "st,ch1-output-mapping", | ||
1037 | &pdata->ch1_output_mapping); | ||
1038 | of_property_read_u8(np, "st,ch2-output-mapping", | ||
1039 | &pdata->ch2_output_mapping); | ||
1040 | of_property_read_u8(np, "st,ch3-output-mapping", | ||
1041 | &pdata->ch3_output_mapping); | ||
1042 | |||
1043 | if (of_get_property(np, "st,thermal-warning-recovery", NULL)) | ||
1044 | pdata->thermal_warning_recovery = 1; | ||
1045 | if (of_get_property(np, "st,thermal-warning-adjustment", NULL)) | ||
1046 | pdata->thermal_warning_adjustment = 1; | ||
1047 | if (of_get_property(np, "st,needs_esd_watchdog", NULL)) | ||
1048 | pdata->needs_esd_watchdog = 1; | ||
1049 | |||
1050 | tmp = 140; | ||
1051 | of_property_read_u16(np, "st,drop-compensation-ns", &tmp); | ||
1052 | pdata->drop_compensation_ns = clamp_t(u16, tmp, 0, 300) / 20; | ||
1053 | |||
1054 | /* CONFE */ | ||
1055 | if (of_get_property(np, "st,max-power-use-mpcc", NULL)) | ||
1056 | pdata->max_power_use_mpcc = 1; | ||
1057 | |||
1058 | if (of_get_property(np, "st,max-power-correction", NULL)) | ||
1059 | pdata->max_power_correction = 1; | ||
1060 | |||
1061 | if (of_get_property(np, "st,am-reduction-mode", NULL)) | ||
1062 | pdata->am_reduction_mode = 1; | ||
1063 | |||
1064 | if (of_get_property(np, "st,odd-pwm-speed-mode", NULL)) | ||
1065 | pdata->odd_pwm_speed_mode = 1; | ||
1066 | |||
1067 | /* CONFF */ | ||
1068 | if (of_get_property(np, "st,invalid-input-detect-mute", NULL)) | ||
1069 | pdata->invalid_input_detect_mute = 1; | ||
1070 | |||
1071 | sta32x->pdata = pdata; | ||
1072 | |||
1073 | return 0; | ||
1074 | } | ||
1075 | #endif | ||
1076 | |||
960 | static int sta32x_i2c_probe(struct i2c_client *i2c, | 1077 | static int sta32x_i2c_probe(struct i2c_client *i2c, |
961 | const struct i2c_device_id *id) | 1078 | const struct i2c_device_id *id) |
962 | { | 1079 | { |
1080 | struct device *dev = &i2c->dev; | ||
963 | struct sta32x_priv *sta32x; | 1081 | struct sta32x_priv *sta32x; |
964 | int ret, i; | 1082 | int ret, i; |
965 | 1083 | ||
@@ -968,6 +1086,29 @@ static int sta32x_i2c_probe(struct i2c_client *i2c, | |||
968 | if (!sta32x) | 1086 | if (!sta32x) |
969 | return -ENOMEM; | 1087 | return -ENOMEM; |
970 | 1088 | ||
1089 | mutex_init(&sta32x->coeff_lock); | ||
1090 | sta32x->pdata = dev_get_platdata(dev); | ||
1091 | |||
1092 | #ifdef CONFIG_OF | ||
1093 | if (dev->of_node) { | ||
1094 | ret = sta32x_probe_dt(dev, sta32x); | ||
1095 | if (ret < 0) | ||
1096 | return ret; | ||
1097 | } | ||
1098 | #endif | ||
1099 | |||
1100 | /* GPIOs */ | ||
1101 | sta32x->gpiod_nreset = devm_gpiod_get(dev, "reset"); | ||
1102 | if (IS_ERR(sta32x->gpiod_nreset)) { | ||
1103 | ret = PTR_ERR(sta32x->gpiod_nreset); | ||
1104 | if (ret != -ENOENT && ret != -ENOSYS) | ||
1105 | return ret; | ||
1106 | |||
1107 | sta32x->gpiod_nreset = NULL; | ||
1108 | } else { | ||
1109 | gpiod_direction_output(sta32x->gpiod_nreset, 0); | ||
1110 | } | ||
1111 | |||
971 | /* regulators */ | 1112 | /* regulators */ |
972 | for (i = 0; i < ARRAY_SIZE(sta32x->supplies); i++) | 1113 | for (i = 0; i < ARRAY_SIZE(sta32x->supplies); i++) |
973 | sta32x->supplies[i].supply = sta32x_supply_names[i]; | 1114 | sta32x->supplies[i].supply = sta32x_supply_names[i]; |
@@ -982,15 +1123,15 @@ static int sta32x_i2c_probe(struct i2c_client *i2c, | |||
982 | sta32x->regmap = devm_regmap_init_i2c(i2c, &sta32x_regmap); | 1123 | sta32x->regmap = devm_regmap_init_i2c(i2c, &sta32x_regmap); |
983 | if (IS_ERR(sta32x->regmap)) { | 1124 | if (IS_ERR(sta32x->regmap)) { |
984 | ret = PTR_ERR(sta32x->regmap); | 1125 | ret = PTR_ERR(sta32x->regmap); |
985 | dev_err(&i2c->dev, "Failed to init regmap: %d\n", ret); | 1126 | dev_err(dev, "Failed to init regmap: %d\n", ret); |
986 | return ret; | 1127 | return ret; |
987 | } | 1128 | } |
988 | 1129 | ||
989 | i2c_set_clientdata(i2c, sta32x); | 1130 | i2c_set_clientdata(i2c, sta32x); |
990 | 1131 | ||
991 | ret = snd_soc_register_codec(&i2c->dev, &sta32x_codec, &sta32x_dai, 1); | 1132 | ret = snd_soc_register_codec(dev, &sta32x_codec, &sta32x_dai, 1); |
992 | if (ret != 0) | 1133 | if (ret < 0) |
993 | dev_err(&i2c->dev, "Failed to register codec (%d)\n", ret); | 1134 | dev_err(dev, "Failed to register codec (%d)\n", ret); |
994 | 1135 | ||
995 | return ret; | 1136 | return ret; |
996 | } | 1137 | } |
@@ -1013,6 +1154,7 @@ static struct i2c_driver sta32x_i2c_driver = { | |||
1013 | .driver = { | 1154 | .driver = { |
1014 | .name = "sta32x", | 1155 | .name = "sta32x", |
1015 | .owner = THIS_MODULE, | 1156 | .owner = THIS_MODULE, |
1157 | .of_match_table = of_match_ptr(st32x_dt_ids), | ||
1016 | }, | 1158 | }, |
1017 | .probe = sta32x_i2c_probe, | 1159 | .probe = sta32x_i2c_probe, |
1018 | .remove = sta32x_i2c_remove, | 1160 | .remove = sta32x_i2c_remove, |
diff --git a/sound/soc/codecs/sta32x.h b/sound/soc/codecs/sta32x.h index d8e32a6262ee..d3191c983d71 100644 --- a/sound/soc/codecs/sta32x.h +++ b/sound/soc/codecs/sta32x.h | |||
@@ -131,7 +131,7 @@ | |||
131 | #define STA32X_CONFF_OCFG_MASK 0x03 | 131 | #define STA32X_CONFF_OCFG_MASK 0x03 |
132 | #define STA32X_CONFF_OCFG_SHIFT 0 | 132 | #define STA32X_CONFF_OCFG_SHIFT 0 |
133 | #define STA32X_CONFF_IDE 0x04 | 133 | #define STA32X_CONFF_IDE 0x04 |
134 | #define STA32X_CONFF_IDE_SHIFT 3 | 134 | #define STA32X_CONFF_IDE_SHIFT 2 |
135 | #define STA32X_CONFF_BCLE 0x08 | 135 | #define STA32X_CONFF_BCLE 0x08 |
136 | #define STA32X_CONFF_ECLE 0x20 | 136 | #define STA32X_CONFF_ECLE 0x20 |
137 | #define STA32X_CONFF_PWDN 0x40 | 137 | #define STA32X_CONFF_PWDN 0x40 |
diff --git a/sound/soc/codecs/tlv320aic31xx.c b/sound/soc/codecs/tlv320aic31xx.c index dc3223d6eca1..c86dd9aae157 100644 --- a/sound/soc/codecs/tlv320aic31xx.c +++ b/sound/soc/codecs/tlv320aic31xx.c | |||
@@ -349,7 +349,8 @@ static int aic31xx_wait_bits(struct aic31xx_priv *aic31xx, unsigned int reg, | |||
349 | static int aic31xx_dapm_power_event(struct snd_soc_dapm_widget *w, | 349 | static int aic31xx_dapm_power_event(struct snd_soc_dapm_widget *w, |
350 | struct snd_kcontrol *kcontrol, int event) | 350 | struct snd_kcontrol *kcontrol, int event) |
351 | { | 351 | { |
352 | struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(w->codec); | 352 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
353 | struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec); | ||
353 | unsigned int reg = AIC31XX_DACFLAG1; | 354 | unsigned int reg = AIC31XX_DACFLAG1; |
354 | unsigned int mask; | 355 | unsigned int mask; |
355 | 356 | ||
@@ -377,7 +378,7 @@ static int aic31xx_dapm_power_event(struct snd_soc_dapm_widget *w, | |||
377 | reg = AIC31XX_ADCFLAG; | 378 | reg = AIC31XX_ADCFLAG; |
378 | break; | 379 | break; |
379 | default: | 380 | default: |
380 | dev_err(w->codec->dev, "Unknown widget '%s' calling %s\n", | 381 | dev_err(codec->dev, "Unknown widget '%s' calling %s\n", |
381 | w->name, __func__); | 382 | w->name, __func__); |
382 | return -EINVAL; | 383 | return -EINVAL; |
383 | } | 384 | } |
@@ -388,7 +389,7 @@ static int aic31xx_dapm_power_event(struct snd_soc_dapm_widget *w, | |||
388 | case SND_SOC_DAPM_POST_PMD: | 389 | case SND_SOC_DAPM_POST_PMD: |
389 | return aic31xx_wait_bits(aic31xx, reg, mask, 0, 5000, 100); | 390 | return aic31xx_wait_bits(aic31xx, reg, mask, 0, 5000, 100); |
390 | default: | 391 | default: |
391 | dev_dbg(w->codec->dev, | 392 | dev_dbg(codec->dev, |
392 | "Unhandled dapm widget event %d from %s\n", | 393 | "Unhandled dapm widget event %d from %s\n", |
393 | event, w->name); | 394 | event, w->name); |
394 | } | 395 | } |
@@ -433,7 +434,7 @@ static const struct snd_kcontrol_new aic31xx_dapm_spr_switch = | |||
433 | static int mic_bias_event(struct snd_soc_dapm_widget *w, | 434 | static int mic_bias_event(struct snd_soc_dapm_widget *w, |
434 | struct snd_kcontrol *kcontrol, int event) | 435 | struct snd_kcontrol *kcontrol, int event) |
435 | { | 436 | { |
436 | struct snd_soc_codec *codec = w->codec; | 437 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
437 | struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec); | 438 | struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec); |
438 | 439 | ||
439 | switch (event) { | 440 | switch (event) { |
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c index b7ebce054b4e..51c4713ac6e3 100644 --- a/sound/soc/codecs/tlv320aic3x.c +++ b/sound/soc/codecs/tlv320aic3x.c | |||
@@ -87,6 +87,7 @@ struct aic3x_priv { | |||
87 | #define AIC3X_MODEL_3X 0 | 87 | #define AIC3X_MODEL_3X 0 |
88 | #define AIC3X_MODEL_33 1 | 88 | #define AIC3X_MODEL_33 1 |
89 | #define AIC3X_MODEL_3007 2 | 89 | #define AIC3X_MODEL_3007 2 |
90 | #define AIC3X_MODEL_3104 3 | ||
90 | u16 model; | 91 | u16 model; |
91 | 92 | ||
92 | /* Selects the micbias voltage */ | 93 | /* Selects the micbias voltage */ |
@@ -197,7 +198,7 @@ static int snd_soc_dapm_put_volsw_aic3x(struct snd_kcontrol *kcontrol, | |||
197 | static int mic_bias_event(struct snd_soc_dapm_widget *w, | 198 | static int mic_bias_event(struct snd_soc_dapm_widget *w, |
198 | struct snd_kcontrol *kcontrol, int event) | 199 | struct snd_kcontrol *kcontrol, int event) |
199 | { | 200 | { |
200 | struct snd_soc_codec *codec = w->codec; | 201 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
201 | struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec); | 202 | struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec); |
202 | 203 | ||
203 | switch (event) { | 204 | switch (event) { |
@@ -316,52 +317,37 @@ static const struct snd_kcontrol_new aic3x_snd_controls[] = { | |||
316 | * only for swapped L-to-R and R-to-L routes. See below stereo controls | 317 | * only for swapped L-to-R and R-to-L routes. See below stereo controls |
317 | * for direct L-to-L and R-to-R routes. | 318 | * for direct L-to-L and R-to-R routes. |
318 | */ | 319 | */ |
319 | SOC_SINGLE_TLV("Left Line Mixer Line2R Bypass Volume", | ||
320 | LINE2R_2_LLOPM_VOL, 0, 118, 1, output_stage_tlv), | ||
321 | SOC_SINGLE_TLV("Left Line Mixer PGAR Bypass Volume", | 320 | SOC_SINGLE_TLV("Left Line Mixer PGAR Bypass Volume", |
322 | PGAR_2_LLOPM_VOL, 0, 118, 1, output_stage_tlv), | 321 | PGAR_2_LLOPM_VOL, 0, 118, 1, output_stage_tlv), |
323 | SOC_SINGLE_TLV("Left Line Mixer DACR1 Playback Volume", | 322 | SOC_SINGLE_TLV("Left Line Mixer DACR1 Playback Volume", |
324 | DACR1_2_LLOPM_VOL, 0, 118, 1, output_stage_tlv), | 323 | DACR1_2_LLOPM_VOL, 0, 118, 1, output_stage_tlv), |
325 | 324 | ||
326 | SOC_SINGLE_TLV("Right Line Mixer Line2L Bypass Volume", | ||
327 | LINE2L_2_RLOPM_VOL, 0, 118, 1, output_stage_tlv), | ||
328 | SOC_SINGLE_TLV("Right Line Mixer PGAL Bypass Volume", | 325 | SOC_SINGLE_TLV("Right Line Mixer PGAL Bypass Volume", |
329 | PGAL_2_RLOPM_VOL, 0, 118, 1, output_stage_tlv), | 326 | PGAL_2_RLOPM_VOL, 0, 118, 1, output_stage_tlv), |
330 | SOC_SINGLE_TLV("Right Line Mixer DACL1 Playback Volume", | 327 | SOC_SINGLE_TLV("Right Line Mixer DACL1 Playback Volume", |
331 | DACL1_2_RLOPM_VOL, 0, 118, 1, output_stage_tlv), | 328 | DACL1_2_RLOPM_VOL, 0, 118, 1, output_stage_tlv), |
332 | 329 | ||
333 | SOC_SINGLE_TLV("Left HP Mixer Line2R Bypass Volume", | ||
334 | LINE2R_2_HPLOUT_VOL, 0, 118, 1, output_stage_tlv), | ||
335 | SOC_SINGLE_TLV("Left HP Mixer PGAR Bypass Volume", | 330 | SOC_SINGLE_TLV("Left HP Mixer PGAR Bypass Volume", |
336 | PGAR_2_HPLOUT_VOL, 0, 118, 1, output_stage_tlv), | 331 | PGAR_2_HPLOUT_VOL, 0, 118, 1, output_stage_tlv), |
337 | SOC_SINGLE_TLV("Left HP Mixer DACR1 Playback Volume", | 332 | SOC_SINGLE_TLV("Left HP Mixer DACR1 Playback Volume", |
338 | DACR1_2_HPLOUT_VOL, 0, 118, 1, output_stage_tlv), | 333 | DACR1_2_HPLOUT_VOL, 0, 118, 1, output_stage_tlv), |
339 | 334 | ||
340 | SOC_SINGLE_TLV("Right HP Mixer Line2L Bypass Volume", | ||
341 | LINE2L_2_HPROUT_VOL, 0, 118, 1, output_stage_tlv), | ||
342 | SOC_SINGLE_TLV("Right HP Mixer PGAL Bypass Volume", | 335 | SOC_SINGLE_TLV("Right HP Mixer PGAL Bypass Volume", |
343 | PGAL_2_HPROUT_VOL, 0, 118, 1, output_stage_tlv), | 336 | PGAL_2_HPROUT_VOL, 0, 118, 1, output_stage_tlv), |
344 | SOC_SINGLE_TLV("Right HP Mixer DACL1 Playback Volume", | 337 | SOC_SINGLE_TLV("Right HP Mixer DACL1 Playback Volume", |
345 | DACL1_2_HPROUT_VOL, 0, 118, 1, output_stage_tlv), | 338 | DACL1_2_HPROUT_VOL, 0, 118, 1, output_stage_tlv), |
346 | 339 | ||
347 | SOC_SINGLE_TLV("Left HPCOM Mixer Line2R Bypass Volume", | ||
348 | LINE2R_2_HPLCOM_VOL, 0, 118, 1, output_stage_tlv), | ||
349 | SOC_SINGLE_TLV("Left HPCOM Mixer PGAR Bypass Volume", | 340 | SOC_SINGLE_TLV("Left HPCOM Mixer PGAR Bypass Volume", |
350 | PGAR_2_HPLCOM_VOL, 0, 118, 1, output_stage_tlv), | 341 | PGAR_2_HPLCOM_VOL, 0, 118, 1, output_stage_tlv), |
351 | SOC_SINGLE_TLV("Left HPCOM Mixer DACR1 Playback Volume", | 342 | SOC_SINGLE_TLV("Left HPCOM Mixer DACR1 Playback Volume", |
352 | DACR1_2_HPLCOM_VOL, 0, 118, 1, output_stage_tlv), | 343 | DACR1_2_HPLCOM_VOL, 0, 118, 1, output_stage_tlv), |
353 | 344 | ||
354 | SOC_SINGLE_TLV("Right HPCOM Mixer Line2L Bypass Volume", | ||
355 | LINE2L_2_HPRCOM_VOL, 0, 118, 1, output_stage_tlv), | ||
356 | SOC_SINGLE_TLV("Right HPCOM Mixer PGAL Bypass Volume", | 345 | SOC_SINGLE_TLV("Right HPCOM Mixer PGAL Bypass Volume", |
357 | PGAL_2_HPRCOM_VOL, 0, 118, 1, output_stage_tlv), | 346 | PGAL_2_HPRCOM_VOL, 0, 118, 1, output_stage_tlv), |
358 | SOC_SINGLE_TLV("Right HPCOM Mixer DACL1 Playback Volume", | 347 | SOC_SINGLE_TLV("Right HPCOM Mixer DACL1 Playback Volume", |
359 | DACL1_2_HPRCOM_VOL, 0, 118, 1, output_stage_tlv), | 348 | DACL1_2_HPRCOM_VOL, 0, 118, 1, output_stage_tlv), |
360 | 349 | ||
361 | /* Stereo output controls for direct L-to-L and R-to-R routes */ | 350 | /* Stereo output controls for direct L-to-L and R-to-R routes */ |
362 | SOC_DOUBLE_R_TLV("Line Line2 Bypass Volume", | ||
363 | LINE2L_2_LLOPM_VOL, LINE2R_2_RLOPM_VOL, | ||
364 | 0, 118, 1, output_stage_tlv), | ||
365 | SOC_DOUBLE_R_TLV("Line PGA Bypass Volume", | 351 | SOC_DOUBLE_R_TLV("Line PGA Bypass Volume", |
366 | PGAL_2_LLOPM_VOL, PGAR_2_RLOPM_VOL, | 352 | PGAL_2_LLOPM_VOL, PGAR_2_RLOPM_VOL, |
367 | 0, 118, 1, output_stage_tlv), | 353 | 0, 118, 1, output_stage_tlv), |
@@ -369,9 +355,6 @@ static const struct snd_kcontrol_new aic3x_snd_controls[] = { | |||
369 | DACL1_2_LLOPM_VOL, DACR1_2_RLOPM_VOL, | 355 | DACL1_2_LLOPM_VOL, DACR1_2_RLOPM_VOL, |
370 | 0, 118, 1, output_stage_tlv), | 356 | 0, 118, 1, output_stage_tlv), |
371 | 357 | ||
372 | SOC_DOUBLE_R_TLV("HP Line2 Bypass Volume", | ||
373 | LINE2L_2_HPLOUT_VOL, LINE2R_2_HPROUT_VOL, | ||
374 | 0, 118, 1, output_stage_tlv), | ||
375 | SOC_DOUBLE_R_TLV("HP PGA Bypass Volume", | 358 | SOC_DOUBLE_R_TLV("HP PGA Bypass Volume", |
376 | PGAL_2_HPLOUT_VOL, PGAR_2_HPROUT_VOL, | 359 | PGAL_2_HPLOUT_VOL, PGAR_2_HPROUT_VOL, |
377 | 0, 118, 1, output_stage_tlv), | 360 | 0, 118, 1, output_stage_tlv), |
@@ -379,9 +362,6 @@ static const struct snd_kcontrol_new aic3x_snd_controls[] = { | |||
379 | DACL1_2_HPLOUT_VOL, DACR1_2_HPROUT_VOL, | 362 | DACL1_2_HPLOUT_VOL, DACR1_2_HPROUT_VOL, |
380 | 0, 118, 1, output_stage_tlv), | 363 | 0, 118, 1, output_stage_tlv), |
381 | 364 | ||
382 | SOC_DOUBLE_R_TLV("HPCOM Line2 Bypass Volume", | ||
383 | LINE2L_2_HPLCOM_VOL, LINE2R_2_HPRCOM_VOL, | ||
384 | 0, 118, 1, output_stage_tlv), | ||
385 | SOC_DOUBLE_R_TLV("HPCOM PGA Bypass Volume", | 365 | SOC_DOUBLE_R_TLV("HPCOM PGA Bypass Volume", |
386 | PGAL_2_HPLCOM_VOL, PGAR_2_HPRCOM_VOL, | 366 | PGAL_2_HPLCOM_VOL, PGAR_2_HPRCOM_VOL, |
387 | 0, 118, 1, output_stage_tlv), | 367 | 0, 118, 1, output_stage_tlv), |
@@ -424,6 +404,45 @@ static const struct snd_kcontrol_new aic3x_snd_controls[] = { | |||
424 | SOC_ENUM("Output Driver Ramp-up step", aic3x_rampup_step_enum), | 404 | SOC_ENUM("Output Driver Ramp-up step", aic3x_rampup_step_enum), |
425 | }; | 405 | }; |
426 | 406 | ||
407 | /* For other than tlv320aic3104 */ | ||
408 | static const struct snd_kcontrol_new aic3x_extra_snd_controls[] = { | ||
409 | /* | ||
410 | * Output controls that map to output mixer switches. Note these are | ||
411 | * only for swapped L-to-R and R-to-L routes. See below stereo controls | ||
412 | * for direct L-to-L and R-to-R routes. | ||
413 | */ | ||
414 | SOC_SINGLE_TLV("Left Line Mixer Line2R Bypass Volume", | ||
415 | LINE2R_2_LLOPM_VOL, 0, 118, 1, output_stage_tlv), | ||
416 | |||
417 | SOC_SINGLE_TLV("Right Line Mixer Line2L Bypass Volume", | ||
418 | LINE2L_2_RLOPM_VOL, 0, 118, 1, output_stage_tlv), | ||
419 | |||
420 | SOC_SINGLE_TLV("Left HP Mixer Line2R Bypass Volume", | ||
421 | LINE2R_2_HPLOUT_VOL, 0, 118, 1, output_stage_tlv), | ||
422 | |||
423 | SOC_SINGLE_TLV("Right HP Mixer Line2L Bypass Volume", | ||
424 | LINE2L_2_HPROUT_VOL, 0, 118, 1, output_stage_tlv), | ||
425 | |||
426 | SOC_SINGLE_TLV("Left HPCOM Mixer Line2R Bypass Volume", | ||
427 | LINE2R_2_HPLCOM_VOL, 0, 118, 1, output_stage_tlv), | ||
428 | |||
429 | SOC_SINGLE_TLV("Right HPCOM Mixer Line2L Bypass Volume", | ||
430 | LINE2L_2_HPRCOM_VOL, 0, 118, 1, output_stage_tlv), | ||
431 | |||
432 | /* Stereo output controls for direct L-to-L and R-to-R routes */ | ||
433 | SOC_DOUBLE_R_TLV("Line Line2 Bypass Volume", | ||
434 | LINE2L_2_LLOPM_VOL, LINE2R_2_RLOPM_VOL, | ||
435 | 0, 118, 1, output_stage_tlv), | ||
436 | |||
437 | SOC_DOUBLE_R_TLV("HP Line2 Bypass Volume", | ||
438 | LINE2L_2_HPLOUT_VOL, LINE2R_2_HPROUT_VOL, | ||
439 | 0, 118, 1, output_stage_tlv), | ||
440 | |||
441 | SOC_DOUBLE_R_TLV("HPCOM Line2 Bypass Volume", | ||
442 | LINE2L_2_HPLCOM_VOL, LINE2R_2_HPRCOM_VOL, | ||
443 | 0, 118, 1, output_stage_tlv), | ||
444 | }; | ||
445 | |||
427 | static const struct snd_kcontrol_new aic3x_mono_controls[] = { | 446 | static const struct snd_kcontrol_new aic3x_mono_controls[] = { |
428 | SOC_DOUBLE_R_TLV("Mono Line2 Bypass Volume", | 447 | SOC_DOUBLE_R_TLV("Mono Line2 Bypass Volume", |
429 | LINE2L_2_MONOLOPM_VOL, LINE2R_2_MONOLOPM_VOL, | 448 | LINE2L_2_MONOLOPM_VOL, LINE2R_2_MONOLOPM_VOL, |
@@ -464,22 +483,24 @@ SOC_DAPM_ENUM("Route", aic3x_right_hpcom_enum); | |||
464 | 483 | ||
465 | /* Left Line Mixer */ | 484 | /* Left Line Mixer */ |
466 | static const struct snd_kcontrol_new aic3x_left_line_mixer_controls[] = { | 485 | static const struct snd_kcontrol_new aic3x_left_line_mixer_controls[] = { |
467 | SOC_DAPM_SINGLE("Line2L Bypass Switch", LINE2L_2_LLOPM_VOL, 7, 1, 0), | ||
468 | SOC_DAPM_SINGLE("PGAL Bypass Switch", PGAL_2_LLOPM_VOL, 7, 1, 0), | 486 | SOC_DAPM_SINGLE("PGAL Bypass Switch", PGAL_2_LLOPM_VOL, 7, 1, 0), |
469 | SOC_DAPM_SINGLE("DACL1 Switch", DACL1_2_LLOPM_VOL, 7, 1, 0), | 487 | SOC_DAPM_SINGLE("DACL1 Switch", DACL1_2_LLOPM_VOL, 7, 1, 0), |
470 | SOC_DAPM_SINGLE("Line2R Bypass Switch", LINE2R_2_LLOPM_VOL, 7, 1, 0), | ||
471 | SOC_DAPM_SINGLE("PGAR Bypass Switch", PGAR_2_LLOPM_VOL, 7, 1, 0), | 488 | SOC_DAPM_SINGLE("PGAR Bypass Switch", PGAR_2_LLOPM_VOL, 7, 1, 0), |
472 | SOC_DAPM_SINGLE("DACR1 Switch", DACR1_2_LLOPM_VOL, 7, 1, 0), | 489 | SOC_DAPM_SINGLE("DACR1 Switch", DACR1_2_LLOPM_VOL, 7, 1, 0), |
490 | /* Not on tlv320aic3104 */ | ||
491 | SOC_DAPM_SINGLE("Line2L Bypass Switch", LINE2L_2_LLOPM_VOL, 7, 1, 0), | ||
492 | SOC_DAPM_SINGLE("Line2R Bypass Switch", LINE2R_2_LLOPM_VOL, 7, 1, 0), | ||
473 | }; | 493 | }; |
474 | 494 | ||
475 | /* Right Line Mixer */ | 495 | /* Right Line Mixer */ |
476 | static const struct snd_kcontrol_new aic3x_right_line_mixer_controls[] = { | 496 | static const struct snd_kcontrol_new aic3x_right_line_mixer_controls[] = { |
477 | SOC_DAPM_SINGLE("Line2L Bypass Switch", LINE2L_2_RLOPM_VOL, 7, 1, 0), | ||
478 | SOC_DAPM_SINGLE("PGAL Bypass Switch", PGAL_2_RLOPM_VOL, 7, 1, 0), | 497 | SOC_DAPM_SINGLE("PGAL Bypass Switch", PGAL_2_RLOPM_VOL, 7, 1, 0), |
479 | SOC_DAPM_SINGLE("DACL1 Switch", DACL1_2_RLOPM_VOL, 7, 1, 0), | 498 | SOC_DAPM_SINGLE("DACL1 Switch", DACL1_2_RLOPM_VOL, 7, 1, 0), |
480 | SOC_DAPM_SINGLE("Line2R Bypass Switch", LINE2R_2_RLOPM_VOL, 7, 1, 0), | ||
481 | SOC_DAPM_SINGLE("PGAR Bypass Switch", PGAR_2_RLOPM_VOL, 7, 1, 0), | 499 | SOC_DAPM_SINGLE("PGAR Bypass Switch", PGAR_2_RLOPM_VOL, 7, 1, 0), |
482 | SOC_DAPM_SINGLE("DACR1 Switch", DACR1_2_RLOPM_VOL, 7, 1, 0), | 500 | SOC_DAPM_SINGLE("DACR1 Switch", DACR1_2_RLOPM_VOL, 7, 1, 0), |
501 | /* Not on tlv320aic3104 */ | ||
502 | SOC_DAPM_SINGLE("Line2L Bypass Switch", LINE2L_2_RLOPM_VOL, 7, 1, 0), | ||
503 | SOC_DAPM_SINGLE("Line2R Bypass Switch", LINE2R_2_RLOPM_VOL, 7, 1, 0), | ||
483 | }; | 504 | }; |
484 | 505 | ||
485 | /* Mono Mixer */ | 506 | /* Mono Mixer */ |
@@ -494,42 +515,46 @@ static const struct snd_kcontrol_new aic3x_mono_mixer_controls[] = { | |||
494 | 515 | ||
495 | /* Left HP Mixer */ | 516 | /* Left HP Mixer */ |
496 | static const struct snd_kcontrol_new aic3x_left_hp_mixer_controls[] = { | 517 | static const struct snd_kcontrol_new aic3x_left_hp_mixer_controls[] = { |
497 | SOC_DAPM_SINGLE("Line2L Bypass Switch", LINE2L_2_HPLOUT_VOL, 7, 1, 0), | ||
498 | SOC_DAPM_SINGLE("PGAL Bypass Switch", PGAL_2_HPLOUT_VOL, 7, 1, 0), | 518 | SOC_DAPM_SINGLE("PGAL Bypass Switch", PGAL_2_HPLOUT_VOL, 7, 1, 0), |
499 | SOC_DAPM_SINGLE("DACL1 Switch", DACL1_2_HPLOUT_VOL, 7, 1, 0), | 519 | SOC_DAPM_SINGLE("DACL1 Switch", DACL1_2_HPLOUT_VOL, 7, 1, 0), |
500 | SOC_DAPM_SINGLE("Line2R Bypass Switch", LINE2R_2_HPLOUT_VOL, 7, 1, 0), | ||
501 | SOC_DAPM_SINGLE("PGAR Bypass Switch", PGAR_2_HPLOUT_VOL, 7, 1, 0), | 520 | SOC_DAPM_SINGLE("PGAR Bypass Switch", PGAR_2_HPLOUT_VOL, 7, 1, 0), |
502 | SOC_DAPM_SINGLE("DACR1 Switch", DACR1_2_HPLOUT_VOL, 7, 1, 0), | 521 | SOC_DAPM_SINGLE("DACR1 Switch", DACR1_2_HPLOUT_VOL, 7, 1, 0), |
522 | /* Not on tlv320aic3104 */ | ||
523 | SOC_DAPM_SINGLE("Line2L Bypass Switch", LINE2L_2_HPLOUT_VOL, 7, 1, 0), | ||
524 | SOC_DAPM_SINGLE("Line2R Bypass Switch", LINE2R_2_HPLOUT_VOL, 7, 1, 0), | ||
503 | }; | 525 | }; |
504 | 526 | ||
505 | /* Right HP Mixer */ | 527 | /* Right HP Mixer */ |
506 | static const struct snd_kcontrol_new aic3x_right_hp_mixer_controls[] = { | 528 | static const struct snd_kcontrol_new aic3x_right_hp_mixer_controls[] = { |
507 | SOC_DAPM_SINGLE("Line2L Bypass Switch", LINE2L_2_HPROUT_VOL, 7, 1, 0), | ||
508 | SOC_DAPM_SINGLE("PGAL Bypass Switch", PGAL_2_HPROUT_VOL, 7, 1, 0), | 529 | SOC_DAPM_SINGLE("PGAL Bypass Switch", PGAL_2_HPROUT_VOL, 7, 1, 0), |
509 | SOC_DAPM_SINGLE("DACL1 Switch", DACL1_2_HPROUT_VOL, 7, 1, 0), | 530 | SOC_DAPM_SINGLE("DACL1 Switch", DACL1_2_HPROUT_VOL, 7, 1, 0), |
510 | SOC_DAPM_SINGLE("Line2R Bypass Switch", LINE2R_2_HPROUT_VOL, 7, 1, 0), | ||
511 | SOC_DAPM_SINGLE("PGAR Bypass Switch", PGAR_2_HPROUT_VOL, 7, 1, 0), | 531 | SOC_DAPM_SINGLE("PGAR Bypass Switch", PGAR_2_HPROUT_VOL, 7, 1, 0), |
512 | SOC_DAPM_SINGLE("DACR1 Switch", DACR1_2_HPROUT_VOL, 7, 1, 0), | 532 | SOC_DAPM_SINGLE("DACR1 Switch", DACR1_2_HPROUT_VOL, 7, 1, 0), |
533 | /* Not on tlv320aic3104 */ | ||
534 | SOC_DAPM_SINGLE("Line2L Bypass Switch", LINE2L_2_HPROUT_VOL, 7, 1, 0), | ||
535 | SOC_DAPM_SINGLE("Line2R Bypass Switch", LINE2R_2_HPROUT_VOL, 7, 1, 0), | ||
513 | }; | 536 | }; |
514 | 537 | ||
515 | /* Left HPCOM Mixer */ | 538 | /* Left HPCOM Mixer */ |
516 | static const struct snd_kcontrol_new aic3x_left_hpcom_mixer_controls[] = { | 539 | static const struct snd_kcontrol_new aic3x_left_hpcom_mixer_controls[] = { |
517 | SOC_DAPM_SINGLE("Line2L Bypass Switch", LINE2L_2_HPLCOM_VOL, 7, 1, 0), | ||
518 | SOC_DAPM_SINGLE("PGAL Bypass Switch", PGAL_2_HPLCOM_VOL, 7, 1, 0), | 540 | SOC_DAPM_SINGLE("PGAL Bypass Switch", PGAL_2_HPLCOM_VOL, 7, 1, 0), |
519 | SOC_DAPM_SINGLE("DACL1 Switch", DACL1_2_HPLCOM_VOL, 7, 1, 0), | 541 | SOC_DAPM_SINGLE("DACL1 Switch", DACL1_2_HPLCOM_VOL, 7, 1, 0), |
520 | SOC_DAPM_SINGLE("Line2R Bypass Switch", LINE2R_2_HPLCOM_VOL, 7, 1, 0), | ||
521 | SOC_DAPM_SINGLE("PGAR Bypass Switch", PGAR_2_HPLCOM_VOL, 7, 1, 0), | 542 | SOC_DAPM_SINGLE("PGAR Bypass Switch", PGAR_2_HPLCOM_VOL, 7, 1, 0), |
522 | SOC_DAPM_SINGLE("DACR1 Switch", DACR1_2_HPLCOM_VOL, 7, 1, 0), | 543 | SOC_DAPM_SINGLE("DACR1 Switch", DACR1_2_HPLCOM_VOL, 7, 1, 0), |
544 | /* Not on tlv320aic3104 */ | ||
545 | SOC_DAPM_SINGLE("Line2L Bypass Switch", LINE2L_2_HPLCOM_VOL, 7, 1, 0), | ||
546 | SOC_DAPM_SINGLE("Line2R Bypass Switch", LINE2R_2_HPLCOM_VOL, 7, 1, 0), | ||
523 | }; | 547 | }; |
524 | 548 | ||
525 | /* Right HPCOM Mixer */ | 549 | /* Right HPCOM Mixer */ |
526 | static const struct snd_kcontrol_new aic3x_right_hpcom_mixer_controls[] = { | 550 | static const struct snd_kcontrol_new aic3x_right_hpcom_mixer_controls[] = { |
527 | SOC_DAPM_SINGLE("Line2L Bypass Switch", LINE2L_2_HPRCOM_VOL, 7, 1, 0), | ||
528 | SOC_DAPM_SINGLE("PGAL Bypass Switch", PGAL_2_HPRCOM_VOL, 7, 1, 0), | 551 | SOC_DAPM_SINGLE("PGAL Bypass Switch", PGAL_2_HPRCOM_VOL, 7, 1, 0), |
529 | SOC_DAPM_SINGLE("DACL1 Switch", DACL1_2_HPRCOM_VOL, 7, 1, 0), | 552 | SOC_DAPM_SINGLE("DACL1 Switch", DACL1_2_HPRCOM_VOL, 7, 1, 0), |
530 | SOC_DAPM_SINGLE("Line2R Bypass Switch", LINE2R_2_HPRCOM_VOL, 7, 1, 0), | ||
531 | SOC_DAPM_SINGLE("PGAR Bypass Switch", PGAR_2_HPRCOM_VOL, 7, 1, 0), | 553 | SOC_DAPM_SINGLE("PGAR Bypass Switch", PGAR_2_HPRCOM_VOL, 7, 1, 0), |
532 | SOC_DAPM_SINGLE("DACR1 Switch", DACR1_2_HPRCOM_VOL, 7, 1, 0), | 554 | SOC_DAPM_SINGLE("DACR1 Switch", DACR1_2_HPRCOM_VOL, 7, 1, 0), |
555 | /* Not on tlv320aic3104 */ | ||
556 | SOC_DAPM_SINGLE("Line2L Bypass Switch", LINE2L_2_HPRCOM_VOL, 7, 1, 0), | ||
557 | SOC_DAPM_SINGLE("Line2R Bypass Switch", LINE2R_2_HPRCOM_VOL, 7, 1, 0), | ||
533 | }; | 558 | }; |
534 | 559 | ||
535 | /* Left PGA Mixer */ | 560 | /* Left PGA Mixer */ |
@@ -550,6 +575,22 @@ static const struct snd_kcontrol_new aic3x_right_pga_mixer_controls[] = { | |||
550 | SOC_DAPM_SINGLE_AIC3X("Mic3R Switch", MIC3LR_2_RADC_CTRL, 0, 1, 1), | 575 | SOC_DAPM_SINGLE_AIC3X("Mic3R Switch", MIC3LR_2_RADC_CTRL, 0, 1, 1), |
551 | }; | 576 | }; |
552 | 577 | ||
578 | /* Left PGA Mixer for tlv320aic3104 */ | ||
579 | static const struct snd_kcontrol_new aic3104_left_pga_mixer_controls[] = { | ||
580 | SOC_DAPM_SINGLE_AIC3X("Line1L Switch", LINE1L_2_LADC_CTRL, 3, 1, 1), | ||
581 | SOC_DAPM_SINGLE_AIC3X("Line1R Switch", LINE1R_2_LADC_CTRL, 3, 1, 1), | ||
582 | SOC_DAPM_SINGLE_AIC3X("Mic2L Switch", MIC3LR_2_LADC_CTRL, 4, 1, 1), | ||
583 | SOC_DAPM_SINGLE_AIC3X("Mic2R Switch", MIC3LR_2_LADC_CTRL, 0, 1, 1), | ||
584 | }; | ||
585 | |||
586 | /* Right PGA Mixer for tlv320aic3104 */ | ||
587 | static const struct snd_kcontrol_new aic3104_right_pga_mixer_controls[] = { | ||
588 | SOC_DAPM_SINGLE_AIC3X("Line1R Switch", LINE1R_2_RADC_CTRL, 3, 1, 1), | ||
589 | SOC_DAPM_SINGLE_AIC3X("Line1L Switch", LINE1L_2_RADC_CTRL, 3, 1, 1), | ||
590 | SOC_DAPM_SINGLE_AIC3X("Mic2L Switch", MIC3LR_2_RADC_CTRL, 4, 1, 1), | ||
591 | SOC_DAPM_SINGLE_AIC3X("Mic2R Switch", MIC3LR_2_RADC_CTRL, 0, 1, 1), | ||
592 | }; | ||
593 | |||
553 | /* Left Line1 Mux */ | 594 | /* Left Line1 Mux */ |
554 | static const struct snd_kcontrol_new aic3x_left_line1l_mux_controls = | 595 | static const struct snd_kcontrol_new aic3x_left_line1l_mux_controls = |
555 | SOC_DAPM_ENUM("Route", aic3x_line1l_2_l_enum); | 596 | SOC_DAPM_ENUM("Route", aic3x_line1l_2_l_enum); |
@@ -593,26 +634,56 @@ static const struct snd_soc_dapm_widget aic3x_dapm_widgets[] = { | |||
593 | 634 | ||
594 | /* Inputs to Left ADC */ | 635 | /* Inputs to Left ADC */ |
595 | SND_SOC_DAPM_ADC("Left ADC", "Left Capture", LINE1L_2_LADC_CTRL, 2, 0), | 636 | SND_SOC_DAPM_ADC("Left ADC", "Left Capture", LINE1L_2_LADC_CTRL, 2, 0), |
596 | SND_SOC_DAPM_MIXER("Left PGA Mixer", SND_SOC_NOPM, 0, 0, | ||
597 | &aic3x_left_pga_mixer_controls[0], | ||
598 | ARRAY_SIZE(aic3x_left_pga_mixer_controls)), | ||
599 | SND_SOC_DAPM_MUX("Left Line1L Mux", SND_SOC_NOPM, 0, 0, | 637 | SND_SOC_DAPM_MUX("Left Line1L Mux", SND_SOC_NOPM, 0, 0, |
600 | &aic3x_left_line1l_mux_controls), | 638 | &aic3x_left_line1l_mux_controls), |
601 | SND_SOC_DAPM_MUX("Left Line1R Mux", SND_SOC_NOPM, 0, 0, | 639 | SND_SOC_DAPM_MUX("Left Line1R Mux", SND_SOC_NOPM, 0, 0, |
602 | &aic3x_left_line1r_mux_controls), | 640 | &aic3x_left_line1r_mux_controls), |
603 | SND_SOC_DAPM_MUX("Left Line2L Mux", SND_SOC_NOPM, 0, 0, | ||
604 | &aic3x_left_line2_mux_controls), | ||
605 | 641 | ||
606 | /* Inputs to Right ADC */ | 642 | /* Inputs to Right ADC */ |
607 | SND_SOC_DAPM_ADC("Right ADC", "Right Capture", | 643 | SND_SOC_DAPM_ADC("Right ADC", "Right Capture", |
608 | LINE1R_2_RADC_CTRL, 2, 0), | 644 | LINE1R_2_RADC_CTRL, 2, 0), |
609 | SND_SOC_DAPM_MIXER("Right PGA Mixer", SND_SOC_NOPM, 0, 0, | ||
610 | &aic3x_right_pga_mixer_controls[0], | ||
611 | ARRAY_SIZE(aic3x_right_pga_mixer_controls)), | ||
612 | SND_SOC_DAPM_MUX("Right Line1L Mux", SND_SOC_NOPM, 0, 0, | 645 | SND_SOC_DAPM_MUX("Right Line1L Mux", SND_SOC_NOPM, 0, 0, |
613 | &aic3x_right_line1l_mux_controls), | 646 | &aic3x_right_line1l_mux_controls), |
614 | SND_SOC_DAPM_MUX("Right Line1R Mux", SND_SOC_NOPM, 0, 0, | 647 | SND_SOC_DAPM_MUX("Right Line1R Mux", SND_SOC_NOPM, 0, 0, |
615 | &aic3x_right_line1r_mux_controls), | 648 | &aic3x_right_line1r_mux_controls), |
649 | |||
650 | /* Mic Bias */ | ||
651 | SND_SOC_DAPM_SUPPLY("Mic Bias", MICBIAS_CTRL, 6, 0, | ||
652 | mic_bias_event, | ||
653 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), | ||
654 | |||
655 | SND_SOC_DAPM_OUTPUT("LLOUT"), | ||
656 | SND_SOC_DAPM_OUTPUT("RLOUT"), | ||
657 | SND_SOC_DAPM_OUTPUT("HPLOUT"), | ||
658 | SND_SOC_DAPM_OUTPUT("HPROUT"), | ||
659 | SND_SOC_DAPM_OUTPUT("HPLCOM"), | ||
660 | SND_SOC_DAPM_OUTPUT("HPRCOM"), | ||
661 | |||
662 | SND_SOC_DAPM_INPUT("LINE1L"), | ||
663 | SND_SOC_DAPM_INPUT("LINE1R"), | ||
664 | |||
665 | /* | ||
666 | * Virtual output pin to detection block inside codec. This can be | ||
667 | * used to keep codec bias on if gpio or detection features are needed. | ||
668 | * Force pin on or construct a path with an input jack and mic bias | ||
669 | * widgets. | ||
670 | */ | ||
671 | SND_SOC_DAPM_OUTPUT("Detection"), | ||
672 | }; | ||
673 | |||
674 | /* For other than tlv320aic3104 */ | ||
675 | static const struct snd_soc_dapm_widget aic3x_extra_dapm_widgets[] = { | ||
676 | /* Inputs to Left ADC */ | ||
677 | SND_SOC_DAPM_MIXER("Left PGA Mixer", SND_SOC_NOPM, 0, 0, | ||
678 | &aic3x_left_pga_mixer_controls[0], | ||
679 | ARRAY_SIZE(aic3x_left_pga_mixer_controls)), | ||
680 | SND_SOC_DAPM_MUX("Left Line2L Mux", SND_SOC_NOPM, 0, 0, | ||
681 | &aic3x_left_line2_mux_controls), | ||
682 | |||
683 | /* Inputs to Right ADC */ | ||
684 | SND_SOC_DAPM_MIXER("Right PGA Mixer", SND_SOC_NOPM, 0, 0, | ||
685 | &aic3x_right_pga_mixer_controls[0], | ||
686 | ARRAY_SIZE(aic3x_right_pga_mixer_controls)), | ||
616 | SND_SOC_DAPM_MUX("Right Line2R Mux", SND_SOC_NOPM, 0, 0, | 687 | SND_SOC_DAPM_MUX("Right Line2R Mux", SND_SOC_NOPM, 0, 0, |
617 | &aic3x_right_line2_mux_controls), | 688 | &aic3x_right_line2_mux_controls), |
618 | 689 | ||
@@ -637,11 +708,6 @@ static const struct snd_soc_dapm_widget aic3x_dapm_widgets[] = { | |||
637 | SND_SOC_DAPM_REG(snd_soc_dapm_micbias, "DMic Rate 32", | 708 | SND_SOC_DAPM_REG(snd_soc_dapm_micbias, "DMic Rate 32", |
638 | AIC3X_ASD_INTF_CTRLA, 0, 3, 3, 0), | 709 | AIC3X_ASD_INTF_CTRLA, 0, 3, 3, 0), |
639 | 710 | ||
640 | /* Mic Bias */ | ||
641 | SND_SOC_DAPM_SUPPLY("Mic Bias", MICBIAS_CTRL, 6, 0, | ||
642 | mic_bias_event, | ||
643 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), | ||
644 | |||
645 | /* Output mixers */ | 711 | /* Output mixers */ |
646 | SND_SOC_DAPM_MIXER("Left Line Mixer", SND_SOC_NOPM, 0, 0, | 712 | SND_SOC_DAPM_MIXER("Left Line Mixer", SND_SOC_NOPM, 0, 0, |
647 | &aic3x_left_line_mixer_controls[0], | 713 | &aic3x_left_line_mixer_controls[0], |
@@ -662,27 +728,46 @@ static const struct snd_soc_dapm_widget aic3x_dapm_widgets[] = { | |||
662 | &aic3x_right_hpcom_mixer_controls[0], | 728 | &aic3x_right_hpcom_mixer_controls[0], |
663 | ARRAY_SIZE(aic3x_right_hpcom_mixer_controls)), | 729 | ARRAY_SIZE(aic3x_right_hpcom_mixer_controls)), |
664 | 730 | ||
665 | SND_SOC_DAPM_OUTPUT("LLOUT"), | ||
666 | SND_SOC_DAPM_OUTPUT("RLOUT"), | ||
667 | SND_SOC_DAPM_OUTPUT("HPLOUT"), | ||
668 | SND_SOC_DAPM_OUTPUT("HPROUT"), | ||
669 | SND_SOC_DAPM_OUTPUT("HPLCOM"), | ||
670 | SND_SOC_DAPM_OUTPUT("HPRCOM"), | ||
671 | |||
672 | SND_SOC_DAPM_INPUT("MIC3L"), | 731 | SND_SOC_DAPM_INPUT("MIC3L"), |
673 | SND_SOC_DAPM_INPUT("MIC3R"), | 732 | SND_SOC_DAPM_INPUT("MIC3R"), |
674 | SND_SOC_DAPM_INPUT("LINE1L"), | ||
675 | SND_SOC_DAPM_INPUT("LINE1R"), | ||
676 | SND_SOC_DAPM_INPUT("LINE2L"), | 733 | SND_SOC_DAPM_INPUT("LINE2L"), |
677 | SND_SOC_DAPM_INPUT("LINE2R"), | 734 | SND_SOC_DAPM_INPUT("LINE2R"), |
735 | }; | ||
678 | 736 | ||
679 | /* | 737 | /* For tlv320aic3104 */ |
680 | * Virtual output pin to detection block inside codec. This can be | 738 | static const struct snd_soc_dapm_widget aic3104_extra_dapm_widgets[] = { |
681 | * used to keep codec bias on if gpio or detection features are needed. | 739 | /* Inputs to Left ADC */ |
682 | * Force pin on or construct a path with an input jack and mic bias | 740 | SND_SOC_DAPM_MIXER("Left PGA Mixer", SND_SOC_NOPM, 0, 0, |
683 | * widgets. | 741 | &aic3104_left_pga_mixer_controls[0], |
684 | */ | 742 | ARRAY_SIZE(aic3104_left_pga_mixer_controls)), |
685 | SND_SOC_DAPM_OUTPUT("Detection"), | 743 | |
744 | /* Inputs to Right ADC */ | ||
745 | SND_SOC_DAPM_MIXER("Right PGA Mixer", SND_SOC_NOPM, 0, 0, | ||
746 | &aic3104_right_pga_mixer_controls[0], | ||
747 | ARRAY_SIZE(aic3104_right_pga_mixer_controls)), | ||
748 | |||
749 | /* Output mixers */ | ||
750 | SND_SOC_DAPM_MIXER("Left Line Mixer", SND_SOC_NOPM, 0, 0, | ||
751 | &aic3x_left_line_mixer_controls[0], | ||
752 | ARRAY_SIZE(aic3x_left_line_mixer_controls) - 2), | ||
753 | SND_SOC_DAPM_MIXER("Right Line Mixer", SND_SOC_NOPM, 0, 0, | ||
754 | &aic3x_right_line_mixer_controls[0], | ||
755 | ARRAY_SIZE(aic3x_right_line_mixer_controls) - 2), | ||
756 | SND_SOC_DAPM_MIXER("Left HP Mixer", SND_SOC_NOPM, 0, 0, | ||
757 | &aic3x_left_hp_mixer_controls[0], | ||
758 | ARRAY_SIZE(aic3x_left_hp_mixer_controls) - 2), | ||
759 | SND_SOC_DAPM_MIXER("Right HP Mixer", SND_SOC_NOPM, 0, 0, | ||
760 | &aic3x_right_hp_mixer_controls[0], | ||
761 | ARRAY_SIZE(aic3x_right_hp_mixer_controls) - 2), | ||
762 | SND_SOC_DAPM_MIXER("Left HPCOM Mixer", SND_SOC_NOPM, 0, 0, | ||
763 | &aic3x_left_hpcom_mixer_controls[0], | ||
764 | ARRAY_SIZE(aic3x_left_hpcom_mixer_controls) - 2), | ||
765 | SND_SOC_DAPM_MIXER("Right HPCOM Mixer", SND_SOC_NOPM, 0, 0, | ||
766 | &aic3x_right_hpcom_mixer_controls[0], | ||
767 | ARRAY_SIZE(aic3x_right_hpcom_mixer_controls) - 2), | ||
768 | |||
769 | SND_SOC_DAPM_INPUT("MIC2L"), | ||
770 | SND_SOC_DAPM_INPUT("MIC2R"), | ||
686 | }; | 771 | }; |
687 | 772 | ||
688 | static const struct snd_soc_dapm_widget aic3x_dapm_mono_widgets[] = { | 773 | static const struct snd_soc_dapm_widget aic3x_dapm_mono_widgets[] = { |
@@ -712,17 +797,10 @@ static const struct snd_soc_dapm_route intercon[] = { | |||
712 | {"Left Line1R Mux", "single-ended", "LINE1R"}, | 797 | {"Left Line1R Mux", "single-ended", "LINE1R"}, |
713 | {"Left Line1R Mux", "differential", "LINE1R"}, | 798 | {"Left Line1R Mux", "differential", "LINE1R"}, |
714 | 799 | ||
715 | {"Left Line2L Mux", "single-ended", "LINE2L"}, | ||
716 | {"Left Line2L Mux", "differential", "LINE2L"}, | ||
717 | |||
718 | {"Left PGA Mixer", "Line1L Switch", "Left Line1L Mux"}, | 800 | {"Left PGA Mixer", "Line1L Switch", "Left Line1L Mux"}, |
719 | {"Left PGA Mixer", "Line1R Switch", "Left Line1R Mux"}, | 801 | {"Left PGA Mixer", "Line1R Switch", "Left Line1R Mux"}, |
720 | {"Left PGA Mixer", "Line2L Switch", "Left Line2L Mux"}, | ||
721 | {"Left PGA Mixer", "Mic3L Switch", "MIC3L"}, | ||
722 | {"Left PGA Mixer", "Mic3R Switch", "MIC3R"}, | ||
723 | 802 | ||
724 | {"Left ADC", NULL, "Left PGA Mixer"}, | 803 | {"Left ADC", NULL, "Left PGA Mixer"}, |
725 | {"Left ADC", NULL, "GPIO1 dmic modclk"}, | ||
726 | 804 | ||
727 | /* Right Input */ | 805 | /* Right Input */ |
728 | {"Right Line1R Mux", "single-ended", "LINE1R"}, | 806 | {"Right Line1R Mux", "single-ended", "LINE1R"}, |
@@ -730,25 +808,10 @@ static const struct snd_soc_dapm_route intercon[] = { | |||
730 | {"Right Line1L Mux", "single-ended", "LINE1L"}, | 808 | {"Right Line1L Mux", "single-ended", "LINE1L"}, |
731 | {"Right Line1L Mux", "differential", "LINE1L"}, | 809 | {"Right Line1L Mux", "differential", "LINE1L"}, |
732 | 810 | ||
733 | {"Right Line2R Mux", "single-ended", "LINE2R"}, | ||
734 | {"Right Line2R Mux", "differential", "LINE2R"}, | ||
735 | |||
736 | {"Right PGA Mixer", "Line1L Switch", "Right Line1L Mux"}, | 811 | {"Right PGA Mixer", "Line1L Switch", "Right Line1L Mux"}, |
737 | {"Right PGA Mixer", "Line1R Switch", "Right Line1R Mux"}, | 812 | {"Right PGA Mixer", "Line1R Switch", "Right Line1R Mux"}, |
738 | {"Right PGA Mixer", "Line2R Switch", "Right Line2R Mux"}, | ||
739 | {"Right PGA Mixer", "Mic3L Switch", "MIC3L"}, | ||
740 | {"Right PGA Mixer", "Mic3R Switch", "MIC3R"}, | ||
741 | 813 | ||
742 | {"Right ADC", NULL, "Right PGA Mixer"}, | 814 | {"Right ADC", NULL, "Right PGA Mixer"}, |
743 | {"Right ADC", NULL, "GPIO1 dmic modclk"}, | ||
744 | |||
745 | /* | ||
746 | * Logical path between digital mic enable and GPIO1 modulator clock | ||
747 | * output function | ||
748 | */ | ||
749 | {"GPIO1 dmic modclk", NULL, "DMic Rate 128"}, | ||
750 | {"GPIO1 dmic modclk", NULL, "DMic Rate 64"}, | ||
751 | {"GPIO1 dmic modclk", NULL, "DMic Rate 32"}, | ||
752 | 815 | ||
753 | /* Left DAC Output */ | 816 | /* Left DAC Output */ |
754 | {"Left DAC Mux", "DAC_L1", "Left DAC"}, | 817 | {"Left DAC Mux", "DAC_L1", "Left DAC"}, |
@@ -761,10 +824,8 @@ static const struct snd_soc_dapm_route intercon[] = { | |||
761 | {"Right DAC Mux", "DAC_R3", "Right DAC"}, | 824 | {"Right DAC Mux", "DAC_R3", "Right DAC"}, |
762 | 825 | ||
763 | /* Left Line Output */ | 826 | /* Left Line Output */ |
764 | {"Left Line Mixer", "Line2L Bypass Switch", "Left Line2L Mux"}, | ||
765 | {"Left Line Mixer", "PGAL Bypass Switch", "Left PGA Mixer"}, | 827 | {"Left Line Mixer", "PGAL Bypass Switch", "Left PGA Mixer"}, |
766 | {"Left Line Mixer", "DACL1 Switch", "Left DAC Mux"}, | 828 | {"Left Line Mixer", "DACL1 Switch", "Left DAC Mux"}, |
767 | {"Left Line Mixer", "Line2R Bypass Switch", "Right Line2R Mux"}, | ||
768 | {"Left Line Mixer", "PGAR Bypass Switch", "Right PGA Mixer"}, | 829 | {"Left Line Mixer", "PGAR Bypass Switch", "Right PGA Mixer"}, |
769 | {"Left Line Mixer", "DACR1 Switch", "Right DAC Mux"}, | 830 | {"Left Line Mixer", "DACR1 Switch", "Right DAC Mux"}, |
770 | 831 | ||
@@ -773,10 +834,8 @@ static const struct snd_soc_dapm_route intercon[] = { | |||
773 | {"LLOUT", NULL, "Left Line Out"}, | 834 | {"LLOUT", NULL, "Left Line Out"}, |
774 | 835 | ||
775 | /* Right Line Output */ | 836 | /* Right Line Output */ |
776 | {"Right Line Mixer", "Line2L Bypass Switch", "Left Line2L Mux"}, | ||
777 | {"Right Line Mixer", "PGAL Bypass Switch", "Left PGA Mixer"}, | 837 | {"Right Line Mixer", "PGAL Bypass Switch", "Left PGA Mixer"}, |
778 | {"Right Line Mixer", "DACL1 Switch", "Left DAC Mux"}, | 838 | {"Right Line Mixer", "DACL1 Switch", "Left DAC Mux"}, |
779 | {"Right Line Mixer", "Line2R Bypass Switch", "Right Line2R Mux"}, | ||
780 | {"Right Line Mixer", "PGAR Bypass Switch", "Right PGA Mixer"}, | 839 | {"Right Line Mixer", "PGAR Bypass Switch", "Right PGA Mixer"}, |
781 | {"Right Line Mixer", "DACR1 Switch", "Right DAC Mux"}, | 840 | {"Right Line Mixer", "DACR1 Switch", "Right DAC Mux"}, |
782 | 841 | ||
@@ -785,10 +844,8 @@ static const struct snd_soc_dapm_route intercon[] = { | |||
785 | {"RLOUT", NULL, "Right Line Out"}, | 844 | {"RLOUT", NULL, "Right Line Out"}, |
786 | 845 | ||
787 | /* Left HP Output */ | 846 | /* Left HP Output */ |
788 | {"Left HP Mixer", "Line2L Bypass Switch", "Left Line2L Mux"}, | ||
789 | {"Left HP Mixer", "PGAL Bypass Switch", "Left PGA Mixer"}, | 847 | {"Left HP Mixer", "PGAL Bypass Switch", "Left PGA Mixer"}, |
790 | {"Left HP Mixer", "DACL1 Switch", "Left DAC Mux"}, | 848 | {"Left HP Mixer", "DACL1 Switch", "Left DAC Mux"}, |
791 | {"Left HP Mixer", "Line2R Bypass Switch", "Right Line2R Mux"}, | ||
792 | {"Left HP Mixer", "PGAR Bypass Switch", "Right PGA Mixer"}, | 849 | {"Left HP Mixer", "PGAR Bypass Switch", "Right PGA Mixer"}, |
793 | {"Left HP Mixer", "DACR1 Switch", "Right DAC Mux"}, | 850 | {"Left HP Mixer", "DACR1 Switch", "Right DAC Mux"}, |
794 | 851 | ||
@@ -797,10 +854,8 @@ static const struct snd_soc_dapm_route intercon[] = { | |||
797 | {"HPLOUT", NULL, "Left HP Out"}, | 854 | {"HPLOUT", NULL, "Left HP Out"}, |
798 | 855 | ||
799 | /* Right HP Output */ | 856 | /* Right HP Output */ |
800 | {"Right HP Mixer", "Line2L Bypass Switch", "Left Line2L Mux"}, | ||
801 | {"Right HP Mixer", "PGAL Bypass Switch", "Left PGA Mixer"}, | 857 | {"Right HP Mixer", "PGAL Bypass Switch", "Left PGA Mixer"}, |
802 | {"Right HP Mixer", "DACL1 Switch", "Left DAC Mux"}, | 858 | {"Right HP Mixer", "DACL1 Switch", "Left DAC Mux"}, |
803 | {"Right HP Mixer", "Line2R Bypass Switch", "Right Line2R Mux"}, | ||
804 | {"Right HP Mixer", "PGAR Bypass Switch", "Right PGA Mixer"}, | 859 | {"Right HP Mixer", "PGAR Bypass Switch", "Right PGA Mixer"}, |
805 | {"Right HP Mixer", "DACR1 Switch", "Right DAC Mux"}, | 860 | {"Right HP Mixer", "DACR1 Switch", "Right DAC Mux"}, |
806 | 861 | ||
@@ -809,10 +864,8 @@ static const struct snd_soc_dapm_route intercon[] = { | |||
809 | {"HPROUT", NULL, "Right HP Out"}, | 864 | {"HPROUT", NULL, "Right HP Out"}, |
810 | 865 | ||
811 | /* Left HPCOM Output */ | 866 | /* Left HPCOM Output */ |
812 | {"Left HPCOM Mixer", "Line2L Bypass Switch", "Left Line2L Mux"}, | ||
813 | {"Left HPCOM Mixer", "PGAL Bypass Switch", "Left PGA Mixer"}, | 867 | {"Left HPCOM Mixer", "PGAL Bypass Switch", "Left PGA Mixer"}, |
814 | {"Left HPCOM Mixer", "DACL1 Switch", "Left DAC Mux"}, | 868 | {"Left HPCOM Mixer", "DACL1 Switch", "Left DAC Mux"}, |
815 | {"Left HPCOM Mixer", "Line2R Bypass Switch", "Right Line2R Mux"}, | ||
816 | {"Left HPCOM Mixer", "PGAR Bypass Switch", "Right PGA Mixer"}, | 869 | {"Left HPCOM Mixer", "PGAR Bypass Switch", "Right PGA Mixer"}, |
817 | {"Left HPCOM Mixer", "DACR1 Switch", "Right DAC Mux"}, | 870 | {"Left HPCOM Mixer", "DACR1 Switch", "Right DAC Mux"}, |
818 | 871 | ||
@@ -823,10 +876,8 @@ static const struct snd_soc_dapm_route intercon[] = { | |||
823 | {"HPLCOM", NULL, "Left HP Com"}, | 876 | {"HPLCOM", NULL, "Left HP Com"}, |
824 | 877 | ||
825 | /* Right HPCOM Output */ | 878 | /* Right HPCOM Output */ |
826 | {"Right HPCOM Mixer", "Line2L Bypass Switch", "Left Line2L Mux"}, | ||
827 | {"Right HPCOM Mixer", "PGAL Bypass Switch", "Left PGA Mixer"}, | 879 | {"Right HPCOM Mixer", "PGAL Bypass Switch", "Left PGA Mixer"}, |
828 | {"Right HPCOM Mixer", "DACL1 Switch", "Left DAC Mux"}, | 880 | {"Right HPCOM Mixer", "DACL1 Switch", "Left DAC Mux"}, |
829 | {"Right HPCOM Mixer", "Line2R Bypass Switch", "Right Line2R Mux"}, | ||
830 | {"Right HPCOM Mixer", "PGAR Bypass Switch", "Right PGA Mixer"}, | 881 | {"Right HPCOM Mixer", "PGAR Bypass Switch", "Right PGA Mixer"}, |
831 | {"Right HPCOM Mixer", "DACR1 Switch", "Right DAC Mux"}, | 882 | {"Right HPCOM Mixer", "DACR1 Switch", "Right DAC Mux"}, |
832 | 883 | ||
@@ -839,6 +890,72 @@ static const struct snd_soc_dapm_route intercon[] = { | |||
839 | {"HPRCOM", NULL, "Right HP Com"}, | 890 | {"HPRCOM", NULL, "Right HP Com"}, |
840 | }; | 891 | }; |
841 | 892 | ||
893 | /* For other than tlv320aic3104 */ | ||
894 | static const struct snd_soc_dapm_route intercon_extra[] = { | ||
895 | /* Left Input */ | ||
896 | {"Left Line2L Mux", "single-ended", "LINE2L"}, | ||
897 | {"Left Line2L Mux", "differential", "LINE2L"}, | ||
898 | |||
899 | {"Left PGA Mixer", "Line2L Switch", "Left Line2L Mux"}, | ||
900 | {"Left PGA Mixer", "Mic3L Switch", "MIC3L"}, | ||
901 | {"Left PGA Mixer", "Mic3R Switch", "MIC3R"}, | ||
902 | |||
903 | {"Left ADC", NULL, "GPIO1 dmic modclk"}, | ||
904 | |||
905 | /* Right Input */ | ||
906 | {"Right Line2R Mux", "single-ended", "LINE2R"}, | ||
907 | {"Right Line2R Mux", "differential", "LINE2R"}, | ||
908 | |||
909 | {"Right PGA Mixer", "Line2R Switch", "Right Line2R Mux"}, | ||
910 | {"Right PGA Mixer", "Mic3L Switch", "MIC3L"}, | ||
911 | {"Right PGA Mixer", "Mic3R Switch", "MIC3R"}, | ||
912 | |||
913 | {"Right ADC", NULL, "GPIO1 dmic modclk"}, | ||
914 | |||
915 | /* | ||
916 | * Logical path between digital mic enable and GPIO1 modulator clock | ||
917 | * output function | ||
918 | */ | ||
919 | {"GPIO1 dmic modclk", NULL, "DMic Rate 128"}, | ||
920 | {"GPIO1 dmic modclk", NULL, "DMic Rate 64"}, | ||
921 | {"GPIO1 dmic modclk", NULL, "DMic Rate 32"}, | ||
922 | |||
923 | /* Left Line Output */ | ||
924 | {"Left Line Mixer", "Line2L Bypass Switch", "Left Line2L Mux"}, | ||
925 | {"Left Line Mixer", "Line2R Bypass Switch", "Right Line2R Mux"}, | ||
926 | |||
927 | /* Right Line Output */ | ||
928 | {"Right Line Mixer", "Line2L Bypass Switch", "Left Line2L Mux"}, | ||
929 | {"Right Line Mixer", "Line2R Bypass Switch", "Right Line2R Mux"}, | ||
930 | |||
931 | /* Left HP Output */ | ||
932 | {"Left HP Mixer", "Line2L Bypass Switch", "Left Line2L Mux"}, | ||
933 | {"Left HP Mixer", "Line2R Bypass Switch", "Right Line2R Mux"}, | ||
934 | |||
935 | /* Right HP Output */ | ||
936 | {"Right HP Mixer", "Line2L Bypass Switch", "Left Line2L Mux"}, | ||
937 | {"Right HP Mixer", "Line2R Bypass Switch", "Right Line2R Mux"}, | ||
938 | |||
939 | /* Left HPCOM Output */ | ||
940 | {"Left HPCOM Mixer", "Line2L Bypass Switch", "Left Line2L Mux"}, | ||
941 | {"Left HPCOM Mixer", "Line2R Bypass Switch", "Right Line2R Mux"}, | ||
942 | |||
943 | /* Right HPCOM Output */ | ||
944 | {"Right HPCOM Mixer", "Line2L Bypass Switch", "Left Line2L Mux"}, | ||
945 | {"Right HPCOM Mixer", "Line2R Bypass Switch", "Right Line2R Mux"}, | ||
946 | }; | ||
947 | |||
948 | /* For tlv320aic3104 */ | ||
949 | static const struct snd_soc_dapm_route intercon_extra_3104[] = { | ||
950 | /* Left Input */ | ||
951 | {"Left PGA Mixer", "Mic2L Switch", "MIC2L"}, | ||
952 | {"Left PGA Mixer", "Mic2R Switch", "MIC2R"}, | ||
953 | |||
954 | /* Right Input */ | ||
955 | {"Right PGA Mixer", "Mic2L Switch", "MIC2L"}, | ||
956 | {"Right PGA Mixer", "Mic2R Switch", "MIC2R"}, | ||
957 | }; | ||
958 | |||
842 | static const struct snd_soc_dapm_route intercon_mono[] = { | 959 | static const struct snd_soc_dapm_route intercon_mono[] = { |
843 | /* Mono Output */ | 960 | /* Mono Output */ |
844 | {"Mono Mixer", "Line2L Bypass Switch", "Left Line2L Mux"}, | 961 | {"Mono Mixer", "Line2L Bypass Switch", "Left Line2L Mux"}, |
@@ -867,17 +984,31 @@ static int aic3x_add_widgets(struct snd_soc_codec *codec) | |||
867 | switch (aic3x->model) { | 984 | switch (aic3x->model) { |
868 | case AIC3X_MODEL_3X: | 985 | case AIC3X_MODEL_3X: |
869 | case AIC3X_MODEL_33: | 986 | case AIC3X_MODEL_33: |
987 | snd_soc_dapm_new_controls(dapm, aic3x_extra_dapm_widgets, | ||
988 | ARRAY_SIZE(aic3x_extra_dapm_widgets)); | ||
989 | snd_soc_dapm_add_routes(dapm, intercon_extra, | ||
990 | ARRAY_SIZE(intercon_extra)); | ||
870 | snd_soc_dapm_new_controls(dapm, aic3x_dapm_mono_widgets, | 991 | snd_soc_dapm_new_controls(dapm, aic3x_dapm_mono_widgets, |
871 | ARRAY_SIZE(aic3x_dapm_mono_widgets)); | 992 | ARRAY_SIZE(aic3x_dapm_mono_widgets)); |
872 | snd_soc_dapm_add_routes(dapm, intercon_mono, | 993 | snd_soc_dapm_add_routes(dapm, intercon_mono, |
873 | ARRAY_SIZE(intercon_mono)); | 994 | ARRAY_SIZE(intercon_mono)); |
874 | break; | 995 | break; |
875 | case AIC3X_MODEL_3007: | 996 | case AIC3X_MODEL_3007: |
997 | snd_soc_dapm_new_controls(dapm, aic3x_extra_dapm_widgets, | ||
998 | ARRAY_SIZE(aic3x_extra_dapm_widgets)); | ||
999 | snd_soc_dapm_add_routes(dapm, intercon_extra, | ||
1000 | ARRAY_SIZE(intercon_extra)); | ||
876 | snd_soc_dapm_new_controls(dapm, aic3007_dapm_widgets, | 1001 | snd_soc_dapm_new_controls(dapm, aic3007_dapm_widgets, |
877 | ARRAY_SIZE(aic3007_dapm_widgets)); | 1002 | ARRAY_SIZE(aic3007_dapm_widgets)); |
878 | snd_soc_dapm_add_routes(dapm, intercon_3007, | 1003 | snd_soc_dapm_add_routes(dapm, intercon_3007, |
879 | ARRAY_SIZE(intercon_3007)); | 1004 | ARRAY_SIZE(intercon_3007)); |
880 | break; | 1005 | break; |
1006 | case AIC3X_MODEL_3104: | ||
1007 | snd_soc_dapm_new_controls(dapm, aic3104_extra_dapm_widgets, | ||
1008 | ARRAY_SIZE(aic3104_extra_dapm_widgets)); | ||
1009 | snd_soc_dapm_add_routes(dapm, intercon_extra_3104, | ||
1010 | ARRAY_SIZE(intercon_extra_3104)); | ||
1011 | break; | ||
881 | } | 1012 | } |
882 | 1013 | ||
883 | return 0; | 1014 | return 0; |
@@ -1046,7 +1177,7 @@ static int aic3x_prepare(struct snd_pcm_substream *substream, | |||
1046 | delay += aic3x->tdm_delay; | 1177 | delay += aic3x->tdm_delay; |
1047 | 1178 | ||
1048 | /* Configure data delay */ | 1179 | /* Configure data delay */ |
1049 | snd_soc_write(codec, AIC3X_ASD_INTF_CTRLC, aic3x->tdm_delay); | 1180 | snd_soc_write(codec, AIC3X_ASD_INTF_CTRLC, delay); |
1050 | 1181 | ||
1051 | return 0; | 1182 | return 0; |
1052 | } | 1183 | } |
@@ -1438,23 +1569,33 @@ static int aic3x_probe(struct snd_soc_codec *codec) | |||
1438 | aic3x_init(codec); | 1569 | aic3x_init(codec); |
1439 | 1570 | ||
1440 | if (aic3x->setup) { | 1571 | if (aic3x->setup) { |
1441 | /* setup GPIO functions */ | 1572 | if (aic3x->model != AIC3X_MODEL_3104) { |
1442 | snd_soc_write(codec, AIC3X_GPIO1_REG, | 1573 | /* setup GPIO functions */ |
1443 | (aic3x->setup->gpio_func[0] & 0xf) << 4); | 1574 | snd_soc_write(codec, AIC3X_GPIO1_REG, |
1444 | snd_soc_write(codec, AIC3X_GPIO2_REG, | 1575 | (aic3x->setup->gpio_func[0] & 0xf) << 4); |
1445 | (aic3x->setup->gpio_func[1] & 0xf) << 4); | 1576 | snd_soc_write(codec, AIC3X_GPIO2_REG, |
1577 | (aic3x->setup->gpio_func[1] & 0xf) << 4); | ||
1578 | } else { | ||
1579 | dev_warn(codec->dev, "GPIO functionality is not supported on tlv320aic3104\n"); | ||
1580 | } | ||
1446 | } | 1581 | } |
1447 | 1582 | ||
1448 | switch (aic3x->model) { | 1583 | switch (aic3x->model) { |
1449 | case AIC3X_MODEL_3X: | 1584 | case AIC3X_MODEL_3X: |
1450 | case AIC3X_MODEL_33: | 1585 | case AIC3X_MODEL_33: |
1586 | snd_soc_add_codec_controls(codec, aic3x_extra_snd_controls, | ||
1587 | ARRAY_SIZE(aic3x_extra_snd_controls)); | ||
1451 | snd_soc_add_codec_controls(codec, aic3x_mono_controls, | 1588 | snd_soc_add_codec_controls(codec, aic3x_mono_controls, |
1452 | ARRAY_SIZE(aic3x_mono_controls)); | 1589 | ARRAY_SIZE(aic3x_mono_controls)); |
1453 | break; | 1590 | break; |
1454 | case AIC3X_MODEL_3007: | 1591 | case AIC3X_MODEL_3007: |
1592 | snd_soc_add_codec_controls(codec, aic3x_extra_snd_controls, | ||
1593 | ARRAY_SIZE(aic3x_extra_snd_controls)); | ||
1455 | snd_soc_add_codec_controls(codec, | 1594 | snd_soc_add_codec_controls(codec, |
1456 | &aic3x_classd_amp_gain_ctrl, 1); | 1595 | &aic3x_classd_amp_gain_ctrl, 1); |
1457 | break; | 1596 | break; |
1597 | case AIC3X_MODEL_3104: | ||
1598 | break; | ||
1458 | } | 1599 | } |
1459 | 1600 | ||
1460 | /* set mic bias voltage */ | 1601 | /* set mic bias voltage */ |
@@ -1522,6 +1663,7 @@ static const struct i2c_device_id aic3x_i2c_id[] = { | |||
1522 | { "tlv320aic33", AIC3X_MODEL_33 }, | 1663 | { "tlv320aic33", AIC3X_MODEL_33 }, |
1523 | { "tlv320aic3007", AIC3X_MODEL_3007 }, | 1664 | { "tlv320aic3007", AIC3X_MODEL_3007 }, |
1524 | { "tlv320aic3106", AIC3X_MODEL_3X }, | 1665 | { "tlv320aic3106", AIC3X_MODEL_3X }, |
1666 | { "tlv320aic3104", AIC3X_MODEL_3104 }, | ||
1525 | { } | 1667 | { } |
1526 | }; | 1668 | }; |
1527 | MODULE_DEVICE_TABLE(i2c, aic3x_i2c_id); | 1669 | MODULE_DEVICE_TABLE(i2c, aic3x_i2c_id); |
@@ -1673,6 +1815,7 @@ static const struct of_device_id tlv320aic3x_of_match[] = { | |||
1673 | { .compatible = "ti,tlv320aic33" }, | 1815 | { .compatible = "ti,tlv320aic33" }, |
1674 | { .compatible = "ti,tlv320aic3007" }, | 1816 | { .compatible = "ti,tlv320aic3007" }, |
1675 | { .compatible = "ti,tlv320aic3106" }, | 1817 | { .compatible = "ti,tlv320aic3106" }, |
1818 | { .compatible = "ti,tlv320aic3104" }, | ||
1676 | {}, | 1819 | {}, |
1677 | }; | 1820 | }; |
1678 | MODULE_DEVICE_TABLE(of, tlv320aic3x_of_match); | 1821 | MODULE_DEVICE_TABLE(of, tlv320aic3x_of_match); |
diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c index 0fe2ced5b09f..4e3e607dec13 100644 --- a/sound/soc/codecs/tlv320dac33.c +++ b/sound/soc/codecs/tlv320dac33.c | |||
@@ -423,17 +423,18 @@ exit: | |||
423 | static int dac33_playback_event(struct snd_soc_dapm_widget *w, | 423 | static int dac33_playback_event(struct snd_soc_dapm_widget *w, |
424 | struct snd_kcontrol *kcontrol, int event) | 424 | struct snd_kcontrol *kcontrol, int event) |
425 | { | 425 | { |
426 | struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(w->codec); | 426 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
427 | struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec); | ||
427 | 428 | ||
428 | switch (event) { | 429 | switch (event) { |
429 | case SND_SOC_DAPM_PRE_PMU: | 430 | case SND_SOC_DAPM_PRE_PMU: |
430 | if (likely(dac33->substream)) { | 431 | if (likely(dac33->substream)) { |
431 | dac33_calculate_times(dac33->substream, w->codec); | 432 | dac33_calculate_times(dac33->substream, codec); |
432 | dac33_prepare_chip(dac33->substream, w->codec); | 433 | dac33_prepare_chip(dac33->substream, codec); |
433 | } | 434 | } |
434 | break; | 435 | break; |
435 | case SND_SOC_DAPM_POST_PMD: | 436 | case SND_SOC_DAPM_POST_PMD: |
436 | dac33_disable_digital(w->codec); | 437 | dac33_disable_digital(codec); |
437 | break; | 438 | break; |
438 | } | 439 | } |
439 | return 0; | 440 | return 0; |
diff --git a/sound/soc/codecs/ts3a227e.c b/sound/soc/codecs/ts3a227e.c index 1d1205702d23..9fd80ac1897f 100644 --- a/sound/soc/codecs/ts3a227e.c +++ b/sound/soc/codecs/ts3a227e.c | |||
@@ -20,6 +20,8 @@ | |||
20 | #include <sound/jack.h> | 20 | #include <sound/jack.h> |
21 | #include <sound/soc.h> | 21 | #include <sound/soc.h> |
22 | 22 | ||
23 | #include "ts3a227e.h" | ||
24 | |||
23 | struct ts3a227e { | 25 | struct ts3a227e { |
24 | struct regmap *regmap; | 26 | struct regmap *regmap; |
25 | struct snd_soc_jack *jack; | 27 | struct snd_soc_jack *jack; |
@@ -79,6 +81,10 @@ static const int ts3a227e_buttons[] = { | |||
79 | /* TS3A227E_REG_SETTING_2 0x05 */ | 81 | /* TS3A227E_REG_SETTING_2 0x05 */ |
80 | #define KP_ENABLE 0x04 | 82 | #define KP_ENABLE 0x04 |
81 | 83 | ||
84 | /* TS3A227E_REG_SETTING_3 0x06 */ | ||
85 | #define MICBIAS_SETTING_SFT (3) | ||
86 | #define MICBIAS_SETTING_MASK (0x7 << MICBIAS_SETTING_SFT) | ||
87 | |||
82 | /* TS3A227E_REG_ACCESSORY_STATUS 0x0b */ | 88 | /* TS3A227E_REG_ACCESSORY_STATUS 0x0b */ |
83 | #define TYPE_3_POLE 0x01 | 89 | #define TYPE_3_POLE 0x01 |
84 | #define TYPE_4_POLE_OMTP 0x02 | 90 | #define TYPE_4_POLE_OMTP 0x02 |
@@ -221,9 +227,9 @@ int ts3a227e_enable_jack_detect(struct snd_soc_component *component, | |||
221 | struct ts3a227e *ts3a227e = snd_soc_component_get_drvdata(component); | 227 | struct ts3a227e *ts3a227e = snd_soc_component_get_drvdata(component); |
222 | 228 | ||
223 | snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_MEDIA); | 229 | snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_MEDIA); |
224 | snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOLUMEUP); | 230 | snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOICECOMMAND); |
225 | snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEDOWN); | 231 | snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP); |
226 | snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOICECOMMAND); | 232 | snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN); |
227 | 233 | ||
228 | ts3a227e->jack = jack; | 234 | ts3a227e->jack = jack; |
229 | ts3a227e_jack_report(ts3a227e); | 235 | ts3a227e_jack_report(ts3a227e); |
@@ -248,12 +254,28 @@ static const struct regmap_config ts3a227e_regmap_config = { | |||
248 | .num_reg_defaults = ARRAY_SIZE(ts3a227e_reg_defaults), | 254 | .num_reg_defaults = ARRAY_SIZE(ts3a227e_reg_defaults), |
249 | }; | 255 | }; |
250 | 256 | ||
257 | static int ts3a227e_parse_dt(struct ts3a227e *ts3a227e, struct device_node *np) | ||
258 | { | ||
259 | u32 micbias; | ||
260 | int err; | ||
261 | |||
262 | err = of_property_read_u32(np, "ti,micbias", &micbias); | ||
263 | if (!err) { | ||
264 | regmap_update_bits(ts3a227e->regmap, TS3A227E_REG_SETTING_3, | ||
265 | MICBIAS_SETTING_MASK, | ||
266 | (micbias & 0x07) << MICBIAS_SETTING_SFT); | ||
267 | } | ||
268 | |||
269 | return 0; | ||
270 | } | ||
271 | |||
251 | static int ts3a227e_i2c_probe(struct i2c_client *i2c, | 272 | static int ts3a227e_i2c_probe(struct i2c_client *i2c, |
252 | const struct i2c_device_id *id) | 273 | const struct i2c_device_id *id) |
253 | { | 274 | { |
254 | struct ts3a227e *ts3a227e; | 275 | struct ts3a227e *ts3a227e; |
255 | struct device *dev = &i2c->dev; | 276 | struct device *dev = &i2c->dev; |
256 | int ret; | 277 | int ret; |
278 | unsigned int acc_reg; | ||
257 | 279 | ||
258 | ts3a227e = devm_kzalloc(&i2c->dev, sizeof(*ts3a227e), GFP_KERNEL); | 280 | ts3a227e = devm_kzalloc(&i2c->dev, sizeof(*ts3a227e), GFP_KERNEL); |
259 | if (ts3a227e == NULL) | 281 | if (ts3a227e == NULL) |
@@ -265,6 +287,14 @@ static int ts3a227e_i2c_probe(struct i2c_client *i2c, | |||
265 | if (IS_ERR(ts3a227e->regmap)) | 287 | if (IS_ERR(ts3a227e->regmap)) |
266 | return PTR_ERR(ts3a227e->regmap); | 288 | return PTR_ERR(ts3a227e->regmap); |
267 | 289 | ||
290 | if (dev->of_node) { | ||
291 | ret = ts3a227e_parse_dt(ts3a227e, dev->of_node); | ||
292 | if (ret) { | ||
293 | dev_err(dev, "Failed to parse device tree: %d\n", ret); | ||
294 | return ret; | ||
295 | } | ||
296 | } | ||
297 | |||
268 | ret = devm_request_threaded_irq(dev, i2c->irq, NULL, ts3a227e_interrupt, | 298 | ret = devm_request_threaded_irq(dev, i2c->irq, NULL, ts3a227e_interrupt, |
269 | IRQF_TRIGGER_LOW | IRQF_ONESHOT, | 299 | IRQF_TRIGGER_LOW | IRQF_ONESHOT, |
270 | "TS3A227E", ts3a227e); | 300 | "TS3A227E", ts3a227e); |
@@ -283,6 +313,11 @@ static int ts3a227e_i2c_probe(struct i2c_client *i2c, | |||
283 | INTB_DISABLE | ADC_COMPLETE_INT_DISABLE, | 313 | INTB_DISABLE | ADC_COMPLETE_INT_DISABLE, |
284 | ADC_COMPLETE_INT_DISABLE); | 314 | ADC_COMPLETE_INT_DISABLE); |
285 | 315 | ||
316 | /* Read jack status because chip might not trigger interrupt at boot. */ | ||
317 | regmap_read(ts3a227e->regmap, TS3A227E_REG_ACCESSORY_STATUS, &acc_reg); | ||
318 | ts3a227e_new_jack_state(ts3a227e, acc_reg); | ||
319 | ts3a227e_jack_report(ts3a227e); | ||
320 | |||
286 | return 0; | 321 | return 0; |
287 | } | 322 | } |
288 | 323 | ||
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c index 44af3188afb9..d04693e9cf9f 100644 --- a/sound/soc/codecs/twl4030.c +++ b/sound/soc/codecs/twl4030.c | |||
@@ -567,12 +567,13 @@ static const struct snd_kcontrol_new twl4030_dapm_dbypassv_control = | |||
567 | static int pin_name##pga_event(struct snd_soc_dapm_widget *w, \ | 567 | static int pin_name##pga_event(struct snd_soc_dapm_widget *w, \ |
568 | struct snd_kcontrol *kcontrol, int event) \ | 568 | struct snd_kcontrol *kcontrol, int event) \ |
569 | { \ | 569 | { \ |
570 | struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(w->codec); \ | 570 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); \ |
571 | struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); \ | ||
571 | \ | 572 | \ |
572 | switch (event) { \ | 573 | switch (event) { \ |
573 | case SND_SOC_DAPM_POST_PMU: \ | 574 | case SND_SOC_DAPM_POST_PMU: \ |
574 | twl4030->pin_name##_enabled = 1; \ | 575 | twl4030->pin_name##_enabled = 1; \ |
575 | twl4030_write(w->codec, reg, twl4030_read(w->codec, reg)); \ | 576 | twl4030_write(codec, reg, twl4030_read(codec, reg)); \ |
576 | break; \ | 577 | break; \ |
577 | case SND_SOC_DAPM_POST_PMD: \ | 578 | case SND_SOC_DAPM_POST_PMD: \ |
578 | twl4030->pin_name##_enabled = 0; \ | 579 | twl4030->pin_name##_enabled = 0; \ |
@@ -621,12 +622,14 @@ static void handsfree_ramp(struct snd_soc_codec *codec, int reg, int ramp) | |||
621 | static int handsfreelpga_event(struct snd_soc_dapm_widget *w, | 622 | static int handsfreelpga_event(struct snd_soc_dapm_widget *w, |
622 | struct snd_kcontrol *kcontrol, int event) | 623 | struct snd_kcontrol *kcontrol, int event) |
623 | { | 624 | { |
625 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); | ||
626 | |||
624 | switch (event) { | 627 | switch (event) { |
625 | case SND_SOC_DAPM_POST_PMU: | 628 | case SND_SOC_DAPM_POST_PMU: |
626 | handsfree_ramp(w->codec, TWL4030_REG_HFL_CTL, 1); | 629 | handsfree_ramp(codec, TWL4030_REG_HFL_CTL, 1); |
627 | break; | 630 | break; |
628 | case SND_SOC_DAPM_POST_PMD: | 631 | case SND_SOC_DAPM_POST_PMD: |
629 | handsfree_ramp(w->codec, TWL4030_REG_HFL_CTL, 0); | 632 | handsfree_ramp(codec, TWL4030_REG_HFL_CTL, 0); |
630 | break; | 633 | break; |
631 | } | 634 | } |
632 | return 0; | 635 | return 0; |
@@ -635,12 +638,14 @@ static int handsfreelpga_event(struct snd_soc_dapm_widget *w, | |||
635 | static int handsfreerpga_event(struct snd_soc_dapm_widget *w, | 638 | static int handsfreerpga_event(struct snd_soc_dapm_widget *w, |
636 | struct snd_kcontrol *kcontrol, int event) | 639 | struct snd_kcontrol *kcontrol, int event) |
637 | { | 640 | { |
641 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); | ||
642 | |||
638 | switch (event) { | 643 | switch (event) { |
639 | case SND_SOC_DAPM_POST_PMU: | 644 | case SND_SOC_DAPM_POST_PMU: |
640 | handsfree_ramp(w->codec, TWL4030_REG_HFR_CTL, 1); | 645 | handsfree_ramp(codec, TWL4030_REG_HFR_CTL, 1); |
641 | break; | 646 | break; |
642 | case SND_SOC_DAPM_POST_PMD: | 647 | case SND_SOC_DAPM_POST_PMD: |
643 | handsfree_ramp(w->codec, TWL4030_REG_HFR_CTL, 0); | 648 | handsfree_ramp(codec, TWL4030_REG_HFR_CTL, 0); |
644 | break; | 649 | break; |
645 | } | 650 | } |
646 | return 0; | 651 | return 0; |
@@ -649,19 +654,23 @@ static int handsfreerpga_event(struct snd_soc_dapm_widget *w, | |||
649 | static int vibramux_event(struct snd_soc_dapm_widget *w, | 654 | static int vibramux_event(struct snd_soc_dapm_widget *w, |
650 | struct snd_kcontrol *kcontrol, int event) | 655 | struct snd_kcontrol *kcontrol, int event) |
651 | { | 656 | { |
652 | twl4030_write(w->codec, TWL4030_REG_VIBRA_SET, 0xff); | 657 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
658 | |||
659 | twl4030_write(codec, TWL4030_REG_VIBRA_SET, 0xff); | ||
653 | return 0; | 660 | return 0; |
654 | } | 661 | } |
655 | 662 | ||
656 | static int apll_event(struct snd_soc_dapm_widget *w, | 663 | static int apll_event(struct snd_soc_dapm_widget *w, |
657 | struct snd_kcontrol *kcontrol, int event) | 664 | struct snd_kcontrol *kcontrol, int event) |
658 | { | 665 | { |
666 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); | ||
667 | |||
659 | switch (event) { | 668 | switch (event) { |
660 | case SND_SOC_DAPM_PRE_PMU: | 669 | case SND_SOC_DAPM_PRE_PMU: |
661 | twl4030_apll_enable(w->codec, 1); | 670 | twl4030_apll_enable(codec, 1); |
662 | break; | 671 | break; |
663 | case SND_SOC_DAPM_POST_PMD: | 672 | case SND_SOC_DAPM_POST_PMD: |
664 | twl4030_apll_enable(w->codec, 0); | 673 | twl4030_apll_enable(codec, 0); |
665 | break; | 674 | break; |
666 | } | 675 | } |
667 | return 0; | 676 | return 0; |
@@ -670,23 +679,24 @@ static int apll_event(struct snd_soc_dapm_widget *w, | |||
670 | static int aif_event(struct snd_soc_dapm_widget *w, | 679 | static int aif_event(struct snd_soc_dapm_widget *w, |
671 | struct snd_kcontrol *kcontrol, int event) | 680 | struct snd_kcontrol *kcontrol, int event) |
672 | { | 681 | { |
682 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); | ||
673 | u8 audio_if; | 683 | u8 audio_if; |
674 | 684 | ||
675 | audio_if = twl4030_read(w->codec, TWL4030_REG_AUDIO_IF); | 685 | audio_if = twl4030_read(codec, TWL4030_REG_AUDIO_IF); |
676 | switch (event) { | 686 | switch (event) { |
677 | case SND_SOC_DAPM_PRE_PMU: | 687 | case SND_SOC_DAPM_PRE_PMU: |
678 | /* Enable AIF */ | 688 | /* Enable AIF */ |
679 | /* enable the PLL before we use it to clock the DAI */ | 689 | /* enable the PLL before we use it to clock the DAI */ |
680 | twl4030_apll_enable(w->codec, 1); | 690 | twl4030_apll_enable(codec, 1); |
681 | 691 | ||
682 | twl4030_write(w->codec, TWL4030_REG_AUDIO_IF, | 692 | twl4030_write(codec, TWL4030_REG_AUDIO_IF, |
683 | audio_if | TWL4030_AIF_EN); | 693 | audio_if | TWL4030_AIF_EN); |
684 | break; | 694 | break; |
685 | case SND_SOC_DAPM_POST_PMD: | 695 | case SND_SOC_DAPM_POST_PMD: |
686 | /* disable the DAI before we stop it's source PLL */ | 696 | /* disable the DAI before we stop it's source PLL */ |
687 | twl4030_write(w->codec, TWL4030_REG_AUDIO_IF, | 697 | twl4030_write(codec, TWL4030_REG_AUDIO_IF, |
688 | audio_if & ~TWL4030_AIF_EN); | 698 | audio_if & ~TWL4030_AIF_EN); |
689 | twl4030_apll_enable(w->codec, 0); | 699 | twl4030_apll_enable(codec, 0); |
690 | break; | 700 | break; |
691 | } | 701 | } |
692 | return 0; | 702 | return 0; |
@@ -758,20 +768,21 @@ static void headset_ramp(struct snd_soc_codec *codec, int ramp) | |||
758 | static int headsetlpga_event(struct snd_soc_dapm_widget *w, | 768 | static int headsetlpga_event(struct snd_soc_dapm_widget *w, |
759 | struct snd_kcontrol *kcontrol, int event) | 769 | struct snd_kcontrol *kcontrol, int event) |
760 | { | 770 | { |
761 | struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(w->codec); | 771 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
772 | struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); | ||
762 | 773 | ||
763 | switch (event) { | 774 | switch (event) { |
764 | case SND_SOC_DAPM_POST_PMU: | 775 | case SND_SOC_DAPM_POST_PMU: |
765 | /* Do the ramp-up only once */ | 776 | /* Do the ramp-up only once */ |
766 | if (!twl4030->hsr_enabled) | 777 | if (!twl4030->hsr_enabled) |
767 | headset_ramp(w->codec, 1); | 778 | headset_ramp(codec, 1); |
768 | 779 | ||
769 | twl4030->hsl_enabled = 1; | 780 | twl4030->hsl_enabled = 1; |
770 | break; | 781 | break; |
771 | case SND_SOC_DAPM_POST_PMD: | 782 | case SND_SOC_DAPM_POST_PMD: |
772 | /* Do the ramp-down only if both headsetL/R is disabled */ | 783 | /* Do the ramp-down only if both headsetL/R is disabled */ |
773 | if (!twl4030->hsr_enabled) | 784 | if (!twl4030->hsr_enabled) |
774 | headset_ramp(w->codec, 0); | 785 | headset_ramp(codec, 0); |
775 | 786 | ||
776 | twl4030->hsl_enabled = 0; | 787 | twl4030->hsl_enabled = 0; |
777 | break; | 788 | break; |
@@ -782,20 +793,21 @@ static int headsetlpga_event(struct snd_soc_dapm_widget *w, | |||
782 | static int headsetrpga_event(struct snd_soc_dapm_widget *w, | 793 | static int headsetrpga_event(struct snd_soc_dapm_widget *w, |
783 | struct snd_kcontrol *kcontrol, int event) | 794 | struct snd_kcontrol *kcontrol, int event) |
784 | { | 795 | { |
785 | struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(w->codec); | 796 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
797 | struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); | ||
786 | 798 | ||
787 | switch (event) { | 799 | switch (event) { |
788 | case SND_SOC_DAPM_POST_PMU: | 800 | case SND_SOC_DAPM_POST_PMU: |
789 | /* Do the ramp-up only once */ | 801 | /* Do the ramp-up only once */ |
790 | if (!twl4030->hsl_enabled) | 802 | if (!twl4030->hsl_enabled) |
791 | headset_ramp(w->codec, 1); | 803 | headset_ramp(codec, 1); |
792 | 804 | ||
793 | twl4030->hsr_enabled = 1; | 805 | twl4030->hsr_enabled = 1; |
794 | break; | 806 | break; |
795 | case SND_SOC_DAPM_POST_PMD: | 807 | case SND_SOC_DAPM_POST_PMD: |
796 | /* Do the ramp-down only if both headsetL/R is disabled */ | 808 | /* Do the ramp-down only if both headsetL/R is disabled */ |
797 | if (!twl4030->hsl_enabled) | 809 | if (!twl4030->hsl_enabled) |
798 | headset_ramp(w->codec, 0); | 810 | headset_ramp(codec, 0); |
799 | 811 | ||
800 | twl4030->hsr_enabled = 0; | 812 | twl4030->hsr_enabled = 0; |
801 | break; | 813 | break; |
@@ -806,7 +818,8 @@ static int headsetrpga_event(struct snd_soc_dapm_widget *w, | |||
806 | static int digimic_event(struct snd_soc_dapm_widget *w, | 818 | static int digimic_event(struct snd_soc_dapm_widget *w, |
807 | struct snd_kcontrol *kcontrol, int event) | 819 | struct snd_kcontrol *kcontrol, int event) |
808 | { | 820 | { |
809 | struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(w->codec); | 821 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
822 | struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); | ||
810 | struct twl4030_codec_data *pdata = twl4030->pdata; | 823 | struct twl4030_codec_data *pdata = twl4030->pdata; |
811 | 824 | ||
812 | if (pdata && pdata->digimic_delay) | 825 | if (pdata && pdata->digimic_delay) |
diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c index 90f47f988b3f..aeec27b6f1af 100644 --- a/sound/soc/codecs/twl6040.c +++ b/sound/soc/codecs/twl6040.c | |||
@@ -234,7 +234,7 @@ static int headset_power_mode(struct snd_soc_codec *codec, int high_perf) | |||
234 | static int twl6040_hs_dac_event(struct snd_soc_dapm_widget *w, | 234 | static int twl6040_hs_dac_event(struct snd_soc_dapm_widget *w, |
235 | struct snd_kcontrol *kcontrol, int event) | 235 | struct snd_kcontrol *kcontrol, int event) |
236 | { | 236 | { |
237 | struct snd_soc_codec *codec = w->codec; | 237 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
238 | u8 hslctl, hsrctl; | 238 | u8 hslctl, hsrctl; |
239 | 239 | ||
240 | /* | 240 | /* |
@@ -261,7 +261,7 @@ static int twl6040_hs_dac_event(struct snd_soc_dapm_widget *w, | |||
261 | static int twl6040_ep_drv_event(struct snd_soc_dapm_widget *w, | 261 | static int twl6040_ep_drv_event(struct snd_soc_dapm_widget *w, |
262 | struct snd_kcontrol *kcontrol, int event) | 262 | struct snd_kcontrol *kcontrol, int event) |
263 | { | 263 | { |
264 | struct snd_soc_codec *codec = w->codec; | 264 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
265 | struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); | 265 | struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); |
266 | int ret = 0; | 266 | int ret = 0; |
267 | 267 | ||
diff --git a/sound/soc/codecs/wm2000.c b/sound/soc/codecs/wm2000.c index 34ef65c52a7d..8d9de49a5052 100644 --- a/sound/soc/codecs/wm2000.c +++ b/sound/soc/codecs/wm2000.c | |||
@@ -683,7 +683,7 @@ static const struct snd_kcontrol_new wm2000_controls[] = { | |||
683 | static int wm2000_anc_power_event(struct snd_soc_dapm_widget *w, | 683 | static int wm2000_anc_power_event(struct snd_soc_dapm_widget *w, |
684 | struct snd_kcontrol *kcontrol, int event) | 684 | struct snd_kcontrol *kcontrol, int event) |
685 | { | 685 | { |
686 | struct snd_soc_codec *codec = w->codec; | 686 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
687 | struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev); | 687 | struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev); |
688 | int ret; | 688 | int ret; |
689 | 689 | ||
diff --git a/sound/soc/codecs/wm5100.c b/sound/soc/codecs/wm5100.c index b80970dc2d2f..ea09db585aa1 100644 --- a/sound/soc/codecs/wm5100.c +++ b/sound/soc/codecs/wm5100.c | |||
@@ -775,7 +775,8 @@ static int wm5100_out_ev(struct snd_soc_dapm_widget *w, | |||
775 | struct snd_kcontrol *kcontrol, | 775 | struct snd_kcontrol *kcontrol, |
776 | int event) | 776 | int event) |
777 | { | 777 | { |
778 | struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(w->codec); | 778 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
779 | struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec); | ||
779 | 780 | ||
780 | switch (w->reg) { | 781 | switch (w->reg) { |
781 | case WM5100_CHANNEL_ENABLES_1: | 782 | case WM5100_CHANNEL_ENABLES_1: |
@@ -839,7 +840,7 @@ static int wm5100_post_ev(struct snd_soc_dapm_widget *w, | |||
839 | struct snd_kcontrol *kcontrol, | 840 | struct snd_kcontrol *kcontrol, |
840 | int event) | 841 | int event) |
841 | { | 842 | { |
842 | struct snd_soc_codec *codec = w->codec; | 843 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
843 | struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec); | 844 | struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec); |
844 | int ret; | 845 | int ret; |
845 | 846 | ||
diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c index f439ae052128..6d0fe0ac95a3 100644 --- a/sound/soc/codecs/wm5102.c +++ b/sound/soc/codecs/wm5102.c | |||
@@ -28,6 +28,7 @@ | |||
28 | 28 | ||
29 | #include <linux/mfd/arizona/core.h> | 29 | #include <linux/mfd/arizona/core.h> |
30 | #include <linux/mfd/arizona/registers.h> | 30 | #include <linux/mfd/arizona/registers.h> |
31 | #include <asm/unaligned.h> | ||
31 | 32 | ||
32 | #include "arizona.h" | 33 | #include "arizona.h" |
33 | #include "wm5102.h" | 34 | #include "wm5102.h" |
@@ -580,7 +581,7 @@ static const struct reg_default wm5102_sysclk_revb_patch[] = { | |||
580 | static int wm5102_sysclk_ev(struct snd_soc_dapm_widget *w, | 581 | static int wm5102_sysclk_ev(struct snd_soc_dapm_widget *w, |
581 | struct snd_kcontrol *kcontrol, int event) | 582 | struct snd_kcontrol *kcontrol, int event) |
582 | { | 583 | { |
583 | struct snd_soc_codec *codec = w->codec; | 584 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
584 | struct arizona *arizona = dev_get_drvdata(codec->dev->parent); | 585 | struct arizona *arizona = dev_get_drvdata(codec->dev->parent); |
585 | struct regmap *regmap = arizona->regmap; | 586 | struct regmap *regmap = arizona->regmap; |
586 | const struct reg_default *patch = NULL; | 587 | const struct reg_default *patch = NULL; |
@@ -617,11 +618,10 @@ static int wm5102_out_comp_coeff_get(struct snd_kcontrol *kcontrol, | |||
617 | { | 618 | { |
618 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); | 619 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
619 | struct arizona *arizona = dev_get_drvdata(codec->dev->parent); | 620 | struct arizona *arizona = dev_get_drvdata(codec->dev->parent); |
620 | uint16_t data; | ||
621 | 621 | ||
622 | mutex_lock(&arizona->dac_comp_lock); | 622 | mutex_lock(&arizona->dac_comp_lock); |
623 | data = cpu_to_be16(arizona->dac_comp_coeff); | 623 | put_unaligned_be16(arizona->dac_comp_coeff, |
624 | memcpy(ucontrol->value.bytes.data, &data, sizeof(data)); | 624 | ucontrol->value.bytes.data); |
625 | mutex_unlock(&arizona->dac_comp_lock); | 625 | mutex_unlock(&arizona->dac_comp_lock); |
626 | 626 | ||
627 | return 0; | 627 | return 0; |
@@ -1272,19 +1272,24 @@ SND_SOC_DAPM_MUX("AEC Loopback", ARIZONA_DAC_AEC_CONTROL_1, | |||
1272 | 1272 | ||
1273 | SND_SOC_DAPM_PGA_E("OUT1L", SND_SOC_NOPM, | 1273 | SND_SOC_DAPM_PGA_E("OUT1L", SND_SOC_NOPM, |
1274 | ARIZONA_OUT1L_ENA_SHIFT, 0, NULL, 0, arizona_hp_ev, | 1274 | ARIZONA_OUT1L_ENA_SHIFT, 0, NULL, 0, arizona_hp_ev, |
1275 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), | 1275 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | |
1276 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), | ||
1276 | SND_SOC_DAPM_PGA_E("OUT1R", SND_SOC_NOPM, | 1277 | SND_SOC_DAPM_PGA_E("OUT1R", SND_SOC_NOPM, |
1277 | ARIZONA_OUT1R_ENA_SHIFT, 0, NULL, 0, arizona_hp_ev, | 1278 | ARIZONA_OUT1R_ENA_SHIFT, 0, NULL, 0, arizona_hp_ev, |
1278 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), | 1279 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | |
1280 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), | ||
1279 | SND_SOC_DAPM_PGA_E("OUT2L", ARIZONA_OUTPUT_ENABLES_1, | 1281 | SND_SOC_DAPM_PGA_E("OUT2L", ARIZONA_OUTPUT_ENABLES_1, |
1280 | ARIZONA_OUT2L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, | 1282 | ARIZONA_OUT2L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, |
1281 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), | 1283 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | |
1284 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), | ||
1282 | SND_SOC_DAPM_PGA_E("OUT2R", ARIZONA_OUTPUT_ENABLES_1, | 1285 | SND_SOC_DAPM_PGA_E("OUT2R", ARIZONA_OUTPUT_ENABLES_1, |
1283 | ARIZONA_OUT2R_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, | 1286 | ARIZONA_OUT2R_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, |
1284 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), | 1287 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | |
1288 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), | ||
1285 | SND_SOC_DAPM_PGA_E("OUT3L", ARIZONA_OUTPUT_ENABLES_1, | 1289 | SND_SOC_DAPM_PGA_E("OUT3L", ARIZONA_OUTPUT_ENABLES_1, |
1286 | ARIZONA_OUT3L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, | 1290 | ARIZONA_OUT3L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, |
1287 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), | 1291 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | |
1292 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), | ||
1288 | SND_SOC_DAPM_PGA_E("OUT5L", ARIZONA_OUTPUT_ENABLES_1, | 1293 | SND_SOC_DAPM_PGA_E("OUT5L", ARIZONA_OUTPUT_ENABLES_1, |
1289 | ARIZONA_OUT5L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, | 1294 | ARIZONA_OUT5L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, |
1290 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), | 1295 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), |
diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c index 4456b38a3ef5..fbaeddb3e903 100644 --- a/sound/soc/codecs/wm5110.c +++ b/sound/soc/codecs/wm5110.c | |||
@@ -134,7 +134,7 @@ static const struct reg_default wm5110_sysclk_revd_patch[] = { | |||
134 | static int wm5110_sysclk_ev(struct snd_soc_dapm_widget *w, | 134 | static int wm5110_sysclk_ev(struct snd_soc_dapm_widget *w, |
135 | struct snd_kcontrol *kcontrol, int event) | 135 | struct snd_kcontrol *kcontrol, int event) |
136 | { | 136 | { |
137 | struct snd_soc_codec *codec = w->codec; | 137 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
138 | struct arizona *arizona = dev_get_drvdata(codec->dev->parent); | 138 | struct arizona *arizona = dev_get_drvdata(codec->dev->parent); |
139 | struct regmap *regmap = arizona->regmap; | 139 | struct regmap *regmap = arizona->regmap; |
140 | const struct reg_default *patch = NULL; | 140 | const struct reg_default *patch = NULL; |
@@ -905,22 +905,28 @@ SND_SOC_DAPM_AIF_IN("AIF3RX2", NULL, 0, | |||
905 | 905 | ||
906 | SND_SOC_DAPM_PGA_E("OUT1L", SND_SOC_NOPM, | 906 | SND_SOC_DAPM_PGA_E("OUT1L", SND_SOC_NOPM, |
907 | ARIZONA_OUT1L_ENA_SHIFT, 0, NULL, 0, arizona_hp_ev, | 907 | ARIZONA_OUT1L_ENA_SHIFT, 0, NULL, 0, arizona_hp_ev, |
908 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), | 908 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | |
909 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), | ||
909 | SND_SOC_DAPM_PGA_E("OUT1R", SND_SOC_NOPM, | 910 | SND_SOC_DAPM_PGA_E("OUT1R", SND_SOC_NOPM, |
910 | ARIZONA_OUT1R_ENA_SHIFT, 0, NULL, 0, arizona_hp_ev, | 911 | ARIZONA_OUT1R_ENA_SHIFT, 0, NULL, 0, arizona_hp_ev, |
911 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), | 912 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | |
913 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), | ||
912 | SND_SOC_DAPM_PGA_E("OUT2L", ARIZONA_OUTPUT_ENABLES_1, | 914 | SND_SOC_DAPM_PGA_E("OUT2L", ARIZONA_OUTPUT_ENABLES_1, |
913 | ARIZONA_OUT2L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, | 915 | ARIZONA_OUT2L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, |
914 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), | 916 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | |
917 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), | ||
915 | SND_SOC_DAPM_PGA_E("OUT2R", ARIZONA_OUTPUT_ENABLES_1, | 918 | SND_SOC_DAPM_PGA_E("OUT2R", ARIZONA_OUTPUT_ENABLES_1, |
916 | ARIZONA_OUT2R_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, | 919 | ARIZONA_OUT2R_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, |
917 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), | 920 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | |
921 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), | ||
918 | SND_SOC_DAPM_PGA_E("OUT3L", ARIZONA_OUTPUT_ENABLES_1, | 922 | SND_SOC_DAPM_PGA_E("OUT3L", ARIZONA_OUTPUT_ENABLES_1, |
919 | ARIZONA_OUT3L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, | 923 | ARIZONA_OUT3L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, |
920 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), | 924 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | |
925 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), | ||
921 | SND_SOC_DAPM_PGA_E("OUT3R", ARIZONA_OUTPUT_ENABLES_1, | 926 | SND_SOC_DAPM_PGA_E("OUT3R", ARIZONA_OUTPUT_ENABLES_1, |
922 | ARIZONA_OUT3R_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, | 927 | ARIZONA_OUT3R_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, |
923 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), | 928 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | |
929 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), | ||
924 | SND_SOC_DAPM_PGA_E("OUT5L", ARIZONA_OUTPUT_ENABLES_1, | 930 | SND_SOC_DAPM_PGA_E("OUT5L", ARIZONA_OUTPUT_ENABLES_1, |
925 | ARIZONA_OUT5L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, | 931 | ARIZONA_OUT5L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, |
926 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), | 932 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), |
diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c index 574579b98872..c81a9eab3e3e 100644 --- a/sound/soc/codecs/wm8350.c +++ b/sound/soc/codecs/wm8350.c | |||
@@ -259,7 +259,7 @@ static void wm8350_pga_work(struct work_struct *work) | |||
259 | static int pga_event(struct snd_soc_dapm_widget *w, | 259 | static int pga_event(struct snd_soc_dapm_widget *w, |
260 | struct snd_kcontrol *kcontrol, int event) | 260 | struct snd_kcontrol *kcontrol, int event) |
261 | { | 261 | { |
262 | struct snd_soc_codec *codec = w->codec; | 262 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
263 | struct wm8350_data *wm8350_data = snd_soc_codec_get_drvdata(codec); | 263 | struct wm8350_data *wm8350_data = snd_soc_codec_get_drvdata(codec); |
264 | struct wm8350_output *out; | 264 | struct wm8350_output *out; |
265 | 265 | ||
diff --git a/sound/soc/codecs/wm8400.c b/sound/soc/codecs/wm8400.c index 8ee446987aa9..b0d84e552fca 100644 --- a/sound/soc/codecs/wm8400.c +++ b/sound/soc/codecs/wm8400.c | |||
@@ -324,6 +324,7 @@ SOC_SINGLE("RIN34 Mute Switch", WM8400_RIGHT_LINE_INPUT_3_4_VOLUME, | |||
324 | static int outmixer_event (struct snd_soc_dapm_widget *w, | 324 | static int outmixer_event (struct snd_soc_dapm_widget *w, |
325 | struct snd_kcontrol * kcontrol, int event) | 325 | struct snd_kcontrol * kcontrol, int event) |
326 | { | 326 | { |
327 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); | ||
327 | struct soc_mixer_control *mc = | 328 | struct soc_mixer_control *mc = |
328 | (struct soc_mixer_control *)kcontrol->private_value; | 329 | (struct soc_mixer_control *)kcontrol->private_value; |
329 | u32 reg_shift = mc->shift; | 330 | u32 reg_shift = mc->shift; |
@@ -332,7 +333,7 @@ static int outmixer_event (struct snd_soc_dapm_widget *w, | |||
332 | 333 | ||
333 | switch (reg_shift) { | 334 | switch (reg_shift) { |
334 | case WM8400_SPEAKER_MIXER | (WM8400_LDSPK << 8) : | 335 | case WM8400_SPEAKER_MIXER | (WM8400_LDSPK << 8) : |
335 | reg = snd_soc_read(w->codec, WM8400_OUTPUT_MIXER1); | 336 | reg = snd_soc_read(codec, WM8400_OUTPUT_MIXER1); |
336 | if (reg & WM8400_LDLO) { | 337 | if (reg & WM8400_LDLO) { |
337 | printk(KERN_WARNING | 338 | printk(KERN_WARNING |
338 | "Cannot set as Output Mixer 1 LDLO Set\n"); | 339 | "Cannot set as Output Mixer 1 LDLO Set\n"); |
@@ -340,7 +341,7 @@ static int outmixer_event (struct snd_soc_dapm_widget *w, | |||
340 | } | 341 | } |
341 | break; | 342 | break; |
342 | case WM8400_SPEAKER_MIXER | (WM8400_RDSPK << 8): | 343 | case WM8400_SPEAKER_MIXER | (WM8400_RDSPK << 8): |
343 | reg = snd_soc_read(w->codec, WM8400_OUTPUT_MIXER2); | 344 | reg = snd_soc_read(codec, WM8400_OUTPUT_MIXER2); |
344 | if (reg & WM8400_RDRO) { | 345 | if (reg & WM8400_RDRO) { |
345 | printk(KERN_WARNING | 346 | printk(KERN_WARNING |
346 | "Cannot set as Output Mixer 2 RDRO Set\n"); | 347 | "Cannot set as Output Mixer 2 RDRO Set\n"); |
@@ -348,7 +349,7 @@ static int outmixer_event (struct snd_soc_dapm_widget *w, | |||
348 | } | 349 | } |
349 | break; | 350 | break; |
350 | case WM8400_OUTPUT_MIXER1 | (WM8400_LDLO << 8): | 351 | case WM8400_OUTPUT_MIXER1 | (WM8400_LDLO << 8): |
351 | reg = snd_soc_read(w->codec, WM8400_SPEAKER_MIXER); | 352 | reg = snd_soc_read(codec, WM8400_SPEAKER_MIXER); |
352 | if (reg & WM8400_LDSPK) { | 353 | if (reg & WM8400_LDSPK) { |
353 | printk(KERN_WARNING | 354 | printk(KERN_WARNING |
354 | "Cannot set as Speaker Mixer LDSPK Set\n"); | 355 | "Cannot set as Speaker Mixer LDSPK Set\n"); |
@@ -356,7 +357,7 @@ static int outmixer_event (struct snd_soc_dapm_widget *w, | |||
356 | } | 357 | } |
357 | break; | 358 | break; |
358 | case WM8400_OUTPUT_MIXER2 | (WM8400_RDRO << 8): | 359 | case WM8400_OUTPUT_MIXER2 | (WM8400_RDRO << 8): |
359 | reg = snd_soc_read(w->codec, WM8400_SPEAKER_MIXER); | 360 | reg = snd_soc_read(codec, WM8400_SPEAKER_MIXER); |
360 | if (reg & WM8400_RDSPK) { | 361 | if (reg & WM8400_RDSPK) { |
361 | printk(KERN_WARNING | 362 | printk(KERN_WARNING |
362 | "Cannot set as Speaker Mixer RDSPK Set\n"); | 363 | "Cannot set as Speaker Mixer RDSPK Set\n"); |
diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c index b9211b42f6e9..098c143f44d6 100644 --- a/sound/soc/codecs/wm8731.c +++ b/sound/soc/codecs/wm8731.c | |||
@@ -217,7 +217,8 @@ SND_SOC_DAPM_INPUT("LLINEIN"), | |||
217 | static int wm8731_check_osc(struct snd_soc_dapm_widget *source, | 217 | static int wm8731_check_osc(struct snd_soc_dapm_widget *source, |
218 | struct snd_soc_dapm_widget *sink) | 218 | struct snd_soc_dapm_widget *sink) |
219 | { | 219 | { |
220 | struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(source->codec); | 220 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm); |
221 | struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec); | ||
221 | 222 | ||
222 | return wm8731->sysclk_type == WM8731_SYSCLK_XTAL; | 223 | return wm8731->sysclk_type == WM8731_SYSCLK_XTAL; |
223 | } | 224 | } |
@@ -717,6 +718,8 @@ static int wm8731_i2c_probe(struct i2c_client *i2c, | |||
717 | if (wm8731 == NULL) | 718 | if (wm8731 == NULL) |
718 | return -ENOMEM; | 719 | return -ENOMEM; |
719 | 720 | ||
721 | mutex_init(&wm8731->lock); | ||
722 | |||
720 | wm8731->regmap = devm_regmap_init_i2c(i2c, &wm8731_regmap); | 723 | wm8731->regmap = devm_regmap_init_i2c(i2c, &wm8731_regmap); |
721 | if (IS_ERR(wm8731->regmap)) { | 724 | if (IS_ERR(wm8731->regmap)) { |
722 | ret = PTR_ERR(wm8731->regmap); | 725 | ret = PTR_ERR(wm8731->regmap); |
diff --git a/sound/soc/codecs/wm8750.c b/sound/soc/codecs/wm8750.c index f6847fdd6ddd..eb0a1644ba11 100644 --- a/sound/soc/codecs/wm8750.c +++ b/sound/soc/codecs/wm8750.c | |||
@@ -323,7 +323,7 @@ static const struct snd_soc_dapm_widget wm8750_dapm_widgets[] = { | |||
323 | SND_SOC_DAPM_OUTPUT("ROUT2"), | 323 | SND_SOC_DAPM_OUTPUT("ROUT2"), |
324 | SND_SOC_DAPM_OUTPUT("MONO1"), | 324 | SND_SOC_DAPM_OUTPUT("MONO1"), |
325 | SND_SOC_DAPM_OUTPUT("OUT3"), | 325 | SND_SOC_DAPM_OUTPUT("OUT3"), |
326 | SND_SOC_DAPM_OUTPUT("VREF"), | 326 | SND_SOC_DAPM_VMID("VREF"), |
327 | 327 | ||
328 | SND_SOC_DAPM_INPUT("LINPUT1"), | 328 | SND_SOC_DAPM_INPUT("LINPUT1"), |
329 | SND_SOC_DAPM_INPUT("LINPUT2"), | 329 | SND_SOC_DAPM_INPUT("LINPUT2"), |
diff --git a/sound/soc/codecs/wm8770.c b/sound/soc/codecs/wm8770.c index 180e7a098726..53e977da2f86 100644 --- a/sound/soc/codecs/wm8770.c +++ b/sound/soc/codecs/wm8770.c | |||
@@ -308,9 +308,7 @@ static const struct snd_soc_dapm_route wm8770_intercon[] = { | |||
308 | static int vout12supply_event(struct snd_soc_dapm_widget *w, | 308 | static int vout12supply_event(struct snd_soc_dapm_widget *w, |
309 | struct snd_kcontrol *kcontrol, int event) | 309 | struct snd_kcontrol *kcontrol, int event) |
310 | { | 310 | { |
311 | struct snd_soc_codec *codec; | 311 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
312 | |||
313 | codec = w->codec; | ||
314 | 312 | ||
315 | switch (event) { | 313 | switch (event) { |
316 | case SND_SOC_DAPM_PRE_PMU: | 314 | case SND_SOC_DAPM_PRE_PMU: |
@@ -327,9 +325,7 @@ static int vout12supply_event(struct snd_soc_dapm_widget *w, | |||
327 | static int vout34supply_event(struct snd_soc_dapm_widget *w, | 325 | static int vout34supply_event(struct snd_soc_dapm_widget *w, |
328 | struct snd_kcontrol *kcontrol, int event) | 326 | struct snd_kcontrol *kcontrol, int event) |
329 | { | 327 | { |
330 | struct snd_soc_codec *codec; | 328 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
331 | |||
332 | codec = w->codec; | ||
333 | 329 | ||
334 | switch (event) { | 330 | switch (event) { |
335 | case SND_SOC_DAPM_PRE_PMU: | 331 | case SND_SOC_DAPM_PRE_PMU: |
diff --git a/sound/soc/codecs/wm8900.c b/sound/soc/codecs/wm8900.c index 3a0d4b7d692f..2eb986c19b88 100644 --- a/sound/soc/codecs/wm8900.c +++ b/sound/soc/codecs/wm8900.c | |||
@@ -224,7 +224,7 @@ static void wm8900_reset(struct snd_soc_codec *codec) | |||
224 | static int wm8900_hp_event(struct snd_soc_dapm_widget *w, | 224 | static int wm8900_hp_event(struct snd_soc_dapm_widget *w, |
225 | struct snd_kcontrol *kcontrol, int event) | 225 | struct snd_kcontrol *kcontrol, int event) |
226 | { | 226 | { |
227 | struct snd_soc_codec *codec = w->codec; | 227 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
228 | u16 hpctl1 = snd_soc_read(codec, WM8900_REG_HPCTL1); | 228 | u16 hpctl1 = snd_soc_read(codec, WM8900_REG_HPCTL1); |
229 | 229 | ||
230 | switch (event) { | 230 | switch (event) { |
diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c index cc6b0ef98a34..dde462c082be 100644 --- a/sound/soc/codecs/wm8903.c +++ b/sound/soc/codecs/wm8903.c | |||
@@ -260,7 +260,7 @@ static int wm8903_cp_event(struct snd_soc_dapm_widget *w, | |||
260 | static int wm8903_dcs_event(struct snd_soc_dapm_widget *w, | 260 | static int wm8903_dcs_event(struct snd_soc_dapm_widget *w, |
261 | struct snd_kcontrol *kcontrol, int event) | 261 | struct snd_kcontrol *kcontrol, int event) |
262 | { | 262 | { |
263 | struct snd_soc_codec *codec = w->codec; | 263 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
264 | struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); | 264 | struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); |
265 | 265 | ||
266 | switch (event) { | 266 | switch (event) { |
diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c index 4d2d2b1380d5..c5eaa0198ef0 100644 --- a/sound/soc/codecs/wm8904.c +++ b/sound/soc/codecs/wm8904.c | |||
@@ -673,7 +673,7 @@ static int cp_event(struct snd_soc_dapm_widget *w, | |||
673 | static int sysclk_event(struct snd_soc_dapm_widget *w, | 673 | static int sysclk_event(struct snd_soc_dapm_widget *w, |
674 | struct snd_kcontrol *kcontrol, int event) | 674 | struct snd_kcontrol *kcontrol, int event) |
675 | { | 675 | { |
676 | struct snd_soc_codec *codec = w->codec; | 676 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
677 | struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec); | 677 | struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec); |
678 | 678 | ||
679 | switch (event) { | 679 | switch (event) { |
@@ -711,7 +711,7 @@ static int sysclk_event(struct snd_soc_dapm_widget *w, | |||
711 | static int out_pga_event(struct snd_soc_dapm_widget *w, | 711 | static int out_pga_event(struct snd_soc_dapm_widget *w, |
712 | struct snd_kcontrol *kcontrol, int event) | 712 | struct snd_kcontrol *kcontrol, int event) |
713 | { | 713 | { |
714 | struct snd_soc_codec *codec = w->codec; | 714 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
715 | struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec); | 715 | struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec); |
716 | int reg, val; | 716 | int reg, val; |
717 | int dcs_mask; | 717 | int dcs_mask; |
@@ -1076,10 +1076,13 @@ static const struct snd_soc_dapm_route adc_intercon[] = { | |||
1076 | { "Right Capture PGA", NULL, "Right Capture Mux" }, | 1076 | { "Right Capture PGA", NULL, "Right Capture Mux" }, |
1077 | { "Right Capture PGA", NULL, "Right Capture Inverting Mux" }, | 1077 | { "Right Capture PGA", NULL, "Right Capture Inverting Mux" }, |
1078 | 1078 | ||
1079 | { "AIFOUTL", "Left", "ADCL" }, | 1079 | { "AIFOUTL Mux", "Left", "ADCL" }, |
1080 | { "AIFOUTL", "Right", "ADCR" }, | 1080 | { "AIFOUTL Mux", "Right", "ADCR" }, |
1081 | { "AIFOUTR", "Left", "ADCL" }, | 1081 | { "AIFOUTR Mux", "Left", "ADCL" }, |
1082 | { "AIFOUTR", "Right", "ADCR" }, | 1082 | { "AIFOUTR Mux", "Right", "ADCR" }, |
1083 | |||
1084 | { "AIFOUTL", NULL, "AIFOUTL Mux" }, | ||
1085 | { "AIFOUTR", NULL, "AIFOUTR Mux" }, | ||
1083 | 1086 | ||
1084 | { "ADCL", NULL, "CLK_DSP" }, | 1087 | { "ADCL", NULL, "CLK_DSP" }, |
1085 | { "ADCL", NULL, "Left Capture PGA" }, | 1088 | { "ADCL", NULL, "Left Capture PGA" }, |
@@ -1089,12 +1092,16 @@ static const struct snd_soc_dapm_route adc_intercon[] = { | |||
1089 | }; | 1092 | }; |
1090 | 1093 | ||
1091 | static const struct snd_soc_dapm_route dac_intercon[] = { | 1094 | static const struct snd_soc_dapm_route dac_intercon[] = { |
1092 | { "DACL", "Right", "AIFINR" }, | 1095 | { "DACL Mux", "Left", "AIFINL" }, |
1093 | { "DACL", "Left", "AIFINL" }, | 1096 | { "DACL Mux", "Right", "AIFINR" }, |
1097 | |||
1098 | { "DACR Mux", "Left", "AIFINL" }, | ||
1099 | { "DACR Mux", "Right", "AIFINR" }, | ||
1100 | |||
1101 | { "DACL", NULL, "DACL Mux" }, | ||
1094 | { "DACL", NULL, "CLK_DSP" }, | 1102 | { "DACL", NULL, "CLK_DSP" }, |
1095 | 1103 | ||
1096 | { "DACR", "Right", "AIFINR" }, | 1104 | { "DACR", NULL, "DACR Mux" }, |
1097 | { "DACR", "Left", "AIFINL" }, | ||
1098 | { "DACR", NULL, "CLK_DSP" }, | 1105 | { "DACR", NULL, "CLK_DSP" }, |
1099 | 1106 | ||
1100 | { "Charge pump", NULL, "SYSCLK" }, | 1107 | { "Charge pump", NULL, "SYSCLK" }, |
diff --git a/sound/soc/codecs/wm8955.c b/sound/soc/codecs/wm8955.c index 1173f7fef5a7..1ab2d462afad 100644 --- a/sound/soc/codecs/wm8955.c +++ b/sound/soc/codecs/wm8955.c | |||
@@ -333,7 +333,7 @@ static int wm8955_configure_clocking(struct snd_soc_codec *codec) | |||
333 | static int wm8955_sysclk(struct snd_soc_dapm_widget *w, | 333 | static int wm8955_sysclk(struct snd_soc_dapm_widget *w, |
334 | struct snd_kcontrol *kcontrol, int event) | 334 | struct snd_kcontrol *kcontrol, int event) |
335 | { | 335 | { |
336 | struct snd_soc_codec *codec = w->codec; | 336 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
337 | int ret = 0; | 337 | int ret = 0; |
338 | 338 | ||
339 | /* Always disable the clocks - if we're doing reconfiguration this | 339 | /* Always disable the clocks - if we're doing reconfiguration this |
diff --git a/sound/soc/codecs/wm8958-dsp2.c b/sound/soc/codecs/wm8958-dsp2.c index 3cbc82b33292..c799cca5abeb 100644 --- a/sound/soc/codecs/wm8958-dsp2.c +++ b/sound/soc/codecs/wm8958-dsp2.c | |||
@@ -418,7 +418,7 @@ static void wm8958_dsp_apply(struct snd_soc_codec *codec, int path, int start) | |||
418 | int wm8958_aif_ev(struct snd_soc_dapm_widget *w, | 418 | int wm8958_aif_ev(struct snd_soc_dapm_widget *w, |
419 | struct snd_kcontrol *kcontrol, int event) | 419 | struct snd_kcontrol *kcontrol, int event) |
420 | { | 420 | { |
421 | struct snd_soc_codec *codec = w->codec; | 421 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
422 | int i; | 422 | int i; |
423 | 423 | ||
424 | switch (event) { | 424 | switch (event) { |
diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c index 031a1ae71d94..a96eb497a379 100644 --- a/sound/soc/codecs/wm8960.c +++ b/sound/soc/codecs/wm8960.c | |||
@@ -556,7 +556,7 @@ static struct { | |||
556 | { 22050, 2 }, | 556 | { 22050, 2 }, |
557 | { 24000, 2 }, | 557 | { 24000, 2 }, |
558 | { 16000, 3 }, | 558 | { 16000, 3 }, |
559 | { 11250, 4 }, | 559 | { 11025, 4 }, |
560 | { 12000, 4 }, | 560 | { 12000, 4 }, |
561 | { 8000, 5 }, | 561 | { 8000, 5 }, |
562 | }; | 562 | }; |
diff --git a/sound/soc/codecs/wm8961.c b/sound/soc/codecs/wm8961.c index eeffd05384b4..95e2c1bfc809 100644 --- a/sound/soc/codecs/wm8961.c +++ b/sound/soc/codecs/wm8961.c | |||
@@ -194,7 +194,7 @@ static bool wm8961_readable(struct device *dev, unsigned int reg) | |||
194 | static int wm8961_hp_event(struct snd_soc_dapm_widget *w, | 194 | static int wm8961_hp_event(struct snd_soc_dapm_widget *w, |
195 | struct snd_kcontrol *kcontrol, int event) | 195 | struct snd_kcontrol *kcontrol, int event) |
196 | { | 196 | { |
197 | struct snd_soc_codec *codec = w->codec; | 197 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
198 | u16 hp_reg = snd_soc_read(codec, WM8961_ANALOGUE_HP_0); | 198 | u16 hp_reg = snd_soc_read(codec, WM8961_ANALOGUE_HP_0); |
199 | u16 cp_reg = snd_soc_read(codec, WM8961_CHARGE_PUMP_1); | 199 | u16 cp_reg = snd_soc_read(codec, WM8961_CHARGE_PUMP_1); |
200 | u16 pwr_reg = snd_soc_read(codec, WM8961_PWR_MGMT_2); | 200 | u16 pwr_reg = snd_soc_read(codec, WM8961_PWR_MGMT_2); |
@@ -286,7 +286,7 @@ static int wm8961_hp_event(struct snd_soc_dapm_widget *w, | |||
286 | static int wm8961_spk_event(struct snd_soc_dapm_widget *w, | 286 | static int wm8961_spk_event(struct snd_soc_dapm_widget *w, |
287 | struct snd_kcontrol *kcontrol, int event) | 287 | struct snd_kcontrol *kcontrol, int event) |
288 | { | 288 | { |
289 | struct snd_soc_codec *codec = w->codec; | 289 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
290 | u16 pwr_reg = snd_soc_read(codec, WM8961_PWR_MGMT_2); | 290 | u16 pwr_reg = snd_soc_read(codec, WM8961_PWR_MGMT_2); |
291 | u16 spk_reg = snd_soc_read(codec, WM8961_CLASS_D_CONTROL_1); | 291 | u16 spk_reg = snd_soc_read(codec, WM8961_CLASS_D_CONTROL_1); |
292 | 292 | ||
diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c index d32d554f5b34..118b0034ba23 100644 --- a/sound/soc/codecs/wm8962.c +++ b/sound/soc/codecs/wm8962.c | |||
@@ -1866,7 +1866,7 @@ static int cp_event(struct snd_soc_dapm_widget *w, | |||
1866 | static int hp_event(struct snd_soc_dapm_widget *w, | 1866 | static int hp_event(struct snd_soc_dapm_widget *w, |
1867 | struct snd_kcontrol *kcontrol, int event) | 1867 | struct snd_kcontrol *kcontrol, int event) |
1868 | { | 1868 | { |
1869 | struct snd_soc_codec *codec = w->codec; | 1869 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
1870 | int timeout; | 1870 | int timeout; |
1871 | int reg; | 1871 | int reg; |
1872 | int expected = (WM8962_DCS_STARTUP_DONE_HP1L | | 1872 | int expected = (WM8962_DCS_STARTUP_DONE_HP1L | |
@@ -1960,7 +1960,7 @@ static int hp_event(struct snd_soc_dapm_widget *w, | |||
1960 | static int out_pga_event(struct snd_soc_dapm_widget *w, | 1960 | static int out_pga_event(struct snd_soc_dapm_widget *w, |
1961 | struct snd_kcontrol *kcontrol, int event) | 1961 | struct snd_kcontrol *kcontrol, int event) |
1962 | { | 1962 | { |
1963 | struct snd_soc_codec *codec = w->codec; | 1963 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
1964 | int reg; | 1964 | int reg; |
1965 | 1965 | ||
1966 | switch (w->shift) { | 1966 | switch (w->shift) { |
@@ -1993,7 +1993,7 @@ static int out_pga_event(struct snd_soc_dapm_widget *w, | |||
1993 | static int dsp2_event(struct snd_soc_dapm_widget *w, | 1993 | static int dsp2_event(struct snd_soc_dapm_widget *w, |
1994 | struct snd_kcontrol *kcontrol, int event) | 1994 | struct snd_kcontrol *kcontrol, int event) |
1995 | { | 1995 | { |
1996 | struct snd_soc_codec *codec = w->codec; | 1996 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
1997 | struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); | 1997 | struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); |
1998 | 1998 | ||
1999 | switch (event) { | 1999 | switch (event) { |
diff --git a/sound/soc/codecs/wm8988.c b/sound/soc/codecs/wm8988.c index e418199155a8..baff2cc222a6 100644 --- a/sound/soc/codecs/wm8988.c +++ b/sound/soc/codecs/wm8988.c | |||
@@ -244,7 +244,7 @@ SOC_DOUBLE_R_TLV("Output 2 Playback Volume", WM8988_LOUT2V, WM8988_ROUT2V, | |||
244 | static int wm8988_lrc_control(struct snd_soc_dapm_widget *w, | 244 | static int wm8988_lrc_control(struct snd_soc_dapm_widget *w, |
245 | struct snd_kcontrol *kcontrol, int event) | 245 | struct snd_kcontrol *kcontrol, int event) |
246 | { | 246 | { |
247 | struct snd_soc_codec *codec = w->codec; | 247 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
248 | u16 adctl2 = snd_soc_read(codec, WM8988_ADCTL2); | 248 | u16 adctl2 = snd_soc_read(codec, WM8988_ADCTL2); |
249 | 249 | ||
250 | /* Use the DAC to gate LRC if active, otherwise use ADC */ | 250 | /* Use the DAC to gate LRC if active, otherwise use ADC */ |
diff --git a/sound/soc/codecs/wm8990.c b/sound/soc/codecs/wm8990.c index 8a584229310a..c93bffcb3cfb 100644 --- a/sound/soc/codecs/wm8990.c +++ b/sound/soc/codecs/wm8990.c | |||
@@ -374,13 +374,14 @@ SOC_SINGLE("RIN34 Mute Switch", WM8990_RIGHT_LINE_INPUT_3_4_VOLUME, | |||
374 | static int outmixer_event(struct snd_soc_dapm_widget *w, | 374 | static int outmixer_event(struct snd_soc_dapm_widget *w, |
375 | struct snd_kcontrol *kcontrol, int event) | 375 | struct snd_kcontrol *kcontrol, int event) |
376 | { | 376 | { |
377 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); | ||
377 | u32 reg_shift = kcontrol->private_value & 0xfff; | 378 | u32 reg_shift = kcontrol->private_value & 0xfff; |
378 | int ret = 0; | 379 | int ret = 0; |
379 | u16 reg; | 380 | u16 reg; |
380 | 381 | ||
381 | switch (reg_shift) { | 382 | switch (reg_shift) { |
382 | case WM8990_SPEAKER_MIXER | (WM8990_LDSPK_BIT << 8) : | 383 | case WM8990_SPEAKER_MIXER | (WM8990_LDSPK_BIT << 8) : |
383 | reg = snd_soc_read(w->codec, WM8990_OUTPUT_MIXER1); | 384 | reg = snd_soc_read(codec, WM8990_OUTPUT_MIXER1); |
384 | if (reg & WM8990_LDLO) { | 385 | if (reg & WM8990_LDLO) { |
385 | printk(KERN_WARNING | 386 | printk(KERN_WARNING |
386 | "Cannot set as Output Mixer 1 LDLO Set\n"); | 387 | "Cannot set as Output Mixer 1 LDLO Set\n"); |
@@ -388,7 +389,7 @@ static int outmixer_event(struct snd_soc_dapm_widget *w, | |||
388 | } | 389 | } |
389 | break; | 390 | break; |
390 | case WM8990_SPEAKER_MIXER | (WM8990_RDSPK_BIT << 8): | 391 | case WM8990_SPEAKER_MIXER | (WM8990_RDSPK_BIT << 8): |
391 | reg = snd_soc_read(w->codec, WM8990_OUTPUT_MIXER2); | 392 | reg = snd_soc_read(codec, WM8990_OUTPUT_MIXER2); |
392 | if (reg & WM8990_RDRO) { | 393 | if (reg & WM8990_RDRO) { |
393 | printk(KERN_WARNING | 394 | printk(KERN_WARNING |
394 | "Cannot set as Output Mixer 2 RDRO Set\n"); | 395 | "Cannot set as Output Mixer 2 RDRO Set\n"); |
@@ -396,7 +397,7 @@ static int outmixer_event(struct snd_soc_dapm_widget *w, | |||
396 | } | 397 | } |
397 | break; | 398 | break; |
398 | case WM8990_OUTPUT_MIXER1 | (WM8990_LDLO_BIT << 8): | 399 | case WM8990_OUTPUT_MIXER1 | (WM8990_LDLO_BIT << 8): |
399 | reg = snd_soc_read(w->codec, WM8990_SPEAKER_MIXER); | 400 | reg = snd_soc_read(codec, WM8990_SPEAKER_MIXER); |
400 | if (reg & WM8990_LDSPK) { | 401 | if (reg & WM8990_LDSPK) { |
401 | printk(KERN_WARNING | 402 | printk(KERN_WARNING |
402 | "Cannot set as Speaker Mixer LDSPK Set\n"); | 403 | "Cannot set as Speaker Mixer LDSPK Set\n"); |
@@ -404,7 +405,7 @@ static int outmixer_event(struct snd_soc_dapm_widget *w, | |||
404 | } | 405 | } |
405 | break; | 406 | break; |
406 | case WM8990_OUTPUT_MIXER2 | (WM8990_RDRO_BIT << 8): | 407 | case WM8990_OUTPUT_MIXER2 | (WM8990_RDRO_BIT << 8): |
407 | reg = snd_soc_read(w->codec, WM8990_SPEAKER_MIXER); | 408 | reg = snd_soc_read(codec, WM8990_SPEAKER_MIXER); |
408 | if (reg & WM8990_RDSPK) { | 409 | if (reg & WM8990_RDSPK) { |
409 | printk(KERN_WARNING | 410 | printk(KERN_WARNING |
410 | "Cannot set as Speaker Mixer RDSPK Set\n"); | 411 | "Cannot set as Speaker Mixer RDSPK Set\n"); |
diff --git a/sound/soc/codecs/wm8991.c b/sound/soc/codecs/wm8991.c index b0ac2c3e31b9..49df0dc607e6 100644 --- a/sound/soc/codecs/wm8991.c +++ b/sound/soc/codecs/wm8991.c | |||
@@ -382,13 +382,14 @@ static const struct snd_kcontrol_new wm8991_snd_controls[] = { | |||
382 | static int outmixer_event(struct snd_soc_dapm_widget *w, | 382 | static int outmixer_event(struct snd_soc_dapm_widget *w, |
383 | struct snd_kcontrol *kcontrol, int event) | 383 | struct snd_kcontrol *kcontrol, int event) |
384 | { | 384 | { |
385 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); | ||
385 | u32 reg_shift = kcontrol->private_value & 0xfff; | 386 | u32 reg_shift = kcontrol->private_value & 0xfff; |
386 | int ret = 0; | 387 | int ret = 0; |
387 | u16 reg; | 388 | u16 reg; |
388 | 389 | ||
389 | switch (reg_shift) { | 390 | switch (reg_shift) { |
390 | case WM8991_SPEAKER_MIXER | (WM8991_LDSPK_BIT << 8): | 391 | case WM8991_SPEAKER_MIXER | (WM8991_LDSPK_BIT << 8): |
391 | reg = snd_soc_read(w->codec, WM8991_OUTPUT_MIXER1); | 392 | reg = snd_soc_read(codec, WM8991_OUTPUT_MIXER1); |
392 | if (reg & WM8991_LDLO) { | 393 | if (reg & WM8991_LDLO) { |
393 | printk(KERN_WARNING | 394 | printk(KERN_WARNING |
394 | "Cannot set as Output Mixer 1 LDLO Set\n"); | 395 | "Cannot set as Output Mixer 1 LDLO Set\n"); |
@@ -397,7 +398,7 @@ static int outmixer_event(struct snd_soc_dapm_widget *w, | |||
397 | break; | 398 | break; |
398 | 399 | ||
399 | case WM8991_SPEAKER_MIXER | (WM8991_RDSPK_BIT << 8): | 400 | case WM8991_SPEAKER_MIXER | (WM8991_RDSPK_BIT << 8): |
400 | reg = snd_soc_read(w->codec, WM8991_OUTPUT_MIXER2); | 401 | reg = snd_soc_read(codec, WM8991_OUTPUT_MIXER2); |
401 | if (reg & WM8991_RDRO) { | 402 | if (reg & WM8991_RDRO) { |
402 | printk(KERN_WARNING | 403 | printk(KERN_WARNING |
403 | "Cannot set as Output Mixer 2 RDRO Set\n"); | 404 | "Cannot set as Output Mixer 2 RDRO Set\n"); |
@@ -406,7 +407,7 @@ static int outmixer_event(struct snd_soc_dapm_widget *w, | |||
406 | break; | 407 | break; |
407 | 408 | ||
408 | case WM8991_OUTPUT_MIXER1 | (WM8991_LDLO_BIT << 8): | 409 | case WM8991_OUTPUT_MIXER1 | (WM8991_LDLO_BIT << 8): |
409 | reg = snd_soc_read(w->codec, WM8991_SPEAKER_MIXER); | 410 | reg = snd_soc_read(codec, WM8991_SPEAKER_MIXER); |
410 | if (reg & WM8991_LDSPK) { | 411 | if (reg & WM8991_LDSPK) { |
411 | printk(KERN_WARNING | 412 | printk(KERN_WARNING |
412 | "Cannot set as Speaker Mixer LDSPK Set\n"); | 413 | "Cannot set as Speaker Mixer LDSPK Set\n"); |
@@ -415,7 +416,7 @@ static int outmixer_event(struct snd_soc_dapm_widget *w, | |||
415 | break; | 416 | break; |
416 | 417 | ||
417 | case WM8991_OUTPUT_MIXER2 | (WM8991_RDRO_BIT << 8): | 418 | case WM8991_OUTPUT_MIXER2 | (WM8991_RDRO_BIT << 8): |
418 | reg = snd_soc_read(w->codec, WM8991_SPEAKER_MIXER); | 419 | reg = snd_soc_read(codec, WM8991_SPEAKER_MIXER); |
419 | if (reg & WM8991_RDSPK) { | 420 | if (reg & WM8991_RDSPK) { |
420 | printk(KERN_WARNING | 421 | printk(KERN_WARNING |
421 | "Cannot set as Speaker Mixer RDSPK Set\n"); | 422 | "Cannot set as Speaker Mixer RDSPK Set\n"); |
diff --git a/sound/soc/codecs/wm8993.c b/sound/soc/codecs/wm8993.c index 53c6fe359496..2e70a270eb28 100644 --- a/sound/soc/codecs/wm8993.c +++ b/sound/soc/codecs/wm8993.c | |||
@@ -810,7 +810,7 @@ SOC_SINGLE_TLV("EQ5 Volume", WM8993_EQ6, 0, 24, 0, eq_tlv), | |||
810 | static int clk_sys_event(struct snd_soc_dapm_widget *w, | 810 | static int clk_sys_event(struct snd_soc_dapm_widget *w, |
811 | struct snd_kcontrol *kcontrol, int event) | 811 | struct snd_kcontrol *kcontrol, int event) |
812 | { | 812 | { |
813 | struct snd_soc_codec *codec = w->codec; | 813 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
814 | 814 | ||
815 | switch (event) { | 815 | switch (event) { |
816 | case SND_SOC_DAPM_PRE_PMU: | 816 | case SND_SOC_DAPM_PRE_PMU: |
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index 1b97de2e4e67..4fbc7689339a 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c | |||
@@ -249,7 +249,8 @@ static int configure_clock(struct snd_soc_codec *codec) | |||
249 | static int check_clk_sys(struct snd_soc_dapm_widget *source, | 249 | static int check_clk_sys(struct snd_soc_dapm_widget *source, |
250 | struct snd_soc_dapm_widget *sink) | 250 | struct snd_soc_dapm_widget *sink) |
251 | { | 251 | { |
252 | int reg = snd_soc_read(source->codec, WM8994_CLOCKING_1); | 252 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm); |
253 | int reg = snd_soc_read(codec, WM8994_CLOCKING_1); | ||
253 | const char *clk; | 254 | const char *clk; |
254 | 255 | ||
255 | /* Check what we're currently using for CLK_SYS */ | 256 | /* Check what we're currently using for CLK_SYS */ |
@@ -806,7 +807,7 @@ static void active_dereference(struct snd_soc_codec *codec) | |||
806 | static int clk_sys_event(struct snd_soc_dapm_widget *w, | 807 | static int clk_sys_event(struct snd_soc_dapm_widget *w, |
807 | struct snd_kcontrol *kcontrol, int event) | 808 | struct snd_kcontrol *kcontrol, int event) |
808 | { | 809 | { |
809 | struct snd_soc_codec *codec = w->codec; | 810 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
810 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | 811 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
811 | 812 | ||
812 | switch (event) { | 813 | switch (event) { |
@@ -981,7 +982,7 @@ static void vmid_dereference(struct snd_soc_codec *codec) | |||
981 | static int vmid_event(struct snd_soc_dapm_widget *w, | 982 | static int vmid_event(struct snd_soc_dapm_widget *w, |
982 | struct snd_kcontrol *kcontrol, int event) | 983 | struct snd_kcontrol *kcontrol, int event) |
983 | { | 984 | { |
984 | struct snd_soc_codec *codec = w->codec; | 985 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
985 | 986 | ||
986 | switch (event) { | 987 | switch (event) { |
987 | case SND_SOC_DAPM_PRE_PMU: | 988 | case SND_SOC_DAPM_PRE_PMU: |
@@ -1037,7 +1038,7 @@ static bool wm8994_check_class_w_digital(struct snd_soc_codec *codec) | |||
1037 | static int aif1clk_ev(struct snd_soc_dapm_widget *w, | 1038 | static int aif1clk_ev(struct snd_soc_dapm_widget *w, |
1038 | struct snd_kcontrol *kcontrol, int event) | 1039 | struct snd_kcontrol *kcontrol, int event) |
1039 | { | 1040 | { |
1040 | struct snd_soc_codec *codec = w->codec; | 1041 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
1041 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | 1042 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
1042 | struct wm8994 *control = wm8994->wm8994; | 1043 | struct wm8994 *control = wm8994->wm8994; |
1043 | int mask = WM8994_AIF1DAC1L_ENA | WM8994_AIF1DAC1R_ENA; | 1044 | int mask = WM8994_AIF1DAC1L_ENA | WM8994_AIF1DAC1R_ENA; |
@@ -1135,7 +1136,7 @@ static int aif1clk_ev(struct snd_soc_dapm_widget *w, | |||
1135 | static int aif2clk_ev(struct snd_soc_dapm_widget *w, | 1136 | static int aif2clk_ev(struct snd_soc_dapm_widget *w, |
1136 | struct snd_kcontrol *kcontrol, int event) | 1137 | struct snd_kcontrol *kcontrol, int event) |
1137 | { | 1138 | { |
1138 | struct snd_soc_codec *codec = w->codec; | 1139 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
1139 | int i; | 1140 | int i; |
1140 | int dac; | 1141 | int dac; |
1141 | int adc; | 1142 | int adc; |
@@ -1220,7 +1221,7 @@ static int aif2clk_ev(struct snd_soc_dapm_widget *w, | |||
1220 | static int aif1clk_late_ev(struct snd_soc_dapm_widget *w, | 1221 | static int aif1clk_late_ev(struct snd_soc_dapm_widget *w, |
1221 | struct snd_kcontrol *kcontrol, int event) | 1222 | struct snd_kcontrol *kcontrol, int event) |
1222 | { | 1223 | { |
1223 | struct snd_soc_codec *codec = w->codec; | 1224 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
1224 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | 1225 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
1225 | 1226 | ||
1226 | switch (event) { | 1227 | switch (event) { |
@@ -1238,7 +1239,7 @@ static int aif1clk_late_ev(struct snd_soc_dapm_widget *w, | |||
1238 | static int aif2clk_late_ev(struct snd_soc_dapm_widget *w, | 1239 | static int aif2clk_late_ev(struct snd_soc_dapm_widget *w, |
1239 | struct snd_kcontrol *kcontrol, int event) | 1240 | struct snd_kcontrol *kcontrol, int event) |
1240 | { | 1241 | { |
1241 | struct snd_soc_codec *codec = w->codec; | 1242 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
1242 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | 1243 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
1243 | 1244 | ||
1244 | switch (event) { | 1245 | switch (event) { |
@@ -1256,7 +1257,7 @@ static int aif2clk_late_ev(struct snd_soc_dapm_widget *w, | |||
1256 | static int late_enable_ev(struct snd_soc_dapm_widget *w, | 1257 | static int late_enable_ev(struct snd_soc_dapm_widget *w, |
1257 | struct snd_kcontrol *kcontrol, int event) | 1258 | struct snd_kcontrol *kcontrol, int event) |
1258 | { | 1259 | { |
1259 | struct snd_soc_codec *codec = w->codec; | 1260 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
1260 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | 1261 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
1261 | 1262 | ||
1262 | switch (event) { | 1263 | switch (event) { |
@@ -1289,7 +1290,7 @@ static int late_enable_ev(struct snd_soc_dapm_widget *w, | |||
1289 | static int late_disable_ev(struct snd_soc_dapm_widget *w, | 1290 | static int late_disable_ev(struct snd_soc_dapm_widget *w, |
1290 | struct snd_kcontrol *kcontrol, int event) | 1291 | struct snd_kcontrol *kcontrol, int event) |
1291 | { | 1292 | { |
1292 | struct snd_soc_codec *codec = w->codec; | 1293 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
1293 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | 1294 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
1294 | 1295 | ||
1295 | switch (event) { | 1296 | switch (event) { |
@@ -1331,7 +1332,7 @@ static int micbias_ev(struct snd_soc_dapm_widget *w, | |||
1331 | static int dac_ev(struct snd_soc_dapm_widget *w, | 1332 | static int dac_ev(struct snd_soc_dapm_widget *w, |
1332 | struct snd_kcontrol *kcontrol, int event) | 1333 | struct snd_kcontrol *kcontrol, int event) |
1333 | { | 1334 | { |
1334 | struct snd_soc_codec *codec = w->codec; | 1335 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
1335 | unsigned int mask = 1 << w->shift; | 1336 | unsigned int mask = 1 << w->shift; |
1336 | 1337 | ||
1337 | snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_5, | 1338 | snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_5, |
@@ -1372,7 +1373,7 @@ SOC_DAPM_SINGLE("DAC1 Switch", WM8994_SPEAKER_MIXER, 0, 1, 0), | |||
1372 | static int post_ev(struct snd_soc_dapm_widget *w, | 1373 | static int post_ev(struct snd_soc_dapm_widget *w, |
1373 | struct snd_kcontrol *kcontrol, int event) | 1374 | struct snd_kcontrol *kcontrol, int event) |
1374 | { | 1375 | { |
1375 | struct snd_soc_codec *codec = w->codec; | 1376 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
1376 | dev_dbg(codec->dev, "SRC status: %x\n", | 1377 | dev_dbg(codec->dev, "SRC status: %x\n", |
1377 | snd_soc_read(codec, | 1378 | snd_soc_read(codec, |
1378 | WM8994_RATE_STATUS)); | 1379 | WM8994_RATE_STATUS)); |
diff --git a/sound/soc/codecs/wm8995.c b/sound/soc/codecs/wm8995.c index c280f0a3a424..79e1aead5131 100644 --- a/sound/soc/codecs/wm8995.c +++ b/sound/soc/codecs/wm8995.c | |||
@@ -534,10 +534,11 @@ static void wm8995_update_class_w(struct snd_soc_codec *codec) | |||
534 | static int check_clk_sys(struct snd_soc_dapm_widget *source, | 534 | static int check_clk_sys(struct snd_soc_dapm_widget *source, |
535 | struct snd_soc_dapm_widget *sink) | 535 | struct snd_soc_dapm_widget *sink) |
536 | { | 536 | { |
537 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm); | ||
537 | unsigned int reg; | 538 | unsigned int reg; |
538 | const char *clk; | 539 | const char *clk; |
539 | 540 | ||
540 | reg = snd_soc_read(source->codec, WM8995_CLOCKING_1); | 541 | reg = snd_soc_read(codec, WM8995_CLOCKING_1); |
541 | /* Check what we're currently using for CLK_SYS */ | 542 | /* Check what we're currently using for CLK_SYS */ |
542 | if (reg & WM8995_SYSCLK_SRC) | 543 | if (reg & WM8995_SYSCLK_SRC) |
543 | clk = "AIF2CLK"; | 544 | clk = "AIF2CLK"; |
@@ -560,9 +561,7 @@ static int wm8995_put_class_w(struct snd_kcontrol *kcontrol, | |||
560 | static int hp_supply_event(struct snd_soc_dapm_widget *w, | 561 | static int hp_supply_event(struct snd_soc_dapm_widget *w, |
561 | struct snd_kcontrol *kcontrol, int event) | 562 | struct snd_kcontrol *kcontrol, int event) |
562 | { | 563 | { |
563 | struct snd_soc_codec *codec; | 564 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
564 | |||
565 | codec = w->codec; | ||
566 | 565 | ||
567 | switch (event) { | 566 | switch (event) { |
568 | case SND_SOC_DAPM_PRE_PMU: | 567 | case SND_SOC_DAPM_PRE_PMU: |
@@ -611,10 +610,9 @@ static void dc_servo_cmd(struct snd_soc_codec *codec, | |||
611 | static int hp_event(struct snd_soc_dapm_widget *w, | 610 | static int hp_event(struct snd_soc_dapm_widget *w, |
612 | struct snd_kcontrol *kcontrol, int event) | 611 | struct snd_kcontrol *kcontrol, int event) |
613 | { | 612 | { |
614 | struct snd_soc_codec *codec; | 613 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
615 | unsigned int reg; | 614 | unsigned int reg; |
616 | 615 | ||
617 | codec = w->codec; | ||
618 | reg = snd_soc_read(codec, WM8995_ANALOGUE_HP_1); | 616 | reg = snd_soc_read(codec, WM8995_ANALOGUE_HP_1); |
619 | 617 | ||
620 | switch (event) { | 618 | switch (event) { |
@@ -761,9 +759,7 @@ static int configure_clock(struct snd_soc_codec *codec) | |||
761 | static int clk_sys_event(struct snd_soc_dapm_widget *w, | 759 | static int clk_sys_event(struct snd_soc_dapm_widget *w, |
762 | struct snd_kcontrol *kcontrol, int event) | 760 | struct snd_kcontrol *kcontrol, int event) |
763 | { | 761 | { |
764 | struct snd_soc_codec *codec; | 762 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
765 | |||
766 | codec = w->codec; | ||
767 | 763 | ||
768 | switch (event) { | 764 | switch (event) { |
769 | case SND_SOC_DAPM_PRE_PMU: | 765 | case SND_SOC_DAPM_PRE_PMU: |
diff --git a/sound/soc/codecs/wm8996.c b/sound/soc/codecs/wm8996.c index b1dcc11c1b23..dc92d5e4e942 100644 --- a/sound/soc/codecs/wm8996.c +++ b/sound/soc/codecs/wm8996.c | |||
@@ -599,7 +599,7 @@ static void wm8996_bg_disable(struct snd_soc_codec *codec) | |||
599 | static int bg_event(struct snd_soc_dapm_widget *w, | 599 | static int bg_event(struct snd_soc_dapm_widget *w, |
600 | struct snd_kcontrol *kcontrol, int event) | 600 | struct snd_kcontrol *kcontrol, int event) |
601 | { | 601 | { |
602 | struct snd_soc_codec *codec = w->codec; | 602 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
603 | int ret = 0; | 603 | int ret = 0; |
604 | 604 | ||
605 | switch (event) { | 605 | switch (event) { |
@@ -634,7 +634,8 @@ static int cp_event(struct snd_soc_dapm_widget *w, | |||
634 | static int rmv_short_event(struct snd_soc_dapm_widget *w, | 634 | static int rmv_short_event(struct snd_soc_dapm_widget *w, |
635 | struct snd_kcontrol *kcontrol, int event) | 635 | struct snd_kcontrol *kcontrol, int event) |
636 | { | 636 | { |
637 | struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(w->codec); | 637 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
638 | struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec); | ||
638 | 639 | ||
639 | /* Record which outputs we enabled */ | 640 | /* Record which outputs we enabled */ |
640 | switch (event) { | 641 | switch (event) { |
@@ -758,7 +759,8 @@ static void wm8996_seq_notifier(struct snd_soc_dapm_context *dapm, | |||
758 | static int dcs_start(struct snd_soc_dapm_widget *w, | 759 | static int dcs_start(struct snd_soc_dapm_widget *w, |
759 | struct snd_kcontrol *kcontrol, int event) | 760 | struct snd_kcontrol *kcontrol, int event) |
760 | { | 761 | { |
761 | struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(w->codec); | 762 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
763 | struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec); | ||
762 | 764 | ||
763 | switch (event) { | 765 | switch (event) { |
764 | case SND_SOC_DAPM_POST_PMU: | 766 | case SND_SOC_DAPM_POST_PMU: |
diff --git a/sound/soc/codecs/wm8997.c b/sound/soc/codecs/wm8997.c index 7e8bfe27566b..a4d11770630c 100644 --- a/sound/soc/codecs/wm8997.c +++ b/sound/soc/codecs/wm8997.c | |||
@@ -84,7 +84,7 @@ static const struct reg_default wm8997_sysclk_reva_patch[] = { | |||
84 | static int wm8997_sysclk_ev(struct snd_soc_dapm_widget *w, | 84 | static int wm8997_sysclk_ev(struct snd_soc_dapm_widget *w, |
85 | struct snd_kcontrol *kcontrol, int event) | 85 | struct snd_kcontrol *kcontrol, int event) |
86 | { | 86 | { |
87 | struct snd_soc_codec *codec = w->codec; | 87 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
88 | struct arizona *arizona = dev_get_drvdata(codec->dev->parent); | 88 | struct arizona *arizona = dev_get_drvdata(codec->dev->parent); |
89 | struct regmap *regmap = arizona->regmap; | 89 | struct regmap *regmap = arizona->regmap; |
90 | const struct reg_default *patch = NULL; | 90 | const struct reg_default *patch = NULL; |
@@ -610,13 +610,16 @@ SND_SOC_DAPM_MUX("AEC Loopback", ARIZONA_DAC_AEC_CONTROL_1, | |||
610 | 610 | ||
611 | SND_SOC_DAPM_PGA_E("OUT1L", SND_SOC_NOPM, | 611 | SND_SOC_DAPM_PGA_E("OUT1L", SND_SOC_NOPM, |
612 | ARIZONA_OUT1L_ENA_SHIFT, 0, NULL, 0, arizona_hp_ev, | 612 | ARIZONA_OUT1L_ENA_SHIFT, 0, NULL, 0, arizona_hp_ev, |
613 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), | 613 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | |
614 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), | ||
614 | SND_SOC_DAPM_PGA_E("OUT1R", SND_SOC_NOPM, | 615 | SND_SOC_DAPM_PGA_E("OUT1R", SND_SOC_NOPM, |
615 | ARIZONA_OUT1R_ENA_SHIFT, 0, NULL, 0, arizona_hp_ev, | 616 | ARIZONA_OUT1R_ENA_SHIFT, 0, NULL, 0, arizona_hp_ev, |
616 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), | 617 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | |
618 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), | ||
617 | SND_SOC_DAPM_PGA_E("OUT3L", ARIZONA_OUTPUT_ENABLES_1, | 619 | SND_SOC_DAPM_PGA_E("OUT3L", ARIZONA_OUTPUT_ENABLES_1, |
618 | ARIZONA_OUT3L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, | 620 | ARIZONA_OUT3L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, |
619 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), | 621 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | |
622 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), | ||
620 | SND_SOC_DAPM_PGA_E("OUT5L", ARIZONA_OUTPUT_ENABLES_1, | 623 | SND_SOC_DAPM_PGA_E("OUT5L", ARIZONA_OUTPUT_ENABLES_1, |
621 | ARIZONA_OUT5L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, | 624 | ARIZONA_OUT5L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, |
622 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), | 625 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), |
diff --git a/sound/soc/codecs/wm9081.c b/sound/soc/codecs/wm9081.c index b1d946facd57..13a3f335ea5b 100644 --- a/sound/soc/codecs/wm9081.c +++ b/sound/soc/codecs/wm9081.c | |||
@@ -734,7 +734,7 @@ static int configure_clock(struct snd_soc_codec *codec) | |||
734 | static int clk_sys_event(struct snd_soc_dapm_widget *w, | 734 | static int clk_sys_event(struct snd_soc_dapm_widget *w, |
735 | struct snd_kcontrol *kcontrol, int event) | 735 | struct snd_kcontrol *kcontrol, int event) |
736 | { | 736 | { |
737 | struct snd_soc_codec *codec = w->codec; | 737 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
738 | struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec); | 738 | struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec); |
739 | 739 | ||
740 | /* This should be done on init() for bypass paths */ | 740 | /* This should be done on init() for bypass paths */ |
diff --git a/sound/soc/codecs/wm9090.c b/sound/soc/codecs/wm9090.c index 6ffe8dc4f3fa..60d243c904f5 100644 --- a/sound/soc/codecs/wm9090.c +++ b/sound/soc/codecs/wm9090.c | |||
@@ -254,7 +254,7 @@ SOC_SINGLE_TLV("MIXOUTR IN2B Volume", WM9090_OUTPUT_MIXER4, 0, 3, 1, | |||
254 | static int hp_ev(struct snd_soc_dapm_widget *w, | 254 | static int hp_ev(struct snd_soc_dapm_widget *w, |
255 | struct snd_kcontrol *kcontrol, int event) | 255 | struct snd_kcontrol *kcontrol, int event) |
256 | { | 256 | { |
257 | struct snd_soc_codec *codec = w->codec; | 257 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
258 | unsigned int reg = snd_soc_read(codec, WM9090_ANALOGUE_HP_0); | 258 | unsigned int reg = snd_soc_read(codec, WM9090_ANALOGUE_HP_0); |
259 | 259 | ||
260 | switch (event) { | 260 | switch (event) { |
diff --git a/sound/soc/codecs/wm9705.c b/sound/soc/codecs/wm9705.c index 3eddb18fefd1..5cc457ef8894 100644 --- a/sound/soc/codecs/wm9705.c +++ b/sound/soc/codecs/wm9705.c | |||
@@ -344,23 +344,27 @@ static int wm9705_soc_probe(struct snd_soc_codec *codec) | |||
344 | struct snd_ac97 *ac97; | 344 | struct snd_ac97 *ac97; |
345 | int ret = 0; | 345 | int ret = 0; |
346 | 346 | ||
347 | ac97 = snd_soc_new_ac97_codec(codec); | 347 | ac97 = snd_soc_alloc_ac97_codec(codec); |
348 | if (IS_ERR(ac97)) { | 348 | if (IS_ERR(ac97)) { |
349 | ret = PTR_ERR(ac97); | 349 | ret = PTR_ERR(ac97); |
350 | dev_err(codec->dev, "Failed to register AC97 codec\n"); | 350 | dev_err(codec->dev, "Failed to register AC97 codec\n"); |
351 | return ret; | 351 | return ret; |
352 | } | 352 | } |
353 | 353 | ||
354 | snd_soc_codec_set_drvdata(codec, ac97); | ||
355 | |||
356 | ret = wm9705_reset(codec); | 354 | ret = wm9705_reset(codec); |
357 | if (ret) | 355 | if (ret) |
358 | goto reset_err; | 356 | goto err_put_device; |
357 | |||
358 | ret = device_add(&ac97->dev); | ||
359 | if (ret) | ||
360 | goto err_put_device; | ||
361 | |||
362 | snd_soc_codec_set_drvdata(codec, ac97); | ||
359 | 363 | ||
360 | return 0; | 364 | return 0; |
361 | 365 | ||
362 | reset_err: | 366 | err_put_device: |
363 | snd_soc_free_ac97_codec(ac97); | 367 | put_device(&ac97->dev); |
364 | return ret; | 368 | return ret; |
365 | } | 369 | } |
366 | 370 | ||
diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c index e04643d2bb24..9517571e820d 100644 --- a/sound/soc/codecs/wm9712.c +++ b/sound/soc/codecs/wm9712.c | |||
@@ -666,7 +666,7 @@ static int wm9712_soc_probe(struct snd_soc_codec *codec) | |||
666 | struct wm9712_priv *wm9712 = snd_soc_codec_get_drvdata(codec); | 666 | struct wm9712_priv *wm9712 = snd_soc_codec_get_drvdata(codec); |
667 | int ret = 0; | 667 | int ret = 0; |
668 | 668 | ||
669 | wm9712->ac97 = snd_soc_new_ac97_codec(codec); | 669 | wm9712->ac97 = snd_soc_alloc_ac97_codec(codec); |
670 | if (IS_ERR(wm9712->ac97)) { | 670 | if (IS_ERR(wm9712->ac97)) { |
671 | ret = PTR_ERR(wm9712->ac97); | 671 | ret = PTR_ERR(wm9712->ac97); |
672 | dev_err(codec->dev, "Failed to register AC97 codec: %d\n", ret); | 672 | dev_err(codec->dev, "Failed to register AC97 codec: %d\n", ret); |
@@ -675,15 +675,19 @@ static int wm9712_soc_probe(struct snd_soc_codec *codec) | |||
675 | 675 | ||
676 | ret = wm9712_reset(codec, 0); | 676 | ret = wm9712_reset(codec, 0); |
677 | if (ret < 0) | 677 | if (ret < 0) |
678 | goto reset_err; | 678 | goto err_put_device; |
679 | |||
680 | ret = device_add(&wm9712->ac97->dev); | ||
681 | if (ret) | ||
682 | goto err_put_device; | ||
679 | 683 | ||
680 | /* set alc mux to none */ | 684 | /* set alc mux to none */ |
681 | ac97_write(codec, AC97_VIDEO, ac97_read(codec, AC97_VIDEO) | 0x3000); | 685 | ac97_write(codec, AC97_VIDEO, ac97_read(codec, AC97_VIDEO) | 0x3000); |
682 | 686 | ||
683 | return 0; | 687 | return 0; |
684 | 688 | ||
685 | reset_err: | 689 | err_put_device: |
686 | snd_soc_free_ac97_codec(wm9712->ac97); | 690 | put_device(&wm9712->ac97->dev); |
687 | return ret; | 691 | return ret; |
688 | } | 692 | } |
689 | 693 | ||
diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c index 71b9d5b0734d..68222917b396 100644 --- a/sound/soc/codecs/wm9713.c +++ b/sound/soc/codecs/wm9713.c | |||
@@ -217,7 +217,7 @@ SOC_SINGLE("3D Depth", AC97_REC_GAIN_MIC, 0, 15, 1), | |||
217 | static int wm9713_voice_shutdown(struct snd_soc_dapm_widget *w, | 217 | static int wm9713_voice_shutdown(struct snd_soc_dapm_widget *w, |
218 | struct snd_kcontrol *kcontrol, int event) | 218 | struct snd_kcontrol *kcontrol, int event) |
219 | { | 219 | { |
220 | struct snd_soc_codec *codec = w->codec; | 220 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
221 | u16 status, rate; | 221 | u16 status, rate; |
222 | 222 | ||
223 | if (WARN_ON(event != SND_SOC_DAPM_PRE_PMD)) | 223 | if (WARN_ON(event != SND_SOC_DAPM_PRE_PMD)) |
@@ -1225,7 +1225,7 @@ static int wm9713_soc_probe(struct snd_soc_codec *codec) | |||
1225 | struct wm9713_priv *wm9713 = snd_soc_codec_get_drvdata(codec); | 1225 | struct wm9713_priv *wm9713 = snd_soc_codec_get_drvdata(codec); |
1226 | int ret = 0, reg; | 1226 | int ret = 0, reg; |
1227 | 1227 | ||
1228 | wm9713->ac97 = snd_soc_new_ac97_codec(codec); | 1228 | wm9713->ac97 = snd_soc_alloc_ac97_codec(codec); |
1229 | if (IS_ERR(wm9713->ac97)) | 1229 | if (IS_ERR(wm9713->ac97)) |
1230 | return PTR_ERR(wm9713->ac97); | 1230 | return PTR_ERR(wm9713->ac97); |
1231 | 1231 | ||
@@ -1234,7 +1234,11 @@ static int wm9713_soc_probe(struct snd_soc_codec *codec) | |||
1234 | wm9713_reset(codec, 0); | 1234 | wm9713_reset(codec, 0); |
1235 | ret = wm9713_reset(codec, 1); | 1235 | ret = wm9713_reset(codec, 1); |
1236 | if (ret < 0) | 1236 | if (ret < 0) |
1237 | goto reset_err; | 1237 | goto err_put_device; |
1238 | |||
1239 | ret = device_add(&wm9713->ac97->dev); | ||
1240 | if (ret) | ||
1241 | goto err_put_device; | ||
1238 | 1242 | ||
1239 | /* unmute the adc - move to kcontrol */ | 1243 | /* unmute the adc - move to kcontrol */ |
1240 | reg = ac97_read(codec, AC97_CD) & 0x7fff; | 1244 | reg = ac97_read(codec, AC97_CD) & 0x7fff; |
@@ -1242,8 +1246,8 @@ static int wm9713_soc_probe(struct snd_soc_codec *codec) | |||
1242 | 1246 | ||
1243 | return 0; | 1247 | return 0; |
1244 | 1248 | ||
1245 | reset_err: | 1249 | err_put_device: |
1246 | snd_soc_free_ac97_codec(wm9713->ac97); | 1250 | put_device(&wm9713->ac97->dev); |
1247 | return ret; | 1251 | return ret; |
1248 | } | 1252 | } |
1249 | 1253 | ||
diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c index 720d6e852986..ff67b334065b 100644 --- a/sound/soc/codecs/wm_adsp.c +++ b/sound/soc/codecs/wm_adsp.c | |||
@@ -1373,7 +1373,7 @@ int wm_adsp1_event(struct snd_soc_dapm_widget *w, | |||
1373 | struct snd_kcontrol *kcontrol, | 1373 | struct snd_kcontrol *kcontrol, |
1374 | int event) | 1374 | int event) |
1375 | { | 1375 | { |
1376 | struct snd_soc_codec *codec = w->codec; | 1376 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
1377 | struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec); | 1377 | struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec); |
1378 | struct wm_adsp *dsp = &dsps[w->shift]; | 1378 | struct wm_adsp *dsp = &dsps[w->shift]; |
1379 | struct wm_adsp_alg_region *alg_region; | 1379 | struct wm_adsp_alg_region *alg_region; |
@@ -1605,7 +1605,7 @@ err: | |||
1605 | int wm_adsp2_early_event(struct snd_soc_dapm_widget *w, | 1605 | int wm_adsp2_early_event(struct snd_soc_dapm_widget *w, |
1606 | struct snd_kcontrol *kcontrol, int event) | 1606 | struct snd_kcontrol *kcontrol, int event) |
1607 | { | 1607 | { |
1608 | struct snd_soc_codec *codec = w->codec; | 1608 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
1609 | struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec); | 1609 | struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec); |
1610 | struct wm_adsp *dsp = &dsps[w->shift]; | 1610 | struct wm_adsp *dsp = &dsps[w->shift]; |
1611 | 1611 | ||
@@ -1626,7 +1626,7 @@ EXPORT_SYMBOL_GPL(wm_adsp2_early_event); | |||
1626 | int wm_adsp2_event(struct snd_soc_dapm_widget *w, | 1626 | int wm_adsp2_event(struct snd_soc_dapm_widget *w, |
1627 | struct snd_kcontrol *kcontrol, int event) | 1627 | struct snd_kcontrol *kcontrol, int event) |
1628 | { | 1628 | { |
1629 | struct snd_soc_codec *codec = w->codec; | 1629 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
1630 | struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec); | 1630 | struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec); |
1631 | struct wm_adsp *dsp = &dsps[w->shift]; | 1631 | struct wm_adsp *dsp = &dsps[w->shift]; |
1632 | struct wm_adsp_alg_region *alg_region; | 1632 | struct wm_adsp_alg_region *alg_region; |
diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c index 374537d5e179..8366e19657a7 100644 --- a/sound/soc/codecs/wm_hubs.c +++ b/sound/soc/codecs/wm_hubs.c | |||
@@ -500,7 +500,7 @@ SOC_SINGLE_TLV("LINEOUT2 Volume", WM8993_LINE_OUTPUTS_VOLUME, 0, 1, 1, | |||
500 | static int hp_supply_event(struct snd_soc_dapm_widget *w, | 500 | static int hp_supply_event(struct snd_soc_dapm_widget *w, |
501 | struct snd_kcontrol *kcontrol, int event) | 501 | struct snd_kcontrol *kcontrol, int event) |
502 | { | 502 | { |
503 | struct snd_soc_codec *codec = w->codec; | 503 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
504 | struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec); | 504 | struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec); |
505 | 505 | ||
506 | switch (event) { | 506 | switch (event) { |
@@ -542,7 +542,7 @@ static int hp_supply_event(struct snd_soc_dapm_widget *w, | |||
542 | static int hp_event(struct snd_soc_dapm_widget *w, | 542 | static int hp_event(struct snd_soc_dapm_widget *w, |
543 | struct snd_kcontrol *kcontrol, int event) | 543 | struct snd_kcontrol *kcontrol, int event) |
544 | { | 544 | { |
545 | struct snd_soc_codec *codec = w->codec; | 545 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
546 | unsigned int reg = snd_soc_read(codec, WM8993_ANALOGUE_HP_0); | 546 | unsigned int reg = snd_soc_read(codec, WM8993_ANALOGUE_HP_0); |
547 | 547 | ||
548 | switch (event) { | 548 | switch (event) { |
@@ -594,7 +594,7 @@ static int hp_event(struct snd_soc_dapm_widget *w, | |||
594 | static int earpiece_event(struct snd_soc_dapm_widget *w, | 594 | static int earpiece_event(struct snd_soc_dapm_widget *w, |
595 | struct snd_kcontrol *control, int event) | 595 | struct snd_kcontrol *control, int event) |
596 | { | 596 | { |
597 | struct snd_soc_codec *codec = w->codec; | 597 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
598 | u16 reg = snd_soc_read(codec, WM8993_ANTIPOP1) & ~WM8993_HPOUT2_IN_ENA; | 598 | u16 reg = snd_soc_read(codec, WM8993_ANTIPOP1) & ~WM8993_HPOUT2_IN_ENA; |
599 | 599 | ||
600 | switch (event) { | 600 | switch (event) { |
@@ -619,7 +619,7 @@ static int earpiece_event(struct snd_soc_dapm_widget *w, | |||
619 | static int lineout_event(struct snd_soc_dapm_widget *w, | 619 | static int lineout_event(struct snd_soc_dapm_widget *w, |
620 | struct snd_kcontrol *control, int event) | 620 | struct snd_kcontrol *control, int event) |
621 | { | 621 | { |
622 | struct snd_soc_codec *codec = w->codec; | 622 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
623 | struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec); | 623 | struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec); |
624 | bool *flag; | 624 | bool *flag; |
625 | 625 | ||
@@ -649,7 +649,7 @@ static int lineout_event(struct snd_soc_dapm_widget *w, | |||
649 | static int micbias_event(struct snd_soc_dapm_widget *w, | 649 | static int micbias_event(struct snd_soc_dapm_widget *w, |
650 | struct snd_kcontrol *kcontrol, int event) | 650 | struct snd_kcontrol *kcontrol, int event) |
651 | { | 651 | { |
652 | struct snd_soc_codec *codec = w->codec; | 652 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
653 | struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec); | 653 | struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec); |
654 | 654 | ||
655 | switch (w->shift) { | 655 | switch (w->shift) { |
diff --git a/sound/soc/davinci/Kconfig b/sound/soc/davinci/Kconfig index 8e948c63f3d9..2b81ca418d2a 100644 --- a/sound/soc/davinci/Kconfig +++ b/sound/soc/davinci/Kconfig | |||
@@ -58,13 +58,12 @@ choice | |||
58 | depends on MACH_DAVINCI_DM365_EVM | 58 | depends on MACH_DAVINCI_DM365_EVM |
59 | 59 | ||
60 | config SND_DM365_AIC3X_CODEC | 60 | config SND_DM365_AIC3X_CODEC |
61 | bool "Audio Codec - AIC3101" | 61 | tristate "Audio Codec - AIC3101" |
62 | help | 62 | help |
63 | Say Y if you want to add support for AIC3101 audio codec | 63 | Say Y if you want to add support for AIC3101 audio codec |
64 | 64 | ||
65 | config SND_DM365_VOICE_CODEC | 65 | config SND_DM365_VOICE_CODEC |
66 | tristate "Voice Codec - CQ93VC" | 66 | tristate "Voice Codec - CQ93VC" |
67 | depends on SND_DAVINCI_SOC | ||
68 | select MFD_DAVINCI_VOICECODEC | 67 | select MFD_DAVINCI_VOICECODEC |
69 | select SND_DAVINCI_SOC_VCIF | 68 | select SND_DAVINCI_SOC_VCIF |
70 | select SND_SOC_CQ0093VC | 69 | select SND_SOC_CQ0093VC |
diff --git a/sound/soc/davinci/davinci-evm.c b/sound/soc/davinci/davinci-evm.c index 158cb3d1db70..b6bb5947a8a8 100644 --- a/sound/soc/davinci/davinci-evm.c +++ b/sound/soc/davinci/davinci-evm.c | |||
@@ -14,7 +14,6 @@ | |||
14 | #include <linux/timer.h> | 14 | #include <linux/timer.h> |
15 | #include <linux/interrupt.h> | 15 | #include <linux/interrupt.h> |
16 | #include <linux/platform_device.h> | 16 | #include <linux/platform_device.h> |
17 | #include <linux/platform_data/edma.h> | ||
18 | #include <linux/i2c.h> | 17 | #include <linux/i2c.h> |
19 | #include <linux/of_platform.h> | 18 | #include <linux/of_platform.h> |
20 | #include <linux/clk.h> | 19 | #include <linux/clk.h> |
@@ -25,11 +24,6 @@ | |||
25 | #include <asm/dma.h> | 24 | #include <asm/dma.h> |
26 | #include <asm/mach-types.h> | 25 | #include <asm/mach-types.h> |
27 | 26 | ||
28 | #include <linux/edma.h> | ||
29 | |||
30 | #include "davinci-pcm.h" | ||
31 | #include "davinci-i2s.h" | ||
32 | |||
33 | struct snd_soc_card_drvdata_davinci { | 27 | struct snd_soc_card_drvdata_davinci { |
34 | struct clk *mclk; | 28 | struct clk *mclk; |
35 | unsigned sysclk; | 29 | unsigned sysclk; |
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index 30b94d4f9c5d..de3b155a5011 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c | |||
@@ -364,6 +364,20 @@ static irqreturn_t davinci_mcasp_rx_irq_handler(int irq, void *data) | |||
364 | return IRQ_RETVAL(handled_mask); | 364 | return IRQ_RETVAL(handled_mask); |
365 | } | 365 | } |
366 | 366 | ||
367 | static irqreturn_t davinci_mcasp_common_irq_handler(int irq, void *data) | ||
368 | { | ||
369 | struct davinci_mcasp *mcasp = (struct davinci_mcasp *)data; | ||
370 | irqreturn_t ret = IRQ_NONE; | ||
371 | |||
372 | if (mcasp->substreams[SNDRV_PCM_STREAM_PLAYBACK]) | ||
373 | ret = davinci_mcasp_tx_irq_handler(irq, data); | ||
374 | |||
375 | if (mcasp->substreams[SNDRV_PCM_STREAM_CAPTURE]) | ||
376 | ret |= davinci_mcasp_rx_irq_handler(irq, data); | ||
377 | |||
378 | return ret; | ||
379 | } | ||
380 | |||
367 | static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai, | 381 | static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai, |
368 | unsigned int fmt) | 382 | unsigned int fmt) |
369 | { | 383 | { |
@@ -1313,16 +1327,19 @@ static struct davinci_mcasp_pdata *davinci_mcasp_set_pdata_from_of( | |||
1313 | 1327 | ||
1314 | pdata->tx_dma_channel = dma_spec.args[0]; | 1328 | pdata->tx_dma_channel = dma_spec.args[0]; |
1315 | 1329 | ||
1316 | ret = of_property_match_string(np, "dma-names", "rx"); | 1330 | /* RX is not valid in DIT mode */ |
1317 | if (ret < 0) | 1331 | if (pdata->op_mode != DAVINCI_MCASP_DIT_MODE) { |
1318 | goto nodata; | 1332 | ret = of_property_match_string(np, "dma-names", "rx"); |
1333 | if (ret < 0) | ||
1334 | goto nodata; | ||
1319 | 1335 | ||
1320 | ret = of_parse_phandle_with_args(np, "dmas", "#dma-cells", ret, | 1336 | ret = of_parse_phandle_with_args(np, "dmas", "#dma-cells", ret, |
1321 | &dma_spec); | 1337 | &dma_spec); |
1322 | if (ret < 0) | 1338 | if (ret < 0) |
1323 | goto nodata; | 1339 | goto nodata; |
1324 | 1340 | ||
1325 | pdata->rx_dma_channel = dma_spec.args[0]; | 1341 | pdata->rx_dma_channel = dma_spec.args[0]; |
1342 | } | ||
1326 | 1343 | ||
1327 | ret = of_property_read_u32(np, "tx-num-evt", &val); | 1344 | ret = of_property_read_u32(np, "tx-num-evt", &val); |
1328 | if (ret >= 0) | 1345 | if (ret >= 0) |
@@ -1441,6 +1458,23 @@ static int davinci_mcasp_probe(struct platform_device *pdev) | |||
1441 | 1458 | ||
1442 | mcasp->dev = &pdev->dev; | 1459 | mcasp->dev = &pdev->dev; |
1443 | 1460 | ||
1461 | irq = platform_get_irq_byname(pdev, "common"); | ||
1462 | if (irq >= 0) { | ||
1463 | irq_name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%s_common\n", | ||
1464 | dev_name(&pdev->dev)); | ||
1465 | ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, | ||
1466 | davinci_mcasp_common_irq_handler, | ||
1467 | IRQF_ONESHOT | IRQF_SHARED, | ||
1468 | irq_name, mcasp); | ||
1469 | if (ret) { | ||
1470 | dev_err(&pdev->dev, "common IRQ request failed\n"); | ||
1471 | goto err; | ||
1472 | } | ||
1473 | |||
1474 | mcasp->irq_request[SNDRV_PCM_STREAM_PLAYBACK] = XUNDRN; | ||
1475 | mcasp->irq_request[SNDRV_PCM_STREAM_CAPTURE] = ROVRN; | ||
1476 | } | ||
1477 | |||
1444 | irq = platform_get_irq_byname(pdev, "rx"); | 1478 | irq = platform_get_irq_byname(pdev, "rx"); |
1445 | if (irq >= 0) { | 1479 | if (irq >= 0) { |
1446 | irq_name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%s_rx\n", | 1480 | irq_name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%s_rx\n", |
@@ -1501,19 +1535,34 @@ static int davinci_mcasp_probe(struct platform_device *pdev) | |||
1501 | else | 1535 | else |
1502 | dma_data->filter_data = &dma_params->channel; | 1536 | dma_data->filter_data = &dma_params->channel; |
1503 | 1537 | ||
1504 | dma_params = &mcasp->dma_params[SNDRV_PCM_STREAM_CAPTURE]; | 1538 | /* RX is not valid in DIT mode */ |
1505 | dma_data = &mcasp->dma_data[SNDRV_PCM_STREAM_CAPTURE]; | 1539 | if (mcasp->op_mode != DAVINCI_MCASP_DIT_MODE) { |
1506 | dma_params->asp_chan_q = pdata->asp_chan_q; | 1540 | dma_params = &mcasp->dma_params[SNDRV_PCM_STREAM_CAPTURE]; |
1507 | dma_params->ram_chan_q = pdata->ram_chan_q; | 1541 | dma_data = &mcasp->dma_data[SNDRV_PCM_STREAM_CAPTURE]; |
1508 | dma_params->sram_pool = pdata->sram_pool; | 1542 | dma_params->asp_chan_q = pdata->asp_chan_q; |
1509 | dma_params->sram_size = pdata->sram_size_capture; | 1543 | dma_params->ram_chan_q = pdata->ram_chan_q; |
1510 | if (dat) | 1544 | dma_params->sram_pool = pdata->sram_pool; |
1511 | dma_params->dma_addr = dat->start; | 1545 | dma_params->sram_size = pdata->sram_size_capture; |
1512 | else | 1546 | if (dat) |
1513 | dma_params->dma_addr = mem->start + pdata->rx_dma_offset; | 1547 | dma_params->dma_addr = dat->start; |
1514 | 1548 | else | |
1515 | /* Unconditional dmaengine stuff */ | 1549 | dma_params->dma_addr = mem->start + pdata->rx_dma_offset; |
1516 | dma_data->addr = dma_params->dma_addr; | 1550 | |
1551 | /* Unconditional dmaengine stuff */ | ||
1552 | dma_data->addr = dma_params->dma_addr; | ||
1553 | |||
1554 | res = platform_get_resource(pdev, IORESOURCE_DMA, 1); | ||
1555 | if (res) | ||
1556 | dma_params->channel = res->start; | ||
1557 | else | ||
1558 | dma_params->channel = pdata->rx_dma_channel; | ||
1559 | |||
1560 | /* dmaengine filter data for DT and non-DT boot */ | ||
1561 | if (pdev->dev.of_node) | ||
1562 | dma_data->filter_data = "rx"; | ||
1563 | else | ||
1564 | dma_data->filter_data = &dma_params->channel; | ||
1565 | } | ||
1517 | 1566 | ||
1518 | if (mcasp->version < MCASP_VERSION_3) { | 1567 | if (mcasp->version < MCASP_VERSION_3) { |
1519 | mcasp->fifo_base = DAVINCI_MCASP_V2_AFIFO_BASE; | 1568 | mcasp->fifo_base = DAVINCI_MCASP_V2_AFIFO_BASE; |
@@ -1523,18 +1572,6 @@ static int davinci_mcasp_probe(struct platform_device *pdev) | |||
1523 | mcasp->fifo_base = DAVINCI_MCASP_V3_AFIFO_BASE; | 1572 | mcasp->fifo_base = DAVINCI_MCASP_V3_AFIFO_BASE; |
1524 | } | 1573 | } |
1525 | 1574 | ||
1526 | res = platform_get_resource(pdev, IORESOURCE_DMA, 1); | ||
1527 | if (res) | ||
1528 | dma_params->channel = res->start; | ||
1529 | else | ||
1530 | dma_params->channel = pdata->rx_dma_channel; | ||
1531 | |||
1532 | /* dmaengine filter data for DT and non-DT boot */ | ||
1533 | if (pdev->dev.of_node) | ||
1534 | dma_data->filter_data = "rx"; | ||
1535 | else | ||
1536 | dma_data->filter_data = &dma_params->channel; | ||
1537 | |||
1538 | dev_set_drvdata(&pdev->dev, mcasp); | 1575 | dev_set_drvdata(&pdev->dev, mcasp); |
1539 | 1576 | ||
1540 | mcasp_reparent_fck(pdev); | 1577 | mcasp_reparent_fck(pdev); |
diff --git a/sound/soc/dwc/Kconfig b/sound/soc/dwc/Kconfig index e334900cf0b8..d50e08517dce 100644 --- a/sound/soc/dwc/Kconfig +++ b/sound/soc/dwc/Kconfig | |||
@@ -1,6 +1,7 @@ | |||
1 | config SND_DESIGNWARE_I2S | 1 | config SND_DESIGNWARE_I2S |
2 | tristate "Synopsys I2S Device Driver" | 2 | tristate "Synopsys I2S Device Driver" |
3 | depends on CLKDEV_LOOKUP | 3 | depends on CLKDEV_LOOKUP |
4 | select SND_SOC_GENERIC_DMAENGINE_PCM | ||
4 | help | 5 | help |
5 | Say Y or M if you want to add support for I2S driver for | 6 | Say Y or M if you want to add support for I2S driver for |
6 | Synopsys desigwnware I2S device. The device supports upto | 7 | Synopsys desigwnware I2S device. The device supports upto |
diff --git a/sound/soc/dwc/designware_i2s.c b/sound/soc/dwc/designware_i2s.c index b93168d4f648..a3e97b46b64e 100644 --- a/sound/soc/dwc/designware_i2s.c +++ b/sound/soc/dwc/designware_i2s.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <sound/pcm.h> | 22 | #include <sound/pcm.h> |
23 | #include <sound/pcm_params.h> | 23 | #include <sound/pcm_params.h> |
24 | #include <sound/soc.h> | 24 | #include <sound/soc.h> |
25 | #include <sound/dmaengine_pcm.h> | ||
25 | 26 | ||
26 | /* common register for all channel */ | 27 | /* common register for all channel */ |
27 | #define IER 0x000 | 28 | #define IER 0x000 |
@@ -54,9 +55,39 @@ | |||
54 | #define I2S_COMP_VERSION 0x01F8 | 55 | #define I2S_COMP_VERSION 0x01F8 |
55 | #define I2S_COMP_TYPE 0x01FC | 56 | #define I2S_COMP_TYPE 0x01FC |
56 | 57 | ||
58 | /* | ||
59 | * Component parameter register fields - define the I2S block's | ||
60 | * configuration. | ||
61 | */ | ||
62 | #define COMP1_TX_WORDSIZE_3(r) (((r) & GENMASK(27, 25)) >> 25) | ||
63 | #define COMP1_TX_WORDSIZE_2(r) (((r) & GENMASK(24, 22)) >> 22) | ||
64 | #define COMP1_TX_WORDSIZE_1(r) (((r) & GENMASK(21, 19)) >> 19) | ||
65 | #define COMP1_TX_WORDSIZE_0(r) (((r) & GENMASK(18, 16)) >> 16) | ||
66 | #define COMP1_TX_CHANNELS(r) (((r) & GENMASK(10, 9)) >> 9) | ||
67 | #define COMP1_RX_CHANNELS(r) (((r) & GENMASK(8, 7)) >> 7) | ||
68 | #define COMP1_RX_ENABLED(r) (((r) & BIT(6)) >> 6) | ||
69 | #define COMP1_TX_ENABLED(r) (((r) & BIT(5)) >> 5) | ||
70 | #define COMP1_MODE_EN(r) (((r) & BIT(4)) >> 4) | ||
71 | #define COMP1_FIFO_DEPTH_GLOBAL(r) (((r) & GENMASK(3, 2)) >> 2) | ||
72 | #define COMP1_APB_DATA_WIDTH(r) (((r) & GENMASK(1, 0)) >> 0) | ||
73 | |||
74 | #define COMP2_RX_WORDSIZE_3(r) (((r) & GENMASK(12, 10)) >> 10) | ||
75 | #define COMP2_RX_WORDSIZE_2(r) (((r) & GENMASK(9, 7)) >> 7) | ||
76 | #define COMP2_RX_WORDSIZE_1(r) (((r) & GENMASK(5, 3)) >> 3) | ||
77 | #define COMP2_RX_WORDSIZE_0(r) (((r) & GENMASK(2, 0)) >> 0) | ||
78 | |||
79 | /* Number of entries in WORDSIZE and DATA_WIDTH parameter registers */ | ||
80 | #define COMP_MAX_WORDSIZE (1 << 3) | ||
81 | #define COMP_MAX_DATA_WIDTH (1 << 2) | ||
82 | |||
57 | #define MAX_CHANNEL_NUM 8 | 83 | #define MAX_CHANNEL_NUM 8 |
58 | #define MIN_CHANNEL_NUM 2 | 84 | #define MIN_CHANNEL_NUM 2 |
59 | 85 | ||
86 | union dw_i2s_snd_dma_data { | ||
87 | struct i2s_dma_data pd; | ||
88 | struct snd_dmaengine_dai_dma_data dt; | ||
89 | }; | ||
90 | |||
60 | struct dw_i2s_dev { | 91 | struct dw_i2s_dev { |
61 | void __iomem *i2s_base; | 92 | void __iomem *i2s_base; |
62 | struct clk *clk; | 93 | struct clk *clk; |
@@ -65,8 +96,8 @@ struct dw_i2s_dev { | |||
65 | struct device *dev; | 96 | struct device *dev; |
66 | 97 | ||
67 | /* data related to DMA transfers b/w i2s and DMAC */ | 98 | /* data related to DMA transfers b/w i2s and DMAC */ |
68 | struct i2s_dma_data play_dma_data; | 99 | union dw_i2s_snd_dma_data play_dma_data; |
69 | struct i2s_dma_data capture_dma_data; | 100 | union dw_i2s_snd_dma_data capture_dma_data; |
70 | struct i2s_clk_config_data config; | 101 | struct i2s_clk_config_data config; |
71 | int (*i2s_clk_cfg)(struct i2s_clk_config_data *config); | 102 | int (*i2s_clk_cfg)(struct i2s_clk_config_data *config); |
72 | }; | 103 | }; |
@@ -153,7 +184,7 @@ static int dw_i2s_startup(struct snd_pcm_substream *substream, | |||
153 | struct snd_soc_dai *cpu_dai) | 184 | struct snd_soc_dai *cpu_dai) |
154 | { | 185 | { |
155 | struct dw_i2s_dev *dev = snd_soc_dai_get_drvdata(cpu_dai); | 186 | struct dw_i2s_dev *dev = snd_soc_dai_get_drvdata(cpu_dai); |
156 | struct i2s_dma_data *dma_data = NULL; | 187 | union dw_i2s_snd_dma_data *dma_data = NULL; |
157 | 188 | ||
158 | if (!(dev->capability & DWC_I2S_RECORD) && | 189 | if (!(dev->capability & DWC_I2S_RECORD) && |
159 | (substream->stream == SNDRV_PCM_STREAM_CAPTURE)) | 190 | (substream->stream == SNDRV_PCM_STREAM_CAPTURE)) |
@@ -209,16 +240,9 @@ static int dw_i2s_hw_params(struct snd_pcm_substream *substream, | |||
209 | 240 | ||
210 | switch (config->chan_nr) { | 241 | switch (config->chan_nr) { |
211 | case EIGHT_CHANNEL_SUPPORT: | 242 | case EIGHT_CHANNEL_SUPPORT: |
212 | ch_reg = 3; | ||
213 | break; | ||
214 | case SIX_CHANNEL_SUPPORT: | 243 | case SIX_CHANNEL_SUPPORT: |
215 | ch_reg = 2; | ||
216 | break; | ||
217 | case FOUR_CHANNEL_SUPPORT: | 244 | case FOUR_CHANNEL_SUPPORT: |
218 | ch_reg = 1; | ||
219 | break; | ||
220 | case TWO_CHANNEL_SUPPORT: | 245 | case TWO_CHANNEL_SUPPORT: |
221 | ch_reg = 0; | ||
222 | break; | 246 | break; |
223 | default: | 247 | default: |
224 | dev_err(dev->dev, "channel not supported\n"); | 248 | dev_err(dev->dev, "channel not supported\n"); |
@@ -227,31 +251,43 @@ static int dw_i2s_hw_params(struct snd_pcm_substream *substream, | |||
227 | 251 | ||
228 | i2s_disable_channels(dev, substream->stream); | 252 | i2s_disable_channels(dev, substream->stream); |
229 | 253 | ||
230 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { | 254 | for (ch_reg = 0; ch_reg < (config->chan_nr / 2); ch_reg++) { |
231 | i2s_write_reg(dev->i2s_base, TCR(ch_reg), xfer_resolution); | 255 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { |
232 | i2s_write_reg(dev->i2s_base, TFCR(ch_reg), 0x02); | 256 | i2s_write_reg(dev->i2s_base, TCR(ch_reg), |
233 | irq = i2s_read_reg(dev->i2s_base, IMR(ch_reg)); | 257 | xfer_resolution); |
234 | i2s_write_reg(dev->i2s_base, IMR(ch_reg), irq & ~0x30); | 258 | i2s_write_reg(dev->i2s_base, TFCR(ch_reg), 0x02); |
235 | i2s_write_reg(dev->i2s_base, TER(ch_reg), 1); | 259 | irq = i2s_read_reg(dev->i2s_base, IMR(ch_reg)); |
236 | } else { | 260 | i2s_write_reg(dev->i2s_base, IMR(ch_reg), irq & ~0x30); |
237 | i2s_write_reg(dev->i2s_base, RCR(ch_reg), xfer_resolution); | 261 | i2s_write_reg(dev->i2s_base, TER(ch_reg), 1); |
238 | i2s_write_reg(dev->i2s_base, RFCR(ch_reg), 0x07); | 262 | } else { |
239 | irq = i2s_read_reg(dev->i2s_base, IMR(ch_reg)); | 263 | i2s_write_reg(dev->i2s_base, RCR(ch_reg), |
240 | i2s_write_reg(dev->i2s_base, IMR(ch_reg), irq & ~0x03); | 264 | xfer_resolution); |
241 | i2s_write_reg(dev->i2s_base, RER(ch_reg), 1); | 265 | i2s_write_reg(dev->i2s_base, RFCR(ch_reg), 0x07); |
266 | irq = i2s_read_reg(dev->i2s_base, IMR(ch_reg)); | ||
267 | i2s_write_reg(dev->i2s_base, IMR(ch_reg), irq & ~0x03); | ||
268 | i2s_write_reg(dev->i2s_base, RER(ch_reg), 1); | ||
269 | } | ||
242 | } | 270 | } |
243 | 271 | ||
244 | i2s_write_reg(dev->i2s_base, CCR, ccr); | 272 | i2s_write_reg(dev->i2s_base, CCR, ccr); |
245 | 273 | ||
246 | config->sample_rate = params_rate(params); | 274 | config->sample_rate = params_rate(params); |
247 | 275 | ||
248 | if (!dev->i2s_clk_cfg) | 276 | if (dev->i2s_clk_cfg) { |
249 | return -EINVAL; | 277 | ret = dev->i2s_clk_cfg(config); |
278 | if (ret < 0) { | ||
279 | dev_err(dev->dev, "runtime audio clk config fail\n"); | ||
280 | return ret; | ||
281 | } | ||
282 | } else { | ||
283 | u32 bitclk = config->sample_rate * config->data_width * 2; | ||
250 | 284 | ||
251 | ret = dev->i2s_clk_cfg(config); | 285 | ret = clk_set_rate(dev->clk, bitclk); |
252 | if (ret < 0) { | 286 | if (ret) { |
253 | dev_err(dev->dev, "runtime audio clk config fail\n"); | 287 | dev_err(dev->dev, "Can't set I2S clock rate: %d\n", |
254 | return ret; | 288 | ret); |
289 | return ret; | ||
290 | } | ||
255 | } | 291 | } |
256 | 292 | ||
257 | return 0; | 293 | return 0; |
@@ -263,6 +299,19 @@ static void dw_i2s_shutdown(struct snd_pcm_substream *substream, | |||
263 | snd_soc_dai_set_dma_data(dai, substream, NULL); | 299 | snd_soc_dai_set_dma_data(dai, substream, NULL); |
264 | } | 300 | } |
265 | 301 | ||
302 | static int dw_i2s_prepare(struct snd_pcm_substream *substream, | ||
303 | struct snd_soc_dai *dai) | ||
304 | { | ||
305 | struct dw_i2s_dev *dev = snd_soc_dai_get_drvdata(dai); | ||
306 | |||
307 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | ||
308 | i2s_write_reg(dev->i2s_base, TXFFR, 1); | ||
309 | else | ||
310 | i2s_write_reg(dev->i2s_base, RXFFR, 1); | ||
311 | |||
312 | return 0; | ||
313 | } | ||
314 | |||
266 | static int dw_i2s_trigger(struct snd_pcm_substream *substream, | 315 | static int dw_i2s_trigger(struct snd_pcm_substream *substream, |
267 | int cmd, struct snd_soc_dai *dai) | 316 | int cmd, struct snd_soc_dai *dai) |
268 | { | 317 | { |
@@ -294,6 +343,7 @@ static struct snd_soc_dai_ops dw_i2s_dai_ops = { | |||
294 | .startup = dw_i2s_startup, | 343 | .startup = dw_i2s_startup, |
295 | .shutdown = dw_i2s_shutdown, | 344 | .shutdown = dw_i2s_shutdown, |
296 | .hw_params = dw_i2s_hw_params, | 345 | .hw_params = dw_i2s_hw_params, |
346 | .prepare = dw_i2s_prepare, | ||
297 | .trigger = dw_i2s_trigger, | 347 | .trigger = dw_i2s_trigger, |
298 | }; | 348 | }; |
299 | 349 | ||
@@ -324,20 +374,162 @@ static int dw_i2s_resume(struct snd_soc_dai *dai) | |||
324 | #define dw_i2s_resume NULL | 374 | #define dw_i2s_resume NULL |
325 | #endif | 375 | #endif |
326 | 376 | ||
377 | /* | ||
378 | * The following tables allow a direct lookup of various parameters | ||
379 | * defined in the I2S block's configuration in terms of sound system | ||
380 | * parameters. Each table is sized to the number of entries possible | ||
381 | * according to the number of configuration bits describing an I2S | ||
382 | * block parameter. | ||
383 | */ | ||
384 | |||
385 | /* Maximum bit resolution of a channel - not uniformly spaced */ | ||
386 | static const u32 fifo_width[COMP_MAX_WORDSIZE] = { | ||
387 | 12, 16, 20, 24, 32, 0, 0, 0 | ||
388 | }; | ||
389 | |||
390 | /* Width of (DMA) bus */ | ||
391 | static const u32 bus_widths[COMP_MAX_DATA_WIDTH] = { | ||
392 | DMA_SLAVE_BUSWIDTH_1_BYTE, | ||
393 | DMA_SLAVE_BUSWIDTH_2_BYTES, | ||
394 | DMA_SLAVE_BUSWIDTH_4_BYTES, | ||
395 | DMA_SLAVE_BUSWIDTH_UNDEFINED | ||
396 | }; | ||
397 | |||
398 | /* PCM format to support channel resolution */ | ||
399 | static const u32 formats[COMP_MAX_WORDSIZE] = { | ||
400 | SNDRV_PCM_FMTBIT_S16_LE, | ||
401 | SNDRV_PCM_FMTBIT_S16_LE, | ||
402 | SNDRV_PCM_FMTBIT_S24_LE, | ||
403 | SNDRV_PCM_FMTBIT_S24_LE, | ||
404 | SNDRV_PCM_FMTBIT_S32_LE, | ||
405 | 0, | ||
406 | 0, | ||
407 | 0 | ||
408 | }; | ||
409 | |||
410 | static int dw_configure_dai(struct dw_i2s_dev *dev, | ||
411 | struct snd_soc_dai_driver *dw_i2s_dai, | ||
412 | unsigned int rates) | ||
413 | { | ||
414 | /* | ||
415 | * Read component parameter registers to extract | ||
416 | * the I2S block's configuration. | ||
417 | */ | ||
418 | u32 comp1 = i2s_read_reg(dev->i2s_base, I2S_COMP_PARAM_1); | ||
419 | u32 comp2 = i2s_read_reg(dev->i2s_base, I2S_COMP_PARAM_2); | ||
420 | u32 idx; | ||
421 | |||
422 | if (COMP1_TX_ENABLED(comp1)) { | ||
423 | dev_dbg(dev->dev, " designware: play supported\n"); | ||
424 | idx = COMP1_TX_WORDSIZE_0(comp1); | ||
425 | if (WARN_ON(idx >= ARRAY_SIZE(formats))) | ||
426 | return -EINVAL; | ||
427 | dw_i2s_dai->playback.channels_min = MIN_CHANNEL_NUM; | ||
428 | dw_i2s_dai->playback.channels_max = | ||
429 | 1 << (COMP1_TX_CHANNELS(comp1) + 1); | ||
430 | dw_i2s_dai->playback.formats = formats[idx]; | ||
431 | dw_i2s_dai->playback.rates = rates; | ||
432 | } | ||
433 | |||
434 | if (COMP1_RX_ENABLED(comp1)) { | ||
435 | dev_dbg(dev->dev, "designware: record supported\n"); | ||
436 | idx = COMP2_RX_WORDSIZE_0(comp2); | ||
437 | if (WARN_ON(idx >= ARRAY_SIZE(formats))) | ||
438 | return -EINVAL; | ||
439 | dw_i2s_dai->capture.channels_min = MIN_CHANNEL_NUM; | ||
440 | dw_i2s_dai->capture.channels_max = | ||
441 | 1 << (COMP1_RX_CHANNELS(comp1) + 1); | ||
442 | dw_i2s_dai->capture.formats = formats[idx]; | ||
443 | dw_i2s_dai->capture.rates = rates; | ||
444 | } | ||
445 | |||
446 | return 0; | ||
447 | } | ||
448 | |||
449 | static int dw_configure_dai_by_pd(struct dw_i2s_dev *dev, | ||
450 | struct snd_soc_dai_driver *dw_i2s_dai, | ||
451 | struct resource *res, | ||
452 | const struct i2s_platform_data *pdata) | ||
453 | { | ||
454 | u32 comp1 = i2s_read_reg(dev->i2s_base, I2S_COMP_PARAM_1); | ||
455 | u32 idx = COMP1_APB_DATA_WIDTH(comp1); | ||
456 | int ret; | ||
457 | |||
458 | if (WARN_ON(idx >= ARRAY_SIZE(bus_widths))) | ||
459 | return -EINVAL; | ||
460 | |||
461 | ret = dw_configure_dai(dev, dw_i2s_dai, pdata->snd_rates); | ||
462 | if (ret < 0) | ||
463 | return ret; | ||
464 | |||
465 | /* Set DMA slaves info */ | ||
466 | dev->play_dma_data.pd.data = pdata->play_dma_data; | ||
467 | dev->capture_dma_data.pd.data = pdata->capture_dma_data; | ||
468 | dev->play_dma_data.pd.addr = res->start + I2S_TXDMA; | ||
469 | dev->capture_dma_data.pd.addr = res->start + I2S_RXDMA; | ||
470 | dev->play_dma_data.pd.max_burst = 16; | ||
471 | dev->capture_dma_data.pd.max_burst = 16; | ||
472 | dev->play_dma_data.pd.addr_width = bus_widths[idx]; | ||
473 | dev->capture_dma_data.pd.addr_width = bus_widths[idx]; | ||
474 | dev->play_dma_data.pd.filter = pdata->filter; | ||
475 | dev->capture_dma_data.pd.filter = pdata->filter; | ||
476 | |||
477 | return 0; | ||
478 | } | ||
479 | |||
480 | static int dw_configure_dai_by_dt(struct dw_i2s_dev *dev, | ||
481 | struct snd_soc_dai_driver *dw_i2s_dai, | ||
482 | struct resource *res) | ||
483 | { | ||
484 | u32 comp1 = i2s_read_reg(dev->i2s_base, I2S_COMP_PARAM_1); | ||
485 | u32 comp2 = i2s_read_reg(dev->i2s_base, I2S_COMP_PARAM_2); | ||
486 | u32 fifo_depth = 1 << (1 + COMP1_FIFO_DEPTH_GLOBAL(comp1)); | ||
487 | u32 idx = COMP1_APB_DATA_WIDTH(comp1); | ||
488 | u32 idx2; | ||
489 | int ret; | ||
490 | |||
491 | if (WARN_ON(idx >= ARRAY_SIZE(bus_widths))) | ||
492 | return -EINVAL; | ||
493 | |||
494 | ret = dw_configure_dai(dev, dw_i2s_dai, SNDRV_PCM_RATE_8000_192000); | ||
495 | if (ret < 0) | ||
496 | return ret; | ||
497 | |||
498 | if (COMP1_TX_ENABLED(comp1)) { | ||
499 | idx2 = COMP1_TX_WORDSIZE_0(comp1); | ||
500 | |||
501 | dev->capability |= DWC_I2S_PLAY; | ||
502 | dev->play_dma_data.dt.addr = res->start + I2S_TXDMA; | ||
503 | dev->play_dma_data.dt.addr_width = bus_widths[idx]; | ||
504 | dev->play_dma_data.dt.chan_name = "TX"; | ||
505 | dev->play_dma_data.dt.fifo_size = fifo_depth * | ||
506 | (fifo_width[idx2]) >> 8; | ||
507 | dev->play_dma_data.dt.maxburst = 16; | ||
508 | } | ||
509 | if (COMP1_RX_ENABLED(comp1)) { | ||
510 | idx2 = COMP2_RX_WORDSIZE_0(comp2); | ||
511 | |||
512 | dev->capability |= DWC_I2S_RECORD; | ||
513 | dev->capture_dma_data.dt.addr = res->start + I2S_RXDMA; | ||
514 | dev->capture_dma_data.dt.addr_width = bus_widths[idx]; | ||
515 | dev->capture_dma_data.dt.chan_name = "RX"; | ||
516 | dev->capture_dma_data.dt.fifo_size = fifo_depth * | ||
517 | (fifo_width[idx2] >> 8); | ||
518 | dev->capture_dma_data.dt.maxburst = 16; | ||
519 | } | ||
520 | |||
521 | return 0; | ||
522 | |||
523 | } | ||
524 | |||
327 | static int dw_i2s_probe(struct platform_device *pdev) | 525 | static int dw_i2s_probe(struct platform_device *pdev) |
328 | { | 526 | { |
329 | const struct i2s_platform_data *pdata = pdev->dev.platform_data; | 527 | const struct i2s_platform_data *pdata = pdev->dev.platform_data; |
330 | struct dw_i2s_dev *dev; | 528 | struct dw_i2s_dev *dev; |
331 | struct resource *res; | 529 | struct resource *res; |
332 | int ret; | 530 | int ret; |
333 | unsigned int cap; | ||
334 | struct snd_soc_dai_driver *dw_i2s_dai; | 531 | struct snd_soc_dai_driver *dw_i2s_dai; |
335 | 532 | ||
336 | if (!pdata) { | ||
337 | dev_err(&pdev->dev, "Invalid platform data\n"); | ||
338 | return -EINVAL; | ||
339 | } | ||
340 | |||
341 | dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL); | 533 | dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL); |
342 | if (!dev) { | 534 | if (!dev) { |
343 | dev_warn(&pdev->dev, "kzalloc fail\n"); | 535 | dev_warn(&pdev->dev, "kzalloc fail\n"); |
@@ -345,83 +537,67 @@ static int dw_i2s_probe(struct platform_device *pdev) | |||
345 | } | 537 | } |
346 | 538 | ||
347 | dw_i2s_dai = devm_kzalloc(&pdev->dev, sizeof(*dw_i2s_dai), GFP_KERNEL); | 539 | dw_i2s_dai = devm_kzalloc(&pdev->dev, sizeof(*dw_i2s_dai), GFP_KERNEL); |
348 | if (!dw_i2s_dai) { | 540 | if (!dw_i2s_dai) |
349 | dev_err(&pdev->dev, "mem allocation failed for dai driver\n"); | ||
350 | return -ENOMEM; | 541 | return -ENOMEM; |
351 | } | ||
352 | 542 | ||
353 | dw_i2s_dai->ops = &dw_i2s_dai_ops; | 543 | dw_i2s_dai->ops = &dw_i2s_dai_ops; |
354 | dw_i2s_dai->suspend = dw_i2s_suspend; | 544 | dw_i2s_dai->suspend = dw_i2s_suspend; |
355 | dw_i2s_dai->resume = dw_i2s_resume; | 545 | dw_i2s_dai->resume = dw_i2s_resume; |
356 | 546 | ||
357 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 547 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
358 | if (!res) { | ||
359 | dev_err(&pdev->dev, "no i2s resource defined\n"); | ||
360 | return -ENODEV; | ||
361 | } | ||
362 | |||
363 | dev->i2s_base = devm_ioremap_resource(&pdev->dev, res); | 548 | dev->i2s_base = devm_ioremap_resource(&pdev->dev, res); |
364 | if (IS_ERR(dev->i2s_base)) { | 549 | if (IS_ERR(dev->i2s_base)) |
365 | dev_err(&pdev->dev, "ioremap fail for i2s_region\n"); | ||
366 | return PTR_ERR(dev->i2s_base); | 550 | return PTR_ERR(dev->i2s_base); |
367 | } | ||
368 | 551 | ||
369 | cap = pdata->cap; | 552 | dev->dev = &pdev->dev; |
370 | dev->capability = cap; | 553 | if (pdata) { |
371 | dev->i2s_clk_cfg = pdata->i2s_clk_cfg; | 554 | ret = dw_configure_dai_by_pd(dev, dw_i2s_dai, res, pdata); |
555 | if (ret < 0) | ||
556 | return ret; | ||
557 | |||
558 | dev->capability = pdata->cap; | ||
559 | dev->i2s_clk_cfg = pdata->i2s_clk_cfg; | ||
560 | if (!dev->i2s_clk_cfg) { | ||
561 | dev_err(&pdev->dev, "no clock configure method\n"); | ||
562 | return -ENODEV; | ||
563 | } | ||
372 | 564 | ||
373 | /* Set DMA slaves info */ | 565 | dev->clk = devm_clk_get(&pdev->dev, NULL); |
566 | } else { | ||
567 | ret = dw_configure_dai_by_dt(dev, dw_i2s_dai, res); | ||
568 | if (ret < 0) | ||
569 | return ret; | ||
374 | 570 | ||
375 | dev->play_dma_data.data = pdata->play_dma_data; | 571 | dev->clk = devm_clk_get(&pdev->dev, "i2sclk"); |
376 | dev->capture_dma_data.data = pdata->capture_dma_data; | 572 | } |
377 | dev->play_dma_data.addr = res->start + I2S_TXDMA; | ||
378 | dev->capture_dma_data.addr = res->start + I2S_RXDMA; | ||
379 | dev->play_dma_data.max_burst = 16; | ||
380 | dev->capture_dma_data.max_burst = 16; | ||
381 | dev->play_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES; | ||
382 | dev->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES; | ||
383 | dev->play_dma_data.filter = pdata->filter; | ||
384 | dev->capture_dma_data.filter = pdata->filter; | ||
385 | |||
386 | dev->clk = clk_get(&pdev->dev, NULL); | ||
387 | if (IS_ERR(dev->clk)) | 573 | if (IS_ERR(dev->clk)) |
388 | return PTR_ERR(dev->clk); | 574 | return PTR_ERR(dev->clk); |
389 | 575 | ||
390 | ret = clk_enable(dev->clk); | 576 | ret = clk_prepare_enable(dev->clk); |
391 | if (ret < 0) | 577 | if (ret < 0) |
392 | goto err_clk_put; | 578 | return ret; |
393 | |||
394 | if (cap & DWC_I2S_PLAY) { | ||
395 | dev_dbg(&pdev->dev, " designware: play supported\n"); | ||
396 | dw_i2s_dai->playback.channels_min = MIN_CHANNEL_NUM; | ||
397 | dw_i2s_dai->playback.channels_max = pdata->channel; | ||
398 | dw_i2s_dai->playback.formats = pdata->snd_fmts; | ||
399 | dw_i2s_dai->playback.rates = pdata->snd_rates; | ||
400 | } | ||
401 | |||
402 | if (cap & DWC_I2S_RECORD) { | ||
403 | dev_dbg(&pdev->dev, "designware: record supported\n"); | ||
404 | dw_i2s_dai->capture.channels_min = MIN_CHANNEL_NUM; | ||
405 | dw_i2s_dai->capture.channels_max = pdata->channel; | ||
406 | dw_i2s_dai->capture.formats = pdata->snd_fmts; | ||
407 | dw_i2s_dai->capture.rates = pdata->snd_rates; | ||
408 | } | ||
409 | 579 | ||
410 | dev->dev = &pdev->dev; | ||
411 | dev_set_drvdata(&pdev->dev, dev); | 580 | dev_set_drvdata(&pdev->dev, dev); |
412 | ret = snd_soc_register_component(&pdev->dev, &dw_i2s_component, | 581 | ret = devm_snd_soc_register_component(&pdev->dev, &dw_i2s_component, |
413 | dw_i2s_dai, 1); | 582 | dw_i2s_dai, 1); |
414 | if (ret != 0) { | 583 | if (ret != 0) { |
415 | dev_err(&pdev->dev, "not able to register dai\n"); | 584 | dev_err(&pdev->dev, "not able to register dai\n"); |
416 | goto err_clk_disable; | 585 | goto err_clk_disable; |
417 | } | 586 | } |
418 | 587 | ||
588 | if (!pdata) { | ||
589 | ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0); | ||
590 | if (ret) { | ||
591 | dev_err(&pdev->dev, | ||
592 | "Could not register PCM: %d\n", ret); | ||
593 | goto err_clk_disable; | ||
594 | } | ||
595 | } | ||
596 | |||
419 | return 0; | 597 | return 0; |
420 | 598 | ||
421 | err_clk_disable: | 599 | err_clk_disable: |
422 | clk_disable(dev->clk); | 600 | clk_disable_unprepare(dev->clk); |
423 | err_clk_put: | ||
424 | clk_put(dev->clk); | ||
425 | return ret; | 601 | return ret; |
426 | } | 602 | } |
427 | 603 | ||
@@ -429,18 +605,26 @@ static int dw_i2s_remove(struct platform_device *pdev) | |||
429 | { | 605 | { |
430 | struct dw_i2s_dev *dev = dev_get_drvdata(&pdev->dev); | 606 | struct dw_i2s_dev *dev = dev_get_drvdata(&pdev->dev); |
431 | 607 | ||
432 | snd_soc_unregister_component(&pdev->dev); | 608 | clk_disable_unprepare(dev->clk); |
433 | |||
434 | clk_put(dev->clk); | ||
435 | 609 | ||
436 | return 0; | 610 | return 0; |
437 | } | 611 | } |
438 | 612 | ||
613 | #ifdef CONFIG_OF | ||
614 | static const struct of_device_id dw_i2s_of_match[] = { | ||
615 | { .compatible = "snps,designware-i2s", }, | ||
616 | {}, | ||
617 | }; | ||
618 | |||
619 | MODULE_DEVICE_TABLE(of, dw_i2s_of_match); | ||
620 | #endif | ||
621 | |||
439 | static struct platform_driver dw_i2s_driver = { | 622 | static struct platform_driver dw_i2s_driver = { |
440 | .probe = dw_i2s_probe, | 623 | .probe = dw_i2s_probe, |
441 | .remove = dw_i2s_remove, | 624 | .remove = dw_i2s_remove, |
442 | .driver = { | 625 | .driver = { |
443 | .name = "designware-i2s", | 626 | .name = "designware-i2s", |
627 | .of_match_table = of_match_ptr(dw_i2s_of_match), | ||
444 | }, | 628 | }, |
445 | }; | 629 | }; |
446 | 630 | ||
diff --git a/sound/soc/fsl/eukrea-tlv320.c b/sound/soc/fsl/eukrea-tlv320.c index 9ce70fc67b09..e1aa3834b101 100644 --- a/sound/soc/fsl/eukrea-tlv320.c +++ b/sound/soc/fsl/eukrea-tlv320.c | |||
@@ -42,25 +42,6 @@ static int eukrea_tlv320_hw_params(struct snd_pcm_substream *substream, | |||
42 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | 42 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; |
43 | int ret; | 43 | int ret; |
44 | 44 | ||
45 | ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | | ||
46 | SND_SOC_DAIFMT_NB_NF | | ||
47 | SND_SOC_DAIFMT_CBM_CFM); | ||
48 | /* fsl_ssi lacks the set_fmt ops. */ | ||
49 | if (ret && ret != -ENOTSUPP) { | ||
50 | dev_err(cpu_dai->dev, | ||
51 | "Failed to set the cpu dai format.\n"); | ||
52 | return ret; | ||
53 | } | ||
54 | |||
55 | ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | | ||
56 | SND_SOC_DAIFMT_NB_NF | | ||
57 | SND_SOC_DAIFMT_CBM_CFM); | ||
58 | if (ret) { | ||
59 | dev_err(cpu_dai->dev, | ||
60 | "Failed to set the codec format.\n"); | ||
61 | return ret; | ||
62 | } | ||
63 | |||
64 | ret = snd_soc_dai_set_sysclk(codec_dai, 0, | 45 | ret = snd_soc_dai_set_sysclk(codec_dai, 0, |
65 | CODEC_CLOCK, SND_SOC_CLOCK_OUT); | 46 | CODEC_CLOCK, SND_SOC_CLOCK_OUT); |
66 | if (ret) { | 47 | if (ret) { |
@@ -69,7 +50,7 @@ static int eukrea_tlv320_hw_params(struct snd_pcm_substream *substream, | |||
69 | return ret; | 50 | return ret; |
70 | } | 51 | } |
71 | 52 | ||
72 | snd_soc_dai_set_tdm_slot(cpu_dai, 0xffffffc, 0xffffffc, 2, 0); | 53 | snd_soc_dai_set_tdm_slot(cpu_dai, 0x3, 0x3, 2, 0); |
73 | 54 | ||
74 | ret = snd_soc_dai_set_sysclk(cpu_dai, IMX_SSP_SYS_CLK, 0, | 55 | ret = snd_soc_dai_set_sysclk(cpu_dai, IMX_SSP_SYS_CLK, 0, |
75 | SND_SOC_CLOCK_IN); | 56 | SND_SOC_CLOCK_IN); |
@@ -91,6 +72,8 @@ static struct snd_soc_dai_link eukrea_tlv320_dai = { | |||
91 | .name = "tlv320aic23", | 72 | .name = "tlv320aic23", |
92 | .stream_name = "TLV320AIC23", | 73 | .stream_name = "TLV320AIC23", |
93 | .codec_dai_name = "tlv320aic23-hifi", | 74 | .codec_dai_name = "tlv320aic23-hifi", |
75 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | | ||
76 | SND_SOC_DAIFMT_CBM_CFM, | ||
94 | .ops = &eukrea_tlv320_snd_ops, | 77 | .ops = &eukrea_tlv320_snd_ops, |
95 | }; | 78 | }; |
96 | 79 | ||
diff --git a/sound/soc/fsl/fsl_asrc.c b/sound/soc/fsl/fsl_asrc.c index 026a80117540..c068494bae30 100644 --- a/sound/soc/fsl/fsl_asrc.c +++ b/sound/soc/fsl/fsl_asrc.c | |||
@@ -818,7 +818,6 @@ static int fsl_asrc_probe(struct platform_device *pdev) | |||
818 | return -ENOMEM; | 818 | return -ENOMEM; |
819 | 819 | ||
820 | asrc_priv->pdev = pdev; | 820 | asrc_priv->pdev = pdev; |
821 | strncpy(asrc_priv->name, np->name, sizeof(asrc_priv->name) - 1); | ||
822 | 821 | ||
823 | /* Get the addresses and IRQ */ | 822 | /* Get the addresses and IRQ */ |
824 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 823 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
@@ -837,12 +836,12 @@ static int fsl_asrc_probe(struct platform_device *pdev) | |||
837 | 836 | ||
838 | irq = platform_get_irq(pdev, 0); | 837 | irq = platform_get_irq(pdev, 0); |
839 | if (irq < 0) { | 838 | if (irq < 0) { |
840 | dev_err(&pdev->dev, "no irq for node %s\n", np->full_name); | 839 | dev_err(&pdev->dev, "no irq for node %s\n", pdev->name); |
841 | return irq; | 840 | return irq; |
842 | } | 841 | } |
843 | 842 | ||
844 | ret = devm_request_irq(&pdev->dev, irq, fsl_asrc_isr, 0, | 843 | ret = devm_request_irq(&pdev->dev, irq, fsl_asrc_isr, 0, |
845 | asrc_priv->name, asrc_priv); | 844 | dev_name(&pdev->dev), asrc_priv); |
846 | if (ret) { | 845 | if (ret) { |
847 | dev_err(&pdev->dev, "failed to claim irq %u: %d\n", irq, ret); | 846 | dev_err(&pdev->dev, "failed to claim irq %u: %d\n", irq, ret); |
848 | return ret; | 847 | return ret; |
diff --git a/sound/soc/fsl/fsl_asrc.h b/sound/soc/fsl/fsl_asrc.h index a3f211f53c23..4aed63c4b431 100644 --- a/sound/soc/fsl/fsl_asrc.h +++ b/sound/soc/fsl/fsl_asrc.h | |||
@@ -433,7 +433,6 @@ struct fsl_asrc_pair { | |||
433 | * @channel_avail: non-occupied channel numbers | 433 | * @channel_avail: non-occupied channel numbers |
434 | * @asrc_rate: default sample rate for ASoC Back-Ends | 434 | * @asrc_rate: default sample rate for ASoC Back-Ends |
435 | * @asrc_width: default sample width for ASoC Back-Ends | 435 | * @asrc_width: default sample width for ASoC Back-Ends |
436 | * @name: driver name | ||
437 | */ | 436 | */ |
438 | struct fsl_asrc { | 437 | struct fsl_asrc { |
439 | struct snd_dmaengine_dai_dma_data dma_params_rx; | 438 | struct snd_dmaengine_dai_dma_data dma_params_rx; |
@@ -452,8 +451,6 @@ struct fsl_asrc { | |||
452 | 451 | ||
453 | int asrc_rate; | 452 | int asrc_rate; |
454 | int asrc_width; | 453 | int asrc_width; |
455 | |||
456 | char name[32]; | ||
457 | }; | 454 | }; |
458 | 455 | ||
459 | extern struct snd_soc_platform_driver fsl_asrc_platform; | 456 | extern struct snd_soc_platform_driver fsl_asrc_platform; |
diff --git a/sound/soc/fsl/fsl_esai.c b/sound/soc/fsl/fsl_esai.c index 1c08ab13637c..5c7597191e3f 100644 --- a/sound/soc/fsl/fsl_esai.c +++ b/sound/soc/fsl/fsl_esai.c | |||
@@ -774,7 +774,7 @@ static int fsl_esai_probe(struct platform_device *pdev) | |||
774 | 774 | ||
775 | irq = platform_get_irq(pdev, 0); | 775 | irq = platform_get_irq(pdev, 0); |
776 | if (irq < 0) { | 776 | if (irq < 0) { |
777 | dev_err(&pdev->dev, "no irq for node %s\n", np->full_name); | 777 | dev_err(&pdev->dev, "no irq for node %s\n", pdev->name); |
778 | return irq; | 778 | return irq; |
779 | } | 779 | } |
780 | 780 | ||
diff --git a/sound/soc/fsl/fsl_esai.h b/sound/soc/fsl/fsl_esai.h index 91a550f4a10d..5e793bbb6b02 100644 --- a/sound/soc/fsl/fsl_esai.h +++ b/sound/soc/fsl/fsl_esai.h | |||
@@ -302,7 +302,7 @@ | |||
302 | #define ESAI_xCCR_xFP_MASK (((1 << ESAI_xCCR_xFP_WIDTH) - 1) << ESAI_xCCR_xFP_SHIFT) | 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) | 303 | #define ESAI_xCCR_xFP(v) ((((v) - 1) << ESAI_xCCR_xFP_SHIFT) & ESAI_xCCR_xFP_MASK) |
304 | #define ESAI_xCCR_xDC_SHIFT 9 | 304 | #define ESAI_xCCR_xDC_SHIFT 9 |
305 | #define ESAI_xCCR_xDC_WIDTH 4 | 305 | #define ESAI_xCCR_xDC_WIDTH 5 |
306 | #define ESAI_xCCR_xDC_MASK (((1 << ESAI_xCCR_xDC_WIDTH) - 1) << ESAI_xCCR_xDC_SHIFT) | 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) | 307 | #define ESAI_xCCR_xDC(v) ((((v) - 1) << ESAI_xCCR_xDC_SHIFT) & ESAI_xCCR_xDC_MASK) |
308 | #define ESAI_xCCR_xPSR_SHIFT 8 | 308 | #define ESAI_xCCR_xPSR_SHIFT 8 |
diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c index 032d2d33619c..ec79c3d5e65e 100644 --- a/sound/soc/fsl/fsl_sai.c +++ b/sound/soc/fsl/fsl_sai.c | |||
@@ -612,7 +612,7 @@ static int fsl_sai_probe(struct platform_device *pdev) | |||
612 | 612 | ||
613 | irq = platform_get_irq(pdev, 0); | 613 | irq = platform_get_irq(pdev, 0); |
614 | if (irq < 0) { | 614 | if (irq < 0) { |
615 | dev_err(&pdev->dev, "no irq for node %s\n", np->full_name); | 615 | dev_err(&pdev->dev, "no irq for node %s\n", pdev->name); |
616 | return irq; | 616 | return irq; |
617 | } | 617 | } |
618 | 618 | ||
diff --git a/sound/soc/fsl/fsl_spdif.c b/sound/soc/fsl/fsl_spdif.c index af0429421fc8..75870c0ea2c9 100644 --- a/sound/soc/fsl/fsl_spdif.c +++ b/sound/soc/fsl/fsl_spdif.c | |||
@@ -90,7 +90,6 @@ struct spdif_mixer_control { | |||
90 | * @sysclk: system clock for rx clock rate measurement | 90 | * @sysclk: system clock for rx clock rate measurement |
91 | * @dma_params_tx: DMA parameters for transmit channel | 91 | * @dma_params_tx: DMA parameters for transmit channel |
92 | * @dma_params_rx: DMA parameters for receive channel | 92 | * @dma_params_rx: DMA parameters for receive channel |
93 | * @name: driver name | ||
94 | */ | 93 | */ |
95 | struct fsl_spdif_priv { | 94 | struct fsl_spdif_priv { |
96 | struct spdif_mixer_control fsl_spdif_control; | 95 | struct spdif_mixer_control fsl_spdif_control; |
@@ -109,12 +108,8 @@ struct fsl_spdif_priv { | |||
109 | struct clk *sysclk; | 108 | struct clk *sysclk; |
110 | struct snd_dmaengine_dai_dma_data dma_params_tx; | 109 | struct snd_dmaengine_dai_dma_data dma_params_tx; |
111 | struct snd_dmaengine_dai_dma_data dma_params_rx; | 110 | struct snd_dmaengine_dai_dma_data dma_params_rx; |
112 | |||
113 | /* The name space will be allocated dynamically */ | ||
114 | char name[0]; | ||
115 | }; | 111 | }; |
116 | 112 | ||
117 | |||
118 | /* DPLL locked and lock loss interrupt handler */ | 113 | /* DPLL locked and lock loss interrupt handler */ |
119 | static void spdif_irq_dpll_lock(struct fsl_spdif_priv *spdif_priv) | 114 | static void spdif_irq_dpll_lock(struct fsl_spdif_priv *spdif_priv) |
120 | { | 115 | { |
@@ -1169,19 +1164,15 @@ static int fsl_spdif_probe(struct platform_device *pdev) | |||
1169 | if (!np) | 1164 | if (!np) |
1170 | return -ENODEV; | 1165 | return -ENODEV; |
1171 | 1166 | ||
1172 | spdif_priv = devm_kzalloc(&pdev->dev, | 1167 | spdif_priv = devm_kzalloc(&pdev->dev, sizeof(*spdif_priv), GFP_KERNEL); |
1173 | sizeof(struct fsl_spdif_priv) + strlen(np->name) + 1, | ||
1174 | GFP_KERNEL); | ||
1175 | if (!spdif_priv) | 1168 | if (!spdif_priv) |
1176 | return -ENOMEM; | 1169 | return -ENOMEM; |
1177 | 1170 | ||
1178 | strcpy(spdif_priv->name, np->name); | ||
1179 | |||
1180 | spdif_priv->pdev = pdev; | 1171 | spdif_priv->pdev = pdev; |
1181 | 1172 | ||
1182 | /* Initialize this copy of the CPU DAI driver structure */ | 1173 | /* Initialize this copy of the CPU DAI driver structure */ |
1183 | memcpy(&spdif_priv->cpu_dai_drv, &fsl_spdif_dai, sizeof(fsl_spdif_dai)); | 1174 | memcpy(&spdif_priv->cpu_dai_drv, &fsl_spdif_dai, sizeof(fsl_spdif_dai)); |
1184 | spdif_priv->cpu_dai_drv.name = spdif_priv->name; | 1175 | spdif_priv->cpu_dai_drv.name = dev_name(&pdev->dev); |
1185 | 1176 | ||
1186 | /* Get the addresses and IRQ */ | 1177 | /* Get the addresses and IRQ */ |
1187 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1178 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
@@ -1198,12 +1189,12 @@ static int fsl_spdif_probe(struct platform_device *pdev) | |||
1198 | 1189 | ||
1199 | irq = platform_get_irq(pdev, 0); | 1190 | irq = platform_get_irq(pdev, 0); |
1200 | if (irq < 0) { | 1191 | if (irq < 0) { |
1201 | dev_err(&pdev->dev, "no irq for node %s\n", np->full_name); | 1192 | dev_err(&pdev->dev, "no irq for node %s\n", pdev->name); |
1202 | return irq; | 1193 | return irq; |
1203 | } | 1194 | } |
1204 | 1195 | ||
1205 | ret = devm_request_irq(&pdev->dev, irq, spdif_isr, 0, | 1196 | ret = devm_request_irq(&pdev->dev, irq, spdif_isr, 0, |
1206 | spdif_priv->name, spdif_priv); | 1197 | dev_name(&pdev->dev), spdif_priv); |
1207 | if (ret) { | 1198 | if (ret) { |
1208 | dev_err(&pdev->dev, "could not claim irq %u\n", irq); | 1199 | dev_err(&pdev->dev, "could not claim irq %u\n", irq); |
1209 | return ret; | 1200 | return ret; |
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index a65f17d57ffb..2595611e8a6d 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c | |||
@@ -160,7 +160,7 @@ struct fsl_ssi_soc_data { | |||
160 | */ | 160 | */ |
161 | struct fsl_ssi_private { | 161 | struct fsl_ssi_private { |
162 | struct regmap *regs; | 162 | struct regmap *regs; |
163 | unsigned int irq; | 163 | int irq; |
164 | struct snd_soc_dai_driver cpu_dai_drv; | 164 | struct snd_soc_dai_driver cpu_dai_drv; |
165 | 165 | ||
166 | unsigned int dai_fmt; | 166 | unsigned int dai_fmt; |
@@ -992,8 +992,8 @@ static int fsl_ssi_set_dai_tdm_slot(struct snd_soc_dai *cpu_dai, u32 tx_mask, | |||
992 | regmap_update_bits(regs, CCSR_SSI_SCR, CCSR_SSI_SCR_SSIEN, | 992 | regmap_update_bits(regs, CCSR_SSI_SCR, CCSR_SSI_SCR_SSIEN, |
993 | CCSR_SSI_SCR_SSIEN); | 993 | CCSR_SSI_SCR_SSIEN); |
994 | 994 | ||
995 | regmap_write(regs, CCSR_SSI_STMSK, tx_mask); | 995 | regmap_write(regs, CCSR_SSI_STMSK, ~tx_mask); |
996 | regmap_write(regs, CCSR_SSI_SRMSK, rx_mask); | 996 | regmap_write(regs, CCSR_SSI_SRMSK, ~rx_mask); |
997 | 997 | ||
998 | regmap_update_bits(regs, CCSR_SSI_SCR, CCSR_SSI_SCR_SSIEN, val); | 998 | regmap_update_bits(regs, CCSR_SSI_SCR, CCSR_SSI_SCR_SSIEN, val); |
999 | 999 | ||
@@ -1363,8 +1363,8 @@ static int fsl_ssi_probe(struct platform_device *pdev) | |||
1363 | 1363 | ||
1364 | ssi_private->irq = platform_get_irq(pdev, 0); | 1364 | ssi_private->irq = platform_get_irq(pdev, 0); |
1365 | if (!ssi_private->irq) { | 1365 | if (!ssi_private->irq) { |
1366 | dev_err(&pdev->dev, "no irq for node %s\n", np->full_name); | 1366 | dev_err(&pdev->dev, "no irq for node %s\n", pdev->name); |
1367 | return -ENXIO; | 1367 | return ssi_private->irq; |
1368 | } | 1368 | } |
1369 | 1369 | ||
1370 | /* Are the RX and the TX clocks locked? */ | 1370 | /* Are the RX and the TX clocks locked? */ |
diff --git a/sound/soc/fsl/fsl_utils.c b/sound/soc/fsl/fsl_utils.c index 2ac7755da876..b9e42b503a37 100644 --- a/sound/soc/fsl/fsl_utils.c +++ b/sound/soc/fsl/fsl_utils.c | |||
@@ -86,33 +86,6 @@ int fsl_asoc_get_dma_channel(struct device_node *ssi_np, | |||
86 | } | 86 | } |
87 | EXPORT_SYMBOL(fsl_asoc_get_dma_channel); | 87 | EXPORT_SYMBOL(fsl_asoc_get_dma_channel); |
88 | 88 | ||
89 | /** | ||
90 | * fsl_asoc_xlate_tdm_slot_mask - generate TDM slot TX/RX mask. | ||
91 | * | ||
92 | * @slots: Number of slots in use. | ||
93 | * @tx_mask: bitmask representing active TX slots. | ||
94 | * @rx_mask: bitmask representing active RX slots. | ||
95 | * | ||
96 | * This function used to generate the TDM slot TX/RX mask. And the TX/RX | ||
97 | * mask will use a 0 bit for an active slot as default, and the default | ||
98 | * active bits are at the LSB of the mask value. | ||
99 | */ | ||
100 | int fsl_asoc_xlate_tdm_slot_mask(unsigned int slots, | ||
101 | unsigned int *tx_mask, | ||
102 | unsigned int *rx_mask) | ||
103 | { | ||
104 | if (!slots) | ||
105 | return -EINVAL; | ||
106 | |||
107 | if (tx_mask) | ||
108 | *tx_mask = ~((1 << slots) - 1); | ||
109 | if (rx_mask) | ||
110 | *rx_mask = ~((1 << slots) - 1); | ||
111 | |||
112 | return 0; | ||
113 | } | ||
114 | EXPORT_SYMBOL_GPL(fsl_asoc_xlate_tdm_slot_mask); | ||
115 | |||
116 | MODULE_AUTHOR("Timur Tabi <timur@freescale.com>"); | 89 | MODULE_AUTHOR("Timur Tabi <timur@freescale.com>"); |
117 | MODULE_DESCRIPTION("Freescale ASoC utility code"); | 90 | MODULE_DESCRIPTION("Freescale ASoC utility code"); |
118 | MODULE_LICENSE("GPL v2"); | 91 | MODULE_LICENSE("GPL v2"); |
diff --git a/sound/soc/fsl/fsl_utils.h b/sound/soc/fsl/fsl_utils.h index df535db40313..1687b66ef18e 100644 --- a/sound/soc/fsl/fsl_utils.h +++ b/sound/soc/fsl/fsl_utils.h | |||
@@ -22,7 +22,4 @@ int fsl_asoc_get_dma_channel(struct device_node *ssi_np, const char *name, | |||
22 | struct snd_soc_dai_link *dai, | 22 | struct snd_soc_dai_link *dai, |
23 | unsigned int *dma_channel_id, | 23 | unsigned int *dma_channel_id, |
24 | unsigned int *dma_id); | 24 | unsigned int *dma_id); |
25 | int fsl_asoc_xlate_tdm_slot_mask(unsigned int slots, | ||
26 | unsigned int *tx_mask, | ||
27 | unsigned int *rx_mask); | ||
28 | #endif /* _FSL_UTILS_H */ | 25 | #endif /* _FSL_UTILS_H */ |
diff --git a/sound/soc/fsl/imx-mc13783.c b/sound/soc/fsl/imx-mc13783.c index 6bf5bce01a92..9e6493d4e7ff 100644 --- a/sound/soc/fsl/imx-mc13783.c +++ b/sound/soc/fsl/imx-mc13783.c | |||
@@ -37,8 +37,7 @@ static int imx_mc13783_hifi_hw_params(struct snd_pcm_substream *substream, | |||
37 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | 37 | struct snd_soc_dai *codec_dai = rtd->codec_dai; |
38 | int ret; | 38 | int ret; |
39 | 39 | ||
40 | ret = snd_soc_dai_set_tdm_slot(codec_dai, 0xfffffffc, 0xfffffffc, | 40 | ret = snd_soc_dai_set_tdm_slot(codec_dai, 0x3, 0x3, 4, 16); |
41 | 4, 16); | ||
42 | if (ret) | 41 | if (ret) |
43 | return ret; | 42 | return ret; |
44 | 43 | ||
@@ -46,7 +45,7 @@ static int imx_mc13783_hifi_hw_params(struct snd_pcm_substream *substream, | |||
46 | if (ret) | 45 | if (ret) |
47 | return ret; | 46 | return ret; |
48 | 47 | ||
49 | ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0x0, 0xfffffffc, 2, 16); | 48 | ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0x3, 0x3, 2, 16); |
50 | if (ret) | 49 | if (ret) |
51 | return ret; | 50 | return ret; |
52 | 51 | ||
diff --git a/sound/soc/fsl/imx-spdif.c b/sound/soc/fsl/imx-spdif.c index e94704f1b9ee..33da26a12457 100644 --- a/sound/soc/fsl/imx-spdif.c +++ b/sound/soc/fsl/imx-spdif.c | |||
@@ -60,6 +60,7 @@ static int imx_spdif_audio_probe(struct platform_device *pdev) | |||
60 | data->card.dev = &pdev->dev; | 60 | data->card.dev = &pdev->dev; |
61 | data->card.dai_link = &data->dai; | 61 | data->card.dai_link = &data->dai; |
62 | data->card.num_links = 1; | 62 | data->card.num_links = 1; |
63 | data->card.owner = THIS_MODULE; | ||
63 | 64 | ||
64 | ret = snd_soc_of_parse_card_name(&data->card, "model"); | 65 | ret = snd_soc_of_parse_card_name(&data->card, "model"); |
65 | if (ret) | 66 | if (ret) |
diff --git a/sound/soc/fsl/imx-ssi.c b/sound/soc/fsl/imx-ssi.c index fa801e17c51e..461ce27b884f 100644 --- a/sound/soc/fsl/imx-ssi.c +++ b/sound/soc/fsl/imx-ssi.c | |||
@@ -74,8 +74,8 @@ static int imx_ssi_set_dai_tdm_slot(struct snd_soc_dai *cpu_dai, | |||
74 | sccr |= SSI_STCCR_DC(slots - 1); | 74 | sccr |= SSI_STCCR_DC(slots - 1); |
75 | writel(sccr, ssi->base + SSI_SRCCR); | 75 | writel(sccr, ssi->base + SSI_SRCCR); |
76 | 76 | ||
77 | writel(tx_mask, ssi->base + SSI_STMSK); | 77 | writel(~tx_mask, ssi->base + SSI_STMSK); |
78 | writel(rx_mask, ssi->base + SSI_SRMSK); | 78 | writel(~rx_mask, ssi->base + SSI_SRMSK); |
79 | 79 | ||
80 | return 0; | 80 | return 0; |
81 | } | 81 | } |
@@ -340,7 +340,6 @@ static const struct snd_soc_dai_ops imx_ssi_pcm_dai_ops = { | |||
340 | .set_fmt = imx_ssi_set_dai_fmt, | 340 | .set_fmt = imx_ssi_set_dai_fmt, |
341 | .set_clkdiv = imx_ssi_set_dai_clkdiv, | 341 | .set_clkdiv = imx_ssi_set_dai_clkdiv, |
342 | .set_sysclk = imx_ssi_set_dai_sysclk, | 342 | .set_sysclk = imx_ssi_set_dai_sysclk, |
343 | .xlate_tdm_slot_mask = fsl_asoc_xlate_tdm_slot_mask, | ||
344 | .set_tdm_slot = imx_ssi_set_dai_tdm_slot, | 343 | .set_tdm_slot = imx_ssi_set_dai_tdm_slot, |
345 | .trigger = imx_ssi_trigger, | 344 | .trigger = imx_ssi_trigger, |
346 | }; | 345 | }; |
diff --git a/sound/soc/fsl/imx-wm8962.c b/sound/soc/fsl/imx-wm8962.c index 4caacb05a623..cd146d4fa805 100644 --- a/sound/soc/fsl/imx-wm8962.c +++ b/sound/soc/fsl/imx-wm8962.c | |||
@@ -257,6 +257,7 @@ static int imx_wm8962_probe(struct platform_device *pdev) | |||
257 | if (ret) | 257 | if (ret) |
258 | goto clk_fail; | 258 | goto clk_fail; |
259 | data->card.num_links = 1; | 259 | data->card.num_links = 1; |
260 | data->card.owner = THIS_MODULE; | ||
260 | data->card.dai_link = &data->dai; | 261 | data->card.dai_link = &data->dai; |
261 | data->card.dapm_widgets = imx_wm8962_dapm_widgets; | 262 | data->card.dapm_widgets = imx_wm8962_dapm_widgets; |
262 | data->card.num_dapm_widgets = ARRAY_SIZE(imx_wm8962_dapm_widgets); | 263 | data->card.num_dapm_widgets = ARRAY_SIZE(imx_wm8962_dapm_widgets); |
diff --git a/sound/soc/fsl/mx27vis-aic32x4.c b/sound/soc/fsl/mx27vis-aic32x4.c index b1ced7b8d80c..198eeb3f3f7a 100644 --- a/sound/soc/fsl/mx27vis-aic32x4.c +++ b/sound/soc/fsl/mx27vis-aic32x4.c | |||
@@ -55,16 +55,6 @@ static int mx27vis_aic32x4_hw_params(struct snd_pcm_substream *substream, | |||
55 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | 55 | struct snd_soc_dai *codec_dai = rtd->codec_dai; |
56 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | 56 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; |
57 | int ret; | 57 | int ret; |
58 | u32 dai_format; | ||
59 | |||
60 | dai_format = SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_NB_NF | | ||
61 | SND_SOC_DAIFMT_CBM_CFM; | ||
62 | |||
63 | /* set codec DAI configuration */ | ||
64 | snd_soc_dai_set_fmt(codec_dai, dai_format); | ||
65 | |||
66 | /* set cpu DAI configuration */ | ||
67 | snd_soc_dai_set_fmt(cpu_dai, dai_format); | ||
68 | 58 | ||
69 | ret = snd_soc_dai_set_sysclk(codec_dai, 0, | 59 | ret = snd_soc_dai_set_sysclk(codec_dai, 0, |
70 | 25000000, SND_SOC_CLOCK_OUT); | 60 | 25000000, SND_SOC_CLOCK_OUT); |
@@ -164,6 +154,8 @@ static struct snd_soc_dai_link mx27vis_aic32x4_dai = { | |||
164 | .platform_name = "imx-ssi.0", | 154 | .platform_name = "imx-ssi.0", |
165 | .codec_name = "tlv320aic32x4.0-0018", | 155 | .codec_name = "tlv320aic32x4.0-0018", |
166 | .cpu_dai_name = "imx-ssi.0", | 156 | .cpu_dai_name = "imx-ssi.0", |
157 | .dai_fmt = SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_NB_NF | | ||
158 | SND_SOC_DAIFMT_CBM_CFM, | ||
167 | .ops = &mx27vis_aic32x4_snd_ops, | 159 | .ops = &mx27vis_aic32x4_snd_ops, |
168 | }; | 160 | }; |
169 | 161 | ||
diff --git a/sound/soc/fsl/wm1133-ev1.c b/sound/soc/fsl/wm1133-ev1.c index 804749a6c61e..a958937ab405 100644 --- a/sound/soc/fsl/wm1133-ev1.c +++ b/sound/soc/fsl/wm1133-ev1.c | |||
@@ -87,7 +87,6 @@ static int wm1133_ev1_hw_params(struct snd_pcm_substream *substream, | |||
87 | snd_pcm_format_t format = params_format(params); | 87 | snd_pcm_format_t format = params_format(params); |
88 | unsigned int rate = params_rate(params); | 88 | unsigned int rate = params_rate(params); |
89 | unsigned int channels = params_channels(params); | 89 | unsigned int channels = params_channels(params); |
90 | u32 dai_format; | ||
91 | 90 | ||
92 | /* find the correct audio parameters */ | 91 | /* find the correct audio parameters */ |
93 | for (i = 0; i < ARRAY_SIZE(wm8350_audio); i++) { | 92 | for (i = 0; i < ARRAY_SIZE(wm8350_audio); i++) { |
@@ -104,22 +103,13 @@ static int wm1133_ev1_hw_params(struct snd_pcm_substream *substream, | |||
104 | /* codec FLL input is 14.75 MHz from MCLK */ | 103 | /* codec FLL input is 14.75 MHz from MCLK */ |
105 | snd_soc_dai_set_pll(codec_dai, 0, 0, 14750000, wm8350_audio[i].sysclk); | 104 | snd_soc_dai_set_pll(codec_dai, 0, 0, 14750000, wm8350_audio[i].sysclk); |
106 | 105 | ||
107 | dai_format = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | | ||
108 | SND_SOC_DAIFMT_CBM_CFM; | ||
109 | |||
110 | /* set codec DAI configuration */ | ||
111 | snd_soc_dai_set_fmt(codec_dai, dai_format); | ||
112 | |||
113 | /* set cpu DAI configuration */ | ||
114 | snd_soc_dai_set_fmt(cpu_dai, dai_format); | ||
115 | |||
116 | /* TODO: The SSI driver should figure this out for us */ | 106 | /* TODO: The SSI driver should figure this out for us */ |
117 | switch (channels) { | 107 | switch (channels) { |
118 | case 2: | 108 | case 2: |
119 | snd_soc_dai_set_tdm_slot(cpu_dai, 0xffffffc, 0xffffffc, 2, 0); | 109 | snd_soc_dai_set_tdm_slot(cpu_dai, 0x3, 0x3, 2, 0); |
120 | break; | 110 | break; |
121 | case 1: | 111 | case 1: |
122 | snd_soc_dai_set_tdm_slot(cpu_dai, 0xffffffe, 0xffffffe, 1, 0); | 112 | snd_soc_dai_set_tdm_slot(cpu_dai, 0x1, 0x1, 1, 0); |
123 | break; | 113 | break; |
124 | default: | 114 | default: |
125 | return -EINVAL; | 115 | return -EINVAL; |
@@ -244,6 +234,8 @@ static struct snd_soc_dai_link wm1133_ev1_dai = { | |||
244 | .init = wm1133_ev1_init, | 234 | .init = wm1133_ev1_init, |
245 | .ops = &wm1133_ev1_ops, | 235 | .ops = &wm1133_ev1_ops, |
246 | .symmetric_rates = 1, | 236 | .symmetric_rates = 1, |
237 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | | ||
238 | SND_SOC_DAIFMT_CBM_CFM, | ||
247 | }; | 239 | }; |
248 | 240 | ||
249 | static struct snd_soc_card wm1133_ev1 = { | 241 | static struct snd_soc_card wm1133_ev1 = { |
diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c index fb9240fdc9b7..f7c6734bd5da 100644 --- a/sound/soc/generic/simple-card.c +++ b/sound/soc/generic/simple-card.c | |||
@@ -39,6 +39,37 @@ struct simple_card_data { | |||
39 | #define simple_priv_to_link(priv, i) ((priv)->snd_card.dai_link + i) | 39 | #define simple_priv_to_link(priv, i) ((priv)->snd_card.dai_link + i) |
40 | #define simple_priv_to_props(priv, i) ((priv)->dai_props + i) | 40 | #define simple_priv_to_props(priv, i) ((priv)->dai_props + i) |
41 | 41 | ||
42 | static int asoc_simple_card_startup(struct snd_pcm_substream *substream) | ||
43 | { | ||
44 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
45 | struct simple_card_data *priv = snd_soc_card_get_drvdata(rtd->card); | ||
46 | struct simple_dai_props *dai_props = | ||
47 | &priv->dai_props[rtd - rtd->card->rtd]; | ||
48 | int ret; | ||
49 | |||
50 | ret = clk_prepare_enable(dai_props->cpu_dai.clk); | ||
51 | if (ret) | ||
52 | return ret; | ||
53 | |||
54 | ret = clk_prepare_enable(dai_props->codec_dai.clk); | ||
55 | if (ret) | ||
56 | clk_disable_unprepare(dai_props->cpu_dai.clk); | ||
57 | |||
58 | return ret; | ||
59 | } | ||
60 | |||
61 | static void asoc_simple_card_shutdown(struct snd_pcm_substream *substream) | ||
62 | { | ||
63 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
64 | struct simple_card_data *priv = snd_soc_card_get_drvdata(rtd->card); | ||
65 | struct simple_dai_props *dai_props = | ||
66 | &priv->dai_props[rtd - rtd->card->rtd]; | ||
67 | |||
68 | clk_disable_unprepare(dai_props->cpu_dai.clk); | ||
69 | |||
70 | clk_disable_unprepare(dai_props->codec_dai.clk); | ||
71 | } | ||
72 | |||
42 | static int asoc_simple_card_hw_params(struct snd_pcm_substream *substream, | 73 | static int asoc_simple_card_hw_params(struct snd_pcm_substream *substream, |
43 | struct snd_pcm_hw_params *params) | 74 | struct snd_pcm_hw_params *params) |
44 | { | 75 | { |
@@ -58,6 +89,8 @@ static int asoc_simple_card_hw_params(struct snd_pcm_substream *substream, | |||
58 | } | 89 | } |
59 | 90 | ||
60 | static struct snd_soc_ops asoc_simple_card_ops = { | 91 | static struct snd_soc_ops asoc_simple_card_ops = { |
92 | .startup = asoc_simple_card_startup, | ||
93 | .shutdown = asoc_simple_card_shutdown, | ||
61 | .hw_params = asoc_simple_card_hw_params, | 94 | .hw_params = asoc_simple_card_hw_params, |
62 | }; | 95 | }; |
63 | 96 | ||
@@ -219,6 +252,7 @@ asoc_simple_card_sub_parse_of(struct device_node *np, | |||
219 | } | 252 | } |
220 | 253 | ||
221 | dai->sysclk = clk_get_rate(clk); | 254 | dai->sysclk = clk_get_rate(clk); |
255 | dai->clk = clk; | ||
222 | } else if (!of_property_read_u32(np, "system-clock-frequency", &val)) { | 256 | } else if (!of_property_read_u32(np, "system-clock-frequency", &val)) { |
223 | dai->sysclk = val; | 257 | dai->sysclk = val; |
224 | } else { | 258 | } else { |
@@ -452,9 +486,8 @@ static int asoc_simple_card_parse_of(struct device_node *node, | |||
452 | } | 486 | } |
453 | 487 | ||
454 | /* Decrease the reference count of the device nodes */ | 488 | /* Decrease the reference count of the device nodes */ |
455 | static int asoc_simple_card_unref(struct platform_device *pdev) | 489 | static int asoc_simple_card_unref(struct snd_soc_card *card) |
456 | { | 490 | { |
457 | struct snd_soc_card *card = platform_get_drvdata(pdev); | ||
458 | struct snd_soc_dai_link *dai_link; | 491 | struct snd_soc_dai_link *dai_link; |
459 | int num_links; | 492 | int num_links; |
460 | 493 | ||
@@ -556,7 +589,7 @@ static int asoc_simple_card_probe(struct platform_device *pdev) | |||
556 | return ret; | 589 | return ret; |
557 | 590 | ||
558 | err: | 591 | err: |
559 | asoc_simple_card_unref(pdev); | 592 | asoc_simple_card_unref(&priv->snd_card); |
560 | return ret; | 593 | return ret; |
561 | } | 594 | } |
562 | 595 | ||
@@ -572,7 +605,7 @@ static int asoc_simple_card_remove(struct platform_device *pdev) | |||
572 | snd_soc_jack_free_gpios(&simple_card_mic_jack, 1, | 605 | snd_soc_jack_free_gpios(&simple_card_mic_jack, 1, |
573 | &simple_card_mic_jack_gpio); | 606 | &simple_card_mic_jack_gpio); |
574 | 607 | ||
575 | return asoc_simple_card_unref(pdev); | 608 | return asoc_simple_card_unref(card); |
576 | } | 609 | } |
577 | 610 | ||
578 | static const struct of_device_id asoc_simple_of_match[] = { | 611 | static const struct of_device_id asoc_simple_of_match[] = { |
diff --git a/sound/soc/intel/Kconfig b/sound/soc/intel/Kconfig index e989ecf046c9..ee03dbdda235 100644 --- a/sound/soc/intel/Kconfig +++ b/sound/soc/intel/Kconfig | |||
@@ -46,7 +46,7 @@ config SND_SOC_INTEL_BAYTRAIL | |||
46 | 46 | ||
47 | config SND_SOC_INTEL_HASWELL_MACH | 47 | config SND_SOC_INTEL_HASWELL_MACH |
48 | tristate "ASoC Audio DSP support for Intel Haswell Lynxpoint" | 48 | tristate "ASoC Audio DSP support for Intel Haswell Lynxpoint" |
49 | depends on SND_SOC_INTEL_SST && X86_INTEL_LPSS && I2C && \\ | 49 | depends on SND_SOC_INTEL_SST && X86_INTEL_LPSS && I2C && \ |
50 | I2C_DESIGNWARE_PLATFORM | 50 | I2C_DESIGNWARE_PLATFORM |
51 | select SND_SOC_INTEL_HASWELL | 51 | select SND_SOC_INTEL_HASWELL |
52 | select SND_SOC_RT5640 | 52 | select SND_SOC_RT5640 |
@@ -76,7 +76,7 @@ config SND_SOC_INTEL_BYT_MAX98090_MACH | |||
76 | 76 | ||
77 | config SND_SOC_INTEL_BROADWELL_MACH | 77 | config SND_SOC_INTEL_BROADWELL_MACH |
78 | tristate "ASoC Audio DSP support for Intel Broadwell Wildcatpoint" | 78 | tristate "ASoC Audio DSP support for Intel Broadwell Wildcatpoint" |
79 | depends on SND_SOC_INTEL_SST && X86_INTEL_LPSS && DW_DMAC && \\ | 79 | depends on SND_SOC_INTEL_SST && X86_INTEL_LPSS && DW_DMAC && \ |
80 | I2C_DESIGNWARE_PLATFORM | 80 | I2C_DESIGNWARE_PLATFORM |
81 | select SND_SOC_INTEL_HASWELL | 81 | select SND_SOC_INTEL_HASWELL |
82 | select SND_COMPRESS_OFFLOAD | 82 | select SND_COMPRESS_OFFLOAD |
@@ -89,7 +89,7 @@ config SND_SOC_INTEL_BROADWELL_MACH | |||
89 | 89 | ||
90 | config SND_SOC_INTEL_BYTCR_RT5640_MACH | 90 | config SND_SOC_INTEL_BYTCR_RT5640_MACH |
91 | tristate "ASoC Audio DSP Support for MID BYT Platform" | 91 | tristate "ASoC Audio DSP Support for MID BYT Platform" |
92 | depends on X86 | 92 | depends on X86 && I2C |
93 | select SND_SOC_RT5640 | 93 | select SND_SOC_RT5640 |
94 | select SND_SST_MFLD_PLATFORM | 94 | select SND_SST_MFLD_PLATFORM |
95 | select SND_SST_IPC_ACPI | 95 | select SND_SST_IPC_ACPI |
@@ -101,7 +101,7 @@ config SND_SOC_INTEL_BYTCR_RT5640_MACH | |||
101 | 101 | ||
102 | config SND_SOC_INTEL_CHT_BSW_RT5672_MACH | 102 | config SND_SOC_INTEL_CHT_BSW_RT5672_MACH |
103 | tristate "ASoC Audio driver for Intel Cherrytrail & Braswell with RT5672 codec" | 103 | tristate "ASoC Audio driver for Intel Cherrytrail & Braswell with RT5672 codec" |
104 | depends on X86_INTEL_LPSS | 104 | depends on X86_INTEL_LPSS && I2C |
105 | select SND_SOC_RT5670 | 105 | select SND_SOC_RT5670 |
106 | select SND_SST_MFLD_PLATFORM | 106 | select SND_SST_MFLD_PLATFORM |
107 | select SND_SST_IPC_ACPI | 107 | select SND_SST_IPC_ACPI |
@@ -110,3 +110,14 @@ config SND_SOC_INTEL_CHT_BSW_RT5672_MACH | |||
110 | platforms with RT5672 audio codec. | 110 | platforms with RT5672 audio codec. |
111 | Say Y if you have such a device | 111 | Say Y if you have such a device |
112 | If unsure select "N". | 112 | If unsure select "N". |
113 | |||
114 | config SND_SOC_INTEL_CHT_BSW_RT5645_MACH | ||
115 | tristate "ASoC Audio driver for Intel Cherrytrail & Braswell with RT5645 codec" | ||
116 | depends on X86_INTEL_LPSS | ||
117 | select SND_SOC_RT5645 | ||
118 | select SND_SST_MFLD_PLATFORM | ||
119 | select SND_SST_IPC_ACPI | ||
120 | help | ||
121 | This adds support for ASoC machine driver for Intel(R) Cherrytrail & Braswell | ||
122 | platforms with RT5645 audio codec. | ||
123 | If unsure select "N". | ||
diff --git a/sound/soc/intel/Makefile b/sound/soc/intel/Makefile index e928ec385300..a8e53c45c6b6 100644 --- a/sound/soc/intel/Makefile +++ b/sound/soc/intel/Makefile | |||
@@ -28,6 +28,7 @@ snd-soc-sst-byt-max98090-mach-objs := byt-max98090.o | |||
28 | snd-soc-sst-broadwell-objs := broadwell.o | 28 | snd-soc-sst-broadwell-objs := broadwell.o |
29 | snd-soc-sst-bytcr-dpcm-rt5640-objs := bytcr_dpcm_rt5640.o | 29 | snd-soc-sst-bytcr-dpcm-rt5640-objs := bytcr_dpcm_rt5640.o |
30 | snd-soc-sst-cht-bsw-rt5672-objs := cht_bsw_rt5672.o | 30 | snd-soc-sst-cht-bsw-rt5672-objs := cht_bsw_rt5672.o |
31 | snd-soc-sst-cht-bsw-rt5645-objs := cht_bsw_rt5645.o | ||
31 | 32 | ||
32 | obj-$(CONFIG_SND_SOC_INTEL_HASWELL_MACH) += snd-soc-sst-haswell.o | 33 | obj-$(CONFIG_SND_SOC_INTEL_HASWELL_MACH) += snd-soc-sst-haswell.o |
33 | obj-$(CONFIG_SND_SOC_INTEL_BYT_RT5640_MACH) += snd-soc-sst-byt-rt5640-mach.o | 34 | obj-$(CONFIG_SND_SOC_INTEL_BYT_RT5640_MACH) += snd-soc-sst-byt-rt5640-mach.o |
@@ -35,6 +36,7 @@ obj-$(CONFIG_SND_SOC_INTEL_BYT_MAX98090_MACH) += snd-soc-sst-byt-max98090-mach.o | |||
35 | obj-$(CONFIG_SND_SOC_INTEL_BROADWELL_MACH) += snd-soc-sst-broadwell.o | 36 | obj-$(CONFIG_SND_SOC_INTEL_BROADWELL_MACH) += snd-soc-sst-broadwell.o |
36 | obj-$(CONFIG_SND_SOC_INTEL_BYTCR_RT5640_MACH) += snd-soc-sst-bytcr-dpcm-rt5640.o | 37 | obj-$(CONFIG_SND_SOC_INTEL_BYTCR_RT5640_MACH) += snd-soc-sst-bytcr-dpcm-rt5640.o |
37 | obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_RT5672_MACH) += snd-soc-sst-cht-bsw-rt5672.o | 38 | obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_RT5672_MACH) += snd-soc-sst-cht-bsw-rt5672.o |
39 | obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_RT5645_MACH) += snd-soc-sst-cht-bsw-rt5645.o | ||
38 | 40 | ||
39 | # DSP driver | 41 | # DSP driver |
40 | obj-$(CONFIG_SND_SST_IPC) += sst/ | 42 | obj-$(CONFIG_SND_SST_IPC) += sst/ |
diff --git a/sound/soc/intel/broadwell.c b/sound/soc/intel/broadwell.c index 7cf95d5d5d80..9cf7d01479ad 100644 --- a/sound/soc/intel/broadwell.c +++ b/sound/soc/intel/broadwell.c | |||
@@ -140,8 +140,6 @@ static struct snd_soc_ops broadwell_rt286_ops = { | |||
140 | 140 | ||
141 | static int broadwell_rtd_init(struct snd_soc_pcm_runtime *rtd) | 141 | static int broadwell_rtd_init(struct snd_soc_pcm_runtime *rtd) |
142 | { | 142 | { |
143 | struct snd_soc_codec *codec = rtd->codec; | ||
144 | struct snd_soc_dapm_context *dapm = &codec->dapm; | ||
145 | struct sst_pdata *pdata = dev_get_platdata(rtd->platform->dev); | 143 | struct sst_pdata *pdata = dev_get_platdata(rtd->platform->dev); |
146 | struct sst_hsw *broadwell = pdata->dsp; | 144 | struct sst_hsw *broadwell = pdata->dsp; |
147 | int ret; | 145 | int ret; |
@@ -155,14 +153,6 @@ static int broadwell_rtd_init(struct snd_soc_pcm_runtime *rtd) | |||
155 | return ret; | 153 | return ret; |
156 | } | 154 | } |
157 | 155 | ||
158 | /* always connected - check HP for jack detect */ | ||
159 | snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); | ||
160 | snd_soc_dapm_enable_pin(dapm, "Speaker"); | ||
161 | snd_soc_dapm_enable_pin(dapm, "Mic Jack"); | ||
162 | snd_soc_dapm_enable_pin(dapm, "Line Jack"); | ||
163 | snd_soc_dapm_enable_pin(dapm, "DMIC1"); | ||
164 | snd_soc_dapm_enable_pin(dapm, "DMIC2"); | ||
165 | |||
166 | return 0; | 156 | return 0; |
167 | } | 157 | } |
168 | 158 | ||
diff --git a/sound/soc/intel/byt-rt5640.c b/sound/soc/intel/byt-rt5640.c index 0cba7830c5e9..354eaad886e1 100644 --- a/sound/soc/intel/byt-rt5640.c +++ b/sound/soc/intel/byt-rt5640.c | |||
@@ -132,7 +132,6 @@ static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime) | |||
132 | { | 132 | { |
133 | int ret; | 133 | int ret; |
134 | struct snd_soc_codec *codec = runtime->codec; | 134 | struct snd_soc_codec *codec = runtime->codec; |
135 | struct snd_soc_dapm_context *dapm = &codec->dapm; | ||
136 | struct snd_soc_card *card = runtime->card; | 135 | struct snd_soc_card *card = runtime->card; |
137 | const struct snd_soc_dapm_route *custom_map; | 136 | const struct snd_soc_dapm_route *custom_map; |
138 | int num_routes; | 137 | int num_routes; |
@@ -161,7 +160,7 @@ static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime) | |||
161 | num_routes = ARRAY_SIZE(byt_rt5640_intmic_dmic1_map); | 160 | num_routes = ARRAY_SIZE(byt_rt5640_intmic_dmic1_map); |
162 | } | 161 | } |
163 | 162 | ||
164 | ret = snd_soc_dapm_add_routes(dapm, custom_map, num_routes); | 163 | ret = snd_soc_dapm_add_routes(&card->dapm, custom_map, num_routes); |
165 | if (ret) | 164 | if (ret) |
166 | return ret; | 165 | return ret; |
167 | 166 | ||
@@ -171,13 +170,8 @@ static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime) | |||
171 | return ret; | 170 | return ret; |
172 | } | 171 | } |
173 | 172 | ||
174 | snd_soc_dapm_ignore_suspend(dapm, "HPOL"); | 173 | snd_soc_dapm_ignore_suspend(&card->dapm, "Headphone"); |
175 | snd_soc_dapm_ignore_suspend(dapm, "HPOR"); | 174 | snd_soc_dapm_ignore_suspend(&card->dapm, "Speaker"); |
176 | |||
177 | snd_soc_dapm_ignore_suspend(dapm, "SPOLP"); | ||
178 | snd_soc_dapm_ignore_suspend(dapm, "SPOLN"); | ||
179 | snd_soc_dapm_ignore_suspend(dapm, "SPORP"); | ||
180 | snd_soc_dapm_ignore_suspend(dapm, "SPORN"); | ||
181 | 175 | ||
182 | return ret; | 176 | return ret; |
183 | } | 177 | } |
diff --git a/sound/soc/intel/bytcr_dpcm_rt5640.c b/sound/soc/intel/bytcr_dpcm_rt5640.c index f5d0fc1ab10c..59308629043e 100644 --- a/sound/soc/intel/bytcr_dpcm_rt5640.c +++ b/sound/soc/intel/bytcr_dpcm_rt5640.c | |||
@@ -215,7 +215,6 @@ static int snd_byt_mc_probe(struct platform_device *pdev) | |||
215 | 215 | ||
216 | static struct platform_driver snd_byt_mc_driver = { | 216 | static struct platform_driver snd_byt_mc_driver = { |
217 | .driver = { | 217 | .driver = { |
218 | .owner = THIS_MODULE, | ||
219 | .name = "bytt100_rt5640", | 218 | .name = "bytt100_rt5640", |
220 | .pm = &snd_soc_pm_ops, | 219 | .pm = &snd_soc_pm_ops, |
221 | }, | 220 | }, |
@@ -227,4 +226,4 @@ module_platform_driver(snd_byt_mc_driver); | |||
227 | MODULE_DESCRIPTION("ASoC Intel(R) Baytrail CR Machine driver"); | 226 | MODULE_DESCRIPTION("ASoC Intel(R) Baytrail CR Machine driver"); |
228 | MODULE_AUTHOR("Subhransu S. Prusty <subhransu.s.prusty@intel.com>"); | 227 | MODULE_AUTHOR("Subhransu S. Prusty <subhransu.s.prusty@intel.com>"); |
229 | MODULE_LICENSE("GPL v2"); | 228 | MODULE_LICENSE("GPL v2"); |
230 | MODULE_ALIAS("platform:bytrt5640-audio"); | 229 | MODULE_ALIAS("platform:bytt100_rt5640"); |
diff --git a/sound/soc/intel/cht_bsw_rt5645.c b/sound/soc/intel/cht_bsw_rt5645.c new file mode 100644 index 000000000000..bd29617a9ab9 --- /dev/null +++ b/sound/soc/intel/cht_bsw_rt5645.c | |||
@@ -0,0 +1,326 @@ | |||
1 | /* | ||
2 | * cht-bsw-rt5645.c - ASoc Machine driver for Intel Cherryview-based platforms | ||
3 | * Cherrytrail and Braswell, with RT5645 codec. | ||
4 | * | ||
5 | * Copyright (C) 2015 Intel Corp | ||
6 | * Author: Fang, Yang A <yang.a.fang@intel.com> | ||
7 | * N,Harshapriya <harshapriya.n@intel.com> | ||
8 | * This file is modified from cht_bsw_rt5672.c | ||
9 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify | ||
12 | * it under the terms of the GNU General Public License as published by | ||
13 | * the Free Software Foundation; version 2 of the License. | ||
14 | * | ||
15 | * This program is distributed in the hope that it will be useful, but | ||
16 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
18 | * General Public License for more details. | ||
19 | * | ||
20 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
21 | */ | ||
22 | |||
23 | #include <linux/module.h> | ||
24 | #include <linux/platform_device.h> | ||
25 | #include <linux/slab.h> | ||
26 | #include <sound/pcm.h> | ||
27 | #include <sound/pcm_params.h> | ||
28 | #include <sound/soc.h> | ||
29 | #include <sound/jack.h> | ||
30 | #include "../codecs/rt5645.h" | ||
31 | #include "sst-atom-controls.h" | ||
32 | |||
33 | #define CHT_PLAT_CLK_3_HZ 19200000 | ||
34 | #define CHT_CODEC_DAI "rt5645-aif1" | ||
35 | |||
36 | struct cht_mc_private { | ||
37 | struct snd_soc_jack hp_jack; | ||
38 | struct snd_soc_jack mic_jack; | ||
39 | }; | ||
40 | |||
41 | static inline struct snd_soc_dai *cht_get_codec_dai(struct snd_soc_card *card) | ||
42 | { | ||
43 | int i; | ||
44 | |||
45 | for (i = 0; i < card->num_rtd; i++) { | ||
46 | struct snd_soc_pcm_runtime *rtd; | ||
47 | |||
48 | rtd = card->rtd + i; | ||
49 | if (!strncmp(rtd->codec_dai->name, CHT_CODEC_DAI, | ||
50 | strlen(CHT_CODEC_DAI))) | ||
51 | return rtd->codec_dai; | ||
52 | } | ||
53 | return NULL; | ||
54 | } | ||
55 | |||
56 | static int platform_clock_control(struct snd_soc_dapm_widget *w, | ||
57 | struct snd_kcontrol *k, int event) | ||
58 | { | ||
59 | struct snd_soc_dapm_context *dapm = w->dapm; | ||
60 | struct snd_soc_card *card = dapm->card; | ||
61 | struct snd_soc_dai *codec_dai; | ||
62 | int ret; | ||
63 | |||
64 | codec_dai = cht_get_codec_dai(card); | ||
65 | if (!codec_dai) { | ||
66 | dev_err(card->dev, "Codec dai not found; Unable to set platform clock\n"); | ||
67 | return -EIO; | ||
68 | } | ||
69 | |||
70 | if (!SND_SOC_DAPM_EVENT_OFF(event)) | ||
71 | return 0; | ||
72 | |||
73 | /* Set codec sysclk source to its internal clock because codec PLL will | ||
74 | * be off when idle and MCLK will also be off by ACPI when codec is | ||
75 | * runtime suspended. Codec needs clock for jack detection and button | ||
76 | * press. | ||
77 | */ | ||
78 | ret = snd_soc_dai_set_sysclk(codec_dai, RT5645_SCLK_S_RCCLK, | ||
79 | 0, SND_SOC_CLOCK_IN); | ||
80 | if (ret < 0) { | ||
81 | dev_err(card->dev, "can't set codec sysclk: %d\n", ret); | ||
82 | return ret; | ||
83 | } | ||
84 | |||
85 | return 0; | ||
86 | } | ||
87 | |||
88 | static const struct snd_soc_dapm_widget cht_dapm_widgets[] = { | ||
89 | SND_SOC_DAPM_HP("Headphone", NULL), | ||
90 | SND_SOC_DAPM_MIC("Headset Mic", NULL), | ||
91 | SND_SOC_DAPM_MIC("Int Mic", NULL), | ||
92 | SND_SOC_DAPM_SPK("Ext Spk", NULL), | ||
93 | SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0, | ||
94 | platform_clock_control, SND_SOC_DAPM_POST_PMD), | ||
95 | }; | ||
96 | |||
97 | static const struct snd_soc_dapm_route cht_audio_map[] = { | ||
98 | {"IN1P", NULL, "Headset Mic"}, | ||
99 | {"IN1N", NULL, "Headset Mic"}, | ||
100 | {"DMIC L1", NULL, "Int Mic"}, | ||
101 | {"DMIC R1", NULL, "Int Mic"}, | ||
102 | {"Headphone", NULL, "HPOL"}, | ||
103 | {"Headphone", NULL, "HPOR"}, | ||
104 | {"Ext Spk", NULL, "SPOL"}, | ||
105 | {"Ext Spk", NULL, "SPOR"}, | ||
106 | {"AIF1 Playback", NULL, "ssp2 Tx"}, | ||
107 | {"ssp2 Tx", NULL, "codec_out0"}, | ||
108 | {"ssp2 Tx", NULL, "codec_out1"}, | ||
109 | {"codec_in0", NULL, "ssp2 Rx" }, | ||
110 | {"codec_in1", NULL, "ssp2 Rx" }, | ||
111 | {"ssp2 Rx", NULL, "AIF1 Capture"}, | ||
112 | {"Headphone", NULL, "Platform Clock"}, | ||
113 | {"Headset Mic", NULL, "Platform Clock"}, | ||
114 | {"Int Mic", NULL, "Platform Clock"}, | ||
115 | {"Ext Spk", NULL, "Platform Clock"}, | ||
116 | }; | ||
117 | |||
118 | static const struct snd_kcontrol_new cht_mc_controls[] = { | ||
119 | SOC_DAPM_PIN_SWITCH("Headphone"), | ||
120 | SOC_DAPM_PIN_SWITCH("Headset Mic"), | ||
121 | SOC_DAPM_PIN_SWITCH("Int Mic"), | ||
122 | SOC_DAPM_PIN_SWITCH("Ext Spk"), | ||
123 | }; | ||
124 | |||
125 | static int cht_aif1_hw_params(struct snd_pcm_substream *substream, | ||
126 | struct snd_pcm_hw_params *params) | ||
127 | { | ||
128 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
129 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | ||
130 | int ret; | ||
131 | |||
132 | /* set codec PLL source to the 19.2MHz platform clock (MCLK) */ | ||
133 | ret = snd_soc_dai_set_pll(codec_dai, 0, RT5645_PLL1_S_MCLK, | ||
134 | CHT_PLAT_CLK_3_HZ, params_rate(params) * 512); | ||
135 | if (ret < 0) { | ||
136 | dev_err(rtd->dev, "can't set codec pll: %d\n", ret); | ||
137 | return ret; | ||
138 | } | ||
139 | |||
140 | ret = snd_soc_dai_set_sysclk(codec_dai, RT5645_SCLK_S_PLL1, | ||
141 | params_rate(params) * 512, SND_SOC_CLOCK_IN); | ||
142 | if (ret < 0) { | ||
143 | dev_err(rtd->dev, "can't set codec sysclk: %d\n", ret); | ||
144 | return ret; | ||
145 | } | ||
146 | |||
147 | return 0; | ||
148 | } | ||
149 | |||
150 | static int cht_codec_init(struct snd_soc_pcm_runtime *runtime) | ||
151 | { | ||
152 | int ret; | ||
153 | struct snd_soc_codec *codec = runtime->codec; | ||
154 | struct snd_soc_dai *codec_dai = runtime->codec_dai; | ||
155 | struct cht_mc_private *ctx = snd_soc_card_get_drvdata(runtime->card); | ||
156 | |||
157 | /* Select clk_i2s1_asrc as ASRC clock source */ | ||
158 | rt5645_sel_asrc_clk_src(codec, | ||
159 | RT5645_DA_STEREO_FILTER | | ||
160 | RT5645_DA_MONO_L_FILTER | | ||
161 | RT5645_DA_MONO_R_FILTER | | ||
162 | RT5645_AD_STEREO_FILTER, | ||
163 | RT5645_CLK_SEL_I2S1_ASRC); | ||
164 | |||
165 | /* TDM 4 slots 24 bit, set Rx & Tx bitmask to 4 active slots */ | ||
166 | ret = snd_soc_dai_set_tdm_slot(codec_dai, 0xF, 0xF, 4, 24); | ||
167 | if (ret < 0) { | ||
168 | dev_err(runtime->dev, "can't set codec TDM slot %d\n", ret); | ||
169 | return ret; | ||
170 | } | ||
171 | |||
172 | ret = snd_soc_jack_new(codec, "Headphone Jack", | ||
173 | SND_JACK_HEADPHONE, | ||
174 | &ctx->hp_jack); | ||
175 | if (ret) { | ||
176 | dev_err(runtime->dev, "HP jack creation failed %d\n", ret); | ||
177 | return ret; | ||
178 | } | ||
179 | |||
180 | ret = snd_soc_jack_new(codec, "Mic Jack", | ||
181 | SND_JACK_MICROPHONE, | ||
182 | &ctx->mic_jack); | ||
183 | if (ret) { | ||
184 | dev_err(runtime->dev, "Mic jack creation failed %d\n", ret); | ||
185 | return ret; | ||
186 | } | ||
187 | |||
188 | rt5645_set_jack_detect(codec, &ctx->hp_jack, &ctx->mic_jack); | ||
189 | |||
190 | return ret; | ||
191 | } | ||
192 | |||
193 | static int cht_codec_fixup(struct snd_soc_pcm_runtime *rtd, | ||
194 | struct snd_pcm_hw_params *params) | ||
195 | { | ||
196 | struct snd_interval *rate = hw_param_interval(params, | ||
197 | SNDRV_PCM_HW_PARAM_RATE); | ||
198 | struct snd_interval *channels = hw_param_interval(params, | ||
199 | SNDRV_PCM_HW_PARAM_CHANNELS); | ||
200 | |||
201 | /* The DSP will covert the FE rate to 48k, stereo, 24bits */ | ||
202 | rate->min = rate->max = 48000; | ||
203 | channels->min = channels->max = 2; | ||
204 | |||
205 | /* set SSP2 to 24-bit */ | ||
206 | snd_mask_set(¶ms->masks[SNDRV_PCM_HW_PARAM_FORMAT - | ||
207 | SNDRV_PCM_HW_PARAM_FIRST_MASK], | ||
208 | SNDRV_PCM_FORMAT_S24_LE); | ||
209 | return 0; | ||
210 | } | ||
211 | |||
212 | static unsigned int rates_48000[] = { | ||
213 | 48000, | ||
214 | }; | ||
215 | |||
216 | static struct snd_pcm_hw_constraint_list constraints_48000 = { | ||
217 | .count = ARRAY_SIZE(rates_48000), | ||
218 | .list = rates_48000, | ||
219 | }; | ||
220 | |||
221 | static int cht_aif1_startup(struct snd_pcm_substream *substream) | ||
222 | { | ||
223 | return snd_pcm_hw_constraint_list(substream->runtime, 0, | ||
224 | SNDRV_PCM_HW_PARAM_RATE, | ||
225 | &constraints_48000); | ||
226 | } | ||
227 | |||
228 | static struct snd_soc_ops cht_aif1_ops = { | ||
229 | .startup = cht_aif1_startup, | ||
230 | }; | ||
231 | |||
232 | static struct snd_soc_ops cht_be_ssp2_ops = { | ||
233 | .hw_params = cht_aif1_hw_params, | ||
234 | }; | ||
235 | |||
236 | static struct snd_soc_dai_link cht_dailink[] = { | ||
237 | [MERR_DPCM_AUDIO] = { | ||
238 | .name = "Audio Port", | ||
239 | .stream_name = "Audio", | ||
240 | .cpu_dai_name = "media-cpu-dai", | ||
241 | .codec_dai_name = "snd-soc-dummy-dai", | ||
242 | .codec_name = "snd-soc-dummy", | ||
243 | .platform_name = "sst-mfld-platform", | ||
244 | .ignore_suspend = 1, | ||
245 | .dynamic = 1, | ||
246 | .dpcm_playback = 1, | ||
247 | .dpcm_capture = 1, | ||
248 | .ops = &cht_aif1_ops, | ||
249 | }, | ||
250 | [MERR_DPCM_COMPR] = { | ||
251 | .name = "Compressed Port", | ||
252 | .stream_name = "Compress", | ||
253 | .cpu_dai_name = "compress-cpu-dai", | ||
254 | .codec_dai_name = "snd-soc-dummy-dai", | ||
255 | .codec_name = "snd-soc-dummy", | ||
256 | .platform_name = "sst-mfld-platform", | ||
257 | }, | ||
258 | /* CODEC<->CODEC link */ | ||
259 | /* back ends */ | ||
260 | { | ||
261 | .name = "SSP2-Codec", | ||
262 | .be_id = 1, | ||
263 | .cpu_dai_name = "ssp2-port", | ||
264 | .platform_name = "sst-mfld-platform", | ||
265 | .no_pcm = 1, | ||
266 | .codec_dai_name = "rt5645-aif1", | ||
267 | .codec_name = "i2c-10EC5645:00", | ||
268 | .dai_fmt = SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_IB_NF | ||
269 | | SND_SOC_DAIFMT_CBS_CFS, | ||
270 | .init = cht_codec_init, | ||
271 | .be_hw_params_fixup = cht_codec_fixup, | ||
272 | .ignore_suspend = 1, | ||
273 | .dpcm_playback = 1, | ||
274 | .dpcm_capture = 1, | ||
275 | .ops = &cht_be_ssp2_ops, | ||
276 | }, | ||
277 | }; | ||
278 | |||
279 | /* SoC card */ | ||
280 | static struct snd_soc_card snd_soc_card_cht = { | ||
281 | .name = "chtrt5645", | ||
282 | .dai_link = cht_dailink, | ||
283 | .num_links = ARRAY_SIZE(cht_dailink), | ||
284 | .dapm_widgets = cht_dapm_widgets, | ||
285 | .num_dapm_widgets = ARRAY_SIZE(cht_dapm_widgets), | ||
286 | .dapm_routes = cht_audio_map, | ||
287 | .num_dapm_routes = ARRAY_SIZE(cht_audio_map), | ||
288 | .controls = cht_mc_controls, | ||
289 | .num_controls = ARRAY_SIZE(cht_mc_controls), | ||
290 | }; | ||
291 | |||
292 | static int snd_cht_mc_probe(struct platform_device *pdev) | ||
293 | { | ||
294 | int ret_val = 0; | ||
295 | struct cht_mc_private *drv; | ||
296 | |||
297 | drv = devm_kzalloc(&pdev->dev, sizeof(*drv), GFP_ATOMIC); | ||
298 | if (!drv) | ||
299 | return -ENOMEM; | ||
300 | |||
301 | snd_soc_card_cht.dev = &pdev->dev; | ||
302 | snd_soc_card_set_drvdata(&snd_soc_card_cht, drv); | ||
303 | ret_val = devm_snd_soc_register_card(&pdev->dev, &snd_soc_card_cht); | ||
304 | if (ret_val) { | ||
305 | dev_err(&pdev->dev, | ||
306 | "snd_soc_register_card failed %d\n", ret_val); | ||
307 | return ret_val; | ||
308 | } | ||
309 | platform_set_drvdata(pdev, &snd_soc_card_cht); | ||
310 | return ret_val; | ||
311 | } | ||
312 | |||
313 | static struct platform_driver snd_cht_mc_driver = { | ||
314 | .driver = { | ||
315 | .name = "cht-bsw-rt5645", | ||
316 | .pm = &snd_soc_pm_ops, | ||
317 | }, | ||
318 | .probe = snd_cht_mc_probe, | ||
319 | }; | ||
320 | |||
321 | module_platform_driver(snd_cht_mc_driver) | ||
322 | |||
323 | MODULE_DESCRIPTION("ASoC Intel(R) Braswell Machine driver"); | ||
324 | MODULE_AUTHOR("Fang, Yang A,N,Harshapriya"); | ||
325 | MODULE_LICENSE("GPL v2"); | ||
326 | MODULE_ALIAS("platform:cht-bsw-rt5645"); | ||
diff --git a/sound/soc/intel/cht_bsw_rt5672.c b/sound/soc/intel/cht_bsw_rt5672.c index 9b8b561171b7..ff016621583a 100644 --- a/sound/soc/intel/cht_bsw_rt5672.c +++ b/sound/soc/intel/cht_bsw_rt5672.c | |||
@@ -140,6 +140,7 @@ static int cht_codec_init(struct snd_soc_pcm_runtime *runtime) | |||
140 | { | 140 | { |
141 | int ret; | 141 | int ret; |
142 | struct snd_soc_dai *codec_dai = runtime->codec_dai; | 142 | struct snd_soc_dai *codec_dai = runtime->codec_dai; |
143 | struct snd_soc_codec *codec = codec_dai->codec; | ||
143 | 144 | ||
144 | /* TDM 4 slots 24 bit, set Rx & Tx bitmask to 4 active slots */ | 145 | /* TDM 4 slots 24 bit, set Rx & Tx bitmask to 4 active slots */ |
145 | ret = snd_soc_dai_set_tdm_slot(codec_dai, 0xF, 0xF, 4, 24); | 146 | ret = snd_soc_dai_set_tdm_slot(codec_dai, 0xF, 0xF, 4, 24); |
@@ -148,6 +149,19 @@ static int cht_codec_init(struct snd_soc_pcm_runtime *runtime) | |||
148 | return ret; | 149 | return ret; |
149 | } | 150 | } |
150 | 151 | ||
152 | /* Select codec ASRC clock source to track I2S1 clock, because codec | ||
153 | * is in slave mode and 100fs I2S format (BCLK = 100 * LRCLK) cannot | ||
154 | * be supported by RT5672. Otherwise, ASRC will be disabled and cause | ||
155 | * noise. | ||
156 | */ | ||
157 | rt5670_sel_asrc_clk_src(codec, | ||
158 | RT5670_DA_STEREO_FILTER | ||
159 | | RT5670_DA_MONO_L_FILTER | ||
160 | | RT5670_DA_MONO_R_FILTER | ||
161 | | RT5670_AD_STEREO_FILTER | ||
162 | | RT5670_AD_MONO_L_FILTER | ||
163 | | RT5670_AD_MONO_R_FILTER, | ||
164 | RT5670_CLK_SEL_I2S1_ASRC); | ||
151 | return 0; | 165 | return 0; |
152 | } | 166 | } |
153 | 167 | ||
@@ -270,7 +284,6 @@ static int snd_cht_mc_probe(struct platform_device *pdev) | |||
270 | 284 | ||
271 | static struct platform_driver snd_cht_mc_driver = { | 285 | static struct platform_driver snd_cht_mc_driver = { |
272 | .driver = { | 286 | .driver = { |
273 | .owner = THIS_MODULE, | ||
274 | .name = "cht-bsw-rt5672", | 287 | .name = "cht-bsw-rt5672", |
275 | .pm = &snd_soc_pm_ops, | 288 | .pm = &snd_soc_pm_ops, |
276 | }, | 289 | }, |
diff --git a/sound/soc/intel/sst-baytrail-pcm.c b/sound/soc/intel/sst-baytrail-pcm.c index 3bb6288d8b4d..224c49c9f135 100644 --- a/sound/soc/intel/sst-baytrail-pcm.c +++ b/sound/soc/intel/sst-baytrail-pcm.c | |||
@@ -320,11 +320,6 @@ static struct snd_pcm_ops sst_byt_pcm_ops = { | |||
320 | .mmap = sst_byt_pcm_mmap, | 320 | .mmap = sst_byt_pcm_mmap, |
321 | }; | 321 | }; |
322 | 322 | ||
323 | static void sst_byt_pcm_free(struct snd_pcm *pcm) | ||
324 | { | ||
325 | snd_pcm_lib_preallocate_free_for_all(pcm); | ||
326 | } | ||
327 | |||
328 | static int sst_byt_pcm_new(struct snd_soc_pcm_runtime *rtd) | 323 | static int sst_byt_pcm_new(struct snd_soc_pcm_runtime *rtd) |
329 | { | 324 | { |
330 | struct snd_pcm *pcm = rtd->pcm; | 325 | struct snd_pcm *pcm = rtd->pcm; |
@@ -403,7 +398,6 @@ static struct snd_soc_platform_driver byt_soc_platform = { | |||
403 | .remove = sst_byt_pcm_remove, | 398 | .remove = sst_byt_pcm_remove, |
404 | .ops = &sst_byt_pcm_ops, | 399 | .ops = &sst_byt_pcm_ops, |
405 | .pcm_new = sst_byt_pcm_new, | 400 | .pcm_new = sst_byt_pcm_new, |
406 | .pcm_free = sst_byt_pcm_free, | ||
407 | }; | 401 | }; |
408 | 402 | ||
409 | static const struct snd_soc_component_driver byt_dai_component = { | 403 | static const struct snd_soc_component_driver byt_dai_component = { |
diff --git a/sound/soc/intel/sst-dsp.c b/sound/soc/intel/sst-dsp.c index 86e410845670..64e94212d2d2 100644 --- a/sound/soc/intel/sst-dsp.c +++ b/sound/soc/intel/sst-dsp.c | |||
@@ -410,8 +410,7 @@ void sst_dsp_free(struct sst_dsp *sst) | |||
410 | if (sst->ops->free) | 410 | if (sst->ops->free) |
411 | sst->ops->free(sst); | 411 | sst->ops->free(sst); |
412 | 412 | ||
413 | if (sst->dma) | 413 | sst_dma_free(sst->dma); |
414 | sst_dma_free(sst->dma); | ||
415 | } | 414 | } |
416 | EXPORT_SYMBOL_GPL(sst_dsp_free); | 415 | EXPORT_SYMBOL_GPL(sst_dsp_free); |
417 | 416 | ||
diff --git a/sound/soc/intel/sst-firmware.c b/sound/soc/intel/sst-firmware.c index 4a5bde9c686b..5f71ef607a57 100644 --- a/sound/soc/intel/sst-firmware.c +++ b/sound/soc/intel/sst-firmware.c | |||
@@ -497,6 +497,7 @@ struct sst_module *sst_module_new(struct sst_fw *sst_fw, | |||
497 | sst_module->sst_fw = sst_fw; | 497 | sst_module->sst_fw = sst_fw; |
498 | sst_module->scratch_size = template->scratch_size; | 498 | sst_module->scratch_size = template->scratch_size; |
499 | sst_module->persistent_size = template->persistent_size; | 499 | sst_module->persistent_size = template->persistent_size; |
500 | sst_module->entry = template->entry; | ||
500 | 501 | ||
501 | INIT_LIST_HEAD(&sst_module->block_list); | 502 | INIT_LIST_HEAD(&sst_module->block_list); |
502 | INIT_LIST_HEAD(&sst_module->runtime_list); | 503 | INIT_LIST_HEAD(&sst_module->runtime_list); |
@@ -706,6 +707,7 @@ static int block_alloc_fixed(struct sst_dsp *dsp, struct sst_block_allocator *ba | |||
706 | struct list_head *block_list) | 707 | struct list_head *block_list) |
707 | { | 708 | { |
708 | struct sst_mem_block *block, *tmp; | 709 | struct sst_mem_block *block, *tmp; |
710 | struct sst_block_allocator ba_tmp = *ba; | ||
709 | u32 end = ba->offset + ba->size, block_end; | 711 | u32 end = ba->offset + ba->size, block_end; |
710 | int err; | 712 | int err; |
711 | 713 | ||
@@ -730,9 +732,9 @@ static int block_alloc_fixed(struct sst_dsp *dsp, struct sst_block_allocator *ba | |||
730 | if (ba->offset >= block->offset && ba->offset < block_end) { | 732 | if (ba->offset >= block->offset && ba->offset < block_end) { |
731 | 733 | ||
732 | /* align ba to block boundary */ | 734 | /* align ba to block boundary */ |
733 | ba->size -= block_end - ba->offset; | 735 | ba_tmp.size -= block_end - ba->offset; |
734 | ba->offset = block_end; | 736 | ba_tmp.offset = block_end; |
735 | err = block_alloc_contiguous(dsp, ba, block_list); | 737 | err = block_alloc_contiguous(dsp, &ba_tmp, block_list); |
736 | if (err < 0) | 738 | if (err < 0) |
737 | return -ENOMEM; | 739 | return -ENOMEM; |
738 | 740 | ||
@@ -763,10 +765,14 @@ static int block_alloc_fixed(struct sst_dsp *dsp, struct sst_block_allocator *ba | |||
763 | /* does block span more than 1 section */ | 765 | /* does block span more than 1 section */ |
764 | if (ba->offset >= block->offset && ba->offset < block_end) { | 766 | if (ba->offset >= block->offset && ba->offset < block_end) { |
765 | 767 | ||
768 | /* add block */ | ||
769 | list_move(&block->list, &dsp->used_block_list); | ||
770 | list_add(&block->module_list, block_list); | ||
766 | /* align ba to block boundary */ | 771 | /* align ba to block boundary */ |
767 | ba->offset = block->offset; | 772 | ba_tmp.size -= block_end - ba->offset; |
773 | ba_tmp.offset = block_end; | ||
768 | 774 | ||
769 | err = block_alloc_contiguous(dsp, ba, block_list); | 775 | err = block_alloc_contiguous(dsp, &ba_tmp, block_list); |
770 | if (err < 0) | 776 | if (err < 0) |
771 | return -ENOMEM; | 777 | return -ENOMEM; |
772 | 778 | ||
@@ -785,6 +791,7 @@ int sst_module_alloc_blocks(struct sst_module *module) | |||
785 | struct sst_block_allocator ba; | 791 | struct sst_block_allocator ba; |
786 | int ret; | 792 | int ret; |
787 | 793 | ||
794 | memset(&ba, 0, sizeof(ba)); | ||
788 | ba.size = module->size; | 795 | ba.size = module->size; |
789 | ba.type = module->type; | 796 | ba.type = module->type; |
790 | ba.offset = module->offset; | 797 | ba.offset = module->offset; |
@@ -858,6 +865,7 @@ int sst_module_runtime_alloc_blocks(struct sst_module_runtime *runtime, | |||
858 | if (module->persistent_size == 0) | 865 | if (module->persistent_size == 0) |
859 | return 0; | 866 | return 0; |
860 | 867 | ||
868 | memset(&ba, 0, sizeof(ba)); | ||
861 | ba.size = module->persistent_size; | 869 | ba.size = module->persistent_size; |
862 | ba.type = SST_MEM_DRAM; | 870 | ba.type = SST_MEM_DRAM; |
863 | 871 | ||
diff --git a/sound/soc/intel/sst-haswell-dsp.c b/sound/soc/intel/sst-haswell-dsp.c index 57039b00efc2..c42ffae5fe9f 100644 --- a/sound/soc/intel/sst-haswell-dsp.c +++ b/sound/soc/intel/sst-haswell-dsp.c | |||
@@ -306,7 +306,7 @@ static void hsw_reset(struct sst_dsp *sst) | |||
306 | static int hsw_set_dsp_D0(struct sst_dsp *sst) | 306 | static int hsw_set_dsp_D0(struct sst_dsp *sst) |
307 | { | 307 | { |
308 | int tries = 10; | 308 | int tries = 10; |
309 | u32 reg; | 309 | u32 reg, fw_dump_bit; |
310 | 310 | ||
311 | /* Disable core clock gating (VDRTCTL2.DCLCGE = 0) */ | 311 | /* Disable core clock gating (VDRTCTL2.DCLCGE = 0) */ |
312 | reg = readl(sst->addr.pci_cfg + SST_VDRTCTL2); | 312 | reg = readl(sst->addr.pci_cfg + SST_VDRTCTL2); |
@@ -368,7 +368,9 @@ finish: | |||
368 | can't be accessed, please enable each block before accessing. */ | 368 | can't be accessed, please enable each block before accessing. */ |
369 | reg = readl(sst->addr.pci_cfg + SST_VDRTCTL0); | 369 | reg = readl(sst->addr.pci_cfg + SST_VDRTCTL0); |
370 | reg |= SST_VDRTCL0_DSRAMPGE_MASK | SST_VDRTCL0_ISRAMPGE_MASK; | 370 | reg |= SST_VDRTCL0_DSRAMPGE_MASK | SST_VDRTCL0_ISRAMPGE_MASK; |
371 | writel(reg, sst->addr.pci_cfg + SST_VDRTCTL0); | 371 | /* for D0, always enable the block(DSRAM[0]) used for FW dump */ |
372 | fw_dump_bit = 1 << SST_VDRTCL0_DSRAMPGE_SHIFT; | ||
373 | writel(reg & ~fw_dump_bit, sst->addr.pci_cfg + SST_VDRTCTL0); | ||
372 | 374 | ||
373 | 375 | ||
374 | /* disable DMA finish function for SSP0 & SSP1 */ | 376 | /* disable DMA finish function for SSP0 & SSP1 */ |
@@ -491,6 +493,7 @@ static const struct sst_sram_shift sram_shift[] = { | |||
491 | {SST_DEV_ID_LYNX_POINT, 6, 16}, /* lp */ | 493 | {SST_DEV_ID_LYNX_POINT, 6, 16}, /* lp */ |
492 | {SST_DEV_ID_WILDCAT_POINT, 2, 12}, /* wpt */ | 494 | {SST_DEV_ID_WILDCAT_POINT, 2, 12}, /* wpt */ |
493 | }; | 495 | }; |
496 | |||
494 | static u32 hsw_block_get_bit(struct sst_mem_block *block) | 497 | static u32 hsw_block_get_bit(struct sst_mem_block *block) |
495 | { | 498 | { |
496 | u32 bit = 0, shift = 0, index; | 499 | u32 bit = 0, shift = 0, index; |
@@ -587,7 +590,9 @@ static int hsw_block_disable(struct sst_mem_block *block) | |||
587 | 590 | ||
588 | val = readl(sst->addr.pci_cfg + SST_VDRTCTL0); | 591 | val = readl(sst->addr.pci_cfg + SST_VDRTCTL0); |
589 | bit = hsw_block_get_bit(block); | 592 | bit = hsw_block_get_bit(block); |
590 | writel(val | bit, sst->addr.pci_cfg + SST_VDRTCTL0); | 593 | /* don't disable DSRAM[0], keep it always enable for FW dump*/ |
594 | if (bit != (1 << SST_VDRTCL0_DSRAMPGE_SHIFT)) | ||
595 | writel(val | bit, sst->addr.pci_cfg + SST_VDRTCTL0); | ||
591 | 596 | ||
592 | /* wait 18 DSP clock ticks */ | 597 | /* wait 18 DSP clock ticks */ |
593 | udelay(10); | 598 | udelay(10); |
@@ -612,7 +617,7 @@ static int hsw_init(struct sst_dsp *sst, struct sst_pdata *pdata) | |||
612 | const struct sst_adsp_memregion *region; | 617 | const struct sst_adsp_memregion *region; |
613 | struct device *dev; | 618 | struct device *dev; |
614 | int ret = -ENODEV, i, j, region_count; | 619 | int ret = -ENODEV, i, j, region_count; |
615 | u32 offset, size; | 620 | u32 offset, size, fw_dump_bit; |
616 | 621 | ||
617 | dev = sst->dma_dev; | 622 | dev = sst->dma_dev; |
618 | 623 | ||
@@ -669,9 +674,11 @@ static int hsw_init(struct sst_dsp *sst, struct sst_pdata *pdata) | |||
669 | } | 674 | } |
670 | } | 675 | } |
671 | 676 | ||
677 | /* always enable the block(DSRAM[0]) used for FW dump */ | ||
678 | fw_dump_bit = 1 << SST_VDRTCL0_DSRAMPGE_SHIFT; | ||
672 | /* set default power gating control, enable power gating control for all blocks. that is, | 679 | /* set default power gating control, enable power gating control for all blocks. that is, |
673 | can't be accessed, please enable each block before accessing. */ | 680 | can't be accessed, please enable each block before accessing. */ |
674 | writel(0xffffffff, sst->addr.pci_cfg + SST_VDRTCTL0); | 681 | writel(0xffffffff & ~fw_dump_bit, sst->addr.pci_cfg + SST_VDRTCTL0); |
675 | 682 | ||
676 | return 0; | 683 | return 0; |
677 | } | 684 | } |
diff --git a/sound/soc/intel/sst-haswell-ipc.c b/sound/soc/intel/sst-haswell-ipc.c index 3f8c48231364..0ab1309ef274 100644 --- a/sound/soc/intel/sst-haswell-ipc.c +++ b/sound/soc/intel/sst-haswell-ipc.c | |||
@@ -94,6 +94,8 @@ | |||
94 | /* Mailbox */ | 94 | /* Mailbox */ |
95 | #define IPC_MAX_MAILBOX_BYTES 256 | 95 | #define IPC_MAX_MAILBOX_BYTES 256 |
96 | 96 | ||
97 | #define INVALID_STREAM_HW_ID 0xffffffff | ||
98 | |||
97 | /* Global Message - Types and Replies */ | 99 | /* Global Message - Types and Replies */ |
98 | enum ipc_glb_type { | 100 | enum ipc_glb_type { |
99 | IPC_GLB_GET_FW_VERSION = 0, /* Retrieves firmware version */ | 101 | IPC_GLB_GET_FW_VERSION = 0, /* Retrieves firmware version */ |
@@ -275,7 +277,6 @@ struct sst_hsw { | |||
275 | /* FW config */ | 277 | /* FW config */ |
276 | struct sst_hsw_ipc_fw_ready fw_ready; | 278 | struct sst_hsw_ipc_fw_ready fw_ready; |
277 | struct sst_hsw_ipc_fw_version version; | 279 | struct sst_hsw_ipc_fw_version version; |
278 | struct sst_module *scratch; | ||
279 | bool fw_done; | 280 | bool fw_done; |
280 | struct sst_fw *sst_fw; | 281 | struct sst_fw *sst_fw; |
281 | 282 | ||
@@ -337,12 +338,6 @@ static inline u32 msg_get_stage_type(u32 msg) | |||
337 | return (msg & IPC_STG_TYPE_MASK) >> IPC_STG_TYPE_SHIFT; | 338 | return (msg & IPC_STG_TYPE_MASK) >> IPC_STG_TYPE_SHIFT; |
338 | } | 339 | } |
339 | 340 | ||
340 | static inline u32 msg_set_stage_type(u32 msg, u32 type) | ||
341 | { | ||
342 | return (msg & ~IPC_STG_TYPE_MASK) + | ||
343 | (type << IPC_STG_TYPE_SHIFT); | ||
344 | } | ||
345 | |||
346 | static inline u32 msg_get_stream_id(u32 msg) | 341 | static inline u32 msg_get_stream_id(u32 msg) |
347 | { | 342 | { |
348 | return (msg & IPC_STR_ID_MASK) >> IPC_STR_ID_SHIFT; | 343 | return (msg & IPC_STR_ID_MASK) >> IPC_STR_ID_SHIFT; |
@@ -651,11 +646,11 @@ static void hsw_notification_work(struct work_struct *work) | |||
651 | } | 646 | } |
652 | 647 | ||
653 | /* tell DSP that notification has been handled */ | 648 | /* tell DSP that notification has been handled */ |
654 | sst_dsp_shim_update_bits_unlocked(hsw->dsp, SST_IPCD, | 649 | sst_dsp_shim_update_bits(hsw->dsp, SST_IPCD, |
655 | SST_IPCD_BUSY | SST_IPCD_DONE, SST_IPCD_DONE); | 650 | SST_IPCD_BUSY | SST_IPCD_DONE, SST_IPCD_DONE); |
656 | 651 | ||
657 | /* unmask busy interrupt */ | 652 | /* unmask busy interrupt */ |
658 | sst_dsp_shim_update_bits_unlocked(hsw->dsp, SST_IMRX, SST_IMRX_BUSY, 0); | 653 | sst_dsp_shim_update_bits(hsw->dsp, SST_IMRX, SST_IMRX_BUSY, 0); |
659 | } | 654 | } |
660 | 655 | ||
661 | static struct ipc_message *reply_find_msg(struct sst_hsw *hsw, u32 header) | 656 | static struct ipc_message *reply_find_msg(struct sst_hsw *hsw, u32 header) |
@@ -969,45 +964,6 @@ int sst_hsw_fw_get_version(struct sst_hsw *hsw, | |||
969 | } | 964 | } |
970 | 965 | ||
971 | /* Mixer Controls */ | 966 | /* Mixer Controls */ |
972 | int sst_hsw_stream_mute(struct sst_hsw *hsw, struct sst_hsw_stream *stream, | ||
973 | u32 stage_id, u32 channel) | ||
974 | { | ||
975 | int ret; | ||
976 | |||
977 | ret = sst_hsw_stream_get_volume(hsw, stream, stage_id, channel, | ||
978 | &stream->mute_volume[channel]); | ||
979 | if (ret < 0) | ||
980 | return ret; | ||
981 | |||
982 | ret = sst_hsw_stream_set_volume(hsw, stream, stage_id, channel, 0); | ||
983 | if (ret < 0) { | ||
984 | dev_err(hsw->dev, "error: can't unmute stream %d channel %d\n", | ||
985 | stream->reply.stream_hw_id, channel); | ||
986 | return ret; | ||
987 | } | ||
988 | |||
989 | stream->mute[channel] = 1; | ||
990 | return 0; | ||
991 | } | ||
992 | |||
993 | int sst_hsw_stream_unmute(struct sst_hsw *hsw, struct sst_hsw_stream *stream, | ||
994 | u32 stage_id, u32 channel) | ||
995 | |||
996 | { | ||
997 | int ret; | ||
998 | |||
999 | stream->mute[channel] = 0; | ||
1000 | ret = sst_hsw_stream_set_volume(hsw, stream, stage_id, channel, | ||
1001 | stream->mute_volume[channel]); | ||
1002 | if (ret < 0) { | ||
1003 | dev_err(hsw->dev, "error: can't unmute stream %d channel %d\n", | ||
1004 | stream->reply.stream_hw_id, channel); | ||
1005 | return ret; | ||
1006 | } | ||
1007 | |||
1008 | return 0; | ||
1009 | } | ||
1010 | |||
1011 | int sst_hsw_stream_get_volume(struct sst_hsw *hsw, struct sst_hsw_stream *stream, | 967 | int sst_hsw_stream_get_volume(struct sst_hsw *hsw, struct sst_hsw_stream *stream, |
1012 | u32 stage_id, u32 channel, u32 *volume) | 968 | u32 stage_id, u32 channel, u32 *volume) |
1013 | { | 969 | { |
@@ -1021,17 +977,6 @@ int sst_hsw_stream_get_volume(struct sst_hsw *hsw, struct sst_hsw_stream *stream | |||
1021 | return 0; | 977 | return 0; |
1022 | } | 978 | } |
1023 | 979 | ||
1024 | int sst_hsw_stream_set_volume_curve(struct sst_hsw *hsw, | ||
1025 | struct sst_hsw_stream *stream, u64 curve_duration, | ||
1026 | enum sst_hsw_volume_curve curve) | ||
1027 | { | ||
1028 | /* curve duration in steps of 100ns */ | ||
1029 | stream->vol_req.curve_duration = curve_duration; | ||
1030 | stream->vol_req.curve_type = curve; | ||
1031 | |||
1032 | return 0; | ||
1033 | } | ||
1034 | |||
1035 | /* stream volume */ | 980 | /* stream volume */ |
1036 | int sst_hsw_stream_set_volume(struct sst_hsw *hsw, | 981 | int sst_hsw_stream_set_volume(struct sst_hsw *hsw, |
1037 | struct sst_hsw_stream *stream, u32 stage_id, u32 channel, u32 volume) | 982 | struct sst_hsw_stream *stream, u32 stage_id, u32 channel, u32 volume) |
@@ -1083,42 +1028,6 @@ int sst_hsw_stream_set_volume(struct sst_hsw *hsw, | |||
1083 | return 0; | 1028 | return 0; |
1084 | } | 1029 | } |
1085 | 1030 | ||
1086 | int sst_hsw_mixer_mute(struct sst_hsw *hsw, u32 stage_id, u32 channel) | ||
1087 | { | ||
1088 | int ret; | ||
1089 | |||
1090 | ret = sst_hsw_mixer_get_volume(hsw, stage_id, channel, | ||
1091 | &hsw->mute_volume[channel]); | ||
1092 | if (ret < 0) | ||
1093 | return ret; | ||
1094 | |||
1095 | ret = sst_hsw_mixer_set_volume(hsw, stage_id, channel, 0); | ||
1096 | if (ret < 0) { | ||
1097 | dev_err(hsw->dev, "error: failed to unmute mixer channel %d\n", | ||
1098 | channel); | ||
1099 | return ret; | ||
1100 | } | ||
1101 | |||
1102 | hsw->mute[channel] = 1; | ||
1103 | return 0; | ||
1104 | } | ||
1105 | |||
1106 | int sst_hsw_mixer_unmute(struct sst_hsw *hsw, u32 stage_id, u32 channel) | ||
1107 | { | ||
1108 | int ret; | ||
1109 | |||
1110 | ret = sst_hsw_mixer_set_volume(hsw, stage_id, channel, | ||
1111 | hsw->mixer_info.volume_register_address[channel]); | ||
1112 | if (ret < 0) { | ||
1113 | dev_err(hsw->dev, "error: failed to unmute mixer channel %d\n", | ||
1114 | channel); | ||
1115 | return ret; | ||
1116 | } | ||
1117 | |||
1118 | hsw->mute[channel] = 0; | ||
1119 | return 0; | ||
1120 | } | ||
1121 | |||
1122 | int sst_hsw_mixer_get_volume(struct sst_hsw *hsw, u32 stage_id, u32 channel, | 1031 | int sst_hsw_mixer_get_volume(struct sst_hsw *hsw, u32 stage_id, u32 channel, |
1123 | u32 *volume) | 1032 | u32 *volume) |
1124 | { | 1033 | { |
@@ -1132,16 +1041,6 @@ int sst_hsw_mixer_get_volume(struct sst_hsw *hsw, u32 stage_id, u32 channel, | |||
1132 | return 0; | 1041 | return 0; |
1133 | } | 1042 | } |
1134 | 1043 | ||
1135 | int sst_hsw_mixer_set_volume_curve(struct sst_hsw *hsw, | ||
1136 | u64 curve_duration, enum sst_hsw_volume_curve curve) | ||
1137 | { | ||
1138 | /* curve duration in steps of 100ns */ | ||
1139 | hsw->curve_duration = curve_duration; | ||
1140 | hsw->curve_type = curve; | ||
1141 | |||
1142 | return 0; | ||
1143 | } | ||
1144 | |||
1145 | /* global mixer volume */ | 1044 | /* global mixer volume */ |
1146 | int sst_hsw_mixer_set_volume(struct sst_hsw *hsw, u32 stage_id, u32 channel, | 1045 | int sst_hsw_mixer_set_volume(struct sst_hsw *hsw, u32 stage_id, u32 channel, |
1147 | u32 volume) | 1046 | u32 volume) |
@@ -1208,6 +1107,7 @@ struct sst_hsw_stream *sst_hsw_stream_new(struct sst_hsw *hsw, int id, | |||
1208 | return NULL; | 1107 | return NULL; |
1209 | 1108 | ||
1210 | spin_lock_irqsave(&sst->spinlock, flags); | 1109 | spin_lock_irqsave(&sst->spinlock, flags); |
1110 | stream->reply.stream_hw_id = INVALID_STREAM_HW_ID; | ||
1211 | list_add(&stream->node, &hsw->stream_list); | 1111 | list_add(&stream->node, &hsw->stream_list); |
1212 | stream->notify_position = notify_position; | 1112 | stream->notify_position = notify_position; |
1213 | stream->pdata = data; | 1113 | stream->pdata = data; |
@@ -1228,6 +1128,11 @@ int sst_hsw_stream_free(struct sst_hsw *hsw, struct sst_hsw_stream *stream) | |||
1228 | struct sst_dsp *sst = hsw->dsp; | 1128 | struct sst_dsp *sst = hsw->dsp; |
1229 | unsigned long flags; | 1129 | unsigned long flags; |
1230 | 1130 | ||
1131 | if (!stream) { | ||
1132 | dev_warn(hsw->dev, "warning: stream is NULL, no stream to free, ignore it.\n"); | ||
1133 | return 0; | ||
1134 | } | ||
1135 | |||
1231 | /* dont free DSP streams that are not commited */ | 1136 | /* dont free DSP streams that are not commited */ |
1232 | if (!stream->commited) | 1137 | if (!stream->commited) |
1233 | goto out; | 1138 | goto out; |
@@ -1415,6 +1320,16 @@ int sst_hsw_stream_commit(struct sst_hsw *hsw, struct sst_hsw_stream *stream) | |||
1415 | u32 header; | 1320 | u32 header; |
1416 | int ret; | 1321 | int ret; |
1417 | 1322 | ||
1323 | if (!stream) { | ||
1324 | dev_warn(hsw->dev, "warning: stream is NULL, no stream to commit, ignore it.\n"); | ||
1325 | return 0; | ||
1326 | } | ||
1327 | |||
1328 | if (stream->commited) { | ||
1329 | dev_warn(hsw->dev, "warning: stream is already committed, ignore it.\n"); | ||
1330 | return 0; | ||
1331 | } | ||
1332 | |||
1418 | trace_ipc_request("stream alloc", stream->host_id); | 1333 | trace_ipc_request("stream alloc", stream->host_id); |
1419 | 1334 | ||
1420 | header = IPC_GLB_TYPE(IPC_GLB_ALLOCATE_STREAM); | 1335 | header = IPC_GLB_TYPE(IPC_GLB_ALLOCATE_STREAM); |
@@ -1434,48 +1349,6 @@ int sst_hsw_stream_commit(struct sst_hsw *hsw, struct sst_hsw_stream *stream) | |||
1434 | 1349 | ||
1435 | /* Stream Information - these calls could be inline but we want the IPC | 1350 | /* Stream Information - these calls could be inline but we want the IPC |
1436 | ABI to be opaque to client PCM drivers to cope with any future ABI changes */ | 1351 | ABI to be opaque to client PCM drivers to cope with any future ABI changes */ |
1437 | int sst_hsw_stream_get_hw_id(struct sst_hsw *hsw, | ||
1438 | struct sst_hsw_stream *stream) | ||
1439 | { | ||
1440 | return stream->reply.stream_hw_id; | ||
1441 | } | ||
1442 | |||
1443 | int sst_hsw_stream_get_mixer_id(struct sst_hsw *hsw, | ||
1444 | struct sst_hsw_stream *stream) | ||
1445 | { | ||
1446 | return stream->reply.mixer_hw_id; | ||
1447 | } | ||
1448 | |||
1449 | u32 sst_hsw_stream_get_read_reg(struct sst_hsw *hsw, | ||
1450 | struct sst_hsw_stream *stream) | ||
1451 | { | ||
1452 | return stream->reply.read_position_register_address; | ||
1453 | } | ||
1454 | |||
1455 | u32 sst_hsw_stream_get_pointer_reg(struct sst_hsw *hsw, | ||
1456 | struct sst_hsw_stream *stream) | ||
1457 | { | ||
1458 | return stream->reply.presentation_position_register_address; | ||
1459 | } | ||
1460 | |||
1461 | u32 sst_hsw_stream_get_peak_reg(struct sst_hsw *hsw, | ||
1462 | struct sst_hsw_stream *stream, u32 channel) | ||
1463 | { | ||
1464 | if (channel >= 2) | ||
1465 | return 0; | ||
1466 | |||
1467 | return stream->reply.peak_meter_register_address[channel]; | ||
1468 | } | ||
1469 | |||
1470 | u32 sst_hsw_stream_get_vol_reg(struct sst_hsw *hsw, | ||
1471 | struct sst_hsw_stream *stream, u32 channel) | ||
1472 | { | ||
1473 | if (channel >= 2) | ||
1474 | return 0; | ||
1475 | |||
1476 | return stream->reply.volume_register_address[channel]; | ||
1477 | } | ||
1478 | |||
1479 | int sst_hsw_mixer_get_info(struct sst_hsw *hsw) | 1352 | int sst_hsw_mixer_get_info(struct sst_hsw *hsw) |
1480 | { | 1353 | { |
1481 | struct sst_hsw_ipc_stream_info_reply *reply; | 1354 | struct sst_hsw_ipc_stream_info_reply *reply; |
@@ -1519,6 +1392,11 @@ int sst_hsw_stream_pause(struct sst_hsw *hsw, struct sst_hsw_stream *stream, | |||
1519 | { | 1392 | { |
1520 | int ret; | 1393 | int ret; |
1521 | 1394 | ||
1395 | if (!stream) { | ||
1396 | dev_warn(hsw->dev, "warning: stream is NULL, no stream to pause, ignore it.\n"); | ||
1397 | return 0; | ||
1398 | } | ||
1399 | |||
1522 | trace_ipc_request("stream pause", stream->reply.stream_hw_id); | 1400 | trace_ipc_request("stream pause", stream->reply.stream_hw_id); |
1523 | 1401 | ||
1524 | ret = sst_hsw_stream_operations(hsw, IPC_STR_PAUSE, | 1402 | ret = sst_hsw_stream_operations(hsw, IPC_STR_PAUSE, |
@@ -1535,6 +1413,11 @@ int sst_hsw_stream_resume(struct sst_hsw *hsw, struct sst_hsw_stream *stream, | |||
1535 | { | 1413 | { |
1536 | int ret; | 1414 | int ret; |
1537 | 1415 | ||
1416 | if (!stream) { | ||
1417 | dev_warn(hsw->dev, "warning: stream is NULL, no stream to resume, ignore it.\n"); | ||
1418 | return 0; | ||
1419 | } | ||
1420 | |||
1538 | trace_ipc_request("stream resume", stream->reply.stream_hw_id); | 1421 | trace_ipc_request("stream resume", stream->reply.stream_hw_id); |
1539 | 1422 | ||
1540 | ret = sst_hsw_stream_operations(hsw, IPC_STR_RESUME, | 1423 | ret = sst_hsw_stream_operations(hsw, IPC_STR_RESUME, |
@@ -1550,6 +1433,11 @@ int sst_hsw_stream_reset(struct sst_hsw *hsw, struct sst_hsw_stream *stream) | |||
1550 | { | 1433 | { |
1551 | int ret, tries = 10; | 1434 | int ret, tries = 10; |
1552 | 1435 | ||
1436 | if (!stream) { | ||
1437 | dev_warn(hsw->dev, "warning: stream is NULL, no stream to reset, ignore it.\n"); | ||
1438 | return 0; | ||
1439 | } | ||
1440 | |||
1553 | /* dont reset streams that are not commited */ | 1441 | /* dont reset streams that are not commited */ |
1554 | if (!stream->commited) | 1442 | if (!stream->commited) |
1555 | return 0; | 1443 | return 0; |
@@ -1598,30 +1486,6 @@ u64 sst_hsw_get_dsp_presentation_position(struct sst_hsw *hsw, | |||
1598 | return ppos; | 1486 | return ppos; |
1599 | } | 1487 | } |
1600 | 1488 | ||
1601 | int sst_hsw_stream_set_write_position(struct sst_hsw *hsw, | ||
1602 | struct sst_hsw_stream *stream, u32 stage_id, u32 position) | ||
1603 | { | ||
1604 | u32 header; | ||
1605 | int ret; | ||
1606 | |||
1607 | trace_stream_write_position(stream->reply.stream_hw_id, position); | ||
1608 | |||
1609 | header = IPC_GLB_TYPE(IPC_GLB_STREAM_MESSAGE) | | ||
1610 | IPC_STR_TYPE(IPC_STR_STAGE_MESSAGE); | ||
1611 | header |= (stream->reply.stream_hw_id << IPC_STR_ID_SHIFT); | ||
1612 | header |= (IPC_STG_SET_WRITE_POSITION << IPC_STG_TYPE_SHIFT); | ||
1613 | header |= (stage_id << IPC_STG_ID_SHIFT); | ||
1614 | stream->wpos.position = position; | ||
1615 | |||
1616 | ret = ipc_tx_message_nowait(hsw, header, &stream->wpos, | ||
1617 | sizeof(stream->wpos)); | ||
1618 | if (ret < 0) | ||
1619 | dev_err(hsw->dev, "error: stream %d set position %d failed\n", | ||
1620 | stream->reply.stream_hw_id, position); | ||
1621 | |||
1622 | return ret; | ||
1623 | } | ||
1624 | |||
1625 | /* physical BE config */ | 1489 | /* physical BE config */ |
1626 | int sst_hsw_device_set_config(struct sst_hsw *hsw, | 1490 | int sst_hsw_device_set_config(struct sst_hsw *hsw, |
1627 | enum sst_hsw_device_id dev, enum sst_hsw_device_mclk mclk, | 1491 | enum sst_hsw_device_id dev, enum sst_hsw_device_mclk mclk, |
@@ -2102,7 +1966,6 @@ void sst_hsw_dsp_free(struct device *dev, struct sst_pdata *pdata) | |||
2102 | dma_free_coherent(hsw->dsp->dma_dev, SST_HSW_DX_CONTEXT_SIZE, | 1966 | dma_free_coherent(hsw->dsp->dma_dev, SST_HSW_DX_CONTEXT_SIZE, |
2103 | hsw->dx_context, hsw->dx_context_paddr); | 1967 | hsw->dx_context, hsw->dx_context_paddr); |
2104 | sst_dsp_free(hsw->dsp); | 1968 | sst_dsp_free(hsw->dsp); |
2105 | kfree(hsw->scratch); | ||
2106 | kthread_stop(hsw->tx_thread); | 1969 | kthread_stop(hsw->tx_thread); |
2107 | kfree(hsw->msg); | 1970 | kfree(hsw->msg); |
2108 | } | 1971 | } |
diff --git a/sound/soc/intel/sst-haswell-ipc.h b/sound/soc/intel/sst-haswell-ipc.h index 138e894ab413..c1ad901342f2 100644 --- a/sound/soc/intel/sst-haswell-ipc.h +++ b/sound/soc/intel/sst-haswell-ipc.h | |||
@@ -376,32 +376,17 @@ int sst_hsw_fw_get_version(struct sst_hsw *hsw, | |||
376 | u32 create_channel_map(enum sst_hsw_channel_config config); | 376 | u32 create_channel_map(enum sst_hsw_channel_config config); |
377 | 377 | ||
378 | /* Stream Mixer Controls - */ | 378 | /* Stream Mixer Controls - */ |
379 | int sst_hsw_stream_mute(struct sst_hsw *hsw, struct sst_hsw_stream *stream, | ||
380 | u32 stage_id, u32 channel); | ||
381 | int sst_hsw_stream_unmute(struct sst_hsw *hsw, struct sst_hsw_stream *stream, | ||
382 | u32 stage_id, u32 channel); | ||
383 | |||
384 | int sst_hsw_stream_set_volume(struct sst_hsw *hsw, | 379 | int sst_hsw_stream_set_volume(struct sst_hsw *hsw, |
385 | struct sst_hsw_stream *stream, u32 stage_id, u32 channel, u32 volume); | 380 | struct sst_hsw_stream *stream, u32 stage_id, u32 channel, u32 volume); |
386 | int sst_hsw_stream_get_volume(struct sst_hsw *hsw, | 381 | int sst_hsw_stream_get_volume(struct sst_hsw *hsw, |
387 | struct sst_hsw_stream *stream, u32 stage_id, u32 channel, u32 *volume); | 382 | struct sst_hsw_stream *stream, u32 stage_id, u32 channel, u32 *volume); |
388 | 383 | ||
389 | int sst_hsw_stream_set_volume_curve(struct sst_hsw *hsw, | ||
390 | struct sst_hsw_stream *stream, u64 curve_duration, | ||
391 | enum sst_hsw_volume_curve curve); | ||
392 | |||
393 | /* Global Mixer Controls - */ | 384 | /* Global Mixer Controls - */ |
394 | int sst_hsw_mixer_mute(struct sst_hsw *hsw, u32 stage_id, u32 channel); | ||
395 | int sst_hsw_mixer_unmute(struct sst_hsw *hsw, u32 stage_id, u32 channel); | ||
396 | |||
397 | int sst_hsw_mixer_set_volume(struct sst_hsw *hsw, u32 stage_id, u32 channel, | 385 | int sst_hsw_mixer_set_volume(struct sst_hsw *hsw, u32 stage_id, u32 channel, |
398 | u32 volume); | 386 | u32 volume); |
399 | int sst_hsw_mixer_get_volume(struct sst_hsw *hsw, u32 stage_id, u32 channel, | 387 | int sst_hsw_mixer_get_volume(struct sst_hsw *hsw, u32 stage_id, u32 channel, |
400 | u32 *volume); | 388 | u32 *volume); |
401 | 389 | ||
402 | int sst_hsw_mixer_set_volume_curve(struct sst_hsw *hsw, | ||
403 | u64 curve_duration, enum sst_hsw_volume_curve curve); | ||
404 | |||
405 | /* Stream API */ | 390 | /* Stream API */ |
406 | struct sst_hsw_stream *sst_hsw_stream_new(struct sst_hsw *hsw, int id, | 391 | struct sst_hsw_stream *sst_hsw_stream_new(struct sst_hsw *hsw, int id, |
407 | u32 (*get_write_position)(struct sst_hsw_stream *stream, void *data), | 392 | u32 (*get_write_position)(struct sst_hsw_stream *stream, void *data), |
@@ -440,18 +425,6 @@ int sst_hsw_stream_set_pmemory_info(struct sst_hsw *hsw, | |||
440 | struct sst_hsw_stream *stream, u32 offset, u32 size); | 425 | struct sst_hsw_stream *stream, u32 offset, u32 size); |
441 | int sst_hsw_stream_set_smemory_info(struct sst_hsw *hsw, | 426 | int sst_hsw_stream_set_smemory_info(struct sst_hsw *hsw, |
442 | struct sst_hsw_stream *stream, u32 offset, u32 size); | 427 | struct sst_hsw_stream *stream, u32 offset, u32 size); |
443 | int sst_hsw_stream_get_hw_id(struct sst_hsw *hsw, | ||
444 | struct sst_hsw_stream *stream); | ||
445 | int sst_hsw_stream_get_mixer_id(struct sst_hsw *hsw, | ||
446 | struct sst_hsw_stream *stream); | ||
447 | u32 sst_hsw_stream_get_read_reg(struct sst_hsw *hsw, | ||
448 | struct sst_hsw_stream *stream); | ||
449 | u32 sst_hsw_stream_get_pointer_reg(struct sst_hsw *hsw, | ||
450 | struct sst_hsw_stream *stream); | ||
451 | u32 sst_hsw_stream_get_peak_reg(struct sst_hsw *hsw, | ||
452 | struct sst_hsw_stream *stream, u32 channel); | ||
453 | u32 sst_hsw_stream_get_vol_reg(struct sst_hsw *hsw, | ||
454 | struct sst_hsw_stream *stream, u32 channel); | ||
455 | int sst_hsw_mixer_get_info(struct sst_hsw *hsw); | 428 | int sst_hsw_mixer_get_info(struct sst_hsw *hsw); |
456 | 429 | ||
457 | /* Stream ALSA trigger operations */ | 430 | /* Stream ALSA trigger operations */ |
@@ -466,8 +439,6 @@ int sst_hsw_stream_get_read_pos(struct sst_hsw *hsw, | |||
466 | struct sst_hsw_stream *stream, u32 *position); | 439 | struct sst_hsw_stream *stream, u32 *position); |
467 | int sst_hsw_stream_get_write_pos(struct sst_hsw *hsw, | 440 | int sst_hsw_stream_get_write_pos(struct sst_hsw *hsw, |
468 | struct sst_hsw_stream *stream, u32 *position); | 441 | struct sst_hsw_stream *stream, u32 *position); |
469 | int sst_hsw_stream_set_write_position(struct sst_hsw *hsw, | ||
470 | struct sst_hsw_stream *stream, u32 stage_id, u32 position); | ||
471 | u32 sst_hsw_get_dsp_position(struct sst_hsw *hsw, | 442 | u32 sst_hsw_get_dsp_position(struct sst_hsw *hsw, |
472 | struct sst_hsw_stream *stream); | 443 | struct sst_hsw_stream *stream); |
473 | u64 sst_hsw_get_dsp_presentation_position(struct sst_hsw *hsw, | 444 | u64 sst_hsw_get_dsp_presentation_position(struct sst_hsw *hsw, |
@@ -481,8 +452,6 @@ int sst_hsw_device_set_config(struct sst_hsw *hsw, | |||
481 | /* DX Config */ | 452 | /* DX Config */ |
482 | int sst_hsw_dx_set_state(struct sst_hsw *hsw, | 453 | int sst_hsw_dx_set_state(struct sst_hsw *hsw, |
483 | enum sst_hsw_dx_state state, struct sst_hsw_ipc_dx_reply *dx); | 454 | enum sst_hsw_dx_state state, struct sst_hsw_ipc_dx_reply *dx); |
484 | int sst_hsw_dx_get_state(struct sst_hsw *hsw, u32 item, | ||
485 | u32 *offset, u32 *size, u32 *source); | ||
486 | 455 | ||
487 | /* init */ | 456 | /* init */ |
488 | int sst_hsw_dsp_init(struct device *dev, struct sst_pdata *pdata); | 457 | int sst_hsw_dsp_init(struct device *dev, struct sst_pdata *pdata); |
diff --git a/sound/soc/intel/sst-haswell-pcm.c b/sound/soc/intel/sst-haswell-pcm.c index 619525200705..78fa01be57f2 100644 --- a/sound/soc/intel/sst-haswell-pcm.c +++ b/sound/soc/intel/sst-haswell-pcm.c | |||
@@ -78,7 +78,6 @@ static const u32 volume_map[] = { | |||
78 | #define HSW_PCM_DAI_ID_OFFLOAD0 1 | 78 | #define HSW_PCM_DAI_ID_OFFLOAD0 1 |
79 | #define HSW_PCM_DAI_ID_OFFLOAD1 2 | 79 | #define HSW_PCM_DAI_ID_OFFLOAD1 2 |
80 | #define HSW_PCM_DAI_ID_LOOPBACK 3 | 80 | #define HSW_PCM_DAI_ID_LOOPBACK 3 |
81 | #define HSW_PCM_DAI_ID_CAPTURE 4 | ||
82 | 81 | ||
83 | 82 | ||
84 | static const struct snd_pcm_hardware hsw_pcm_hardware = { | 83 | static const struct snd_pcm_hardware hsw_pcm_hardware = { |
@@ -99,6 +98,7 @@ static const struct snd_pcm_hardware hsw_pcm_hardware = { | |||
99 | 98 | ||
100 | struct hsw_pcm_module_map { | 99 | struct hsw_pcm_module_map { |
101 | int dai_id; | 100 | int dai_id; |
101 | int stream; | ||
102 | enum sst_hsw_module_id mod_id; | 102 | enum sst_hsw_module_id mod_id; |
103 | }; | 103 | }; |
104 | 104 | ||
@@ -119,8 +119,9 @@ struct hsw_pcm_data { | |||
119 | }; | 119 | }; |
120 | 120 | ||
121 | enum hsw_pm_state { | 121 | enum hsw_pm_state { |
122 | HSW_PM_STATE_D3 = 0, | 122 | HSW_PM_STATE_D0 = 0, |
123 | HSW_PM_STATE_D0 = 1, | 123 | HSW_PM_STATE_RTD3 = 1, |
124 | HSW_PM_STATE_D3 = 2, | ||
124 | }; | 125 | }; |
125 | 126 | ||
126 | /* private data for the driver */ | 127 | /* private data for the driver */ |
@@ -135,7 +136,17 @@ struct hsw_priv_data { | |||
135 | struct snd_dma_buffer dmab[HSW_PCM_COUNT][2]; | 136 | struct snd_dma_buffer dmab[HSW_PCM_COUNT][2]; |
136 | 137 | ||
137 | /* DAI data */ | 138 | /* DAI data */ |
138 | struct hsw_pcm_data pcm[HSW_PCM_COUNT]; | 139 | struct hsw_pcm_data pcm[HSW_PCM_COUNT][2]; |
140 | }; | ||
141 | |||
142 | |||
143 | /* static mappings between PCMs and modules - may be dynamic in future */ | ||
144 | static struct hsw_pcm_module_map mod_map[] = { | ||
145 | {HSW_PCM_DAI_ID_SYSTEM, 0, SST_HSW_MODULE_PCM_SYSTEM}, | ||
146 | {HSW_PCM_DAI_ID_OFFLOAD0, 0, SST_HSW_MODULE_PCM}, | ||
147 | {HSW_PCM_DAI_ID_OFFLOAD1, 0, SST_HSW_MODULE_PCM}, | ||
148 | {HSW_PCM_DAI_ID_LOOPBACK, 1, SST_HSW_MODULE_PCM_REFERENCE}, | ||
149 | {HSW_PCM_DAI_ID_SYSTEM, 1, SST_HSW_MODULE_PCM_CAPTURE}, | ||
139 | }; | 150 | }; |
140 | 151 | ||
141 | static u32 hsw_notify_pointer(struct sst_hsw_stream *stream, void *data); | 152 | static u32 hsw_notify_pointer(struct sst_hsw_stream *stream, void *data); |
@@ -168,9 +179,14 @@ static int hsw_stream_volume_put(struct snd_kcontrol *kcontrol, | |||
168 | (struct soc_mixer_control *)kcontrol->private_value; | 179 | (struct soc_mixer_control *)kcontrol->private_value; |
169 | struct hsw_priv_data *pdata = | 180 | struct hsw_priv_data *pdata = |
170 | snd_soc_platform_get_drvdata(platform); | 181 | snd_soc_platform_get_drvdata(platform); |
171 | struct hsw_pcm_data *pcm_data = &pdata->pcm[mc->reg]; | 182 | struct hsw_pcm_data *pcm_data; |
172 | struct sst_hsw *hsw = pdata->hsw; | 183 | struct sst_hsw *hsw = pdata->hsw; |
173 | u32 volume; | 184 | u32 volume; |
185 | int dai, stream; | ||
186 | |||
187 | dai = mod_map[mc->reg].dai_id; | ||
188 | stream = mod_map[mc->reg].stream; | ||
189 | pcm_data = &pdata->pcm[dai][stream]; | ||
174 | 190 | ||
175 | mutex_lock(&pcm_data->mutex); | 191 | mutex_lock(&pcm_data->mutex); |
176 | pm_runtime_get_sync(pdata->dev); | 192 | pm_runtime_get_sync(pdata->dev); |
@@ -212,9 +228,14 @@ static int hsw_stream_volume_get(struct snd_kcontrol *kcontrol, | |||
212 | (struct soc_mixer_control *)kcontrol->private_value; | 228 | (struct soc_mixer_control *)kcontrol->private_value; |
213 | struct hsw_priv_data *pdata = | 229 | struct hsw_priv_data *pdata = |
214 | snd_soc_platform_get_drvdata(platform); | 230 | snd_soc_platform_get_drvdata(platform); |
215 | struct hsw_pcm_data *pcm_data = &pdata->pcm[mc->reg]; | 231 | struct hsw_pcm_data *pcm_data; |
216 | struct sst_hsw *hsw = pdata->hsw; | 232 | struct sst_hsw *hsw = pdata->hsw; |
217 | u32 volume; | 233 | u32 volume; |
234 | int dai, stream; | ||
235 | |||
236 | dai = mod_map[mc->reg].dai_id; | ||
237 | stream = mod_map[mc->reg].stream; | ||
238 | pcm_data = &pdata->pcm[dai][stream]; | ||
218 | 239 | ||
219 | mutex_lock(&pcm_data->mutex); | 240 | mutex_lock(&pcm_data->mutex); |
220 | pm_runtime_get_sync(pdata->dev); | 241 | pm_runtime_get_sync(pdata->dev); |
@@ -309,7 +330,7 @@ static const struct snd_kcontrol_new hsw_volume_controls[] = { | |||
309 | ARRAY_SIZE(volume_map) - 1, 0, | 330 | ARRAY_SIZE(volume_map) - 1, 0, |
310 | hsw_stream_volume_get, hsw_stream_volume_put, hsw_vol_tlv), | 331 | hsw_stream_volume_get, hsw_stream_volume_put, hsw_vol_tlv), |
311 | /* Mic Capture volume */ | 332 | /* Mic Capture volume */ |
312 | SOC_DOUBLE_EXT_TLV("Mic Capture Volume", 0, 0, 8, | 333 | SOC_DOUBLE_EXT_TLV("Mic Capture Volume", 4, 0, 8, |
313 | ARRAY_SIZE(volume_map) - 1, 0, | 334 | ARRAY_SIZE(volume_map) - 1, 0, |
314 | hsw_stream_volume_get, hsw_stream_volume_put, hsw_vol_tlv), | 335 | hsw_stream_volume_get, hsw_stream_volume_put, hsw_vol_tlv), |
315 | }; | 336 | }; |
@@ -353,7 +374,7 @@ static int hsw_pcm_hw_params(struct snd_pcm_substream *substream, | |||
353 | struct snd_pcm_runtime *runtime = substream->runtime; | 374 | struct snd_pcm_runtime *runtime = substream->runtime; |
354 | struct hsw_priv_data *pdata = | 375 | struct hsw_priv_data *pdata = |
355 | snd_soc_platform_get_drvdata(rtd->platform); | 376 | snd_soc_platform_get_drvdata(rtd->platform); |
356 | struct hsw_pcm_data *pcm_data = snd_soc_pcm_get_drvdata(rtd); | 377 | struct hsw_pcm_data *pcm_data; |
357 | struct sst_hsw *hsw = pdata->hsw; | 378 | struct sst_hsw *hsw = pdata->hsw; |
358 | struct sst_module *module_data; | 379 | struct sst_module *module_data; |
359 | struct sst_dsp *dsp; | 380 | struct sst_dsp *dsp; |
@@ -362,7 +383,10 @@ static int hsw_pcm_hw_params(struct snd_pcm_substream *substream, | |||
362 | enum sst_hsw_stream_path_id path_id; | 383 | enum sst_hsw_stream_path_id path_id; |
363 | u32 rate, bits, map, pages, module_id; | 384 | u32 rate, bits, map, pages, module_id; |
364 | u8 channels; | 385 | u8 channels; |
365 | int ret; | 386 | int ret, dai; |
387 | |||
388 | dai = mod_map[rtd->cpu_dai->id].dai_id; | ||
389 | pcm_data = &pdata->pcm[dai][substream->stream]; | ||
366 | 390 | ||
367 | /* check if we are being called a subsequent time */ | 391 | /* check if we are being called a subsequent time */ |
368 | if (pcm_data->allocated) { | 392 | if (pcm_data->allocated) { |
@@ -552,8 +576,12 @@ static int hsw_pcm_trigger(struct snd_pcm_substream *substream, int cmd) | |||
552 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 576 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
553 | struct hsw_priv_data *pdata = | 577 | struct hsw_priv_data *pdata = |
554 | snd_soc_platform_get_drvdata(rtd->platform); | 578 | snd_soc_platform_get_drvdata(rtd->platform); |
555 | struct hsw_pcm_data *pcm_data = snd_soc_pcm_get_drvdata(rtd); | 579 | struct hsw_pcm_data *pcm_data; |
556 | struct sst_hsw *hsw = pdata->hsw; | 580 | struct sst_hsw *hsw = pdata->hsw; |
581 | int dai; | ||
582 | |||
583 | dai = mod_map[rtd->cpu_dai->id].dai_id; | ||
584 | pcm_data = &pdata->pcm[dai][substream->stream]; | ||
557 | 585 | ||
558 | switch (cmd) { | 586 | switch (cmd) { |
559 | case SNDRV_PCM_TRIGGER_START: | 587 | case SNDRV_PCM_TRIGGER_START: |
@@ -597,11 +625,16 @@ static snd_pcm_uframes_t hsw_pcm_pointer(struct snd_pcm_substream *substream) | |||
597 | struct snd_pcm_runtime *runtime = substream->runtime; | 625 | struct snd_pcm_runtime *runtime = substream->runtime; |
598 | struct hsw_priv_data *pdata = | 626 | struct hsw_priv_data *pdata = |
599 | snd_soc_platform_get_drvdata(rtd->platform); | 627 | snd_soc_platform_get_drvdata(rtd->platform); |
600 | struct hsw_pcm_data *pcm_data = snd_soc_pcm_get_drvdata(rtd); | 628 | struct hsw_pcm_data *pcm_data; |
601 | struct sst_hsw *hsw = pdata->hsw; | 629 | struct sst_hsw *hsw = pdata->hsw; |
602 | snd_pcm_uframes_t offset; | 630 | snd_pcm_uframes_t offset; |
603 | uint64_t ppos; | 631 | uint64_t ppos; |
604 | u32 position = sst_hsw_get_dsp_position(hsw, pcm_data->stream); | 632 | u32 position; |
633 | int dai; | ||
634 | |||
635 | dai = mod_map[rtd->cpu_dai->id].dai_id; | ||
636 | pcm_data = &pdata->pcm[dai][substream->stream]; | ||
637 | position = sst_hsw_get_dsp_position(hsw, pcm_data->stream); | ||
605 | 638 | ||
606 | offset = bytes_to_frames(runtime, position); | 639 | offset = bytes_to_frames(runtime, position); |
607 | ppos = sst_hsw_get_dsp_presentation_position(hsw, pcm_data->stream); | 640 | ppos = sst_hsw_get_dsp_presentation_position(hsw, pcm_data->stream); |
@@ -618,8 +651,10 @@ static int hsw_pcm_open(struct snd_pcm_substream *substream) | |||
618 | snd_soc_platform_get_drvdata(rtd->platform); | 651 | snd_soc_platform_get_drvdata(rtd->platform); |
619 | struct hsw_pcm_data *pcm_data; | 652 | struct hsw_pcm_data *pcm_data; |
620 | struct sst_hsw *hsw = pdata->hsw; | 653 | struct sst_hsw *hsw = pdata->hsw; |
654 | int dai; | ||
621 | 655 | ||
622 | pcm_data = &pdata->pcm[rtd->cpu_dai->id]; | 656 | dai = mod_map[rtd->cpu_dai->id].dai_id; |
657 | pcm_data = &pdata->pcm[dai][substream->stream]; | ||
623 | 658 | ||
624 | mutex_lock(&pcm_data->mutex); | 659 | mutex_lock(&pcm_data->mutex); |
625 | pm_runtime_get_sync(pdata->dev); | 660 | pm_runtime_get_sync(pdata->dev); |
@@ -648,9 +683,12 @@ static int hsw_pcm_close(struct snd_pcm_substream *substream) | |||
648 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 683 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
649 | struct hsw_priv_data *pdata = | 684 | struct hsw_priv_data *pdata = |
650 | snd_soc_platform_get_drvdata(rtd->platform); | 685 | snd_soc_platform_get_drvdata(rtd->platform); |
651 | struct hsw_pcm_data *pcm_data = snd_soc_pcm_get_drvdata(rtd); | 686 | struct hsw_pcm_data *pcm_data; |
652 | struct sst_hsw *hsw = pdata->hsw; | 687 | struct sst_hsw *hsw = pdata->hsw; |
653 | int ret; | 688 | int ret, dai; |
689 | |||
690 | dai = mod_map[rtd->cpu_dai->id].dai_id; | ||
691 | pcm_data = &pdata->pcm[dai][substream->stream]; | ||
654 | 692 | ||
655 | mutex_lock(&pcm_data->mutex); | 693 | mutex_lock(&pcm_data->mutex); |
656 | ret = sst_hsw_stream_reset(hsw, pcm_data->stream); | 694 | ret = sst_hsw_stream_reset(hsw, pcm_data->stream); |
@@ -685,15 +723,6 @@ static struct snd_pcm_ops hsw_pcm_ops = { | |||
685 | .page = snd_pcm_sgbuf_ops_page, | 723 | .page = snd_pcm_sgbuf_ops_page, |
686 | }; | 724 | }; |
687 | 725 | ||
688 | /* static mappings between PCMs and modules - may be dynamic in future */ | ||
689 | static struct hsw_pcm_module_map mod_map[] = { | ||
690 | {HSW_PCM_DAI_ID_SYSTEM, SST_HSW_MODULE_PCM_SYSTEM}, | ||
691 | {HSW_PCM_DAI_ID_OFFLOAD0, SST_HSW_MODULE_PCM}, | ||
692 | {HSW_PCM_DAI_ID_OFFLOAD1, SST_HSW_MODULE_PCM}, | ||
693 | {HSW_PCM_DAI_ID_LOOPBACK, SST_HSW_MODULE_PCM_REFERENCE}, | ||
694 | {HSW_PCM_DAI_ID_CAPTURE, SST_HSW_MODULE_PCM_CAPTURE}, | ||
695 | }; | ||
696 | |||
697 | static int hsw_pcm_create_modules(struct hsw_priv_data *pdata) | 726 | static int hsw_pcm_create_modules(struct hsw_priv_data *pdata) |
698 | { | 727 | { |
699 | struct sst_hsw *hsw = pdata->hsw; | 728 | struct sst_hsw *hsw = pdata->hsw; |
@@ -701,7 +730,7 @@ static int hsw_pcm_create_modules(struct hsw_priv_data *pdata) | |||
701 | int i; | 730 | int i; |
702 | 731 | ||
703 | for (i = 0; i < ARRAY_SIZE(mod_map); i++) { | 732 | for (i = 0; i < ARRAY_SIZE(mod_map); i++) { |
704 | pcm_data = &pdata->pcm[i]; | 733 | pcm_data = &pdata->pcm[mod_map[i].dai_id][mod_map[i].stream]; |
705 | 734 | ||
706 | /* create new runtime module, use same offset if recreated */ | 735 | /* create new runtime module, use same offset if recreated */ |
707 | pcm_data->runtime = sst_hsw_runtime_module_create(hsw, | 736 | pcm_data->runtime = sst_hsw_runtime_module_create(hsw, |
@@ -716,7 +745,7 @@ static int hsw_pcm_create_modules(struct hsw_priv_data *pdata) | |||
716 | 745 | ||
717 | err: | 746 | err: |
718 | for (--i; i >= 0; i--) { | 747 | for (--i; i >= 0; i--) { |
719 | pcm_data = &pdata->pcm[i]; | 748 | pcm_data = &pdata->pcm[mod_map[i].dai_id][mod_map[i].stream]; |
720 | sst_hsw_runtime_module_free(pcm_data->runtime); | 749 | sst_hsw_runtime_module_free(pcm_data->runtime); |
721 | } | 750 | } |
722 | 751 | ||
@@ -729,17 +758,12 @@ static void hsw_pcm_free_modules(struct hsw_priv_data *pdata) | |||
729 | int i; | 758 | int i; |
730 | 759 | ||
731 | for (i = 0; i < ARRAY_SIZE(mod_map); i++) { | 760 | for (i = 0; i < ARRAY_SIZE(mod_map); i++) { |
732 | pcm_data = &pdata->pcm[i]; | 761 | pcm_data = &pdata->pcm[mod_map[i].dai_id][mod_map[i].stream]; |
733 | 762 | ||
734 | sst_hsw_runtime_module_free(pcm_data->runtime); | 763 | sst_hsw_runtime_module_free(pcm_data->runtime); |
735 | } | 764 | } |
736 | } | 765 | } |
737 | 766 | ||
738 | static void hsw_pcm_free(struct snd_pcm *pcm) | ||
739 | { | ||
740 | snd_pcm_lib_preallocate_free_for_all(pcm); | ||
741 | } | ||
742 | |||
743 | static int hsw_pcm_new(struct snd_soc_pcm_runtime *rtd) | 767 | static int hsw_pcm_new(struct snd_soc_pcm_runtime *rtd) |
744 | { | 768 | { |
745 | struct snd_pcm *pcm = rtd->pcm; | 769 | struct snd_pcm *pcm = rtd->pcm; |
@@ -762,7 +786,10 @@ static int hsw_pcm_new(struct snd_soc_pcm_runtime *rtd) | |||
762 | return ret; | 786 | return ret; |
763 | } | 787 | } |
764 | } | 788 | } |
765 | priv_data->pcm[rtd->cpu_dai->id].hsw_pcm = pcm; | 789 | if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) |
790 | priv_data->pcm[rtd->cpu_dai->id][SNDRV_PCM_STREAM_PLAYBACK].hsw_pcm = pcm; | ||
791 | if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) | ||
792 | priv_data->pcm[rtd->cpu_dai->id][SNDRV_PCM_STREAM_CAPTURE].hsw_pcm = pcm; | ||
766 | 793 | ||
767 | return ret; | 794 | return ret; |
768 | } | 795 | } |
@@ -871,10 +898,9 @@ static int hsw_pcm_probe(struct snd_soc_platform *platform) | |||
871 | /* allocate DSP buffer page tables */ | 898 | /* allocate DSP buffer page tables */ |
872 | for (i = 0; i < ARRAY_SIZE(hsw_dais); i++) { | 899 | for (i = 0; i < ARRAY_SIZE(hsw_dais); i++) { |
873 | 900 | ||
874 | mutex_init(&priv_data->pcm[i].mutex); | ||
875 | |||
876 | /* playback */ | 901 | /* playback */ |
877 | if (hsw_dais[i].playback.channels_min) { | 902 | if (hsw_dais[i].playback.channels_min) { |
903 | mutex_init(&priv_data->pcm[i][SNDRV_PCM_STREAM_PLAYBACK].mutex); | ||
878 | ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, dma_dev, | 904 | ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, dma_dev, |
879 | PAGE_SIZE, &priv_data->dmab[i][0]); | 905 | PAGE_SIZE, &priv_data->dmab[i][0]); |
880 | if (ret < 0) | 906 | if (ret < 0) |
@@ -883,6 +909,7 @@ static int hsw_pcm_probe(struct snd_soc_platform *platform) | |||
883 | 909 | ||
884 | /* capture */ | 910 | /* capture */ |
885 | if (hsw_dais[i].capture.channels_min) { | 911 | if (hsw_dais[i].capture.channels_min) { |
912 | mutex_init(&priv_data->pcm[i][SNDRV_PCM_STREAM_CAPTURE].mutex); | ||
886 | ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, dma_dev, | 913 | ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, dma_dev, |
887 | PAGE_SIZE, &priv_data->dmab[i][1]); | 914 | PAGE_SIZE, &priv_data->dmab[i][1]); |
888 | if (ret < 0) | 915 | if (ret < 0) |
@@ -936,7 +963,6 @@ static struct snd_soc_platform_driver hsw_soc_platform = { | |||
936 | .remove = hsw_pcm_remove, | 963 | .remove = hsw_pcm_remove, |
937 | .ops = &hsw_pcm_ops, | 964 | .ops = &hsw_pcm_ops, |
938 | .pcm_new = hsw_pcm_new, | 965 | .pcm_new = hsw_pcm_new, |
939 | .pcm_free = hsw_pcm_free, | ||
940 | }; | 966 | }; |
941 | 967 | ||
942 | static const struct snd_soc_component_driver hsw_dai_component = { | 968 | static const struct snd_soc_component_driver hsw_dai_component = { |
@@ -1010,12 +1036,12 @@ static int hsw_pcm_runtime_suspend(struct device *dev) | |||
1010 | struct hsw_priv_data *pdata = dev_get_drvdata(dev); | 1036 | struct hsw_priv_data *pdata = dev_get_drvdata(dev); |
1011 | struct sst_hsw *hsw = pdata->hsw; | 1037 | struct sst_hsw *hsw = pdata->hsw; |
1012 | 1038 | ||
1013 | if (pdata->pm_state == HSW_PM_STATE_D3) | 1039 | if (pdata->pm_state >= HSW_PM_STATE_RTD3) |
1014 | return 0; | 1040 | return 0; |
1015 | 1041 | ||
1016 | sst_hsw_dsp_runtime_suspend(hsw); | 1042 | sst_hsw_dsp_runtime_suspend(hsw); |
1017 | sst_hsw_dsp_runtime_sleep(hsw); | 1043 | sst_hsw_dsp_runtime_sleep(hsw); |
1018 | pdata->pm_state = HSW_PM_STATE_D3; | 1044 | pdata->pm_state = HSW_PM_STATE_RTD3; |
1019 | 1045 | ||
1020 | return 0; | 1046 | return 0; |
1021 | } | 1047 | } |
@@ -1026,7 +1052,7 @@ static int hsw_pcm_runtime_resume(struct device *dev) | |||
1026 | struct sst_hsw *hsw = pdata->hsw; | 1052 | struct sst_hsw *hsw = pdata->hsw; |
1027 | int ret; | 1053 | int ret; |
1028 | 1054 | ||
1029 | if (pdata->pm_state == HSW_PM_STATE_D0) | 1055 | if (pdata->pm_state != HSW_PM_STATE_RTD3) |
1030 | return 0; | 1056 | return 0; |
1031 | 1057 | ||
1032 | ret = sst_hsw_dsp_load(hsw); | 1058 | ret = sst_hsw_dsp_load(hsw); |
@@ -1066,7 +1092,7 @@ static void hsw_pcm_complete(struct device *dev) | |||
1066 | struct hsw_pcm_data *pcm_data; | 1092 | struct hsw_pcm_data *pcm_data; |
1067 | int i, err; | 1093 | int i, err; |
1068 | 1094 | ||
1069 | if (pdata->pm_state == HSW_PM_STATE_D0) | 1095 | if (pdata->pm_state != HSW_PM_STATE_D3) |
1070 | return; | 1096 | return; |
1071 | 1097 | ||
1072 | err = sst_hsw_dsp_load(hsw); | 1098 | err = sst_hsw_dsp_load(hsw); |
@@ -1081,8 +1107,8 @@ static void hsw_pcm_complete(struct device *dev) | |||
1081 | return; | 1107 | return; |
1082 | } | 1108 | } |
1083 | 1109 | ||
1084 | for (i = 0; i < HSW_PCM_DAI_ID_CAPTURE + 1; i++) { | 1110 | for (i = 0; i < ARRAY_SIZE(mod_map); i++) { |
1085 | pcm_data = &pdata->pcm[i]; | 1111 | pcm_data = &pdata->pcm[mod_map[i].dai_id][mod_map[i].stream]; |
1086 | 1112 | ||
1087 | if (!pcm_data->substream) | 1113 | if (!pcm_data->substream) |
1088 | continue; | 1114 | continue; |
@@ -1114,41 +1140,42 @@ static int hsw_pcm_prepare(struct device *dev) | |||
1114 | 1140 | ||
1115 | if (pdata->pm_state == HSW_PM_STATE_D3) | 1141 | if (pdata->pm_state == HSW_PM_STATE_D3) |
1116 | return 0; | 1142 | return 0; |
1117 | /* suspend all active streams */ | 1143 | else if (pdata->pm_state == HSW_PM_STATE_D0) { |
1118 | for (i = 0; i < HSW_PCM_DAI_ID_CAPTURE + 1; i++) { | 1144 | /* suspend all active streams */ |
1119 | pcm_data = &pdata->pcm[i]; | 1145 | for (i = 0; i < ARRAY_SIZE(mod_map); i++) { |
1146 | pcm_data = &pdata->pcm[mod_map[i].dai_id][mod_map[i].stream]; | ||
1147 | |||
1148 | if (!pcm_data->substream) | ||
1149 | continue; | ||
1150 | dev_dbg(dev, "suspending pcm %d\n", i); | ||
1151 | snd_pcm_suspend_all(pcm_data->hsw_pcm); | ||
1152 | |||
1153 | /* We need to wait until the DSP FW stops the streams */ | ||
1154 | msleep(2); | ||
1155 | } | ||
1120 | 1156 | ||
1121 | if (!pcm_data->substream) | 1157 | /* preserve persistent memory */ |
1122 | continue; | 1158 | for (i = 0; i < ARRAY_SIZE(mod_map); i++) { |
1123 | dev_dbg(dev, "suspending pcm %d\n", i); | 1159 | pcm_data = &pdata->pcm[mod_map[i].dai_id][mod_map[i].stream]; |
1124 | snd_pcm_suspend_all(pcm_data->hsw_pcm); | 1160 | |
1161 | if (!pcm_data->substream) | ||
1162 | continue; | ||
1125 | 1163 | ||
1126 | /* We need to wait until the DSP FW stops the streams */ | 1164 | dev_dbg(dev, "saving context pcm %d\n", i); |
1127 | msleep(2); | 1165 | err = sst_module_runtime_save(pcm_data->runtime, |
1166 | &pcm_data->context); | ||
1167 | if (err < 0) | ||
1168 | dev_err(dev, "failed to save context for PCM %d\n", i); | ||
1169 | } | ||
1170 | /* enter D3 state and stall */ | ||
1171 | sst_hsw_dsp_runtime_suspend(hsw); | ||
1172 | /* put the DSP to sleep */ | ||
1173 | sst_hsw_dsp_runtime_sleep(hsw); | ||
1128 | } | 1174 | } |
1129 | 1175 | ||
1130 | snd_soc_suspend(pdata->soc_card->dev); | 1176 | snd_soc_suspend(pdata->soc_card->dev); |
1131 | snd_soc_poweroff(pdata->soc_card->dev); | 1177 | snd_soc_poweroff(pdata->soc_card->dev); |
1132 | 1178 | ||
1133 | /* enter D3 state and stall */ | ||
1134 | sst_hsw_dsp_runtime_suspend(hsw); | ||
1135 | |||
1136 | /* preserve persistent memory */ | ||
1137 | for (i = 0; i < HSW_PCM_DAI_ID_CAPTURE + 1; i++) { | ||
1138 | pcm_data = &pdata->pcm[i]; | ||
1139 | |||
1140 | if (!pcm_data->substream) | ||
1141 | continue; | ||
1142 | |||
1143 | dev_dbg(dev, "saving context pcm %d\n", i); | ||
1144 | err = sst_module_runtime_save(pcm_data->runtime, | ||
1145 | &pcm_data->context); | ||
1146 | if (err < 0) | ||
1147 | dev_err(dev, "failed to save context for PCM %d\n", i); | ||
1148 | } | ||
1149 | |||
1150 | /* put the DSP to sleep */ | ||
1151 | sst_hsw_dsp_runtime_sleep(hsw); | ||
1152 | pdata->pm_state = HSW_PM_STATE_D3; | 1179 | pdata->pm_state = HSW_PM_STATE_D3; |
1153 | 1180 | ||
1154 | return 0; | 1181 | return 0; |
diff --git a/sound/soc/intel/sst-mfld-platform-pcm.c b/sound/soc/intel/sst-mfld-platform-pcm.c index a1a8d9d91539..7523cbef8780 100644 --- a/sound/soc/intel/sst-mfld-platform-pcm.c +++ b/sound/soc/intel/sst-mfld-platform-pcm.c | |||
@@ -643,12 +643,6 @@ static struct snd_pcm_ops sst_platform_ops = { | |||
643 | .pointer = sst_platform_pcm_pointer, | 643 | .pointer = sst_platform_pcm_pointer, |
644 | }; | 644 | }; |
645 | 645 | ||
646 | static void sst_pcm_free(struct snd_pcm *pcm) | ||
647 | { | ||
648 | dev_dbg(pcm->dev, "sst_pcm_free called\n"); | ||
649 | snd_pcm_lib_preallocate_free_for_all(pcm); | ||
650 | } | ||
651 | |||
652 | static int sst_pcm_new(struct snd_soc_pcm_runtime *rtd) | 646 | static int sst_pcm_new(struct snd_soc_pcm_runtime *rtd) |
653 | { | 647 | { |
654 | struct snd_soc_dai *dai = rtd->cpu_dai; | 648 | struct snd_soc_dai *dai = rtd->cpu_dai; |
@@ -679,7 +673,6 @@ static struct snd_soc_platform_driver sst_soc_platform_drv = { | |||
679 | .ops = &sst_platform_ops, | 673 | .ops = &sst_platform_ops, |
680 | .compr_ops = &sst_platform_compr_ops, | 674 | .compr_ops = &sst_platform_compr_ops, |
681 | .pcm_new = sst_pcm_new, | 675 | .pcm_new = sst_pcm_new, |
682 | .pcm_free = sst_pcm_free, | ||
683 | }; | 676 | }; |
684 | 677 | ||
685 | static const struct snd_soc_component_driver sst_component = { | 678 | static const struct snd_soc_component_driver sst_component = { |
diff --git a/sound/soc/intel/sst/sst.h b/sound/soc/intel/sst/sst.h index 7f4bbfcbc6f5..562bc483d6b7 100644 --- a/sound/soc/intel/sst/sst.h +++ b/sound/soc/intel/sst/sst.h | |||
@@ -58,6 +58,7 @@ enum sst_algo_ops { | |||
58 | #define SST_BLOCK_TIMEOUT 1000 | 58 | #define SST_BLOCK_TIMEOUT 1000 |
59 | 59 | ||
60 | #define FW_SIGNATURE_SIZE 4 | 60 | #define FW_SIGNATURE_SIZE 4 |
61 | #define FW_NAME_SIZE 32 | ||
61 | 62 | ||
62 | /* stream states */ | 63 | /* stream states */ |
63 | enum sst_stream_states { | 64 | enum sst_stream_states { |
@@ -426,7 +427,7 @@ struct intel_sst_drv { | |||
426 | * Holder for firmware name. Due to async call it needs to be | 427 | * Holder for firmware name. Due to async call it needs to be |
427 | * persistent till worker thread gets called | 428 | * persistent till worker thread gets called |
428 | */ | 429 | */ |
429 | char firmware_name[20]; | 430 | char firmware_name[FW_NAME_SIZE]; |
430 | }; | 431 | }; |
431 | 432 | ||
432 | /* misc definitions */ | 433 | /* misc definitions */ |
diff --git a/sound/soc/intel/sst/sst_acpi.c b/sound/soc/intel/sst/sst_acpi.c index 3abc29e8a928..b782dfdcdbba 100644 --- a/sound/soc/intel/sst/sst_acpi.c +++ b/sound/soc/intel/sst/sst_acpi.c | |||
@@ -47,7 +47,7 @@ struct sst_machines { | |||
47 | char board[32]; | 47 | char board[32]; |
48 | char machine[32]; | 48 | char machine[32]; |
49 | void (*machine_quirk)(void); | 49 | void (*machine_quirk)(void); |
50 | char firmware[32]; | 50 | char firmware[FW_NAME_SIZE]; |
51 | struct sst_platform_info *pdata; | 51 | struct sst_platform_info *pdata; |
52 | 52 | ||
53 | }; | 53 | }; |
@@ -245,7 +245,7 @@ static struct sst_machines *sst_acpi_find_machine( | |||
245 | return NULL; | 245 | return NULL; |
246 | } | 246 | } |
247 | 247 | ||
248 | int sst_acpi_probe(struct platform_device *pdev) | 248 | static int sst_acpi_probe(struct platform_device *pdev) |
249 | { | 249 | { |
250 | struct device *dev = &pdev->dev; | 250 | struct device *dev = &pdev->dev; |
251 | int ret = 0; | 251 | int ret = 0; |
@@ -332,7 +332,7 @@ do_sst_cleanup: | |||
332 | * This function is called by OS when a device is unloaded | 332 | * This function is called by OS when a device is unloaded |
333 | * This frees the interrupt etc | 333 | * This frees the interrupt etc |
334 | */ | 334 | */ |
335 | int sst_acpi_remove(struct platform_device *pdev) | 335 | static int sst_acpi_remove(struct platform_device *pdev) |
336 | { | 336 | { |
337 | struct intel_sst_drv *ctx; | 337 | struct intel_sst_drv *ctx; |
338 | 338 | ||
@@ -343,14 +343,16 @@ int sst_acpi_remove(struct platform_device *pdev) | |||
343 | } | 343 | } |
344 | 344 | ||
345 | static struct sst_machines sst_acpi_bytcr[] = { | 345 | static struct sst_machines sst_acpi_bytcr[] = { |
346 | {"10EC5640", "T100", "bytt100_rt5640", NULL, "fw_sst_0f28.bin", | 346 | {"10EC5640", "T100", "bytt100_rt5640", NULL, "intel/fw_sst_0f28.bin", |
347 | &byt_rvp_platform_data }, | 347 | &byt_rvp_platform_data }, |
348 | {}, | 348 | {}, |
349 | }; | 349 | }; |
350 | 350 | ||
351 | /* Cherryview-based platforms: CherryTrail and Braswell */ | 351 | /* Cherryview-based platforms: CherryTrail and Braswell */ |
352 | static struct sst_machines sst_acpi_chv[] = { | 352 | static struct sst_machines sst_acpi_chv[] = { |
353 | {"10EC5670", "cht-bsw", "cht-bsw-rt5672", NULL, "fw_sst_22a8.bin", | 353 | {"10EC5670", "cht-bsw", "cht-bsw-rt5672", NULL, "intel/fw_sst_22a8.bin", |
354 | &chv_platform_data }, | ||
355 | {"10EC5645", "cht-bsw", "cht-bsw-rt5645", NULL, "intel/fw_sst_22a8.bin", | ||
354 | &chv_platform_data }, | 356 | &chv_platform_data }, |
355 | {}, | 357 | {}, |
356 | }; | 358 | }; |
@@ -366,7 +368,6 @@ MODULE_DEVICE_TABLE(acpi, sst_acpi_ids); | |||
366 | static struct platform_driver sst_acpi_driver = { | 368 | static struct platform_driver sst_acpi_driver = { |
367 | .driver = { | 369 | .driver = { |
368 | .name = "intel_sst_acpi", | 370 | .name = "intel_sst_acpi", |
369 | .owner = THIS_MODULE, | ||
370 | .acpi_match_table = ACPI_PTR(sst_acpi_ids), | 371 | .acpi_match_table = ACPI_PTR(sst_acpi_ids), |
371 | .pm = &intel_sst_pm, | 372 | .pm = &intel_sst_pm, |
372 | }, | 373 | }, |
diff --git a/sound/soc/intel/sst/sst_loader.c b/sound/soc/intel/sst/sst_loader.c index b580f96e25e5..7888cd707853 100644 --- a/sound/soc/intel/sst/sst_loader.c +++ b/sound/soc/intel/sst/sst_loader.c | |||
@@ -324,8 +324,7 @@ void sst_firmware_load_cb(const struct firmware *fw, void *context) | |||
324 | 324 | ||
325 | if (ctx->sst_state != SST_RESET || | 325 | if (ctx->sst_state != SST_RESET || |
326 | ctx->fw_in_mem != NULL) { | 326 | ctx->fw_in_mem != NULL) { |
327 | if (fw != NULL) | 327 | release_firmware(fw); |
328 | release_firmware(fw); | ||
329 | mutex_unlock(&ctx->sst_lock); | 328 | mutex_unlock(&ctx->sst_lock); |
330 | return; | 329 | return; |
331 | } | 330 | } |
diff --git a/sound/soc/jz4740/jz4740-i2s.c b/sound/soc/jz4740/jz4740-i2s.c index d3d45c6f064f..07f77815a586 100644 --- a/sound/soc/jz4740/jz4740-i2s.c +++ b/sound/soc/jz4740/jz4740-i2s.c | |||
@@ -14,6 +14,8 @@ | |||
14 | 14 | ||
15 | #include <linux/init.h> | 15 | #include <linux/init.h> |
16 | #include <linux/io.h> | 16 | #include <linux/io.h> |
17 | #include <linux/of.h> | ||
18 | #include <linux/of_device.h> | ||
17 | #include <linux/kernel.h> | 19 | #include <linux/kernel.h> |
18 | #include <linux/module.h> | 20 | #include <linux/module.h> |
19 | #include <linux/platform_device.h> | 21 | #include <linux/platform_device.h> |
@@ -83,6 +85,8 @@ | |||
83 | #define JZ_AIC_I2S_STATUS_BUSY BIT(2) | 85 | #define JZ_AIC_I2S_STATUS_BUSY BIT(2) |
84 | 86 | ||
85 | #define JZ_AIC_CLK_DIV_MASK 0xf | 87 | #define JZ_AIC_CLK_DIV_MASK 0xf |
88 | #define I2SDIV_DV_SHIFT 8 | ||
89 | #define I2SDIV_DV_MASK (0xf << I2SDIV_DV_SHIFT) | ||
86 | 90 | ||
87 | struct jz4740_i2s { | 91 | struct jz4740_i2s { |
88 | struct resource *mem; | 92 | struct resource *mem; |
@@ -237,10 +241,14 @@ static int jz4740_i2s_hw_params(struct snd_pcm_substream *substream, | |||
237 | { | 241 | { |
238 | struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai); | 242 | struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai); |
239 | unsigned int sample_size; | 243 | unsigned int sample_size; |
240 | uint32_t ctrl; | 244 | uint32_t ctrl, div_reg; |
245 | int div; | ||
241 | 246 | ||
242 | ctrl = jz4740_i2s_read(i2s, JZ_REG_AIC_CTRL); | 247 | ctrl = jz4740_i2s_read(i2s, JZ_REG_AIC_CTRL); |
243 | 248 | ||
249 | div_reg = jz4740_i2s_read(i2s, JZ_REG_AIC_CLK_DIV); | ||
250 | div = clk_get_rate(i2s->clk_i2s) / (64 * params_rate(params)); | ||
251 | |||
244 | switch (params_format(params)) { | 252 | switch (params_format(params)) { |
245 | case SNDRV_PCM_FORMAT_S8: | 253 | case SNDRV_PCM_FORMAT_S8: |
246 | sample_size = 0; | 254 | sample_size = 0; |
@@ -264,7 +272,10 @@ static int jz4740_i2s_hw_params(struct snd_pcm_substream *substream, | |||
264 | ctrl |= sample_size << JZ_AIC_CTRL_INPUT_SAMPLE_SIZE_OFFSET; | 272 | ctrl |= sample_size << JZ_AIC_CTRL_INPUT_SAMPLE_SIZE_OFFSET; |
265 | } | 273 | } |
266 | 274 | ||
275 | div_reg &= ~I2SDIV_DV_MASK; | ||
276 | div_reg |= (div - 1) << I2SDIV_DV_SHIFT; | ||
267 | jz4740_i2s_write(i2s, JZ_REG_AIC_CTRL, ctrl); | 277 | jz4740_i2s_write(i2s, JZ_REG_AIC_CTRL, ctrl); |
278 | jz4740_i2s_write(i2s, JZ_REG_AIC_CLK_DIV, div_reg); | ||
268 | 279 | ||
269 | return 0; | 280 | return 0; |
270 | } | 281 | } |
@@ -415,6 +426,13 @@ static const struct snd_soc_component_driver jz4740_i2s_component = { | |||
415 | .name = "jz4740-i2s", | 426 | .name = "jz4740-i2s", |
416 | }; | 427 | }; |
417 | 428 | ||
429 | #ifdef CONFIG_OF | ||
430 | static const struct of_device_id jz4740_of_matches[] = { | ||
431 | { .compatible = "ingenic,jz4740-i2s" }, | ||
432 | { /* sentinel */ } | ||
433 | }; | ||
434 | #endif | ||
435 | |||
418 | static int jz4740_i2s_dev_probe(struct platform_device *pdev) | 436 | static int jz4740_i2s_dev_probe(struct platform_device *pdev) |
419 | { | 437 | { |
420 | struct jz4740_i2s *i2s; | 438 | struct jz4740_i2s *i2s; |
@@ -455,6 +473,7 @@ static struct platform_driver jz4740_i2s_driver = { | |||
455 | .probe = jz4740_i2s_dev_probe, | 473 | .probe = jz4740_i2s_dev_probe, |
456 | .driver = { | 474 | .driver = { |
457 | .name = "jz4740-i2s", | 475 | .name = "jz4740-i2s", |
476 | .of_match_table = of_match_ptr(jz4740_of_matches) | ||
458 | }, | 477 | }, |
459 | }; | 478 | }; |
460 | 479 | ||
diff --git a/sound/soc/mxs/mxs-saif.c b/sound/soc/mxs/mxs-saif.c index d9865082160c..c866ade28ad0 100644 --- a/sound/soc/mxs/mxs-saif.c +++ b/sound/soc/mxs/mxs-saif.c | |||
@@ -710,7 +710,7 @@ static int mxs_saif_probe(struct platform_device *pdev) | |||
710 | struct device_node *np = pdev->dev.of_node; | 710 | struct device_node *np = pdev->dev.of_node; |
711 | struct resource *iores; | 711 | struct resource *iores; |
712 | struct mxs_saif *saif; | 712 | struct mxs_saif *saif; |
713 | int ret = 0; | 713 | int irq, ret = 0; |
714 | struct device_node *master; | 714 | struct device_node *master; |
715 | 715 | ||
716 | if (!np) | 716 | if (!np) |
@@ -763,16 +763,16 @@ static int mxs_saif_probe(struct platform_device *pdev) | |||
763 | if (IS_ERR(saif->base)) | 763 | if (IS_ERR(saif->base)) |
764 | return PTR_ERR(saif->base); | 764 | return PTR_ERR(saif->base); |
765 | 765 | ||
766 | saif->irq = platform_get_irq(pdev, 0); | 766 | irq = platform_get_irq(pdev, 0); |
767 | if (saif->irq < 0) { | 767 | if (irq < 0) { |
768 | ret = saif->irq; | 768 | ret = irq; |
769 | dev_err(&pdev->dev, "failed to get irq resource: %d\n", | 769 | dev_err(&pdev->dev, "failed to get irq resource: %d\n", |
770 | ret); | 770 | ret); |
771 | return ret; | 771 | return ret; |
772 | } | 772 | } |
773 | 773 | ||
774 | saif->dev = &pdev->dev; | 774 | saif->dev = &pdev->dev; |
775 | ret = devm_request_irq(&pdev->dev, saif->irq, mxs_saif_irq, 0, | 775 | ret = devm_request_irq(&pdev->dev, irq, mxs_saif_irq, 0, |
776 | dev_name(&pdev->dev), saif); | 776 | dev_name(&pdev->dev), saif); |
777 | if (ret) { | 777 | if (ret) { |
778 | dev_err(&pdev->dev, "failed to request irq\n"); | 778 | dev_err(&pdev->dev, "failed to request irq\n"); |
diff --git a/sound/soc/mxs/mxs-saif.h b/sound/soc/mxs/mxs-saif.h index fbaf7badfdfb..9a4c0b291b9e 100644 --- a/sound/soc/mxs/mxs-saif.h +++ b/sound/soc/mxs/mxs-saif.h | |||
@@ -116,7 +116,6 @@ struct mxs_saif { | |||
116 | unsigned int mclk; | 116 | unsigned int mclk; |
117 | unsigned int mclk_in_use; | 117 | unsigned int mclk_in_use; |
118 | void __iomem *base; | 118 | void __iomem *base; |
119 | int irq; | ||
120 | unsigned int id; | 119 | unsigned int id; |
121 | unsigned int master_id; | 120 | unsigned int master_id; |
122 | unsigned int cur_rate; | 121 | unsigned int cur_rate; |
diff --git a/sound/soc/mxs/mxs-sgtl5000.c b/sound/soc/mxs/mxs-sgtl5000.c index 6f1916b71815..6e6fce6a14ba 100644 --- a/sound/soc/mxs/mxs-sgtl5000.c +++ b/sound/soc/mxs/mxs-sgtl5000.c | |||
@@ -36,7 +36,7 @@ static int mxs_sgtl5000_hw_params(struct snd_pcm_substream *substream, | |||
36 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | 36 | struct snd_soc_dai *codec_dai = rtd->codec_dai; |
37 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | 37 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; |
38 | unsigned int rate = params_rate(params); | 38 | unsigned int rate = params_rate(params); |
39 | u32 dai_format, mclk; | 39 | u32 mclk; |
40 | int ret; | 40 | int ret; |
41 | 41 | ||
42 | /* sgtl5000 does not support 512*rate when in 96000 fs */ | 42 | /* sgtl5000 does not support 512*rate when in 96000 fs */ |
@@ -65,26 +65,6 @@ static int mxs_sgtl5000_hw_params(struct snd_pcm_substream *substream, | |||
65 | return ret; | 65 | return ret; |
66 | } | 66 | } |
67 | 67 | ||
68 | /* set codec to slave mode */ | ||
69 | dai_format = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | | ||
70 | SND_SOC_DAIFMT_CBS_CFS; | ||
71 | |||
72 | /* set codec DAI configuration */ | ||
73 | ret = snd_soc_dai_set_fmt(codec_dai, dai_format); | ||
74 | if (ret) { | ||
75 | dev_err(codec_dai->dev, "Failed to set dai format to %08x\n", | ||
76 | dai_format); | ||
77 | return ret; | ||
78 | } | ||
79 | |||
80 | /* set cpu DAI configuration */ | ||
81 | ret = snd_soc_dai_set_fmt(cpu_dai, dai_format); | ||
82 | if (ret) { | ||
83 | dev_err(cpu_dai->dev, "Failed to set dai format to %08x\n", | ||
84 | dai_format); | ||
85 | return ret; | ||
86 | } | ||
87 | |||
88 | return 0; | 68 | return 0; |
89 | } | 69 | } |
90 | 70 | ||
@@ -92,17 +72,22 @@ static struct snd_soc_ops mxs_sgtl5000_hifi_ops = { | |||
92 | .hw_params = mxs_sgtl5000_hw_params, | 72 | .hw_params = mxs_sgtl5000_hw_params, |
93 | }; | 73 | }; |
94 | 74 | ||
75 | #define MXS_SGTL5000_DAI_FMT (SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | \ | ||
76 | SND_SOC_DAIFMT_CBS_CFS) | ||
77 | |||
95 | static struct snd_soc_dai_link mxs_sgtl5000_dai[] = { | 78 | static struct snd_soc_dai_link mxs_sgtl5000_dai[] = { |
96 | { | 79 | { |
97 | .name = "HiFi Tx", | 80 | .name = "HiFi Tx", |
98 | .stream_name = "HiFi Playback", | 81 | .stream_name = "HiFi Playback", |
99 | .codec_dai_name = "sgtl5000", | 82 | .codec_dai_name = "sgtl5000", |
83 | .dai_fmt = MXS_SGTL5000_DAI_FMT, | ||
100 | .ops = &mxs_sgtl5000_hifi_ops, | 84 | .ops = &mxs_sgtl5000_hifi_ops, |
101 | .playback_only = true, | 85 | .playback_only = true, |
102 | }, { | 86 | }, { |
103 | .name = "HiFi Rx", | 87 | .name = "HiFi Rx", |
104 | .stream_name = "HiFi Capture", | 88 | .stream_name = "HiFi Capture", |
105 | .codec_dai_name = "sgtl5000", | 89 | .codec_dai_name = "sgtl5000", |
90 | .dai_fmt = MXS_SGTL5000_DAI_FMT, | ||
106 | .ops = &mxs_sgtl5000_hifi_ops, | 91 | .ops = &mxs_sgtl5000_hifi_ops, |
107 | .capture_only = true, | 92 | .capture_only = true, |
108 | }, | 93 | }, |
diff --git a/sound/soc/nuc900/nuc900-pcm.c b/sound/soc/nuc900/nuc900-pcm.c index b779a3d9b5dd..b809fa909e4d 100644 --- a/sound/soc/nuc900/nuc900-pcm.c +++ b/sound/soc/nuc900/nuc900-pcm.c | |||
@@ -306,11 +306,6 @@ static struct snd_pcm_ops nuc900_dma_ops = { | |||
306 | .mmap = nuc900_dma_mmap, | 306 | .mmap = nuc900_dma_mmap, |
307 | }; | 307 | }; |
308 | 308 | ||
309 | static void nuc900_dma_free_dma_buffers(struct snd_pcm *pcm) | ||
310 | { | ||
311 | snd_pcm_lib_preallocate_free_for_all(pcm); | ||
312 | } | ||
313 | |||
314 | static int nuc900_dma_new(struct snd_soc_pcm_runtime *rtd) | 309 | static int nuc900_dma_new(struct snd_soc_pcm_runtime *rtd) |
315 | { | 310 | { |
316 | struct snd_card *card = rtd->card->snd_card; | 311 | struct snd_card *card = rtd->card->snd_card; |
@@ -330,7 +325,6 @@ static int nuc900_dma_new(struct snd_soc_pcm_runtime *rtd) | |||
330 | static struct snd_soc_platform_driver nuc900_soc_platform = { | 325 | static struct snd_soc_platform_driver nuc900_soc_platform = { |
331 | .ops = &nuc900_dma_ops, | 326 | .ops = &nuc900_dma_ops, |
332 | .pcm_new = nuc900_dma_new, | 327 | .pcm_new = nuc900_dma_new, |
333 | .pcm_free = nuc900_dma_free_dma_buffers, | ||
334 | }; | 328 | }; |
335 | 329 | ||
336 | static int nuc900_soc_platform_probe(struct platform_device *pdev) | 330 | static int nuc900_soc_platform_probe(struct platform_device *pdev) |
diff --git a/sound/soc/omap/ams-delta.c b/sound/soc/omap/ams-delta.c index 4c6afb75eea6..706613077c15 100644 --- a/sound/soc/omap/ams-delta.c +++ b/sound/soc/omap/ams-delta.c | |||
@@ -412,21 +412,7 @@ static struct tty_ldisc_ops cx81801_ops = { | |||
412 | * over the modem port. | 412 | * over the modem port. |
413 | */ | 413 | */ |
414 | 414 | ||
415 | static int ams_delta_hw_params(struct snd_pcm_substream *substream, | 415 | static struct snd_soc_ops ams_delta_ops; |
416 | struct snd_pcm_hw_params *params) | ||
417 | { | ||
418 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
419 | |||
420 | /* Set cpu DAI configuration */ | ||
421 | return snd_soc_dai_set_fmt(rtd->cpu_dai, | ||
422 | SND_SOC_DAIFMT_DSP_A | | ||
423 | SND_SOC_DAIFMT_NB_NF | | ||
424 | SND_SOC_DAIFMT_CBM_CFM); | ||
425 | } | ||
426 | |||
427 | static struct snd_soc_ops ams_delta_ops = { | ||
428 | .hw_params = ams_delta_hw_params, | ||
429 | }; | ||
430 | 416 | ||
431 | 417 | ||
432 | /* Digital mute implemented using modem/CPU multiplexer. | 418 | /* Digital mute implemented using modem/CPU multiplexer. |
@@ -546,6 +532,8 @@ static struct snd_soc_dai_link ams_delta_dai_link = { | |||
546 | .platform_name = "omap-mcbsp.1", | 532 | .platform_name = "omap-mcbsp.1", |
547 | .codec_name = "cx20442-codec", | 533 | .codec_name = "cx20442-codec", |
548 | .ops = &ams_delta_ops, | 534 | .ops = &ams_delta_ops, |
535 | .dai_fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_NB_NF | | ||
536 | SND_SOC_DAIFMT_CBM_CFM, | ||
549 | }; | 537 | }; |
550 | 538 | ||
551 | /* Audio card driver */ | 539 | /* Audio card driver */ |
diff --git a/sound/soc/omap/omap-hdmi-audio.c b/sound/soc/omap/omap-hdmi-audio.c index 3f9ac7dbdc80..ccfb41c22e53 100644 --- a/sound/soc/omap/omap-hdmi-audio.c +++ b/sound/soc/omap/omap-hdmi-audio.c | |||
@@ -393,7 +393,6 @@ static int omap_hdmi_audio_remove(struct platform_device *pdev) | |||
393 | static struct platform_driver hdmi_audio_driver = { | 393 | static struct platform_driver hdmi_audio_driver = { |
394 | .driver = { | 394 | .driver = { |
395 | .name = DRV_NAME, | 395 | .name = DRV_NAME, |
396 | .owner = THIS_MODULE, | ||
397 | }, | 396 | }, |
398 | .probe = omap_hdmi_audio_probe, | 397 | .probe = omap_hdmi_audio_probe, |
399 | .remove = omap_hdmi_audio_remove, | 398 | .remove = omap_hdmi_audio_remove, |
diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c index 8b79cafab1e2..c7eb9dd67f60 100644 --- a/sound/soc/omap/omap-mcbsp.c +++ b/sound/soc/omap/omap-mcbsp.c | |||
@@ -434,7 +434,7 @@ static int omap_mcbsp_dai_set_dai_fmt(struct snd_soc_dai *cpu_dai, | |||
434 | case SND_SOC_DAIFMT_CBM_CFS: | 434 | case SND_SOC_DAIFMT_CBM_CFS: |
435 | /* McBSP slave. FS clock as output */ | 435 | /* McBSP slave. FS clock as output */ |
436 | regs->srgr2 |= FSGM; | 436 | regs->srgr2 |= FSGM; |
437 | regs->pcr0 |= FSXM; | 437 | regs->pcr0 |= FSXM | FSRM; |
438 | break; | 438 | break; |
439 | case SND_SOC_DAIFMT_CBM_CFM: | 439 | case SND_SOC_DAIFMT_CBM_CFM: |
440 | /* McBSP slave */ | 440 | /* McBSP slave */ |
diff --git a/sound/soc/omap/omap-twl4030.c b/sound/soc/omap/omap-twl4030.c index 5e551c762b7a..fb1f6bb87cd4 100644 --- a/sound/soc/omap/omap-twl4030.c +++ b/sound/soc/omap/omap-twl4030.c | |||
@@ -53,11 +53,7 @@ static int omap_twl4030_hw_params(struct snd_pcm_substream *substream, | |||
53 | struct snd_pcm_hw_params *params) | 53 | struct snd_pcm_hw_params *params) |
54 | { | 54 | { |
55 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 55 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
56 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | ||
57 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | ||
58 | struct snd_soc_card *card = rtd->card; | ||
59 | unsigned int fmt; | 56 | unsigned int fmt; |
60 | int ret; | ||
61 | 57 | ||
62 | switch (params_channels(params)) { | 58 | switch (params_channels(params)) { |
63 | case 2: /* Stereo I2S mode */ | 59 | case 2: /* Stereo I2S mode */ |
@@ -74,21 +70,7 @@ static int omap_twl4030_hw_params(struct snd_pcm_substream *substream, | |||
74 | return -EINVAL; | 70 | return -EINVAL; |
75 | } | 71 | } |
76 | 72 | ||
77 | /* Set codec DAI configuration */ | 73 | return snd_soc_runtime_set_dai_fmt(rtd, fmt); |
78 | ret = snd_soc_dai_set_fmt(codec_dai, fmt); | ||
79 | if (ret < 0) { | ||
80 | dev_err(card->dev, "can't set codec DAI configuration\n"); | ||
81 | return ret; | ||
82 | } | ||
83 | |||
84 | /* Set cpu DAI configuration */ | ||
85 | ret = snd_soc_dai_set_fmt(cpu_dai, fmt); | ||
86 | if (ret < 0) { | ||
87 | dev_err(card->dev, "can't set cpu DAI configuration\n"); | ||
88 | return ret; | ||
89 | } | ||
90 | |||
91 | return 0; | ||
92 | } | 74 | } |
93 | 75 | ||
94 | static struct snd_soc_ops omap_twl4030_ops = { | 76 | static struct snd_soc_ops omap_twl4030_ops = { |
diff --git a/sound/soc/omap/rx51.c b/sound/soc/omap/rx51.c index 04896d6252a2..7f299357c2d2 100644 --- a/sound/soc/omap/rx51.c +++ b/sound/soc/omap/rx51.c | |||
@@ -250,14 +250,14 @@ static const struct snd_soc_dapm_route audio_map[] = { | |||
250 | {"FM Transmitter", NULL, "LLOUT"}, | 250 | {"FM Transmitter", NULL, "LLOUT"}, |
251 | {"FM Transmitter", NULL, "RLOUT"}, | 251 | {"FM Transmitter", NULL, "RLOUT"}, |
252 | 252 | ||
253 | {"DMic Rate 64", NULL, "Mic Bias"}, | 253 | {"DMic Rate 64", NULL, "DMic"}, |
254 | {"Mic Bias", NULL, "DMic"}, | 254 | {"DMic", NULL, "Mic Bias"}, |
255 | 255 | ||
256 | {"b LINE2R", NULL, "MONO_LOUT"}, | 256 | {"b LINE2R", NULL, "MONO_LOUT"}, |
257 | {"Earphone", NULL, "b HPLOUT"}, | 257 | {"Earphone", NULL, "b HPLOUT"}, |
258 | 258 | ||
259 | {"LINE1L", NULL, "b Mic Bias"}, | 259 | {"LINE1L", NULL, "HS Mic"}, |
260 | {"b Mic Bias", NULL, "HS Mic"} | 260 | {"HS Mic", NULL, "b Mic Bias"}, |
261 | }; | 261 | }; |
262 | 262 | ||
263 | static const char * const spk_function[] = {"Off", "On"}; | 263 | static const char * const spk_function[] = {"Off", "On"}; |
diff --git a/sound/soc/pxa/Kconfig b/sound/soc/pxa/Kconfig index 2434b6d61675..39cea80846c3 100644 --- a/sound/soc/pxa/Kconfig +++ b/sound/soc/pxa/Kconfig | |||
@@ -140,7 +140,7 @@ config SND_PXA910_SOC | |||
140 | Marvell PXA910 reference platform. | 140 | Marvell PXA910 reference platform. |
141 | 141 | ||
142 | config SND_SOC_TTC_DKB | 142 | config SND_SOC_TTC_DKB |
143 | bool "SoC Audio support for TTC DKB" | 143 | tristate "SoC Audio support for TTC DKB" |
144 | depends on SND_PXA910_SOC && MACH_TTC_DKB && I2C=y | 144 | depends on SND_PXA910_SOC && MACH_TTC_DKB && I2C=y |
145 | select PXA_SSP | 145 | select PXA_SSP |
146 | select SND_PXA_SOC_SSP | 146 | select SND_PXA_SOC_SSP |
diff --git a/sound/soc/pxa/corgi.c b/sound/soc/pxa/corgi.c index b7cd0a71fd70..3580d10c9f28 100644 --- a/sound/soc/pxa/corgi.c +++ b/sound/soc/pxa/corgi.c | |||
@@ -259,20 +259,6 @@ static const struct snd_kcontrol_new wm8731_corgi_controls[] = { | |||
259 | corgi_set_spk), | 259 | corgi_set_spk), |
260 | }; | 260 | }; |
261 | 261 | ||
262 | /* | ||
263 | * Logic for a wm8731 as connected on a Sharp SL-C7x0 Device | ||
264 | */ | ||
265 | static int corgi_wm8731_init(struct snd_soc_pcm_runtime *rtd) | ||
266 | { | ||
267 | struct snd_soc_codec *codec = rtd->codec; | ||
268 | struct snd_soc_dapm_context *dapm = &codec->dapm; | ||
269 | |||
270 | snd_soc_dapm_nc_pin(dapm, "LLINEIN"); | ||
271 | snd_soc_dapm_nc_pin(dapm, "RLINEIN"); | ||
272 | |||
273 | return 0; | ||
274 | } | ||
275 | |||
276 | /* corgi digital audio interface glue - connects codec <--> CPU */ | 262 | /* corgi digital audio interface glue - connects codec <--> CPU */ |
277 | static struct snd_soc_dai_link corgi_dai = { | 263 | static struct snd_soc_dai_link corgi_dai = { |
278 | .name = "WM8731", | 264 | .name = "WM8731", |
@@ -281,7 +267,6 @@ static struct snd_soc_dai_link corgi_dai = { | |||
281 | .codec_dai_name = "wm8731-hifi", | 267 | .codec_dai_name = "wm8731-hifi", |
282 | .platform_name = "pxa-pcm-audio", | 268 | .platform_name = "pxa-pcm-audio", |
283 | .codec_name = "wm8731.0-001b", | 269 | .codec_name = "wm8731.0-001b", |
284 | .init = corgi_wm8731_init, | ||
285 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | | 270 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | |
286 | SND_SOC_DAIFMT_CBS_CFS, | 271 | SND_SOC_DAIFMT_CBS_CFS, |
287 | .ops = &corgi_ops, | 272 | .ops = &corgi_ops, |
@@ -300,6 +285,7 @@ static struct snd_soc_card corgi = { | |||
300 | .num_dapm_widgets = ARRAY_SIZE(wm8731_dapm_widgets), | 285 | .num_dapm_widgets = ARRAY_SIZE(wm8731_dapm_widgets), |
301 | .dapm_routes = corgi_audio_map, | 286 | .dapm_routes = corgi_audio_map, |
302 | .num_dapm_routes = ARRAY_SIZE(corgi_audio_map), | 287 | .num_dapm_routes = ARRAY_SIZE(corgi_audio_map), |
288 | .fully_routed = true, | ||
303 | }; | 289 | }; |
304 | 290 | ||
305 | static int corgi_probe(struct platform_device *pdev) | 291 | static int corgi_probe(struct platform_device *pdev) |
diff --git a/sound/soc/pxa/e740_wm9705.c b/sound/soc/pxa/e740_wm9705.c index 7c691aae8af2..d72e124a3676 100644 --- a/sound/soc/pxa/e740_wm9705.c +++ b/sound/soc/pxa/e740_wm9705.c | |||
@@ -88,24 +88,6 @@ static const struct snd_soc_dapm_route audio_map[] = { | |||
88 | {"Mic Amp", NULL, "Mic (Internal)"}, | 88 | {"Mic Amp", NULL, "Mic (Internal)"}, |
89 | }; | 89 | }; |
90 | 90 | ||
91 | static int e740_ac97_init(struct snd_soc_pcm_runtime *rtd) | ||
92 | { | ||
93 | struct snd_soc_codec *codec = rtd->codec; | ||
94 | struct snd_soc_dapm_context *dapm = &codec->dapm; | ||
95 | |||
96 | snd_soc_dapm_nc_pin(dapm, "HPOUTL"); | ||
97 | snd_soc_dapm_nc_pin(dapm, "HPOUTR"); | ||
98 | snd_soc_dapm_nc_pin(dapm, "PHONE"); | ||
99 | snd_soc_dapm_nc_pin(dapm, "LINEINL"); | ||
100 | snd_soc_dapm_nc_pin(dapm, "LINEINR"); | ||
101 | snd_soc_dapm_nc_pin(dapm, "CDINL"); | ||
102 | snd_soc_dapm_nc_pin(dapm, "CDINR"); | ||
103 | snd_soc_dapm_nc_pin(dapm, "PCBEEP"); | ||
104 | snd_soc_dapm_nc_pin(dapm, "MIC2"); | ||
105 | |||
106 | return 0; | ||
107 | } | ||
108 | |||
109 | static struct snd_soc_dai_link e740_dai[] = { | 91 | static struct snd_soc_dai_link e740_dai[] = { |
110 | { | 92 | { |
111 | .name = "AC97", | 93 | .name = "AC97", |
@@ -114,7 +96,6 @@ static struct snd_soc_dai_link e740_dai[] = { | |||
114 | .codec_dai_name = "wm9705-hifi", | 96 | .codec_dai_name = "wm9705-hifi", |
115 | .platform_name = "pxa-pcm-audio", | 97 | .platform_name = "pxa-pcm-audio", |
116 | .codec_name = "wm9705-codec", | 98 | .codec_name = "wm9705-codec", |
117 | .init = e740_ac97_init, | ||
118 | }, | 99 | }, |
119 | { | 100 | { |
120 | .name = "AC97 Aux", | 101 | .name = "AC97 Aux", |
@@ -136,6 +117,7 @@ static struct snd_soc_card e740 = { | |||
136 | .num_dapm_widgets = ARRAY_SIZE(e740_dapm_widgets), | 117 | .num_dapm_widgets = ARRAY_SIZE(e740_dapm_widgets), |
137 | .dapm_routes = audio_map, | 118 | .dapm_routes = audio_map, |
138 | .num_dapm_routes = ARRAY_SIZE(audio_map), | 119 | .num_dapm_routes = ARRAY_SIZE(audio_map), |
120 | .fully_routed = true, | ||
139 | }; | 121 | }; |
140 | 122 | ||
141 | static struct gpio e740_audio_gpios[] = { | 123 | static struct gpio e740_audio_gpios[] = { |
diff --git a/sound/soc/pxa/e750_wm9705.c b/sound/soc/pxa/e750_wm9705.c index 30544b65b5a8..48f2d7c2e68c 100644 --- a/sound/soc/pxa/e750_wm9705.c +++ b/sound/soc/pxa/e750_wm9705.c | |||
@@ -70,24 +70,6 @@ static const struct snd_soc_dapm_route audio_map[] = { | |||
70 | {"MIC1", NULL, "Mic (Internal)"}, | 70 | {"MIC1", NULL, "Mic (Internal)"}, |
71 | }; | 71 | }; |
72 | 72 | ||
73 | static int e750_ac97_init(struct snd_soc_pcm_runtime *rtd) | ||
74 | { | ||
75 | struct snd_soc_codec *codec = rtd->codec; | ||
76 | struct snd_soc_dapm_context *dapm = &codec->dapm; | ||
77 | |||
78 | snd_soc_dapm_nc_pin(dapm, "LOUT"); | ||
79 | snd_soc_dapm_nc_pin(dapm, "ROUT"); | ||
80 | snd_soc_dapm_nc_pin(dapm, "PHONE"); | ||
81 | snd_soc_dapm_nc_pin(dapm, "LINEINL"); | ||
82 | snd_soc_dapm_nc_pin(dapm, "LINEINR"); | ||
83 | snd_soc_dapm_nc_pin(dapm, "CDINL"); | ||
84 | snd_soc_dapm_nc_pin(dapm, "CDINR"); | ||
85 | snd_soc_dapm_nc_pin(dapm, "PCBEEP"); | ||
86 | snd_soc_dapm_nc_pin(dapm, "MIC2"); | ||
87 | |||
88 | return 0; | ||
89 | } | ||
90 | |||
91 | static struct snd_soc_dai_link e750_dai[] = { | 73 | static struct snd_soc_dai_link e750_dai[] = { |
92 | { | 74 | { |
93 | .name = "AC97", | 75 | .name = "AC97", |
@@ -96,7 +78,6 @@ static struct snd_soc_dai_link e750_dai[] = { | |||
96 | .codec_dai_name = "wm9705-hifi", | 78 | .codec_dai_name = "wm9705-hifi", |
97 | .platform_name = "pxa-pcm-audio", | 79 | .platform_name = "pxa-pcm-audio", |
98 | .codec_name = "wm9705-codec", | 80 | .codec_name = "wm9705-codec", |
99 | .init = e750_ac97_init, | ||
100 | /* use ops to check startup state */ | 81 | /* use ops to check startup state */ |
101 | }, | 82 | }, |
102 | { | 83 | { |
@@ -119,6 +100,7 @@ static struct snd_soc_card e750 = { | |||
119 | .num_dapm_widgets = ARRAY_SIZE(e750_dapm_widgets), | 100 | .num_dapm_widgets = ARRAY_SIZE(e750_dapm_widgets), |
120 | .dapm_routes = audio_map, | 101 | .dapm_routes = audio_map, |
121 | .num_dapm_routes = ARRAY_SIZE(audio_map), | 102 | .num_dapm_routes = ARRAY_SIZE(audio_map), |
103 | .fully_routed = true, | ||
122 | }; | 104 | }; |
123 | 105 | ||
124 | static struct gpio e750_audio_gpios[] = { | 106 | static struct gpio e750_audio_gpios[] = { |
diff --git a/sound/soc/pxa/hx4700.c b/sound/soc/pxa/hx4700.c index ce26551052a3..73eb5ddf9753 100644 --- a/sound/soc/pxa/hx4700.c +++ b/sound/soc/pxa/hx4700.c | |||
@@ -127,15 +127,8 @@ static const struct snd_soc_dapm_route hx4700_audio_map[] = { | |||
127 | static int hx4700_ak4641_init(struct snd_soc_pcm_runtime *rtd) | 127 | static int hx4700_ak4641_init(struct snd_soc_pcm_runtime *rtd) |
128 | { | 128 | { |
129 | struct snd_soc_codec *codec = rtd->codec; | 129 | struct snd_soc_codec *codec = rtd->codec; |
130 | struct snd_soc_dapm_context *dapm = &codec->dapm; | ||
131 | int err; | 130 | int err; |
132 | 131 | ||
133 | /* NC codec pins */ | ||
134 | /* FIXME: is anything connected here? */ | ||
135 | snd_soc_dapm_nc_pin(dapm, "MOUT1"); | ||
136 | snd_soc_dapm_nc_pin(dapm, "MICEXT"); | ||
137 | snd_soc_dapm_nc_pin(dapm, "AUX"); | ||
138 | |||
139 | /* Jack detection API stuff */ | 132 | /* Jack detection API stuff */ |
140 | err = snd_soc_jack_new(codec, "Headphone Jack", | 133 | err = snd_soc_jack_new(codec, "Headphone Jack", |
141 | SND_JACK_HEADPHONE, &hs_jack); | 134 | SND_JACK_HEADPHONE, &hs_jack); |
@@ -184,6 +177,7 @@ static struct snd_soc_card snd_soc_card_hx4700 = { | |||
184 | .num_dapm_widgets = ARRAY_SIZE(hx4700_dapm_widgets), | 177 | .num_dapm_widgets = ARRAY_SIZE(hx4700_dapm_widgets), |
185 | .dapm_routes = hx4700_audio_map, | 178 | .dapm_routes = hx4700_audio_map, |
186 | .num_dapm_routes = ARRAY_SIZE(hx4700_audio_map), | 179 | .num_dapm_routes = ARRAY_SIZE(hx4700_audio_map), |
180 | .fully_routed = true, | ||
187 | }; | 181 | }; |
188 | 182 | ||
189 | static struct gpio hx4700_audio_gpios[] = { | 183 | static struct gpio hx4700_audio_gpios[] = { |
diff --git a/sound/soc/pxa/magician.c b/sound/soc/pxa/magician.c index 259e048681c0..241d0be42d7a 100644 --- a/sound/soc/pxa/magician.c +++ b/sound/soc/pxa/magician.c | |||
@@ -391,25 +391,6 @@ static const struct snd_kcontrol_new uda1380_magician_controls[] = { | |||
391 | magician_get_input, magician_set_input), | 391 | magician_get_input, magician_set_input), |
392 | }; | 392 | }; |
393 | 393 | ||
394 | /* | ||
395 | * Logic for a uda1380 as connected on a HTC Magician | ||
396 | */ | ||
397 | static int magician_uda1380_init(struct snd_soc_pcm_runtime *rtd) | ||
398 | { | ||
399 | struct snd_soc_codec *codec = rtd->codec; | ||
400 | struct snd_soc_dapm_context *dapm = &codec->dapm; | ||
401 | |||
402 | /* NC codec pins */ | ||
403 | snd_soc_dapm_nc_pin(dapm, "VOUTLHP"); | ||
404 | snd_soc_dapm_nc_pin(dapm, "VOUTRHP"); | ||
405 | |||
406 | /* FIXME: is anything connected here? */ | ||
407 | snd_soc_dapm_nc_pin(dapm, "VINL"); | ||
408 | snd_soc_dapm_nc_pin(dapm, "VINR"); | ||
409 | |||
410 | return 0; | ||
411 | } | ||
412 | |||
413 | /* magician digital audio interface glue - connects codec <--> CPU */ | 394 | /* magician digital audio interface glue - connects codec <--> CPU */ |
414 | static struct snd_soc_dai_link magician_dai[] = { | 395 | static struct snd_soc_dai_link magician_dai[] = { |
415 | { | 396 | { |
@@ -419,7 +400,6 @@ static struct snd_soc_dai_link magician_dai[] = { | |||
419 | .codec_dai_name = "uda1380-hifi-playback", | 400 | .codec_dai_name = "uda1380-hifi-playback", |
420 | .platform_name = "pxa-pcm-audio", | 401 | .platform_name = "pxa-pcm-audio", |
421 | .codec_name = "uda1380-codec.0-0018", | 402 | .codec_name = "uda1380-codec.0-0018", |
422 | .init = magician_uda1380_init, | ||
423 | .ops = &magician_playback_ops, | 403 | .ops = &magician_playback_ops, |
424 | }, | 404 | }, |
425 | { | 405 | { |
@@ -446,6 +426,7 @@ static struct snd_soc_card snd_soc_card_magician = { | |||
446 | .num_dapm_widgets = ARRAY_SIZE(uda1380_dapm_widgets), | 426 | .num_dapm_widgets = ARRAY_SIZE(uda1380_dapm_widgets), |
447 | .dapm_routes = audio_map, | 427 | .dapm_routes = audio_map, |
448 | .num_dapm_routes = ARRAY_SIZE(audio_map), | 428 | .num_dapm_routes = ARRAY_SIZE(audio_map), |
429 | .fully_routed = true, | ||
449 | }; | 430 | }; |
450 | 431 | ||
451 | static struct platform_device *magician_snd_device; | 432 | static struct platform_device *magician_snd_device; |
diff --git a/sound/soc/pxa/mioa701_wm9713.c b/sound/soc/pxa/mioa701_wm9713.c index 396dbd51a64f..a9615a574546 100644 --- a/sound/soc/pxa/mioa701_wm9713.c +++ b/sound/soc/pxa/mioa701_wm9713.c | |||
@@ -81,7 +81,7 @@ static int rear_amp_power(struct snd_soc_codec *codec, int power) | |||
81 | static int rear_amp_event(struct snd_soc_dapm_widget *widget, | 81 | static int rear_amp_event(struct snd_soc_dapm_widget *widget, |
82 | struct snd_kcontrol *kctl, int event) | 82 | struct snd_kcontrol *kctl, int event) |
83 | { | 83 | { |
84 | struct snd_soc_codec *codec = widget->codec; | 84 | struct snd_soc_codec *codec = widget->dapm->card->rtd[0].codec; |
85 | 85 | ||
86 | return rear_amp_power(codec, SND_SOC_DAPM_EVENT_ON(event)); | 86 | return rear_amp_power(codec, SND_SOC_DAPM_EVENT_ON(event)); |
87 | } | 87 | } |
diff --git a/sound/soc/pxa/palm27x.c b/sound/soc/pxa/palm27x.c index 1eebca2f0a97..910336c5ebeb 100644 --- a/sound/soc/pxa/palm27x.c +++ b/sound/soc/pxa/palm27x.c | |||
@@ -68,7 +68,7 @@ static const struct snd_soc_dapm_route audio_map[] = { | |||
68 | {"Ext. Speaker", NULL, "ROUT2"}, | 68 | {"Ext. Speaker", NULL, "ROUT2"}, |
69 | 69 | ||
70 | /* mic connected to MIC1 */ | 70 | /* mic connected to MIC1 */ |
71 | {"Ext. Microphone", NULL, "MIC1"}, | 71 | {"MIC1", NULL, "Ext. Microphone"}, |
72 | }; | 72 | }; |
73 | 73 | ||
74 | static struct snd_soc_card palm27x_asoc; | 74 | static struct snd_soc_card palm27x_asoc; |
@@ -76,18 +76,8 @@ static struct snd_soc_card palm27x_asoc; | |||
76 | static int palm27x_ac97_init(struct snd_soc_pcm_runtime *rtd) | 76 | static int palm27x_ac97_init(struct snd_soc_pcm_runtime *rtd) |
77 | { | 77 | { |
78 | struct snd_soc_codec *codec = rtd->codec; | 78 | struct snd_soc_codec *codec = rtd->codec; |
79 | struct snd_soc_dapm_context *dapm = &codec->dapm; | ||
80 | int err; | 79 | int err; |
81 | 80 | ||
82 | /* not connected pins */ | ||
83 | snd_soc_dapm_nc_pin(dapm, "OUT3"); | ||
84 | snd_soc_dapm_nc_pin(dapm, "MONOOUT"); | ||
85 | snd_soc_dapm_nc_pin(dapm, "LINEINL"); | ||
86 | snd_soc_dapm_nc_pin(dapm, "LINEINR"); | ||
87 | snd_soc_dapm_nc_pin(dapm, "PCBEEP"); | ||
88 | snd_soc_dapm_nc_pin(dapm, "PHONE"); | ||
89 | snd_soc_dapm_nc_pin(dapm, "MIC2"); | ||
90 | |||
91 | /* Jack detection API stuff */ | 81 | /* Jack detection API stuff */ |
92 | err = snd_soc_jack_new(codec, "Headphone Jack", | 82 | err = snd_soc_jack_new(codec, "Headphone Jack", |
93 | SND_JACK_HEADPHONE, &hs_jack); | 83 | SND_JACK_HEADPHONE, &hs_jack); |
@@ -133,7 +123,8 @@ static struct snd_soc_card palm27x_asoc = { | |||
133 | .dapm_widgets = palm27x_dapm_widgets, | 123 | .dapm_widgets = palm27x_dapm_widgets, |
134 | .num_dapm_widgets = ARRAY_SIZE(palm27x_dapm_widgets), | 124 | .num_dapm_widgets = ARRAY_SIZE(palm27x_dapm_widgets), |
135 | .dapm_routes = audio_map, | 125 | .dapm_routes = audio_map, |
136 | .num_dapm_routes = ARRAY_SIZE(audio_map) | 126 | .num_dapm_routes = ARRAY_SIZE(audio_map), |
127 | .fully_routed = true, | ||
137 | }; | 128 | }; |
138 | 129 | ||
139 | static int palm27x_asoc_probe(struct platform_device *pdev) | 130 | static int palm27x_asoc_probe(struct platform_device *pdev) |
diff --git a/sound/soc/pxa/raumfeld.c b/sound/soc/pxa/raumfeld.c index 083706595495..552b763005ed 100644 --- a/sound/soc/pxa/raumfeld.c +++ b/sound/soc/pxa/raumfeld.c | |||
@@ -88,7 +88,7 @@ static int raumfeld_cs4270_hw_params(struct snd_pcm_substream *substream, | |||
88 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 88 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
89 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | 89 | struct snd_soc_dai *codec_dai = rtd->codec_dai; |
90 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | 90 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; |
91 | unsigned int fmt, clk = 0; | 91 | unsigned int clk = 0; |
92 | int ret = 0; | 92 | int ret = 0; |
93 | 93 | ||
94 | switch (params_rate(params)) { | 94 | switch (params_rate(params)) { |
@@ -112,15 +112,6 @@ static int raumfeld_cs4270_hw_params(struct snd_pcm_substream *substream, | |||
112 | return -EINVAL; | 112 | return -EINVAL; |
113 | } | 113 | } |
114 | 114 | ||
115 | fmt = SND_SOC_DAIFMT_I2S | | ||
116 | SND_SOC_DAIFMT_NB_NF | | ||
117 | SND_SOC_DAIFMT_CBS_CFS; | ||
118 | |||
119 | /* setup the CODEC DAI */ | ||
120 | ret = snd_soc_dai_set_fmt(codec_dai, fmt); | ||
121 | if (ret < 0) | ||
122 | return ret; | ||
123 | |||
124 | ret = snd_soc_dai_set_sysclk(codec_dai, 0, clk, 0); | 115 | ret = snd_soc_dai_set_sysclk(codec_dai, 0, clk, 0); |
125 | if (ret < 0) | 116 | if (ret < 0) |
126 | return ret; | 117 | return ret; |
@@ -130,10 +121,6 @@ static int raumfeld_cs4270_hw_params(struct snd_pcm_substream *substream, | |||
130 | if (ret < 0) | 121 | if (ret < 0) |
131 | return ret; | 122 | return ret; |
132 | 123 | ||
133 | ret = snd_soc_dai_set_fmt(cpu_dai, fmt); | ||
134 | if (ret < 0) | ||
135 | return ret; | ||
136 | |||
137 | ret = snd_soc_dai_set_clkdiv(cpu_dai, PXA_SSP_DIV_SCR, 4); | 124 | ret = snd_soc_dai_set_clkdiv(cpu_dai, PXA_SSP_DIV_SCR, 4); |
138 | if (ret < 0) | 125 | if (ret < 0) |
139 | return ret; | 126 | return ret; |
@@ -169,9 +156,8 @@ static int raumfeld_ak4104_hw_params(struct snd_pcm_substream *substream, | |||
169 | struct snd_pcm_hw_params *params) | 156 | struct snd_pcm_hw_params *params) |
170 | { | 157 | { |
171 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 158 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
172 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | ||
173 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | 159 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; |
174 | int fmt, ret = 0, clk = 0; | 160 | int ret = 0, clk = 0; |
175 | 161 | ||
176 | switch (params_rate(params)) { | 162 | switch (params_rate(params)) { |
177 | case 44100: | 163 | case 44100: |
@@ -194,22 +180,11 @@ static int raumfeld_ak4104_hw_params(struct snd_pcm_substream *substream, | |||
194 | return -EINVAL; | 180 | return -EINVAL; |
195 | } | 181 | } |
196 | 182 | ||
197 | fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF; | ||
198 | |||
199 | /* setup the CODEC DAI */ | ||
200 | ret = snd_soc_dai_set_fmt(codec_dai, fmt | SND_SOC_DAIFMT_CBS_CFS); | ||
201 | if (ret < 0) | ||
202 | return ret; | ||
203 | |||
204 | /* setup the CPU DAI */ | 183 | /* setup the CPU DAI */ |
205 | ret = snd_soc_dai_set_pll(cpu_dai, 0, 0, 0, clk); | 184 | ret = snd_soc_dai_set_pll(cpu_dai, 0, 0, 0, clk); |
206 | if (ret < 0) | 185 | if (ret < 0) |
207 | return ret; | 186 | return ret; |
208 | 187 | ||
209 | ret = snd_soc_dai_set_fmt(cpu_dai, fmt | SND_SOC_DAIFMT_CBS_CFS); | ||
210 | if (ret < 0) | ||
211 | return ret; | ||
212 | |||
213 | ret = snd_soc_dai_set_clkdiv(cpu_dai, PXA_SSP_DIV_SCR, 4); | 188 | ret = snd_soc_dai_set_clkdiv(cpu_dai, PXA_SSP_DIV_SCR, 4); |
214 | if (ret < 0) | 189 | if (ret < 0) |
215 | return ret; | 190 | return ret; |
@@ -233,6 +208,9 @@ static struct snd_soc_ops raumfeld_ak4104_ops = { | |||
233 | .platform_name = "pxa-pcm-audio", \ | 208 | .platform_name = "pxa-pcm-audio", \ |
234 | .codec_dai_name = "cs4270-hifi", \ | 209 | .codec_dai_name = "cs4270-hifi", \ |
235 | .codec_name = "cs4270.0-0048", \ | 210 | .codec_name = "cs4270.0-0048", \ |
211 | .dai_fmt = SND_SOC_DAIFMT_I2S | \ | ||
212 | SND_SOC_DAIFMT_NB_NF | \ | ||
213 | SND_SOC_DAIFMT_CBS_CFS, \ | ||
236 | .ops = &raumfeld_cs4270_ops, \ | 214 | .ops = &raumfeld_cs4270_ops, \ |
237 | } | 215 | } |
238 | 216 | ||
@@ -243,6 +221,9 @@ static struct snd_soc_ops raumfeld_ak4104_ops = { | |||
243 | .cpu_dai_name = "pxa-ssp-dai.1", \ | 221 | .cpu_dai_name = "pxa-ssp-dai.1", \ |
244 | .codec_dai_name = "ak4104-hifi", \ | 222 | .codec_dai_name = "ak4104-hifi", \ |
245 | .platform_name = "pxa-pcm-audio", \ | 223 | .platform_name = "pxa-pcm-audio", \ |
224 | .dai_fmt = SND_SOC_DAIFMT_I2S | \ | ||
225 | SND_SOC_DAIFMT_NB_NF | \ | ||
226 | SND_SOC_DAIFMT_CBS_CFS, \ | ||
246 | .ops = &raumfeld_ak4104_ops, \ | 227 | .ops = &raumfeld_ak4104_ops, \ |
247 | .codec_name = "spi0.0", \ | 228 | .codec_name = "spi0.0", \ |
248 | } | 229 | } |
diff --git a/sound/soc/pxa/spitz.c b/sound/soc/pxa/spitz.c index d7d5fb20ea6f..461123ad5ff2 100644 --- a/sound/soc/pxa/spitz.c +++ b/sound/soc/pxa/spitz.c | |||
@@ -256,26 +256,6 @@ static const struct snd_kcontrol_new wm8750_spitz_controls[] = { | |||
256 | spitz_set_spk), | 256 | spitz_set_spk), |
257 | }; | 257 | }; |
258 | 258 | ||
259 | /* | ||
260 | * Logic for a wm8750 as connected on a Sharp SL-Cxx00 Device | ||
261 | */ | ||
262 | static int spitz_wm8750_init(struct snd_soc_pcm_runtime *rtd) | ||
263 | { | ||
264 | struct snd_soc_codec *codec = rtd->codec; | ||
265 | struct snd_soc_dapm_context *dapm = &codec->dapm; | ||
266 | |||
267 | /* NC codec pins */ | ||
268 | snd_soc_dapm_nc_pin(dapm, "RINPUT1"); | ||
269 | snd_soc_dapm_nc_pin(dapm, "LINPUT2"); | ||
270 | snd_soc_dapm_nc_pin(dapm, "RINPUT2"); | ||
271 | snd_soc_dapm_nc_pin(dapm, "LINPUT3"); | ||
272 | snd_soc_dapm_nc_pin(dapm, "RINPUT3"); | ||
273 | snd_soc_dapm_nc_pin(dapm, "OUT3"); | ||
274 | snd_soc_dapm_nc_pin(dapm, "MONO1"); | ||
275 | |||
276 | return 0; | ||
277 | } | ||
278 | |||
279 | /* spitz digital audio interface glue - connects codec <--> CPU */ | 259 | /* spitz digital audio interface glue - connects codec <--> CPU */ |
280 | static struct snd_soc_dai_link spitz_dai = { | 260 | static struct snd_soc_dai_link spitz_dai = { |
281 | .name = "wm8750", | 261 | .name = "wm8750", |
@@ -284,7 +264,6 @@ static struct snd_soc_dai_link spitz_dai = { | |||
284 | .codec_dai_name = "wm8750-hifi", | 264 | .codec_dai_name = "wm8750-hifi", |
285 | .platform_name = "pxa-pcm-audio", | 265 | .platform_name = "pxa-pcm-audio", |
286 | .codec_name = "wm8750.0-001b", | 266 | .codec_name = "wm8750.0-001b", |
287 | .init = spitz_wm8750_init, | ||
288 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | | 267 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | |
289 | SND_SOC_DAIFMT_CBS_CFS, | 268 | SND_SOC_DAIFMT_CBS_CFS, |
290 | .ops = &spitz_ops, | 269 | .ops = &spitz_ops, |
@@ -303,6 +282,7 @@ static struct snd_soc_card snd_soc_spitz = { | |||
303 | .num_dapm_widgets = ARRAY_SIZE(wm8750_dapm_widgets), | 282 | .num_dapm_widgets = ARRAY_SIZE(wm8750_dapm_widgets), |
304 | .dapm_routes = spitz_audio_map, | 283 | .dapm_routes = spitz_audio_map, |
305 | .num_dapm_routes = ARRAY_SIZE(spitz_audio_map), | 284 | .num_dapm_routes = ARRAY_SIZE(spitz_audio_map), |
285 | .fully_routed = true, | ||
306 | }; | 286 | }; |
307 | 287 | ||
308 | static int spitz_probe(struct platform_device *pdev) | 288 | static int spitz_probe(struct platform_device *pdev) |
@@ -352,7 +332,6 @@ static int spitz_remove(struct platform_device *pdev) | |||
352 | static struct platform_driver spitz_driver = { | 332 | static struct platform_driver spitz_driver = { |
353 | .driver = { | 333 | .driver = { |
354 | .name = "spitz-audio", | 334 | .name = "spitz-audio", |
355 | .owner = THIS_MODULE, | ||
356 | .pm = &snd_soc_pm_ops, | 335 | .pm = &snd_soc_pm_ops, |
357 | }, | 336 | }, |
358 | .probe = spitz_probe, | 337 | .probe = spitz_probe, |
diff --git a/sound/soc/pxa/ttc-dkb.c b/sound/soc/pxa/ttc-dkb.c index e3d7257ad09c..5001dbb9b257 100644 --- a/sound/soc/pxa/ttc-dkb.c +++ b/sound/soc/pxa/ttc-dkb.c | |||
@@ -76,10 +76,6 @@ static const struct snd_soc_dapm_route ttc_audio_map[] = { | |||
76 | static int ttc_pm860x_init(struct snd_soc_pcm_runtime *rtd) | 76 | static int ttc_pm860x_init(struct snd_soc_pcm_runtime *rtd) |
77 | { | 77 | { |
78 | struct snd_soc_codec *codec = rtd->codec; | 78 | struct snd_soc_codec *codec = rtd->codec; |
79 | struct snd_soc_dapm_context *dapm = &codec->dapm; | ||
80 | |||
81 | snd_soc_dapm_disable_pin(dapm, "Headset Mic 2"); | ||
82 | snd_soc_dapm_disable_pin(dapm, "Headset Stereophone"); | ||
83 | 79 | ||
84 | /* Headset jack detection */ | 80 | /* Headset jack detection */ |
85 | snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE | 81 | snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE |
diff --git a/sound/soc/pxa/zylonite.c b/sound/soc/pxa/zylonite.c index 23bf991e95d5..8f301c72ee5e 100644 --- a/sound/soc/pxa/zylonite.c +++ b/sound/soc/pxa/zylonite.c | |||
@@ -130,16 +130,6 @@ static int zylonite_voice_hw_params(struct snd_pcm_substream *substream, | |||
130 | if (ret < 0) | 130 | if (ret < 0) |
131 | return ret; | 131 | return ret; |
132 | 132 | ||
133 | ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | | ||
134 | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); | ||
135 | if (ret < 0) | ||
136 | return ret; | ||
137 | |||
138 | ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | | ||
139 | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); | ||
140 | if (ret < 0) | ||
141 | return ret; | ||
142 | |||
143 | return 0; | 133 | return 0; |
144 | } | 134 | } |
145 | 135 | ||
@@ -172,6 +162,8 @@ static struct snd_soc_dai_link zylonite_dai[] = { | |||
172 | .platform_name = "pxa-pcm-audio", | 162 | .platform_name = "pxa-pcm-audio", |
173 | .cpu_dai_name = "pxa-ssp-dai.2", | 163 | .cpu_dai_name = "pxa-ssp-dai.2", |
174 | .codec_dai_name = "wm9713-voice", | 164 | .codec_dai_name = "wm9713-voice", |
165 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | | ||
166 | SND_SOC_DAIFMT_CBS_CFS, | ||
175 | .ops = &zylonite_voice_ops, | 167 | .ops = &zylonite_voice_ops, |
176 | }, | 168 | }, |
177 | }; | 169 | }; |
diff --git a/sound/soc/rockchip/rockchip_i2s.c b/sound/soc/rockchip/rockchip_i2s.c index 26ec5117b35c..acb5be53bfb4 100644 --- a/sound/soc/rockchip/rockchip_i2s.c +++ b/sound/soc/rockchip/rockchip_i2s.c | |||
@@ -247,6 +247,10 @@ static int rockchip_i2s_hw_params(struct snd_pcm_substream *substream, | |||
247 | 247 | ||
248 | regmap_update_bits(i2s->regmap, I2S_TXCR, I2S_TXCR_VDW_MASK, val); | 248 | regmap_update_bits(i2s->regmap, I2S_TXCR, I2S_TXCR_VDW_MASK, val); |
249 | regmap_update_bits(i2s->regmap, I2S_RXCR, I2S_RXCR_VDW_MASK, val); | 249 | regmap_update_bits(i2s->regmap, I2S_RXCR, I2S_RXCR_VDW_MASK, val); |
250 | regmap_update_bits(i2s->regmap, I2S_DMACR, I2S_DMACR_TDL_MASK, | ||
251 | I2S_DMACR_TDL(16)); | ||
252 | regmap_update_bits(i2s->regmap, I2S_DMACR, I2S_DMACR_RDL_MASK, | ||
253 | I2S_DMACR_RDL(16)); | ||
250 | 254 | ||
251 | return 0; | 255 | return 0; |
252 | } | 256 | } |
@@ -335,6 +339,7 @@ static struct snd_soc_dai_driver rockchip_i2s_dai = { | |||
335 | SNDRV_PCM_FMTBIT_S24_LE), | 339 | SNDRV_PCM_FMTBIT_S24_LE), |
336 | }, | 340 | }, |
337 | .ops = &rockchip_i2s_dai_ops, | 341 | .ops = &rockchip_i2s_dai_ops, |
342 | .symmetric_rates = 1, | ||
338 | }; | 343 | }; |
339 | 344 | ||
340 | static const struct snd_soc_component_driver rockchip_i2s_component = { | 345 | static const struct snd_soc_component_driver rockchip_i2s_component = { |
@@ -454,11 +459,11 @@ static int rockchip_i2s_probe(struct platform_device *pdev) | |||
454 | 459 | ||
455 | i2s->playback_dma_data.addr = res->start + I2S_TXDR; | 460 | i2s->playback_dma_data.addr = res->start + I2S_TXDR; |
456 | i2s->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; | 461 | i2s->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; |
457 | i2s->playback_dma_data.maxburst = 16; | 462 | i2s->playback_dma_data.maxburst = 4; |
458 | 463 | ||
459 | i2s->capture_dma_data.addr = res->start + I2S_RXDR; | 464 | i2s->capture_dma_data.addr = res->start + I2S_RXDR; |
460 | i2s->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; | 465 | i2s->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; |
461 | i2s->capture_dma_data.maxburst = 16; | 466 | i2s->capture_dma_data.maxburst = 4; |
462 | 467 | ||
463 | i2s->dev = &pdev->dev; | 468 | i2s->dev = &pdev->dev; |
464 | dev_set_drvdata(&pdev->dev, i2s); | 469 | dev_set_drvdata(&pdev->dev, i2s); |
diff --git a/sound/soc/rockchip/rockchip_i2s.h b/sound/soc/rockchip/rockchip_i2s.h index 89a5d8bc6ee7..93f456f518a9 100644 --- a/sound/soc/rockchip/rockchip_i2s.h +++ b/sound/soc/rockchip/rockchip_i2s.h | |||
@@ -127,7 +127,7 @@ | |||
127 | #define I2S_DMACR_TDE_DISABLE (0 << I2S_DMACR_TDE_SHIFT) | 127 | #define I2S_DMACR_TDE_DISABLE (0 << I2S_DMACR_TDE_SHIFT) |
128 | #define I2S_DMACR_TDE_ENABLE (1 << I2S_DMACR_TDE_SHIFT) | 128 | #define I2S_DMACR_TDE_ENABLE (1 << I2S_DMACR_TDE_SHIFT) |
129 | #define I2S_DMACR_TDL_SHIFT 0 | 129 | #define I2S_DMACR_TDL_SHIFT 0 |
130 | #define I2S_DMACR_TDL(x) ((x - 1) << I2S_DMACR_TDL_SHIFT) | 130 | #define I2S_DMACR_TDL(x) ((x) << I2S_DMACR_TDL_SHIFT) |
131 | #define I2S_DMACR_TDL_MASK (0x1f << I2S_DMACR_TDL_SHIFT) | 131 | #define I2S_DMACR_TDL_MASK (0x1f << I2S_DMACR_TDL_SHIFT) |
132 | 132 | ||
133 | /* | 133 | /* |
diff --git a/sound/soc/samsung/Kconfig b/sound/soc/samsung/Kconfig index fc67f97f19f6..3cebf6ca03df 100644 --- a/sound/soc/samsung/Kconfig +++ b/sound/soc/samsung/Kconfig | |||
@@ -54,7 +54,7 @@ config SND_SOC_SAMSUNG_JIVE_WM8750 | |||
54 | config SND_SOC_SAMSUNG_SMDK_WM8580 | 54 | config SND_SOC_SAMSUNG_SMDK_WM8580 |
55 | tristate "SoC I2S Audio support for WM8580 on SMDK" | 55 | tristate "SoC I2S Audio support for WM8580 on SMDK" |
56 | depends on SND_SOC_SAMSUNG && (MACH_SMDK6410 || MACH_SMDKC100 || MACH_SMDKV210 || MACH_SMDKC110) | 56 | depends on SND_SOC_SAMSUNG && (MACH_SMDK6410 || MACH_SMDKC100 || MACH_SMDKV210 || MACH_SMDKC110) |
57 | depends on REGMAP_I2C | 57 | depends on I2C |
58 | select SND_SOC_WM8580 | 58 | select SND_SOC_WM8580 |
59 | select SND_SAMSUNG_I2S | 59 | select SND_SAMSUNG_I2S |
60 | help | 60 | help |
@@ -146,17 +146,6 @@ config SND_SOC_SMARTQ | |||
146 | select SND_SAMSUNG_I2S | 146 | select SND_SAMSUNG_I2S |
147 | select SND_SOC_WM8750 | 147 | select SND_SOC_WM8750 |
148 | 148 | ||
149 | config SND_SOC_GONI_AQUILA_WM8994 | ||
150 | tristate "SoC I2S Audio support for AQUILA/GONI - WM8994" | ||
151 | depends on SND_SOC_SAMSUNG && (MACH_GONI || MACH_AQUILA) | ||
152 | depends on I2C=y | ||
153 | select SND_SAMSUNG_I2S | ||
154 | select MFD_WM8994 | ||
155 | select SND_SOC_WM8994 | ||
156 | help | ||
157 | Say Y if you want to add support for SoC audio on goni or aquila | ||
158 | with the WM8994. | ||
159 | |||
160 | config SND_SOC_SAMSUNG_SMDK_SPDIF | 149 | config SND_SOC_SAMSUNG_SMDK_SPDIF |
161 | tristate "SoC S/PDIF Audio support for SMDK" | 150 | tristate "SoC S/PDIF Audio support for SMDK" |
162 | depends on SND_SOC_SAMSUNG | 151 | depends on SND_SOC_SAMSUNG |
@@ -167,7 +156,7 @@ config SND_SOC_SAMSUNG_SMDK_SPDIF | |||
167 | config SND_SOC_SMDK_WM8580_PCM | 156 | config SND_SOC_SMDK_WM8580_PCM |
168 | tristate "SoC PCM Audio support for WM8580 on SMDK" | 157 | tristate "SoC PCM Audio support for WM8580 on SMDK" |
169 | depends on SND_SOC_SAMSUNG && (MACH_SMDKV210 || MACH_SMDKC110) | 158 | depends on SND_SOC_SAMSUNG && (MACH_SMDKV210 || MACH_SMDKC110) |
170 | depends on REGMAP_I2C | 159 | depends on I2C |
171 | select SND_SOC_WM8580 | 160 | select SND_SOC_WM8580 |
172 | select SND_SAMSUNG_PCM | 161 | select SND_SAMSUNG_PCM |
173 | help | 162 | help |
diff --git a/sound/soc/samsung/Makefile b/sound/soc/samsung/Makefile index 31e3dba7e3b5..052fe71be518 100644 --- a/sound/soc/samsung/Makefile +++ b/sound/soc/samsung/Makefile | |||
@@ -35,7 +35,6 @@ snd-soc-smdk-wm8994-objs := smdk_wm8994.o | |||
35 | snd-soc-snow-objs := snow.o | 35 | snd-soc-snow-objs := snow.o |
36 | snd-soc-smdk-wm9713-objs := smdk_wm9713.o | 36 | snd-soc-smdk-wm9713-objs := smdk_wm9713.o |
37 | snd-soc-s3c64xx-smartq-wm8987-objs := smartq_wm8987.o | 37 | snd-soc-s3c64xx-smartq-wm8987-objs := smartq_wm8987.o |
38 | snd-soc-goni-wm8994-objs := goni_wm8994.o | ||
39 | snd-soc-smdk-spdif-objs := smdk_spdif.o | 38 | snd-soc-smdk-spdif-objs := smdk_spdif.o |
40 | snd-soc-smdk-wm8580pcm-objs := smdk_wm8580pcm.o | 39 | snd-soc-smdk-wm8580pcm-objs := smdk_wm8580pcm.o |
41 | snd-soc-smdk-wm8994pcm-objs := smdk_wm8994pcm.o | 40 | snd-soc-smdk-wm8994pcm-objs := smdk_wm8994pcm.o |
@@ -63,7 +62,6 @@ obj-$(CONFIG_SND_SOC_SNOW) += snd-soc-snow.o | |||
63 | obj-$(CONFIG_SND_SOC_SAMSUNG_SMDK_WM9713) += snd-soc-smdk-wm9713.o | 62 | obj-$(CONFIG_SND_SOC_SAMSUNG_SMDK_WM9713) += snd-soc-smdk-wm9713.o |
64 | obj-$(CONFIG_SND_SOC_SMARTQ) += snd-soc-s3c64xx-smartq-wm8987.o | 63 | obj-$(CONFIG_SND_SOC_SMARTQ) += snd-soc-s3c64xx-smartq-wm8987.o |
65 | obj-$(CONFIG_SND_SOC_SAMSUNG_SMDK_SPDIF) += snd-soc-smdk-spdif.o | 64 | obj-$(CONFIG_SND_SOC_SAMSUNG_SMDK_SPDIF) += snd-soc-smdk-spdif.o |
66 | obj-$(CONFIG_SND_SOC_GONI_AQUILA_WM8994) += snd-soc-goni-wm8994.o | ||
67 | obj-$(CONFIG_SND_SOC_SMDK_WM8580_PCM) += snd-soc-smdk-wm8580pcm.o | 65 | obj-$(CONFIG_SND_SOC_SMDK_WM8580_PCM) += snd-soc-smdk-wm8580pcm.o |
68 | obj-$(CONFIG_SND_SOC_SMDK_WM8994_PCM) += snd-soc-smdk-wm8994pcm.o | 66 | obj-$(CONFIG_SND_SOC_SMDK_WM8994_PCM) += snd-soc-smdk-wm8994pcm.o |
69 | obj-$(CONFIG_SND_SOC_SPEYSIDE) += snd-soc-speyside.o | 67 | obj-$(CONFIG_SND_SOC_SPEYSIDE) += snd-soc-speyside.o |
diff --git a/sound/soc/samsung/arndale_rt5631.c b/sound/soc/samsung/arndale_rt5631.c index 1e2b61ca8db2..8bf2e2c4bafb 100644 --- a/sound/soc/samsung/arndale_rt5631.c +++ b/sound/soc/samsung/arndale_rt5631.c | |||
@@ -135,7 +135,6 @@ MODULE_DEVICE_TABLE(of, samsung_arndale_rt5631_of_match); | |||
135 | static struct platform_driver arndale_audio_driver = { | 135 | static struct platform_driver arndale_audio_driver = { |
136 | .driver = { | 136 | .driver = { |
137 | .name = "arndale-audio", | 137 | .name = "arndale-audio", |
138 | .owner = THIS_MODULE, | ||
139 | .pm = &snd_soc_pm_ops, | 138 | .pm = &snd_soc_pm_ops, |
140 | .of_match_table = of_match_ptr(samsung_arndale_rt5631_of_match), | 139 | .of_match_table = of_match_ptr(samsung_arndale_rt5631_of_match), |
141 | }, | 140 | }, |
diff --git a/sound/soc/samsung/goni_wm8994.c b/sound/soc/samsung/goni_wm8994.c deleted file mode 100644 index 3b527dcfc0aa..000000000000 --- a/sound/soc/samsung/goni_wm8994.c +++ /dev/null | |||
@@ -1,304 +0,0 @@ | |||
1 | /* | ||
2 | * goni_wm8994.c | ||
3 | * | ||
4 | * Copyright (C) 2010 Samsung Electronics Co.Ltd | ||
5 | * Author: Chanwoo Choi <cw00.choi@samsung.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | ||
8 | * under the terms of the GNU General Public License as published by the | ||
9 | * Free Software Foundation; either version 2 of the License, or (at your | ||
10 | * option) any later version. | ||
11 | * | ||
12 | */ | ||
13 | |||
14 | #include <linux/module.h> | ||
15 | #include <sound/soc.h> | ||
16 | #include <sound/jack.h> | ||
17 | |||
18 | #include <asm/mach-types.h> | ||
19 | #include <mach/gpio-samsung.h> | ||
20 | |||
21 | #include "../codecs/wm8994.h" | ||
22 | |||
23 | #define MACHINE_NAME 0 | ||
24 | #define CPU_VOICE_DAI 1 | ||
25 | |||
26 | static const char *aquila_str[] = { | ||
27 | [MACHINE_NAME] = "aquila", | ||
28 | [CPU_VOICE_DAI] = "aquila-voice-dai", | ||
29 | }; | ||
30 | |||
31 | static struct snd_soc_card goni; | ||
32 | static struct platform_device *goni_snd_device; | ||
33 | |||
34 | /* 3.5 pie jack */ | ||
35 | static struct snd_soc_jack jack; | ||
36 | |||
37 | /* 3.5 pie jack detection DAPM pins */ | ||
38 | static struct snd_soc_jack_pin jack_pins[] = { | ||
39 | { | ||
40 | .pin = "Headset Mic", | ||
41 | .mask = SND_JACK_MICROPHONE, | ||
42 | }, { | ||
43 | .pin = "Headset Stereophone", | ||
44 | .mask = SND_JACK_HEADPHONE | SND_JACK_MECHANICAL | | ||
45 | SND_JACK_AVOUT, | ||
46 | }, | ||
47 | }; | ||
48 | |||
49 | /* 3.5 pie jack detection gpios */ | ||
50 | static struct snd_soc_jack_gpio jack_gpios[] = { | ||
51 | { | ||
52 | .gpio = S5PV210_GPH0(6), | ||
53 | .name = "DET_3.5", | ||
54 | .report = SND_JACK_HEADSET | SND_JACK_MECHANICAL | | ||
55 | SND_JACK_AVOUT, | ||
56 | .debounce_time = 200, | ||
57 | }, | ||
58 | }; | ||
59 | |||
60 | static const struct snd_soc_dapm_widget goni_dapm_widgets[] = { | ||
61 | SND_SOC_DAPM_SPK("Ext Left Spk", NULL), | ||
62 | SND_SOC_DAPM_SPK("Ext Right Spk", NULL), | ||
63 | SND_SOC_DAPM_SPK("Ext Rcv", NULL), | ||
64 | SND_SOC_DAPM_HP("Headset Stereophone", NULL), | ||
65 | SND_SOC_DAPM_MIC("Headset Mic", NULL), | ||
66 | SND_SOC_DAPM_MIC("Main Mic", NULL), | ||
67 | SND_SOC_DAPM_MIC("2nd Mic", NULL), | ||
68 | SND_SOC_DAPM_LINE("Radio In", NULL), | ||
69 | }; | ||
70 | |||
71 | static const struct snd_soc_dapm_route goni_dapm_routes[] = { | ||
72 | {"Ext Left Spk", NULL, "SPKOUTLP"}, | ||
73 | {"Ext Left Spk", NULL, "SPKOUTLN"}, | ||
74 | |||
75 | {"Ext Right Spk", NULL, "SPKOUTRP"}, | ||
76 | {"Ext Right Spk", NULL, "SPKOUTRN"}, | ||
77 | |||
78 | {"Ext Rcv", NULL, "HPOUT2N"}, | ||
79 | {"Ext Rcv", NULL, "HPOUT2P"}, | ||
80 | |||
81 | {"Headset Stereophone", NULL, "HPOUT1L"}, | ||
82 | {"Headset Stereophone", NULL, "HPOUT1R"}, | ||
83 | |||
84 | {"IN1RN", NULL, "Headset Mic"}, | ||
85 | {"IN1RP", NULL, "Headset Mic"}, | ||
86 | |||
87 | {"IN1RN", NULL, "2nd Mic"}, | ||
88 | {"IN1RP", NULL, "2nd Mic"}, | ||
89 | |||
90 | {"IN1LN", NULL, "Main Mic"}, | ||
91 | {"IN1LP", NULL, "Main Mic"}, | ||
92 | |||
93 | {"IN2LN", NULL, "Radio In"}, | ||
94 | {"IN2RN", NULL, "Radio In"}, | ||
95 | }; | ||
96 | |||
97 | static int goni_wm8994_init(struct snd_soc_pcm_runtime *rtd) | ||
98 | { | ||
99 | struct snd_soc_codec *codec = rtd->codec; | ||
100 | struct snd_soc_dapm_context *dapm = &codec->dapm; | ||
101 | int ret; | ||
102 | |||
103 | /* set endpoints to not connected */ | ||
104 | snd_soc_dapm_nc_pin(dapm, "IN2LP:VXRN"); | ||
105 | snd_soc_dapm_nc_pin(dapm, "IN2RP:VXRP"); | ||
106 | snd_soc_dapm_nc_pin(dapm, "LINEOUT1N"); | ||
107 | snd_soc_dapm_nc_pin(dapm, "LINEOUT1P"); | ||
108 | snd_soc_dapm_nc_pin(dapm, "LINEOUT2N"); | ||
109 | snd_soc_dapm_nc_pin(dapm, "LINEOUT2P"); | ||
110 | |||
111 | if (machine_is_aquila()) { | ||
112 | snd_soc_dapm_nc_pin(dapm, "SPKOUTRN"); | ||
113 | snd_soc_dapm_nc_pin(dapm, "SPKOUTRP"); | ||
114 | } | ||
115 | |||
116 | /* Headset jack detection */ | ||
117 | ret = snd_soc_jack_new(codec, "Headset Jack", | ||
118 | SND_JACK_HEADSET | SND_JACK_MECHANICAL | SND_JACK_AVOUT, | ||
119 | &jack); | ||
120 | if (ret) | ||
121 | return ret; | ||
122 | |||
123 | ret = snd_soc_jack_add_pins(&jack, ARRAY_SIZE(jack_pins), jack_pins); | ||
124 | if (ret) | ||
125 | return ret; | ||
126 | |||
127 | ret = snd_soc_jack_add_gpios(&jack, ARRAY_SIZE(jack_gpios), jack_gpios); | ||
128 | if (ret) | ||
129 | return ret; | ||
130 | |||
131 | return 0; | ||
132 | } | ||
133 | |||
134 | static int goni_hifi_hw_params(struct snd_pcm_substream *substream, | ||
135 | struct snd_pcm_hw_params *params) | ||
136 | { | ||
137 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
138 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | ||
139 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | ||
140 | unsigned int pll_out = 24000000; | ||
141 | int ret = 0; | ||
142 | |||
143 | /* set the cpu DAI configuration */ | ||
144 | ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | | ||
145 | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM); | ||
146 | if (ret < 0) | ||
147 | return ret; | ||
148 | |||
149 | /* set codec DAI configuration */ | ||
150 | ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | | ||
151 | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM); | ||
152 | if (ret < 0) | ||
153 | return ret; | ||
154 | |||
155 | /* set the codec FLL */ | ||
156 | ret = snd_soc_dai_set_pll(codec_dai, WM8994_FLL1, 0, pll_out, | ||
157 | params_rate(params) * 256); | ||
158 | if (ret < 0) | ||
159 | return ret; | ||
160 | |||
161 | /* set the codec system clock */ | ||
162 | ret = snd_soc_dai_set_sysclk(codec_dai, WM8994_SYSCLK_FLL1, | ||
163 | params_rate(params) * 256, SND_SOC_CLOCK_IN); | ||
164 | if (ret < 0) | ||
165 | return ret; | ||
166 | |||
167 | return 0; | ||
168 | } | ||
169 | |||
170 | static struct snd_soc_ops goni_hifi_ops = { | ||
171 | .hw_params = goni_hifi_hw_params, | ||
172 | }; | ||
173 | |||
174 | static int goni_voice_hw_params(struct snd_pcm_substream *substream, | ||
175 | struct snd_pcm_hw_params *params) | ||
176 | { | ||
177 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
178 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | ||
179 | unsigned int pll_out = 24000000; | ||
180 | int ret = 0; | ||
181 | |||
182 | if (params_rate(params) != 8000) | ||
183 | return -EINVAL; | ||
184 | |||
185 | /* set codec DAI configuration */ | ||
186 | ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_LEFT_J | | ||
187 | SND_SOC_DAIFMT_IB_IF | SND_SOC_DAIFMT_CBM_CFM); | ||
188 | if (ret < 0) | ||
189 | return ret; | ||
190 | |||
191 | /* set the codec FLL */ | ||
192 | ret = snd_soc_dai_set_pll(codec_dai, WM8994_FLL2, 0, pll_out, | ||
193 | params_rate(params) * 256); | ||
194 | if (ret < 0) | ||
195 | return ret; | ||
196 | |||
197 | /* set the codec system clock */ | ||
198 | ret = snd_soc_dai_set_sysclk(codec_dai, WM8994_SYSCLK_FLL2, | ||
199 | params_rate(params) * 256, SND_SOC_CLOCK_IN); | ||
200 | if (ret < 0) | ||
201 | return ret; | ||
202 | |||
203 | return 0; | ||
204 | } | ||
205 | |||
206 | static struct snd_soc_dai_driver voice_dai = { | ||
207 | .name = "goni-voice-dai", | ||
208 | .id = 0, | ||
209 | .playback = { | ||
210 | .channels_min = 1, | ||
211 | .channels_max = 2, | ||
212 | .rates = SNDRV_PCM_RATE_8000, | ||
213 | .formats = SNDRV_PCM_FMTBIT_S16_LE,}, | ||
214 | .capture = { | ||
215 | .channels_min = 1, | ||
216 | .channels_max = 2, | ||
217 | .rates = SNDRV_PCM_RATE_8000, | ||
218 | .formats = SNDRV_PCM_FMTBIT_S16_LE,}, | ||
219 | }; | ||
220 | |||
221 | static const struct snd_soc_component_driver voice_component = { | ||
222 | .name = "goni-voice", | ||
223 | }; | ||
224 | |||
225 | static struct snd_soc_ops goni_voice_ops = { | ||
226 | .hw_params = goni_voice_hw_params, | ||
227 | }; | ||
228 | |||
229 | static struct snd_soc_dai_link goni_dai[] = { | ||
230 | { | ||
231 | .name = "WM8994", | ||
232 | .stream_name = "WM8994 HiFi", | ||
233 | .cpu_dai_name = "samsung-i2s.0", | ||
234 | .codec_dai_name = "wm8994-aif1", | ||
235 | .platform_name = "samsung-i2s.0", | ||
236 | .codec_name = "wm8994-codec.0-001a", | ||
237 | .init = goni_wm8994_init, | ||
238 | .ops = &goni_hifi_ops, | ||
239 | }, { | ||
240 | .name = "WM8994 Voice", | ||
241 | .stream_name = "Voice", | ||
242 | .cpu_dai_name = "goni-voice-dai", | ||
243 | .codec_dai_name = "wm8994-aif2", | ||
244 | .codec_name = "wm8994-codec.0-001a", | ||
245 | .ops = &goni_voice_ops, | ||
246 | }, | ||
247 | }; | ||
248 | |||
249 | static struct snd_soc_card goni = { | ||
250 | .name = "goni", | ||
251 | .owner = THIS_MODULE, | ||
252 | .dai_link = goni_dai, | ||
253 | .num_links = ARRAY_SIZE(goni_dai), | ||
254 | |||
255 | .dapm_widgets = goni_dapm_widgets, | ||
256 | .num_dapm_widgets = ARRAY_SIZE(goni_dapm_widgets), | ||
257 | .dapm_routes = goni_dapm_routes, | ||
258 | .num_dapm_routes = ARRAY_SIZE(goni_dapm_routes), | ||
259 | }; | ||
260 | |||
261 | static int __init goni_init(void) | ||
262 | { | ||
263 | int ret; | ||
264 | |||
265 | if (machine_is_aquila()) { | ||
266 | voice_dai.name = aquila_str[CPU_VOICE_DAI]; | ||
267 | goni_dai[1].cpu_dai_name = aquila_str[CPU_VOICE_DAI]; | ||
268 | goni.name = aquila_str[MACHINE_NAME]; | ||
269 | } else if (!machine_is_goni()) | ||
270 | return -ENODEV; | ||
271 | |||
272 | goni_snd_device = platform_device_alloc("soc-audio", -1); | ||
273 | if (!goni_snd_device) | ||
274 | return -ENOMEM; | ||
275 | |||
276 | /* register voice DAI here */ | ||
277 | ret = devm_snd_soc_register_component(&goni_snd_device->dev, | ||
278 | &voice_component, &voice_dai, 1); | ||
279 | if (ret) { | ||
280 | platform_device_put(goni_snd_device); | ||
281 | return ret; | ||
282 | } | ||
283 | |||
284 | platform_set_drvdata(goni_snd_device, &goni); | ||
285 | ret = platform_device_add(goni_snd_device); | ||
286 | |||
287 | if (ret) | ||
288 | platform_device_put(goni_snd_device); | ||
289 | |||
290 | return ret; | ||
291 | } | ||
292 | |||
293 | static void __exit goni_exit(void) | ||
294 | { | ||
295 | platform_device_unregister(goni_snd_device); | ||
296 | } | ||
297 | |||
298 | module_init(goni_init); | ||
299 | module_exit(goni_exit); | ||
300 | |||
301 | /* Module information */ | ||
302 | MODULE_DESCRIPTION("ALSA SoC WM8994 GONI(S5PV210)"); | ||
303 | MODULE_AUTHOR("Chanwoo Choi <cw00.choi@samsung.com>"); | ||
304 | MODULE_LICENSE("GPL"); | ||
diff --git a/sound/soc/samsung/h1940_uda1380.c b/sound/soc/samsung/h1940_uda1380.c index f2d7980d7ddc..59b044255b78 100644 --- a/sound/soc/samsung/h1940_uda1380.c +++ b/sound/soc/samsung/h1940_uda1380.c | |||
@@ -76,7 +76,6 @@ static int h1940_hw_params(struct snd_pcm_substream *substream, | |||
76 | { | 76 | { |
77 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 77 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
78 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | 78 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; |
79 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | ||
80 | int div; | 79 | int div; |
81 | int ret; | 80 | int ret; |
82 | unsigned int rate = params_rate(params); | 81 | unsigned int rate = params_rate(params); |
@@ -95,18 +94,6 @@ static int h1940_hw_params(struct snd_pcm_substream *substream, | |||
95 | return -EINVAL; | 94 | return -EINVAL; |
96 | } | 95 | } |
97 | 96 | ||
98 | /* set codec DAI configuration */ | ||
99 | ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | | ||
100 | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); | ||
101 | if (ret < 0) | ||
102 | return ret; | ||
103 | |||
104 | /* set cpu DAI configuration */ | ||
105 | ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | | ||
106 | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); | ||
107 | if (ret < 0) | ||
108 | return ret; | ||
109 | |||
110 | /* select clock source */ | 97 | /* select clock source */ |
111 | ret = snd_soc_dai_set_sysclk(cpu_dai, S3C24XX_CLKSRC_PCLK, rate, | 98 | ret = snd_soc_dai_set_sysclk(cpu_dai, S3C24XX_CLKSRC_PCLK, rate, |
112 | SND_SOC_CLOCK_OUT); | 99 | SND_SOC_CLOCK_OUT); |
@@ -207,6 +194,8 @@ static struct snd_soc_dai_link h1940_uda1380_dai[] = { | |||
207 | .init = h1940_uda1380_init, | 194 | .init = h1940_uda1380_init, |
208 | .platform_name = "s3c24xx-iis", | 195 | .platform_name = "s3c24xx-iis", |
209 | .codec_name = "uda1380-codec.0-001a", | 196 | .codec_name = "uda1380-codec.0-001a", |
197 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | | ||
198 | SND_SOC_DAIFMT_CBS_CFS, | ||
210 | .ops = &h1940_ops, | 199 | .ops = &h1940_ops, |
211 | }, | 200 | }, |
212 | }; | 201 | }; |
diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c index b5a80c528d86..b92ab40d2be6 100644 --- a/sound/soc/samsung/i2s.c +++ b/sound/soc/samsung/i2s.c | |||
@@ -10,9 +10,11 @@ | |||
10 | * published by the Free Software Foundation. | 10 | * published by the Free Software Foundation. |
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include <dt-bindings/sound/samsung-i2s.h> | ||
13 | #include <linux/delay.h> | 14 | #include <linux/delay.h> |
14 | #include <linux/slab.h> | 15 | #include <linux/slab.h> |
15 | #include <linux/clk.h> | 16 | #include <linux/clk.h> |
17 | #include <linux/clk-provider.h> | ||
16 | #include <linux/io.h> | 18 | #include <linux/io.h> |
17 | #include <linux/module.h> | 19 | #include <linux/module.h> |
18 | #include <linux/of.h> | 20 | #include <linux/of.h> |
@@ -59,10 +61,8 @@ struct samsung_i2s_dai_data { | |||
59 | struct i2s_dai { | 61 | struct i2s_dai { |
60 | /* Platform device for this DAI */ | 62 | /* Platform device for this DAI */ |
61 | struct platform_device *pdev; | 63 | struct platform_device *pdev; |
62 | /* IOREMAP'd SFRs */ | 64 | /* Memory mapped SFR region */ |
63 | void __iomem *addr; | 65 | void __iomem *addr; |
64 | /* Physical base address of SFRs */ | ||
65 | u32 base; | ||
66 | /* Rate of RCLK source clock */ | 66 | /* Rate of RCLK source clock */ |
67 | unsigned long rclk_srcrate; | 67 | unsigned long rclk_srcrate; |
68 | /* Frame Clock */ | 68 | /* Frame Clock */ |
@@ -83,8 +83,6 @@ struct i2s_dai { | |||
83 | #define DAI_OPENED (1 << 0) /* Dai is opened */ | 83 | #define DAI_OPENED (1 << 0) /* Dai is opened */ |
84 | #define DAI_MANAGER (1 << 1) /* Dai is the manager */ | 84 | #define DAI_MANAGER (1 << 1) /* Dai is the manager */ |
85 | unsigned mode; | 85 | unsigned mode; |
86 | /* CDCLK pin direction: 0 - input, 1 - output */ | ||
87 | unsigned int cdclk_out:1; | ||
88 | /* Driver for this DAI */ | 86 | /* Driver for this DAI */ |
89 | struct snd_soc_dai_driver i2s_dai_drv; | 87 | struct snd_soc_dai_driver i2s_dai_drv; |
90 | /* DMA parameters */ | 88 | /* DMA parameters */ |
@@ -95,8 +93,15 @@ struct i2s_dai { | |||
95 | u32 suspend_i2smod; | 93 | u32 suspend_i2smod; |
96 | u32 suspend_i2scon; | 94 | u32 suspend_i2scon; |
97 | u32 suspend_i2spsr; | 95 | u32 suspend_i2spsr; |
98 | unsigned long gpios[7]; /* i2s gpio line numbers */ | ||
99 | const struct samsung_i2s_variant_regs *variant_regs; | 96 | const struct samsung_i2s_variant_regs *variant_regs; |
97 | |||
98 | /* Spinlock protecting access to the device's registers */ | ||
99 | spinlock_t spinlock; | ||
100 | spinlock_t *lock; | ||
101 | |||
102 | /* Below fields are only valid if this is the primary FIFO */ | ||
103 | struct clk *clk_table[3]; | ||
104 | struct clk_onecell_data clk_data; | ||
100 | }; | 105 | }; |
101 | 106 | ||
102 | /* Lock for cross i/f checks */ | 107 | /* Lock for cross i/f checks */ |
@@ -133,10 +138,16 @@ static inline bool tx_active(struct i2s_dai *i2s) | |||
133 | return active ? true : false; | 138 | return active ? true : false; |
134 | } | 139 | } |
135 | 140 | ||
141 | /* Return pointer to the other DAI */ | ||
142 | static inline struct i2s_dai *get_other_dai(struct i2s_dai *i2s) | ||
143 | { | ||
144 | return i2s->pri_dai ? : i2s->sec_dai; | ||
145 | } | ||
146 | |||
136 | /* If the other interface of the controller is transmitting data */ | 147 | /* If the other interface of the controller is transmitting data */ |
137 | static inline bool other_tx_active(struct i2s_dai *i2s) | 148 | static inline bool other_tx_active(struct i2s_dai *i2s) |
138 | { | 149 | { |
139 | struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai; | 150 | struct i2s_dai *other = get_other_dai(i2s); |
140 | 151 | ||
141 | return tx_active(other); | 152 | return tx_active(other); |
142 | } | 153 | } |
@@ -163,7 +174,7 @@ static inline bool rx_active(struct i2s_dai *i2s) | |||
163 | /* If the other interface of the controller is receiving data */ | 174 | /* If the other interface of the controller is receiving data */ |
164 | static inline bool other_rx_active(struct i2s_dai *i2s) | 175 | static inline bool other_rx_active(struct i2s_dai *i2s) |
165 | { | 176 | { |
166 | struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai; | 177 | struct i2s_dai *other = get_other_dai(i2s); |
167 | 178 | ||
168 | return rx_active(other); | 179 | return rx_active(other); |
169 | } | 180 | } |
@@ -464,18 +475,23 @@ static int i2s_set_sysclk(struct snd_soc_dai *dai, | |||
464 | int clk_id, unsigned int rfs, int dir) | 475 | int clk_id, unsigned int rfs, int dir) |
465 | { | 476 | { |
466 | struct i2s_dai *i2s = to_info(dai); | 477 | struct i2s_dai *i2s = to_info(dai); |
467 | struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai; | 478 | struct i2s_dai *other = get_other_dai(i2s); |
468 | u32 mod = readl(i2s->addr + I2SMOD); | ||
469 | const struct samsung_i2s_variant_regs *i2s_regs = i2s->variant_regs; | 479 | const struct samsung_i2s_variant_regs *i2s_regs = i2s->variant_regs; |
470 | unsigned int cdcon_mask = 1 << i2s_regs->cdclkcon_off; | 480 | unsigned int cdcon_mask = 1 << i2s_regs->cdclkcon_off; |
471 | unsigned int rsrc_mask = 1 << i2s_regs->rclksrc_off; | 481 | unsigned int rsrc_mask = 1 << i2s_regs->rclksrc_off; |
482 | u32 mod, mask, val = 0; | ||
483 | |||
484 | spin_lock(i2s->lock); | ||
485 | mod = readl(i2s->addr + I2SMOD); | ||
486 | spin_unlock(i2s->lock); | ||
472 | 487 | ||
473 | switch (clk_id) { | 488 | switch (clk_id) { |
474 | case SAMSUNG_I2S_OPCLK: | 489 | case SAMSUNG_I2S_OPCLK: |
475 | mod &= ~MOD_OPCLK_MASK; | 490 | mask = MOD_OPCLK_MASK; |
476 | mod |= dir; | 491 | val = dir; |
477 | break; | 492 | break; |
478 | case SAMSUNG_I2S_CDCLK: | 493 | case SAMSUNG_I2S_CDCLK: |
494 | mask = 1 << i2s_regs->cdclkcon_off; | ||
479 | /* Shouldn't matter in GATING(CLOCK_IN) mode */ | 495 | /* Shouldn't matter in GATING(CLOCK_IN) mode */ |
480 | if (dir == SND_SOC_CLOCK_IN) | 496 | if (dir == SND_SOC_CLOCK_IN) |
481 | rfs = 0; | 497 | rfs = 0; |
@@ -492,15 +508,15 @@ static int i2s_set_sysclk(struct snd_soc_dai *dai, | |||
492 | } | 508 | } |
493 | 509 | ||
494 | if (dir == SND_SOC_CLOCK_IN) | 510 | if (dir == SND_SOC_CLOCK_IN) |
495 | mod |= 1 << i2s_regs->cdclkcon_off; | 511 | val = 1 << i2s_regs->cdclkcon_off; |
496 | else | ||
497 | mod &= ~(1 << i2s_regs->cdclkcon_off); | ||
498 | 512 | ||
499 | i2s->rfs = rfs; | 513 | i2s->rfs = rfs; |
500 | break; | 514 | break; |
501 | 515 | ||
502 | case SAMSUNG_I2S_RCLKSRC_0: /* clock corrsponding to IISMOD[10] := 0 */ | 516 | case SAMSUNG_I2S_RCLKSRC_0: /* clock corrsponding to IISMOD[10] := 0 */ |
503 | case SAMSUNG_I2S_RCLKSRC_1: /* clock corrsponding to IISMOD[10] := 1 */ | 517 | case SAMSUNG_I2S_RCLKSRC_1: /* clock corrsponding to IISMOD[10] := 1 */ |
518 | mask = 1 << i2s_regs->rclksrc_off; | ||
519 | |||
504 | if ((i2s->quirks & QUIRK_NO_MUXPSR) | 520 | if ((i2s->quirks & QUIRK_NO_MUXPSR) |
505 | || (clk_id == SAMSUNG_I2S_RCLKSRC_0)) | 521 | || (clk_id == SAMSUNG_I2S_RCLKSRC_0)) |
506 | clk_id = 0; | 522 | clk_id = 0; |
@@ -550,18 +566,19 @@ static int i2s_set_sysclk(struct snd_soc_dai *dai, | |||
550 | return 0; | 566 | return 0; |
551 | } | 567 | } |
552 | 568 | ||
553 | if (clk_id == 0) | 569 | if (clk_id == 1) |
554 | mod &= ~(1 << i2s_regs->rclksrc_off); | 570 | val = 1 << i2s_regs->rclksrc_off; |
555 | else | ||
556 | mod |= 1 << i2s_regs->rclksrc_off; | ||
557 | |||
558 | break; | 571 | break; |
559 | default: | 572 | default: |
560 | dev_err(&i2s->pdev->dev, "We don't serve that!\n"); | 573 | dev_err(&i2s->pdev->dev, "We don't serve that!\n"); |
561 | return -EINVAL; | 574 | return -EINVAL; |
562 | } | 575 | } |
563 | 576 | ||
577 | spin_lock(i2s->lock); | ||
578 | mod = readl(i2s->addr + I2SMOD); | ||
579 | mod = (mod & ~mask) | val; | ||
564 | writel(mod, i2s->addr + I2SMOD); | 580 | writel(mod, i2s->addr + I2SMOD); |
581 | spin_unlock(i2s->lock); | ||
565 | 582 | ||
566 | return 0; | 583 | return 0; |
567 | } | 584 | } |
@@ -570,9 +587,8 @@ static int i2s_set_fmt(struct snd_soc_dai *dai, | |||
570 | unsigned int fmt) | 587 | unsigned int fmt) |
571 | { | 588 | { |
572 | struct i2s_dai *i2s = to_info(dai); | 589 | struct i2s_dai *i2s = to_info(dai); |
573 | u32 mod = readl(i2s->addr + I2SMOD); | ||
574 | int lrp_shift, sdf_shift, sdf_mask, lrp_rlow, mod_slave; | 590 | int lrp_shift, sdf_shift, sdf_mask, lrp_rlow, mod_slave; |
575 | u32 tmp = 0; | 591 | u32 mod, tmp = 0; |
576 | 592 | ||
577 | lrp_shift = i2s->variant_regs->lrp_off; | 593 | lrp_shift = i2s->variant_regs->lrp_off; |
578 | sdf_shift = i2s->variant_regs->sdf_off; | 594 | sdf_shift = i2s->variant_regs->sdf_off; |
@@ -632,12 +648,15 @@ static int i2s_set_fmt(struct snd_soc_dai *dai, | |||
632 | return -EINVAL; | 648 | return -EINVAL; |
633 | } | 649 | } |
634 | 650 | ||
651 | spin_lock(i2s->lock); | ||
652 | mod = readl(i2s->addr + I2SMOD); | ||
635 | /* | 653 | /* |
636 | * Don't change the I2S mode if any controller is active on this | 654 | * Don't change the I2S mode if any controller is active on this |
637 | * channel. | 655 | * channel. |
638 | */ | 656 | */ |
639 | if (any_active(i2s) && | 657 | if (any_active(i2s) && |
640 | ((mod & (sdf_mask | lrp_rlow | mod_slave)) != tmp)) { | 658 | ((mod & (sdf_mask | lrp_rlow | mod_slave)) != tmp)) { |
659 | spin_unlock(i2s->lock); | ||
641 | dev_err(&i2s->pdev->dev, | 660 | dev_err(&i2s->pdev->dev, |
642 | "%s:%d Other DAI busy\n", __func__, __LINE__); | 661 | "%s:%d Other DAI busy\n", __func__, __LINE__); |
643 | return -EAGAIN; | 662 | return -EAGAIN; |
@@ -646,6 +665,7 @@ static int i2s_set_fmt(struct snd_soc_dai *dai, | |||
646 | mod &= ~(sdf_mask | lrp_rlow | mod_slave); | 665 | mod &= ~(sdf_mask | lrp_rlow | mod_slave); |
647 | mod |= tmp; | 666 | mod |= tmp; |
648 | writel(mod, i2s->addr + I2SMOD); | 667 | writel(mod, i2s->addr + I2SMOD); |
668 | spin_unlock(i2s->lock); | ||
649 | 669 | ||
650 | return 0; | 670 | return 0; |
651 | } | 671 | } |
@@ -654,16 +674,16 @@ static int i2s_hw_params(struct snd_pcm_substream *substream, | |||
654 | struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) | 674 | struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) |
655 | { | 675 | { |
656 | struct i2s_dai *i2s = to_info(dai); | 676 | struct i2s_dai *i2s = to_info(dai); |
657 | u32 mod = readl(i2s->addr + I2SMOD); | 677 | u32 mod, mask = 0, val = 0; |
658 | 678 | ||
659 | if (!is_secondary(i2s)) | 679 | if (!is_secondary(i2s)) |
660 | mod &= ~(MOD_DC2_EN | MOD_DC1_EN); | 680 | mask |= (MOD_DC2_EN | MOD_DC1_EN); |
661 | 681 | ||
662 | switch (params_channels(params)) { | 682 | switch (params_channels(params)) { |
663 | case 6: | 683 | case 6: |
664 | mod |= MOD_DC2_EN; | 684 | val |= MOD_DC2_EN; |
665 | case 4: | 685 | case 4: |
666 | mod |= MOD_DC1_EN; | 686 | val |= MOD_DC1_EN; |
667 | break; | 687 | break; |
668 | case 2: | 688 | case 2: |
669 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | 689 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) |
@@ -685,44 +705,49 @@ static int i2s_hw_params(struct snd_pcm_substream *substream, | |||
685 | } | 705 | } |
686 | 706 | ||
687 | if (is_secondary(i2s)) | 707 | if (is_secondary(i2s)) |
688 | mod &= ~MOD_BLCS_MASK; | 708 | mask |= MOD_BLCS_MASK; |
689 | else | 709 | else |
690 | mod &= ~MOD_BLCP_MASK; | 710 | mask |= MOD_BLCP_MASK; |
691 | 711 | ||
692 | if (is_manager(i2s)) | 712 | if (is_manager(i2s)) |
693 | mod &= ~MOD_BLC_MASK; | 713 | mask |= MOD_BLC_MASK; |
694 | 714 | ||
695 | switch (params_width(params)) { | 715 | switch (params_width(params)) { |
696 | case 8: | 716 | case 8: |
697 | if (is_secondary(i2s)) | 717 | if (is_secondary(i2s)) |
698 | mod |= MOD_BLCS_8BIT; | 718 | val |= MOD_BLCS_8BIT; |
699 | else | 719 | else |
700 | mod |= MOD_BLCP_8BIT; | 720 | val |= MOD_BLCP_8BIT; |
701 | if (is_manager(i2s)) | 721 | if (is_manager(i2s)) |
702 | mod |= MOD_BLC_8BIT; | 722 | val |= MOD_BLC_8BIT; |
703 | break; | 723 | break; |
704 | case 16: | 724 | case 16: |
705 | if (is_secondary(i2s)) | 725 | if (is_secondary(i2s)) |
706 | mod |= MOD_BLCS_16BIT; | 726 | val |= MOD_BLCS_16BIT; |
707 | else | 727 | else |
708 | mod |= MOD_BLCP_16BIT; | 728 | val |= MOD_BLCP_16BIT; |
709 | if (is_manager(i2s)) | 729 | if (is_manager(i2s)) |
710 | mod |= MOD_BLC_16BIT; | 730 | val |= MOD_BLC_16BIT; |
711 | break; | 731 | break; |
712 | case 24: | 732 | case 24: |
713 | if (is_secondary(i2s)) | 733 | if (is_secondary(i2s)) |
714 | mod |= MOD_BLCS_24BIT; | 734 | val |= MOD_BLCS_24BIT; |
715 | else | 735 | else |
716 | mod |= MOD_BLCP_24BIT; | 736 | val |= MOD_BLCP_24BIT; |
717 | if (is_manager(i2s)) | 737 | if (is_manager(i2s)) |
718 | mod |= MOD_BLC_24BIT; | 738 | val |= MOD_BLC_24BIT; |
719 | break; | 739 | break; |
720 | default: | 740 | default: |
721 | dev_err(&i2s->pdev->dev, "Format(%d) not supported\n", | 741 | dev_err(&i2s->pdev->dev, "Format(%d) not supported\n", |
722 | params_format(params)); | 742 | params_format(params)); |
723 | return -EINVAL; | 743 | return -EINVAL; |
724 | } | 744 | } |
745 | |||
746 | spin_lock(i2s->lock); | ||
747 | mod = readl(i2s->addr + I2SMOD); | ||
748 | mod = (mod & ~mask) | val; | ||
725 | writel(mod, i2s->addr + I2SMOD); | 749 | writel(mod, i2s->addr + I2SMOD); |
750 | spin_unlock(i2s->lock); | ||
726 | 751 | ||
727 | samsung_asoc_init_dma_data(dai, &i2s->dma_playback, &i2s->dma_capture); | 752 | samsung_asoc_init_dma_data(dai, &i2s->dma_playback, &i2s->dma_capture); |
728 | 753 | ||
@@ -736,7 +761,7 @@ static int i2s_startup(struct snd_pcm_substream *substream, | |||
736 | struct snd_soc_dai *dai) | 761 | struct snd_soc_dai *dai) |
737 | { | 762 | { |
738 | struct i2s_dai *i2s = to_info(dai); | 763 | struct i2s_dai *i2s = to_info(dai); |
739 | struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai; | 764 | struct i2s_dai *other = get_other_dai(i2s); |
740 | unsigned long flags; | 765 | unsigned long flags; |
741 | 766 | ||
742 | spin_lock_irqsave(&lock, flags); | 767 | spin_lock_irqsave(&lock, flags); |
@@ -753,9 +778,6 @@ static int i2s_startup(struct snd_pcm_substream *substream, | |||
753 | 778 | ||
754 | spin_unlock_irqrestore(&lock, flags); | 779 | spin_unlock_irqrestore(&lock, flags); |
755 | 780 | ||
756 | if (!is_opened(other) && i2s->cdclk_out) | ||
757 | i2s_set_sysclk(dai, SAMSUNG_I2S_CDCLK, | ||
758 | 0, SND_SOC_CLOCK_OUT); | ||
759 | return 0; | 781 | return 0; |
760 | } | 782 | } |
761 | 783 | ||
@@ -763,38 +785,27 @@ static void i2s_shutdown(struct snd_pcm_substream *substream, | |||
763 | struct snd_soc_dai *dai) | 785 | struct snd_soc_dai *dai) |
764 | { | 786 | { |
765 | struct i2s_dai *i2s = to_info(dai); | 787 | struct i2s_dai *i2s = to_info(dai); |
766 | struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai; | 788 | struct i2s_dai *other = get_other_dai(i2s); |
767 | unsigned long flags; | 789 | unsigned long flags; |
768 | const struct samsung_i2s_variant_regs *i2s_regs = i2s->variant_regs; | ||
769 | 790 | ||
770 | spin_lock_irqsave(&lock, flags); | 791 | spin_lock_irqsave(&lock, flags); |
771 | 792 | ||
772 | i2s->mode &= ~DAI_OPENED; | 793 | i2s->mode &= ~DAI_OPENED; |
773 | i2s->mode &= ~DAI_MANAGER; | 794 | i2s->mode &= ~DAI_MANAGER; |
774 | 795 | ||
775 | if (is_opened(other)) { | 796 | if (is_opened(other)) |
776 | other->mode |= DAI_MANAGER; | 797 | other->mode |= DAI_MANAGER; |
777 | } else { | 798 | |
778 | u32 mod = readl(i2s->addr + I2SMOD); | ||
779 | i2s->cdclk_out = !(mod & (1 << i2s_regs->cdclkcon_off)); | ||
780 | if (other) | ||
781 | other->cdclk_out = i2s->cdclk_out; | ||
782 | } | ||
783 | /* Reset any constraint on RFS and BFS */ | 799 | /* Reset any constraint on RFS and BFS */ |
784 | i2s->rfs = 0; | 800 | i2s->rfs = 0; |
785 | i2s->bfs = 0; | 801 | i2s->bfs = 0; |
786 | 802 | ||
787 | spin_unlock_irqrestore(&lock, flags); | 803 | spin_unlock_irqrestore(&lock, flags); |
788 | |||
789 | /* Gate CDCLK by default */ | ||
790 | if (!is_opened(other)) | ||
791 | i2s_set_sysclk(dai, SAMSUNG_I2S_CDCLK, | ||
792 | 0, SND_SOC_CLOCK_IN); | ||
793 | } | 804 | } |
794 | 805 | ||
795 | static int config_setup(struct i2s_dai *i2s) | 806 | static int config_setup(struct i2s_dai *i2s) |
796 | { | 807 | { |
797 | struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai; | 808 | struct i2s_dai *other = get_other_dai(i2s); |
798 | unsigned rfs, bfs, blc; | 809 | unsigned rfs, bfs, blc; |
799 | u32 psr; | 810 | u32 psr; |
800 | 811 | ||
@@ -864,10 +875,10 @@ static int i2s_trigger(struct snd_pcm_substream *substream, | |||
864 | case SNDRV_PCM_TRIGGER_START: | 875 | case SNDRV_PCM_TRIGGER_START: |
865 | case SNDRV_PCM_TRIGGER_RESUME: | 876 | case SNDRV_PCM_TRIGGER_RESUME: |
866 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | 877 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: |
867 | local_irq_save(flags); | 878 | spin_lock_irqsave(i2s->lock, flags); |
868 | 879 | ||
869 | if (config_setup(i2s)) { | 880 | if (config_setup(i2s)) { |
870 | local_irq_restore(flags); | 881 | spin_unlock_irqrestore(i2s->lock, flags); |
871 | return -EINVAL; | 882 | return -EINVAL; |
872 | } | 883 | } |
873 | 884 | ||
@@ -876,12 +887,12 @@ static int i2s_trigger(struct snd_pcm_substream *substream, | |||
876 | else | 887 | else |
877 | i2s_txctrl(i2s, 1); | 888 | i2s_txctrl(i2s, 1); |
878 | 889 | ||
879 | local_irq_restore(flags); | 890 | spin_unlock_irqrestore(i2s->lock, flags); |
880 | break; | 891 | break; |
881 | case SNDRV_PCM_TRIGGER_STOP: | 892 | case SNDRV_PCM_TRIGGER_STOP: |
882 | case SNDRV_PCM_TRIGGER_SUSPEND: | 893 | case SNDRV_PCM_TRIGGER_SUSPEND: |
883 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: | 894 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: |
884 | local_irq_save(flags); | 895 | spin_lock_irqsave(i2s->lock, flags); |
885 | 896 | ||
886 | if (capture) { | 897 | if (capture) { |
887 | i2s_rxctrl(i2s, 0); | 898 | i2s_rxctrl(i2s, 0); |
@@ -891,7 +902,7 @@ static int i2s_trigger(struct snd_pcm_substream *substream, | |||
891 | i2s_fifo(i2s, FIC_TXFLUSH); | 902 | i2s_fifo(i2s, FIC_TXFLUSH); |
892 | } | 903 | } |
893 | 904 | ||
894 | local_irq_restore(flags); | 905 | spin_unlock_irqrestore(i2s->lock, flags); |
895 | break; | 906 | break; |
896 | } | 907 | } |
897 | 908 | ||
@@ -902,7 +913,7 @@ static int i2s_set_clkdiv(struct snd_soc_dai *dai, | |||
902 | int div_id, int div) | 913 | int div_id, int div) |
903 | { | 914 | { |
904 | struct i2s_dai *i2s = to_info(dai); | 915 | struct i2s_dai *i2s = to_info(dai); |
905 | struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai; | 916 | struct i2s_dai *other = get_other_dai(i2s); |
906 | 917 | ||
907 | switch (div_id) { | 918 | switch (div_id) { |
908 | case SAMSUNG_I2S_DIV_BCLK: | 919 | case SAMSUNG_I2S_DIV_BCLK: |
@@ -971,58 +982,36 @@ static int i2s_resume(struct snd_soc_dai *dai) | |||
971 | static int samsung_i2s_dai_probe(struct snd_soc_dai *dai) | 982 | static int samsung_i2s_dai_probe(struct snd_soc_dai *dai) |
972 | { | 983 | { |
973 | struct i2s_dai *i2s = to_info(dai); | 984 | struct i2s_dai *i2s = to_info(dai); |
974 | struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai; | 985 | struct i2s_dai *other = get_other_dai(i2s); |
975 | int ret; | 986 | unsigned long flags; |
976 | 987 | ||
977 | if (other && other->clk) { /* If this is probe on secondary */ | 988 | if (is_secondary(i2s)) { /* If this is probe on the secondary DAI */ |
978 | samsung_asoc_init_dma_data(dai, &other->sec_dai->dma_playback, | 989 | samsung_asoc_init_dma_data(dai, &other->sec_dai->dma_playback, |
979 | NULL); | 990 | NULL); |
980 | goto probe_exit; | 991 | } else { |
981 | } | 992 | samsung_asoc_init_dma_data(dai, &i2s->dma_playback, |
982 | 993 | &i2s->dma_capture); | |
983 | i2s->addr = ioremap(i2s->base, 0x100); | ||
984 | if (i2s->addr == NULL) { | ||
985 | dev_err(&i2s->pdev->dev, "cannot ioremap registers\n"); | ||
986 | return -ENXIO; | ||
987 | } | ||
988 | |||
989 | i2s->clk = clk_get(&i2s->pdev->dev, "iis"); | ||
990 | if (IS_ERR(i2s->clk)) { | ||
991 | dev_err(&i2s->pdev->dev, "failed to get i2s_clock\n"); | ||
992 | iounmap(i2s->addr); | ||
993 | return PTR_ERR(i2s->clk); | ||
994 | } | ||
995 | |||
996 | ret = clk_prepare_enable(i2s->clk); | ||
997 | if (ret != 0) { | ||
998 | dev_err(&i2s->pdev->dev, "failed to enable clock: %d\n", ret); | ||
999 | return ret; | ||
1000 | } | ||
1001 | |||
1002 | samsung_asoc_init_dma_data(dai, &i2s->dma_playback, &i2s->dma_capture); | ||
1003 | |||
1004 | if (other) { | ||
1005 | other->addr = i2s->addr; | ||
1006 | other->clk = i2s->clk; | ||
1007 | } | ||
1008 | 994 | ||
1009 | if (i2s->quirks & QUIRK_NEED_RSTCLR) | 995 | if (i2s->quirks & QUIRK_NEED_RSTCLR) |
1010 | writel(CON_RSTCLR, i2s->addr + I2SCON); | 996 | writel(CON_RSTCLR, i2s->addr + I2SCON); |
1011 | 997 | ||
1012 | if (i2s->quirks & QUIRK_SUPPORTS_IDMA) | 998 | if (i2s->quirks & QUIRK_SUPPORTS_IDMA) |
1013 | idma_reg_addr_init(i2s->addr, | 999 | idma_reg_addr_init(i2s->addr, |
1014 | i2s->sec_dai->idma_playback.dma_addr); | 1000 | i2s->sec_dai->idma_playback.dma_addr); |
1001 | } | ||
1015 | 1002 | ||
1016 | probe_exit: | ||
1017 | /* Reset any constraint on RFS and BFS */ | 1003 | /* Reset any constraint on RFS and BFS */ |
1018 | i2s->rfs = 0; | 1004 | i2s->rfs = 0; |
1019 | i2s->bfs = 0; | 1005 | i2s->bfs = 0; |
1020 | i2s->rclk_srcrate = 0; | 1006 | i2s->rclk_srcrate = 0; |
1007 | |||
1008 | spin_lock_irqsave(i2s->lock, flags); | ||
1021 | i2s_txctrl(i2s, 0); | 1009 | i2s_txctrl(i2s, 0); |
1022 | i2s_rxctrl(i2s, 0); | 1010 | i2s_rxctrl(i2s, 0); |
1023 | i2s_fifo(i2s, FIC_TXFLUSH); | 1011 | i2s_fifo(i2s, FIC_TXFLUSH); |
1024 | i2s_fifo(other, FIC_TXFLUSH); | 1012 | i2s_fifo(other, FIC_TXFLUSH); |
1025 | i2s_fifo(i2s, FIC_RXFLUSH); | 1013 | i2s_fifo(i2s, FIC_RXFLUSH); |
1014 | spin_unlock_irqrestore(i2s->lock, flags); | ||
1026 | 1015 | ||
1027 | /* Gate CDCLK by default */ | 1016 | /* Gate CDCLK by default */ |
1028 | if (!is_opened(other)) | 1017 | if (!is_opened(other)) |
@@ -1035,21 +1024,15 @@ probe_exit: | |||
1035 | static int samsung_i2s_dai_remove(struct snd_soc_dai *dai) | 1024 | static int samsung_i2s_dai_remove(struct snd_soc_dai *dai) |
1036 | { | 1025 | { |
1037 | struct i2s_dai *i2s = snd_soc_dai_get_drvdata(dai); | 1026 | struct i2s_dai *i2s = snd_soc_dai_get_drvdata(dai); |
1038 | struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai; | ||
1039 | |||
1040 | if (!other || !other->clk) { | ||
1041 | 1027 | ||
1042 | if (i2s->quirks & QUIRK_NEED_RSTCLR) | 1028 | if (!is_secondary(i2s)) { |
1029 | if (i2s->quirks & QUIRK_NEED_RSTCLR) { | ||
1030 | spin_lock(i2s->lock); | ||
1043 | writel(0, i2s->addr + I2SCON); | 1031 | writel(0, i2s->addr + I2SCON); |
1044 | 1032 | spin_unlock(i2s->lock); | |
1045 | clk_disable_unprepare(i2s->clk); | 1033 | } |
1046 | clk_put(i2s->clk); | ||
1047 | |||
1048 | iounmap(i2s->addr); | ||
1049 | } | 1034 | } |
1050 | 1035 | ||
1051 | i2s->clk = NULL; | ||
1052 | |||
1053 | return 0; | 1036 | return 0; |
1054 | } | 1037 | } |
1055 | 1038 | ||
@@ -1124,15 +1107,14 @@ static const struct of_device_id exynos_i2s_match[]; | |||
1124 | static inline const struct samsung_i2s_dai_data *samsung_i2s_get_driver_data( | 1107 | static inline const struct samsung_i2s_dai_data *samsung_i2s_get_driver_data( |
1125 | struct platform_device *pdev) | 1108 | struct platform_device *pdev) |
1126 | { | 1109 | { |
1127 | #ifdef CONFIG_OF | 1110 | if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node) { |
1128 | if (pdev->dev.of_node) { | ||
1129 | const struct of_device_id *match; | 1111 | const struct of_device_id *match; |
1130 | match = of_match_node(exynos_i2s_match, pdev->dev.of_node); | 1112 | match = of_match_node(exynos_i2s_match, pdev->dev.of_node); |
1131 | return match->data; | 1113 | return match ? match->data : NULL; |
1132 | } else | 1114 | } else { |
1133 | #endif | ||
1134 | return (struct samsung_i2s_dai_data *) | 1115 | return (struct samsung_i2s_dai_data *) |
1135 | platform_get_device_id(pdev)->driver_data; | 1116 | platform_get_device_id(pdev)->driver_data; |
1117 | } | ||
1136 | } | 1118 | } |
1137 | 1119 | ||
1138 | #ifdef CONFIG_PM | 1120 | #ifdef CONFIG_PM |
@@ -1155,6 +1137,87 @@ static int i2s_runtime_resume(struct device *dev) | |||
1155 | } | 1137 | } |
1156 | #endif /* CONFIG_PM */ | 1138 | #endif /* CONFIG_PM */ |
1157 | 1139 | ||
1140 | static void i2s_unregister_clocks(struct i2s_dai *i2s) | ||
1141 | { | ||
1142 | int i; | ||
1143 | |||
1144 | for (i = 0; i < i2s->clk_data.clk_num; i++) { | ||
1145 | if (!IS_ERR(i2s->clk_table[i])) | ||
1146 | clk_unregister(i2s->clk_table[i]); | ||
1147 | } | ||
1148 | } | ||
1149 | |||
1150 | static void i2s_unregister_clock_provider(struct platform_device *pdev) | ||
1151 | { | ||
1152 | struct i2s_dai *i2s = dev_get_drvdata(&pdev->dev); | ||
1153 | |||
1154 | of_clk_del_provider(pdev->dev.of_node); | ||
1155 | i2s_unregister_clocks(i2s); | ||
1156 | } | ||
1157 | |||
1158 | static int i2s_register_clock_provider(struct platform_device *pdev) | ||
1159 | { | ||
1160 | struct device *dev = &pdev->dev; | ||
1161 | struct i2s_dai *i2s = dev_get_drvdata(dev); | ||
1162 | const char *clk_name[2] = { "i2s_opclk0", "i2s_opclk1" }; | ||
1163 | const char *p_names[2] = { NULL }; | ||
1164 | const struct samsung_i2s_variant_regs *reg_info = i2s->variant_regs; | ||
1165 | struct clk *rclksrc; | ||
1166 | int ret, i; | ||
1167 | |||
1168 | /* Register the clock provider only if it's expected in the DTB */ | ||
1169 | if (!of_find_property(dev->of_node, "#clock-cells", NULL)) | ||
1170 | return 0; | ||
1171 | |||
1172 | /* Get the RCLKSRC mux clock parent clock names */ | ||
1173 | for (i = 0; i < ARRAY_SIZE(p_names); i++) { | ||
1174 | rclksrc = clk_get(dev, clk_name[i]); | ||
1175 | if (IS_ERR(rclksrc)) | ||
1176 | continue; | ||
1177 | p_names[i] = __clk_get_name(rclksrc); | ||
1178 | clk_put(rclksrc); | ||
1179 | } | ||
1180 | |||
1181 | if (!(i2s->quirks & QUIRK_NO_MUXPSR)) { | ||
1182 | /* Activate the prescaler */ | ||
1183 | u32 val = readl(i2s->addr + I2SPSR); | ||
1184 | writel(val | PSR_PSREN, i2s->addr + I2SPSR); | ||
1185 | |||
1186 | i2s->clk_table[CLK_I2S_RCLK_SRC] = clk_register_mux(NULL, | ||
1187 | "i2s_rclksrc", p_names, ARRAY_SIZE(p_names), | ||
1188 | CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_PARENT, | ||
1189 | i2s->addr + I2SMOD, reg_info->rclksrc_off, | ||
1190 | 1, 0, i2s->lock); | ||
1191 | |||
1192 | i2s->clk_table[CLK_I2S_RCLK_PSR] = clk_register_divider(NULL, | ||
1193 | "i2s_presc", "i2s_rclksrc", | ||
1194 | CLK_SET_RATE_PARENT, | ||
1195 | i2s->addr + I2SPSR, 8, 6, 0, i2s->lock); | ||
1196 | |||
1197 | p_names[0] = "i2s_presc"; | ||
1198 | i2s->clk_data.clk_num = 2; | ||
1199 | } | ||
1200 | of_property_read_string_index(dev->of_node, | ||
1201 | "clock-output-names", 0, &clk_name[0]); | ||
1202 | |||
1203 | i2s->clk_table[CLK_I2S_CDCLK] = clk_register_gate(NULL, clk_name[0], | ||
1204 | p_names[0], CLK_SET_RATE_PARENT, | ||
1205 | i2s->addr + I2SMOD, reg_info->cdclkcon_off, | ||
1206 | CLK_GATE_SET_TO_DISABLE, i2s->lock); | ||
1207 | |||
1208 | i2s->clk_data.clk_num += 1; | ||
1209 | i2s->clk_data.clks = i2s->clk_table; | ||
1210 | |||
1211 | ret = of_clk_add_provider(dev->of_node, of_clk_src_onecell_get, | ||
1212 | &i2s->clk_data); | ||
1213 | if (ret < 0) { | ||
1214 | dev_err(dev, "failed to add clock provider: %d\n", ret); | ||
1215 | i2s_unregister_clocks(i2s); | ||
1216 | } | ||
1217 | |||
1218 | return ret; | ||
1219 | } | ||
1220 | |||
1158 | static int samsung_i2s_probe(struct platform_device *pdev) | 1221 | static int samsung_i2s_probe(struct platform_device *pdev) |
1159 | { | 1222 | { |
1160 | struct i2s_dai *pri_dai, *sec_dai = NULL; | 1223 | struct i2s_dai *pri_dai, *sec_dai = NULL; |
@@ -1164,7 +1227,7 @@ static int samsung_i2s_probe(struct platform_device *pdev) | |||
1164 | u32 regs_base, quirks = 0, idma_addr = 0; | 1227 | u32 regs_base, quirks = 0, idma_addr = 0; |
1165 | struct device_node *np = pdev->dev.of_node; | 1228 | struct device_node *np = pdev->dev.of_node; |
1166 | const struct samsung_i2s_dai_data *i2s_dai_data; | 1229 | const struct samsung_i2s_dai_data *i2s_dai_data; |
1167 | int ret = 0; | 1230 | int ret; |
1168 | 1231 | ||
1169 | /* Call during Seconday interface registration */ | 1232 | /* Call during Seconday interface registration */ |
1170 | i2s_dai_data = samsung_i2s_get_driver_data(pdev); | 1233 | i2s_dai_data = samsung_i2s_get_driver_data(pdev); |
@@ -1175,11 +1238,13 @@ static int samsung_i2s_probe(struct platform_device *pdev) | |||
1175 | dev_err(&pdev->dev, "Unable to get drvdata\n"); | 1238 | dev_err(&pdev->dev, "Unable to get drvdata\n"); |
1176 | return -EFAULT; | 1239 | return -EFAULT; |
1177 | } | 1240 | } |
1178 | devm_snd_soc_register_component(&sec_dai->pdev->dev, | 1241 | ret = devm_snd_soc_register_component(&sec_dai->pdev->dev, |
1179 | &samsung_i2s_component, | 1242 | &samsung_i2s_component, |
1180 | &sec_dai->i2s_dai_drv, 1); | 1243 | &sec_dai->i2s_dai_drv, 1); |
1181 | samsung_asoc_dma_platform_register(&pdev->dev); | 1244 | if (ret != 0) |
1182 | return 0; | 1245 | return ret; |
1246 | |||
1247 | return samsung_asoc_dma_platform_register(&pdev->dev); | ||
1183 | } | 1248 | } |
1184 | 1249 | ||
1185 | pri_dai = i2s_alloc_dai(pdev, false); | 1250 | pri_dai = i2s_alloc_dai(pdev, false); |
@@ -1188,6 +1253,9 @@ static int samsung_i2s_probe(struct platform_device *pdev) | |||
1188 | return -ENOMEM; | 1253 | return -ENOMEM; |
1189 | } | 1254 | } |
1190 | 1255 | ||
1256 | spin_lock_init(&pri_dai->spinlock); | ||
1257 | pri_dai->lock = &pri_dai->spinlock; | ||
1258 | |||
1191 | if (!np) { | 1259 | if (!np) { |
1192 | res = platform_get_resource(pdev, IORESOURCE_DMA, 0); | 1260 | res = platform_get_resource(pdev, IORESOURCE_DMA, 0); |
1193 | if (!res) { | 1261 | if (!res) { |
@@ -1229,25 +1297,29 @@ static int samsung_i2s_probe(struct platform_device *pdev) | |||
1229 | } | 1297 | } |
1230 | 1298 | ||
1231 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1299 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
1232 | if (!res) { | 1300 | pri_dai->addr = devm_ioremap_resource(&pdev->dev, res); |
1233 | dev_err(&pdev->dev, "Unable to get I2S SFR address\n"); | 1301 | if (IS_ERR(pri_dai->addr)) |
1234 | return -ENXIO; | 1302 | return PTR_ERR(pri_dai->addr); |
1235 | } | ||
1236 | 1303 | ||
1237 | if (!request_mem_region(res->start, resource_size(res), | ||
1238 | "samsung-i2s")) { | ||
1239 | dev_err(&pdev->dev, "Unable to request SFR region\n"); | ||
1240 | return -EBUSY; | ||
1241 | } | ||
1242 | regs_base = res->start; | 1304 | regs_base = res->start; |
1243 | 1305 | ||
1306 | pri_dai->clk = devm_clk_get(&pdev->dev, "iis"); | ||
1307 | if (IS_ERR(pri_dai->clk)) { | ||
1308 | dev_err(&pdev->dev, "Failed to get iis clock\n"); | ||
1309 | return PTR_ERR(pri_dai->clk); | ||
1310 | } | ||
1311 | |||
1312 | ret = clk_prepare_enable(pri_dai->clk); | ||
1313 | if (ret != 0) { | ||
1314 | dev_err(&pdev->dev, "failed to enable clock: %d\n", ret); | ||
1315 | return ret; | ||
1316 | } | ||
1244 | pri_dai->dma_playback.dma_addr = regs_base + I2STXD; | 1317 | pri_dai->dma_playback.dma_addr = regs_base + I2STXD; |
1245 | pri_dai->dma_capture.dma_addr = regs_base + I2SRXD; | 1318 | pri_dai->dma_capture.dma_addr = regs_base + I2SRXD; |
1246 | pri_dai->dma_playback.ch_name = "tx"; | 1319 | pri_dai->dma_playback.ch_name = "tx"; |
1247 | pri_dai->dma_capture.ch_name = "rx"; | 1320 | pri_dai->dma_capture.ch_name = "rx"; |
1248 | pri_dai->dma_playback.dma_size = 4; | 1321 | pri_dai->dma_playback.dma_size = 4; |
1249 | pri_dai->dma_capture.dma_size = 4; | 1322 | pri_dai->dma_capture.dma_size = 4; |
1250 | pri_dai->base = regs_base; | ||
1251 | pri_dai->quirks = quirks; | 1323 | pri_dai->quirks = quirks; |
1252 | pri_dai->variant_regs = i2s_dai_data->i2s_variant_regs; | 1324 | pri_dai->variant_regs = i2s_dai_data->i2s_variant_regs; |
1253 | 1325 | ||
@@ -1258,10 +1330,10 @@ static int samsung_i2s_probe(struct platform_device *pdev) | |||
1258 | sec_dai = i2s_alloc_dai(pdev, true); | 1330 | sec_dai = i2s_alloc_dai(pdev, true); |
1259 | if (!sec_dai) { | 1331 | if (!sec_dai) { |
1260 | dev_err(&pdev->dev, "Unable to alloc I2S_sec\n"); | 1332 | dev_err(&pdev->dev, "Unable to alloc I2S_sec\n"); |
1261 | ret = -ENOMEM; | 1333 | return -ENOMEM; |
1262 | goto err; | ||
1263 | } | 1334 | } |
1264 | 1335 | ||
1336 | sec_dai->lock = &pri_dai->spinlock; | ||
1265 | sec_dai->variant_regs = pri_dai->variant_regs; | 1337 | sec_dai->variant_regs = pri_dai->variant_regs; |
1266 | sec_dai->dma_playback.dma_addr = regs_base + I2STXDS; | 1338 | sec_dai->dma_playback.dma_addr = regs_base + I2STXDS; |
1267 | sec_dai->dma_playback.ch_name = "tx-sec"; | 1339 | sec_dai->dma_playback.ch_name = "tx-sec"; |
@@ -1273,7 +1345,8 @@ static int samsung_i2s_probe(struct platform_device *pdev) | |||
1273 | } | 1345 | } |
1274 | 1346 | ||
1275 | sec_dai->dma_playback.dma_size = 4; | 1347 | sec_dai->dma_playback.dma_size = 4; |
1276 | sec_dai->base = regs_base; | 1348 | sec_dai->addr = pri_dai->addr; |
1349 | sec_dai->clk = pri_dai->clk; | ||
1277 | sec_dai->quirks = quirks; | 1350 | sec_dai->quirks = quirks; |
1278 | sec_dai->idma_playback.dma_addr = idma_addr; | 1351 | sec_dai->idma_playback.dma_addr = idma_addr; |
1279 | sec_dai->pri_dai = pri_dai; | 1352 | sec_dai->pri_dai = pri_dai; |
@@ -1282,8 +1355,7 @@ static int samsung_i2s_probe(struct platform_device *pdev) | |||
1282 | 1355 | ||
1283 | if (i2s_pdata && i2s_pdata->cfg_gpio && i2s_pdata->cfg_gpio(pdev)) { | 1356 | if (i2s_pdata && i2s_pdata->cfg_gpio && i2s_pdata->cfg_gpio(pdev)) { |
1284 | dev_err(&pdev->dev, "Unable to configure gpio\n"); | 1357 | dev_err(&pdev->dev, "Unable to configure gpio\n"); |
1285 | ret = -EINVAL; | 1358 | return -EINVAL; |
1286 | goto err; | ||
1287 | } | 1359 | } |
1288 | 1360 | ||
1289 | devm_snd_soc_register_component(&pri_dai->pdev->dev, | 1361 | devm_snd_soc_register_component(&pri_dai->pdev->dev, |
@@ -1292,32 +1364,30 @@ static int samsung_i2s_probe(struct platform_device *pdev) | |||
1292 | 1364 | ||
1293 | pm_runtime_enable(&pdev->dev); | 1365 | pm_runtime_enable(&pdev->dev); |
1294 | 1366 | ||
1295 | samsung_asoc_dma_platform_register(&pdev->dev); | 1367 | ret = samsung_asoc_dma_platform_register(&pdev->dev); |
1296 | 1368 | if (ret != 0) | |
1297 | return 0; | 1369 | return ret; |
1298 | err: | ||
1299 | if (res) | ||
1300 | release_mem_region(regs_base, resource_size(res)); | ||
1301 | 1370 | ||
1302 | return ret; | 1371 | return i2s_register_clock_provider(pdev); |
1303 | } | 1372 | } |
1304 | 1373 | ||
1305 | static int samsung_i2s_remove(struct platform_device *pdev) | 1374 | static int samsung_i2s_remove(struct platform_device *pdev) |
1306 | { | 1375 | { |
1307 | struct i2s_dai *i2s, *other; | 1376 | struct i2s_dai *i2s, *other; |
1308 | struct resource *res; | ||
1309 | 1377 | ||
1310 | i2s = dev_get_drvdata(&pdev->dev); | 1378 | i2s = dev_get_drvdata(&pdev->dev); |
1311 | other = i2s->pri_dai ? : i2s->sec_dai; | 1379 | other = get_other_dai(i2s); |
1312 | 1380 | ||
1313 | if (other) { | 1381 | if (other) { |
1314 | other->pri_dai = NULL; | 1382 | other->pri_dai = NULL; |
1315 | other->sec_dai = NULL; | 1383 | other->sec_dai = NULL; |
1316 | } else { | 1384 | } else { |
1317 | pm_runtime_disable(&pdev->dev); | 1385 | pm_runtime_disable(&pdev->dev); |
1318 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1386 | } |
1319 | if (res) | 1387 | |
1320 | release_mem_region(res->start, resource_size(res)); | 1388 | if (!is_secondary(i2s)) { |
1389 | i2s_unregister_clock_provider(pdev); | ||
1390 | clk_disable_unprepare(i2s->clk); | ||
1321 | } | 1391 | } |
1322 | 1392 | ||
1323 | i2s->pri_dai = NULL; | 1393 | i2s->pri_dai = NULL; |
diff --git a/sound/soc/samsung/jive_wm8750.c b/sound/soc/samsung/jive_wm8750.c index b5f6abd9d221..7fcb51faa2a0 100644 --- a/sound/soc/samsung/jive_wm8750.c +++ b/sound/soc/samsung/jive_wm8750.c | |||
@@ -61,20 +61,6 @@ static int jive_hw_params(struct snd_pcm_substream *substream, | |||
61 | s3c_i2sv2_iis_calc_rate(&div, NULL, params_rate(params), | 61 | s3c_i2sv2_iis_calc_rate(&div, NULL, params_rate(params), |
62 | s3c_i2sv2_get_clock(cpu_dai)); | 62 | s3c_i2sv2_get_clock(cpu_dai)); |
63 | 63 | ||
64 | /* set codec DAI configuration */ | ||
65 | ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | | ||
66 | SND_SOC_DAIFMT_NB_NF | | ||
67 | SND_SOC_DAIFMT_CBS_CFS); | ||
68 | if (ret < 0) | ||
69 | return ret; | ||
70 | |||
71 | /* set cpu DAI configuration */ | ||
72 | ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | | ||
73 | SND_SOC_DAIFMT_NB_NF | | ||
74 | SND_SOC_DAIFMT_CBS_CFS); | ||
75 | if (ret < 0) | ||
76 | return ret; | ||
77 | |||
78 | /* set the codec system clock for DAC and ADC */ | 64 | /* set the codec system clock for DAC and ADC */ |
79 | ret = snd_soc_dai_set_sysclk(codec_dai, WM8750_SYSCLK, clk, | 65 | ret = snd_soc_dai_set_sysclk(codec_dai, WM8750_SYSCLK, clk, |
80 | SND_SOC_CLOCK_IN); | 66 | SND_SOC_CLOCK_IN); |
@@ -97,22 +83,6 @@ static struct snd_soc_ops jive_ops = { | |||
97 | .hw_params = jive_hw_params, | 83 | .hw_params = jive_hw_params, |
98 | }; | 84 | }; |
99 | 85 | ||
100 | static int jive_wm8750_init(struct snd_soc_pcm_runtime *rtd) | ||
101 | { | ||
102 | struct snd_soc_codec *codec = rtd->codec; | ||
103 | struct snd_soc_dapm_context *dapm = &codec->dapm; | ||
104 | |||
105 | /* These endpoints are not being used. */ | ||
106 | snd_soc_dapm_nc_pin(dapm, "LINPUT2"); | ||
107 | snd_soc_dapm_nc_pin(dapm, "RINPUT2"); | ||
108 | snd_soc_dapm_nc_pin(dapm, "LINPUT3"); | ||
109 | snd_soc_dapm_nc_pin(dapm, "RINPUT3"); | ||
110 | snd_soc_dapm_nc_pin(dapm, "OUT3"); | ||
111 | snd_soc_dapm_nc_pin(dapm, "MONO"); | ||
112 | |||
113 | return 0; | ||
114 | } | ||
115 | |||
116 | static struct snd_soc_dai_link jive_dai = { | 86 | static struct snd_soc_dai_link jive_dai = { |
117 | .name = "wm8750", | 87 | .name = "wm8750", |
118 | .stream_name = "WM8750", | 88 | .stream_name = "WM8750", |
@@ -120,7 +90,8 @@ static struct snd_soc_dai_link jive_dai = { | |||
120 | .codec_dai_name = "wm8750-hifi", | 90 | .codec_dai_name = "wm8750-hifi", |
121 | .platform_name = "s3c2412-i2s", | 91 | .platform_name = "s3c2412-i2s", |
122 | .codec_name = "wm8750.0-001a", | 92 | .codec_name = "wm8750.0-001a", |
123 | .init = jive_wm8750_init, | 93 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | |
94 | SND_SOC_DAIFMT_CBS_CFS, | ||
124 | .ops = &jive_ops, | 95 | .ops = &jive_ops, |
125 | }; | 96 | }; |
126 | 97 | ||
@@ -135,6 +106,7 @@ static struct snd_soc_card snd_soc_machine_jive = { | |||
135 | .num_dapm_widgets = ARRAY_SIZE(wm8750_dapm_widgets), | 106 | .num_dapm_widgets = ARRAY_SIZE(wm8750_dapm_widgets), |
136 | .dapm_routes = audio_map, | 107 | .dapm_routes = audio_map, |
137 | .num_dapm_routes = ARRAY_SIZE(audio_map), | 108 | .num_dapm_routes = ARRAY_SIZE(audio_map), |
109 | .fully_routed = true, | ||
138 | }; | 110 | }; |
139 | 111 | ||
140 | static struct platform_device *jive_snd_device; | 112 | static struct platform_device *jive_snd_device; |
diff --git a/sound/soc/samsung/neo1973_wm8753.c b/sound/soc/samsung/neo1973_wm8753.c index 9b4a09f14b6c..65602b935377 100644 --- a/sound/soc/samsung/neo1973_wm8753.c +++ b/sound/soc/samsung/neo1973_wm8753.c | |||
@@ -70,20 +70,6 @@ static int neo1973_hifi_hw_params(struct snd_pcm_substream *substream, | |||
70 | break; | 70 | break; |
71 | } | 71 | } |
72 | 72 | ||
73 | /* set codec DAI configuration */ | ||
74 | ret = snd_soc_dai_set_fmt(codec_dai, | ||
75 | SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | | ||
76 | SND_SOC_DAIFMT_CBM_CFM); | ||
77 | if (ret < 0) | ||
78 | return ret; | ||
79 | |||
80 | /* set cpu DAI configuration */ | ||
81 | ret = snd_soc_dai_set_fmt(cpu_dai, | ||
82 | SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | | ||
83 | SND_SOC_DAIFMT_CBM_CFM); | ||
84 | if (ret < 0) | ||
85 | return ret; | ||
86 | |||
87 | /* set the codec system clock for DAC and ADC */ | 73 | /* set the codec system clock for DAC and ADC */ |
88 | ret = snd_soc_dai_set_sysclk(codec_dai, WM8753_MCLK, pll_out, | 74 | ret = snd_soc_dai_set_sysclk(codec_dai, WM8753_MCLK, pll_out, |
89 | SND_SOC_CLOCK_IN); | 75 | SND_SOC_CLOCK_IN); |
@@ -151,13 +137,6 @@ static int neo1973_voice_hw_params(struct snd_pcm_substream *substream, | |||
151 | 137 | ||
152 | pcmdiv = WM8753_PCM_DIV_6; /* 2.048 MHz */ | 138 | pcmdiv = WM8753_PCM_DIV_6; /* 2.048 MHz */ |
153 | 139 | ||
154 | /* todo: gg check mode (DSP_B) against CSR datasheet */ | ||
155 | /* set codec DAI configuration */ | ||
156 | ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_DSP_B | | ||
157 | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); | ||
158 | if (ret < 0) | ||
159 | return ret; | ||
160 | |||
161 | /* set the codec system clock for DAC and ADC */ | 140 | /* set the codec system clock for DAC and ADC */ |
162 | ret = snd_soc_dai_set_sysclk(codec_dai, WM8753_PCMCLK, 12288000, | 141 | ret = snd_soc_dai_set_sysclk(codec_dai, WM8753_PCMCLK, 12288000, |
163 | SND_SOC_CLOCK_IN); | 142 | SND_SOC_CLOCK_IN); |
@@ -300,6 +279,8 @@ static struct snd_soc_dai_link neo1973_dai[] = { | |||
300 | .cpu_dai_name = "s3c24xx-iis", | 279 | .cpu_dai_name = "s3c24xx-iis", |
301 | .codec_dai_name = "wm8753-hifi", | 280 | .codec_dai_name = "wm8753-hifi", |
302 | .codec_name = "wm8753.0-001a", | 281 | .codec_name = "wm8753.0-001a", |
282 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | | ||
283 | SND_SOC_DAIFMT_CBM_CFM, | ||
303 | .init = neo1973_wm8753_init, | 284 | .init = neo1973_wm8753_init, |
304 | .ops = &neo1973_hifi_ops, | 285 | .ops = &neo1973_hifi_ops, |
305 | }, | 286 | }, |
@@ -309,6 +290,8 @@ static struct snd_soc_dai_link neo1973_dai[] = { | |||
309 | .cpu_dai_name = "bt-sco-pcm", | 290 | .cpu_dai_name = "bt-sco-pcm", |
310 | .codec_dai_name = "wm8753-voice", | 291 | .codec_dai_name = "wm8753-voice", |
311 | .codec_name = "wm8753.0-001a", | 292 | .codec_name = "wm8753.0-001a", |
293 | .dai_fmt = SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_NB_NF | | ||
294 | SND_SOC_DAIFMT_CBS_CFS, | ||
312 | .ops = &neo1973_voice_ops, | 295 | .ops = &neo1973_voice_ops, |
313 | }, | 296 | }, |
314 | }; | 297 | }; |
diff --git a/sound/soc/samsung/odroidx2_max98090.c b/sound/soc/samsung/odroidx2_max98090.c index fa4f1d2f69bf..596f1180a369 100644 --- a/sound/soc/samsung/odroidx2_max98090.c +++ b/sound/soc/samsung/odroidx2_max98090.c | |||
@@ -21,6 +21,8 @@ struct odroidx2_drv_data { | |||
21 | /* The I2S CDCLK output clock frequency for the MAX98090 codec */ | 21 | /* The I2S CDCLK output clock frequency for the MAX98090 codec */ |
22 | #define MAX98090_MCLK 19200000 | 22 | #define MAX98090_MCLK 19200000 |
23 | 23 | ||
24 | static struct snd_soc_dai_link odroidx2_dai[]; | ||
25 | |||
24 | static int odroidx2_late_probe(struct snd_soc_card *card) | 26 | static int odroidx2_late_probe(struct snd_soc_card *card) |
25 | { | 27 | { |
26 | struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai; | 28 | struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai; |
@@ -29,7 +31,9 @@ static int odroidx2_late_probe(struct snd_soc_card *card) | |||
29 | 31 | ||
30 | ret = snd_soc_dai_set_sysclk(codec_dai, 0, MAX98090_MCLK, | 32 | ret = snd_soc_dai_set_sysclk(codec_dai, 0, MAX98090_MCLK, |
31 | SND_SOC_CLOCK_IN); | 33 | SND_SOC_CLOCK_IN); |
32 | if (ret < 0) | 34 | |
35 | if (ret < 0 || of_find_property(odroidx2_dai[0].codec_of_node, | ||
36 | "clocks", NULL)) | ||
33 | return ret; | 37 | return ret; |
34 | 38 | ||
35 | /* Set the cpu DAI configuration in order to use CDCLK */ | 39 | /* Set the cpu DAI configuration in order to use CDCLK */ |
diff --git a/sound/soc/samsung/rx1950_uda1380.c b/sound/soc/samsung/rx1950_uda1380.c index 37688ebbb2b4..873f2cb4bebe 100644 --- a/sound/soc/samsung/rx1950_uda1380.c +++ b/sound/soc/samsung/rx1950_uda1380.c | |||
@@ -89,6 +89,8 @@ static struct snd_soc_dai_link rx1950_uda1380_dai[] = { | |||
89 | .init = rx1950_uda1380_init, | 89 | .init = rx1950_uda1380_init, |
90 | .platform_name = "s3c24xx-iis", | 90 | .platform_name = "s3c24xx-iis", |
91 | .codec_name = "uda1380-codec.0-001a", | 91 | .codec_name = "uda1380-codec.0-001a", |
92 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | | ||
93 | SND_SOC_DAIFMT_CBS_CFS, | ||
92 | .ops = &rx1950_ops, | 94 | .ops = &rx1950_ops, |
93 | }, | 95 | }, |
94 | }; | 96 | }; |
@@ -154,7 +156,6 @@ static int rx1950_hw_params(struct snd_pcm_substream *substream, | |||
154 | { | 156 | { |
155 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 157 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
156 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | 158 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; |
157 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | ||
158 | int div; | 159 | int div; |
159 | int ret; | 160 | int ret; |
160 | unsigned int rate = params_rate(params); | 161 | unsigned int rate = params_rate(params); |
@@ -181,18 +182,6 @@ static int rx1950_hw_params(struct snd_pcm_substream *substream, | |||
181 | return -EINVAL; | 182 | return -EINVAL; |
182 | } | 183 | } |
183 | 184 | ||
184 | /* set codec DAI configuration */ | ||
185 | ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | | ||
186 | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); | ||
187 | if (ret < 0) | ||
188 | return ret; | ||
189 | |||
190 | /* set cpu DAI configuration */ | ||
191 | ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | | ||
192 | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); | ||
193 | if (ret < 0) | ||
194 | return ret; | ||
195 | |||
196 | /* select clock source */ | 185 | /* select clock source */ |
197 | ret = snd_soc_dai_set_sysclk(cpu_dai, clk_source, rate, | 186 | ret = snd_soc_dai_set_sysclk(cpu_dai, clk_source, rate, |
198 | SND_SOC_CLOCK_OUT); | 187 | SND_SOC_CLOCK_OUT); |
diff --git a/sound/soc/samsung/s3c24xx_simtec.c b/sound/soc/samsung/s3c24xx_simtec.c index 2c015f62ead6..dcc008d1e1ab 100644 --- a/sound/soc/samsung/s3c24xx_simtec.c +++ b/sound/soc/samsung/s3c24xx_simtec.c | |||
@@ -169,24 +169,6 @@ static int simtec_hw_params(struct snd_pcm_substream *substream, | |||
169 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | 169 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; |
170 | int ret; | 170 | int ret; |
171 | 171 | ||
172 | /* Set the CODEC as the bus clock master, I2S */ | ||
173 | ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | | ||
174 | SND_SOC_DAIFMT_NB_NF | | ||
175 | SND_SOC_DAIFMT_CBM_CFM); | ||
176 | if (ret) { | ||
177 | pr_err("%s: failed set cpu dai format\n", __func__); | ||
178 | return ret; | ||
179 | } | ||
180 | |||
181 | /* Set the CODEC as the bus clock master */ | ||
182 | ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | | ||
183 | SND_SOC_DAIFMT_NB_NF | | ||
184 | SND_SOC_DAIFMT_CBM_CFM); | ||
185 | if (ret) { | ||
186 | pr_err("%s: failed set codec dai format\n", __func__); | ||
187 | return ret; | ||
188 | } | ||
189 | |||
190 | ret = snd_soc_dai_set_sysclk(codec_dai, 0, | 172 | ret = snd_soc_dai_set_sysclk(codec_dai, 0, |
191 | CODEC_CLOCK, SND_SOC_CLOCK_IN); | 173 | CODEC_CLOCK, SND_SOC_CLOCK_IN); |
192 | if (ret) { | 174 | if (ret) { |
@@ -320,6 +302,8 @@ int simtec_audio_core_probe(struct platform_device *pdev, | |||
320 | int ret; | 302 | int ret; |
321 | 303 | ||
322 | card->dai_link->ops = &simtec_snd_ops; | 304 | card->dai_link->ops = &simtec_snd_ops; |
305 | card->dai_link->dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | | ||
306 | SND_SOC_DAIFMT_CBM_CFM; | ||
323 | 307 | ||
324 | pdata = pdev->dev.platform_data; | 308 | pdata = pdev->dev.platform_data; |
325 | if (!pdata) { | 309 | if (!pdata) { |
diff --git a/sound/soc/samsung/s3c24xx_uda134x.c b/sound/soc/samsung/s3c24xx_uda134x.c index 9c6f7db56f60..50849e137fc0 100644 --- a/sound/soc/samsung/s3c24xx_uda134x.c +++ b/sound/soc/samsung/s3c24xx_uda134x.c | |||
@@ -173,16 +173,6 @@ static int s3c24xx_uda134x_hw_params(struct snd_pcm_substream *substream, | |||
173 | return -EINVAL; | 173 | return -EINVAL; |
174 | } | 174 | } |
175 | 175 | ||
176 | ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | | ||
177 | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); | ||
178 | if (ret < 0) | ||
179 | return ret; | ||
180 | |||
181 | ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | | ||
182 | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); | ||
183 | if (ret < 0) | ||
184 | return ret; | ||
185 | |||
186 | ret = snd_soc_dai_set_sysclk(cpu_dai, clk_source , clk, | 176 | ret = snd_soc_dai_set_sysclk(cpu_dai, clk_source , clk, |
187 | SND_SOC_CLOCK_IN); | 177 | SND_SOC_CLOCK_IN); |
188 | if (ret < 0) | 178 | if (ret < 0) |
@@ -223,6 +213,8 @@ static struct snd_soc_dai_link s3c24xx_uda134x_dai_link = { | |||
223 | .codec_name = "uda134x-codec", | 213 | .codec_name = "uda134x-codec", |
224 | .codec_dai_name = "uda134x-hifi", | 214 | .codec_dai_name = "uda134x-hifi", |
225 | .cpu_dai_name = "s3c24xx-iis", | 215 | .cpu_dai_name = "s3c24xx-iis", |
216 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | | ||
217 | SND_SOC_DAIFMT_CBS_CFS, | ||
226 | .ops = &s3c24xx_uda134x_ops, | 218 | .ops = &s3c24xx_uda134x_ops, |
227 | .platform_name = "s3c24xx-iis", | 219 | .platform_name = "s3c24xx-iis", |
228 | }; | 220 | }; |
diff --git a/sound/soc/samsung/smartq_wm8987.c b/sound/soc/samsung/smartq_wm8987.c index 9b0ffacab790..8291d2a5f152 100644 --- a/sound/soc/samsung/smartq_wm8987.c +++ b/sound/soc/samsung/smartq_wm8987.c | |||
@@ -56,20 +56,6 @@ static int smartq_hifi_hw_params(struct snd_pcm_substream *substream, | |||
56 | break; | 56 | break; |
57 | } | 57 | } |
58 | 58 | ||
59 | /* set codec DAI configuration */ | ||
60 | ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | | ||
61 | SND_SOC_DAIFMT_NB_NF | | ||
62 | SND_SOC_DAIFMT_CBS_CFS); | ||
63 | if (ret < 0) | ||
64 | return ret; | ||
65 | |||
66 | /* set cpu DAI configuration */ | ||
67 | ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | | ||
68 | SND_SOC_DAIFMT_NB_NF | | ||
69 | SND_SOC_DAIFMT_CBS_CFS); | ||
70 | if (ret < 0) | ||
71 | return ret; | ||
72 | |||
73 | /* Use PCLK for I2S signal generation */ | 59 | /* Use PCLK for I2S signal generation */ |
74 | ret = snd_soc_dai_set_sysclk(cpu_dai, SAMSUNG_I2S_RCLKSRC_0, | 60 | ret = snd_soc_dai_set_sysclk(cpu_dai, SAMSUNG_I2S_RCLKSRC_0, |
75 | 0, SND_SOC_CLOCK_IN); | 61 | 0, SND_SOC_CLOCK_IN); |
@@ -199,6 +185,8 @@ static struct snd_soc_dai_link smartq_dai[] = { | |||
199 | .platform_name = "samsung-i2s.0", | 185 | .platform_name = "samsung-i2s.0", |
200 | .codec_name = "wm8750.0-0x1a", | 186 | .codec_name = "wm8750.0-0x1a", |
201 | .init = smartq_wm8987_init, | 187 | .init = smartq_wm8987_init, |
188 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | | ||
189 | SND_SOC_DAIFMT_CBS_CFS, | ||
202 | .ops = &smartq_hifi_ops, | 190 | .ops = &smartq_hifi_ops, |
203 | }, | 191 | }, |
204 | }; | 192 | }; |
diff --git a/sound/soc/samsung/smdk_wm8580.c b/sound/soc/samsung/smdk_wm8580.c index b1a519f83b29..548bfd993788 100644 --- a/sound/soc/samsung/smdk_wm8580.c +++ b/sound/soc/samsung/smdk_wm8580.c | |||
@@ -32,7 +32,6 @@ static int smdk_hw_params(struct snd_pcm_substream *substream, | |||
32 | struct snd_pcm_hw_params *params) | 32 | struct snd_pcm_hw_params *params) |
33 | { | 33 | { |
34 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 34 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
35 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | ||
36 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | 35 | struct snd_soc_dai *codec_dai = rtd->codec_dai; |
37 | unsigned int pll_out; | 36 | unsigned int pll_out; |
38 | int bfs, rfs, ret; | 37 | int bfs, rfs, ret; |
@@ -77,20 +76,6 @@ static int smdk_hw_params(struct snd_pcm_substream *substream, | |||
77 | } | 76 | } |
78 | pll_out = params_rate(params) * rfs; | 77 | pll_out = params_rate(params) * rfs; |
79 | 78 | ||
80 | /* Set the Codec DAI configuration */ | ||
81 | ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | ||
82 | | SND_SOC_DAIFMT_NB_NF | ||
83 | | SND_SOC_DAIFMT_CBM_CFM); | ||
84 | if (ret < 0) | ||
85 | return ret; | ||
86 | |||
87 | /* Set the AP DAI configuration */ | ||
88 | ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | ||
89 | | SND_SOC_DAIFMT_NB_NF | ||
90 | | SND_SOC_DAIFMT_CBM_CFM); | ||
91 | if (ret < 0) | ||
92 | return ret; | ||
93 | |||
94 | /* Set WM8580 to drive MCLK from its PLLA */ | 79 | /* Set WM8580 to drive MCLK from its PLLA */ |
95 | ret = snd_soc_dai_set_clkdiv(codec_dai, WM8580_MCLK, | 80 | ret = snd_soc_dai_set_clkdiv(codec_dai, WM8580_MCLK, |
96 | WM8580_CLKSRC_PLLA); | 81 | WM8580_CLKSRC_PLLA); |
@@ -151,13 +136,10 @@ static const struct snd_soc_dapm_route smdk_wm8580_audio_map[] = { | |||
151 | 136 | ||
152 | static int smdk_wm8580_init_paiftx(struct snd_soc_pcm_runtime *rtd) | 137 | static int smdk_wm8580_init_paiftx(struct snd_soc_pcm_runtime *rtd) |
153 | { | 138 | { |
154 | struct snd_soc_codec *codec = rtd->codec; | ||
155 | struct snd_soc_dapm_context *dapm = &codec->dapm; | ||
156 | |||
157 | /* Enabling the microphone requires the fitting of a 0R | 139 | /* Enabling the microphone requires the fitting of a 0R |
158 | * resistor to connect the line from the microphone jack. | 140 | * resistor to connect the line from the microphone jack. |
159 | */ | 141 | */ |
160 | snd_soc_dapm_disable_pin(dapm, "MicIn"); | 142 | snd_soc_dapm_disable_pin(&rtd->card->dapm, "MicIn"); |
161 | 143 | ||
162 | return 0; | 144 | return 0; |
163 | } | 145 | } |
@@ -168,6 +150,9 @@ enum { | |||
168 | SEC_PLAYBACK, | 150 | SEC_PLAYBACK, |
169 | }; | 151 | }; |
170 | 152 | ||
153 | #define SMDK_DAI_FMT (SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | \ | ||
154 | SND_SOC_DAIFMT_CBM_CFM) | ||
155 | |||
171 | static struct snd_soc_dai_link smdk_dai[] = { | 156 | static struct snd_soc_dai_link smdk_dai[] = { |
172 | [PRI_PLAYBACK] = { /* Primary Playback i/f */ | 157 | [PRI_PLAYBACK] = { /* Primary Playback i/f */ |
173 | .name = "WM8580 PAIF RX", | 158 | .name = "WM8580 PAIF RX", |
@@ -176,6 +161,7 @@ static struct snd_soc_dai_link smdk_dai[] = { | |||
176 | .codec_dai_name = "wm8580-hifi-playback", | 161 | .codec_dai_name = "wm8580-hifi-playback", |
177 | .platform_name = "samsung-i2s.0", | 162 | .platform_name = "samsung-i2s.0", |
178 | .codec_name = "wm8580.0-001b", | 163 | .codec_name = "wm8580.0-001b", |
164 | .dai_fmt = SMDK_DAI_FMT, | ||
179 | .ops = &smdk_ops, | 165 | .ops = &smdk_ops, |
180 | }, | 166 | }, |
181 | [PRI_CAPTURE] = { /* Primary Capture i/f */ | 167 | [PRI_CAPTURE] = { /* Primary Capture i/f */ |
@@ -185,6 +171,7 @@ static struct snd_soc_dai_link smdk_dai[] = { | |||
185 | .codec_dai_name = "wm8580-hifi-capture", | 171 | .codec_dai_name = "wm8580-hifi-capture", |
186 | .platform_name = "samsung-i2s.0", | 172 | .platform_name = "samsung-i2s.0", |
187 | .codec_name = "wm8580.0-001b", | 173 | .codec_name = "wm8580.0-001b", |
174 | .dai_fmt = SMDK_DAI_FMT, | ||
188 | .init = smdk_wm8580_init_paiftx, | 175 | .init = smdk_wm8580_init_paiftx, |
189 | .ops = &smdk_ops, | 176 | .ops = &smdk_ops, |
190 | }, | 177 | }, |
@@ -195,6 +182,7 @@ static struct snd_soc_dai_link smdk_dai[] = { | |||
195 | .codec_dai_name = "wm8580-hifi-playback", | 182 | .codec_dai_name = "wm8580-hifi-playback", |
196 | .platform_name = "samsung-i2s-sec", | 183 | .platform_name = "samsung-i2s-sec", |
197 | .codec_name = "wm8580.0-001b", | 184 | .codec_name = "wm8580.0-001b", |
185 | .dai_fmt = SMDK_DAI_FMT, | ||
198 | .ops = &smdk_ops, | 186 | .ops = &smdk_ops, |
199 | }, | 187 | }, |
200 | }; | 188 | }; |
diff --git a/sound/soc/samsung/smdk_wm8580pcm.c b/sound/soc/samsung/smdk_wm8580pcm.c index 05c609c62de9..6deec5234c92 100644 --- a/sound/soc/samsung/smdk_wm8580pcm.c +++ b/sound/soc/samsung/smdk_wm8580pcm.c | |||
@@ -62,20 +62,6 @@ static int smdk_wm8580_pcm_hw_params(struct snd_pcm_substream *substream, | |||
62 | 62 | ||
63 | rfs = mclk_freq / params_rate(params) / 2; | 63 | rfs = mclk_freq / params_rate(params) / 2; |
64 | 64 | ||
65 | /* Set the codec DAI configuration */ | ||
66 | ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_DSP_B | ||
67 | | SND_SOC_DAIFMT_IB_NF | ||
68 | | SND_SOC_DAIFMT_CBS_CFS); | ||
69 | if (ret < 0) | ||
70 | return ret; | ||
71 | |||
72 | /* Set the cpu DAI configuration */ | ||
73 | ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_DSP_B | ||
74 | | SND_SOC_DAIFMT_IB_NF | ||
75 | | SND_SOC_DAIFMT_CBS_CFS); | ||
76 | if (ret < 0) | ||
77 | return ret; | ||
78 | |||
79 | if (mclk_freq == xtal_freq) { | 65 | if (mclk_freq == xtal_freq) { |
80 | ret = snd_soc_dai_set_sysclk(codec_dai, WM8580_CLKSRC_MCLK, | 66 | ret = snd_soc_dai_set_sysclk(codec_dai, WM8580_CLKSRC_MCLK, |
81 | mclk_freq, SND_SOC_CLOCK_IN); | 67 | mclk_freq, SND_SOC_CLOCK_IN); |
@@ -121,6 +107,9 @@ static struct snd_soc_ops smdk_wm8580_pcm_ops = { | |||
121 | .hw_params = smdk_wm8580_pcm_hw_params, | 107 | .hw_params = smdk_wm8580_pcm_hw_params, |
122 | }; | 108 | }; |
123 | 109 | ||
110 | #define SMDK_DAI_FMT (SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_IB_NF | \ | ||
111 | SND_SOC_DAIFMT_CBS_CFS) | ||
112 | |||
124 | static struct snd_soc_dai_link smdk_dai[] = { | 113 | static struct snd_soc_dai_link smdk_dai[] = { |
125 | { | 114 | { |
126 | .name = "WM8580 PAIF PCM RX", | 115 | .name = "WM8580 PAIF PCM RX", |
@@ -129,6 +118,7 @@ static struct snd_soc_dai_link smdk_dai[] = { | |||
129 | .codec_dai_name = "wm8580-hifi-playback", | 118 | .codec_dai_name = "wm8580-hifi-playback", |
130 | .platform_name = "samsung-audio", | 119 | .platform_name = "samsung-audio", |
131 | .codec_name = "wm8580.0-001b", | 120 | .codec_name = "wm8580.0-001b", |
121 | .dai_fmt = SMDK_DAI_FMT, | ||
132 | .ops = &smdk_wm8580_pcm_ops, | 122 | .ops = &smdk_wm8580_pcm_ops, |
133 | }, { | 123 | }, { |
134 | .name = "WM8580 PAIF PCM TX", | 124 | .name = "WM8580 PAIF PCM TX", |
@@ -137,6 +127,7 @@ static struct snd_soc_dai_link smdk_dai[] = { | |||
137 | .codec_dai_name = "wm8580-hifi-capture", | 127 | .codec_dai_name = "wm8580-hifi-capture", |
138 | .platform_name = "samsung-pcm.0", | 128 | .platform_name = "samsung-pcm.0", |
139 | .codec_name = "wm8580.0-001b", | 129 | .codec_name = "wm8580.0-001b", |
130 | .dai_fmt = SMDK_DAI_FMT, | ||
140 | .ops = &smdk_wm8580_pcm_ops, | 131 | .ops = &smdk_wm8580_pcm_ops, |
141 | }, | 132 | }, |
142 | }; | 133 | }; |
diff --git a/sound/soc/samsung/smdk_wm8994pcm.c b/sound/soc/samsung/smdk_wm8994pcm.c index c470e8eed6e1..b1c89ec2d999 100644 --- a/sound/soc/samsung/smdk_wm8994pcm.c +++ b/sound/soc/samsung/smdk_wm8994pcm.c | |||
@@ -68,20 +68,6 @@ static int smdk_wm8994_pcm_hw_params(struct snd_pcm_substream *substream, | |||
68 | 68 | ||
69 | mclk_freq = params_rate(params) * rfs; | 69 | mclk_freq = params_rate(params) * rfs; |
70 | 70 | ||
71 | /* Set the codec DAI configuration */ | ||
72 | ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_DSP_B | ||
73 | | SND_SOC_DAIFMT_IB_NF | ||
74 | | SND_SOC_DAIFMT_CBS_CFS); | ||
75 | if (ret < 0) | ||
76 | return ret; | ||
77 | |||
78 | /* Set the cpu DAI configuration */ | ||
79 | ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_DSP_B | ||
80 | | SND_SOC_DAIFMT_IB_NF | ||
81 | | SND_SOC_DAIFMT_CBS_CFS); | ||
82 | if (ret < 0) | ||
83 | return ret; | ||
84 | |||
85 | ret = snd_soc_dai_set_sysclk(codec_dai, WM8994_SYSCLK_FLL1, | 71 | ret = snd_soc_dai_set_sysclk(codec_dai, WM8994_SYSCLK_FLL1, |
86 | mclk_freq, SND_SOC_CLOCK_IN); | 72 | mclk_freq, SND_SOC_CLOCK_IN); |
87 | if (ret < 0) | 73 | if (ret < 0) |
@@ -118,6 +104,8 @@ static struct snd_soc_dai_link smdk_dai[] = { | |||
118 | .codec_dai_name = "wm8994-aif1", | 104 | .codec_dai_name = "wm8994-aif1", |
119 | .platform_name = "samsung-pcm.0", | 105 | .platform_name = "samsung-pcm.0", |
120 | .codec_name = "wm8994-codec", | 106 | .codec_name = "wm8994-codec", |
107 | .dai_fmt = SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_IB_NF | | ||
108 | SND_SOC_DAIFMT_CBS_CFS, | ||
121 | .ops = &smdk_wm8994_pcm_ops, | 109 | .ops = &smdk_wm8994_pcm_ops, |
122 | }, | 110 | }, |
123 | }; | 111 | }; |
diff --git a/sound/soc/sh/dma-sh7760.c b/sound/soc/sh/dma-sh7760.c index a5b2c4ea90d9..fd11404a3bc7 100644 --- a/sound/soc/sh/dma-sh7760.c +++ b/sound/soc/sh/dma-sh7760.c | |||
@@ -305,11 +305,6 @@ static struct snd_pcm_ops camelot_pcm_ops = { | |||
305 | .pointer = camelot_pos, | 305 | .pointer = camelot_pos, |
306 | }; | 306 | }; |
307 | 307 | ||
308 | static void camelot_pcm_free(struct snd_pcm *pcm) | ||
309 | { | ||
310 | snd_pcm_lib_preallocate_free_for_all(pcm); | ||
311 | } | ||
312 | |||
313 | static int camelot_pcm_new(struct snd_soc_pcm_runtime *rtd) | 308 | static int camelot_pcm_new(struct snd_soc_pcm_runtime *rtd) |
314 | { | 309 | { |
315 | struct snd_pcm *pcm = rtd->pcm; | 310 | struct snd_pcm *pcm = rtd->pcm; |
@@ -328,7 +323,6 @@ static int camelot_pcm_new(struct snd_soc_pcm_runtime *rtd) | |||
328 | static struct snd_soc_platform_driver sh7760_soc_platform = { | 323 | static struct snd_soc_platform_driver sh7760_soc_platform = { |
329 | .ops = &camelot_pcm_ops, | 324 | .ops = &camelot_pcm_ops, |
330 | .pcm_new = camelot_pcm_new, | 325 | .pcm_new = camelot_pcm_new, |
331 | .pcm_free = camelot_pcm_free, | ||
332 | }; | 326 | }; |
333 | 327 | ||
334 | static int sh7760_soc_platform_probe(struct platform_device *pdev) | 328 | static int sh7760_soc_platform_probe(struct platform_device *pdev) |
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c index 8869971d7884..b87b22e88e43 100644 --- a/sound/soc/sh/fsi.c +++ b/sound/soc/sh/fsi.c | |||
@@ -820,12 +820,9 @@ static int fsi_clk_enable(struct device *dev, | |||
820 | return ret; | 820 | return ret; |
821 | } | 821 | } |
822 | 822 | ||
823 | if (clock->xck) | 823 | clk_enable(clock->xck); |
824 | clk_enable(clock->xck); | 824 | clk_enable(clock->ick); |
825 | if (clock->ick) | 825 | clk_enable(clock->div); |
826 | clk_enable(clock->ick); | ||
827 | if (clock->div) | ||
828 | clk_enable(clock->div); | ||
829 | 826 | ||
830 | clock->count++; | 827 | clock->count++; |
831 | } | 828 | } |
@@ -1765,11 +1762,6 @@ static struct snd_pcm_ops fsi_pcm_ops = { | |||
1765 | #define PREALLOC_BUFFER (32 * 1024) | 1762 | #define PREALLOC_BUFFER (32 * 1024) |
1766 | #define PREALLOC_BUFFER_MAX (32 * 1024) | 1763 | #define PREALLOC_BUFFER_MAX (32 * 1024) |
1767 | 1764 | ||
1768 | static void fsi_pcm_free(struct snd_pcm *pcm) | ||
1769 | { | ||
1770 | snd_pcm_lib_preallocate_free_for_all(pcm); | ||
1771 | } | ||
1772 | |||
1773 | static int fsi_pcm_new(struct snd_soc_pcm_runtime *rtd) | 1765 | static int fsi_pcm_new(struct snd_soc_pcm_runtime *rtd) |
1774 | { | 1766 | { |
1775 | return snd_pcm_lib_preallocate_pages_for_all( | 1767 | return snd_pcm_lib_preallocate_pages_for_all( |
@@ -1821,7 +1813,6 @@ static struct snd_soc_dai_driver fsi_soc_dai[] = { | |||
1821 | static struct snd_soc_platform_driver fsi_soc_platform = { | 1813 | static struct snd_soc_platform_driver fsi_soc_platform = { |
1822 | .ops = &fsi_pcm_ops, | 1814 | .ops = &fsi_pcm_ops, |
1823 | .pcm_new = fsi_pcm_new, | 1815 | .pcm_new = fsi_pcm_new, |
1824 | .pcm_free = fsi_pcm_free, | ||
1825 | }; | 1816 | }; |
1826 | 1817 | ||
1827 | static const struct snd_soc_component_driver fsi_soc_component = { | 1818 | static const struct snd_soc_component_driver fsi_soc_component = { |
diff --git a/sound/soc/sh/migor.c b/sound/soc/sh/migor.c index c58c2529f103..82f582344fe7 100644 --- a/sound/soc/sh/migor.c +++ b/sound/soc/sh/migor.c | |||
@@ -63,16 +63,6 @@ static int migor_hw_params(struct snd_pcm_substream *substream, | |||
63 | if (ret < 0) | 63 | if (ret < 0) |
64 | return ret; | 64 | return ret; |
65 | 65 | ||
66 | ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_NB_IF | | ||
67 | SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS); | ||
68 | if (ret < 0) | ||
69 | return ret; | ||
70 | |||
71 | ret = snd_soc_dai_set_fmt(rtd->cpu_dai, SND_SOC_DAIFMT_NB_IF | | ||
72 | SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS); | ||
73 | if (ret < 0) | ||
74 | return ret; | ||
75 | |||
76 | codec_freq = rate * 512; | 66 | codec_freq = rate * 512; |
77 | /* | 67 | /* |
78 | * This propagates the parent frequency change to children and | 68 | * This propagates the parent frequency change to children and |
@@ -144,6 +134,8 @@ static struct snd_soc_dai_link migor_dai = { | |||
144 | .codec_dai_name = "wm8978-hifi", | 134 | .codec_dai_name = "wm8978-hifi", |
145 | .platform_name = "siu-pcm-audio", | 135 | .platform_name = "siu-pcm-audio", |
146 | .codec_name = "wm8978.0-001a", | 136 | .codec_name = "wm8978.0-001a", |
137 | .dai_fmt = SND_SOC_DAIFMT_NB_IF | SND_SOC_DAIFMT_I2S | | ||
138 | SND_SOC_DAIFMT_CBS_CFS, | ||
147 | .ops = &migor_dai_ops, | 139 | .ops = &migor_dai_ops, |
148 | }; | 140 | }; |
149 | 141 | ||
diff --git a/sound/soc/sh/rcar/adg.c b/sound/soc/sh/rcar/adg.c index 14d1a7193469..7ac35c9d1cb8 100644 --- a/sound/soc/sh/rcar/adg.c +++ b/sound/soc/sh/rcar/adg.c | |||
@@ -57,8 +57,7 @@ static u32 rsnd_adg_ssi_ws_timing_gen2(struct rsnd_dai_stream *io) | |||
57 | return (0x6 + ws) << 8; | 57 | return (0x6 + ws) << 8; |
58 | } | 58 | } |
59 | 59 | ||
60 | int rsnd_adg_set_cmd_timsel_gen2(struct rsnd_dai *rdai, | 60 | int rsnd_adg_set_cmd_timsel_gen2(struct rsnd_mod *mod, |
61 | struct rsnd_mod *mod, | ||
62 | struct rsnd_dai_stream *io) | 61 | struct rsnd_dai_stream *io) |
63 | { | 62 | { |
64 | int id = rsnd_mod_id(mod); | 63 | int id = rsnd_mod_id(mod); |
@@ -75,12 +74,11 @@ int rsnd_adg_set_cmd_timsel_gen2(struct rsnd_dai *rdai, | |||
75 | return 0; | 74 | return 0; |
76 | } | 75 | } |
77 | 76 | ||
78 | static int rsnd_adg_set_src_timsel_gen2(struct rsnd_dai *rdai, | 77 | static int rsnd_adg_set_src_timsel_gen2(struct rsnd_mod *mod, |
79 | struct rsnd_mod *mod, | ||
80 | struct rsnd_dai_stream *io, | 78 | struct rsnd_dai_stream *io, |
81 | u32 timsel) | 79 | u32 timsel) |
82 | { | 80 | { |
83 | int is_play = rsnd_dai_is_play(rdai, io); | 81 | int is_play = rsnd_io_is_play(io); |
84 | int id = rsnd_mod_id(mod); | 82 | int id = rsnd_mod_id(mod); |
85 | int shift = (id % 2) ? 16 : 0; | 83 | int shift = (id % 2) ? 16 : 0; |
86 | u32 mask, ws; | 84 | u32 mask, ws; |
@@ -122,7 +120,6 @@ static int rsnd_adg_set_src_timsel_gen2(struct rsnd_dai *rdai, | |||
122 | } | 120 | } |
123 | 121 | ||
124 | int rsnd_adg_set_convert_clk_gen2(struct rsnd_mod *mod, | 122 | int rsnd_adg_set_convert_clk_gen2(struct rsnd_mod *mod, |
125 | struct rsnd_dai *rdai, | ||
126 | struct rsnd_dai_stream *io, | 123 | struct rsnd_dai_stream *io, |
127 | unsigned int src_rate, | 124 | unsigned int src_rate, |
128 | unsigned int dst_rate) | 125 | unsigned int dst_rate) |
@@ -178,7 +175,7 @@ int rsnd_adg_set_convert_clk_gen2(struct rsnd_mod *mod, | |||
178 | return -EIO; | 175 | return -EIO; |
179 | } | 176 | } |
180 | 177 | ||
181 | ret = rsnd_adg_set_src_timsel_gen2(rdai, mod, io, val); | 178 | ret = rsnd_adg_set_src_timsel_gen2(mod, io, val); |
182 | if (ret < 0) { | 179 | if (ret < 0) { |
183 | dev_err(dev, "timsel error\n"); | 180 | dev_err(dev, "timsel error\n"); |
184 | return ret; | 181 | return ret; |
@@ -190,12 +187,11 @@ int rsnd_adg_set_convert_clk_gen2(struct rsnd_mod *mod, | |||
190 | } | 187 | } |
191 | 188 | ||
192 | int rsnd_adg_set_convert_timing_gen2(struct rsnd_mod *mod, | 189 | int rsnd_adg_set_convert_timing_gen2(struct rsnd_mod *mod, |
193 | struct rsnd_dai *rdai, | ||
194 | struct rsnd_dai_stream *io) | 190 | struct rsnd_dai_stream *io) |
195 | { | 191 | { |
196 | u32 val = rsnd_adg_ssi_ws_timing_gen2(io); | 192 | u32 val = rsnd_adg_ssi_ws_timing_gen2(io); |
197 | 193 | ||
198 | return rsnd_adg_set_src_timsel_gen2(rdai, mod, io, val); | 194 | return rsnd_adg_set_src_timsel_gen2(mod, io, val); |
199 | } | 195 | } |
200 | 196 | ||
201 | int rsnd_adg_set_convert_clk_gen1(struct rsnd_priv *priv, | 197 | int rsnd_adg_set_convert_clk_gen1(struct rsnd_priv *priv, |
diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c index 75308bbc2ce8..1b53605f7154 100644 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c | |||
@@ -149,16 +149,16 @@ char *rsnd_mod_dma_name(struct rsnd_mod *mod) | |||
149 | return mod->ops->dma_name(mod); | 149 | return mod->ops->dma_name(mod); |
150 | } | 150 | } |
151 | 151 | ||
152 | void rsnd_mod_init(struct rsnd_priv *priv, | 152 | void rsnd_mod_init(struct rsnd_mod *mod, |
153 | struct rsnd_mod *mod, | ||
154 | struct rsnd_mod_ops *ops, | 153 | struct rsnd_mod_ops *ops, |
154 | struct clk *clk, | ||
155 | enum rsnd_mod_type type, | 155 | enum rsnd_mod_type type, |
156 | int id) | 156 | int id) |
157 | { | 157 | { |
158 | mod->priv = priv; | ||
159 | mod->id = id; | 158 | mod->id = id; |
160 | mod->ops = ops; | 159 | mod->ops = ops; |
161 | mod->type = type; | 160 | mod->type = type; |
161 | mod->clk = clk; | ||
162 | } | 162 | } |
163 | 163 | ||
164 | /* | 164 | /* |
@@ -412,7 +412,7 @@ u32 rsnd_get_adinr(struct rsnd_mod *mod) | |||
412 | /* | 412 | /* |
413 | * rsnd_dai functions | 413 | * rsnd_dai functions |
414 | */ | 414 | */ |
415 | #define __rsnd_mod_call(mod, func, rdai...) \ | 415 | #define __rsnd_mod_call(mod, func, param...) \ |
416 | ({ \ | 416 | ({ \ |
417 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); \ | 417 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); \ |
418 | struct device *dev = rsnd_priv_to_dev(priv); \ | 418 | struct device *dev = rsnd_priv_to_dev(priv); \ |
@@ -422,18 +422,18 @@ u32 rsnd_get_adinr(struct rsnd_mod *mod) | |||
422 | if ((mod->status & mask) == call) { \ | 422 | if ((mod->status & mask) == call) { \ |
423 | dev_dbg(dev, "%s[%d] %s\n", \ | 423 | dev_dbg(dev, "%s[%d] %s\n", \ |
424 | rsnd_mod_name(mod), rsnd_mod_id(mod), #func); \ | 424 | rsnd_mod_name(mod), rsnd_mod_id(mod), #func); \ |
425 | ret = (mod)->ops->func(mod, rdai); \ | 425 | ret = (mod)->ops->func(mod, param); \ |
426 | mod->status = (mod->status & ~mask) | (~call & mask); \ | 426 | mod->status = (mod->status & ~mask) | (~call & mask); \ |
427 | } \ | 427 | } \ |
428 | ret; \ | 428 | ret; \ |
429 | }) | 429 | }) |
430 | 430 | ||
431 | #define rsnd_mod_call(mod, func, rdai...) \ | 431 | #define rsnd_mod_call(mod, func, param...) \ |
432 | (!(mod) ? -ENODEV : \ | 432 | (!(mod) ? -ENODEV : \ |
433 | !((mod)->ops->func) ? 0 : \ | 433 | !((mod)->ops->func) ? 0 : \ |
434 | __rsnd_mod_call(mod, func, rdai)) | 434 | __rsnd_mod_call(mod, func, param)) |
435 | 435 | ||
436 | #define rsnd_dai_call(fn, io, rdai...) \ | 436 | #define rsnd_dai_call(fn, io, param...) \ |
437 | ({ \ | 437 | ({ \ |
438 | struct rsnd_mod *mod; \ | 438 | struct rsnd_mod *mod; \ |
439 | int ret = 0, i; \ | 439 | int ret = 0, i; \ |
@@ -441,7 +441,7 @@ u32 rsnd_get_adinr(struct rsnd_mod *mod) | |||
441 | mod = (io)->mod[i]; \ | 441 | mod = (io)->mod[i]; \ |
442 | if (!mod) \ | 442 | if (!mod) \ |
443 | continue; \ | 443 | continue; \ |
444 | ret = rsnd_mod_call(mod, fn, rdai); \ | 444 | ret = rsnd_mod_call(mod, fn, param); \ |
445 | if (ret < 0) \ | 445 | if (ret < 0) \ |
446 | break; \ | 446 | break; \ |
447 | } \ | 447 | } \ |
@@ -477,17 +477,7 @@ static void rsnd_dai_disconnect(struct rsnd_mod *mod, | |||
477 | io->mod[mod->type] = NULL; | 477 | io->mod[mod->type] = NULL; |
478 | } | 478 | } |
479 | 479 | ||
480 | int rsnd_dai_id(struct rsnd_priv *priv, struct rsnd_dai *rdai) | 480 | struct rsnd_dai *rsnd_rdai_get(struct rsnd_priv *priv, int id) |
481 | { | ||
482 | int id = rdai - priv->rdai; | ||
483 | |||
484 | if ((id < 0) || (id >= rsnd_rdai_nr(priv))) | ||
485 | return -EINVAL; | ||
486 | |||
487 | return id; | ||
488 | } | ||
489 | |||
490 | struct rsnd_dai *rsnd_dai_get(struct rsnd_priv *priv, int id) | ||
491 | { | 481 | { |
492 | if ((id < 0) || (id >= rsnd_rdai_nr(priv))) | 482 | if ((id < 0) || (id >= rsnd_rdai_nr(priv))) |
493 | return NULL; | 483 | return NULL; |
@@ -499,12 +489,7 @@ static struct rsnd_dai *rsnd_dai_to_rdai(struct snd_soc_dai *dai) | |||
499 | { | 489 | { |
500 | struct rsnd_priv *priv = snd_soc_dai_get_drvdata(dai); | 490 | struct rsnd_priv *priv = snd_soc_dai_get_drvdata(dai); |
501 | 491 | ||
502 | return rsnd_dai_get(priv, dai->id); | 492 | return rsnd_rdai_get(priv, dai->id); |
503 | } | ||
504 | |||
505 | int rsnd_dai_is_play(struct rsnd_dai *rdai, struct rsnd_dai_stream *io) | ||
506 | { | ||
507 | return &rdai->playback == io; | ||
508 | } | 493 | } |
509 | 494 | ||
510 | /* | 495 | /* |
@@ -598,20 +583,20 @@ static int rsnd_soc_dai_trigger(struct snd_pcm_substream *substream, int cmd, | |||
598 | if (ret < 0) | 583 | if (ret < 0) |
599 | goto dai_trigger_end; | 584 | goto dai_trigger_end; |
600 | 585 | ||
601 | ret = rsnd_dai_call(init, io, rdai); | 586 | ret = rsnd_dai_call(init, io, priv); |
602 | if (ret < 0) | 587 | if (ret < 0) |
603 | goto dai_trigger_end; | 588 | goto dai_trigger_end; |
604 | 589 | ||
605 | ret = rsnd_dai_call(start, io, rdai); | 590 | ret = rsnd_dai_call(start, io, priv); |
606 | if (ret < 0) | 591 | if (ret < 0) |
607 | goto dai_trigger_end; | 592 | goto dai_trigger_end; |
608 | break; | 593 | break; |
609 | case SNDRV_PCM_TRIGGER_STOP: | 594 | case SNDRV_PCM_TRIGGER_STOP: |
610 | ret = rsnd_dai_call(stop, io, rdai); | 595 | ret = rsnd_dai_call(stop, io, priv); |
611 | if (ret < 0) | 596 | if (ret < 0) |
612 | goto dai_trigger_end; | 597 | goto dai_trigger_end; |
613 | 598 | ||
614 | ret = rsnd_dai_call(quit, io, rdai); | 599 | ret = rsnd_dai_call(quit, io, priv); |
615 | if (ret < 0) | 600 | if (ret < 0) |
616 | goto dai_trigger_end; | 601 | goto dai_trigger_end; |
617 | 602 | ||
@@ -873,15 +858,15 @@ static int rsnd_dai_probe(struct platform_device *pdev, | |||
873 | priv->rdai = rdai; | 858 | priv->rdai = rdai; |
874 | 859 | ||
875 | for (i = 0; i < dai_nr; i++) { | 860 | for (i = 0; i < dai_nr; i++) { |
876 | rdai[i].info = &info->dai_info[i]; | ||
877 | 861 | ||
878 | pmod = rdai[i].info->playback.ssi; | 862 | pmod = info->dai_info[i].playback.ssi; |
879 | cmod = rdai[i].info->capture.ssi; | 863 | cmod = info->dai_info[i].capture.ssi; |
880 | 864 | ||
881 | /* | 865 | /* |
882 | * init rsnd_dai | 866 | * init rsnd_dai |
883 | */ | 867 | */ |
884 | snprintf(rdai[i].name, RSND_DAI_NAME_SIZE, "rsnd-dai.%d", i); | 868 | snprintf(rdai[i].name, RSND_DAI_NAME_SIZE, "rsnd-dai.%d", i); |
869 | rdai[i].priv = priv; | ||
885 | 870 | ||
886 | /* | 871 | /* |
887 | * init snd_soc_dai_driver | 872 | * init snd_soc_dai_driver |
@@ -895,6 +880,7 @@ static int rsnd_dai_probe(struct platform_device *pdev, | |||
895 | drv[i].playback.channels_max = 2; | 880 | drv[i].playback.channels_max = 2; |
896 | 881 | ||
897 | rdai[i].playback.info = &info->dai_info[i].playback; | 882 | rdai[i].playback.info = &info->dai_info[i].playback; |
883 | rdai[i].playback.rdai = rdai + i; | ||
898 | rsnd_path_init(priv, &rdai[i], &rdai[i].playback); | 884 | rsnd_path_init(priv, &rdai[i], &rdai[i].playback); |
899 | } | 885 | } |
900 | if (cmod) { | 886 | if (cmod) { |
@@ -904,6 +890,7 @@ static int rsnd_dai_probe(struct platform_device *pdev, | |||
904 | drv[i].capture.channels_max = 2; | 890 | drv[i].capture.channels_max = 2; |
905 | 891 | ||
906 | rdai[i].capture.info = &info->dai_info[i].capture; | 892 | rdai[i].capture.info = &info->dai_info[i].capture; |
893 | rdai[i].capture.rdai = rdai + i; | ||
907 | rsnd_path_init(priv, &rdai[i], &rdai[i].capture); | 894 | rsnd_path_init(priv, &rdai[i], &rdai[i].capture); |
908 | } | 895 | } |
909 | 896 | ||
@@ -1037,7 +1024,6 @@ static int rsnd_kctrl_put(struct snd_kcontrol *kctrl, | |||
1037 | } | 1024 | } |
1038 | 1025 | ||
1039 | static int __rsnd_kctrl_new(struct rsnd_mod *mod, | 1026 | static int __rsnd_kctrl_new(struct rsnd_mod *mod, |
1040 | struct rsnd_dai *rdai, | ||
1041 | struct snd_soc_pcm_runtime *rtd, | 1027 | struct snd_soc_pcm_runtime *rtd, |
1042 | const unsigned char *name, | 1028 | const unsigned char *name, |
1043 | struct rsnd_kctrl_cfg *cfg, | 1029 | struct rsnd_kctrl_cfg *cfg, |
@@ -1060,16 +1046,24 @@ static int __rsnd_kctrl_new(struct rsnd_mod *mod, | |||
1060 | return -ENOMEM; | 1046 | return -ENOMEM; |
1061 | 1047 | ||
1062 | ret = snd_ctl_add(card, kctrl); | 1048 | ret = snd_ctl_add(card, kctrl); |
1063 | if (ret < 0) | 1049 | if (ret < 0) { |
1050 | snd_ctl_free_one(kctrl); | ||
1064 | return ret; | 1051 | return ret; |
1052 | } | ||
1065 | 1053 | ||
1066 | cfg->update = update; | 1054 | cfg->update = update; |
1055 | cfg->card = card; | ||
1056 | cfg->kctrl = kctrl; | ||
1067 | 1057 | ||
1068 | return 0; | 1058 | return 0; |
1069 | } | 1059 | } |
1070 | 1060 | ||
1061 | void _rsnd_kctrl_remove(struct rsnd_kctrl_cfg *cfg) | ||
1062 | { | ||
1063 | snd_ctl_remove(cfg->card, cfg->kctrl); | ||
1064 | } | ||
1065 | |||
1071 | int rsnd_kctrl_new_m(struct rsnd_mod *mod, | 1066 | int rsnd_kctrl_new_m(struct rsnd_mod *mod, |
1072 | struct rsnd_dai *rdai, | ||
1073 | struct snd_soc_pcm_runtime *rtd, | 1067 | struct snd_soc_pcm_runtime *rtd, |
1074 | const unsigned char *name, | 1068 | const unsigned char *name, |
1075 | void (*update)(struct rsnd_mod *mod), | 1069 | void (*update)(struct rsnd_mod *mod), |
@@ -1079,11 +1073,10 @@ int rsnd_kctrl_new_m(struct rsnd_mod *mod, | |||
1079 | _cfg->cfg.max = max; | 1073 | _cfg->cfg.max = max; |
1080 | _cfg->cfg.size = RSND_DVC_CHANNELS; | 1074 | _cfg->cfg.size = RSND_DVC_CHANNELS; |
1081 | _cfg->cfg.val = _cfg->val; | 1075 | _cfg->cfg.val = _cfg->val; |
1082 | return __rsnd_kctrl_new(mod, rdai, rtd, name, &_cfg->cfg, update); | 1076 | return __rsnd_kctrl_new(mod, rtd, name, &_cfg->cfg, update); |
1083 | } | 1077 | } |
1084 | 1078 | ||
1085 | int rsnd_kctrl_new_s(struct rsnd_mod *mod, | 1079 | int rsnd_kctrl_new_s(struct rsnd_mod *mod, |
1086 | struct rsnd_dai *rdai, | ||
1087 | struct snd_soc_pcm_runtime *rtd, | 1080 | struct snd_soc_pcm_runtime *rtd, |
1088 | const unsigned char *name, | 1081 | const unsigned char *name, |
1089 | void (*update)(struct rsnd_mod *mod), | 1082 | void (*update)(struct rsnd_mod *mod), |
@@ -1093,11 +1086,10 @@ int rsnd_kctrl_new_s(struct rsnd_mod *mod, | |||
1093 | _cfg->cfg.max = max; | 1086 | _cfg->cfg.max = max; |
1094 | _cfg->cfg.size = 1; | 1087 | _cfg->cfg.size = 1; |
1095 | _cfg->cfg.val = &_cfg->val; | 1088 | _cfg->cfg.val = &_cfg->val; |
1096 | return __rsnd_kctrl_new(mod, rdai, rtd, name, &_cfg->cfg, update); | 1089 | return __rsnd_kctrl_new(mod, rtd, name, &_cfg->cfg, update); |
1097 | } | 1090 | } |
1098 | 1091 | ||
1099 | int rsnd_kctrl_new_e(struct rsnd_mod *mod, | 1092 | int rsnd_kctrl_new_e(struct rsnd_mod *mod, |
1100 | struct rsnd_dai *rdai, | ||
1101 | struct snd_soc_pcm_runtime *rtd, | 1093 | struct snd_soc_pcm_runtime *rtd, |
1102 | const unsigned char *name, | 1094 | const unsigned char *name, |
1103 | struct rsnd_kctrl_cfg_s *_cfg, | 1095 | struct rsnd_kctrl_cfg_s *_cfg, |
@@ -1109,7 +1101,7 @@ int rsnd_kctrl_new_e(struct rsnd_mod *mod, | |||
1109 | _cfg->cfg.size = 1; | 1101 | _cfg->cfg.size = 1; |
1110 | _cfg->cfg.val = &_cfg->val; | 1102 | _cfg->cfg.val = &_cfg->val; |
1111 | _cfg->cfg.texts = texts; | 1103 | _cfg->cfg.texts = texts; |
1112 | return __rsnd_kctrl_new(mod, rdai, rtd, name, &_cfg->cfg, update); | 1104 | return __rsnd_kctrl_new(mod, rtd, name, &_cfg->cfg, update); |
1113 | } | 1105 | } |
1114 | 1106 | ||
1115 | /* | 1107 | /* |
@@ -1125,11 +1117,11 @@ static int rsnd_pcm_new(struct snd_soc_pcm_runtime *rtd) | |||
1125 | struct rsnd_dai *rdai = rsnd_dai_to_rdai(dai); | 1117 | struct rsnd_dai *rdai = rsnd_dai_to_rdai(dai); |
1126 | int ret; | 1118 | int ret; |
1127 | 1119 | ||
1128 | ret = rsnd_dai_call(pcm_new, &rdai->playback, rdai, rtd); | 1120 | ret = rsnd_dai_call(pcm_new, &rdai->playback, rtd); |
1129 | if (ret) | 1121 | if (ret) |
1130 | return ret; | 1122 | return ret; |
1131 | 1123 | ||
1132 | ret = rsnd_dai_call(pcm_new, &rdai->capture, rdai, rtd); | 1124 | ret = rsnd_dai_call(pcm_new, &rdai->capture, rtd); |
1133 | if (ret) | 1125 | if (ret) |
1134 | return ret; | 1126 | return ret; |
1135 | 1127 | ||
@@ -1140,15 +1132,9 @@ static int rsnd_pcm_new(struct snd_soc_pcm_runtime *rtd) | |||
1140 | PREALLOC_BUFFER, PREALLOC_BUFFER_MAX); | 1132 | PREALLOC_BUFFER, PREALLOC_BUFFER_MAX); |
1141 | } | 1133 | } |
1142 | 1134 | ||
1143 | static void rsnd_pcm_free(struct snd_pcm *pcm) | ||
1144 | { | ||
1145 | snd_pcm_lib_preallocate_free_for_all(pcm); | ||
1146 | } | ||
1147 | |||
1148 | static struct snd_soc_platform_driver rsnd_soc_platform = { | 1135 | static struct snd_soc_platform_driver rsnd_soc_platform = { |
1149 | .ops = &rsnd_pcm_ops, | 1136 | .ops = &rsnd_pcm_ops, |
1150 | .pcm_new = rsnd_pcm_new, | 1137 | .pcm_new = rsnd_pcm_new, |
1151 | .pcm_free = rsnd_pcm_free, | ||
1152 | }; | 1138 | }; |
1153 | 1139 | ||
1154 | static const struct snd_soc_component_driver rsnd_soc_component = { | 1140 | static const struct snd_soc_component_driver rsnd_soc_component = { |
@@ -1156,13 +1142,11 @@ static const struct snd_soc_component_driver rsnd_soc_component = { | |||
1156 | }; | 1142 | }; |
1157 | 1143 | ||
1158 | static int rsnd_rdai_continuance_probe(struct rsnd_priv *priv, | 1144 | static int rsnd_rdai_continuance_probe(struct rsnd_priv *priv, |
1159 | struct rsnd_dai *rdai, | 1145 | struct rsnd_dai_stream *io) |
1160 | int is_play) | ||
1161 | { | 1146 | { |
1162 | struct rsnd_dai_stream *io = is_play ? &rdai->playback : &rdai->capture; | ||
1163 | int ret; | 1147 | int ret; |
1164 | 1148 | ||
1165 | ret = rsnd_dai_call(probe, io, rdai); | 1149 | ret = rsnd_dai_call(probe, io, priv); |
1166 | if (ret == -EAGAIN) { | 1150 | if (ret == -EAGAIN) { |
1167 | /* | 1151 | /* |
1168 | * Fallback to PIO mode | 1152 | * Fallback to PIO mode |
@@ -1175,7 +1159,7 @@ static int rsnd_rdai_continuance_probe(struct rsnd_priv *priv, | |||
1175 | * rsnd_dma_init() | 1159 | * rsnd_dma_init() |
1176 | * rsnd_ssi_fallback() | 1160 | * rsnd_ssi_fallback() |
1177 | */ | 1161 | */ |
1178 | rsnd_dai_call(remove, io, rdai); | 1162 | rsnd_dai_call(remove, io, priv); |
1179 | 1163 | ||
1180 | /* | 1164 | /* |
1181 | * remove SRC/DVC from DAI, | 1165 | * remove SRC/DVC from DAI, |
@@ -1186,13 +1170,13 @@ static int rsnd_rdai_continuance_probe(struct rsnd_priv *priv, | |||
1186 | /* | 1170 | /* |
1187 | * fallback | 1171 | * fallback |
1188 | */ | 1172 | */ |
1189 | rsnd_dai_call(fallback, io, rdai); | 1173 | rsnd_dai_call(fallback, io, priv); |
1190 | 1174 | ||
1191 | /* | 1175 | /* |
1192 | * retry to "probe". | 1176 | * retry to "probe". |
1193 | * DAI has SSI which is PIO mode only now. | 1177 | * DAI has SSI which is PIO mode only now. |
1194 | */ | 1178 | */ |
1195 | ret = rsnd_dai_call(probe, io, rdai); | 1179 | ret = rsnd_dai_call(probe, io, priv); |
1196 | } | 1180 | } |
1197 | 1181 | ||
1198 | return ret; | 1182 | return ret; |
@@ -1259,11 +1243,11 @@ static int rsnd_probe(struct platform_device *pdev) | |||
1259 | } | 1243 | } |
1260 | 1244 | ||
1261 | for_each_rsnd_dai(rdai, priv, i) { | 1245 | for_each_rsnd_dai(rdai, priv, i) { |
1262 | ret = rsnd_rdai_continuance_probe(priv, rdai, 1); | 1246 | ret = rsnd_rdai_continuance_probe(priv, &rdai->playback); |
1263 | if (ret) | 1247 | if (ret) |
1264 | goto exit_snd_probe; | 1248 | goto exit_snd_probe; |
1265 | 1249 | ||
1266 | ret = rsnd_rdai_continuance_probe(priv, rdai, 0); | 1250 | ret = rsnd_rdai_continuance_probe(priv, &rdai->capture); |
1267 | if (ret) | 1251 | if (ret) |
1268 | goto exit_snd_probe; | 1252 | goto exit_snd_probe; |
1269 | } | 1253 | } |
@@ -1295,8 +1279,8 @@ exit_snd_soc: | |||
1295 | snd_soc_unregister_platform(dev); | 1279 | snd_soc_unregister_platform(dev); |
1296 | exit_snd_probe: | 1280 | exit_snd_probe: |
1297 | for_each_rsnd_dai(rdai, priv, i) { | 1281 | for_each_rsnd_dai(rdai, priv, i) { |
1298 | rsnd_dai_call(remove, &rdai->playback, rdai); | 1282 | rsnd_dai_call(remove, &rdai->playback, priv); |
1299 | rsnd_dai_call(remove, &rdai->capture, rdai); | 1283 | rsnd_dai_call(remove, &rdai->capture, priv); |
1300 | } | 1284 | } |
1301 | 1285 | ||
1302 | return ret; | 1286 | return ret; |
@@ -1311,10 +1295,13 @@ static int rsnd_remove(struct platform_device *pdev) | |||
1311 | pm_runtime_disable(&pdev->dev); | 1295 | pm_runtime_disable(&pdev->dev); |
1312 | 1296 | ||
1313 | for_each_rsnd_dai(rdai, priv, i) { | 1297 | for_each_rsnd_dai(rdai, priv, i) { |
1314 | ret |= rsnd_dai_call(remove, &rdai->playback, rdai); | 1298 | ret |= rsnd_dai_call(remove, &rdai->playback, priv); |
1315 | ret |= rsnd_dai_call(remove, &rdai->capture, rdai); | 1299 | ret |= rsnd_dai_call(remove, &rdai->capture, priv); |
1316 | } | 1300 | } |
1317 | 1301 | ||
1302 | snd_soc_unregister_component(&pdev->dev); | ||
1303 | snd_soc_unregister_platform(&pdev->dev); | ||
1304 | |||
1318 | return ret; | 1305 | return ret; |
1319 | } | 1306 | } |
1320 | 1307 | ||
diff --git a/sound/soc/sh/rcar/dvc.c b/sound/soc/sh/rcar/dvc.c index 5380a4827ba7..d7f9ed959c4e 100644 --- a/sound/soc/sh/rcar/dvc.c +++ b/sound/soc/sh/rcar/dvc.c | |||
@@ -17,7 +17,6 @@ | |||
17 | struct rsnd_dvc { | 17 | struct rsnd_dvc { |
18 | struct rsnd_dvc_platform_info *info; /* rcar_snd.h */ | 18 | struct rsnd_dvc_platform_info *info; /* rcar_snd.h */ |
19 | struct rsnd_mod mod; | 19 | struct rsnd_mod mod; |
20 | struct clk *clk; | ||
21 | struct rsnd_kctrl_cfg_m volume; | 20 | struct rsnd_kctrl_cfg_m volume; |
22 | struct rsnd_kctrl_cfg_m mute; | 21 | struct rsnd_kctrl_cfg_m mute; |
23 | struct rsnd_kctrl_cfg_s ren; /* Ramp Enable */ | 22 | struct rsnd_kctrl_cfg_s ren; /* Ramp Enable */ |
@@ -118,9 +117,8 @@ static void rsnd_dvc_volume_update(struct rsnd_mod *mod) | |||
118 | } | 117 | } |
119 | 118 | ||
120 | static int rsnd_dvc_probe_gen2(struct rsnd_mod *mod, | 119 | static int rsnd_dvc_probe_gen2(struct rsnd_mod *mod, |
121 | struct rsnd_dai *rdai) | 120 | struct rsnd_priv *priv) |
122 | { | 121 | { |
123 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); | ||
124 | struct device *dev = rsnd_priv_to_dev(priv); | 122 | struct device *dev = rsnd_priv_to_dev(priv); |
125 | 123 | ||
126 | dev_dbg(dev, "%s[%d] (Gen2) is probed\n", | 124 | dev_dbg(dev, "%s[%d] (Gen2) is probed\n", |
@@ -129,12 +127,24 @@ static int rsnd_dvc_probe_gen2(struct rsnd_mod *mod, | |||
129 | return 0; | 127 | return 0; |
130 | } | 128 | } |
131 | 129 | ||
130 | static int rsnd_dvc_remove_gen2(struct rsnd_mod *mod, | ||
131 | struct rsnd_priv *priv) | ||
132 | { | ||
133 | struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod); | ||
134 | |||
135 | rsnd_kctrl_remove(dvc->volume); | ||
136 | rsnd_kctrl_remove(dvc->mute); | ||
137 | rsnd_kctrl_remove(dvc->ren); | ||
138 | rsnd_kctrl_remove(dvc->rup); | ||
139 | rsnd_kctrl_remove(dvc->rdown); | ||
140 | |||
141 | return 0; | ||
142 | } | ||
143 | |||
132 | static int rsnd_dvc_init(struct rsnd_mod *dvc_mod, | 144 | static int rsnd_dvc_init(struct rsnd_mod *dvc_mod, |
133 | struct rsnd_dai *rdai) | 145 | struct rsnd_priv *priv) |
134 | { | 146 | { |
135 | struct rsnd_dvc *dvc = rsnd_mod_to_dvc(dvc_mod); | ||
136 | struct rsnd_dai_stream *io = rsnd_mod_to_io(dvc_mod); | 147 | struct rsnd_dai_stream *io = rsnd_mod_to_io(dvc_mod); |
137 | struct rsnd_priv *priv = rsnd_mod_to_priv(dvc_mod); | ||
138 | struct rsnd_mod *src_mod = rsnd_io_to_mod_src(io); | 148 | struct rsnd_mod *src_mod = rsnd_io_to_mod_src(io); |
139 | struct device *dev = rsnd_priv_to_dev(priv); | 149 | struct device *dev = rsnd_priv_to_dev(priv); |
140 | int dvc_id = rsnd_mod_id(dvc_mod); | 150 | int dvc_id = rsnd_mod_id(dvc_mod); |
@@ -153,7 +163,7 @@ static int rsnd_dvc_init(struct rsnd_mod *dvc_mod, | |||
153 | return -EINVAL; | 163 | return -EINVAL; |
154 | } | 164 | } |
155 | 165 | ||
156 | clk_prepare_enable(dvc->clk); | 166 | rsnd_mod_hw_start(dvc_mod); |
157 | 167 | ||
158 | /* | 168 | /* |
159 | * fixme | 169 | * fixme |
@@ -173,23 +183,21 @@ static int rsnd_dvc_init(struct rsnd_mod *dvc_mod, | |||
173 | 183 | ||
174 | rsnd_mod_write(dvc_mod, DVC_DVUIR, 0); | 184 | rsnd_mod_write(dvc_mod, DVC_DVUIR, 0); |
175 | 185 | ||
176 | rsnd_adg_set_cmd_timsel_gen2(rdai, dvc_mod, io); | 186 | rsnd_adg_set_cmd_timsel_gen2(dvc_mod, io); |
177 | 187 | ||
178 | return 0; | 188 | return 0; |
179 | } | 189 | } |
180 | 190 | ||
181 | static int rsnd_dvc_quit(struct rsnd_mod *mod, | 191 | static int rsnd_dvc_quit(struct rsnd_mod *mod, |
182 | struct rsnd_dai *rdai) | 192 | struct rsnd_priv *priv) |
183 | { | 193 | { |
184 | struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod); | 194 | rsnd_mod_hw_stop(mod); |
185 | |||
186 | clk_disable_unprepare(dvc->clk); | ||
187 | 195 | ||
188 | return 0; | 196 | return 0; |
189 | } | 197 | } |
190 | 198 | ||
191 | static int rsnd_dvc_start(struct rsnd_mod *mod, | 199 | static int rsnd_dvc_start(struct rsnd_mod *mod, |
192 | struct rsnd_dai *rdai) | 200 | struct rsnd_priv *priv) |
193 | { | 201 | { |
194 | rsnd_mod_write(mod, CMD_CTRL, 0x10); | 202 | rsnd_mod_write(mod, CMD_CTRL, 0x10); |
195 | 203 | ||
@@ -197,7 +205,7 @@ static int rsnd_dvc_start(struct rsnd_mod *mod, | |||
197 | } | 205 | } |
198 | 206 | ||
199 | static int rsnd_dvc_stop(struct rsnd_mod *mod, | 207 | static int rsnd_dvc_stop(struct rsnd_mod *mod, |
200 | struct rsnd_dai *rdai) | 208 | struct rsnd_priv *priv) |
201 | { | 209 | { |
202 | rsnd_mod_write(mod, CMD_CTRL, 0); | 210 | rsnd_mod_write(mod, CMD_CTRL, 0); |
203 | 211 | ||
@@ -205,16 +213,16 @@ static int rsnd_dvc_stop(struct rsnd_mod *mod, | |||
205 | } | 213 | } |
206 | 214 | ||
207 | static int rsnd_dvc_pcm_new(struct rsnd_mod *mod, | 215 | static int rsnd_dvc_pcm_new(struct rsnd_mod *mod, |
208 | struct rsnd_dai *rdai, | ||
209 | struct snd_soc_pcm_runtime *rtd) | 216 | struct snd_soc_pcm_runtime *rtd) |
210 | { | 217 | { |
211 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); | 218 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); |
212 | struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod); | 219 | struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod); |
220 | int is_play = rsnd_io_is_play(io); | ||
213 | int ret; | 221 | int ret; |
214 | 222 | ||
215 | /* Volume */ | 223 | /* Volume */ |
216 | ret = rsnd_kctrl_new_m(mod, rdai, rtd, | 224 | ret = rsnd_kctrl_new_m(mod, rtd, |
217 | rsnd_dai_is_play(rdai, io) ? | 225 | is_play ? |
218 | "DVC Out Playback Volume" : "DVC In Capture Volume", | 226 | "DVC Out Playback Volume" : "DVC In Capture Volume", |
219 | rsnd_dvc_volume_update, | 227 | rsnd_dvc_volume_update, |
220 | &dvc->volume, 0x00800000 - 1); | 228 | &dvc->volume, 0x00800000 - 1); |
@@ -222,8 +230,8 @@ static int rsnd_dvc_pcm_new(struct rsnd_mod *mod, | |||
222 | return ret; | 230 | return ret; |
223 | 231 | ||
224 | /* Mute */ | 232 | /* Mute */ |
225 | ret = rsnd_kctrl_new_m(mod, rdai, rtd, | 233 | ret = rsnd_kctrl_new_m(mod, rtd, |
226 | rsnd_dai_is_play(rdai, io) ? | 234 | is_play ? |
227 | "DVC Out Mute Switch" : "DVC In Mute Switch", | 235 | "DVC Out Mute Switch" : "DVC In Mute Switch", |
228 | rsnd_dvc_volume_update, | 236 | rsnd_dvc_volume_update, |
229 | &dvc->mute, 1); | 237 | &dvc->mute, 1); |
@@ -231,16 +239,16 @@ static int rsnd_dvc_pcm_new(struct rsnd_mod *mod, | |||
231 | return ret; | 239 | return ret; |
232 | 240 | ||
233 | /* Ramp */ | 241 | /* Ramp */ |
234 | ret = rsnd_kctrl_new_s(mod, rdai, rtd, | 242 | ret = rsnd_kctrl_new_s(mod, rtd, |
235 | rsnd_dai_is_play(rdai, io) ? | 243 | is_play ? |
236 | "DVC Out Ramp Switch" : "DVC In Ramp Switch", | 244 | "DVC Out Ramp Switch" : "DVC In Ramp Switch", |
237 | rsnd_dvc_volume_update, | 245 | rsnd_dvc_volume_update, |
238 | &dvc->ren, 1); | 246 | &dvc->ren, 1); |
239 | if (ret < 0) | 247 | if (ret < 0) |
240 | return ret; | 248 | return ret; |
241 | 249 | ||
242 | ret = rsnd_kctrl_new_e(mod, rdai, rtd, | 250 | ret = rsnd_kctrl_new_e(mod, rtd, |
243 | rsnd_dai_is_play(rdai, io) ? | 251 | is_play ? |
244 | "DVC Out Ramp Up Rate" : "DVC In Ramp Up Rate", | 252 | "DVC Out Ramp Up Rate" : "DVC In Ramp Up Rate", |
245 | &dvc->rup, | 253 | &dvc->rup, |
246 | rsnd_dvc_volume_update, | 254 | rsnd_dvc_volume_update, |
@@ -248,8 +256,8 @@ static int rsnd_dvc_pcm_new(struct rsnd_mod *mod, | |||
248 | if (ret < 0) | 256 | if (ret < 0) |
249 | return ret; | 257 | return ret; |
250 | 258 | ||
251 | ret = rsnd_kctrl_new_e(mod, rdai, rtd, | 259 | ret = rsnd_kctrl_new_e(mod, rtd, |
252 | rsnd_dai_is_play(rdai, io) ? | 260 | is_play ? |
253 | "DVC Out Ramp Down Rate" : "DVC In Ramp Down Rate", | 261 | "DVC Out Ramp Down Rate" : "DVC In Ramp Down Rate", |
254 | &dvc->rdown, | 262 | &dvc->rdown, |
255 | rsnd_dvc_volume_update, | 263 | rsnd_dvc_volume_update, |
@@ -264,6 +272,7 @@ static int rsnd_dvc_pcm_new(struct rsnd_mod *mod, | |||
264 | static struct rsnd_mod_ops rsnd_dvc_ops = { | 272 | static struct rsnd_mod_ops rsnd_dvc_ops = { |
265 | .name = DVC_NAME, | 273 | .name = DVC_NAME, |
266 | .probe = rsnd_dvc_probe_gen2, | 274 | .probe = rsnd_dvc_probe_gen2, |
275 | .remove = rsnd_dvc_remove_gen2, | ||
267 | .init = rsnd_dvc_init, | 276 | .init = rsnd_dvc_init, |
268 | .quit = rsnd_dvc_quit, | 277 | .quit = rsnd_dvc_quit, |
269 | .start = rsnd_dvc_start, | 278 | .start = rsnd_dvc_start, |
@@ -356,9 +365,9 @@ int rsnd_dvc_probe(struct platform_device *pdev, | |||
356 | return PTR_ERR(clk); | 365 | return PTR_ERR(clk); |
357 | 366 | ||
358 | dvc->info = &info->dvc_info[i]; | 367 | dvc->info = &info->dvc_info[i]; |
359 | dvc->clk = clk; | ||
360 | 368 | ||
361 | rsnd_mod_init(priv, &dvc->mod, &rsnd_dvc_ops, RSND_MOD_DVC, i); | 369 | rsnd_mod_init(&dvc->mod, &rsnd_dvc_ops, |
370 | clk, RSND_MOD_DVC, i); | ||
362 | 371 | ||
363 | dev_dbg(dev, "CMD%d probed\n", i); | 372 | dev_dbg(dev, "CMD%d probed\n", i); |
364 | } | 373 | } |
diff --git a/sound/soc/sh/rcar/gen.c b/sound/soc/sh/rcar/gen.c index 87a6f2d62775..de0685f2abae 100644 --- a/sound/soc/sh/rcar/gen.c +++ b/sound/soc/sh/rcar/gen.c | |||
@@ -309,8 +309,13 @@ static int rsnd_gen2_probe(struct platform_device *pdev, | |||
309 | RSND_GEN_M_REG(SRC_BUSIF_MODE, 0x0, 0x20), | 309 | RSND_GEN_M_REG(SRC_BUSIF_MODE, 0x0, 0x20), |
310 | RSND_GEN_M_REG(SRC_ROUTE_MODE0, 0xc, 0x20), | 310 | RSND_GEN_M_REG(SRC_ROUTE_MODE0, 0xc, 0x20), |
311 | RSND_GEN_M_REG(SRC_CTRL, 0x10, 0x20), | 311 | RSND_GEN_M_REG(SRC_CTRL, 0x10, 0x20), |
312 | RSND_GEN_M_REG(SRC_INT_ENABLE0, 0x18, 0x20), | ||
312 | RSND_GEN_M_REG(CMD_ROUTE_SLCT, 0x18c, 0x20), | 313 | RSND_GEN_M_REG(CMD_ROUTE_SLCT, 0x18c, 0x20), |
313 | RSND_GEN_M_REG(CMD_CTRL, 0x190, 0x20), | 314 | RSND_GEN_M_REG(CMD_CTRL, 0x190, 0x20), |
315 | RSND_GEN_S_REG(SCU_SYS_STATUS0, 0x1c8), | ||
316 | RSND_GEN_S_REG(SCU_SYS_INT_EN0, 0x1cc), | ||
317 | RSND_GEN_S_REG(SCU_SYS_STATUS1, 0x1d0), | ||
318 | RSND_GEN_S_REG(SCU_SYS_INT_EN1, 0x1c4), | ||
314 | RSND_GEN_M_REG(SRC_SWRSR, 0x200, 0x40), | 319 | RSND_GEN_M_REG(SRC_SWRSR, 0x200, 0x40), |
315 | RSND_GEN_M_REG(SRC_SRCIR, 0x204, 0x40), | 320 | RSND_GEN_M_REG(SRC_SRCIR, 0x204, 0x40), |
316 | RSND_GEN_M_REG(SRC_ADINR, 0x214, 0x40), | 321 | RSND_GEN_M_REG(SRC_ADINR, 0x214, 0x40), |
@@ -403,6 +408,16 @@ static int rsnd_gen1_probe(struct platform_device *pdev, | |||
403 | RSND_GEN_M_REG(SRC_IFSVR, 0x220, 0x40), | 408 | RSND_GEN_M_REG(SRC_IFSVR, 0x220, 0x40), |
404 | RSND_GEN_M_REG(SRC_SRCCR, 0x224, 0x40), | 409 | RSND_GEN_M_REG(SRC_SRCCR, 0x224, 0x40), |
405 | RSND_GEN_M_REG(SRC_MNFSR, 0x228, 0x40), | 410 | RSND_GEN_M_REG(SRC_MNFSR, 0x228, 0x40), |
411 | /* | ||
412 | * ADD US | ||
413 | * | ||
414 | * SRC_STATUS | ||
415 | * SRC_INT_EN | ||
416 | * SCU_SYS_STATUS0 | ||
417 | * SCU_SYS_STATUS1 | ||
418 | * SCU_SYS_INT_EN0 | ||
419 | * SCU_SYS_INT_EN1 | ||
420 | */ | ||
406 | }; | 421 | }; |
407 | struct rsnd_regmap_field_conf conf_adg[] = { | 422 | struct rsnd_regmap_field_conf conf_adg[] = { |
408 | RSND_GEN_S_REG(BRRA, 0x00), | 423 | RSND_GEN_S_REG(BRRA, 0x00), |
diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h index 5826c8abf794..e7914bd610e2 100644 --- a/sound/soc/sh/rcar/rsnd.h +++ b/sound/soc/sh/rcar/rsnd.h | |||
@@ -44,6 +44,8 @@ enum rsnd_reg { | |||
44 | RSND_REG_SRC_IFSCR, | 44 | RSND_REG_SRC_IFSCR, |
45 | RSND_REG_SRC_IFSVR, | 45 | RSND_REG_SRC_IFSVR, |
46 | RSND_REG_SRC_SRCCR, | 46 | RSND_REG_SRC_SRCCR, |
47 | RSND_REG_SCU_SYS_STATUS0, | ||
48 | RSND_REG_SCU_SYS_INT_EN0, | ||
47 | RSND_REG_CMD_ROUTE_SLCT, | 49 | RSND_REG_CMD_ROUTE_SLCT, |
48 | RSND_REG_DVC_SWRSR, | 50 | RSND_REG_DVC_SWRSR, |
49 | RSND_REG_DVC_DVUIR, | 51 | RSND_REG_DVC_DVUIR, |
@@ -94,6 +96,9 @@ enum rsnd_reg { | |||
94 | RSND_REG_SHARE23, | 96 | RSND_REG_SHARE23, |
95 | RSND_REG_SHARE24, | 97 | RSND_REG_SHARE24, |
96 | RSND_REG_SHARE25, | 98 | RSND_REG_SHARE25, |
99 | RSND_REG_SHARE26, | ||
100 | RSND_REG_SHARE27, | ||
101 | RSND_REG_SHARE28, | ||
97 | 102 | ||
98 | RSND_REG_MAX, | 103 | RSND_REG_MAX, |
99 | }; | 104 | }; |
@@ -135,6 +140,9 @@ enum rsnd_reg { | |||
135 | #define RSND_REG_DVC_VRCTR RSND_REG_SHARE23 | 140 | #define RSND_REG_DVC_VRCTR RSND_REG_SHARE23 |
136 | #define RSND_REG_DVC_VRPDR RSND_REG_SHARE24 | 141 | #define RSND_REG_DVC_VRPDR RSND_REG_SHARE24 |
137 | #define RSND_REG_DVC_VRDBR RSND_REG_SHARE25 | 142 | #define RSND_REG_DVC_VRDBR RSND_REG_SHARE25 |
143 | #define RSND_REG_SCU_SYS_STATUS1 RSND_REG_SHARE26 | ||
144 | #define RSND_REG_SCU_SYS_INT_EN1 RSND_REG_SHARE27 | ||
145 | #define RSND_REG_SRC_INT_ENABLE0 RSND_REG_SHARE28 | ||
138 | 146 | ||
139 | struct rsnd_of_data; | 147 | struct rsnd_of_data; |
140 | struct rsnd_priv; | 148 | struct rsnd_priv; |
@@ -182,9 +190,9 @@ void rsnd_dma_quit(struct rsnd_priv *priv, | |||
182 | * R-Car sound mod | 190 | * R-Car sound mod |
183 | */ | 191 | */ |
184 | enum rsnd_mod_type { | 192 | enum rsnd_mod_type { |
185 | RSND_MOD_SRC = 0, | 193 | RSND_MOD_DVC = 0, |
194 | RSND_MOD_SRC, | ||
186 | RSND_MOD_SSI, | 195 | RSND_MOD_SSI, |
187 | RSND_MOD_DVC, | ||
188 | RSND_MOD_MAX, | 196 | RSND_MOD_MAX, |
189 | }; | 197 | }; |
190 | 198 | ||
@@ -192,32 +200,31 @@ struct rsnd_mod_ops { | |||
192 | char *name; | 200 | char *name; |
193 | char* (*dma_name)(struct rsnd_mod *mod); | 201 | char* (*dma_name)(struct rsnd_mod *mod); |
194 | int (*probe)(struct rsnd_mod *mod, | 202 | int (*probe)(struct rsnd_mod *mod, |
195 | struct rsnd_dai *rdai); | 203 | struct rsnd_priv *priv); |
196 | int (*remove)(struct rsnd_mod *mod, | 204 | int (*remove)(struct rsnd_mod *mod, |
197 | struct rsnd_dai *rdai); | 205 | struct rsnd_priv *priv); |
198 | int (*init)(struct rsnd_mod *mod, | 206 | int (*init)(struct rsnd_mod *mod, |
199 | struct rsnd_dai *rdai); | 207 | struct rsnd_priv *priv); |
200 | int (*quit)(struct rsnd_mod *mod, | 208 | int (*quit)(struct rsnd_mod *mod, |
201 | struct rsnd_dai *rdai); | 209 | struct rsnd_priv *priv); |
202 | int (*start)(struct rsnd_mod *mod, | 210 | int (*start)(struct rsnd_mod *mod, |
203 | struct rsnd_dai *rdai); | 211 | struct rsnd_priv *priv); |
204 | int (*stop)(struct rsnd_mod *mod, | 212 | int (*stop)(struct rsnd_mod *mod, |
205 | struct rsnd_dai *rdai); | 213 | struct rsnd_priv *priv); |
206 | int (*pcm_new)(struct rsnd_mod *mod, | 214 | int (*pcm_new)(struct rsnd_mod *mod, |
207 | struct rsnd_dai *rdai, | ||
208 | struct snd_soc_pcm_runtime *rtd); | 215 | struct snd_soc_pcm_runtime *rtd); |
209 | int (*fallback)(struct rsnd_mod *mod, | 216 | int (*fallback)(struct rsnd_mod *mod, |
210 | struct rsnd_dai *rdai); | 217 | struct rsnd_priv *priv); |
211 | }; | 218 | }; |
212 | 219 | ||
213 | struct rsnd_dai_stream; | 220 | struct rsnd_dai_stream; |
214 | struct rsnd_mod { | 221 | struct rsnd_mod { |
215 | int id; | 222 | int id; |
216 | enum rsnd_mod_type type; | 223 | enum rsnd_mod_type type; |
217 | struct rsnd_priv *priv; | ||
218 | struct rsnd_mod_ops *ops; | 224 | struct rsnd_mod_ops *ops; |
219 | struct rsnd_dma dma; | 225 | struct rsnd_dma dma; |
220 | struct rsnd_dai_stream *io; | 226 | struct rsnd_dai_stream *io; |
227 | struct clk *clk; | ||
221 | u32 status; | 228 | u32 status; |
222 | }; | 229 | }; |
223 | /* | 230 | /* |
@@ -248,15 +255,17 @@ struct rsnd_mod { | |||
248 | #define __rsnd_mod_call_pcm_new 0 | 255 | #define __rsnd_mod_call_pcm_new 0 |
249 | #define __rsnd_mod_call_fallback 0 | 256 | #define __rsnd_mod_call_fallback 0 |
250 | 257 | ||
251 | #define rsnd_mod_to_priv(mod) ((mod)->priv) | 258 | #define rsnd_mod_to_priv(mod) (rsnd_io_to_priv(rsnd_mod_to_io(mod))) |
252 | #define rsnd_mod_to_dma(mod) (&(mod)->dma) | 259 | #define rsnd_mod_to_dma(mod) (&(mod)->dma) |
253 | #define rsnd_dma_to_mod(_dma) container_of((_dma), struct rsnd_mod, dma) | 260 | #define rsnd_dma_to_mod(_dma) container_of((_dma), struct rsnd_mod, dma) |
254 | #define rsnd_mod_to_io(mod) ((mod)->io) | 261 | #define rsnd_mod_to_io(mod) ((mod)->io) |
255 | #define rsnd_mod_id(mod) ((mod)->id) | 262 | #define rsnd_mod_id(mod) ((mod)->id) |
263 | #define rsnd_mod_hw_start(mod) clk_prepare_enable((mod)->clk) | ||
264 | #define rsnd_mod_hw_stop(mod) clk_disable_unprepare((mod)->clk) | ||
256 | 265 | ||
257 | void rsnd_mod_init(struct rsnd_priv *priv, | 266 | void rsnd_mod_init(struct rsnd_mod *mod, |
258 | struct rsnd_mod *mod, | ||
259 | struct rsnd_mod_ops *ops, | 267 | struct rsnd_mod_ops *ops, |
268 | struct clk *clk, | ||
260 | enum rsnd_mod_type type, | 269 | enum rsnd_mod_type type, |
261 | int id); | 270 | int id); |
262 | char *rsnd_mod_name(struct rsnd_mod *mod); | 271 | char *rsnd_mod_name(struct rsnd_mod *mod); |
@@ -270,6 +279,7 @@ struct rsnd_dai_stream { | |||
270 | struct snd_pcm_substream *substream; | 279 | struct snd_pcm_substream *substream; |
271 | struct rsnd_mod *mod[RSND_MOD_MAX]; | 280 | struct rsnd_mod *mod[RSND_MOD_MAX]; |
272 | struct rsnd_dai_path_info *info; /* rcar_snd.h */ | 281 | struct rsnd_dai_path_info *info; /* rcar_snd.h */ |
282 | struct rsnd_dai *rdai; | ||
273 | int byte_pos; | 283 | int byte_pos; |
274 | int period_pos; | 284 | int period_pos; |
275 | int byte_per_period; | 285 | int byte_per_period; |
@@ -278,12 +288,18 @@ struct rsnd_dai_stream { | |||
278 | #define rsnd_io_to_mod_ssi(io) ((io)->mod[RSND_MOD_SSI]) | 288 | #define rsnd_io_to_mod_ssi(io) ((io)->mod[RSND_MOD_SSI]) |
279 | #define rsnd_io_to_mod_src(io) ((io)->mod[RSND_MOD_SRC]) | 289 | #define rsnd_io_to_mod_src(io) ((io)->mod[RSND_MOD_SRC]) |
280 | #define rsnd_io_to_mod_dvc(io) ((io)->mod[RSND_MOD_DVC]) | 290 | #define rsnd_io_to_mod_dvc(io) ((io)->mod[RSND_MOD_DVC]) |
291 | #define rsnd_io_to_rdai(io) ((io)->rdai) | ||
292 | #define rsnd_io_to_priv(io) (rsnd_rdai_to_priv(rsnd_io_to_rdai(io))) | ||
293 | #define rsnd_io_is_play(io) (&rsnd_io_to_rdai(io)->playback == io) | ||
294 | #define rsnd_io_to_runtime(io) ((io)->substream ? \ | ||
295 | (io)->substream->runtime : NULL) | ||
296 | |||
281 | 297 | ||
282 | struct rsnd_dai { | 298 | struct rsnd_dai { |
283 | char name[RSND_DAI_NAME_SIZE]; | 299 | char name[RSND_DAI_NAME_SIZE]; |
284 | struct rsnd_dai_platform_info *info; /* rcar_snd.h */ | ||
285 | struct rsnd_dai_stream playback; | 300 | struct rsnd_dai_stream playback; |
286 | struct rsnd_dai_stream capture; | 301 | struct rsnd_dai_stream capture; |
302 | struct rsnd_priv *priv; | ||
287 | 303 | ||
288 | unsigned int clk_master:1; | 304 | unsigned int clk_master:1; |
289 | unsigned int bit_clk_inv:1; | 305 | unsigned int bit_clk_inv:1; |
@@ -293,22 +309,18 @@ struct rsnd_dai { | |||
293 | }; | 309 | }; |
294 | 310 | ||
295 | #define rsnd_rdai_nr(priv) ((priv)->rdai_nr) | 311 | #define rsnd_rdai_nr(priv) ((priv)->rdai_nr) |
312 | #define rsnd_rdai_is_clk_master(rdai) ((rdai)->clk_master) | ||
313 | #define rsnd_rdai_to_priv(rdai) ((rdai)->priv) | ||
296 | #define for_each_rsnd_dai(rdai, priv, i) \ | 314 | #define for_each_rsnd_dai(rdai, priv, i) \ |
297 | for (i = 0; \ | 315 | for (i = 0; \ |
298 | (i < rsnd_rdai_nr(priv)) && \ | 316 | (i < rsnd_rdai_nr(priv)) && \ |
299 | ((rdai) = rsnd_dai_get(priv, i)); \ | 317 | ((rdai) = rsnd_rdai_get(priv, i)); \ |
300 | i++) | 318 | i++) |
301 | 319 | ||
302 | struct rsnd_dai *rsnd_dai_get(struct rsnd_priv *priv, int id); | 320 | struct rsnd_dai *rsnd_rdai_get(struct rsnd_priv *priv, int id); |
303 | int rsnd_dai_is_play(struct rsnd_dai *rdai, struct rsnd_dai_stream *io); | ||
304 | int rsnd_dai_id(struct rsnd_priv *priv, struct rsnd_dai *rdai); | ||
305 | #define rsnd_dai_get_platform_info(rdai) ((rdai)->info) | ||
306 | #define rsnd_io_to_runtime(io) ((io)->substream ? \ | ||
307 | (io)->substream->runtime : NULL) | ||
308 | 321 | ||
309 | void rsnd_dai_pointer_update(struct rsnd_dai_stream *io, int cnt); | 322 | void rsnd_dai_pointer_update(struct rsnd_dai_stream *io, int cnt); |
310 | int rsnd_dai_pointer_offset(struct rsnd_dai_stream *io, int additional); | 323 | int rsnd_dai_pointer_offset(struct rsnd_dai_stream *io, int additional); |
311 | #define rsnd_dai_is_clk_master(rdai) ((rdai)->clk_master) | ||
312 | 324 | ||
313 | /* | 325 | /* |
314 | * R-Car Gen1/Gen2 | 326 | * R-Car Gen1/Gen2 |
@@ -339,15 +351,12 @@ int rsnd_adg_set_convert_clk_gen1(struct rsnd_priv *priv, | |||
339 | unsigned int src_rate, | 351 | unsigned int src_rate, |
340 | unsigned int dst_rate); | 352 | unsigned int dst_rate); |
341 | int rsnd_adg_set_convert_clk_gen2(struct rsnd_mod *mod, | 353 | int rsnd_adg_set_convert_clk_gen2(struct rsnd_mod *mod, |
342 | struct rsnd_dai *rdai, | ||
343 | struct rsnd_dai_stream *io, | 354 | struct rsnd_dai_stream *io, |
344 | unsigned int src_rate, | 355 | unsigned int src_rate, |
345 | unsigned int dst_rate); | 356 | unsigned int dst_rate); |
346 | int rsnd_adg_set_convert_timing_gen2(struct rsnd_mod *mod, | 357 | int rsnd_adg_set_convert_timing_gen2(struct rsnd_mod *mod, |
347 | struct rsnd_dai *rdai, | ||
348 | struct rsnd_dai_stream *io); | 358 | struct rsnd_dai_stream *io); |
349 | int rsnd_adg_set_cmd_timsel_gen2(struct rsnd_dai *rdai, | 359 | int rsnd_adg_set_cmd_timsel_gen2(struct rsnd_mod *mod, |
350 | struct rsnd_mod *mod, | ||
351 | struct rsnd_dai_stream *io); | 360 | struct rsnd_dai_stream *io); |
352 | 361 | ||
353 | /* | 362 | /* |
@@ -427,6 +436,8 @@ struct rsnd_kctrl_cfg { | |||
427 | u32 *val; | 436 | u32 *val; |
428 | const char * const *texts; | 437 | const char * const *texts; |
429 | void (*update)(struct rsnd_mod *mod); | 438 | void (*update)(struct rsnd_mod *mod); |
439 | struct snd_card *card; | ||
440 | struct snd_kcontrol *kctrl; | ||
430 | }; | 441 | }; |
431 | 442 | ||
432 | #define RSND_DVC_CHANNELS 2 | 443 | #define RSND_DVC_CHANNELS 2 |
@@ -440,22 +451,22 @@ struct rsnd_kctrl_cfg_s { | |||
440 | u32 val; | 451 | u32 val; |
441 | }; | 452 | }; |
442 | 453 | ||
454 | void _rsnd_kctrl_remove(struct rsnd_kctrl_cfg *cfg); | ||
455 | #define rsnd_kctrl_remove(_cfg) _rsnd_kctrl_remove(&((_cfg).cfg)) | ||
456 | |||
443 | int rsnd_kctrl_new_m(struct rsnd_mod *mod, | 457 | int rsnd_kctrl_new_m(struct rsnd_mod *mod, |
444 | struct rsnd_dai *rdai, | ||
445 | struct snd_soc_pcm_runtime *rtd, | 458 | struct snd_soc_pcm_runtime *rtd, |
446 | const unsigned char *name, | 459 | const unsigned char *name, |
447 | void (*update)(struct rsnd_mod *mod), | 460 | void (*update)(struct rsnd_mod *mod), |
448 | struct rsnd_kctrl_cfg_m *_cfg, | 461 | struct rsnd_kctrl_cfg_m *_cfg, |
449 | u32 max); | 462 | u32 max); |
450 | int rsnd_kctrl_new_s(struct rsnd_mod *mod, | 463 | int rsnd_kctrl_new_s(struct rsnd_mod *mod, |
451 | struct rsnd_dai *rdai, | ||
452 | struct snd_soc_pcm_runtime *rtd, | 464 | struct snd_soc_pcm_runtime *rtd, |
453 | const unsigned char *name, | 465 | const unsigned char *name, |
454 | void (*update)(struct rsnd_mod *mod), | 466 | void (*update)(struct rsnd_mod *mod), |
455 | struct rsnd_kctrl_cfg_s *_cfg, | 467 | struct rsnd_kctrl_cfg_s *_cfg, |
456 | u32 max); | 468 | u32 max); |
457 | int rsnd_kctrl_new_e(struct rsnd_mod *mod, | 469 | int rsnd_kctrl_new_e(struct rsnd_mod *mod, |
458 | struct rsnd_dai *rdai, | ||
459 | struct snd_soc_pcm_runtime *rtd, | 470 | struct snd_soc_pcm_runtime *rtd, |
460 | const unsigned char *name, | 471 | const unsigned char *name, |
461 | struct rsnd_kctrl_cfg_s *_cfg, | 472 | struct rsnd_kctrl_cfg_s *_cfg, |
@@ -474,14 +485,10 @@ unsigned int rsnd_src_get_ssi_rate(struct rsnd_priv *priv, | |||
474 | struct rsnd_dai_stream *io, | 485 | struct rsnd_dai_stream *io, |
475 | struct snd_pcm_runtime *runtime); | 486 | struct snd_pcm_runtime *runtime); |
476 | int rsnd_src_ssiu_start(struct rsnd_mod *ssi_mod, | 487 | int rsnd_src_ssiu_start(struct rsnd_mod *ssi_mod, |
477 | struct rsnd_dai *rdai, | ||
478 | int use_busif); | 488 | int use_busif); |
479 | int rsnd_src_ssiu_stop(struct rsnd_mod *ssi_mod, | 489 | int rsnd_src_ssiu_stop(struct rsnd_mod *ssi_mod); |
480 | struct rsnd_dai *rdai); | 490 | int rsnd_src_ssi_irq_enable(struct rsnd_mod *ssi_mod); |
481 | int rsnd_src_ssi_irq_enable(struct rsnd_mod *ssi_mod, | 491 | int rsnd_src_ssi_irq_disable(struct rsnd_mod *ssi_mod); |
482 | struct rsnd_dai *rdai); | ||
483 | int rsnd_src_ssi_irq_disable(struct rsnd_mod *ssi_mod, | ||
484 | struct rsnd_dai *rdai); | ||
485 | 492 | ||
486 | #define rsnd_src_nr(priv) ((priv)->src_nr) | 493 | #define rsnd_src_nr(priv) ((priv)->src_nr) |
487 | 494 | ||
diff --git a/sound/soc/sh/rcar/src.c b/sound/soc/sh/rcar/src.c index eede3ac6eed2..81c182b4bad5 100644 --- a/sound/soc/sh/rcar/src.c +++ b/sound/soc/sh/rcar/src.c | |||
@@ -12,10 +12,17 @@ | |||
12 | 12 | ||
13 | #define SRC_NAME "src" | 13 | #define SRC_NAME "src" |
14 | 14 | ||
15 | /* SRCx_STATUS */ | ||
16 | #define OUF_SRCO ((1 << 12) | (1 << 13)) | ||
17 | #define OUF_SRCI ((1 << 9) | (1 << 8)) | ||
18 | |||
19 | /* SCU_SYSTEM_STATUS0/1 */ | ||
20 | #define OUF_SRC(id) ((1 << (id + 16)) | (1 << id)) | ||
21 | |||
15 | struct rsnd_src { | 22 | struct rsnd_src { |
16 | struct rsnd_src_platform_info *info; /* rcar_snd.h */ | 23 | struct rsnd_src_platform_info *info; /* rcar_snd.h */ |
17 | struct rsnd_mod mod; | 24 | struct rsnd_mod mod; |
18 | struct clk *clk; | 25 | int err; |
19 | }; | 26 | }; |
20 | 27 | ||
21 | #define RSND_SRC_NAME_SIZE 16 | 28 | #define RSND_SRC_NAME_SIZE 16 |
@@ -107,10 +114,10 @@ struct rsnd_src { | |||
107 | * Gen1/Gen2 common functions | 114 | * Gen1/Gen2 common functions |
108 | */ | 115 | */ |
109 | int rsnd_src_ssiu_start(struct rsnd_mod *ssi_mod, | 116 | int rsnd_src_ssiu_start(struct rsnd_mod *ssi_mod, |
110 | struct rsnd_dai *rdai, | ||
111 | int use_busif) | 117 | int use_busif) |
112 | { | 118 | { |
113 | struct rsnd_dai_stream *io = rsnd_mod_to_io(ssi_mod); | 119 | struct rsnd_dai_stream *io = rsnd_mod_to_io(ssi_mod); |
120 | struct rsnd_dai *rdai = rsnd_io_to_rdai(io); | ||
114 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); | 121 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); |
115 | int ssi_id = rsnd_mod_id(ssi_mod); | 122 | int ssi_id = rsnd_mod_id(ssi_mod); |
116 | 123 | ||
@@ -140,7 +147,7 @@ int rsnd_src_ssiu_start(struct rsnd_mod *ssi_mod, | |||
140 | if (shift >= 0) | 147 | if (shift >= 0) |
141 | rsnd_mod_bset(ssi_mod, SSI_MODE1, | 148 | rsnd_mod_bset(ssi_mod, SSI_MODE1, |
142 | 0x3 << shift, | 149 | 0x3 << shift, |
143 | rsnd_dai_is_clk_master(rdai) ? | 150 | rsnd_rdai_is_clk_master(rdai) ? |
144 | 0x2 << shift : 0x1 << shift); | 151 | 0x2 << shift : 0x1 << shift); |
145 | } | 152 | } |
146 | 153 | ||
@@ -174,8 +181,7 @@ int rsnd_src_ssiu_start(struct rsnd_mod *ssi_mod, | |||
174 | return 0; | 181 | return 0; |
175 | } | 182 | } |
176 | 183 | ||
177 | int rsnd_src_ssiu_stop(struct rsnd_mod *ssi_mod, | 184 | int rsnd_src_ssiu_stop(struct rsnd_mod *ssi_mod) |
178 | struct rsnd_dai *rdai) | ||
179 | { | 185 | { |
180 | /* | 186 | /* |
181 | * DMA settings for SSIU | 187 | * DMA settings for SSIU |
@@ -185,8 +191,7 @@ int rsnd_src_ssiu_stop(struct rsnd_mod *ssi_mod, | |||
185 | return 0; | 191 | return 0; |
186 | } | 192 | } |
187 | 193 | ||
188 | int rsnd_src_ssi_irq_enable(struct rsnd_mod *ssi_mod, | 194 | int rsnd_src_ssi_irq_enable(struct rsnd_mod *ssi_mod) |
189 | struct rsnd_dai *rdai) | ||
190 | { | 195 | { |
191 | struct rsnd_priv *priv = rsnd_mod_to_priv(ssi_mod); | 196 | struct rsnd_priv *priv = rsnd_mod_to_priv(ssi_mod); |
192 | 197 | ||
@@ -202,8 +207,7 @@ int rsnd_src_ssi_irq_enable(struct rsnd_mod *ssi_mod, | |||
202 | return 0; | 207 | return 0; |
203 | } | 208 | } |
204 | 209 | ||
205 | int rsnd_src_ssi_irq_disable(struct rsnd_mod *ssi_mod, | 210 | int rsnd_src_ssi_irq_disable(struct rsnd_mod *ssi_mod) |
206 | struct rsnd_dai *rdai) | ||
207 | { | 211 | { |
208 | struct rsnd_priv *priv = rsnd_mod_to_priv(ssi_mod); | 212 | struct rsnd_priv *priv = rsnd_mod_to_priv(ssi_mod); |
209 | 213 | ||
@@ -240,8 +244,7 @@ unsigned int rsnd_src_get_ssi_rate(struct rsnd_priv *priv, | |||
240 | return rate; | 244 | return rate; |
241 | } | 245 | } |
242 | 246 | ||
243 | static int rsnd_src_set_convert_rate(struct rsnd_mod *mod, | 247 | static int rsnd_src_set_convert_rate(struct rsnd_mod *mod) |
244 | struct rsnd_dai *rdai) | ||
245 | { | 248 | { |
246 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); | 249 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); |
247 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); | 250 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); |
@@ -273,12 +276,13 @@ static int rsnd_src_set_convert_rate(struct rsnd_mod *mod, | |||
273 | return 0; | 276 | return 0; |
274 | } | 277 | } |
275 | 278 | ||
276 | static int rsnd_src_init(struct rsnd_mod *mod, | 279 | static int rsnd_src_init(struct rsnd_mod *mod) |
277 | struct rsnd_dai *rdai) | ||
278 | { | 280 | { |
279 | struct rsnd_src *src = rsnd_mod_to_src(mod); | 281 | struct rsnd_src *src = rsnd_mod_to_src(mod); |
280 | 282 | ||
281 | clk_prepare_enable(src->clk); | 283 | rsnd_mod_hw_start(mod); |
284 | |||
285 | src->err = 0; | ||
282 | 286 | ||
283 | /* | 287 | /* |
284 | * Initialize the operation of the SRC internal circuits | 288 | * Initialize the operation of the SRC internal circuits |
@@ -290,11 +294,16 @@ static int rsnd_src_init(struct rsnd_mod *mod, | |||
290 | } | 294 | } |
291 | 295 | ||
292 | static int rsnd_src_quit(struct rsnd_mod *mod, | 296 | static int rsnd_src_quit(struct rsnd_mod *mod, |
293 | struct rsnd_dai *rdai) | 297 | struct rsnd_priv *priv) |
294 | { | 298 | { |
295 | struct rsnd_src *src = rsnd_mod_to_src(mod); | 299 | struct rsnd_src *src = rsnd_mod_to_src(mod); |
300 | struct device *dev = rsnd_priv_to_dev(priv); | ||
301 | |||
302 | rsnd_mod_hw_stop(mod); | ||
296 | 303 | ||
297 | clk_disable_unprepare(src->clk); | 304 | if (src->err) |
305 | dev_warn(dev, "%s[%d] under/over flow err = %d\n", | ||
306 | rsnd_mod_name(mod), rsnd_mod_id(mod), src->err); | ||
298 | 307 | ||
299 | return 0; | 308 | return 0; |
300 | } | 309 | } |
@@ -319,8 +328,7 @@ static int rsnd_src_stop(struct rsnd_mod *mod) | |||
319 | /* | 328 | /* |
320 | * Gen1 functions | 329 | * Gen1 functions |
321 | */ | 330 | */ |
322 | static int rsnd_src_set_route_gen1(struct rsnd_mod *mod, | 331 | static int rsnd_src_set_route_gen1(struct rsnd_mod *mod) |
323 | struct rsnd_dai *rdai) | ||
324 | { | 332 | { |
325 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); | 333 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); |
326 | struct src_route_config { | 334 | struct src_route_config { |
@@ -348,7 +356,7 @@ static int rsnd_src_set_route_gen1(struct rsnd_mod *mod, | |||
348 | /* | 356 | /* |
349 | * SRC_ROUTE_SELECT | 357 | * SRC_ROUTE_SELECT |
350 | */ | 358 | */ |
351 | val = rsnd_dai_is_play(rdai, io) ? 0x1 : 0x2; | 359 | val = rsnd_io_is_play(io) ? 0x1 : 0x2; |
352 | val = val << routes[id].shift; | 360 | val = val << routes[id].shift; |
353 | mask = routes[id].mask << routes[id].shift; | 361 | mask = routes[id].mask << routes[id].shift; |
354 | 362 | ||
@@ -357,8 +365,7 @@ static int rsnd_src_set_route_gen1(struct rsnd_mod *mod, | |||
357 | return 0; | 365 | return 0; |
358 | } | 366 | } |
359 | 367 | ||
360 | static int rsnd_src_set_convert_timing_gen1(struct rsnd_mod *mod, | 368 | static int rsnd_src_set_convert_timing_gen1(struct rsnd_mod *mod) |
361 | struct rsnd_dai *rdai) | ||
362 | { | 369 | { |
363 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); | 370 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); |
364 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); | 371 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); |
@@ -416,13 +423,12 @@ static int rsnd_src_set_convert_timing_gen1(struct rsnd_mod *mod, | |||
416 | return 0; | 423 | return 0; |
417 | } | 424 | } |
418 | 425 | ||
419 | static int rsnd_src_set_convert_rate_gen1(struct rsnd_mod *mod, | 426 | static int rsnd_src_set_convert_rate_gen1(struct rsnd_mod *mod) |
420 | struct rsnd_dai *rdai) | ||
421 | { | 427 | { |
422 | struct rsnd_src *src = rsnd_mod_to_src(mod); | 428 | struct rsnd_src *src = rsnd_mod_to_src(mod); |
423 | int ret; | 429 | int ret; |
424 | 430 | ||
425 | ret = rsnd_src_set_convert_rate(mod, rdai); | 431 | ret = rsnd_src_set_convert_rate(mod); |
426 | if (ret < 0) | 432 | if (ret < 0) |
427 | return ret; | 433 | return ret; |
428 | 434 | ||
@@ -443,9 +449,8 @@ static int rsnd_src_set_convert_rate_gen1(struct rsnd_mod *mod, | |||
443 | } | 449 | } |
444 | 450 | ||
445 | static int rsnd_src_probe_gen1(struct rsnd_mod *mod, | 451 | static int rsnd_src_probe_gen1(struct rsnd_mod *mod, |
446 | struct rsnd_dai *rdai) | 452 | struct rsnd_priv *priv) |
447 | { | 453 | { |
448 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); | ||
449 | struct device *dev = rsnd_priv_to_dev(priv); | 454 | struct device *dev = rsnd_priv_to_dev(priv); |
450 | 455 | ||
451 | dev_dbg(dev, "%s[%d] (Gen1) is probed\n", | 456 | dev_dbg(dev, "%s[%d] (Gen1) is probed\n", |
@@ -455,23 +460,23 @@ static int rsnd_src_probe_gen1(struct rsnd_mod *mod, | |||
455 | } | 460 | } |
456 | 461 | ||
457 | static int rsnd_src_init_gen1(struct rsnd_mod *mod, | 462 | static int rsnd_src_init_gen1(struct rsnd_mod *mod, |
458 | struct rsnd_dai *rdai) | 463 | struct rsnd_priv *priv) |
459 | { | 464 | { |
460 | int ret; | 465 | int ret; |
461 | 466 | ||
462 | ret = rsnd_src_init(mod, rdai); | 467 | ret = rsnd_src_init(mod); |
463 | if (ret < 0) | 468 | if (ret < 0) |
464 | return ret; | 469 | return ret; |
465 | 470 | ||
466 | ret = rsnd_src_set_route_gen1(mod, rdai); | 471 | ret = rsnd_src_set_route_gen1(mod); |
467 | if (ret < 0) | 472 | if (ret < 0) |
468 | return ret; | 473 | return ret; |
469 | 474 | ||
470 | ret = rsnd_src_set_convert_rate_gen1(mod, rdai); | 475 | ret = rsnd_src_set_convert_rate_gen1(mod); |
471 | if (ret < 0) | 476 | if (ret < 0) |
472 | return ret; | 477 | return ret; |
473 | 478 | ||
474 | ret = rsnd_src_set_convert_timing_gen1(mod, rdai); | 479 | ret = rsnd_src_set_convert_timing_gen1(mod); |
475 | if (ret < 0) | 480 | if (ret < 0) |
476 | return ret; | 481 | return ret; |
477 | 482 | ||
@@ -479,7 +484,7 @@ static int rsnd_src_init_gen1(struct rsnd_mod *mod, | |||
479 | } | 484 | } |
480 | 485 | ||
481 | static int rsnd_src_start_gen1(struct rsnd_mod *mod, | 486 | static int rsnd_src_start_gen1(struct rsnd_mod *mod, |
482 | struct rsnd_dai *rdai) | 487 | struct rsnd_priv *priv) |
483 | { | 488 | { |
484 | int id = rsnd_mod_id(mod); | 489 | int id = rsnd_mod_id(mod); |
485 | 490 | ||
@@ -489,7 +494,7 @@ static int rsnd_src_start_gen1(struct rsnd_mod *mod, | |||
489 | } | 494 | } |
490 | 495 | ||
491 | static int rsnd_src_stop_gen1(struct rsnd_mod *mod, | 496 | static int rsnd_src_stop_gen1(struct rsnd_mod *mod, |
492 | struct rsnd_dai *rdai) | 497 | struct rsnd_priv *priv) |
493 | { | 498 | { |
494 | int id = rsnd_mod_id(mod); | 499 | int id = rsnd_mod_id(mod); |
495 | 500 | ||
@@ -510,8 +515,111 @@ static struct rsnd_mod_ops rsnd_src_gen1_ops = { | |||
510 | /* | 515 | /* |
511 | * Gen2 functions | 516 | * Gen2 functions |
512 | */ | 517 | */ |
513 | static int rsnd_src_set_convert_rate_gen2(struct rsnd_mod *mod, | 518 | #define rsnd_src_irq_enable_gen2(mod) rsnd_src_irq_ctrol_gen2(mod, 1) |
514 | struct rsnd_dai *rdai) | 519 | #define rsnd_src_irq_disable_gen2(mod) rsnd_src_irq_ctrol_gen2(mod, 0) |
520 | static void rsnd_src_irq_ctrol_gen2(struct rsnd_mod *mod, int enable) | ||
521 | { | ||
522 | struct rsnd_src *src = rsnd_mod_to_src(mod); | ||
523 | u32 sys_int_val, int_val, sys_int_mask; | ||
524 | int irq = src->info->irq; | ||
525 | int id = rsnd_mod_id(mod); | ||
526 | |||
527 | sys_int_val = | ||
528 | sys_int_mask = OUF_SRC(id); | ||
529 | int_val = 0x3300; | ||
530 | |||
531 | /* | ||
532 | * IRQ is not supported on non-DT | ||
533 | * see | ||
534 | * rsnd_src_probe_gen2() | ||
535 | */ | ||
536 | if ((irq <= 0) || !enable) { | ||
537 | sys_int_val = 0; | ||
538 | int_val = 0; | ||
539 | } | ||
540 | |||
541 | rsnd_mod_write(mod, SRC_INT_ENABLE0, int_val); | ||
542 | rsnd_mod_bset(mod, SCU_SYS_INT_EN0, sys_int_mask, sys_int_val); | ||
543 | rsnd_mod_bset(mod, SCU_SYS_INT_EN1, sys_int_mask, sys_int_val); | ||
544 | } | ||
545 | |||
546 | static void rsnd_src_error_clear_gen2(struct rsnd_mod *mod) | ||
547 | { | ||
548 | u32 val = OUF_SRC(rsnd_mod_id(mod)); | ||
549 | |||
550 | rsnd_mod_bset(mod, SCU_SYS_STATUS0, val, val); | ||
551 | rsnd_mod_bset(mod, SCU_SYS_STATUS1, val, val); | ||
552 | } | ||
553 | |||
554 | static bool rsnd_src_error_record_gen2(struct rsnd_mod *mod) | ||
555 | { | ||
556 | u32 val = OUF_SRC(rsnd_mod_id(mod)); | ||
557 | bool ret = false; | ||
558 | |||
559 | if ((rsnd_mod_read(mod, SCU_SYS_STATUS0) & val) || | ||
560 | (rsnd_mod_read(mod, SCU_SYS_STATUS1) & val)) { | ||
561 | struct rsnd_src *src = rsnd_mod_to_src(mod); | ||
562 | |||
563 | src->err++; | ||
564 | ret = true; | ||
565 | } | ||
566 | |||
567 | /* clear error static */ | ||
568 | rsnd_src_error_clear_gen2(mod); | ||
569 | |||
570 | return ret; | ||
571 | } | ||
572 | |||
573 | static int _rsnd_src_start_gen2(struct rsnd_mod *mod) | ||
574 | { | ||
575 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); | ||
576 | u32 val = rsnd_io_to_mod_dvc(io) ? 0x01 : 0x11; | ||
577 | |||
578 | rsnd_mod_write(mod, SRC_CTRL, val); | ||
579 | |||
580 | rsnd_src_error_clear_gen2(mod); | ||
581 | |||
582 | rsnd_src_start(mod); | ||
583 | |||
584 | rsnd_src_irq_enable_gen2(mod); | ||
585 | |||
586 | return 0; | ||
587 | } | ||
588 | |||
589 | static int _rsnd_src_stop_gen2(struct rsnd_mod *mod) | ||
590 | { | ||
591 | rsnd_src_irq_disable_gen2(mod); | ||
592 | |||
593 | rsnd_mod_write(mod, SRC_CTRL, 0); | ||
594 | |||
595 | rsnd_src_error_record_gen2(mod); | ||
596 | |||
597 | return rsnd_src_stop(mod); | ||
598 | } | ||
599 | |||
600 | static irqreturn_t rsnd_src_interrupt_gen2(int irq, void *data) | ||
601 | { | ||
602 | struct rsnd_mod *mod = data; | ||
603 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); | ||
604 | |||
605 | if (!io) | ||
606 | return IRQ_NONE; | ||
607 | |||
608 | if (rsnd_src_error_record_gen2(mod)) { | ||
609 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); | ||
610 | struct device *dev = rsnd_priv_to_dev(priv); | ||
611 | |||
612 | _rsnd_src_stop_gen2(mod); | ||
613 | _rsnd_src_start_gen2(mod); | ||
614 | |||
615 | dev_dbg(dev, "%s[%d] restart\n", | ||
616 | rsnd_mod_name(mod), rsnd_mod_id(mod)); | ||
617 | } | ||
618 | |||
619 | return IRQ_HANDLED; | ||
620 | } | ||
621 | |||
622 | static int rsnd_src_set_convert_rate_gen2(struct rsnd_mod *mod) | ||
515 | { | 623 | { |
516 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); | 624 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); |
517 | struct device *dev = rsnd_priv_to_dev(priv); | 625 | struct device *dev = rsnd_priv_to_dev(priv); |
@@ -535,7 +643,7 @@ static int rsnd_src_set_convert_rate_gen2(struct rsnd_mod *mod, | |||
535 | return -EINVAL; | 643 | return -EINVAL; |
536 | } | 644 | } |
537 | 645 | ||
538 | ret = rsnd_src_set_convert_rate(mod, rdai); | 646 | ret = rsnd_src_set_convert_rate(mod); |
539 | if (ret < 0) | 647 | if (ret < 0) |
540 | return ret; | 648 | return ret; |
541 | 649 | ||
@@ -563,8 +671,7 @@ static int rsnd_src_set_convert_rate_gen2(struct rsnd_mod *mod, | |||
563 | return 0; | 671 | return 0; |
564 | } | 672 | } |
565 | 673 | ||
566 | static int rsnd_src_set_convert_timing_gen2(struct rsnd_mod *mod, | 674 | static int rsnd_src_set_convert_timing_gen2(struct rsnd_mod *mod) |
567 | struct rsnd_dai *rdai) | ||
568 | { | 675 | { |
569 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); | 676 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); |
570 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); | 677 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); |
@@ -573,59 +680,78 @@ static int rsnd_src_set_convert_timing_gen2(struct rsnd_mod *mod, | |||
573 | int ret; | 680 | int ret; |
574 | 681 | ||
575 | if (convert_rate) | 682 | if (convert_rate) |
576 | ret = rsnd_adg_set_convert_clk_gen2(mod, rdai, io, | 683 | ret = rsnd_adg_set_convert_clk_gen2(mod, io, |
577 | runtime->rate, | 684 | runtime->rate, |
578 | convert_rate); | 685 | convert_rate); |
579 | else | 686 | else |
580 | ret = rsnd_adg_set_convert_timing_gen2(mod, rdai, io); | 687 | ret = rsnd_adg_set_convert_timing_gen2(mod, io); |
581 | 688 | ||
582 | return ret; | 689 | return ret; |
583 | } | 690 | } |
584 | 691 | ||
585 | static int rsnd_src_probe_gen2(struct rsnd_mod *mod, | 692 | static int rsnd_src_probe_gen2(struct rsnd_mod *mod, |
586 | struct rsnd_dai *rdai) | 693 | struct rsnd_priv *priv) |
587 | { | 694 | { |
588 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); | ||
589 | struct rsnd_src *src = rsnd_mod_to_src(mod); | 695 | struct rsnd_src *src = rsnd_mod_to_src(mod); |
590 | struct device *dev = rsnd_priv_to_dev(priv); | 696 | struct device *dev = rsnd_priv_to_dev(priv); |
697 | int irq = src->info->irq; | ||
591 | int ret; | 698 | int ret; |
592 | 699 | ||
700 | if (irq > 0) { | ||
701 | /* | ||
702 | * IRQ is not supported on non-DT | ||
703 | * see | ||
704 | * rsnd_src_irq_enable_gen2() | ||
705 | */ | ||
706 | ret = devm_request_irq(dev, irq, | ||
707 | rsnd_src_interrupt_gen2, | ||
708 | IRQF_SHARED, | ||
709 | dev_name(dev), mod); | ||
710 | if (ret) | ||
711 | goto rsnd_src_probe_gen2_fail; | ||
712 | } | ||
713 | |||
593 | ret = rsnd_dma_init(priv, | 714 | ret = rsnd_dma_init(priv, |
594 | rsnd_mod_to_dma(mod), | 715 | rsnd_mod_to_dma(mod), |
595 | rsnd_info_is_playback(priv, src), | 716 | rsnd_info_is_playback(priv, src), |
596 | src->info->dma_id); | 717 | src->info->dma_id); |
597 | if (ret < 0) | 718 | if (ret) |
598 | dev_err(dev, "%s[%d] (Gen2) failed\n", | 719 | goto rsnd_src_probe_gen2_fail; |
599 | rsnd_mod_name(mod), rsnd_mod_id(mod)); | 720 | |
600 | else | 721 | dev_dbg(dev, "%s[%d] (Gen2) is probed\n", |
601 | dev_dbg(dev, "%s[%d] (Gen2) is probed\n", | 722 | rsnd_mod_name(mod), rsnd_mod_id(mod)); |
602 | rsnd_mod_name(mod), rsnd_mod_id(mod)); | 723 | |
724 | return ret; | ||
725 | |||
726 | rsnd_src_probe_gen2_fail: | ||
727 | dev_err(dev, "%s[%d] (Gen2) failed\n", | ||
728 | rsnd_mod_name(mod), rsnd_mod_id(mod)); | ||
603 | 729 | ||
604 | return ret; | 730 | return ret; |
605 | } | 731 | } |
606 | 732 | ||
607 | static int rsnd_src_remove_gen2(struct rsnd_mod *mod, | 733 | static int rsnd_src_remove_gen2(struct rsnd_mod *mod, |
608 | struct rsnd_dai *rdai) | 734 | struct rsnd_priv *priv) |
609 | { | 735 | { |
610 | rsnd_dma_quit(rsnd_mod_to_priv(mod), rsnd_mod_to_dma(mod)); | 736 | rsnd_dma_quit(priv, rsnd_mod_to_dma(mod)); |
611 | 737 | ||
612 | return 0; | 738 | return 0; |
613 | } | 739 | } |
614 | 740 | ||
615 | static int rsnd_src_init_gen2(struct rsnd_mod *mod, | 741 | static int rsnd_src_init_gen2(struct rsnd_mod *mod, |
616 | struct rsnd_dai *rdai) | 742 | struct rsnd_priv *priv) |
617 | { | 743 | { |
618 | int ret; | 744 | int ret; |
619 | 745 | ||
620 | ret = rsnd_src_init(mod, rdai); | 746 | ret = rsnd_src_init(mod); |
621 | if (ret < 0) | 747 | if (ret < 0) |
622 | return ret; | 748 | return ret; |
623 | 749 | ||
624 | ret = rsnd_src_set_convert_rate_gen2(mod, rdai); | 750 | ret = rsnd_src_set_convert_rate_gen2(mod); |
625 | if (ret < 0) | 751 | if (ret < 0) |
626 | return ret; | 752 | return ret; |
627 | 753 | ||
628 | ret = rsnd_src_set_convert_timing_gen2(mod, rdai); | 754 | ret = rsnd_src_set_convert_timing_gen2(mod); |
629 | if (ret < 0) | 755 | if (ret < 0) |
630 | return ret; | 756 | return ret; |
631 | 757 | ||
@@ -633,29 +759,23 @@ static int rsnd_src_init_gen2(struct rsnd_mod *mod, | |||
633 | } | 759 | } |
634 | 760 | ||
635 | static int rsnd_src_start_gen2(struct rsnd_mod *mod, | 761 | static int rsnd_src_start_gen2(struct rsnd_mod *mod, |
636 | struct rsnd_dai *rdai) | 762 | struct rsnd_priv *priv) |
637 | { | 763 | { |
638 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); | 764 | rsnd_dma_start(rsnd_mod_to_dma(mod)); |
639 | struct rsnd_src *src = rsnd_mod_to_src(mod); | ||
640 | u32 val = rsnd_io_to_mod_dvc(io) ? 0x01 : 0x11; | ||
641 | |||
642 | rsnd_dma_start(rsnd_mod_to_dma(&src->mod)); | ||
643 | 765 | ||
644 | rsnd_mod_write(mod, SRC_CTRL, val); | 766 | return _rsnd_src_start_gen2(mod); |
645 | |||
646 | return rsnd_src_start(mod); | ||
647 | } | 767 | } |
648 | 768 | ||
649 | static int rsnd_src_stop_gen2(struct rsnd_mod *mod, | 769 | static int rsnd_src_stop_gen2(struct rsnd_mod *mod, |
650 | struct rsnd_dai *rdai) | 770 | struct rsnd_priv *priv) |
651 | { | 771 | { |
652 | struct rsnd_src *src = rsnd_mod_to_src(mod); | 772 | int ret; |
653 | 773 | ||
654 | rsnd_mod_write(mod, SRC_CTRL, 0); | 774 | ret = _rsnd_src_stop_gen2(mod); |
655 | 775 | ||
656 | rsnd_dma_stop(rsnd_mod_to_dma(&src->mod)); | 776 | rsnd_dma_stop(rsnd_mod_to_dma(mod)); |
657 | 777 | ||
658 | return rsnd_src_stop(mod); | 778 | return ret; |
659 | } | 779 | } |
660 | 780 | ||
661 | static struct rsnd_mod_ops rsnd_src_gen2_ops = { | 781 | static struct rsnd_mod_ops rsnd_src_gen2_ops = { |
@@ -681,10 +801,11 @@ static void rsnd_of_parse_src(struct platform_device *pdev, | |||
681 | struct rsnd_priv *priv) | 801 | struct rsnd_priv *priv) |
682 | { | 802 | { |
683 | struct device_node *src_node; | 803 | struct device_node *src_node; |
804 | struct device_node *np; | ||
684 | struct rcar_snd_info *info = rsnd_priv_to_info(priv); | 805 | struct rcar_snd_info *info = rsnd_priv_to_info(priv); |
685 | struct rsnd_src_platform_info *src_info; | 806 | struct rsnd_src_platform_info *src_info; |
686 | struct device *dev = &pdev->dev; | 807 | struct device *dev = &pdev->dev; |
687 | int nr; | 808 | int nr, i; |
688 | 809 | ||
689 | if (!of_data) | 810 | if (!of_data) |
690 | return; | 811 | return; |
@@ -708,6 +829,13 @@ static void rsnd_of_parse_src(struct platform_device *pdev, | |||
708 | info->src_info = src_info; | 829 | info->src_info = src_info; |
709 | info->src_info_nr = nr; | 830 | info->src_info_nr = nr; |
710 | 831 | ||
832 | i = 0; | ||
833 | for_each_child_of_node(src_node, np) { | ||
834 | src_info[i].irq = irq_of_parse_and_map(np, 0); | ||
835 | |||
836 | i++; | ||
837 | } | ||
838 | |||
711 | rsnd_of_parse_src_end: | 839 | rsnd_of_parse_src_end: |
712 | of_node_put(src_node); | 840 | of_node_put(src_node); |
713 | } | 841 | } |
@@ -761,9 +889,8 @@ int rsnd_src_probe(struct platform_device *pdev, | |||
761 | return PTR_ERR(clk); | 889 | return PTR_ERR(clk); |
762 | 890 | ||
763 | src->info = &info->src_info[i]; | 891 | src->info = &info->src_info[i]; |
764 | src->clk = clk; | ||
765 | 892 | ||
766 | rsnd_mod_init(priv, &src->mod, ops, RSND_MOD_SRC, i); | 893 | rsnd_mod_init(&src->mod, ops, clk, RSND_MOD_SRC, i); |
767 | 894 | ||
768 | dev_dbg(dev, "SRC%d probed\n", i); | 895 | dev_dbg(dev, "SRC%d probed\n", i); |
769 | } | 896 | } |
diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c index 3844fbef4664..9e7b627c08e2 100644 --- a/sound/soc/sh/rcar/ssi.c +++ b/sound/soc/sh/rcar/ssi.c | |||
@@ -60,17 +60,14 @@ | |||
60 | #define SSI_NAME "ssi" | 60 | #define SSI_NAME "ssi" |
61 | 61 | ||
62 | struct rsnd_ssi { | 62 | struct rsnd_ssi { |
63 | struct clk *clk; | ||
64 | struct rsnd_ssi_platform_info *info; /* rcar_snd.h */ | 63 | struct rsnd_ssi_platform_info *info; /* rcar_snd.h */ |
65 | struct rsnd_ssi *parent; | 64 | struct rsnd_ssi *parent; |
66 | struct rsnd_mod mod; | 65 | struct rsnd_mod mod; |
67 | 66 | ||
68 | struct rsnd_dai *rdai; | ||
69 | u32 cr_own; | 67 | u32 cr_own; |
70 | u32 cr_clk; | 68 | u32 cr_clk; |
71 | int err; | 69 | int err; |
72 | unsigned int usrcnt; | 70 | unsigned int usrcnt; |
73 | unsigned int rate; | ||
74 | }; | 71 | }; |
75 | 72 | ||
76 | #define for_each_rsnd_ssi(pos, priv, i) \ | 73 | #define for_each_rsnd_ssi(pos, priv, i) \ |
@@ -128,7 +125,7 @@ static void rsnd_ssi_status_check(struct rsnd_mod *mod, | |||
128 | static int rsnd_ssi_master_clk_start(struct rsnd_ssi *ssi, | 125 | static int rsnd_ssi_master_clk_start(struct rsnd_ssi *ssi, |
129 | struct rsnd_dai_stream *io) | 126 | struct rsnd_dai_stream *io) |
130 | { | 127 | { |
131 | struct rsnd_priv *priv = rsnd_mod_to_priv(&ssi->mod); | 128 | struct rsnd_priv *priv = rsnd_io_to_priv(io); |
132 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); | 129 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); |
133 | struct device *dev = rsnd_priv_to_dev(priv); | 130 | struct device *dev = rsnd_priv_to_dev(priv); |
134 | int i, j, ret; | 131 | int i, j, ret; |
@@ -157,7 +154,6 @@ static int rsnd_ssi_master_clk_start(struct rsnd_ssi *ssi, | |||
157 | 154 | ||
158 | ret = rsnd_adg_ssi_clk_try_start(&ssi->mod, main_rate); | 155 | ret = rsnd_adg_ssi_clk_try_start(&ssi->mod, main_rate); |
159 | if (0 == ret) { | 156 | if (0 == ret) { |
160 | ssi->rate = rate; | ||
161 | ssi->cr_clk = FORCE | SWL_32 | | 157 | ssi->cr_clk = FORCE | SWL_32 | |
162 | SCKD | SWSD | CKDV(j); | 158 | SCKD | SWSD | CKDV(j); |
163 | 159 | ||
@@ -176,26 +172,25 @@ static int rsnd_ssi_master_clk_start(struct rsnd_ssi *ssi, | |||
176 | 172 | ||
177 | static void rsnd_ssi_master_clk_stop(struct rsnd_ssi *ssi) | 173 | static void rsnd_ssi_master_clk_stop(struct rsnd_ssi *ssi) |
178 | { | 174 | { |
179 | ssi->rate = 0; | ||
180 | ssi->cr_clk = 0; | 175 | ssi->cr_clk = 0; |
181 | rsnd_adg_ssi_clk_stop(&ssi->mod); | 176 | rsnd_adg_ssi_clk_stop(&ssi->mod); |
182 | } | 177 | } |
183 | 178 | ||
184 | static void rsnd_ssi_hw_start(struct rsnd_ssi *ssi, | 179 | static void rsnd_ssi_hw_start(struct rsnd_ssi *ssi, |
185 | struct rsnd_dai *rdai, | ||
186 | struct rsnd_dai_stream *io) | 180 | struct rsnd_dai_stream *io) |
187 | { | 181 | { |
188 | struct rsnd_priv *priv = rsnd_mod_to_priv(&ssi->mod); | 182 | struct rsnd_priv *priv = rsnd_io_to_priv(io); |
183 | struct rsnd_dai *rdai = rsnd_io_to_rdai(io); | ||
189 | struct device *dev = rsnd_priv_to_dev(priv); | 184 | struct device *dev = rsnd_priv_to_dev(priv); |
190 | u32 cr_mode; | 185 | u32 cr_mode; |
191 | u32 cr; | 186 | u32 cr; |
192 | 187 | ||
193 | if (0 == ssi->usrcnt) { | 188 | if (0 == ssi->usrcnt) { |
194 | clk_prepare_enable(ssi->clk); | 189 | rsnd_mod_hw_start(&ssi->mod); |
195 | 190 | ||
196 | if (rsnd_dai_is_clk_master(rdai)) { | 191 | if (rsnd_rdai_is_clk_master(rdai)) { |
197 | if (rsnd_ssi_clk_from_parent(ssi)) | 192 | if (rsnd_ssi_clk_from_parent(ssi)) |
198 | rsnd_ssi_hw_start(ssi->parent, rdai, io); | 193 | rsnd_ssi_hw_start(ssi->parent, io); |
199 | else | 194 | else |
200 | rsnd_ssi_master_clk_start(ssi, io); | 195 | rsnd_ssi_master_clk_start(ssi, io); |
201 | } | 196 | } |
@@ -214,7 +209,7 @@ static void rsnd_ssi_hw_start(struct rsnd_ssi *ssi, | |||
214 | rsnd_mod_write(&ssi->mod, SSICR, cr); | 209 | rsnd_mod_write(&ssi->mod, SSICR, cr); |
215 | 210 | ||
216 | /* enable WS continue */ | 211 | /* enable WS continue */ |
217 | if (rsnd_dai_is_clk_master(rdai)) | 212 | if (rsnd_rdai_is_clk_master(rdai)) |
218 | rsnd_mod_write(&ssi->mod, SSIWSR, CONT); | 213 | rsnd_mod_write(&ssi->mod, SSIWSR, CONT); |
219 | 214 | ||
220 | /* clear error status */ | 215 | /* clear error status */ |
@@ -226,10 +221,11 @@ static void rsnd_ssi_hw_start(struct rsnd_ssi *ssi, | |||
226 | rsnd_mod_name(&ssi->mod), rsnd_mod_id(&ssi->mod)); | 221 | rsnd_mod_name(&ssi->mod), rsnd_mod_id(&ssi->mod)); |
227 | } | 222 | } |
228 | 223 | ||
229 | static void rsnd_ssi_hw_stop(struct rsnd_ssi *ssi, | 224 | static void rsnd_ssi_hw_stop(struct rsnd_ssi *ssi) |
230 | struct rsnd_dai *rdai) | ||
231 | { | 225 | { |
232 | struct rsnd_priv *priv = rsnd_mod_to_priv(&ssi->mod); | 226 | struct rsnd_priv *priv = rsnd_mod_to_priv(&ssi->mod); |
227 | struct rsnd_dai_stream *io = rsnd_mod_to_io(&ssi->mod); | ||
228 | struct rsnd_dai *rdai = rsnd_io_to_rdai(io); | ||
233 | struct device *dev = rsnd_priv_to_dev(priv); | 229 | struct device *dev = rsnd_priv_to_dev(priv); |
234 | u32 cr; | 230 | u32 cr; |
235 | 231 | ||
@@ -256,14 +252,14 @@ static void rsnd_ssi_hw_stop(struct rsnd_ssi *ssi, | |||
256 | rsnd_mod_write(&ssi->mod, SSICR, cr); /* disabled all */ | 252 | rsnd_mod_write(&ssi->mod, SSICR, cr); /* disabled all */ |
257 | rsnd_ssi_status_check(&ssi->mod, IIRQ); | 253 | rsnd_ssi_status_check(&ssi->mod, IIRQ); |
258 | 254 | ||
259 | if (rsnd_dai_is_clk_master(rdai)) { | 255 | if (rsnd_rdai_is_clk_master(rdai)) { |
260 | if (rsnd_ssi_clk_from_parent(ssi)) | 256 | if (rsnd_ssi_clk_from_parent(ssi)) |
261 | rsnd_ssi_hw_stop(ssi->parent, rdai); | 257 | rsnd_ssi_hw_stop(ssi->parent); |
262 | else | 258 | else |
263 | rsnd_ssi_master_clk_stop(ssi); | 259 | rsnd_ssi_master_clk_stop(ssi); |
264 | } | 260 | } |
265 | 261 | ||
266 | clk_disable_unprepare(ssi->clk); | 262 | rsnd_mod_hw_stop(&ssi->mod); |
267 | } | 263 | } |
268 | 264 | ||
269 | dev_dbg(dev, "%s[%d] hw stopped\n", | 265 | dev_dbg(dev, "%s[%d] hw stopped\n", |
@@ -274,10 +270,11 @@ static void rsnd_ssi_hw_stop(struct rsnd_ssi *ssi, | |||
274 | * SSI mod common functions | 270 | * SSI mod common functions |
275 | */ | 271 | */ |
276 | static int rsnd_ssi_init(struct rsnd_mod *mod, | 272 | static int rsnd_ssi_init(struct rsnd_mod *mod, |
277 | struct rsnd_dai *rdai) | 273 | struct rsnd_priv *priv) |
278 | { | 274 | { |
279 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); | 275 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); |
280 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); | 276 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); |
277 | struct rsnd_dai *rdai = rsnd_io_to_rdai(io); | ||
281 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); | 278 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); |
282 | u32 cr; | 279 | u32 cr; |
283 | 280 | ||
@@ -311,13 +308,12 @@ static int rsnd_ssi_init(struct rsnd_mod *mod, | |||
311 | cr |= SDTA; | 308 | cr |= SDTA; |
312 | if (rdai->sys_delay) | 309 | if (rdai->sys_delay) |
313 | cr |= DEL; | 310 | cr |= DEL; |
314 | if (rsnd_dai_is_play(rdai, io)) | 311 | if (rsnd_io_is_play(io)) |
315 | cr |= TRMD; | 312 | cr |= TRMD; |
316 | 313 | ||
317 | /* | 314 | /* |
318 | * set ssi parameter | 315 | * set ssi parameter |
319 | */ | 316 | */ |
320 | ssi->rdai = rdai; | ||
321 | ssi->cr_own = cr; | 317 | ssi->cr_own = cr; |
322 | ssi->err = -1; /* ignore 1st error */ | 318 | ssi->err = -1; /* ignore 1st error */ |
323 | 319 | ||
@@ -325,16 +321,15 @@ static int rsnd_ssi_init(struct rsnd_mod *mod, | |||
325 | } | 321 | } |
326 | 322 | ||
327 | static int rsnd_ssi_quit(struct rsnd_mod *mod, | 323 | static int rsnd_ssi_quit(struct rsnd_mod *mod, |
328 | struct rsnd_dai *rdai) | 324 | struct rsnd_priv *priv) |
329 | { | 325 | { |
330 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); | 326 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); |
331 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); | ||
332 | struct device *dev = rsnd_priv_to_dev(priv); | 327 | struct device *dev = rsnd_priv_to_dev(priv); |
333 | 328 | ||
334 | if (ssi->err > 0) | 329 | if (ssi->err > 0) |
335 | dev_warn(dev, "ssi under/over flow err = %d\n", ssi->err); | 330 | dev_warn(dev, "%s[%d] under/over flow err = %d\n", |
331 | rsnd_mod_name(mod), rsnd_mod_id(mod), ssi->err); | ||
336 | 332 | ||
337 | ssi->rdai = NULL; | ||
338 | ssi->cr_own = 0; | 333 | ssi->cr_own = 0; |
339 | ssi->err = 0; | 334 | ssi->err = 0; |
340 | 335 | ||
@@ -353,32 +348,32 @@ static void rsnd_ssi_record_error(struct rsnd_ssi *ssi, u32 status) | |||
353 | } | 348 | } |
354 | 349 | ||
355 | static int rsnd_ssi_start(struct rsnd_mod *mod, | 350 | static int rsnd_ssi_start(struct rsnd_mod *mod, |
356 | struct rsnd_dai *rdai) | 351 | struct rsnd_priv *priv) |
357 | { | 352 | { |
358 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); | 353 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); |
359 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); | 354 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); |
360 | 355 | ||
361 | rsnd_src_ssiu_start(mod, rdai, rsnd_ssi_use_busif(mod)); | 356 | rsnd_src_ssiu_start(mod, rsnd_ssi_use_busif(mod)); |
362 | 357 | ||
363 | rsnd_ssi_hw_start(ssi, rdai, io); | 358 | rsnd_ssi_hw_start(ssi, io); |
364 | 359 | ||
365 | rsnd_src_ssi_irq_enable(mod, rdai); | 360 | rsnd_src_ssi_irq_enable(mod); |
366 | 361 | ||
367 | return 0; | 362 | return 0; |
368 | } | 363 | } |
369 | 364 | ||
370 | static int rsnd_ssi_stop(struct rsnd_mod *mod, | 365 | static int rsnd_ssi_stop(struct rsnd_mod *mod, |
371 | struct rsnd_dai *rdai) | 366 | struct rsnd_priv *priv) |
372 | { | 367 | { |
373 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); | 368 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); |
374 | 369 | ||
375 | rsnd_src_ssi_irq_disable(mod, rdai); | 370 | rsnd_src_ssi_irq_disable(mod); |
376 | 371 | ||
377 | rsnd_ssi_record_error(ssi, rsnd_mod_read(mod, SSISR)); | 372 | rsnd_ssi_record_error(ssi, rsnd_mod_read(mod, SSISR)); |
378 | 373 | ||
379 | rsnd_ssi_hw_stop(ssi, rdai); | 374 | rsnd_ssi_hw_stop(ssi); |
380 | 375 | ||
381 | rsnd_src_ssiu_stop(mod, rdai); | 376 | rsnd_src_ssiu_stop(mod); |
382 | 377 | ||
383 | return 0; | 378 | return 0; |
384 | } | 379 | } |
@@ -386,16 +381,17 @@ static int rsnd_ssi_stop(struct rsnd_mod *mod, | |||
386 | static irqreturn_t rsnd_ssi_interrupt(int irq, void *data) | 381 | static irqreturn_t rsnd_ssi_interrupt(int irq, void *data) |
387 | { | 382 | { |
388 | struct rsnd_ssi *ssi = data; | 383 | struct rsnd_ssi *ssi = data; |
389 | struct rsnd_dai *rdai = ssi->rdai; | ||
390 | struct rsnd_mod *mod = &ssi->mod; | 384 | struct rsnd_mod *mod = &ssi->mod; |
385 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); | ||
391 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); | 386 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); |
387 | int is_dma = rsnd_ssi_is_dma_mode(mod); | ||
392 | u32 status = rsnd_mod_read(mod, SSISR); | 388 | u32 status = rsnd_mod_read(mod, SSISR); |
393 | 389 | ||
394 | if (!io) | 390 | if (!io) |
395 | return IRQ_NONE; | 391 | return IRQ_NONE; |
396 | 392 | ||
397 | /* PIO only */ | 393 | /* PIO only */ |
398 | if (status & DIRQ) { | 394 | if (!is_dma && (status & DIRQ)) { |
399 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); | 395 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); |
400 | u32 *buf = (u32 *)(runtime->dma_area + | 396 | u32 *buf = (u32 *)(runtime->dma_area + |
401 | rsnd_dai_pointer_offset(io, 0)); | 397 | rsnd_dai_pointer_offset(io, 0)); |
@@ -405,7 +401,7 @@ static irqreturn_t rsnd_ssi_interrupt(int irq, void *data) | |||
405 | * directly as 32bit data | 401 | * directly as 32bit data |
406 | * see rsnd_ssi_init() | 402 | * see rsnd_ssi_init() |
407 | */ | 403 | */ |
408 | if (rsnd_dai_is_play(rdai, io)) | 404 | if (rsnd_io_is_play(io)) |
409 | rsnd_mod_write(mod, SSITDR, *buf); | 405 | rsnd_mod_write(mod, SSITDR, *buf); |
410 | else | 406 | else |
411 | *buf = rsnd_mod_read(mod, SSIRDR); | 407 | *buf = rsnd_mod_read(mod, SSIRDR); |
@@ -415,14 +411,13 @@ static irqreturn_t rsnd_ssi_interrupt(int irq, void *data) | |||
415 | 411 | ||
416 | /* PIO / DMA */ | 412 | /* PIO / DMA */ |
417 | if (status & (UIRQ | OIRQ)) { | 413 | if (status & (UIRQ | OIRQ)) { |
418 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); | ||
419 | struct device *dev = rsnd_priv_to_dev(priv); | 414 | struct device *dev = rsnd_priv_to_dev(priv); |
420 | 415 | ||
421 | /* | 416 | /* |
422 | * restart SSI | 417 | * restart SSI |
423 | */ | 418 | */ |
424 | rsnd_ssi_stop(mod, rdai); | 419 | rsnd_ssi_stop(mod, priv); |
425 | rsnd_ssi_start(mod, rdai); | 420 | rsnd_ssi_start(mod, priv); |
426 | 421 | ||
427 | dev_dbg(dev, "%s[%d] restart\n", | 422 | dev_dbg(dev, "%s[%d] restart\n", |
428 | rsnd_mod_name(mod), rsnd_mod_id(mod)); | 423 | rsnd_mod_name(mod), rsnd_mod_id(mod)); |
@@ -437,9 +432,8 @@ static irqreturn_t rsnd_ssi_interrupt(int irq, void *data) | |||
437 | * SSI PIO | 432 | * SSI PIO |
438 | */ | 433 | */ |
439 | static int rsnd_ssi_pio_probe(struct rsnd_mod *mod, | 434 | static int rsnd_ssi_pio_probe(struct rsnd_mod *mod, |
440 | struct rsnd_dai *rdai) | 435 | struct rsnd_priv *priv) |
441 | { | 436 | { |
442 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); | ||
443 | struct device *dev = rsnd_priv_to_dev(priv); | 437 | struct device *dev = rsnd_priv_to_dev(priv); |
444 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); | 438 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); |
445 | int ret; | 439 | int ret; |
@@ -468,9 +462,8 @@ static struct rsnd_mod_ops rsnd_ssi_pio_ops = { | |||
468 | }; | 462 | }; |
469 | 463 | ||
470 | static int rsnd_ssi_dma_probe(struct rsnd_mod *mod, | 464 | static int rsnd_ssi_dma_probe(struct rsnd_mod *mod, |
471 | struct rsnd_dai *rdai) | 465 | struct rsnd_priv *priv) |
472 | { | 466 | { |
473 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); | ||
474 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); | 467 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); |
475 | struct device *dev = rsnd_priv_to_dev(priv); | 468 | struct device *dev = rsnd_priv_to_dev(priv); |
476 | int dma_id = ssi->info->dma_id; | 469 | int dma_id = ssi->info->dma_id; |
@@ -503,14 +496,13 @@ rsnd_ssi_dma_probe_fail: | |||
503 | } | 496 | } |
504 | 497 | ||
505 | static int rsnd_ssi_dma_remove(struct rsnd_mod *mod, | 498 | static int rsnd_ssi_dma_remove(struct rsnd_mod *mod, |
506 | struct rsnd_dai *rdai) | 499 | struct rsnd_priv *priv) |
507 | { | 500 | { |
508 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); | ||
509 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); | 501 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); |
510 | struct device *dev = rsnd_priv_to_dev(priv); | 502 | struct device *dev = rsnd_priv_to_dev(priv); |
511 | int irq = ssi->info->irq; | 503 | int irq = ssi->info->irq; |
512 | 504 | ||
513 | rsnd_dma_quit(rsnd_mod_to_priv(mod), rsnd_mod_to_dma(mod)); | 505 | rsnd_dma_quit(priv, rsnd_mod_to_dma(mod)); |
514 | 506 | ||
515 | /* PIO will request IRQ again */ | 507 | /* PIO will request IRQ again */ |
516 | devm_free_irq(dev, irq, ssi); | 508 | devm_free_irq(dev, irq, ssi); |
@@ -519,9 +511,8 @@ static int rsnd_ssi_dma_remove(struct rsnd_mod *mod, | |||
519 | } | 511 | } |
520 | 512 | ||
521 | static int rsnd_ssi_fallback(struct rsnd_mod *mod, | 513 | static int rsnd_ssi_fallback(struct rsnd_mod *mod, |
522 | struct rsnd_dai *rdai) | 514 | struct rsnd_priv *priv) |
523 | { | 515 | { |
524 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); | ||
525 | struct device *dev = rsnd_priv_to_dev(priv); | 516 | struct device *dev = rsnd_priv_to_dev(priv); |
526 | 517 | ||
527 | /* | 518 | /* |
@@ -540,25 +531,25 @@ static int rsnd_ssi_fallback(struct rsnd_mod *mod, | |||
540 | } | 531 | } |
541 | 532 | ||
542 | static int rsnd_ssi_dma_start(struct rsnd_mod *mod, | 533 | static int rsnd_ssi_dma_start(struct rsnd_mod *mod, |
543 | struct rsnd_dai *rdai) | 534 | struct rsnd_priv *priv) |
544 | { | 535 | { |
545 | struct rsnd_dma *dma = rsnd_mod_to_dma(mod); | 536 | struct rsnd_dma *dma = rsnd_mod_to_dma(mod); |
546 | 537 | ||
547 | rsnd_ssi_start(mod, rdai); | ||
548 | |||
549 | rsnd_dma_start(dma); | 538 | rsnd_dma_start(dma); |
550 | 539 | ||
540 | rsnd_ssi_start(mod, priv); | ||
541 | |||
551 | return 0; | 542 | return 0; |
552 | } | 543 | } |
553 | 544 | ||
554 | static int rsnd_ssi_dma_stop(struct rsnd_mod *mod, | 545 | static int rsnd_ssi_dma_stop(struct rsnd_mod *mod, |
555 | struct rsnd_dai *rdai) | 546 | struct rsnd_priv *priv) |
556 | { | 547 | { |
557 | struct rsnd_dma *dma = rsnd_mod_to_dma(mod); | 548 | struct rsnd_dma *dma = rsnd_mod_to_dma(mod); |
558 | 549 | ||
559 | rsnd_dma_stop(dma); | 550 | rsnd_ssi_stop(mod, priv); |
560 | 551 | ||
561 | rsnd_ssi_stop(mod, rdai); | 552 | rsnd_dma_stop(dma); |
562 | 553 | ||
563 | return 0; | 554 | return 0; |
564 | } | 555 | } |
@@ -734,7 +725,6 @@ int rsnd_ssi_probe(struct platform_device *pdev, | |||
734 | return PTR_ERR(clk); | 725 | return PTR_ERR(clk); |
735 | 726 | ||
736 | ssi->info = pinfo; | 727 | ssi->info = pinfo; |
737 | ssi->clk = clk; | ||
738 | 728 | ||
739 | ops = &rsnd_ssi_non_ops; | 729 | ops = &rsnd_ssi_non_ops; |
740 | if (pinfo->dma_id > 0) | 730 | if (pinfo->dma_id > 0) |
@@ -742,7 +732,7 @@ int rsnd_ssi_probe(struct platform_device *pdev, | |||
742 | else if (rsnd_ssi_pio_available(ssi)) | 732 | else if (rsnd_ssi_pio_available(ssi)) |
743 | ops = &rsnd_ssi_pio_ops; | 733 | ops = &rsnd_ssi_pio_ops; |
744 | 734 | ||
745 | rsnd_mod_init(priv, &ssi->mod, ops, RSND_MOD_SSI, i); | 735 | rsnd_mod_init(&ssi->mod, ops, clk, RSND_MOD_SSI, i); |
746 | 736 | ||
747 | rsnd_ssi_parent_clk_setup(priv, ssi); | 737 | rsnd_ssi_parent_clk_setup(priv, ssi); |
748 | } | 738 | } |
diff --git a/sound/soc/sh/siu_pcm.c b/sound/soc/sh/siu_pcm.c index 32eb6da2d2bd..82902f56e82f 100644 --- a/sound/soc/sh/siu_pcm.c +++ b/sound/soc/sh/siu_pcm.c | |||
@@ -589,7 +589,6 @@ static void siu_pcm_free(struct snd_pcm *pcm) | |||
589 | tasklet_kill(&port_info->playback.tasklet); | 589 | tasklet_kill(&port_info->playback.tasklet); |
590 | 590 | ||
591 | siu_free_port(port_info); | 591 | siu_free_port(port_info); |
592 | snd_pcm_lib_preallocate_free_for_all(pcm); | ||
593 | 592 | ||
594 | dev_dbg(pcm->card->dev, "%s\n", __func__); | 593 | dev_dbg(pcm->card->dev, "%s\n", __func__); |
595 | } | 594 | } |
diff --git a/sound/soc/soc-ac97.c b/sound/soc/soc-ac97.c index 2e10e9a38376..08d7259bbaab 100644 --- a/sound/soc/soc-ac97.c +++ b/sound/soc/soc-ac97.c | |||
@@ -48,15 +48,18 @@ static void soc_ac97_device_release(struct device *dev) | |||
48 | } | 48 | } |
49 | 49 | ||
50 | /** | 50 | /** |
51 | * snd_soc_new_ac97_codec - initailise AC97 device | 51 | * snd_soc_alloc_ac97_codec() - Allocate new a AC'97 device |
52 | * @codec: audio codec | 52 | * @codec: The CODEC for which to create the AC'97 device |
53 | * | 53 | * |
54 | * Initialises AC97 codec resources for use by ad-hoc devices only. | 54 | * Allocated a new snd_ac97 device and intializes it, but does not yet register |
55 | * it. The caller is responsible to either call device_add(&ac97->dev) to | ||
56 | * register the device, or to call put_device(&ac97->dev) to free the device. | ||
57 | * | ||
58 | * Returns: A snd_ac97 device or a PTR_ERR in case of an error. | ||
55 | */ | 59 | */ |
56 | struct snd_ac97 *snd_soc_new_ac97_codec(struct snd_soc_codec *codec) | 60 | struct snd_ac97 *snd_soc_alloc_ac97_codec(struct snd_soc_codec *codec) |
57 | { | 61 | { |
58 | struct snd_ac97 *ac97; | 62 | struct snd_ac97 *ac97; |
59 | int ret; | ||
60 | 63 | ||
61 | ac97 = kzalloc(sizeof(struct snd_ac97), GFP_KERNEL); | 64 | ac97 = kzalloc(sizeof(struct snd_ac97), GFP_KERNEL); |
62 | if (ac97 == NULL) | 65 | if (ac97 == NULL) |
@@ -73,7 +76,28 @@ struct snd_ac97 *snd_soc_new_ac97_codec(struct snd_soc_codec *codec) | |||
73 | codec->component.card->snd_card->number, 0, | 76 | codec->component.card->snd_card->number, 0, |
74 | codec->component.name); | 77 | codec->component.name); |
75 | 78 | ||
76 | ret = device_register(&ac97->dev); | 79 | device_initialize(&ac97->dev); |
80 | |||
81 | return ac97; | ||
82 | } | ||
83 | EXPORT_SYMBOL(snd_soc_alloc_ac97_codec); | ||
84 | |||
85 | /** | ||
86 | * snd_soc_new_ac97_codec - initailise AC97 device | ||
87 | * @codec: audio codec | ||
88 | * | ||
89 | * Initialises AC97 codec resources for use by ad-hoc devices only. | ||
90 | */ | ||
91 | struct snd_ac97 *snd_soc_new_ac97_codec(struct snd_soc_codec *codec) | ||
92 | { | ||
93 | struct snd_ac97 *ac97; | ||
94 | int ret; | ||
95 | |||
96 | ac97 = snd_soc_alloc_ac97_codec(codec); | ||
97 | if (IS_ERR(ac97)) | ||
98 | return ac97; | ||
99 | |||
100 | ret = device_add(&ac97->dev); | ||
77 | if (ret) { | 101 | if (ret) { |
78 | put_device(&ac97->dev); | 102 | put_device(&ac97->dev); |
79 | return ERR_PTR(ret); | 103 | return ERR_PTR(ret); |
diff --git a/sound/soc/soc-compress.c b/sound/soc/soc-compress.c index 590a82f01d0b..025c38fbe3c0 100644 --- a/sound/soc/soc-compress.c +++ b/sound/soc/soc-compress.c | |||
@@ -659,7 +659,8 @@ int soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num) | |||
659 | rtd->dai_link->stream_name); | 659 | rtd->dai_link->stream_name); |
660 | 660 | ||
661 | ret = snd_pcm_new_internal(rtd->card->snd_card, new_name, num, | 661 | ret = snd_pcm_new_internal(rtd->card->snd_card, new_name, num, |
662 | 1, 0, &be_pcm); | 662 | rtd->dai_link->dpcm_playback, |
663 | rtd->dai_link->dpcm_capture, &be_pcm); | ||
663 | if (ret < 0) { | 664 | if (ret < 0) { |
664 | dev_err(rtd->card->dev, "ASoC: can't create compressed for %s\n", | 665 | dev_err(rtd->card->dev, "ASoC: can't create compressed for %s\n", |
665 | rtd->dai_link->name); | 666 | rtd->dai_link->name); |
@@ -668,8 +669,10 @@ int soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num) | |||
668 | 669 | ||
669 | rtd->pcm = be_pcm; | 670 | rtd->pcm = be_pcm; |
670 | rtd->fe_compr = 1; | 671 | rtd->fe_compr = 1; |
671 | be_pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream->private_data = rtd; | 672 | if (rtd->dai_link->dpcm_playback) |
672 | be_pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream->private_data = rtd; | 673 | be_pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream->private_data = rtd; |
674 | else if (rtd->dai_link->dpcm_capture) | ||
675 | be_pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream->private_data = rtd; | ||
673 | memcpy(compr->ops, &soc_compr_dyn_ops, sizeof(soc_compr_dyn_ops)); | 676 | memcpy(compr->ops, &soc_compr_dyn_ops, sizeof(soc_compr_dyn_ops)); |
674 | } else | 677 | } else |
675 | memcpy(compr->ops, &soc_compr_ops, sizeof(soc_compr_ops)); | 678 | memcpy(compr->ops, &soc_compr_ops, sizeof(soc_compr_ops)); |
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 985052b3fbed..30579ca5bacb 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c | |||
@@ -191,6 +191,39 @@ static ssize_t pmdown_time_set(struct device *dev, | |||
191 | 191 | ||
192 | static DEVICE_ATTR(pmdown_time, 0644, pmdown_time_show, pmdown_time_set); | 192 | static DEVICE_ATTR(pmdown_time, 0644, pmdown_time_show, pmdown_time_set); |
193 | 193 | ||
194 | static struct attribute *soc_dev_attrs[] = { | ||
195 | &dev_attr_codec_reg.attr, | ||
196 | &dev_attr_pmdown_time.attr, | ||
197 | NULL | ||
198 | }; | ||
199 | |||
200 | static umode_t soc_dev_attr_is_visible(struct kobject *kobj, | ||
201 | struct attribute *attr, int idx) | ||
202 | { | ||
203 | struct device *dev = kobj_to_dev(kobj); | ||
204 | struct snd_soc_pcm_runtime *rtd = dev_get_drvdata(dev); | ||
205 | |||
206 | if (attr == &dev_attr_pmdown_time.attr) | ||
207 | return attr->mode; /* always visible */ | ||
208 | return rtd->codec ? attr->mode : 0; /* enabled only with codec */ | ||
209 | } | ||
210 | |||
211 | static const struct attribute_group soc_dapm_dev_group = { | ||
212 | .attrs = soc_dapm_dev_attrs, | ||
213 | .is_visible = soc_dev_attr_is_visible, | ||
214 | }; | ||
215 | |||
216 | static const struct attribute_group soc_dev_roup = { | ||
217 | .attrs = soc_dev_attrs, | ||
218 | .is_visible = soc_dev_attr_is_visible, | ||
219 | }; | ||
220 | |||
221 | static const struct attribute_group *soc_dev_attr_groups[] = { | ||
222 | &soc_dapm_dev_group, | ||
223 | &soc_dev_roup, | ||
224 | NULL | ||
225 | }; | ||
226 | |||
194 | #ifdef CONFIG_DEBUG_FS | 227 | #ifdef CONFIG_DEBUG_FS |
195 | static ssize_t codec_reg_read_file(struct file *file, char __user *user_buf, | 228 | static ssize_t codec_reg_read_file(struct file *file, char __user *user_buf, |
196 | size_t count, loff_t *ppos) | 229 | size_t count, loff_t *ppos) |
@@ -949,8 +982,6 @@ static void soc_remove_link_dais(struct snd_soc_card *card, int num, int order) | |||
949 | 982 | ||
950 | /* unregister the rtd device */ | 983 | /* unregister the rtd device */ |
951 | if (rtd->dev_registered) { | 984 | if (rtd->dev_registered) { |
952 | device_remove_file(rtd->dev, &dev_attr_pmdown_time); | ||
953 | device_remove_file(rtd->dev, &dev_attr_codec_reg); | ||
954 | device_unregister(rtd->dev); | 985 | device_unregister(rtd->dev); |
955 | rtd->dev_registered = 0; | 986 | rtd->dev_registered = 0; |
956 | } | 987 | } |
@@ -1120,6 +1151,7 @@ static int soc_post_component_init(struct snd_soc_pcm_runtime *rtd, | |||
1120 | device_initialize(rtd->dev); | 1151 | device_initialize(rtd->dev); |
1121 | rtd->dev->parent = rtd->card->dev; | 1152 | rtd->dev->parent = rtd->card->dev; |
1122 | rtd->dev->release = rtd_release; | 1153 | rtd->dev->release = rtd_release; |
1154 | rtd->dev->groups = soc_dev_attr_groups; | ||
1123 | dev_set_name(rtd->dev, "%s", name); | 1155 | dev_set_name(rtd->dev, "%s", name); |
1124 | dev_set_drvdata(rtd->dev, rtd); | 1156 | dev_set_drvdata(rtd->dev, rtd); |
1125 | mutex_init(&rtd->pcm_mutex); | 1157 | mutex_init(&rtd->pcm_mutex); |
@@ -1136,23 +1168,6 @@ static int soc_post_component_init(struct snd_soc_pcm_runtime *rtd, | |||
1136 | return ret; | 1168 | return ret; |
1137 | } | 1169 | } |
1138 | rtd->dev_registered = 1; | 1170 | rtd->dev_registered = 1; |
1139 | |||
1140 | if (rtd->codec) { | ||
1141 | /* add DAPM sysfs entries for this codec */ | ||
1142 | ret = snd_soc_dapm_sys_add(rtd->dev); | ||
1143 | if (ret < 0) | ||
1144 | dev_err(rtd->dev, | ||
1145 | "ASoC: failed to add codec dapm sysfs entries: %d\n", | ||
1146 | ret); | ||
1147 | |||
1148 | /* add codec sysfs entries */ | ||
1149 | ret = device_create_file(rtd->dev, &dev_attr_codec_reg); | ||
1150 | if (ret < 0) | ||
1151 | dev_err(rtd->dev, | ||
1152 | "ASoC: failed to add codec sysfs files: %d\n", | ||
1153 | ret); | ||
1154 | } | ||
1155 | |||
1156 | return 0; | 1171 | return 0; |
1157 | } | 1172 | } |
1158 | 1173 | ||
@@ -1308,11 +1323,6 @@ static int soc_probe_link_dais(struct snd_soc_card *card, int num, int order) | |||
1308 | } | 1323 | } |
1309 | #endif | 1324 | #endif |
1310 | 1325 | ||
1311 | ret = device_create_file(rtd->dev, &dev_attr_pmdown_time); | ||
1312 | if (ret < 0) | ||
1313 | dev_warn(rtd->dev, "ASoC: failed to add pmdown_time sysfs: %d\n", | ||
1314 | ret); | ||
1315 | |||
1316 | if (cpu_dai->driver->compress_dai) { | 1326 | if (cpu_dai->driver->compress_dai) { |
1317 | /*create compress_device"*/ | 1327 | /*create compress_device"*/ |
1318 | ret = soc_new_compress(rtd, num); | 1328 | ret = soc_new_compress(rtd, num); |
@@ -1427,11 +1437,76 @@ static int snd_soc_init_codec_cache(struct snd_soc_codec *codec) | |||
1427 | return 0; | 1437 | return 0; |
1428 | } | 1438 | } |
1429 | 1439 | ||
1440 | /** | ||
1441 | * snd_soc_runtime_set_dai_fmt() - Change DAI link format for a ASoC runtime | ||
1442 | * @rtd: The runtime for which the DAI link format should be changed | ||
1443 | * @dai_fmt: The new DAI link format | ||
1444 | * | ||
1445 | * This function updates the DAI link format for all DAIs connected to the DAI | ||
1446 | * link for the specified runtime. | ||
1447 | * | ||
1448 | * Note: For setups with a static format set the dai_fmt field in the | ||
1449 | * corresponding snd_dai_link struct instead of using this function. | ||
1450 | * | ||
1451 | * Returns 0 on success, otherwise a negative error code. | ||
1452 | */ | ||
1453 | int snd_soc_runtime_set_dai_fmt(struct snd_soc_pcm_runtime *rtd, | ||
1454 | unsigned int dai_fmt) | ||
1455 | { | ||
1456 | struct snd_soc_dai **codec_dais = rtd->codec_dais; | ||
1457 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | ||
1458 | unsigned int i; | ||
1459 | int ret; | ||
1460 | |||
1461 | for (i = 0; i < rtd->num_codecs; i++) { | ||
1462 | struct snd_soc_dai *codec_dai = codec_dais[i]; | ||
1463 | |||
1464 | ret = snd_soc_dai_set_fmt(codec_dai, dai_fmt); | ||
1465 | if (ret != 0 && ret != -ENOTSUPP) { | ||
1466 | dev_warn(codec_dai->dev, | ||
1467 | "ASoC: Failed to set DAI format: %d\n", ret); | ||
1468 | return ret; | ||
1469 | } | ||
1470 | } | ||
1471 | |||
1472 | /* Flip the polarity for the "CPU" end of a CODEC<->CODEC link */ | ||
1473 | if (cpu_dai->codec) { | ||
1474 | unsigned int inv_dai_fmt; | ||
1475 | |||
1476 | inv_dai_fmt = dai_fmt & ~SND_SOC_DAIFMT_MASTER_MASK; | ||
1477 | switch (dai_fmt & SND_SOC_DAIFMT_MASTER_MASK) { | ||
1478 | case SND_SOC_DAIFMT_CBM_CFM: | ||
1479 | inv_dai_fmt |= SND_SOC_DAIFMT_CBS_CFS; | ||
1480 | break; | ||
1481 | case SND_SOC_DAIFMT_CBM_CFS: | ||
1482 | inv_dai_fmt |= SND_SOC_DAIFMT_CBS_CFM; | ||
1483 | break; | ||
1484 | case SND_SOC_DAIFMT_CBS_CFM: | ||
1485 | inv_dai_fmt |= SND_SOC_DAIFMT_CBM_CFS; | ||
1486 | break; | ||
1487 | case SND_SOC_DAIFMT_CBS_CFS: | ||
1488 | inv_dai_fmt |= SND_SOC_DAIFMT_CBM_CFM; | ||
1489 | break; | ||
1490 | } | ||
1491 | |||
1492 | dai_fmt = inv_dai_fmt; | ||
1493 | } | ||
1494 | |||
1495 | ret = snd_soc_dai_set_fmt(cpu_dai, dai_fmt); | ||
1496 | if (ret != 0 && ret != -ENOTSUPP) { | ||
1497 | dev_warn(cpu_dai->dev, | ||
1498 | "ASoC: Failed to set DAI format: %d\n", ret); | ||
1499 | return ret; | ||
1500 | } | ||
1501 | |||
1502 | return 0; | ||
1503 | } | ||
1504 | EXPORT_SYMBOL_GPL(snd_soc_runtime_set_dai_fmt); | ||
1505 | |||
1430 | static int snd_soc_instantiate_card(struct snd_soc_card *card) | 1506 | static int snd_soc_instantiate_card(struct snd_soc_card *card) |
1431 | { | 1507 | { |
1432 | struct snd_soc_codec *codec; | 1508 | struct snd_soc_codec *codec; |
1433 | struct snd_soc_dai_link *dai_link; | 1509 | int ret, i, order; |
1434 | int ret, i, order, dai_fmt; | ||
1435 | 1510 | ||
1436 | mutex_lock_nested(&card->mutex, SND_SOC_CARD_CLASS_INIT); | 1511 | mutex_lock_nested(&card->mutex, SND_SOC_CARD_CLASS_INIT); |
1437 | 1512 | ||
@@ -1542,60 +1617,9 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card) | |||
1542 | card->num_dapm_routes); | 1617 | card->num_dapm_routes); |
1543 | 1618 | ||
1544 | for (i = 0; i < card->num_links; i++) { | 1619 | for (i = 0; i < card->num_links; i++) { |
1545 | struct snd_soc_pcm_runtime *rtd = &card->rtd[i]; | 1620 | if (card->dai_link[i].dai_fmt) |
1546 | dai_link = &card->dai_link[i]; | 1621 | snd_soc_runtime_set_dai_fmt(&card->rtd[i], |
1547 | dai_fmt = dai_link->dai_fmt; | 1622 | card->dai_link[i].dai_fmt); |
1548 | |||
1549 | if (dai_fmt) { | ||
1550 | struct snd_soc_dai **codec_dais = rtd->codec_dais; | ||
1551 | int j; | ||
1552 | |||
1553 | for (j = 0; j < rtd->num_codecs; j++) { | ||
1554 | struct snd_soc_dai *codec_dai = codec_dais[j]; | ||
1555 | |||
1556 | ret = snd_soc_dai_set_fmt(codec_dai, dai_fmt); | ||
1557 | if (ret != 0 && ret != -ENOTSUPP) | ||
1558 | dev_warn(codec_dai->dev, | ||
1559 | "ASoC: Failed to set DAI format: %d\n", | ||
1560 | ret); | ||
1561 | } | ||
1562 | } | ||
1563 | |||
1564 | /* If this is a regular CPU link there will be a platform */ | ||
1565 | if (dai_fmt && | ||
1566 | (dai_link->platform_name || dai_link->platform_of_node)) { | ||
1567 | ret = snd_soc_dai_set_fmt(card->rtd[i].cpu_dai, | ||
1568 | dai_fmt); | ||
1569 | if (ret != 0 && ret != -ENOTSUPP) | ||
1570 | dev_warn(card->rtd[i].cpu_dai->dev, | ||
1571 | "ASoC: Failed to set DAI format: %d\n", | ||
1572 | ret); | ||
1573 | } else if (dai_fmt) { | ||
1574 | /* Flip the polarity for the "CPU" end */ | ||
1575 | dai_fmt &= ~SND_SOC_DAIFMT_MASTER_MASK; | ||
1576 | switch (dai_link->dai_fmt & | ||
1577 | SND_SOC_DAIFMT_MASTER_MASK) { | ||
1578 | case SND_SOC_DAIFMT_CBM_CFM: | ||
1579 | dai_fmt |= SND_SOC_DAIFMT_CBS_CFS; | ||
1580 | break; | ||
1581 | case SND_SOC_DAIFMT_CBM_CFS: | ||
1582 | dai_fmt |= SND_SOC_DAIFMT_CBS_CFM; | ||
1583 | break; | ||
1584 | case SND_SOC_DAIFMT_CBS_CFM: | ||
1585 | dai_fmt |= SND_SOC_DAIFMT_CBM_CFS; | ||
1586 | break; | ||
1587 | case SND_SOC_DAIFMT_CBS_CFS: | ||
1588 | dai_fmt |= SND_SOC_DAIFMT_CBM_CFM; | ||
1589 | break; | ||
1590 | } | ||
1591 | |||
1592 | ret = snd_soc_dai_set_fmt(card->rtd[i].cpu_dai, | ||
1593 | dai_fmt); | ||
1594 | if (ret != 0 && ret != -ENOTSUPP) | ||
1595 | dev_warn(card->rtd[i].cpu_dai->dev, | ||
1596 | "ASoC: Failed to set DAI format: %d\n", | ||
1597 | ret); | ||
1598 | } | ||
1599 | } | 1623 | } |
1600 | 1624 | ||
1601 | snprintf(card->snd_card->shortname, sizeof(card->snd_card->shortname), | 1625 | snprintf(card->snd_card->shortname, sizeof(card->snd_card->shortname), |
@@ -1626,9 +1650,6 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card) | |||
1626 | } | 1650 | } |
1627 | } | 1651 | } |
1628 | 1652 | ||
1629 | if (card->fully_routed) | ||
1630 | snd_soc_dapm_auto_nc_pins(card); | ||
1631 | |||
1632 | snd_soc_dapm_new_widgets(card); | 1653 | snd_soc_dapm_new_widgets(card); |
1633 | 1654 | ||
1634 | ret = snd_card_register(card->snd_card); | 1655 | ret = snd_card_register(card->snd_card); |
@@ -2119,15 +2140,27 @@ static int snd_soc_xlate_tdm_slot_mask(unsigned int slots, | |||
2119 | } | 2140 | } |
2120 | 2141 | ||
2121 | /** | 2142 | /** |
2122 | * snd_soc_dai_set_tdm_slot - configure DAI TDM. | 2143 | * snd_soc_dai_set_tdm_slot() - Configures a DAI for TDM operation |
2123 | * @dai: DAI | 2144 | * @dai: The DAI to configure |
2124 | * @tx_mask: bitmask representing active TX slots. | 2145 | * @tx_mask: bitmask representing active TX slots. |
2125 | * @rx_mask: bitmask representing active RX slots. | 2146 | * @rx_mask: bitmask representing active RX slots. |
2126 | * @slots: Number of slots in use. | 2147 | * @slots: Number of slots in use. |
2127 | * @slot_width: Width in bits for each slot. | 2148 | * @slot_width: Width in bits for each slot. |
2128 | * | 2149 | * |
2129 | * Configures a DAI for TDM operation. Both mask and slots are codec and DAI | 2150 | * This function configures the specified DAI for TDM operation. @slot contains |
2130 | * specific. | 2151 | * the total number of slots of the TDM stream and @slot_with the width of each |
2152 | * slot in bit clock cycles. @tx_mask and @rx_mask are bitmasks specifying the | ||
2153 | * active slots of the TDM stream for the specified DAI, i.e. which slots the | ||
2154 | * DAI should write to or read from. If a bit is set the corresponding slot is | ||
2155 | * active, if a bit is cleared the corresponding slot is inactive. Bit 0 maps to | ||
2156 | * the first slot, bit 1 to the second slot and so on. The first active slot | ||
2157 | * maps to the first channel of the DAI, the second active slot to the second | ||
2158 | * channel and so on. | ||
2159 | * | ||
2160 | * TDM mode can be disabled by passing 0 for @slots. In this case @tx_mask, | ||
2161 | * @rx_mask and @slot_width will be ignored. | ||
2162 | * | ||
2163 | * Returns 0 on success, a negative error code otherwise. | ||
2131 | */ | 2164 | */ |
2132 | int snd_soc_dai_set_tdm_slot(struct snd_soc_dai *dai, | 2165 | int snd_soc_dai_set_tdm_slot(struct snd_soc_dai *dai, |
2133 | unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width) | 2166 | unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width) |
@@ -2386,8 +2419,8 @@ int snd_soc_unregister_card(struct snd_soc_card *card) | |||
2386 | card->instantiated = false; | 2419 | card->instantiated = false; |
2387 | snd_soc_dapm_shutdown(card); | 2420 | snd_soc_dapm_shutdown(card); |
2388 | soc_cleanup_card_resources(card); | 2421 | soc_cleanup_card_resources(card); |
2422 | dev_dbg(card->dev, "ASoC: Unregistered card '%s'\n", card->name); | ||
2389 | } | 2423 | } |
2390 | dev_dbg(card->dev, "ASoC: Unregistered card '%s'\n", card->name); | ||
2391 | 2424 | ||
2392 | return 0; | 2425 | return 0; |
2393 | } | 2426 | } |
@@ -3230,7 +3263,7 @@ int snd_soc_of_parse_audio_routing(struct snd_soc_card *card, | |||
3230 | const char *propname) | 3263 | const char *propname) |
3231 | { | 3264 | { |
3232 | struct device_node *np = card->dev->of_node; | 3265 | struct device_node *np = card->dev->of_node; |
3233 | int num_routes, old_routes; | 3266 | int num_routes; |
3234 | struct snd_soc_dapm_route *routes; | 3267 | struct snd_soc_dapm_route *routes; |
3235 | int i, ret; | 3268 | int i, ret; |
3236 | 3269 | ||
@@ -3248,9 +3281,7 @@ int snd_soc_of_parse_audio_routing(struct snd_soc_card *card, | |||
3248 | return -EINVAL; | 3281 | return -EINVAL; |
3249 | } | 3282 | } |
3250 | 3283 | ||
3251 | old_routes = card->num_dapm_routes; | 3284 | routes = devm_kzalloc(card->dev, num_routes * sizeof(*routes), |
3252 | routes = devm_kzalloc(card->dev, | ||
3253 | (old_routes + num_routes) * sizeof(*routes), | ||
3254 | GFP_KERNEL); | 3285 | GFP_KERNEL); |
3255 | if (!routes) { | 3286 | if (!routes) { |
3256 | dev_err(card->dev, | 3287 | dev_err(card->dev, |
@@ -3258,11 +3289,9 @@ int snd_soc_of_parse_audio_routing(struct snd_soc_card *card, | |||
3258 | return -EINVAL; | 3289 | return -EINVAL; |
3259 | } | 3290 | } |
3260 | 3291 | ||
3261 | memcpy(routes, card->dapm_routes, old_routes * sizeof(*routes)); | ||
3262 | |||
3263 | for (i = 0; i < num_routes; i++) { | 3292 | for (i = 0; i < num_routes; i++) { |
3264 | ret = of_property_read_string_index(np, propname, | 3293 | ret = of_property_read_string_index(np, propname, |
3265 | 2 * i, &routes[old_routes + i].sink); | 3294 | 2 * i, &routes[i].sink); |
3266 | if (ret) { | 3295 | if (ret) { |
3267 | dev_err(card->dev, | 3296 | dev_err(card->dev, |
3268 | "ASoC: Property '%s' index %d could not be read: %d\n", | 3297 | "ASoC: Property '%s' index %d could not be read: %d\n", |
@@ -3270,7 +3299,7 @@ int snd_soc_of_parse_audio_routing(struct snd_soc_card *card, | |||
3270 | return -EINVAL; | 3299 | return -EINVAL; |
3271 | } | 3300 | } |
3272 | ret = of_property_read_string_index(np, propname, | 3301 | ret = of_property_read_string_index(np, propname, |
3273 | (2 * i) + 1, &routes[old_routes + i].source); | 3302 | (2 * i) + 1, &routes[i].source); |
3274 | if (ret) { | 3303 | if (ret) { |
3275 | dev_err(card->dev, | 3304 | dev_err(card->dev, |
3276 | "ASoC: Property '%s' index %d could not be read: %d\n", | 3305 | "ASoC: Property '%s' index %d could not be read: %d\n", |
@@ -3279,7 +3308,7 @@ int snd_soc_of_parse_audio_routing(struct snd_soc_card *card, | |||
3279 | } | 3308 | } |
3280 | } | 3309 | } |
3281 | 3310 | ||
3282 | card->num_dapm_routes += num_routes; | 3311 | card->num_dapm_routes = num_routes; |
3283 | card->dapm_routes = routes; | 3312 | card->dapm_routes = routes; |
3284 | 3313 | ||
3285 | return 0; | 3314 | return 0; |
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index c5136bb1f982..b6f88202b8c9 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c | |||
@@ -517,8 +517,8 @@ static int soc_dapm_update_bits(struct snd_soc_dapm_context *dapm, | |||
517 | { | 517 | { |
518 | if (!dapm->component) | 518 | if (!dapm->component) |
519 | return -EIO; | 519 | return -EIO; |
520 | return snd_soc_component_update_bits_async(dapm->component, reg, | 520 | return snd_soc_component_update_bits(dapm->component, reg, |
521 | mask, value); | 521 | mask, value); |
522 | } | 522 | } |
523 | 523 | ||
524 | static int soc_dapm_test_bits(struct snd_soc_dapm_context *dapm, | 524 | static int soc_dapm_test_bits(struct snd_soc_dapm_context *dapm, |
@@ -2127,15 +2127,10 @@ static ssize_t dapm_widget_show(struct device *dev, | |||
2127 | 2127 | ||
2128 | static DEVICE_ATTR(dapm_widget, 0444, dapm_widget_show, NULL); | 2128 | static DEVICE_ATTR(dapm_widget, 0444, dapm_widget_show, NULL); |
2129 | 2129 | ||
2130 | int snd_soc_dapm_sys_add(struct device *dev) | 2130 | struct attribute *soc_dapm_dev_attrs[] = { |
2131 | { | 2131 | &dev_attr_dapm_widget.attr, |
2132 | return device_create_file(dev, &dev_attr_dapm_widget); | 2132 | NULL |
2133 | } | 2133 | }; |
2134 | |||
2135 | static void snd_soc_dapm_sys_remove(struct device *dev) | ||
2136 | { | ||
2137 | device_remove_file(dev, &dev_attr_dapm_widget); | ||
2138 | } | ||
2139 | 2134 | ||
2140 | static void dapm_free_path(struct snd_soc_dapm_path *path) | 2135 | static void dapm_free_path(struct snd_soc_dapm_path *path) |
2141 | { | 2136 | { |
@@ -2279,6 +2274,9 @@ static void dapm_update_widget_flags(struct snd_soc_dapm_widget *w) | |||
2279 | 2274 | ||
2280 | switch (w->id) { | 2275 | switch (w->id) { |
2281 | case snd_soc_dapm_input: | 2276 | case snd_soc_dapm_input: |
2277 | /* On a fully routed card a input is never a source */ | ||
2278 | if (w->dapm->card->fully_routed) | ||
2279 | break; | ||
2282 | w->is_source = 1; | 2280 | w->is_source = 1; |
2283 | list_for_each_entry(p, &w->sources, list_sink) { | 2281 | list_for_each_entry(p, &w->sources, list_sink) { |
2284 | if (p->source->id == snd_soc_dapm_micbias || | 2282 | if (p->source->id == snd_soc_dapm_micbias || |
@@ -2291,6 +2289,9 @@ static void dapm_update_widget_flags(struct snd_soc_dapm_widget *w) | |||
2291 | } | 2289 | } |
2292 | break; | 2290 | break; |
2293 | case snd_soc_dapm_output: | 2291 | case snd_soc_dapm_output: |
2292 | /* On a fully routed card a output is never a sink */ | ||
2293 | if (w->dapm->card->fully_routed) | ||
2294 | break; | ||
2294 | w->is_sink = 1; | 2295 | w->is_sink = 1; |
2295 | list_for_each_entry(p, &w->sinks, list_source) { | 2296 | list_for_each_entry(p, &w->sinks, list_source) { |
2296 | if (p->sink->id == snd_soc_dapm_spk || | 2297 | if (p->sink->id == snd_soc_dapm_spk || |
@@ -3085,16 +3086,24 @@ snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm, | |||
3085 | 3086 | ||
3086 | switch (w->id) { | 3087 | switch (w->id) { |
3087 | case snd_soc_dapm_mic: | 3088 | case snd_soc_dapm_mic: |
3088 | case snd_soc_dapm_input: | ||
3089 | w->is_source = 1; | 3089 | w->is_source = 1; |
3090 | w->power_check = dapm_generic_check_power; | 3090 | w->power_check = dapm_generic_check_power; |
3091 | break; | 3091 | break; |
3092 | case snd_soc_dapm_input: | ||
3093 | if (!dapm->card->fully_routed) | ||
3094 | w->is_source = 1; | ||
3095 | w->power_check = dapm_generic_check_power; | ||
3096 | break; | ||
3092 | case snd_soc_dapm_spk: | 3097 | case snd_soc_dapm_spk: |
3093 | case snd_soc_dapm_hp: | 3098 | case snd_soc_dapm_hp: |
3094 | case snd_soc_dapm_output: | ||
3095 | w->is_sink = 1; | 3099 | w->is_sink = 1; |
3096 | w->power_check = dapm_generic_check_power; | 3100 | w->power_check = dapm_generic_check_power; |
3097 | break; | 3101 | break; |
3102 | case snd_soc_dapm_output: | ||
3103 | if (!dapm->card->fully_routed) | ||
3104 | w->is_sink = 1; | ||
3105 | w->power_check = dapm_generic_check_power; | ||
3106 | break; | ||
3098 | case snd_soc_dapm_vmid: | 3107 | case snd_soc_dapm_vmid: |
3099 | case snd_soc_dapm_siggen: | 3108 | case snd_soc_dapm_siggen: |
3100 | w->is_source = 1; | 3109 | w->is_source = 1; |
@@ -3130,8 +3139,6 @@ snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm, | |||
3130 | } | 3139 | } |
3131 | 3140 | ||
3132 | w->dapm = dapm; | 3141 | w->dapm = dapm; |
3133 | if (dapm->component) | ||
3134 | w->codec = dapm->component->codec; | ||
3135 | INIT_LIST_HEAD(&w->sources); | 3142 | INIT_LIST_HEAD(&w->sources); |
3136 | INIT_LIST_HEAD(&w->sinks); | 3143 | INIT_LIST_HEAD(&w->sinks); |
3137 | INIT_LIST_HEAD(&w->list); | 3144 | INIT_LIST_HEAD(&w->list); |
@@ -3809,93 +3816,6 @@ int snd_soc_dapm_ignore_suspend(struct snd_soc_dapm_context *dapm, | |||
3809 | EXPORT_SYMBOL_GPL(snd_soc_dapm_ignore_suspend); | 3816 | EXPORT_SYMBOL_GPL(snd_soc_dapm_ignore_suspend); |
3810 | 3817 | ||
3811 | /** | 3818 | /** |
3812 | * dapm_is_external_path() - Checks if a path is a external path | ||
3813 | * @card: The card the path belongs to | ||
3814 | * @path: The path to check | ||
3815 | * | ||
3816 | * Returns true if the path is either between two different DAPM contexts or | ||
3817 | * between two external pins of the same DAPM context. Otherwise returns | ||
3818 | * false. | ||
3819 | */ | ||
3820 | static bool dapm_is_external_path(struct snd_soc_card *card, | ||
3821 | struct snd_soc_dapm_path *path) | ||
3822 | { | ||
3823 | dev_dbg(card->dev, | ||
3824 | "... Path %s(id:%d dapm:%p) - %s(id:%d dapm:%p)\n", | ||
3825 | path->source->name, path->source->id, path->source->dapm, | ||
3826 | path->sink->name, path->sink->id, path->sink->dapm); | ||
3827 | |||
3828 | /* Connection between two different DAPM contexts */ | ||
3829 | if (path->source->dapm != path->sink->dapm) | ||
3830 | return true; | ||
3831 | |||
3832 | /* Loopback connection from external pin to external pin */ | ||
3833 | if (path->sink->id == snd_soc_dapm_input) { | ||
3834 | switch (path->source->id) { | ||
3835 | case snd_soc_dapm_output: | ||
3836 | case snd_soc_dapm_micbias: | ||
3837 | return true; | ||
3838 | default: | ||
3839 | break; | ||
3840 | } | ||
3841 | } | ||
3842 | |||
3843 | return false; | ||
3844 | } | ||
3845 | |||
3846 | static bool snd_soc_dapm_widget_in_card_paths(struct snd_soc_card *card, | ||
3847 | struct snd_soc_dapm_widget *w) | ||
3848 | { | ||
3849 | struct snd_soc_dapm_path *p; | ||
3850 | |||
3851 | list_for_each_entry(p, &w->sources, list_sink) { | ||
3852 | if (dapm_is_external_path(card, p)) | ||
3853 | return true; | ||
3854 | } | ||
3855 | |||
3856 | list_for_each_entry(p, &w->sinks, list_source) { | ||
3857 | if (dapm_is_external_path(card, p)) | ||
3858 | return true; | ||
3859 | } | ||
3860 | |||
3861 | return false; | ||
3862 | } | ||
3863 | |||
3864 | /** | ||
3865 | * snd_soc_dapm_auto_nc_pins - call snd_soc_dapm_nc_pin for unused pins | ||
3866 | * @card: The card whose pins should be processed | ||
3867 | * | ||
3868 | * Automatically call snd_soc_dapm_nc_pin() for any external pins in the card | ||
3869 | * which are unused. Pins are used if they are connected externally to a | ||
3870 | * component, whether that be to some other device, or a loop-back connection to | ||
3871 | * the component itself. | ||
3872 | */ | ||
3873 | void snd_soc_dapm_auto_nc_pins(struct snd_soc_card *card) | ||
3874 | { | ||
3875 | struct snd_soc_dapm_widget *w; | ||
3876 | |||
3877 | dev_dbg(card->dev, "ASoC: Auto NC: DAPMs: card:%p\n", &card->dapm); | ||
3878 | |||
3879 | list_for_each_entry(w, &card->widgets, list) { | ||
3880 | switch (w->id) { | ||
3881 | case snd_soc_dapm_input: | ||
3882 | case snd_soc_dapm_output: | ||
3883 | case snd_soc_dapm_micbias: | ||
3884 | dev_dbg(card->dev, "ASoC: Auto NC: Checking widget %s\n", | ||
3885 | w->name); | ||
3886 | if (!snd_soc_dapm_widget_in_card_paths(card, w)) { | ||
3887 | dev_dbg(card->dev, | ||
3888 | "... Not in map; disabling\n"); | ||
3889 | snd_soc_dapm_nc_pin(w->dapm, w->name); | ||
3890 | } | ||
3891 | break; | ||
3892 | default: | ||
3893 | break; | ||
3894 | } | ||
3895 | } | ||
3896 | } | ||
3897 | |||
3898 | /** | ||
3899 | * snd_soc_dapm_free - free dapm resources | 3819 | * snd_soc_dapm_free - free dapm resources |
3900 | * @dapm: DAPM context | 3820 | * @dapm: DAPM context |
3901 | * | 3821 | * |
@@ -3903,7 +3823,6 @@ void snd_soc_dapm_auto_nc_pins(struct snd_soc_card *card) | |||
3903 | */ | 3823 | */ |
3904 | void snd_soc_dapm_free(struct snd_soc_dapm_context *dapm) | 3824 | void snd_soc_dapm_free(struct snd_soc_dapm_context *dapm) |
3905 | { | 3825 | { |
3906 | snd_soc_dapm_sys_remove(dapm->dev); | ||
3907 | dapm_debugfs_cleanup(dapm); | 3826 | dapm_debugfs_cleanup(dapm); |
3908 | dapm_free_widgets(dapm); | 3827 | dapm_free_widgets(dapm); |
3909 | list_del(&dapm->list); | 3828 | list_del(&dapm->list); |
diff --git a/sound/soc/soc-devres.c b/sound/soc/soc-devres.c index 057e5ef7dcce..a57921eeee81 100644 --- a/sound/soc/soc-devres.c +++ b/sound/soc/soc-devres.c | |||
@@ -60,7 +60,7 @@ static void devm_platform_release(struct device *dev, void *res) | |||
60 | /** | 60 | /** |
61 | * devm_snd_soc_register_platform - resource managed platform registration | 61 | * devm_snd_soc_register_platform - resource managed platform registration |
62 | * @dev: Device used to manage platform | 62 | * @dev: Device used to manage platform |
63 | * @platform: platform to register | 63 | * @platform_drv: platform to register |
64 | * | 64 | * |
65 | * Register a platform driver with automatic unregistration when the device is | 65 | * Register a platform driver with automatic unregistration when the device is |
66 | * unregistered. | 66 | * unregistered. |
diff --git a/sound/soc/soc-generic-dmaengine-pcm.c b/sound/soc/soc-generic-dmaengine-pcm.c index b329b84bc5af..4864392bfcba 100644 --- a/sound/soc/soc-generic-dmaengine-pcm.c +++ b/sound/soc/soc-generic-dmaengine-pcm.c | |||
@@ -200,11 +200,6 @@ static int dmaengine_pcm_open(struct snd_pcm_substream *substream) | |||
200 | return snd_dmaengine_pcm_open(substream, chan); | 200 | return snd_dmaengine_pcm_open(substream, chan); |
201 | } | 201 | } |
202 | 202 | ||
203 | static void dmaengine_pcm_free(struct snd_pcm *pcm) | ||
204 | { | ||
205 | snd_pcm_lib_preallocate_free_for_all(pcm); | ||
206 | } | ||
207 | |||
208 | static struct dma_chan *dmaengine_pcm_compat_request_channel( | 203 | static struct dma_chan *dmaengine_pcm_compat_request_channel( |
209 | struct snd_soc_pcm_runtime *rtd, | 204 | struct snd_soc_pcm_runtime *rtd, |
210 | struct snd_pcm_substream *substream) | 205 | struct snd_pcm_substream *substream) |
@@ -283,8 +278,7 @@ static int dmaengine_pcm_new(struct snd_soc_pcm_runtime *rtd) | |||
283 | if (!pcm->chan[i]) { | 278 | if (!pcm->chan[i]) { |
284 | dev_err(rtd->platform->dev, | 279 | dev_err(rtd->platform->dev, |
285 | "Missing dma channel for stream: %d\n", i); | 280 | "Missing dma channel for stream: %d\n", i); |
286 | ret = -EINVAL; | 281 | return -EINVAL; |
287 | goto err_free; | ||
288 | } | 282 | } |
289 | 283 | ||
290 | ret = snd_pcm_lib_preallocate_pages(substream, | 284 | ret = snd_pcm_lib_preallocate_pages(substream, |
@@ -293,7 +287,7 @@ static int dmaengine_pcm_new(struct snd_soc_pcm_runtime *rtd) | |||
293 | prealloc_buffer_size, | 287 | prealloc_buffer_size, |
294 | max_buffer_size); | 288 | max_buffer_size); |
295 | if (ret) | 289 | if (ret) |
296 | goto err_free; | 290 | return ret; |
297 | 291 | ||
298 | /* | 292 | /* |
299 | * This will only return false if we know for sure that at least | 293 | * This will only return false if we know for sure that at least |
@@ -307,10 +301,6 @@ static int dmaengine_pcm_new(struct snd_soc_pcm_runtime *rtd) | |||
307 | } | 301 | } |
308 | 302 | ||
309 | return 0; | 303 | return 0; |
310 | |||
311 | err_free: | ||
312 | dmaengine_pcm_free(rtd->pcm); | ||
313 | return ret; | ||
314 | } | 304 | } |
315 | 305 | ||
316 | static snd_pcm_uframes_t dmaengine_pcm_pointer( | 306 | static snd_pcm_uframes_t dmaengine_pcm_pointer( |
@@ -341,7 +331,6 @@ static const struct snd_soc_platform_driver dmaengine_pcm_platform = { | |||
341 | }, | 331 | }, |
342 | .ops = &dmaengine_pcm_ops, | 332 | .ops = &dmaengine_pcm_ops, |
343 | .pcm_new = dmaengine_pcm_new, | 333 | .pcm_new = dmaengine_pcm_new, |
344 | .pcm_free = dmaengine_pcm_free, | ||
345 | }; | 334 | }; |
346 | 335 | ||
347 | static const char * const dmaengine_pcm_dma_channel_names[] = { | 336 | static const char * const dmaengine_pcm_dma_channel_names[] = { |
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index eb87d96e2cf0..0ae0e2a9eed7 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c | |||
@@ -746,7 +746,8 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream) | |||
746 | codec_dai); | 746 | codec_dai); |
747 | if (ret < 0) { | 747 | if (ret < 0) { |
748 | dev_err(codec_dai->dev, | 748 | dev_err(codec_dai->dev, |
749 | "ASoC: DAI prepare error: %d\n", ret); | 749 | "ASoC: codec DAI prepare error: %d\n", |
750 | ret); | ||
750 | goto out; | 751 | goto out; |
751 | } | 752 | } |
752 | } | 753 | } |
@@ -755,8 +756,8 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream) | |||
755 | if (cpu_dai->driver->ops && cpu_dai->driver->ops->prepare) { | 756 | if (cpu_dai->driver->ops && cpu_dai->driver->ops->prepare) { |
756 | ret = cpu_dai->driver->ops->prepare(substream, cpu_dai); | 757 | ret = cpu_dai->driver->ops->prepare(substream, cpu_dai); |
757 | if (ret < 0) { | 758 | if (ret < 0) { |
758 | dev_err(cpu_dai->dev, "ASoC: DAI prepare error: %d\n", | 759 | dev_err(cpu_dai->dev, |
759 | ret); | 760 | "ASoC: cpu DAI prepare error: %d\n", ret); |
760 | goto out; | 761 | goto out; |
761 | } | 762 | } |
762 | } | 763 | } |
diff --git a/sound/soc/tegra/Kconfig b/sound/soc/tegra/Kconfig index 31198cf7f88d..a6768f832c6f 100644 --- a/sound/soc/tegra/Kconfig +++ b/sound/soc/tegra/Kconfig | |||
@@ -128,3 +128,13 @@ config SND_SOC_TEGRA_MAX98090 | |||
128 | help | 128 | help |
129 | Say Y or M here if you want to add support for SoC audio on Tegra | 129 | Say Y or M here if you want to add support for SoC audio on Tegra |
130 | boards using the MAX98090 codec, such as Venice2. | 130 | boards using the MAX98090 codec, such as Venice2. |
131 | |||
132 | config SND_SOC_TEGRA_RT5677 | ||
133 | tristate "SoC Audio support for Tegra boards using a RT5677 codec" | ||
134 | depends on SND_SOC_TEGRA && I2C && GPIOLIB | ||
135 | select SND_SOC_TEGRA20_I2S if ARCH_TEGRA_2x_SOC | ||
136 | select SND_SOC_TEGRA30_I2S if ARCH_TEGRA_3x_SOC | ||
137 | select SND_SOC_RT5677 | ||
138 | help | ||
139 | Say Y or M here if you want to add support for SoC audio on Tegra | ||
140 | boards using the RT5677 codec, such as Ryu. | ||
diff --git a/sound/soc/tegra/Makefile b/sound/soc/tegra/Makefile index 5ae588cd96c4..9171655ad843 100644 --- a/sound/soc/tegra/Makefile +++ b/sound/soc/tegra/Makefile | |||
@@ -19,6 +19,7 @@ obj-$(CONFIG_SND_SOC_TEGRA30_I2S) += snd-soc-tegra30-i2s.o | |||
19 | 19 | ||
20 | # Tegra machine Support | 20 | # Tegra machine Support |
21 | snd-soc-tegra-rt5640-objs := tegra_rt5640.o | 21 | snd-soc-tegra-rt5640-objs := tegra_rt5640.o |
22 | snd-soc-tegra-rt5677-objs := tegra_rt5677.o | ||
22 | snd-soc-tegra-wm8753-objs := tegra_wm8753.o | 23 | snd-soc-tegra-wm8753-objs := tegra_wm8753.o |
23 | snd-soc-tegra-wm8903-objs := tegra_wm8903.o | 24 | snd-soc-tegra-wm8903-objs := tegra_wm8903.o |
24 | snd-soc-tegra-wm9712-objs := tegra_wm9712.o | 25 | snd-soc-tegra-wm9712-objs := tegra_wm9712.o |
@@ -27,6 +28,7 @@ snd-soc-tegra-alc5632-objs := tegra_alc5632.o | |||
27 | snd-soc-tegra-max98090-objs := tegra_max98090.o | 28 | snd-soc-tegra-max98090-objs := tegra_max98090.o |
28 | 29 | ||
29 | obj-$(CONFIG_SND_SOC_TEGRA_RT5640) += snd-soc-tegra-rt5640.o | 30 | obj-$(CONFIG_SND_SOC_TEGRA_RT5640) += snd-soc-tegra-rt5640.o |
31 | obj-$(CONFIG_SND_SOC_TEGRA_RT5677) += snd-soc-tegra-rt5677.o | ||
30 | obj-$(CONFIG_SND_SOC_TEGRA_WM8753) += snd-soc-tegra-wm8753.o | 32 | obj-$(CONFIG_SND_SOC_TEGRA_WM8753) += snd-soc-tegra-wm8753.o |
31 | obj-$(CONFIG_SND_SOC_TEGRA_WM8903) += snd-soc-tegra-wm8903.o | 33 | obj-$(CONFIG_SND_SOC_TEGRA_WM8903) += snd-soc-tegra-wm8903.o |
32 | obj-$(CONFIG_SND_SOC_TEGRA_WM9712) += snd-soc-tegra-wm9712.o | 34 | obj-$(CONFIG_SND_SOC_TEGRA_WM9712) += snd-soc-tegra-wm9712.o |
diff --git a/sound/soc/tegra/tegra_rt5677.c b/sound/soc/tegra/tegra_rt5677.c new file mode 100644 index 000000000000..e4cf978a6e3a --- /dev/null +++ b/sound/soc/tegra/tegra_rt5677.c | |||
@@ -0,0 +1,347 @@ | |||
1 | /* | ||
2 | * tegra_rt5677.c - Tegra machine ASoC driver for boards using RT5677 codec. | ||
3 | * | ||
4 | * Copyright (c) 2014, The Chromium OS Authors. All rights reserved. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms and conditions of the GNU General Public License, | ||
8 | * version 2, as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
13 | * more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
17 | * | ||
18 | * Based on code copyright/by: | ||
19 | * | ||
20 | * Copyright (C) 2010-2012 - NVIDIA, Inc. | ||
21 | * Copyright (C) 2011 The AC100 Kernel Team <ac100@lists.lauchpad.net> | ||
22 | * (c) 2009, 2010 Nvidia Graphics Pvt. Ltd. | ||
23 | * Copyright 2007 Wolfson Microelectronics PLC. | ||
24 | */ | ||
25 | |||
26 | #include <linux/module.h> | ||
27 | #include <linux/platform_device.h> | ||
28 | #include <linux/slab.h> | ||
29 | #include <linux/gpio.h> | ||
30 | #include <linux/of_gpio.h> | ||
31 | |||
32 | #include <sound/core.h> | ||
33 | #include <sound/jack.h> | ||
34 | #include <sound/pcm.h> | ||
35 | #include <sound/pcm_params.h> | ||
36 | #include <sound/soc.h> | ||
37 | |||
38 | #include "../codecs/rt5677.h" | ||
39 | |||
40 | #include "tegra_asoc_utils.h" | ||
41 | |||
42 | #define DRV_NAME "tegra-snd-rt5677" | ||
43 | |||
44 | struct tegra_rt5677 { | ||
45 | struct tegra_asoc_utils_data util_data; | ||
46 | int gpio_hp_det; | ||
47 | int gpio_hp_en; | ||
48 | int gpio_mic_present; | ||
49 | int gpio_dmic_clk_en; | ||
50 | }; | ||
51 | |||
52 | static int tegra_rt5677_asoc_hw_params(struct snd_pcm_substream *substream, | ||
53 | struct snd_pcm_hw_params *params) | ||
54 | { | ||
55 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
56 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | ||
57 | struct snd_soc_card *card = rtd->card; | ||
58 | struct tegra_rt5677 *machine = snd_soc_card_get_drvdata(card); | ||
59 | int srate, mclk, err; | ||
60 | |||
61 | srate = params_rate(params); | ||
62 | mclk = 256 * srate; | ||
63 | |||
64 | err = tegra_asoc_utils_set_rate(&machine->util_data, srate, mclk); | ||
65 | if (err < 0) { | ||
66 | dev_err(card->dev, "Can't configure clocks\n"); | ||
67 | return err; | ||
68 | } | ||
69 | |||
70 | err = snd_soc_dai_set_sysclk(codec_dai, RT5677_SCLK_S_MCLK, mclk, | ||
71 | SND_SOC_CLOCK_IN); | ||
72 | if (err < 0) { | ||
73 | dev_err(card->dev, "codec_dai clock not set\n"); | ||
74 | return err; | ||
75 | } | ||
76 | |||
77 | return 0; | ||
78 | } | ||
79 | |||
80 | static int tegra_rt5677_event_hp(struct snd_soc_dapm_widget *w, | ||
81 | struct snd_kcontrol *k, int event) | ||
82 | { | ||
83 | struct snd_soc_dapm_context *dapm = w->dapm; | ||
84 | struct snd_soc_card *card = dapm->card; | ||
85 | struct tegra_rt5677 *machine = snd_soc_card_get_drvdata(card); | ||
86 | |||
87 | if (!gpio_is_valid(machine->gpio_hp_en)) | ||
88 | return 0; | ||
89 | |||
90 | gpio_set_value_cansleep(machine->gpio_hp_en, | ||
91 | SND_SOC_DAPM_EVENT_ON(event)); | ||
92 | |||
93 | return 0; | ||
94 | } | ||
95 | |||
96 | static struct snd_soc_ops tegra_rt5677_ops = { | ||
97 | .hw_params = tegra_rt5677_asoc_hw_params, | ||
98 | }; | ||
99 | |||
100 | static struct snd_soc_jack tegra_rt5677_hp_jack; | ||
101 | |||
102 | static struct snd_soc_jack_pin tegra_rt5677_hp_jack_pins = { | ||
103 | .pin = "Headphone", | ||
104 | .mask = SND_JACK_HEADPHONE, | ||
105 | }; | ||
106 | static struct snd_soc_jack_gpio tegra_rt5677_hp_jack_gpio = { | ||
107 | .name = "Headphone detection", | ||
108 | .report = SND_JACK_HEADPHONE, | ||
109 | .debounce_time = 150, | ||
110 | }; | ||
111 | |||
112 | static struct snd_soc_jack tegra_rt5677_mic_jack; | ||
113 | |||
114 | static struct snd_soc_jack_pin tegra_rt5677_mic_jack_pins = { | ||
115 | .pin = "Headset Mic", | ||
116 | .mask = SND_JACK_MICROPHONE, | ||
117 | }; | ||
118 | |||
119 | static struct snd_soc_jack_gpio tegra_rt5677_mic_jack_gpio = { | ||
120 | .name = "Headset Mic detection", | ||
121 | .report = SND_JACK_MICROPHONE, | ||
122 | .debounce_time = 150, | ||
123 | .invert = 1 | ||
124 | }; | ||
125 | |||
126 | static const struct snd_soc_dapm_widget tegra_rt5677_dapm_widgets[] = { | ||
127 | SND_SOC_DAPM_SPK("Speaker", NULL), | ||
128 | SND_SOC_DAPM_HP("Headphone", tegra_rt5677_event_hp), | ||
129 | SND_SOC_DAPM_MIC("Headset Mic", NULL), | ||
130 | SND_SOC_DAPM_MIC("Internal Mic 1", NULL), | ||
131 | SND_SOC_DAPM_MIC("Internal Mic 2", NULL), | ||
132 | }; | ||
133 | |||
134 | static const struct snd_kcontrol_new tegra_rt5677_controls[] = { | ||
135 | SOC_DAPM_PIN_SWITCH("Speaker"), | ||
136 | SOC_DAPM_PIN_SWITCH("Headphone"), | ||
137 | SOC_DAPM_PIN_SWITCH("Headset Mic"), | ||
138 | SOC_DAPM_PIN_SWITCH("Internal Mic 1"), | ||
139 | SOC_DAPM_PIN_SWITCH("Internal Mic 2"), | ||
140 | }; | ||
141 | |||
142 | static int tegra_rt5677_asoc_init(struct snd_soc_pcm_runtime *rtd) | ||
143 | { | ||
144 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | ||
145 | struct snd_soc_codec *codec = codec_dai->codec; | ||
146 | struct snd_soc_dapm_context *dapm = &codec->dapm; | ||
147 | struct tegra_rt5677 *machine = snd_soc_card_get_drvdata(rtd->card); | ||
148 | |||
149 | snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE, | ||
150 | &tegra_rt5677_hp_jack); | ||
151 | snd_soc_jack_add_pins(&tegra_rt5677_hp_jack, 1, | ||
152 | &tegra_rt5677_hp_jack_pins); | ||
153 | |||
154 | if (gpio_is_valid(machine->gpio_hp_det)) { | ||
155 | tegra_rt5677_hp_jack_gpio.gpio = machine->gpio_hp_det; | ||
156 | snd_soc_jack_add_gpios(&tegra_rt5677_hp_jack, 1, | ||
157 | &tegra_rt5677_hp_jack_gpio); | ||
158 | } | ||
159 | |||
160 | |||
161 | snd_soc_jack_new(codec, "Mic Jack", SND_JACK_MICROPHONE, | ||
162 | &tegra_rt5677_mic_jack); | ||
163 | snd_soc_jack_add_pins(&tegra_rt5677_mic_jack, 1, | ||
164 | &tegra_rt5677_mic_jack_pins); | ||
165 | |||
166 | if (gpio_is_valid(machine->gpio_mic_present)) { | ||
167 | tegra_rt5677_mic_jack_gpio.gpio = machine->gpio_mic_present; | ||
168 | snd_soc_jack_add_gpios(&tegra_rt5677_mic_jack, 1, | ||
169 | &tegra_rt5677_mic_jack_gpio); | ||
170 | } | ||
171 | |||
172 | snd_soc_dapm_force_enable_pin(dapm, "MICBIAS1"); | ||
173 | |||
174 | return 0; | ||
175 | } | ||
176 | |||
177 | static int tegra_rt5677_card_remove(struct snd_soc_card *card) | ||
178 | { | ||
179 | struct tegra_rt5677 *machine = snd_soc_card_get_drvdata(card); | ||
180 | |||
181 | if (gpio_is_valid(machine->gpio_hp_det)) { | ||
182 | snd_soc_jack_free_gpios(&tegra_rt5677_hp_jack, 1, | ||
183 | &tegra_rt5677_hp_jack_gpio); | ||
184 | } | ||
185 | |||
186 | if (gpio_is_valid(machine->gpio_mic_present)) { | ||
187 | snd_soc_jack_free_gpios(&tegra_rt5677_mic_jack, 1, | ||
188 | &tegra_rt5677_mic_jack_gpio); | ||
189 | } | ||
190 | |||
191 | return 0; | ||
192 | } | ||
193 | |||
194 | static struct snd_soc_dai_link tegra_rt5677_dai = { | ||
195 | .name = "RT5677", | ||
196 | .stream_name = "RT5677 PCM", | ||
197 | .codec_dai_name = "rt5677-aif1", | ||
198 | .init = tegra_rt5677_asoc_init, | ||
199 | .ops = &tegra_rt5677_ops, | ||
200 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | | ||
201 | SND_SOC_DAIFMT_CBS_CFS, | ||
202 | }; | ||
203 | |||
204 | static struct snd_soc_card snd_soc_tegra_rt5677 = { | ||
205 | .name = "tegra-rt5677", | ||
206 | .owner = THIS_MODULE, | ||
207 | .remove = tegra_rt5677_card_remove, | ||
208 | .dai_link = &tegra_rt5677_dai, | ||
209 | .num_links = 1, | ||
210 | .controls = tegra_rt5677_controls, | ||
211 | .num_controls = ARRAY_SIZE(tegra_rt5677_controls), | ||
212 | .dapm_widgets = tegra_rt5677_dapm_widgets, | ||
213 | .num_dapm_widgets = ARRAY_SIZE(tegra_rt5677_dapm_widgets), | ||
214 | .fully_routed = true, | ||
215 | }; | ||
216 | |||
217 | static int tegra_rt5677_probe(struct platform_device *pdev) | ||
218 | { | ||
219 | struct device_node *np = pdev->dev.of_node; | ||
220 | struct snd_soc_card *card = &snd_soc_tegra_rt5677; | ||
221 | struct tegra_rt5677 *machine; | ||
222 | int ret; | ||
223 | |||
224 | machine = devm_kzalloc(&pdev->dev, | ||
225 | sizeof(struct tegra_rt5677), GFP_KERNEL); | ||
226 | if (!machine) | ||
227 | return -ENOMEM; | ||
228 | |||
229 | card->dev = &pdev->dev; | ||
230 | platform_set_drvdata(pdev, card); | ||
231 | snd_soc_card_set_drvdata(card, machine); | ||
232 | |||
233 | machine->gpio_hp_det = of_get_named_gpio(np, "nvidia,hp-det-gpios", 0); | ||
234 | if (machine->gpio_hp_det == -EPROBE_DEFER) | ||
235 | return -EPROBE_DEFER; | ||
236 | |||
237 | machine->gpio_mic_present = of_get_named_gpio(np, | ||
238 | "nvidia,mic-present-gpios", 0); | ||
239 | if (machine->gpio_mic_present == -EPROBE_DEFER) | ||
240 | return -EPROBE_DEFER; | ||
241 | |||
242 | machine->gpio_hp_en = of_get_named_gpio(np, "nvidia,hp-en-gpios", 0); | ||
243 | if (machine->gpio_hp_en == -EPROBE_DEFER) | ||
244 | return -EPROBE_DEFER; | ||
245 | if (gpio_is_valid(machine->gpio_hp_en)) { | ||
246 | ret = devm_gpio_request_one(&pdev->dev, machine->gpio_hp_en, | ||
247 | GPIOF_OUT_INIT_LOW, "hp_en"); | ||
248 | if (ret) { | ||
249 | dev_err(card->dev, "cannot get hp_en gpio\n"); | ||
250 | return ret; | ||
251 | } | ||
252 | } | ||
253 | |||
254 | machine->gpio_dmic_clk_en = of_get_named_gpio(np, | ||
255 | "nvidia,dmic-clk-en-gpios", 0); | ||
256 | if (machine->gpio_dmic_clk_en == -EPROBE_DEFER) | ||
257 | return -EPROBE_DEFER; | ||
258 | if (gpio_is_valid(machine->gpio_dmic_clk_en)) { | ||
259 | ret = devm_gpio_request_one(&pdev->dev, | ||
260 | machine->gpio_dmic_clk_en, | ||
261 | GPIOF_OUT_INIT_HIGH, "dmic_clk_en"); | ||
262 | if (ret) { | ||
263 | dev_err(card->dev, "cannot get dmic_clk_en gpio\n"); | ||
264 | return ret; | ||
265 | } | ||
266 | } | ||
267 | |||
268 | ret = snd_soc_of_parse_card_name(card, "nvidia,model"); | ||
269 | if (ret) | ||
270 | goto err; | ||
271 | |||
272 | ret = snd_soc_of_parse_audio_routing(card, "nvidia,audio-routing"); | ||
273 | if (ret) | ||
274 | goto err; | ||
275 | |||
276 | tegra_rt5677_dai.codec_of_node = of_parse_phandle(np, | ||
277 | "nvidia,audio-codec", 0); | ||
278 | if (!tegra_rt5677_dai.codec_of_node) { | ||
279 | dev_err(&pdev->dev, | ||
280 | "Property 'nvidia,audio-codec' missing or invalid\n"); | ||
281 | ret = -EINVAL; | ||
282 | goto err; | ||
283 | } | ||
284 | |||
285 | tegra_rt5677_dai.cpu_of_node = of_parse_phandle(np, | ||
286 | "nvidia,i2s-controller", 0); | ||
287 | if (!tegra_rt5677_dai.cpu_of_node) { | ||
288 | dev_err(&pdev->dev, | ||
289 | "Property 'nvidia,i2s-controller' missing or invalid\n"); | ||
290 | ret = -EINVAL; | ||
291 | goto err; | ||
292 | } | ||
293 | tegra_rt5677_dai.platform_of_node = tegra_rt5677_dai.cpu_of_node; | ||
294 | |||
295 | ret = tegra_asoc_utils_init(&machine->util_data, &pdev->dev); | ||
296 | if (ret) | ||
297 | goto err; | ||
298 | |||
299 | ret = snd_soc_register_card(card); | ||
300 | if (ret) { | ||
301 | dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", | ||
302 | ret); | ||
303 | goto err_fini_utils; | ||
304 | } | ||
305 | |||
306 | return 0; | ||
307 | |||
308 | err_fini_utils: | ||
309 | tegra_asoc_utils_fini(&machine->util_data); | ||
310 | err: | ||
311 | return ret; | ||
312 | } | ||
313 | |||
314 | static int tegra_rt5677_remove(struct platform_device *pdev) | ||
315 | { | ||
316 | struct snd_soc_card *card = platform_get_drvdata(pdev); | ||
317 | struct tegra_rt5677 *machine = snd_soc_card_get_drvdata(card); | ||
318 | |||
319 | snd_soc_unregister_card(card); | ||
320 | |||
321 | tegra_asoc_utils_fini(&machine->util_data); | ||
322 | |||
323 | return 0; | ||
324 | } | ||
325 | |||
326 | static const struct of_device_id tegra_rt5677_of_match[] = { | ||
327 | { .compatible = "nvidia,tegra-audio-rt5677", }, | ||
328 | {}, | ||
329 | }; | ||
330 | |||
331 | static struct platform_driver tegra_rt5677_driver = { | ||
332 | .driver = { | ||
333 | .name = DRV_NAME, | ||
334 | .owner = THIS_MODULE, | ||
335 | .pm = &snd_soc_pm_ops, | ||
336 | .of_match_table = tegra_rt5677_of_match, | ||
337 | }, | ||
338 | .probe = tegra_rt5677_probe, | ||
339 | .remove = tegra_rt5677_remove, | ||
340 | }; | ||
341 | module_platform_driver(tegra_rt5677_driver); | ||
342 | |||
343 | MODULE_AUTHOR("Anatol Pomozov <anatol@google.com>"); | ||
344 | MODULE_DESCRIPTION("Tegra+RT5677 machine ASoC driver"); | ||
345 | MODULE_LICENSE("GPL v2"); | ||
346 | MODULE_ALIAS("platform:" DRV_NAME); | ||
347 | MODULE_DEVICE_TABLE(of, tegra_rt5677_of_match); | ||
diff --git a/sound/soc/ux500/mop500_ab8500.c b/sound/soc/ux500/mop500_ab8500.c index be4f1ac7cd5e..aa65370db82a 100644 --- a/sound/soc/ux500/mop500_ab8500.c +++ b/sound/soc/ux500/mop500_ab8500.c | |||
@@ -290,21 +290,9 @@ static int mop500_ab8500_hw_params(struct snd_pcm_substream *substream, | |||
290 | SND_SOC_DAIFMT_GATED; | 290 | SND_SOC_DAIFMT_GATED; |
291 | } | 291 | } |
292 | 292 | ||
293 | ret = snd_soc_dai_set_fmt(codec_dai, fmt); | 293 | ret = snd_soc_runtime_set_dai_fmt(rtd, fmt); |
294 | if (ret < 0) { | 294 | if (ret) |
295 | dev_err(dev, | ||
296 | "%s: ERROR: snd_soc_dai_set_fmt failed for codec_dai (ret = %d)!\n", | ||
297 | __func__, ret); | ||
298 | return ret; | ||
299 | } | ||
300 | |||
301 | ret = snd_soc_dai_set_fmt(cpu_dai, fmt); | ||
302 | if (ret < 0) { | ||
303 | dev_err(dev, | ||
304 | "%s: ERROR: snd_soc_dai_set_fmt failed for cpu_dai (ret = %d)!\n", | ||
305 | __func__, ret); | ||
306 | return ret; | 295 | return ret; |
307 | } | ||
308 | 296 | ||
309 | /* Setup TDM-slots */ | 297 | /* Setup TDM-slots */ |
310 | 298 | ||