@@ -298,6 +298,8 @@ static int sof_control_load_bytes(struct snd_soc_component *scomp,
298298{
299299 struct snd_sof_dev * sdev = snd_soc_component_get_drvdata (scomp );
300300 struct sof_ipc_ctrl_data * cdata ;
301+ struct snd_soc_tplg_bytes_control * control =
302+ (struct snd_soc_tplg_bytes_control * )hdr ;
301303
302304 /* init the get/put bytes data */
303305 scontrol -> size = SOF_IPC_MSG_MAX_SIZE ;
@@ -312,6 +314,21 @@ static int sof_control_load_bytes(struct snd_soc_component *scomp,
312314 dev_dbg (sdev -> dev , "tplg: load kcontrol index %d chans %d\n" ,
313315 scontrol -> comp_id , scontrol -> num_channels );
314316
317+ if (le32_to_cpu (control -> priv .size ) > SOF_IPC_MSG_MAX_SIZE ) {
318+ dev_warn (sdev -> dev , "bytes priv data size %d too big\n" ,
319+ control -> priv .size );
320+ return - EINVAL ;
321+ }
322+
323+ if (le32_to_cpu (control -> priv .size ) > 0 ) {
324+ memcpy (cdata -> data -> data , control -> priv .data ,
325+ le32_to_cpu (control -> priv .size ));
326+ cdata -> data -> size = control -> priv .size ;
327+ cdata -> data -> magic = SOF_ABI_MAGIC ;
328+ cdata -> data -> abi = SOF_ABI_VERSION ;
329+ cdata -> data -> comp_abi = SOF_ABI_VERSION ;
330+ }
331+
315332 return 0 ;
316333}
317334
@@ -436,16 +453,6 @@ static const struct sof_topology_token src_tokens[] = {
436453static const struct sof_topology_token tone_tokens [] = {
437454};
438455
439- /* EQ FIR */
440- /*
441- static const struct sof_topology_token eq_fir_tokens[] = {
442- };
443- */
444-
445- /* EQ IIR */
446- static const struct sof_topology_token eq_iir_tokens [] = {
447- };
448-
449456/* EFFECT */
450457static const struct sof_topology_token effect_tokens [] = {
451458 {SOF_TKN_EFFECT_TYPE , SND_SOC_TPLG_TUPLE_TYPE_STRING ,
@@ -1383,67 +1390,217 @@ static int sof_widget_load_siggen(struct snd_soc_component *scomp, int index,
13831390 kfree (tone );
13841391 return ret ;
13851392}
1386- /*
1387- * Effect Topology. Only IIR equalizer is supported at this moment.
1388- * TODO: Need to add also FIR support and have a way to add other
1389- * effects and enhancements.
1390- */
13911393
1392- static int sof_widget_load_effect (struct snd_soc_component * scomp , int index ,
1393- struct snd_sof_widget * swidget ,
1394- struct snd_soc_tplg_dapm_widget * tw ,
1395- struct sof_ipc_comp_reply * r )
1394+ static int sof_effect_fir_load (struct snd_soc_component * scomp , int index ,
1395+ struct snd_sof_widget * swidget ,
1396+ struct snd_soc_tplg_dapm_widget * tw ,
1397+ struct sof_ipc_comp_reply * r )
1398+
13961399{
13971400 struct snd_sof_dev * sdev = snd_soc_component_get_drvdata (scomp );
13981401 struct snd_soc_tplg_private * private = & tw -> priv ;
1399- struct sof_ipc_comp_eq_iir * eq ;
1402+ struct snd_sof_control * scontrol = NULL ;
1403+ struct snd_soc_dapm_widget * widget = swidget -> widget ;
1404+ const struct snd_kcontrol_new * kc = NULL ;
1405+ struct soc_bytes_ext * sbe ;
1406+ struct sof_abi_hdr * pdata = NULL ;
1407+ struct sof_ipc_comp_eq_fir * fir ;
1408+ size_t ipc_size = 0 , fir_data_size = 0 ;
14001409 int ret ;
14011410
1402- eq = kzalloc (sizeof (* eq ), GFP_KERNEL );
1403- if (!eq )
1411+ /* get possible eq controls */
1412+ kc = & widget -> kcontrol_news [0 ];
1413+ if (kc ) {
1414+ sbe = (struct soc_bytes_ext * )kc -> private_value ;
1415+ scontrol = sbe -> dobj .private ;
1416+ }
1417+
1418+ /*
1419+ * Check if there's eq parameters in control's private member and set
1420+ * data size accordingly. If there's no parameters eq will use defaults
1421+ * in firmware (which in this case is passthrough).
1422+ */
1423+ if (scontrol && scontrol -> cmd == SOF_CTRL_CMD_BINARY ) {
1424+ pdata = scontrol -> control_data -> data ;
1425+ if (pdata -> size > 0 && pdata -> magic == SOF_ABI_MAGIC )
1426+ fir_data_size = pdata -> size ;
1427+ }
1428+
1429+ ipc_size = sizeof (struct sof_ipc_comp_eq_fir ) +
1430+ le32_to_cpu (private -> size ) +
1431+ fir_data_size ;
1432+
1433+ fir = kzalloc (ipc_size , GFP_KERNEL );
1434+ if (!fir )
14041435 return - ENOMEM ;
14051436
1406- /* configure IIR EQ IPC message */
1407- eq -> comp .hdr .size = sizeof (* eq );
1408- eq -> comp .hdr .cmd = SOF_IPC_GLB_TPLG_MSG | SOF_IPC_TPLG_COMP_NEW ;
1409- eq -> comp .id = swidget -> comp_id ;
1410- eq -> comp .pipeline_id = index ;
1437+ /* configure fir IPC message */
1438+ fir -> comp .hdr .size = ipc_size ;
1439+ fir -> comp .hdr .cmd = SOF_IPC_GLB_TPLG_MSG | SOF_IPC_TPLG_COMP_NEW ;
1440+ fir -> comp .id = swidget -> comp_id ;
1441+ fir -> comp .type = SOF_COMP_EQ_FIR ;
1442+ fir -> comp .pipeline_id = index ;
14111443
1412- eq -> comp .type = SOF_COMP_EQ_IIR ;
1413- ret = sof_parse_tokens (scomp , eq , eq_iir_tokens ,
1414- ARRAY_SIZE (eq_iir_tokens ), private -> array ,
1444+ ret = sof_parse_tokens (scomp , & fir -> config , comp_tokens ,
1445+ ARRAY_SIZE (comp_tokens ), private -> array ,
14151446 le32_to_cpu (private -> size ));
1416- if (ret ) {
1417- dev_err (sdev -> dev , "error: parse EQ tokens failed %d\n" ,
1418- private -> size );
1447+ if (ret != 0 ) {
1448+ dev_err (sdev -> dev , "error: parse fir.cfg tokens failed %d\n" ,
1449+ le32_to_cpu ( private -> size ) );
14191450 goto err ;
14201451 }
14211452
1422- ret = sof_parse_tokens (scomp , & eq -> config , comp_tokens ,
1453+ sof_dbg_comp_config (scomp , & fir -> config );
1454+
1455+ /* we have a private data found in control, so copy it */
1456+ if (fir_data_size > 0 ) {
1457+ memcpy (& fir -> data , pdata -> data , pdata -> size );
1458+ fir -> size = fir_data_size ;
1459+ }
1460+
1461+ swidget -> private = (void * )fir ;
1462+
1463+ ret = sof_ipc_tx_message (sdev -> ipc , fir -> comp .hdr .cmd , fir ,
1464+ ipc_size , r , sizeof (* r ));
1465+ if (ret >= 0 )
1466+ return ret ;
1467+ err :
1468+ kfree (fir );
1469+ return ret ;
1470+ }
1471+
1472+ static int sof_effect_iir_load (struct snd_soc_component * scomp , int index ,
1473+ struct snd_sof_widget * swidget ,
1474+ struct snd_soc_tplg_dapm_widget * tw ,
1475+ struct sof_ipc_comp_reply * r )
1476+ {
1477+ struct snd_sof_dev * sdev = snd_soc_component_get_drvdata (scomp );
1478+ struct snd_soc_tplg_private * private = & tw -> priv ;
1479+ struct snd_soc_dapm_widget * widget = swidget -> widget ;
1480+ const struct snd_kcontrol_new * kc = NULL ;
1481+ struct soc_bytes_ext * sbe ;
1482+ struct snd_sof_control * scontrol = NULL ;
1483+ struct sof_abi_hdr * pdata = NULL ;
1484+ struct sof_ipc_comp_eq_iir * iir ;
1485+ size_t ipc_size = 0 , iir_data_size = 0 ;
1486+ int ret ;
1487+
1488+ /* get possible eq controls */
1489+ kc = & widget -> kcontrol_news [0 ];
1490+ if (kc ) {
1491+ sbe = (struct soc_bytes_ext * )kc -> private_value ;
1492+ scontrol = sbe -> dobj .private ;
1493+ }
1494+
1495+ /*
1496+ * Check if there's eq parameters in control's private member and set
1497+ * data size accordingly. If there's no parameters eq will use defaults
1498+ * in firmware (which in this case is passthrough).
1499+ */
1500+ if (scontrol && scontrol -> cmd == SOF_CTRL_CMD_BINARY ) {
1501+ pdata = scontrol -> control_data -> data ;
1502+ if (pdata -> size > 0 && pdata -> magic == SOF_ABI_MAGIC )
1503+ iir_data_size = pdata -> size ;
1504+ }
1505+
1506+ ipc_size = sizeof (struct sof_ipc_comp_eq_iir ) +
1507+ le32_to_cpu (private -> size ) +
1508+ iir_data_size ;
1509+
1510+ iir = kzalloc (ipc_size , GFP_KERNEL );
1511+ if (!iir )
1512+ return - ENOMEM ;
1513+
1514+ /* configure iir IPC message */
1515+ iir -> comp .hdr .size = ipc_size ;
1516+ iir -> comp .hdr .cmd = SOF_IPC_GLB_TPLG_MSG | SOF_IPC_TPLG_COMP_NEW ;
1517+ iir -> comp .id = swidget -> comp_id ;
1518+ iir -> comp .type = SOF_COMP_EQ_IIR ;
1519+ iir -> comp .pipeline_id = index ;
1520+
1521+ ret = sof_parse_tokens (scomp , & iir -> config , comp_tokens ,
14231522 ARRAY_SIZE (comp_tokens ), private -> array ,
14241523 le32_to_cpu (private -> size ));
1425- if (ret ) {
1426- dev_err (sdev -> dev , "error: parse EQ .cfg tokens failed %d\n" ,
1524+ if (ret != 0 ) {
1525+ dev_err (sdev -> dev , "error: parse iir .cfg tokens failed %d\n" ,
14271526 le32_to_cpu (private -> size ));
14281527 goto err ;
14291528 }
14301529
1431- dev_dbg ( sdev -> dev , "eq iir %s created\n" , swidget -> widget -> name );
1530+ sof_dbg_comp_config ( scomp , & iir -> config );
14321531
1433- sof_dbg_comp_config (scomp , & eq -> config );
1434-
1435- swidget -> private = (void * )eq ;
1532+ /* we have a private data found in control, so copy it */
1533+ if (iir_data_size > 0 ) {
1534+ memcpy (& iir -> data , pdata -> data , pdata -> size );
1535+ iir -> size = iir_data_size ;
1536+ }
14361537
1437- ret = sof_ipc_tx_message (sdev -> ipc , eq -> comp .hdr .cmd , eq ,
1438- sizeof (* eq ), r , sizeof (* r ));
1538+ swidget -> private = (void * )iir ;
14391539
1540+ ret = sof_ipc_tx_message (sdev -> ipc , iir -> comp .hdr .cmd , iir ,
1541+ ipc_size , r , sizeof (* r ));
14401542 if (ret >= 0 )
14411543 return ret ;
14421544err :
1443- kfree (eq );
1545+ kfree (iir );
14441546 return ret ;
14451547}
14461548
1549+ /*
1550+ * Effect Topology
1551+ */
1552+
1553+ static int sof_widget_load_effect (struct snd_soc_component * scomp , int index ,
1554+ struct snd_sof_widget * swidget ,
1555+ struct snd_soc_tplg_dapm_widget * tw ,
1556+ struct sof_ipc_comp_reply * r )
1557+ {
1558+ struct snd_sof_dev * sdev = snd_soc_component_get_drvdata (scomp );
1559+ struct snd_soc_tplg_private * private = & tw -> priv ;
1560+ struct sof_ipc_comp_effect config ;
1561+ int ret ;
1562+
1563+ /* check we have some tokens - we need at least effect type */
1564+ if (le32_to_cpu (private -> size ) == 0 ) {
1565+ dev_err (sdev -> dev , "error: effect tokens not found\n" );
1566+ return - EINVAL ;
1567+ }
1568+
1569+ memset (& config , 0 , sizeof (config ));
1570+
1571+ /* get the effect token */
1572+ ret = sof_parse_tokens (scomp , & config , effect_tokens ,
1573+ ARRAY_SIZE (effect_tokens ), private -> array ,
1574+ le32_to_cpu (private -> size ));
1575+ if (ret != 0 ) {
1576+ dev_err (sdev -> dev , "error: parse effect tokens failed %d\n" ,
1577+ le32_to_cpu (private -> size ));
1578+ return ret ;
1579+ }
1580+
1581+ /* now load effect specific data and send IPC */
1582+ switch (config .type ) {
1583+ case SOF_EFFECT_INTEL_EQFIR :
1584+ ret = sof_effect_fir_load (scomp , index , swidget , tw , r );
1585+ break ;
1586+ case SOF_EFFECT_INTEL_EQIIR :
1587+ ret = sof_effect_iir_load (scomp , index , swidget , tw , r );
1588+ break ;
1589+ default :
1590+ dev_err (sdev -> dev , "error: invalid effect type %d\n" ,
1591+ config .type );
1592+ ret = - EINVAL ;
1593+ break ;
1594+ }
1595+
1596+ if (ret < 0 ) {
1597+ dev_err (sdev -> dev , "error: effect loading failed\n" );
1598+ return ret ;
1599+ }
1600+
1601+ return 0 ;
1602+ }
1603+
14471604/*
14481605 * Generic widget loader.
14491606 */
0 commit comments