aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeeja KP <jeeja.kp@intel.com>2015-11-28 04:31:50 -0500
committerMark Brown <broonie@kernel.org>2015-12-01 17:17:00 -0500
commit140adfba5280617487a848a0fa84f7523d999cf3 (patch)
tree3d6c9102b15b1005875ee30646506d6af59a879e
parentabb740033b56a2f57582e8e26bb9ea3650b6a3cc (diff)
ASoC: Intel: Skylake: Add tlv byte kcontrols
This adds tlv bytes topology control creation and control load to initialize kcontrol data. And this also adds the callbacks for the these tlv byte kcontrols Signed-off-by: Mythri P K <mythri.p.k@intel.com> Signed-off-by: Divya Prakash <divya1.prakash@intel.com> Signed-off-by: Jeeja KP <jeeja.kp@intel.com> Signed-off-by: Vinod Koul <vinod.koul@intel.com> Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r--sound/soc/intel/skylake/skl-topology.c121
-rw-r--r--sound/soc/intel/skylake/skl-tplg-interface.h7
2 files changed, 123 insertions, 5 deletions
diff --git a/sound/soc/intel/skylake/skl-topology.c b/sound/soc/intel/skylake/skl-topology.c
index bfc138df56bc..622f7430e100 100644
--- a/sound/soc/intel/skylake/skl-topology.c
+++ b/sound/soc/intel/skylake/skl-topology.c
@@ -875,6 +875,60 @@ static int skl_tplg_pga_event(struct snd_soc_dapm_widget *w,
875 return 0; 875 return 0;
876} 876}
877 877
878static int skl_tplg_tlv_control_get(struct snd_kcontrol *kcontrol,
879 unsigned int __user *data, unsigned int size)
880{
881 struct soc_bytes_ext *sb =
882 (struct soc_bytes_ext *)kcontrol->private_value;
883 struct skl_algo_data *bc = (struct skl_algo_data *)sb->dobj.private;
884
885 if (bc->params) {
886 if (copy_to_user(data, &bc->param_id, sizeof(u32)))
887 return -EFAULT;
888 if (copy_to_user(data + sizeof(u32), &size, sizeof(u32)))
889 return -EFAULT;
890 if (copy_to_user(data + 2 * sizeof(u32), bc->params, size))
891 return -EFAULT;
892 }
893
894 return 0;
895}
896
897#define SKL_PARAM_VENDOR_ID 0xff
898
899static int skl_tplg_tlv_control_set(struct snd_kcontrol *kcontrol,
900 const unsigned int __user *data, unsigned int size)
901{
902 struct snd_soc_dapm_widget *w = snd_soc_dapm_kcontrol_widget(kcontrol);
903 struct skl_module_cfg *mconfig = w->priv;
904 struct soc_bytes_ext *sb =
905 (struct soc_bytes_ext *)kcontrol->private_value;
906 struct skl_algo_data *ac = (struct skl_algo_data *)sb->dobj.private;
907 struct skl *skl = get_skl_ctx(w->dapm->dev);
908
909 if (ac->params) {
910 /*
911 * if the param_is is of type Vendor, firmware expects actual
912 * parameter id and size from the control.
913 */
914 if (ac->param_id == SKL_PARAM_VENDOR_ID) {
915 if (copy_from_user(ac->params, data, size))
916 return -EFAULT;
917 } else {
918 if (copy_from_user(ac->params,
919 data + 2 * sizeof(u32), size))
920 return -EFAULT;
921 }
922
923 if (w->power)
924 return skl_set_module_params(skl->skl_sst,
925 (u32 *)ac->params, ac->max,
926 ac->param_id, mconfig);
927 }
928
929 return 0;
930}
931
878/* 932/*
879 * The FE params are passed by hw_params of the DAI. 933 * The FE params are passed by hw_params of the DAI.
880 * On hw_params, the params are stored in Gateway module of the FE and we 934 * On hw_params, the params are stored in Gateway module of the FE and we
@@ -1125,6 +1179,11 @@ static const struct snd_soc_tplg_widget_events skl_tplg_widget_ops[] = {
1125 {SKL_PGA_EVENT, skl_tplg_pga_event}, 1179 {SKL_PGA_EVENT, skl_tplg_pga_event},
1126}; 1180};
1127 1181
1182static const struct snd_soc_tplg_bytes_ext_ops skl_tlv_ops[] = {
1183 {SKL_CONTROL_TYPE_BYTE_TLV, skl_tplg_tlv_control_get,
1184 skl_tplg_tlv_control_set},
1185};
1186
1128/* 1187/*
1129 * The topology binary passes the pin info for a module so initialize the pin 1188 * The topology binary passes the pin info for a module so initialize the pin
1130 * info passed into module instance 1189 * info passed into module instance
@@ -1321,8 +1380,70 @@ bind_event:
1321 return 0; 1380 return 0;
1322} 1381}
1323 1382
1383static int skl_init_algo_data(struct device *dev, struct soc_bytes_ext *be,
1384 struct snd_soc_tplg_bytes_control *bc)
1385{
1386 struct skl_algo_data *ac;
1387 struct skl_dfw_algo_data *dfw_ac =
1388 (struct skl_dfw_algo_data *)bc->priv.data;
1389
1390 ac = devm_kzalloc(dev, sizeof(*ac), GFP_KERNEL);
1391 if (!ac)
1392 return -ENOMEM;
1393
1394 /* Fill private data */
1395 ac->max = dfw_ac->max;
1396 ac->param_id = dfw_ac->param_id;
1397 ac->set_params = dfw_ac->set_params;
1398
1399 if (ac->max) {
1400 ac->params = (char *) devm_kzalloc(dev, ac->max, GFP_KERNEL);
1401 if (!ac->params)
1402 return -ENOMEM;
1403
1404 if (dfw_ac->params)
1405 memcpy(ac->params, dfw_ac->params, ac->max);
1406 }
1407
1408 be->dobj.private = ac;
1409 return 0;
1410}
1411
1412static int skl_tplg_control_load(struct snd_soc_component *cmpnt,
1413 struct snd_kcontrol_new *kctl,
1414 struct snd_soc_tplg_ctl_hdr *hdr)
1415{
1416 struct soc_bytes_ext *sb;
1417 struct snd_soc_tplg_bytes_control *tplg_bc;
1418 struct hdac_ext_bus *ebus = snd_soc_component_get_drvdata(cmpnt);
1419 struct hdac_bus *bus = ebus_to_hbus(ebus);
1420
1421 switch (hdr->ops.info) {
1422 case SND_SOC_TPLG_CTL_BYTES:
1423 tplg_bc = container_of(hdr,
1424 struct snd_soc_tplg_bytes_control, hdr);
1425 if (kctl->access & SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK) {
1426 sb = (struct soc_bytes_ext *)kctl->private_value;
1427 if (tplg_bc->priv.size)
1428 return skl_init_algo_data(
1429 bus->dev, sb, tplg_bc);
1430 }
1431 break;
1432
1433 default:
1434 dev_warn(bus->dev, "Control load not supported %d:%d:%d\n",
1435 hdr->ops.get, hdr->ops.put, hdr->ops.info);
1436 break;
1437 }
1438
1439 return 0;
1440}
1441
1324static struct snd_soc_tplg_ops skl_tplg_ops = { 1442static struct snd_soc_tplg_ops skl_tplg_ops = {
1325 .widget_load = skl_tplg_widget_load, 1443 .widget_load = skl_tplg_widget_load,
1444 .control_load = skl_tplg_control_load,
1445 .bytes_ext_ops = skl_tlv_ops,
1446 .bytes_ext_ops_count = ARRAY_SIZE(skl_tlv_ops),
1326}; 1447};
1327 1448
1328/* This will be read from topology manifest, currently defined here */ 1449/* This will be read from topology manifest, currently defined here */
diff --git a/sound/soc/intel/skylake/skl-tplg-interface.h b/sound/soc/intel/skylake/skl-tplg-interface.h
index 63c83a3eeb7e..3f1908e3ae80 100644
--- a/sound/soc/intel/skylake/skl-tplg-interface.h
+++ b/sound/soc/intel/skylake/skl-tplg-interface.h
@@ -23,10 +23,7 @@
23 * Default types range from 0~12. type can range from 0 to 0xff 23 * Default types range from 0~12. type can range from 0 to 0xff
24 * SST types start at higher to avoid any overlapping in future 24 * SST types start at higher to avoid any overlapping in future
25 */ 25 */
26#define SOC_CONTROL_TYPE_HDA_SST_ALGO_PARAMS 0x100 26#define SKL_CONTROL_TYPE_BYTE_TLV 0x100
27#define SOC_CONTROL_TYPE_HDA_SST_MUX 0x101
28#define SOC_CONTROL_TYPE_HDA_SST_MIX 0x101
29#define SOC_CONTROL_TYPE_HDA_SST_BYTE 0x103
30 27
31#define HDA_SST_CFG_MAX 900 /* size of copier cfg*/ 28#define HDA_SST_CFG_MAX 900 /* size of copier cfg*/
32#define MAX_IN_QUEUE 8 29#define MAX_IN_QUEUE 8
@@ -218,8 +215,8 @@ struct skl_dfw_module {
218struct skl_dfw_algo_data { 215struct skl_dfw_algo_data {
219 u32 set_params:1; 216 u32 set_params:1;
220 u32 rsvd:31; 217 u32 rsvd:31;
221 u32 param_id;
222 u32 max; 218 u32 max;
219 u32 param_id;
223 char params[0]; 220 char params[0];
224} __packed; 221} __packed;
225 222