From c7d1babc96574781a1cbe90cf83a5596b2c0ab73 Mon Sep 17 00:00:00 2001 From: Rander Wang Date: Thu, 19 Jul 2018 10:02:12 +0800 Subject: [PATCH] ASoC: SOF: refine sof for multi-channels support User mode lib calls info function in kcontrol to get the channel number of volume mixer. The default info function is snd_soc_info_volsw which only supports max two channels. Just like get/put function, info function is bound to a bespoke info function in SOF and return correct channel number to user. The snd_sof_volume_info is based on snd_soc_info_volsw, and refines the channel setting. Using standard SND_SOC_TPLG_CTL_VOLSW to register our kcontrol function because only it supports binding all kcontrol functions to bespoke ones. And this change doesn't affect the volume mixer which is not created by topology and doesn't affect the topology released Signed-off-by: Rander Wang --- sound/soc/sof/control.c | 21 +++++++++++++++++++++ sound/soc/sof/sof-priv.h | 2 ++ sound/soc/sof/topology.c | 2 ++ 3 files changed, 25 insertions(+) diff --git a/sound/soc/sof/control.c b/sound/soc/sof/control.c index db09ba63154b69..35deb3bc1c2fb5 100644 --- a/sound/soc/sof/control.c +++ b/sound/soc/sof/control.c @@ -98,6 +98,27 @@ int snd_sof_volume_put(struct snd_kcontrol *kcontrol, return 0; } +int snd_sof_volume_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; + struct snd_sof_control *scontrol = mc->dobj.private; + unsigned int channels = scontrol->num_channels; + int platform_max; + + if (!mc->platform_max) + mc->platform_max = mc->max; + + platform_max = mc->platform_max; + + uinfo->count = channels; + uinfo->value.integer.min = 0; + uinfo->value.integer.max = platform_max - mc->min; + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + return 0; +} + int snd_sof_enum_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { diff --git a/sound/soc/sof/sof-priv.h b/sound/soc/sof/sof-priv.h index 5def46b92f1957..2fc86b14cea83a 100644 --- a/sound/soc/sof/sof-priv.h +++ b/sound/soc/sof/sof-priv.h @@ -479,6 +479,8 @@ int snd_sof_volume_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); int snd_sof_volume_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); +int snd_sof_volume_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo); int snd_sof_enum_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); int snd_sof_enum_put(struct snd_kcontrol *kcontrol, diff --git a/sound/soc/sof/topology.c b/sound/soc/sof/topology.c index 143a191b381ad0..9ec7c69e31e548 100644 --- a/sound/soc/sof/topology.c +++ b/sound/soc/sof/topology.c @@ -1919,6 +1919,8 @@ static int sof_manifest(struct snd_soc_component *scomp, int index, /* vendor specific kcontrol handlers available for binding */ static const struct snd_soc_tplg_kcontrol_ops sof_io_ops[] = { {SOF_TPLG_KCTL_VOL_ID, snd_sof_volume_get, snd_sof_volume_put}, + {SND_SOC_TPLG_CTL_VOLSW, snd_sof_volume_get, snd_sof_volume_put, + snd_sof_volume_info}, {SOF_TPLG_KCTL_ENUM_ID, snd_sof_enum_get, snd_sof_enum_put}, {SOF_TPLG_KCTL_BYTES_ID, snd_sof_bytes_get, snd_sof_bytes_put}, };