aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/davinci
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/davinci')
-rw-r--r--sound/soc/davinci/davinci-mcasp.c27
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
632static int mcasp_i2s_hw_param(struct davinci_mcasp *mcasp, int stream) 632static 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;