summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sound/soc/sof/topology.c314
1 files changed, 157 insertions, 157 deletions
diff --git a/sound/soc/sof/topology.c b/sound/soc/sof/topology.c
index a0b1c38e666b..3918301c573b 100644
--- a/sound/soc/sof/topology.c
+++ b/sound/soc/sof/topology.c
@@ -433,163 +433,6 @@ static enum sof_comp_type find_process_comp_type(enum sof_ipc_process_type type)
}
/*
- * Standard Kcontrols.
- */
-
-static int sof_control_load_volume(struct snd_soc_component *scomp,
- struct snd_sof_control *scontrol,
- struct snd_kcontrol_new *kc,
- struct snd_soc_tplg_ctl_hdr *hdr)
-{
- struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
- struct snd_soc_tplg_mixer_control *mc =
- container_of(hdr, struct snd_soc_tplg_mixer_control, hdr);
- struct sof_ipc_ctrl_data *cdata;
- int tlv[TLV_ITEMS];
- unsigned int i;
- int ret;
-
- /* validate topology data */
- if (le32_to_cpu(mc->num_channels) > SND_SOC_TPLG_MAX_CHAN)
- return -EINVAL;
-
- /* init the volume get/put data */
- scontrol->size = struct_size(scontrol->control_data, chanv,
- le32_to_cpu(mc->num_channels));
- scontrol->control_data = kzalloc(scontrol->size, GFP_KERNEL);
- if (!scontrol->control_data)
- return -ENOMEM;
-
- scontrol->comp_id = sdev->next_comp_id;
- scontrol->min_volume_step = le32_to_cpu(mc->min);
- scontrol->max_volume_step = le32_to_cpu(mc->max);
- scontrol->num_channels = le32_to_cpu(mc->num_channels);
-
- /* set cmd for mixer control */
- if (le32_to_cpu(mc->max) == 1) {
- scontrol->cmd = SOF_CTRL_CMD_SWITCH;
- goto out;
- }
-
- scontrol->cmd = SOF_CTRL_CMD_VOLUME;
-
- /* extract tlv data */
- if (get_tlv_data(kc->tlv.p, tlv) < 0) {
- dev_err(sdev->dev, "error: invalid TLV data\n");
- return -EINVAL;
- }
-
- /* set up volume table */
- ret = set_up_volume_table(scontrol, tlv, le32_to_cpu(mc->max) + 1);
- if (ret < 0) {
- dev_err(sdev->dev, "error: setting up volume table\n");
- return ret;
- }
-
- /* set default volume values to 0dB in control */
- cdata = scontrol->control_data;
- for (i = 0; i < scontrol->num_channels; i++) {
- cdata->chanv[i].channel = i;
- cdata->chanv[i].value = VOL_ZERO_DB;
- }
-
-out:
- dev_dbg(sdev->dev, "tplg: load kcontrol index %d chans %d\n",
- scontrol->comp_id, scontrol->num_channels);
-
- return 0;
-}
-
-static int sof_control_load_enum(struct snd_soc_component *scomp,
- struct snd_sof_control *scontrol,
- struct snd_kcontrol_new *kc,
- struct snd_soc_tplg_ctl_hdr *hdr)
-{
- struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
- struct snd_soc_tplg_enum_control *ec =
- container_of(hdr, struct snd_soc_tplg_enum_control, hdr);
-
- /* validate topology data */
- if (le32_to_cpu(ec->num_channels) > SND_SOC_TPLG_MAX_CHAN)
- return -EINVAL;
-
- /* init the enum get/put data */
- scontrol->size = struct_size(scontrol->control_data, chanv,
- le32_to_cpu(ec->num_channels));
- scontrol->control_data = kzalloc(scontrol->size, GFP_KERNEL);
- if (!scontrol->control_data)
- return -ENOMEM;
-
- scontrol->comp_id = sdev->next_comp_id;
- scontrol->num_channels = le32_to_cpu(ec->num_channels);
-
- scontrol->cmd = SOF_CTRL_CMD_ENUM;
-
- dev_dbg(sdev->dev, "tplg: load kcontrol index %d chans %d comp_id %d\n",
- scontrol->comp_id, scontrol->num_channels, scontrol->comp_id);
-
- return 0;
-}
-
-static int sof_control_load_bytes(struct snd_soc_component *scomp,
- struct snd_sof_control *scontrol,
- struct snd_kcontrol_new *kc,
- struct snd_soc_tplg_ctl_hdr *hdr)
-{
- struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
- struct sof_ipc_ctrl_data *cdata;
- struct snd_soc_tplg_bytes_control *control =
- container_of(hdr, struct snd_soc_tplg_bytes_control, hdr);
- struct soc_bytes_ext *sbe = (struct soc_bytes_ext *)kc->private_value;
- int max_size = sbe->max;
-
- if (le32_to_cpu(control->priv.size) > max_size) {
- dev_err(sdev->dev, "err: bytes data size %d exceeds max %d.\n",
- control->priv.size, max_size);
- return -EINVAL;
- }
-
- /* init the get/put bytes data */
- scontrol->size = sizeof(struct sof_ipc_ctrl_data) +
- le32_to_cpu(control->priv.size);
- scontrol->control_data = kzalloc(max_size, GFP_KERNEL);
- cdata = scontrol->control_data;
- if (!scontrol->control_data)
- return -ENOMEM;
-
- scontrol->comp_id = sdev->next_comp_id;
- scontrol->cmd = SOF_CTRL_CMD_BINARY;
-
- dev_dbg(sdev->dev, "tplg: load kcontrol index %d chans %d\n",
- scontrol->comp_id, scontrol->num_channels);
-
- if (le32_to_cpu(control->priv.size) > 0) {
- memcpy(cdata->data, control->priv.data,
- le32_to_cpu(control->priv.size));
-
- if (cdata->data->magic != SOF_ABI_MAGIC) {
- dev_err(sdev->dev, "error: Wrong ABI magic 0x%08x.\n",
- cdata->data->magic);
- return -EINVAL;
- }
- if (SOF_ABI_VERSION_INCOMPATIBLE(SOF_ABI_VERSION,
- cdata->data->abi)) {
- dev_err(sdev->dev,
- "error: Incompatible ABI version 0x%08x.\n",
- cdata->data->abi);
- return -EINVAL;
- }
- if (cdata->data->size + sizeof(const struct sof_abi_hdr) !=
- le32_to_cpu(control->priv.size)) {
- dev_err(sdev->dev,
- "error: Conflict in bytes vs. priv size.\n");
- return -EINVAL;
- }
- }
- return 0;
-}
-
-/*
* Topology Token Parsing.
* New tokens should be added to headers and parsing tables below.
*/
@@ -1039,6 +882,163 @@ static void sof_dbg_comp_config(struct snd_soc_component *scomp,
config->frame_fmt);
}
+/*
+ * Standard Kcontrols.
+ */
+
+static int sof_control_load_volume(struct snd_soc_component *scomp,
+ struct snd_sof_control *scontrol,
+ struct snd_kcontrol_new *kc,
+ struct snd_soc_tplg_ctl_hdr *hdr)
+{
+ struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
+ struct snd_soc_tplg_mixer_control *mc =
+ container_of(hdr, struct snd_soc_tplg_mixer_control, hdr);
+ struct sof_ipc_ctrl_data *cdata;
+ int tlv[TLV_ITEMS];
+ unsigned int i;
+ int ret;
+
+ /* validate topology data */
+ if (le32_to_cpu(mc->num_channels) > SND_SOC_TPLG_MAX_CHAN)
+ return -EINVAL;
+
+ /* init the volume get/put data */
+ scontrol->size = struct_size(scontrol->control_data, chanv,
+ le32_to_cpu(mc->num_channels));
+ scontrol->control_data = kzalloc(scontrol->size, GFP_KERNEL);
+ if (!scontrol->control_data)
+ return -ENOMEM;
+
+ scontrol->comp_id = sdev->next_comp_id;
+ scontrol->min_volume_step = le32_to_cpu(mc->min);
+ scontrol->max_volume_step = le32_to_cpu(mc->max);
+ scontrol->num_channels = le32_to_cpu(mc->num_channels);
+
+ /* set cmd for mixer control */
+ if (le32_to_cpu(mc->max) == 1) {
+ scontrol->cmd = SOF_CTRL_CMD_SWITCH;
+ goto out;
+ }
+
+ scontrol->cmd = SOF_CTRL_CMD_VOLUME;
+
+ /* extract tlv data */
+ if (get_tlv_data(kc->tlv.p, tlv) < 0) {
+ dev_err(sdev->dev, "error: invalid TLV data\n");
+ return -EINVAL;
+ }
+
+ /* set up volume table */
+ ret = set_up_volume_table(scontrol, tlv, le32_to_cpu(mc->max) + 1);
+ if (ret < 0) {
+ dev_err(sdev->dev, "error: setting up volume table\n");
+ return ret;
+ }
+
+ /* set default volume values to 0dB in control */
+ cdata = scontrol->control_data;
+ for (i = 0; i < scontrol->num_channels; i++) {
+ cdata->chanv[i].channel = i;
+ cdata->chanv[i].value = VOL_ZERO_DB;
+ }
+
+out:
+ dev_dbg(sdev->dev, "tplg: load kcontrol index %d chans %d\n",
+ scontrol->comp_id, scontrol->num_channels);
+
+ return 0;
+}
+
+static int sof_control_load_enum(struct snd_soc_component *scomp,
+ struct snd_sof_control *scontrol,
+ struct snd_kcontrol_new *kc,
+ struct snd_soc_tplg_ctl_hdr *hdr)
+{
+ struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
+ struct snd_soc_tplg_enum_control *ec =
+ container_of(hdr, struct snd_soc_tplg_enum_control, hdr);
+
+ /* validate topology data */
+ if (le32_to_cpu(ec->num_channels) > SND_SOC_TPLG_MAX_CHAN)
+ return -EINVAL;
+
+ /* init the enum get/put data */
+ scontrol->size = struct_size(scontrol->control_data, chanv,
+ le32_to_cpu(ec->num_channels));
+ scontrol->control_data = kzalloc(scontrol->size, GFP_KERNEL);
+ if (!scontrol->control_data)
+ return -ENOMEM;
+
+ scontrol->comp_id = sdev->next_comp_id;
+ scontrol->num_channels = le32_to_cpu(ec->num_channels);
+
+ scontrol->cmd = SOF_CTRL_CMD_ENUM;
+
+ dev_dbg(sdev->dev, "tplg: load kcontrol index %d chans %d comp_id %d\n",
+ scontrol->comp_id, scontrol->num_channels, scontrol->comp_id);
+
+ return 0;
+}
+
+static int sof_control_load_bytes(struct snd_soc_component *scomp,
+ struct snd_sof_control *scontrol,
+ struct snd_kcontrol_new *kc,
+ struct snd_soc_tplg_ctl_hdr *hdr)
+{
+ struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
+ struct sof_ipc_ctrl_data *cdata;
+ struct snd_soc_tplg_bytes_control *control =
+ container_of(hdr, struct snd_soc_tplg_bytes_control, hdr);
+ struct soc_bytes_ext *sbe = (struct soc_bytes_ext *)kc->private_value;
+ int max_size = sbe->max;
+
+ if (le32_to_cpu(control->priv.size) > max_size) {
+ dev_err(sdev->dev, "err: bytes data size %d exceeds max %d.\n",
+ control->priv.size, max_size);
+ return -EINVAL;
+ }
+
+ /* init the get/put bytes data */
+ scontrol->size = sizeof(struct sof_ipc_ctrl_data) +
+ le32_to_cpu(control->priv.size);
+ scontrol->control_data = kzalloc(max_size, GFP_KERNEL);
+ cdata = scontrol->control_data;
+ if (!scontrol->control_data)
+ return -ENOMEM;
+
+ scontrol->comp_id = sdev->next_comp_id;
+ scontrol->cmd = SOF_CTRL_CMD_BINARY;
+
+ dev_dbg(sdev->dev, "tplg: load kcontrol index %d chans %d\n",
+ scontrol->comp_id, scontrol->num_channels);
+
+ if (le32_to_cpu(control->priv.size) > 0) {
+ memcpy(cdata->data, control->priv.data,
+ le32_to_cpu(control->priv.size));
+
+ if (cdata->data->magic != SOF_ABI_MAGIC) {
+ dev_err(sdev->dev, "error: Wrong ABI magic 0x%08x.\n",
+ cdata->data->magic);
+ return -EINVAL;
+ }
+ if (SOF_ABI_VERSION_INCOMPATIBLE(SOF_ABI_VERSION,
+ cdata->data->abi)) {
+ dev_err(sdev->dev,
+ "error: Incompatible ABI version 0x%08x.\n",
+ cdata->data->abi);
+ return -EINVAL;
+ }
+ if (cdata->data->size + sizeof(const struct sof_abi_hdr) !=
+ le32_to_cpu(control->priv.size)) {
+ dev_err(sdev->dev,
+ "error: Conflict in bytes vs. priv size.\n");
+ return -EINVAL;
+ }
+ }
+ return 0;
+}
+
/* external kcontrol init - used for any driver specific init */
static int sof_control_load(struct snd_soc_component *scomp, int index,
struct snd_kcontrol_new *kc,