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: Peter Ujfalusi <peter.ujfalusi@linux.intel.com> Reviewed-by: Daniel Baluta <daniel.baluta@nxp.com> Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com> Link: https://lore.kernel.org/r/20220405172708.122168-14-ranjani.sridharan@linux.intel.com Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
Родитель
2f1f5a4388
Коммит
e394ffb82f
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
Загрузка…
Ссылка в новой задаче