@@ -269,6 +269,30 @@ static int sof_control_load_volume(struct snd_soc_component *scomp,
269269 return 0 ;
270270}
271271
272+ static int sof_control_load_bytes (struct snd_soc_component * scomp ,
273+ struct snd_sof_control * scontrol ,
274+ struct snd_kcontrol_new * kc ,
275+ struct snd_soc_tplg_ctl_hdr * hdr )
276+ {
277+ struct snd_sof_dev * sdev = snd_soc_component_get_drvdata (scomp );
278+ struct sof_ipc_ctrl_data * cdata ;
279+
280+ /* init the get/put bytes data */
281+ scontrol -> size = SOF_IPC_MSG_MAX_SIZE ;
282+ scontrol -> control_data = kzalloc (scontrol -> size , GFP_KERNEL );
283+ cdata = scontrol -> control_data ;
284+ if (!scontrol -> control_data )
285+ return - ENOMEM ;
286+
287+ scontrol -> comp_id = sdev -> next_comp_id ;
288+ scontrol -> cmd = SOF_CTRL_CMD_BINARY ;
289+
290+ dev_dbg (sdev -> dev , "tplg: load kcontrol index %d chans %d\n" ,
291+ scontrol -> comp_id , scontrol -> num_channels );
292+
293+ return 0 ;
294+ }
295+
272296/*
273297 * Topology Token Parsing.
274298 * New tokens should be added to headers and parsing tables below.
@@ -381,6 +405,16 @@ static const struct sof_topology_token src_tokens[] = {
381405static const struct sof_topology_token tone_tokens [] = {
382406};
383407
408+ /* EQ FIR */
409+ /*
410+ static const struct sof_topology_token eq_fir_tokens[] = {
411+ };
412+ */
413+
414+ /* EQ IIR */
415+ static const struct sof_topology_token eq_iir_tokens [] = {
416+ };
417+
384418/* PCM */
385419static const struct sof_topology_token pcm_tokens [] = {
386420 {SOF_TKN_PCM_DMAC_CONFIG , SND_SOC_TPLG_TUPLE_TYPE_WORD , get_token_u32 ,
@@ -707,6 +741,7 @@ static int sof_control_load(struct snd_soc_component *scomp, int index,
707741 struct snd_soc_tplg_ctl_hdr * hdr )
708742{
709743 struct soc_mixer_control * sm ;
744+ struct soc_bytes_ext * sbe ;
710745 struct snd_sof_dev * sdev = snd_soc_component_get_drvdata (scomp );
711746 struct snd_soc_dobj * dobj = NULL ;
712747 struct snd_sof_control * scontrol ;
@@ -730,8 +765,12 @@ static int sof_control_load(struct snd_soc_component *scomp, int index,
730765 dobj = & sm -> dobj ;
731766 ret = sof_control_load_volume (scomp , scontrol , kc , hdr );
732767 break ;
733- case SND_SOC_TPLG_CTL_ENUM :
734768 case SND_SOC_TPLG_CTL_BYTES :
769+ sbe = (struct soc_bytes_ext * )kc -> private_value ;
770+ dobj = & sbe -> dobj ;
771+ ret = sof_control_load_bytes (scomp , scontrol , kc , hdr );
772+ break ;
773+ case SND_SOC_TPLG_CTL_ENUM :
735774 case SND_SOC_TPLG_CTL_ENUM_VALUE :
736775 case SND_SOC_TPLG_CTL_RANGE :
737776 case SND_SOC_TPLG_CTL_STROBE :
@@ -1306,6 +1345,66 @@ static int sof_widget_load_siggen(struct snd_soc_component *scomp, int index,
13061345 kfree (tone );
13071346 return ret ;
13081347}
1348+ /*
1349+ * Effect Topology. Only IIR equalizer is supported at this moment.
1350+ * TODO: Need to add also FIR support and have a way to add other
1351+ * effects and enhancements.
1352+ */
1353+
1354+ static int sof_widget_load_effect (struct snd_soc_component * scomp , int index ,
1355+ struct snd_sof_widget * swidget ,
1356+ struct snd_soc_tplg_dapm_widget * tw ,
1357+ struct sof_ipc_comp_reply * r )
1358+ {
1359+ struct snd_sof_dev * sdev = snd_soc_component_get_drvdata (scomp );
1360+ struct snd_soc_tplg_private * private = & tw -> priv ;
1361+ struct sof_ipc_comp_eq_iir * eq ;
1362+ int ret ;
1363+
1364+ eq = kzalloc (sizeof (* eq ), GFP_KERNEL );
1365+ if (!eq )
1366+ return - ENOMEM ;
1367+
1368+ /* configure IIR EQ IPC message */
1369+ eq -> comp .hdr .size = sizeof (* eq );
1370+ eq -> comp .hdr .cmd = SOF_IPC_GLB_TPLG_MSG | SOF_IPC_TPLG_COMP_NEW ;
1371+ eq -> comp .id = swidget -> comp_id ;
1372+ eq -> comp .pipeline_id = index ;
1373+
1374+ eq -> comp .type = SOF_COMP_EQ_IIR ;
1375+ ret = sof_parse_tokens (scomp , eq , eq_iir_tokens ,
1376+ ARRAY_SIZE (eq_iir_tokens ), private -> array ,
1377+ le32_to_cpu (private -> size ));
1378+ if (ret ) {
1379+ dev_err (sdev -> dev , "error: parse EQ tokens failed %d\n" ,
1380+ private -> size );
1381+ goto err ;
1382+ }
1383+
1384+ ret = sof_parse_tokens (scomp , & eq -> config , comp_tokens ,
1385+ ARRAY_SIZE (comp_tokens ), private -> array ,
1386+ le32_to_cpu (private -> size ));
1387+ if (ret ) {
1388+ dev_err (sdev -> dev , "error: parse EQ.cfg tokens failed %d\n" ,
1389+ le32_to_cpu (private -> size ));
1390+ goto err ;
1391+ }
1392+
1393+ dev_dbg (sdev -> dev , "eq iir %s created\n" , swidget -> widget -> name );
1394+
1395+ sof_dbg_comp_config (scomp , & eq -> config );
1396+
1397+ swidget -> private = (void * )eq ;
1398+
1399+ ret = sof_ipc_tx_message (sdev -> ipc , eq -> comp .hdr .cmd , eq ,
1400+ sizeof (* eq ), r , sizeof (* r ));
1401+
1402+ if (ret >= 0 )
1403+ return ret ;
1404+ err :
1405+ kfree (eq );
1406+ return ret ;
1407+ }
13091408
13101409/*
13111410 * Generic widget loader.
@@ -1403,12 +1502,14 @@ static int sof_widget_ready(struct snd_soc_component *scomp, int index,
14031502 case snd_soc_dapm_siggen :
14041503 ret = sof_widget_load_siggen (scomp , index , swidget , tw , & reply );
14051504 break ;
1505+ case snd_soc_dapm_effect :
1506+ ret = sof_widget_load_effect (scomp , index , swidget , tw , & reply );
1507+ break ;
14061508 case snd_soc_dapm_mux :
14071509 case snd_soc_dapm_demux :
14081510 case snd_soc_dapm_switch :
14091511 case snd_soc_dapm_dai_link :
14101512 case snd_soc_dapm_kcontrol :
1411- case snd_soc_dapm_effect :
14121513 default :
14131514 dev_warn (sdev -> dev , "warning: widget type %d name %s not handled\n" ,
14141515 swidget -> id , tw -> name );
@@ -2110,7 +2211,7 @@ static const struct snd_soc_tplg_kcontrol_ops sof_io_ops[] = {
21102211
21112212/* vendor specific bytes ext handlers available for binding */
21122213static const struct snd_soc_tplg_bytes_ext_ops sof_bytes_ext_ops [] = {
2113- { },
2214+ { SOF_TPLG_KCTL_BYTES_ID , snd_sof_bytes_ext_get , snd_sof_bytes_ext_put },
21142215};
21152216
21162217static struct snd_soc_tplg_ops sof_tplg_ops = {
0 commit comments