diff options
Diffstat (limited to 'sound/soc/davinci')
-rw-r--r-- | sound/soc/davinci/davinci-mcasp.c | 27 |
1 files changed, 22 insertions, 5 deletions
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index 10ae75e19d99..a9822c7bbb0b 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c | |||
@@ -629,13 +629,29 @@ static int mcasp_common_hw_param(struct davinci_mcasp *mcasp, int stream, | |||
629 | return 0; | 629 | return 0; |
630 | } | 630 | } |
631 | 631 | ||
632 | static int mcasp_i2s_hw_param(struct davinci_mcasp *mcasp, int stream) | 632 | static int mcasp_i2s_hw_param(struct davinci_mcasp *mcasp, int stream, |
633 | int channels) | ||
633 | { | 634 | { |
634 | int i, active_slots; | 635 | int i, active_slots; |
636 | int total_slots; | ||
637 | int active_serializers; | ||
635 | u32 mask = 0; | 638 | u32 mask = 0; |
636 | u32 busel = 0; | 639 | u32 busel = 0; |
637 | 640 | ||
638 | active_slots = mcasp->tdm_slots; | 641 | total_slots = mcasp->tdm_slots; |
642 | |||
643 | /* | ||
644 | * If more than one serializer is needed, then use them with | ||
645 | * their specified tdm_slots count. Otherwise, one serializer | ||
646 | * can cope with the transaction using as many slots as channels | ||
647 | * in the stream, requires channels symmetry | ||
648 | */ | ||
649 | active_serializers = (channels + total_slots - 1) / total_slots; | ||
650 | if (active_serializers == 1) | ||
651 | active_slots = channels; | ||
652 | else | ||
653 | active_slots = total_slots; | ||
654 | |||
639 | for (i = 0; i < active_slots; i++) | 655 | for (i = 0; i < active_slots; i++) |
640 | mask |= (1 << i); | 656 | mask |= (1 << i); |
641 | 657 | ||
@@ -647,12 +663,12 @@ static int mcasp_i2s_hw_param(struct davinci_mcasp *mcasp, int stream) | |||
647 | mcasp_set_reg(mcasp, DAVINCI_MCASP_TXTDM_REG, mask); | 663 | mcasp_set_reg(mcasp, DAVINCI_MCASP_TXTDM_REG, mask); |
648 | mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMT_REG, busel | TXORD); | 664 | mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMT_REG, busel | TXORD); |
649 | mcasp_mod_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, | 665 | mcasp_mod_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, |
650 | FSXMOD(active_slots), FSXMOD(0x1FF)); | 666 | FSXMOD(total_slots), FSXMOD(0x1FF)); |
651 | 667 | ||
652 | mcasp_set_reg(mcasp, DAVINCI_MCASP_RXTDM_REG, mask); | 668 | mcasp_set_reg(mcasp, DAVINCI_MCASP_RXTDM_REG, mask); |
653 | mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMT_REG, busel | RXORD); | 669 | mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMT_REG, busel | RXORD); |
654 | mcasp_mod_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, | 670 | mcasp_mod_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, |
655 | FSRMOD(active_slots), FSRMOD(0x1FF)); | 671 | FSRMOD(total_slots), FSRMOD(0x1FF)); |
656 | 672 | ||
657 | return 0; | 673 | return 0; |
658 | } | 674 | } |
@@ -766,7 +782,8 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream, | |||
766 | if (mcasp->op_mode == DAVINCI_MCASP_DIT_MODE) | 782 | if (mcasp->op_mode == DAVINCI_MCASP_DIT_MODE) |
767 | ret = mcasp_dit_hw_param(mcasp, params_rate(params)); | 783 | ret = mcasp_dit_hw_param(mcasp, params_rate(params)); |
768 | else | 784 | else |
769 | ret = mcasp_i2s_hw_param(mcasp, substream->stream); | 785 | ret = mcasp_i2s_hw_param(mcasp, substream->stream, |
786 | channels); | ||
770 | 787 | ||
771 | if (ret) | 788 | if (ret) |
772 | return ret; | 789 | return ret; |