@@ -579,6 +579,38 @@ static int skl_tplg_unload_pipe_modules(struct skl_dev *skl,
579579	return  ret ;
580580}
581581
582+ static  bool  skl_tplg_is_multi_fmt (struct  skl_dev  * skl , struct  skl_pipe  * pipe )
583+ {
584+ 	struct  skl_pipe_fmt  * cur_fmt ;
585+ 	struct  skl_pipe_fmt  * next_fmt ;
586+ 	int  i ;
587+ 
588+ 	if  (pipe -> nr_cfgs  <= 1 )
589+ 		return  false;
590+ 
591+ 	if  (pipe -> conn_type  !=  SKL_PIPE_CONN_TYPE_FE )
592+ 		return  true;
593+ 
594+ 	for  (i  =  0 ; i  <  pipe -> nr_cfgs  -  1 ; i ++ ) {
595+ 		if  (pipe -> direction  ==  SNDRV_PCM_STREAM_PLAYBACK ) {
596+ 			cur_fmt  =  & pipe -> configs [i ].out_fmt ;
597+ 			next_fmt  =  & pipe -> configs [i  +  1 ].out_fmt ;
598+ 		} else  {
599+ 			cur_fmt  =  & pipe -> configs [i ].in_fmt ;
600+ 			next_fmt  =  & pipe -> configs [i  +  1 ].in_fmt ;
601+ 		}
602+ 
603+ 		if  (!CHECK_HW_PARAMS (cur_fmt -> channels , cur_fmt -> freq ,
604+ 				     cur_fmt -> bps ,
605+ 				     next_fmt -> channels ,
606+ 				     next_fmt -> freq ,
607+ 				     next_fmt -> bps ))
608+ 			return  true;
609+ 	}
610+ 
611+ 	return  false;
612+ }
613+ 
582614/* 
583615 * Here, we select pipe format based on the pipe type and pipe 
584616 * direction to determine the current config index for the pipeline. 
@@ -601,6 +633,14 @@ skl_tplg_get_pipe_config(struct skl_dev *skl, struct skl_module_cfg *mconfig)
601633		return  0 ;
602634	}
603635
636+ 	if  (skl_tplg_is_multi_fmt (skl , pipe )) {
637+ 		pipe -> cur_config_idx  =  pipe -> pipe_config_idx ;
638+ 		pipe -> memory_pages  =  pconfig -> mem_pages ;
639+ 		dev_dbg (skl -> dev , "found pipe config idx:%d\n" ,
640+ 			pipe -> cur_config_idx );
641+ 		return  0 ;
642+ 	}
643+ 
604644	if  (pipe -> conn_type  ==  SKL_PIPE_CONN_TYPE_NONE ) {
605645		dev_dbg (skl -> dev , "No conn_type detected, take 0th config\n" );
606646		pipe -> cur_config_idx  =  0 ;
@@ -1315,6 +1355,56 @@ static int skl_tplg_pga_event(struct snd_soc_dapm_widget *w,
13151355	return  0 ;
13161356}
13171357
1358+ static  int  skl_tplg_multi_config_set_get (struct  snd_kcontrol  * kcontrol ,
1359+ 					 struct  snd_ctl_elem_value  * ucontrol ,
1360+ 					 bool  is_set )
1361+ {
1362+ 	struct  snd_soc_component  * component  = 
1363+ 		snd_soc_kcontrol_component (kcontrol );
1364+ 	struct  hdac_bus  * bus  =  snd_soc_component_get_drvdata (component );
1365+ 	struct  skl_dev  * skl  =  bus_to_skl (bus );
1366+ 	struct  skl_pipeline  * ppl ;
1367+ 	struct  skl_pipe  * pipe  =  NULL ;
1368+ 	struct  soc_enum  * ec  =  (struct  soc_enum  * )kcontrol -> private_value ;
1369+ 	u32  * pipe_id ;
1370+ 
1371+ 	if  (!ec )
1372+ 		return  - EINVAL ;
1373+ 
1374+ 	if  (is_set  &&  ucontrol -> value .enumerated .item [0 ] >  ec -> items )
1375+ 		return  - EINVAL ;
1376+ 
1377+ 	pipe_id  =  ec -> dobj .private ;
1378+ 
1379+ 	list_for_each_entry (ppl , & skl -> ppl_list , node ) {
1380+ 		if  (ppl -> pipe -> ppl_id  ==  * pipe_id ) {
1381+ 			pipe  =  ppl -> pipe ;
1382+ 			break ;
1383+ 		}
1384+ 	}
1385+ 	if  (!pipe )
1386+ 		return  - EIO ;
1387+ 
1388+ 	if  (is_set )
1389+ 		pipe -> pipe_config_idx  =  ucontrol -> value .enumerated .item [0 ];
1390+ 	else 
1391+ 		ucontrol -> value .enumerated .item [0 ]  =   pipe -> pipe_config_idx ;
1392+ 
1393+ 	return  0 ;
1394+ }
1395+ 
1396+ static  int  skl_tplg_multi_config_get (struct  snd_kcontrol  * kcontrol ,
1397+ 				     struct  snd_ctl_elem_value  * ucontrol )
1398+ {
1399+ 	return  skl_tplg_multi_config_set_get (kcontrol , ucontrol , false);
1400+ }
1401+ 
1402+ static  int  skl_tplg_multi_config_set (struct  snd_kcontrol  * kcontrol ,
1403+ 				     struct  snd_ctl_elem_value  * ucontrol )
1404+ {
1405+ 	return  skl_tplg_multi_config_set_get (kcontrol , ucontrol , true);
1406+ }
1407+ 
13181408static  int  skl_tplg_tlv_control_get (struct  snd_kcontrol  * kcontrol ,
13191409			unsigned int   __user  * data , unsigned int   size )
13201410{
@@ -1854,6 +1944,11 @@ static const struct snd_soc_tplg_kcontrol_ops skl_tplg_kcontrol_ops[] = {
18541944		.get  =  skl_tplg_mic_control_get ,
18551945		.put  =  skl_tplg_mic_control_set ,
18561946	},
1947+ 	{
1948+ 		.id  =  SKL_CONTROL_TYPE_MULTI_IO_SELECT ,
1949+ 		.get  =  skl_tplg_multi_config_get ,
1950+ 		.put  =  skl_tplg_multi_config_set ,
1951+ 	},
18571952};
18581953
18591954static  int  skl_tplg_fill_pipe_cfg (struct  device  * dev ,
0 commit comments