[alsa-devel] [PATCH 1/3] ASoC: dapm: Add support for virtual mixer controls
Peter Ujfalusi
peter.ujfalusi at ti.com
Mon Oct 7 11:10:42 CEST 2013
On 10/06/2013 02:43 PM, Lars-Peter Clausen wrote:
> This patch adds support for virtual DAPM mixer controls. They are similar to
> virtual DAPM enums. There is no hardware register backing the control, so
> changing the control's value wont have any direct effect on the hardware. But it
> still influences the DAPM graph by causing the path it sits on to be connected
> or disconnected. This in turn can cause power changes for some of the widgets on
> the DAPM graph, which will then modify the hardware state.
Tested-by: Peter Ujfalusi <peter.ujfalusi at ti.com>
>
> Signed-off-by: Lars-Peter Clausen <lars at metafoo.de>
> ---
> include/sound/soc-dapm.h | 4 ++++
> include/sound/soc.h | 3 ++-
> sound/soc/soc-dapm.c | 45 +++++++++++++++++++++++++++------------------
> 3 files changed, 33 insertions(+), 19 deletions(-)
>
> diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h
> index 27a72d5..2037c45 100644
> --- a/include/sound/soc-dapm.h
> +++ b/include/sound/soc-dapm.h
> @@ -286,6 +286,8 @@ struct device;
> .info = snd_soc_info_volsw, \
> .get = snd_soc_dapm_get_volsw, .put = snd_soc_dapm_put_volsw, \
> .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert, 1) }
> +#define SOC_DAPM_SINGLE_VIRT(xname, max) \
> + SOC_DAPM_SINGLE(xname, SND_SOC_NOPM, 0, max, 0)
> #define SOC_DAPM_SINGLE_TLV(xname, reg, shift, max, invert, tlv_array) \
> { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
> .info = snd_soc_info_volsw, \
> @@ -300,6 +302,8 @@ struct device;
> .tlv.p = (tlv_array), \
> .get = snd_soc_dapm_get_volsw, .put = snd_soc_dapm_put_volsw, \
> .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert, 0) }
> +#define SOC_DAPM_SINGLE_TLV_VIRT(xname, max, tlv_array) \
> + SOC_DAPM_SINGLE(xname, SND_SOC_NOPM, 0, max, 0, tlv_array)
> #define SOC_DAPM_ENUM(xname, xenum) \
> { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
> .info = snd_soc_info_enum_double, \
> diff --git a/include/sound/soc.h b/include/sound/soc.h
> index 6dd329a..af1678c 100644
> --- a/include/sound/soc.h
> +++ b/include/sound/soc.h
> @@ -1049,7 +1049,8 @@ struct snd_soc_pcm_runtime {
> /* mixer control */
> struct soc_mixer_control {
> int min, max, platform_max;
> - unsigned int reg, rreg, shift, rshift;
> + int reg, rreg;
> + unsigned int shift, rshift;
> unsigned int invert:1;
> unsigned int autodisable:1;
> };
> diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
> index c17c14c..25b9554 100644
> --- a/sound/soc/soc-dapm.c
> +++ b/sound/soc/soc-dapm.c
> @@ -499,18 +499,22 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w,
> int val;
> struct soc_mixer_control *mc = (struct soc_mixer_control *)
> w->kcontrol_news[i].private_value;
> - unsigned int reg = mc->reg;
> + int reg = mc->reg;
> unsigned int shift = mc->shift;
> int max = mc->max;
> unsigned int mask = (1 << fls(max)) - 1;
> unsigned int invert = mc->invert;
>
> - val = soc_widget_read(w, reg);
> - val = (val >> shift) & mask;
> - if (invert)
> - val = max - val;
> + if (reg != SND_SOC_NOPM) {
> + val = soc_widget_read(w, reg);
> + val = (val >> shift) & mask;
> + if (invert)
> + val = max - val;
> + p->connect = !!val;
> + } else {
> + p->connect = 0;
> + }
>
> - p->connect = !!val;
> }
> break;
> case snd_soc_dapm_mux: {
> @@ -2791,7 +2795,7 @@ int snd_soc_dapm_get_volsw(struct snd_kcontrol *kcontrol,
> struct snd_soc_card *card = codec->card;
> struct soc_mixer_control *mc =
> (struct soc_mixer_control *)kcontrol->private_value;
> - unsigned int reg = mc->reg;
> + int reg = mc->reg;
> unsigned int shift = mc->shift;
> int max = mc->max;
> unsigned int mask = (1 << fls(max)) - 1;
> @@ -2804,7 +2808,7 @@ int snd_soc_dapm_get_volsw(struct snd_kcontrol *kcontrol,
> kcontrol->id.name);
>
> mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
> - if (dapm_kcontrol_is_powered(kcontrol))
> + if (dapm_kcontrol_is_powered(kcontrol) && reg != SND_SOC_NOPM)
> val = (snd_soc_read(codec, reg) >> shift) & mask;
> else
> val = dapm_kcontrol_get_value(kcontrol);
> @@ -2835,7 +2839,7 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol,
> struct snd_soc_card *card = codec->card;
> struct soc_mixer_control *mc =
> (struct soc_mixer_control *)kcontrol->private_value;
> - unsigned int reg = mc->reg;
> + int reg = mc->reg;
> unsigned int shift = mc->shift;
> int max = mc->max;
> unsigned int mask = (1 << fls(max)) - 1;
> @@ -2857,19 +2861,24 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol,
>
> mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
>
> - dapm_kcontrol_set_value(kcontrol, val);
> + change = dapm_kcontrol_set_value(kcontrol, val);
>
> - mask = mask << shift;
> - val = val << shift;
> + if (reg != SND_SOC_NOPM) {
> + mask = mask << shift;
> + val = val << shift;
> +
> + change = snd_soc_test_bits(codec, reg, mask, val);
> + }
>
> - change = snd_soc_test_bits(codec, reg, mask, val);
> if (change) {
> - update.kcontrol = kcontrol;
> - update.reg = reg;
> - update.mask = mask;
> - update.val = val;
> + if (reg != SND_SOC_NOPM) {
> + update.kcontrol = kcontrol;
> + update.reg = reg;
> + update.mask = mask;
> + update.val = val;
>
> - card->update = &update;
> + card->update = &update;
> + }
>
> soc_dapm_mixer_update_power(card, kcontrol, connect);
>
>
--
Péter
More information about the Alsa-devel
mailing list