Unverified Commit e394ffb8 authored by Peter Ujfalusi's avatar Peter Ujfalusi Committed by Mark Brown
Browse files

ASoC: SOF: Add widget_kcontrol_setup control ops for IPC3



Define and set the widget_kcontrol_setup control IPC ops for IPC3.

The widget_kcontrol_setup callback can be used to set up all
kcontrols associated with the swidget.

Signed-off-by: default avatarPeter Ujfalusi <peter.ujfalusi@linux.intel.com>
Reviewed-by: default avatarDaniel Baluta <daniel.baluta@nxp.com>
Reviewed-by: default avatarPierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Signed-off-by: default avatarRanjani Sridharan <ranjani.sridharan@linux.intel.com>
Link: https://lore.kernel.org/r/20220405172708.122168-14-ranjani.sridharan@linux.intel.com


Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 2f1f5a43
Loading
Loading
Loading
Loading
+38 −0
Original line number Diff line number Diff line
@@ -578,6 +578,43 @@ static void sof_ipc3_control_update(struct snd_sof_dev *sdev, void *ipc_control_
	snd_ctl_notify_one(swidget->scomp->card->snd_card, SNDRV_CTL_EVENT_MASK_VALUE, kc, 0);
}

static int sof_ipc3_widget_kcontrol_setup(struct snd_sof_dev *sdev,
					  struct snd_sof_widget *swidget)
{
	struct snd_sof_control *scontrol;
	int ret;

	/* set up all controls for the widget */
	list_for_each_entry(scontrol, &sdev->kcontrol_list, list)
		if (scontrol->comp_id == swidget->comp_id) {
			/* set kcontrol data in DSP */
			ret = snd_sof_ipc_set_get_comp_data(scontrol, true);
			if (ret < 0) {
				dev_err(sdev->dev,
					"kcontrol %d set up failed for widget %s\n",
					scontrol->comp_id, swidget->widget->name);
				return ret;
			}

			/*
			 * Read back the data from the DSP for static widgets.
			 * This is particularly useful for binary kcontrols
			 * associated with static pipeline widgets to initialize
			 * the data size to match that in the DSP.
			 */
			if (swidget->dynamic_pipeline_widget)
				continue;

			ret = snd_sof_ipc_set_get_comp_data(scontrol, false);
			if (ret < 0)
				dev_warn(sdev->dev,
					 "kcontrol %d read failed for widget %s\n",
					 scontrol->comp_id, swidget->widget->name);
		}

	return 0;
}

const struct sof_ipc_tplg_control_ops tplg_ipc3_control_ops = {
	.volume_put = sof_ipc3_volume_put,
	.volume_get = sof_ipc3_volume_get,
@@ -591,4 +628,5 @@ const struct sof_ipc_tplg_control_ops tplg_ipc3_control_ops = {
	.bytes_ext_get = sof_ipc3_bytes_ext_get,
	.bytes_ext_volatile_get = sof_ipc3_bytes_ext_volatile_get,
	.update = sof_ipc3_control_update,
	.widget_kcontrol_setup = sof_ipc3_widget_kcontrol_setup,
};
+2 −0
Original line number Diff line number Diff line
@@ -86,6 +86,8 @@ struct sof_ipc_tplg_control_ops {
			     const unsigned int __user *binary_data, unsigned int size);
	/* update control data based on notification from the DSP */
	void (*update)(struct snd_sof_dev *sdev, void *ipc_control_message);
	/* Optional callback to setup kcontrols associated with an swidget */
	int (*widget_kcontrol_setup)(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget);
};

/**