diff options
-rw-r--r-- | sound/soc/davinci/davinci-evm.c | 1 | ||||
-rw-r--r-- | sound/soc/davinci/davinci-mcasp.c | 83 |
2 files changed, 39 insertions, 45 deletions
diff --git a/sound/soc/davinci/davinci-evm.c b/sound/soc/davinci/davinci-evm.c index d3e4cb0655d2..621e9a997d4c 100644 --- a/sound/soc/davinci/davinci-evm.c +++ b/sound/soc/davinci/davinci-evm.c | |||
@@ -453,6 +453,7 @@ static struct platform_driver davinci_evm_driver = { | |||
453 | .driver = { | 453 | .driver = { |
454 | .name = "davinci_evm", | 454 | .name = "davinci_evm", |
455 | .owner = THIS_MODULE, | 455 | .owner = THIS_MODULE, |
456 | .pm = &snd_soc_pm_ops, | ||
456 | .of_match_table = of_match_ptr(davinci_evm_dt_ids), | 457 | .of_match_table = of_match_ptr(davinci_evm_dt_ids), |
457 | }, | 458 | }, |
458 | }; | 459 | }; |
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index ae328beb676a..f662ef22b8ae 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c | |||
@@ -266,7 +266,9 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai, | |||
266 | unsigned int fmt) | 266 | unsigned int fmt) |
267 | { | 267 | { |
268 | struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(cpu_dai); | 268 | struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(cpu_dai); |
269 | int ret = 0; | ||
269 | 270 | ||
271 | pm_runtime_get_sync(mcasp->dev); | ||
270 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { | 272 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { |
271 | case SND_SOC_DAIFMT_DSP_B: | 273 | case SND_SOC_DAIFMT_DSP_B: |
272 | case SND_SOC_DAIFMT_AC97: | 274 | case SND_SOC_DAIFMT_AC97: |
@@ -323,7 +325,8 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai, | |||
323 | break; | 325 | break; |
324 | 326 | ||
325 | default: | 327 | default: |
326 | return -EINVAL; | 328 | ret = -EINVAL; |
329 | goto out; | ||
327 | } | 330 | } |
328 | 331 | ||
329 | switch (fmt & SND_SOC_DAIFMT_INV_MASK) { | 332 | switch (fmt & SND_SOC_DAIFMT_INV_MASK) { |
@@ -360,10 +363,12 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai, | |||
360 | break; | 363 | break; |
361 | 364 | ||
362 | default: | 365 | default: |
363 | return -EINVAL; | 366 | ret = -EINVAL; |
367 | break; | ||
364 | } | 368 | } |
365 | 369 | out: | |
366 | return 0; | 370 | pm_runtime_put_sync(mcasp->dev); |
371 | return ret; | ||
367 | } | 372 | } |
368 | 373 | ||
369 | static int davinci_mcasp_set_clkdiv(struct snd_soc_dai *dai, int div_id, int div) | 374 | static int davinci_mcasp_set_clkdiv(struct snd_soc_dai *dai, int div_id, int div) |
@@ -456,7 +461,7 @@ static int davinci_config_channel_size(struct davinci_mcasp *mcasp, | |||
456 | return 0; | 461 | return 0; |
457 | } | 462 | } |
458 | 463 | ||
459 | static int davinci_hw_common_param(struct davinci_mcasp *mcasp, int stream, | 464 | static int mcasp_common_hw_param(struct davinci_mcasp *mcasp, int stream, |
460 | int channels) | 465 | int channels) |
461 | { | 466 | { |
462 | int i; | 467 | int i; |
@@ -532,12 +537,18 @@ static int davinci_hw_common_param(struct davinci_mcasp *mcasp, int stream, | |||
532 | return 0; | 537 | return 0; |
533 | } | 538 | } |
534 | 539 | ||
535 | static void davinci_hw_param(struct davinci_mcasp *mcasp, int stream) | 540 | static int mcasp_i2s_hw_param(struct davinci_mcasp *mcasp, int stream) |
536 | { | 541 | { |
537 | int i, active_slots; | 542 | int i, active_slots; |
538 | u32 mask = 0; | 543 | u32 mask = 0; |
539 | u32 busel = 0; | 544 | u32 busel = 0; |
540 | 545 | ||
546 | if ((mcasp->tdm_slots < 2) || (mcasp->tdm_slots > 32)) { | ||
547 | dev_err(mcasp->dev, "tdm slot %d not supported\n", | ||
548 | mcasp->tdm_slots); | ||
549 | return -EINVAL; | ||
550 | } | ||
551 | |||
541 | active_slots = (mcasp->tdm_slots > 31) ? 32 : mcasp->tdm_slots; | 552 | active_slots = (mcasp->tdm_slots > 31) ? 32 : mcasp->tdm_slots; |
542 | for (i = 0; i < active_slots; i++) | 553 | for (i = 0; i < active_slots; i++) |
543 | mask |= (1 << i); | 554 | mask |= (1 << i); |
@@ -547,35 +558,21 @@ static void davinci_hw_param(struct davinci_mcasp *mcasp, int stream) | |||
547 | if (!mcasp->dat_port) | 558 | if (!mcasp->dat_port) |
548 | busel = TXSEL; | 559 | busel = TXSEL; |
549 | 560 | ||
550 | if (stream == SNDRV_PCM_STREAM_PLAYBACK) { | 561 | mcasp_set_reg(mcasp, DAVINCI_MCASP_TXTDM_REG, mask); |
551 | /* bit stream is MSB first with no delay */ | 562 | mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMT_REG, busel | TXORD); |
552 | /* DSP_B mode */ | 563 | mcasp_mod_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, |
553 | mcasp_set_reg(mcasp, DAVINCI_MCASP_TXTDM_REG, mask); | 564 | FSXMOD(mcasp->tdm_slots), FSXMOD(0x1FF)); |
554 | mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMT_REG, busel | TXORD); | 565 | |
555 | 566 | mcasp_set_reg(mcasp, DAVINCI_MCASP_RXTDM_REG, mask); | |
556 | if ((mcasp->tdm_slots >= 2) && (mcasp->tdm_slots <= 32)) | 567 | mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMT_REG, busel | RXORD); |
557 | mcasp_mod_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, | 568 | mcasp_mod_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, |
558 | FSXMOD(mcasp->tdm_slots), FSXMOD(0x1FF)); | 569 | FSRMOD(mcasp->tdm_slots), FSRMOD(0x1FF)); |
559 | else | 570 | |
560 | printk(KERN_ERR "playback tdm slot %d not supported\n", | 571 | return 0; |
561 | mcasp->tdm_slots); | ||
562 | } else { | ||
563 | /* bit stream is MSB first with no delay */ | ||
564 | /* DSP_B mode */ | ||
565 | mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMT_REG, busel | RXORD); | ||
566 | mcasp_set_reg(mcasp, DAVINCI_MCASP_RXTDM_REG, mask); | ||
567 | |||
568 | if ((mcasp->tdm_slots >= 2) && (mcasp->tdm_slots <= 32)) | ||
569 | mcasp_mod_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, | ||
570 | FSRMOD(mcasp->tdm_slots), FSRMOD(0x1FF)); | ||
571 | else | ||
572 | printk(KERN_ERR "capture tdm slot %d not supported\n", | ||
573 | mcasp->tdm_slots); | ||
574 | } | ||
575 | } | 572 | } |
576 | 573 | ||
577 | /* S/PDIF */ | 574 | /* S/PDIF */ |
578 | static void davinci_hw_dit_param(struct davinci_mcasp *mcasp) | 575 | static int mcasp_dit_hw_param(struct davinci_mcasp *mcasp) |
579 | { | 576 | { |
580 | /* Set the TX format : 24 bit right rotation, 32 bit slot, Pad 0 | 577 | /* Set the TX format : 24 bit right rotation, 32 bit slot, Pad 0 |
581 | and LSB first */ | 578 | and LSB first */ |
@@ -597,6 +594,8 @@ static void davinci_hw_dit_param(struct davinci_mcasp *mcasp) | |||
597 | 594 | ||
598 | /* Enable the DIT */ | 595 | /* Enable the DIT */ |
599 | mcasp_set_bits(mcasp, DAVINCI_MCASP_TXDITCTL_REG, DITEN); | 596 | mcasp_set_bits(mcasp, DAVINCI_MCASP_TXDITCTL_REG, DITEN); |
597 | |||
598 | return 0; | ||
600 | } | 599 | } |
601 | 600 | ||
602 | static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream, | 601 | static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream, |
@@ -613,6 +612,7 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream, | |||
613 | u8 slots = mcasp->tdm_slots; | 612 | u8 slots = mcasp->tdm_slots; |
614 | u8 active_serializers; | 613 | u8 active_serializers; |
615 | int channels; | 614 | int channels; |
615 | int ret; | ||
616 | struct snd_interval *pcm_channels = hw_param_interval(params, | 616 | struct snd_interval *pcm_channels = hw_param_interval(params, |
617 | SNDRV_PCM_HW_PARAM_CHANNELS); | 617 | SNDRV_PCM_HW_PARAM_CHANNELS); |
618 | 618 | ||
@@ -631,7 +631,7 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream, | |||
631 | 631 | ||
632 | active_serializers = (channels + slots - 1) / slots; | 632 | active_serializers = (channels + slots - 1) / slots; |
633 | 633 | ||
634 | if (davinci_hw_common_param(mcasp, substream->stream, channels) == -EINVAL) | 634 | if (mcasp_common_hw_param(mcasp, substream->stream, channels) == -EINVAL) |
635 | return -EINVAL; | 635 | return -EINVAL; |
636 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | 636 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) |
637 | fifo_level = mcasp->txnumevt * active_serializers; | 637 | fifo_level = mcasp->txnumevt * active_serializers; |
@@ -639,9 +639,12 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream, | |||
639 | fifo_level = mcasp->rxnumevt * active_serializers; | 639 | fifo_level = mcasp->rxnumevt * active_serializers; |
640 | 640 | ||
641 | if (mcasp->op_mode == DAVINCI_MCASP_DIT_MODE) | 641 | if (mcasp->op_mode == DAVINCI_MCASP_DIT_MODE) |
642 | davinci_hw_dit_param(mcasp); | 642 | ret = mcasp_dit_hw_param(mcasp); |
643 | else | 643 | else |
644 | davinci_hw_param(mcasp, substream->stream); | 644 | ret = mcasp_i2s_hw_param(mcasp, substream->stream); |
645 | |||
646 | if (ret) | ||
647 | return ret; | ||
645 | 648 | ||
646 | switch (params_format(params)) { | 649 | switch (params_format(params)) { |
647 | case SNDRV_PCM_FORMAT_U8: | 650 | case SNDRV_PCM_FORMAT_U8: |
@@ -698,19 +701,9 @@ static int davinci_mcasp_trigger(struct snd_pcm_substream *substream, | |||
698 | case SNDRV_PCM_TRIGGER_RESUME: | 701 | case SNDRV_PCM_TRIGGER_RESUME: |
699 | case SNDRV_PCM_TRIGGER_START: | 702 | case SNDRV_PCM_TRIGGER_START: |
700 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | 703 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: |
701 | ret = pm_runtime_get_sync(mcasp->dev); | ||
702 | if (IS_ERR_VALUE(ret)) | ||
703 | dev_err(mcasp->dev, "pm_runtime_get_sync() failed\n"); | ||
704 | davinci_mcasp_start(mcasp, substream->stream); | 704 | davinci_mcasp_start(mcasp, substream->stream); |
705 | break; | 705 | break; |
706 | |||
707 | case SNDRV_PCM_TRIGGER_SUSPEND: | 706 | case SNDRV_PCM_TRIGGER_SUSPEND: |
708 | davinci_mcasp_stop(mcasp, substream->stream); | ||
709 | ret = pm_runtime_put_sync(mcasp->dev); | ||
710 | if (IS_ERR_VALUE(ret)) | ||
711 | dev_err(mcasp->dev, "pm_runtime_put_sync() failed\n"); | ||
712 | break; | ||
713 | |||
714 | case SNDRV_PCM_TRIGGER_STOP: | 707 | case SNDRV_PCM_TRIGGER_STOP: |
715 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: | 708 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: |
716 | davinci_mcasp_stop(mcasp, substream->stream); | 709 | davinci_mcasp_stop(mcasp, substream->stream); |