@@ -487,13 +487,18 @@ static int fsl_sai_hw_params(struct snd_pcm_substream *substream,
487487 unsigned int ofs = sai -> soc_data -> reg_offset ;
488488 bool tx = substream -> stream == SNDRV_PCM_STREAM_PLAYBACK ;
489489 unsigned int channels = params_channels (params );
490+ struct snd_dmaengine_dai_dma_data * dma_params ;
491+ struct fsl_sai_dl_cfg * dl_cfg = sai -> dl_cfg ;
490492 u32 word_width = params_width (params );
493+ int trce_mask = 0 , dl_cfg_idx = 0 ;
494+ int dl_cfg_cnt = sai -> dl_cfg_cnt ;
495+ u32 dl_type = FSL_SAI_DL_I2S ;
491496 u32 val_cr4 = 0 , val_cr5 = 0 ;
492497 u32 slots = (channels == 1 ) ? 2 : channels ;
493498 u32 slot_width = word_width ;
494499 int adir = tx ? RX : TX ;
495500 u32 pins , bclk ;
496- int ret ;
501+ int ret , i ;
497502
498503 if (sai -> slots )
499504 slots = sai -> slots ;
@@ -507,8 +512,22 @@ static int fsl_sai_hw_params(struct snd_pcm_substream *substream,
507512 * PDM mode, channels are independent
508513 * each channels are on one dataline/FIFO.
509514 */
510- if (sai -> is_pdm_mode )
515+ if (sai -> is_pdm_mode ) {
511516 pins = channels ;
517+ dl_type = FSL_SAI_DL_PDM ;
518+ }
519+
520+ for (i = 0 ; i < dl_cfg_cnt ; i ++ ) {
521+ if (dl_cfg [i ].type == dl_type && dl_cfg [i ].pins [tx ] == pins ) {
522+ dl_cfg_idx = i ;
523+ break ;
524+ }
525+ }
526+
527+ if (hweight8 (dl_cfg [dl_cfg_idx ].mask [tx ]) < pins ) {
528+ dev_err (cpu_dai -> dev , "channel not supported\n" );
529+ return - EINVAL ;
530+ }
512531
513532 bclk = params_rate (params ) * (sai -> bclk_ratio ? sai -> bclk_ratio : slots * slot_width );
514533
@@ -571,13 +590,28 @@ static int fsl_sai_hw_params(struct snd_pcm_substream *substream,
571590 FSL_SAI_CR5_FBT_MASK , val_cr5 );
572591 }
573592
574- if (sai -> soc_data -> pins > 1 )
593+ if (hweight8 (dl_cfg [dl_cfg_idx ].mask [tx ]) <= 1 )
594+ regmap_update_bits (sai -> regmap , FSL_SAI_xCR4 (tx , ofs ),
595+ FSL_SAI_CR4_FCOMB_MASK , 0 );
596+ else
575597 regmap_update_bits (sai -> regmap , FSL_SAI_xCR4 (tx , ofs ),
576598 FSL_SAI_CR4_FCOMB_MASK , FSL_SAI_CR4_FCOMB_SOFT );
577599
600+ dma_params = tx ? & sai -> dma_params_tx : & sai -> dma_params_rx ;
601+ dma_params -> addr = sai -> res -> start + FSL_SAI_xDR0 (tx ) +
602+ dl_cfg [dl_cfg_idx ].start_off [tx ] * 0x4 ;
603+
604+ /* Find a proper tcre setting */
605+ for (i = 0 ; i < sai -> soc_data -> pins ; i ++ ) {
606+ trce_mask = (1 << (i + 1 )) - 1 ;
607+ if (hweight8 (dl_cfg [dl_cfg_idx ].mask [tx ] & trce_mask ) == pins )
608+ break ;
609+ }
610+
578611 regmap_update_bits (sai -> regmap , FSL_SAI_xCR3 (tx , ofs ),
579612 FSL_SAI_CR3_TRCE_MASK ,
580- FSL_SAI_CR3_TRCE ((1 << pins ) - 1 ));
613+ FSL_SAI_CR3_TRCE ((dl_cfg [dl_cfg_idx ].mask [tx ] & trce_mask )));
614+
581615 regmap_update_bits (sai -> regmap , FSL_SAI_xCR4 (tx , ofs ),
582616 FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK |
583617 FSL_SAI_CR4_CHMOD_MASK ,
@@ -1068,6 +1102,118 @@ static int fsl_sai_check_version(struct device *dev)
10681102 return 0 ;
10691103}
10701104
1105+ /*
1106+ * Calculate the offset between first two datalines, don't
1107+ * different offset in one case.
1108+ */
1109+ static unsigned int fsl_sai_calc_dl_off (unsigned long dl_mask )
1110+ {
1111+ int fbidx , nbidx , offset ;
1112+
1113+ fbidx = find_first_bit (& dl_mask , FSL_SAI_DL_NUM );
1114+ nbidx = find_next_bit (& dl_mask , FSL_SAI_DL_NUM , fbidx + 1 );
1115+ offset = nbidx - fbidx - 1 ;
1116+
1117+ return (offset < 0 || offset >= (FSL_SAI_DL_NUM - 1 ) ? 0 : offset );
1118+ }
1119+
1120+ /*
1121+ * read the fsl,dataline property from dts file.
1122+ * It has 3 value for each configuration, first one means the type:
1123+ * I2S(1) or PDM(2), second one is dataline mask for 'rx', third one is
1124+ * dataline mask for 'tx'. for example
1125+ *
1126+ * fsl,dataline = <1 0xff 0xff 2 0xff 0x11>,
1127+ *
1128+ * It means I2S type rx mask is 0xff, tx mask is 0xff, PDM type
1129+ * rx mask is 0xff, tx mask is 0x11 (dataline 1 and 4 enabled).
1130+ *
1131+ */
1132+ static int fsl_sai_read_dlcfg (struct fsl_sai * sai )
1133+ {
1134+ struct platform_device * pdev = sai -> pdev ;
1135+ struct device_node * np = pdev -> dev .of_node ;
1136+ struct device * dev = & pdev -> dev ;
1137+ int ret , elems , i , index , num_cfg ;
1138+ char * propname = "fsl,dataline" ;
1139+ struct fsl_sai_dl_cfg * cfg ;
1140+ unsigned long dl_mask ;
1141+ unsigned int soc_dl ;
1142+ u32 rx , tx , type ;
1143+
1144+ elems = of_property_count_u32_elems (np , propname );
1145+
1146+ if (elems <= 0 ) {
1147+ elems = 0 ;
1148+ } else if (elems % 3 ) {
1149+ dev_err (dev , "Number of elements must be divisible to 3.\n" );
1150+ return - EINVAL ;
1151+ }
1152+
1153+ num_cfg = elems / 3 ;
1154+ /* Add one more for default value */
1155+ cfg = devm_kzalloc (& pdev -> dev , (num_cfg + 1 ) * sizeof (* cfg ), GFP_KERNEL );
1156+ if (!cfg )
1157+ return - ENOMEM ;
1158+
1159+ /* Consider default value "0 0xFF 0xFF" if property is missing */
1160+ soc_dl = BIT (sai -> soc_data -> pins ) - 1 ;
1161+ cfg [0 ].type = FSL_SAI_DL_DEFAULT ;
1162+ cfg [0 ].pins [0 ] = sai -> soc_data -> pins ;
1163+ cfg [0 ].mask [0 ] = soc_dl ;
1164+ cfg [0 ].start_off [0 ] = 0 ;
1165+ cfg [0 ].next_off [0 ] = 0 ;
1166+
1167+ cfg [0 ].pins [1 ] = sai -> soc_data -> pins ;
1168+ cfg [0 ].mask [1 ] = soc_dl ;
1169+ cfg [0 ].start_off [1 ] = 0 ;
1170+ cfg [0 ].next_off [1 ] = 0 ;
1171+ for (i = 1 , index = 0 ; i < num_cfg + 1 ; i ++ ) {
1172+ /*
1173+ * type of dataline
1174+ * 0 means default mode
1175+ * 1 means I2S mode
1176+ * 2 means PDM mode
1177+ */
1178+ ret = of_property_read_u32_index (np , propname , index ++ , & type );
1179+ if (ret )
1180+ return - EINVAL ;
1181+
1182+ ret = of_property_read_u32_index (np , propname , index ++ , & rx );
1183+ if (ret )
1184+ return - EINVAL ;
1185+
1186+ ret = of_property_read_u32_index (np , propname , index ++ , & tx );
1187+ if (ret )
1188+ return - EINVAL ;
1189+
1190+ if ((rx & ~soc_dl ) || (tx & ~soc_dl )) {
1191+ dev_err (dev , "dataline cfg[%d] setting error, mask is 0x%x\n" , i , soc_dl );
1192+ return - EINVAL ;
1193+ }
1194+
1195+ rx = rx & soc_dl ;
1196+ tx = tx & soc_dl ;
1197+
1198+ cfg [i ].type = type ;
1199+ cfg [i ].pins [0 ] = hweight8 (rx );
1200+ cfg [i ].mask [0 ] = rx ;
1201+ dl_mask = rx ;
1202+ cfg [i ].start_off [0 ] = find_first_bit (& dl_mask , FSL_SAI_DL_NUM );
1203+ cfg [i ].next_off [0 ] = fsl_sai_calc_dl_off (rx );
1204+
1205+ cfg [i ].pins [1 ] = hweight8 (tx );
1206+ cfg [i ].mask [1 ] = tx ;
1207+ dl_mask = tx ;
1208+ cfg [i ].start_off [1 ] = find_first_bit (& dl_mask , FSL_SAI_DL_NUM );
1209+ cfg [i ].next_off [1 ] = fsl_sai_calc_dl_off (tx );
1210+ }
1211+
1212+ sai -> dl_cfg = cfg ;
1213+ sai -> dl_cfg_cnt = num_cfg + 1 ;
1214+ return 0 ;
1215+ }
1216+
10711217static int fsl_sai_runtime_suspend (struct device * dev );
10721218static int fsl_sai_runtime_resume (struct device * dev );
10731219
@@ -1134,6 +1280,13 @@ static int fsl_sai_probe(struct platform_device *pdev)
11341280 else
11351281 sai -> mclk_clk [0 ] = sai -> bus_clk ;
11361282
1283+ /* read dataline mask for rx and tx*/
1284+ ret = fsl_sai_read_dlcfg (sai );
1285+ if (ret < 0 ) {
1286+ dev_err (dev , "failed to read dlcfg %d\n" , ret );
1287+ return ret ;
1288+ }
1289+
11371290 irq = platform_get_irq (pdev , 0 );
11381291 if (irq < 0 )
11391292 return irq ;
0 commit comments