aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJyri Sarha <jsarha@ti.com>2015-09-09 14:27:44 -0400
committerMark Brown <broonie@kernel.org>2015-09-16 12:59:15 -0400
commitdd55ff8346a972cca1ad056c8258ee96d090633e (patch)
tree3f264b123c8ded9c269088738ebca657c6aed974
parent6ff33f3902c3b1c5d0db6b1e2c70b6d76fba357f (diff)
ASoC: davinci-mcasp: Add set_tdm_slots() support
Implements set_tdm_slot() callback for mcasp. Channel constraints are updated according to the configured tdm mask and slots each time set_tdm_slot() is called. The special case when slot width is set to zero is allowed and it means that slot width is the same as the sample width. Signed-off-by: Jyri Sarha <jsarha@ti.com> Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r--sound/soc/davinci/davinci-mcasp.c255
1 files changed, 174 insertions, 81 deletions
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c
index add6bb99661d..fa47a39fac86 100644
--- a/sound/soc/davinci/davinci-mcasp.c
+++ b/sound/soc/davinci/davinci-mcasp.c
@@ -80,6 +80,8 @@ struct davinci_mcasp {
80 80
81 /* McASP specific data */ 81 /* McASP specific data */
82 int tdm_slots; 82 int tdm_slots;
83 u32 tdm_mask[2];
84 int slot_width;
83 u8 op_mode; 85 u8 op_mode;
84 u8 num_serializer; 86 u8 num_serializer;
85 u8 *serial_dir; 87 u8 *serial_dir;
@@ -596,6 +598,84 @@ static int davinci_mcasp_set_sysclk(struct snd_soc_dai *dai, int clk_id,
596 return 0; 598 return 0;
597} 599}
598 600
601/* All serializers must have equal number of channels */
602static int davinci_mcasp_ch_constraint(struct davinci_mcasp *mcasp, int stream,
603 int serializers)
604{
605 struct snd_pcm_hw_constraint_list *cl = &mcasp->chconstr[stream];
606 unsigned int *list = (unsigned int *) cl->list;
607 int slots = mcasp->tdm_slots;
608 int i, count = 0;
609
610 if (mcasp->tdm_mask[stream])
611 slots = hweight32(mcasp->tdm_mask[stream]);
612
613 for (i = 2; i <= slots; i++)
614 list[count++] = i;
615
616 for (i = 2; i <= serializers; i++)
617 list[count++] = i*slots;
618
619 cl->count = count;
620
621 return 0;
622}
623
624static int davinci_mcasp_set_ch_constraints(struct davinci_mcasp *mcasp)
625{
626 int rx_serializers = 0, tx_serializers = 0, ret, i;
627
628 for (i = 0; i < mcasp->num_serializer; i++)
629 if (mcasp->serial_dir[i] == TX_MODE)
630 tx_serializers++;
631 else if (mcasp->serial_dir[i] == RX_MODE)
632 rx_serializers++;
633
634 ret = davinci_mcasp_ch_constraint(mcasp, SNDRV_PCM_STREAM_PLAYBACK,
635 tx_serializers);
636 if (ret)
637 return ret;
638
639 ret = davinci_mcasp_ch_constraint(mcasp, SNDRV_PCM_STREAM_CAPTURE,
640 rx_serializers);
641
642 return ret;
643}
644
645
646static int davinci_mcasp_set_tdm_slot(struct snd_soc_dai *dai,
647 unsigned int tx_mask,
648 unsigned int rx_mask,
649 int slots, int slot_width)
650{
651 struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(dai);
652
653 dev_dbg(mcasp->dev,
654 "%s() tx_mask 0x%08x rx_mask 0x%08x slots %d width %d\n",
655 __func__, tx_mask, rx_mask, slots, slot_width);
656
657 if (tx_mask >= (1<<slots) || rx_mask >= (1<<slots)) {
658 dev_err(mcasp->dev,
659 "Bad tdm mask tx: 0x%08x rx: 0x%08x slots %d\n",
660 tx_mask, rx_mask, slots);
661 return -EINVAL;
662 }
663
664 if (slot_width &&
665 (slot_width < 8 || slot_width > 32 || slot_width % 4 != 0)) {
666 dev_err(mcasp->dev, "%s: Unsupported slot_width %d\n",
667 __func__, slot_width);
668 return -EINVAL;
669 }
670
671 mcasp->tdm_slots = slots;
672 mcasp->tdm_mask[SNDRV_PCM_STREAM_PLAYBACK] = rx_mask;
673 mcasp->tdm_mask[SNDRV_PCM_STREAM_CAPTURE] = tx_mask;
674 mcasp->slot_width = slot_width;
675
676 return davinci_mcasp_set_ch_constraints(mcasp);
677}
678
599static int davinci_config_channel_size(struct davinci_mcasp *mcasp, 679static int davinci_config_channel_size(struct davinci_mcasp *mcasp,
600 int word_length) 680 int word_length)
601{ 681{
@@ -632,6 +712,9 @@ static int davinci_config_channel_size(struct davinci_mcasp *mcasp,
632 */ 712 */
633 rx_rotate = (slot_length - word_length) / 4; 713 rx_rotate = (slot_length - word_length) / 4;
634 word_length = slot_length; 714 word_length = slot_length;
715 } else if (mcasp->slot_width) {
716 rx_rotate = (mcasp->slot_width - word_length) / 4;
717 word_length = mcasp->slot_width;
635 } 718 }
636 719
637 /* mapping of the XSSZ bit-field as described in the datasheet */ 720 /* mapping of the XSSZ bit-field as described in the datasheet */
@@ -777,33 +860,50 @@ static int mcasp_i2s_hw_param(struct davinci_mcasp *mcasp, int stream,
777 860
778 /* 861 /*
779 * If more than one serializer is needed, then use them with 862 * If more than one serializer is needed, then use them with
780 * their specified tdm_slots count. Otherwise, one serializer 863 * all the specified tdm_slots. Otherwise, one serializer can
781 * can cope with the transaction using as many slots as channels 864 * cope with the transaction using just as many slots as there
782 * in the stream, requires channels symmetry 865 * are channels in the stream.
783 */ 866 */
784 active_serializers = (channels + total_slots - 1) / total_slots; 867 if (mcasp->tdm_mask[stream]) {
785 if (active_serializers == 1) 868 active_slots = hweight32(mcasp->tdm_mask[stream]);
786 active_slots = channels; 869 active_serializers = (channels + active_slots - 1) /
787 else 870 active_slots;
788 active_slots = total_slots; 871 if (active_serializers == 1) {
789 872 active_slots = channels;
790 for (i = 0; i < active_slots; i++) 873 for (i = 0; i < total_slots; i++) {
791 mask |= (1 << i); 874 if ((1 << i) & mcasp->tdm_mask[stream]) {
875 mask |= (1 << i);
876 if (--active_slots <= 0)
877 break;
878 }
879 }
880 }
881 } else {
882 active_serializers = (channels + total_slots - 1) / total_slots;
883 if (active_serializers == 1)
884 active_slots = channels;
885 else
886 active_slots = total_slots;
792 887
888 for (i = 0; i < active_slots; i++)
889 mask |= (1 << i);
890 }
793 mcasp_clr_bits(mcasp, DAVINCI_MCASP_ACLKXCTL_REG, TX_ASYNC); 891 mcasp_clr_bits(mcasp, DAVINCI_MCASP_ACLKXCTL_REG, TX_ASYNC);
794 892
795 if (!mcasp->dat_port) 893 if (!mcasp->dat_port)
796 busel = TXSEL; 894 busel = TXSEL;
797 895
798 mcasp_set_reg(mcasp, DAVINCI_MCASP_TXTDM_REG, mask); 896 if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
799 mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMT_REG, busel | TXORD); 897 mcasp_set_reg(mcasp, DAVINCI_MCASP_TXTDM_REG, mask);
800 mcasp_mod_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, 898 mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMT_REG, busel | TXORD);
801 FSXMOD(total_slots), FSXMOD(0x1FF)); 899 mcasp_mod_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG,
802 900 FSXMOD(total_slots), FSXMOD(0x1FF));
803 mcasp_set_reg(mcasp, DAVINCI_MCASP_RXTDM_REG, mask); 901 } else if (stream == SNDRV_PCM_STREAM_CAPTURE) {
804 mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMT_REG, busel | RXORD); 902 mcasp_set_reg(mcasp, DAVINCI_MCASP_RXTDM_REG, mask);
805 mcasp_mod_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, 903 mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMT_REG, busel | RXORD);
806 FSRMOD(total_slots), FSRMOD(0x1FF)); 904 mcasp_mod_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG,
905 FSRMOD(total_slots), FSRMOD(0x1FF));
906 }
807 907
808 return 0; 908 return 0;
809} 909}
@@ -923,6 +1023,9 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream,
923 int sbits = params_width(params); 1023 int sbits = params_width(params);
924 int ppm, div; 1024 int ppm, div;
925 1025
1026 if (mcasp->slot_width)
1027 sbits = mcasp->slot_width;
1028
926 div = davinci_mcasp_calc_clk_div(mcasp, rate*sbits*slots, 1029 div = davinci_mcasp_calc_clk_div(mcasp, rate*sbits*slots,
927 &ppm); 1030 &ppm);
928 if (ppm) 1031 if (ppm)
@@ -1028,6 +1131,9 @@ static int davinci_mcasp_hw_rule_rate(struct snd_pcm_hw_params *params,
1028 struct snd_interval range; 1131 struct snd_interval range;
1029 int i; 1132 int i;
1030 1133
1134 if (rd->mcasp->slot_width)
1135 sbits = rd->mcasp->slot_width;
1136
1031 snd_interval_any(&range); 1137 snd_interval_any(&range);
1032 range.empty = 1; 1138 range.empty = 1;
1033 1139
@@ -1070,10 +1176,14 @@ static int davinci_mcasp_hw_rule_format(struct snd_pcm_hw_params *params,
1070 1176
1071 for (i = 0; i < SNDRV_PCM_FORMAT_LAST; i++) { 1177 for (i = 0; i < SNDRV_PCM_FORMAT_LAST; i++) {
1072 if (snd_mask_test(fmt, i)) { 1178 if (snd_mask_test(fmt, i)) {
1073 uint bclk_freq = snd_pcm_format_width(i)*slots*rate; 1179 uint sbits = snd_pcm_format_width(i);
1074 int ppm; 1180 int ppm;
1075 1181
1076 davinci_mcasp_calc_clk_div(rd->mcasp, bclk_freq, &ppm); 1182 if (rd->mcasp->slot_width)
1183 sbits = rd->mcasp->slot_width;
1184
1185 davinci_mcasp_calc_clk_div(rd->mcasp, sbits*slots*rate,
1186 &ppm);
1077 if (abs(ppm) < DAVINCI_MAX_RATE_ERROR_PPM) { 1187 if (abs(ppm) < DAVINCI_MAX_RATE_ERROR_PPM) {
1078 snd_mask_set(&nfmt, i); 1188 snd_mask_set(&nfmt, i);
1079 count++; 1189 count++;
@@ -1095,6 +1205,10 @@ static int davinci_mcasp_startup(struct snd_pcm_substream *substream,
1095 &mcasp->ruledata[substream->stream]; 1205 &mcasp->ruledata[substream->stream];
1096 u32 max_channels = 0; 1206 u32 max_channels = 0;
1097 int i, dir; 1207 int i, dir;
1208 int tdm_slots = mcasp->tdm_slots;
1209
1210 if (mcasp->tdm_mask[substream->stream])
1211 tdm_slots = hweight32(mcasp->tdm_mask[substream->stream]);
1098 1212
1099 mcasp->substreams[substream->stream] = substream; 1213 mcasp->substreams[substream->stream] = substream;
1100 1214
@@ -1115,7 +1229,7 @@ static int davinci_mcasp_startup(struct snd_pcm_substream *substream,
1115 max_channels++; 1229 max_channels++;
1116 } 1230 }
1117 ruledata->serializers = max_channels; 1231 ruledata->serializers = max_channels;
1118 max_channels *= mcasp->tdm_slots; 1232 max_channels *= tdm_slots;
1119 /* 1233 /*
1120 * If the already active stream has less channels than the calculated 1234 * If the already active stream has less channels than the calculated
1121 * limnit based on the seirializers * tdm_slots, we need to use that as 1235 * limnit based on the seirializers * tdm_slots, we need to use that as
@@ -1125,15 +1239,25 @@ static int davinci_mcasp_startup(struct snd_pcm_substream *substream,
1125 */ 1239 */
1126 if (mcasp->channels && mcasp->channels < max_channels) 1240 if (mcasp->channels && mcasp->channels < max_channels)
1127 max_channels = mcasp->channels; 1241 max_channels = mcasp->channels;
1242 /*
1243 * But we can always allow channels upto the amount of
1244 * the available tdm_slots.
1245 */
1246 if (max_channels < tdm_slots)
1247 max_channels = tdm_slots;
1128 1248
1129 snd_pcm_hw_constraint_minmax(substream->runtime, 1249 snd_pcm_hw_constraint_minmax(substream->runtime,
1130 SNDRV_PCM_HW_PARAM_CHANNELS, 1250 SNDRV_PCM_HW_PARAM_CHANNELS,
1131 2, max_channels); 1251 2, max_channels);
1132 1252
1133 if (mcasp->chconstr[substream->stream].count) 1253 snd_pcm_hw_constraint_list(substream->runtime,
1134 snd_pcm_hw_constraint_list(substream->runtime, 1254 0, SNDRV_PCM_HW_PARAM_CHANNELS,
1135 0, SNDRV_PCM_HW_PARAM_CHANNELS, 1255 &mcasp->chconstr[substream->stream]);
1136 &mcasp->chconstr[substream->stream]); 1256
1257 if (mcasp->slot_width)
1258 snd_pcm_hw_constraint_minmax(substream->runtime,
1259 SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
1260 8, mcasp->slot_width);
1137 1261
1138 /* 1262 /*
1139 * If we rely on implicit BCLK divider setting we should 1263 * If we rely on implicit BCLK divider setting we should
@@ -1185,6 +1309,7 @@ static const struct snd_soc_dai_ops davinci_mcasp_dai_ops = {
1185 .set_fmt = davinci_mcasp_set_dai_fmt, 1309 .set_fmt = davinci_mcasp_set_dai_fmt,
1186 .set_clkdiv = davinci_mcasp_set_clkdiv, 1310 .set_clkdiv = davinci_mcasp_set_clkdiv,
1187 .set_sysclk = davinci_mcasp_set_sysclk, 1311 .set_sysclk = davinci_mcasp_set_sysclk,
1312 .set_tdm_slot = davinci_mcasp_set_tdm_slot,
1188}; 1313};
1189 1314
1190static int davinci_mcasp_dai_probe(struct snd_soc_dai *dai) 1315static int davinci_mcasp_dai_probe(struct snd_soc_dai *dai)
@@ -1514,59 +1639,6 @@ nodata:
1514 return pdata; 1639 return pdata;
1515} 1640}
1516 1641
1517/* All serializers must have equal number of channels */
1518static int davinci_mcasp_ch_constraint(struct davinci_mcasp *mcasp,
1519 struct snd_pcm_hw_constraint_list *cl,
1520 int serializers)
1521{
1522 unsigned int *list;
1523 int i, count = 0;
1524
1525 if (serializers <= 1)
1526 return 0;
1527
1528 list = devm_kzalloc(mcasp->dev, sizeof(unsigned int) *
1529 (mcasp->tdm_slots + serializers - 2),
1530 GFP_KERNEL);
1531 if (!list)
1532 return -ENOMEM;
1533
1534 for (i = 2; i <= mcasp->tdm_slots; i++)
1535 list[count++] = i;
1536
1537 for (i = 2; i <= serializers; i++)
1538 list[count++] = i*mcasp->tdm_slots;
1539
1540 cl->count = count;
1541 cl->list = list;
1542
1543 return 0;
1544}
1545
1546
1547static int davinci_mcasp_init_ch_constraints(struct davinci_mcasp *mcasp)
1548{
1549 int rx_serializers = 0, tx_serializers = 0, ret, i;
1550
1551 for (i = 0; i < mcasp->num_serializer; i++)
1552 if (mcasp->serial_dir[i] == TX_MODE)
1553 tx_serializers++;
1554 else if (mcasp->serial_dir[i] == RX_MODE)
1555 rx_serializers++;
1556
1557 ret = davinci_mcasp_ch_constraint(mcasp, &mcasp->chconstr[
1558 SNDRV_PCM_STREAM_PLAYBACK],
1559 tx_serializers);
1560 if (ret)
1561 return ret;
1562
1563 ret = davinci_mcasp_ch_constraint(mcasp, &mcasp->chconstr[
1564 SNDRV_PCM_STREAM_CAPTURE],
1565 rx_serializers);
1566
1567 return ret;
1568}
1569
1570enum { 1642enum {
1571 PCM_EDMA, 1643 PCM_EDMA,
1572 PCM_SDMA, 1644 PCM_SDMA,
@@ -1783,7 +1855,28 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
1783 mcasp->fifo_base = DAVINCI_MCASP_V3_AFIFO_BASE; 1855 mcasp->fifo_base = DAVINCI_MCASP_V3_AFIFO_BASE;
1784 } 1856 }
1785 1857
1786 ret = davinci_mcasp_init_ch_constraints(mcasp); 1858 /* Allocate memory for long enough list for all possible
1859 * scenarios. Maximum number tdm slots is 32 and there cannot
1860 * be more serializers than given in the configuration. The
1861 * serializer directions could be taken into account, but it
1862 * would make code much more complex and save only couple of
1863 * bytes.
1864 */
1865 mcasp->chconstr[SNDRV_PCM_STREAM_PLAYBACK].list =
1866 devm_kzalloc(mcasp->dev, sizeof(unsigned int) *
1867 (32 + mcasp->num_serializer - 2),
1868 GFP_KERNEL);
1869
1870 mcasp->chconstr[SNDRV_PCM_STREAM_CAPTURE].list =
1871 devm_kzalloc(mcasp->dev, sizeof(unsigned int) *
1872 (32 + mcasp->num_serializer - 2),
1873 GFP_KERNEL);
1874
1875 if (!mcasp->chconstr[SNDRV_PCM_STREAM_PLAYBACK].list ||
1876 !mcasp->chconstr[SNDRV_PCM_STREAM_CAPTURE].list)
1877 return -ENOMEM;
1878
1879 ret = davinci_mcasp_set_ch_constraints(mcasp);
1787 if (ret) 1880 if (ret)
1788 goto err; 1881 goto err;
1789 1882