Unverified Commit 783560d0 authored by Dharageswari R's avatar Dharageswari R Committed by Mark Brown
Browse files

ASoC: SOF: Implement snd_sof_bytes_ext_volatile_get kcontrol IO



This patch implements the snd_sof_bytes_ext_volatile_get() to read the
actual parameters from DSP by sending the SOF_IPC_COMP_GET_DATA IPC
for the kcontrol of type SOF_TPLG_KCTL_BYTES_VOLATILE_RO.

Signed-off-by: default avatarDharageswari R <dharageswari.r@intel.com>
Reviewed-by: default avatarGuennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
Reviewed-by: default avatarRanjani Sridharan <ranjani.sridharan@linux.intel.com>
Reviewed-by: default avatarPierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Signed-off-by: default avatarKai Vehmanen <kai.vehmanen@linux.intel.com>
Link: https://lore.kernel.org/r/20200908092825.1813847-2-kai.vehmanen@linux.intel.com


Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 819b9f60
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -24,6 +24,9 @@
#define SOF_TPLG_KCTL_ENUM_ID	257
#define SOF_TPLG_KCTL_BYTES_ID	258
#define SOF_TPLG_KCTL_SWITCH_ID	259
#define SOF_TPLG_KCTL_BYTES_VOLATILE_RO 260
#define SOF_TPLG_KCTL_BYTES_VOLATILE_RW 261
#define SOF_TPLG_KCTL_BYTES_WO_ID 262

/*
 * Tokens - must match values in topology configurations
+58 −0
Original line number Diff line number Diff line
@@ -353,6 +353,64 @@ int snd_sof_bytes_ext_put(struct snd_kcontrol *kcontrol,
	return 0;
}

int snd_sof_bytes_ext_volatile_get(struct snd_kcontrol *kcontrol, unsigned int __user *binary_data,
				   unsigned int size)
{
	struct soc_bytes_ext *be = (struct soc_bytes_ext *)kcontrol->private_value;
	struct snd_sof_control *scontrol = be->dobj.private;
	struct snd_soc_component *scomp = scontrol->scomp;
	struct sof_ipc_ctrl_data *cdata = scontrol->control_data;
	struct snd_ctl_tlv header;
	struct snd_ctl_tlv __user *tlvd = (struct snd_ctl_tlv __user *)binary_data;
	size_t data_size;
	int ret;
	int err;

	ret = pm_runtime_get_sync(scomp->dev);
	if (ret < 0) {
		dev_err_ratelimited(scomp->dev, "error: bytes_ext get failed to resume %d\n", ret);
		pm_runtime_put_noidle(scomp->dev);
		return ret;
	}

	/* set the ABI header values */
	cdata->data->magic = SOF_ABI_MAGIC;
	cdata->data->abi = SOF_ABI_VERSION;
	/* get all the component data from DSP */
	ret = snd_sof_ipc_set_get_comp_data(scontrol, SOF_IPC_COMP_GET_DATA, SOF_CTRL_TYPE_DATA_GET,
					    scontrol->cmd, false);
	if (ret < 0)
		goto out;

	/* check data size doesn't exceed max coming from topology */
	if (cdata->data->size > be->max - sizeof(const struct sof_abi_hdr)) {
		dev_err_ratelimited(scomp->dev, "error: user data size %d exceeds max size %zu.\n",
				    cdata->data->size,
				    be->max - sizeof(const struct sof_abi_hdr));
		ret = -EINVAL;
		goto out;
	}

	data_size = cdata->data->size + sizeof(const struct sof_abi_hdr);

	header.numid = scontrol->cmd;
	header.length = data_size;
	if (copy_to_user(tlvd, &header, sizeof(const struct snd_ctl_tlv))) {
		ret = -EFAULT;
		goto out;
	}

	if (copy_to_user(tlvd->tlv, cdata->data, data_size))
		ret = -EFAULT;
out:
	pm_runtime_mark_last_busy(scomp->dev);
	err = pm_runtime_put_autosuspend(scomp->dev);
	if (err < 0)
		dev_err_ratelimited(scomp->dev, "error: bytes_ext get failed to idle %d\n", err);

	return ret;
}

int snd_sof_bytes_ext_get(struct snd_kcontrol *kcontrol,
			  unsigned int __user *binary_data,
			  unsigned int size)
+2 −0
Original line number Diff line number Diff line
@@ -142,6 +142,8 @@ int snd_sof_bytes_ext_put(struct snd_kcontrol *kcontrol,
int snd_sof_bytes_ext_get(struct snd_kcontrol *kcontrol,
			  unsigned int __user *binary_data,
			  unsigned int size);
int snd_sof_bytes_ext_volatile_get(struct snd_kcontrol *kcontrol, unsigned int __user *binary_data,
				   unsigned int size);

/*
 * Topology.
+1 −0
Original line number Diff line number Diff line
@@ -3688,6 +3688,7 @@ static const struct snd_soc_tplg_kcontrol_ops sof_io_ops[] = {
/* vendor specific bytes ext handlers available for binding */
static const struct snd_soc_tplg_bytes_ext_ops sof_bytes_ext_ops[] = {
	{SOF_TPLG_KCTL_BYTES_ID, snd_sof_bytes_ext_get, snd_sof_bytes_ext_put},
	{SOF_TPLG_KCTL_BYTES_VOLATILE_RO, snd_sof_bytes_ext_volatile_get},
};

static struct snd_soc_tplg_ops sof_tplg_ops = {