diff options
Diffstat (limited to 'sound/soc/davinci/davinci-mcasp.c')
| -rw-r--r-- | sound/soc/davinci/davinci-mcasp.c | 83 |
1 files changed, 38 insertions, 45 deletions
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index b7858bfa0295..670afa29e30d 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c | |||
| @@ -263,7 +263,9 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai, | |||
| 263 | unsigned int fmt) | 263 | unsigned int fmt) |
| 264 | { | 264 | { |
| 265 | struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(cpu_dai); | 265 | struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(cpu_dai); |
| 266 | int ret = 0; | ||
| 266 | 267 | ||
| 268 | pm_runtime_get_sync(mcasp->dev); | ||
| 267 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { | 269 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { |
| 268 | case SND_SOC_DAIFMT_DSP_B: | 270 | case SND_SOC_DAIFMT_DSP_B: |
| 269 | case SND_SOC_DAIFMT_AC97: | 271 | case SND_SOC_DAIFMT_AC97: |
| @@ -317,7 +319,8 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai, | |||
| 317 | break; | 319 | break; |
| 318 | 320 | ||
| 319 | default: | 321 | default: |
| 320 | return -EINVAL; | 322 | ret = -EINVAL; |
| 323 | goto out; | ||
| 321 | } | 324 | } |
| 322 | 325 | ||
| 323 | switch (fmt & SND_SOC_DAIFMT_INV_MASK) { | 326 | switch (fmt & SND_SOC_DAIFMT_INV_MASK) { |
| @@ -354,10 +357,12 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai, | |||
| 354 | break; | 357 | break; |
| 355 | 358 | ||
| 356 | default: | 359 | default: |
| 357 | return -EINVAL; | 360 | ret = -EINVAL; |
| 361 | break; | ||
| 358 | } | 362 | } |
| 359 | 363 | out: | |
| 360 | return 0; | 364 | pm_runtime_put_sync(mcasp->dev); |
| 365 | return ret; | ||
| 361 | } | 366 | } |
| 362 | 367 | ||
| 363 | static int davinci_mcasp_set_clkdiv(struct snd_soc_dai *dai, int div_id, int div) | 368 | static int davinci_mcasp_set_clkdiv(struct snd_soc_dai *dai, int div_id, int div) |
| @@ -448,7 +453,7 @@ static int davinci_config_channel_size(struct davinci_mcasp *mcasp, | |||
| 448 | return 0; | 453 | return 0; |
| 449 | } | 454 | } |
| 450 | 455 | ||
| 451 | static int davinci_hw_common_param(struct davinci_mcasp *mcasp, int stream, | 456 | static int mcasp_common_hw_param(struct davinci_mcasp *mcasp, int stream, |
| 452 | int channels) | 457 | int channels) |
| 453 | { | 458 | { |
| 454 | int i; | 459 | int i; |
| @@ -524,12 +529,18 @@ static int davinci_hw_common_param(struct davinci_mcasp *mcasp, int stream, | |||
| 524 | return 0; | 529 | return 0; |
| 525 | } | 530 | } |
| 526 | 531 | ||
| 527 | static void davinci_hw_param(struct davinci_mcasp *mcasp, int stream) | 532 | static int mcasp_i2s_hw_param(struct davinci_mcasp *mcasp, int stream) |
| 528 | { | 533 | { |
| 529 | int i, active_slots; | 534 | int i, active_slots; |
| 530 | u32 mask = 0; | 535 | u32 mask = 0; |
| 531 | u32 busel = 0; | 536 | u32 busel = 0; |
| 532 | 537 | ||
| 538 | if ((mcasp->tdm_slots < 2) || (mcasp->tdm_slots > 32)) { | ||
| 539 | dev_err(mcasp->dev, "tdm slot %d not supported\n", | ||
| 540 | mcasp->tdm_slots); | ||
| 541 | return -EINVAL; | ||
| 542 | } | ||
| 543 | |||
| 533 | active_slots = (mcasp->tdm_slots > 31) ? 32 : mcasp->tdm_slots; | 544 | active_slots = (mcasp->tdm_slots > 31) ? 32 : mcasp->tdm_slots; |
| 534 | for (i = 0; i < active_slots; i++) | 545 | for (i = 0; i < active_slots; i++) |
| 535 | mask |= (1 << i); | 546 | mask |= (1 << i); |
| @@ -539,35 +550,21 @@ static void davinci_hw_param(struct davinci_mcasp *mcasp, int stream) | |||
| 539 | if (!mcasp->dat_port) | 550 | if (!mcasp->dat_port) |
| 540 | busel = TXSEL; | 551 | busel = TXSEL; |
| 541 | 552 | ||
| 542 | if (stream == SNDRV_PCM_STREAM_PLAYBACK) { | 553 | mcasp_set_reg(mcasp, DAVINCI_MCASP_TXTDM_REG, mask); |
| 543 | /* bit stream is MSB first with no delay */ | 554 | mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMT_REG, busel | TXORD); |
| 544 | /* DSP_B mode */ | 555 | mcasp_mod_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, |
| 545 | mcasp_set_reg(mcasp, DAVINCI_MCASP_TXTDM_REG, mask); | 556 | FSXMOD(mcasp->tdm_slots), FSXMOD(0x1FF)); |
| 546 | mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMT_REG, busel | TXORD); | 557 | |
| 547 | 558 | mcasp_set_reg(mcasp, DAVINCI_MCASP_RXTDM_REG, mask); | |
| 548 | if ((mcasp->tdm_slots >= 2) && (mcasp->tdm_slots <= 32)) | 559 | mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMT_REG, busel | RXORD); |
| 549 | mcasp_mod_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, | 560 | mcasp_mod_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, |
| 550 | FSXMOD(mcasp->tdm_slots), FSXMOD(0x1FF)); | 561 | FSRMOD(mcasp->tdm_slots), FSRMOD(0x1FF)); |
| 551 | else | 562 | |
| 552 | printk(KERN_ERR "playback tdm slot %d not supported\n", | 563 | return 0; |
| 553 | mcasp->tdm_slots); | ||
| 554 | } else { | ||
| 555 | /* bit stream is MSB first with no delay */ | ||
| 556 | /* DSP_B mode */ | ||
| 557 | mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMT_REG, busel | RXORD); | ||
| 558 | mcasp_set_reg(mcasp, DAVINCI_MCASP_RXTDM_REG, mask); | ||
| 559 | |||
| 560 | if ((mcasp->tdm_slots >= 2) && (mcasp->tdm_slots <= 32)) | ||
| 561 | mcasp_mod_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, | ||
| 562 | FSRMOD(mcasp->tdm_slots), FSRMOD(0x1FF)); | ||
| 563 | else | ||
| 564 | printk(KERN_ERR "capture tdm slot %d not supported\n", | ||
| 565 | mcasp->tdm_slots); | ||
| 566 | } | ||
| 567 | } | 564 | } |
| 568 | 565 | ||
| 569 | /* S/PDIF */ | 566 | /* S/PDIF */ |
| 570 | static void davinci_hw_dit_param(struct davinci_mcasp *mcasp) | 567 | static int mcasp_dit_hw_param(struct davinci_mcasp *mcasp) |
| 571 | { | 568 | { |
| 572 | /* Set the TX format : 24 bit right rotation, 32 bit slot, Pad 0 | 569 | /* Set the TX format : 24 bit right rotation, 32 bit slot, Pad 0 |
| 573 | and LSB first */ | 570 | and LSB first */ |
| @@ -589,6 +586,8 @@ static void davinci_hw_dit_param(struct davinci_mcasp *mcasp) | |||
| 589 | 586 | ||
| 590 | /* Enable the DIT */ | 587 | /* Enable the DIT */ |
| 591 | mcasp_set_bits(mcasp, DAVINCI_MCASP_TXDITCTL_REG, DITEN); | 588 | mcasp_set_bits(mcasp, DAVINCI_MCASP_TXDITCTL_REG, DITEN); |
| 589 | |||
| 590 | return 0; | ||
| 592 | } | 591 | } |
| 593 | 592 | ||
| 594 | static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream, | 593 | static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream, |
| @@ -605,13 +604,14 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream, | |||
| 605 | u8 slots = mcasp->tdm_slots; | 604 | u8 slots = mcasp->tdm_slots; |
| 606 | u8 active_serializers; | 605 | u8 active_serializers; |
| 607 | int channels; | 606 | int channels; |
| 607 | int ret; | ||
| 608 | struct snd_interval *pcm_channels = hw_param_interval(params, | 608 | struct snd_interval *pcm_channels = hw_param_interval(params, |
| 609 | SNDRV_PCM_HW_PARAM_CHANNELS); | 609 | SNDRV_PCM_HW_PARAM_CHANNELS); |
| 610 | channels = pcm_channels->min; | 610 | channels = pcm_channels->min; |
| 611 | 611 | ||
| 612 | active_serializers = (channels + slots - 1) / slots; | 612 | active_serializers = (channels + slots - 1) / slots; |
| 613 | 613 | ||
| 614 | if (davinci_hw_common_param(mcasp, substream->stream, channels) == -EINVAL) | 614 | if (mcasp_common_hw_param(mcasp, substream->stream, channels) == -EINVAL) |
| 615 | return -EINVAL; | 615 | return -EINVAL; |
| 616 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | 616 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) |
| 617 | fifo_level = mcasp->txnumevt * active_serializers; | 617 | fifo_level = mcasp->txnumevt * active_serializers; |
| @@ -619,9 +619,12 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream, | |||
| 619 | fifo_level = mcasp->rxnumevt * active_serializers; | 619 | fifo_level = mcasp->rxnumevt * active_serializers; |
| 620 | 620 | ||
| 621 | if (mcasp->op_mode == DAVINCI_MCASP_DIT_MODE) | 621 | if (mcasp->op_mode == DAVINCI_MCASP_DIT_MODE) |
| 622 | davinci_hw_dit_param(mcasp); | 622 | ret = mcasp_dit_hw_param(mcasp); |
| 623 | else | 623 | else |
| 624 | davinci_hw_param(mcasp, substream->stream); | 624 | ret = mcasp_i2s_hw_param(mcasp, substream->stream); |
| 625 | |||
| 626 | if (ret) | ||
| 627 | return ret; | ||
| 625 | 628 | ||
| 626 | switch (params_format(params)) { | 629 | switch (params_format(params)) { |
| 627 | case SNDRV_PCM_FORMAT_U8: | 630 | case SNDRV_PCM_FORMAT_U8: |
| @@ -678,19 +681,9 @@ static int davinci_mcasp_trigger(struct snd_pcm_substream *substream, | |||
| 678 | case SNDRV_PCM_TRIGGER_RESUME: | 681 | case SNDRV_PCM_TRIGGER_RESUME: |
| 679 | case SNDRV_PCM_TRIGGER_START: | 682 | case SNDRV_PCM_TRIGGER_START: |
| 680 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | 683 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: |
| 681 | ret = pm_runtime_get_sync(mcasp->dev); | ||
| 682 | if (IS_ERR_VALUE(ret)) | ||
| 683 | dev_err(mcasp->dev, "pm_runtime_get_sync() failed\n"); | ||
| 684 | davinci_mcasp_start(mcasp, substream->stream); | 684 | davinci_mcasp_start(mcasp, substream->stream); |
| 685 | break; | 685 | break; |
| 686 | |||
| 687 | case SNDRV_PCM_TRIGGER_SUSPEND: | 686 | case SNDRV_PCM_TRIGGER_SUSPEND: |
| 688 | davinci_mcasp_stop(mcasp, substream->stream); | ||
| 689 | ret = pm_runtime_put_sync(mcasp->dev); | ||
| 690 | if (IS_ERR_VALUE(ret)) | ||
| 691 | dev_err(mcasp->dev, "pm_runtime_put_sync() failed\n"); | ||
| 692 | break; | ||
| 693 | |||
| 694 | case SNDRV_PCM_TRIGGER_STOP: | 687 | case SNDRV_PCM_TRIGGER_STOP: |
| 695 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: | 688 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: |
| 696 | davinci_mcasp_stop(mcasp, substream->stream); | 689 | davinci_mcasp_stop(mcasp, substream->stream); |
