]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
ASoC: SDCA: Pull the Q7.8 volume helpers out of soc-ops
authorCharles Keepax <ckeepax@opensource.cirrus.com>
Wed, 25 Feb 2026 14:01:18 +0000 (14:01 +0000)
committerMark Brown <broonie@kernel.org>
Thu, 26 Feb 2026 19:16:48 +0000 (19:16 +0000)
It is cleaner to keep the SDCA code contained and not update the core
code for things that are unlikely to see reuse outside of SDCA. Move the
Q7.8 volume helpers back into the SDCA core code.

Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.dev>
Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com>
Link: https://patch.msgid.link/20260225140118.402695-5-ckeepax@opensource.cirrus.com
Signed-off-by: Mark Brown <broonie@kernel.org>
include/sound/soc.h
sound/soc/sdca/sdca_asoc.c
sound/soc/soc-ops.c

index 7d8376c8e1bededf7f5a3cb478b6f1f966c99da5..172bd68e1315fc56359eb17e4fa601f7bdca17a9 100644 (file)
@@ -1239,7 +1239,6 @@ struct soc_mixer_control {
        unsigned int sign_bit;
        unsigned int invert:1;
        unsigned int autodisable:1;
-       unsigned int sdca_q78:1;
 #ifdef CONFIG_SND_SOC_TOPOLOGY
        struct snd_soc_dobj dobj;
 #endif
index e6f7c2778bec5e4599c5ecb2def3db8bf032c5ab..a342a4e56717a7a7cfb979e7fb5f82423dd7c6ff 100644 (file)
@@ -805,6 +805,70 @@ int sdca_asoc_populate_dapm(struct device *dev, struct sdca_function_data *funct
 }
 EXPORT_SYMBOL_NS(sdca_asoc_populate_dapm, "SND_SOC_SDCA");
 
+static int q78_write(struct snd_soc_component *component,
+                    struct soc_mixer_control *mc,
+                    unsigned int reg, const int val)
+{
+       unsigned int mask = GENMASK(mc->sign_bit, 0);
+       unsigned int reg_val;
+
+       if (val < 0 || val > mc->max - mc->min)
+               return -EINVAL;
+
+       reg_val = (val + mc->min) * mc->shift;
+
+       return snd_soc_component_update_bits(component, reg, mask, reg_val);
+}
+
+static int q78_put_volsw(struct snd_kcontrol *kcontrol,
+                        struct snd_ctl_elem_value *ucontrol)
+{
+       struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value;
+       struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
+       int ret;
+
+       ret = q78_write(component, mc, mc->reg, ucontrol->value.integer.value[0]);
+       if (ret < 0)
+               return ret;
+
+       if (snd_soc_volsw_is_stereo(mc)) {
+               int err; /* Don't drop change flag */
+
+               err = q78_write(component, mc, mc->rreg, ucontrol->value.integer.value[1]);
+               if (err)
+                       return err;
+       }
+
+       return ret;
+}
+
+static int q78_read(struct snd_soc_component *component,
+                   struct soc_mixer_control *mc, unsigned int reg)
+{
+       unsigned int reg_val;
+       int val;
+
+       reg_val = snd_soc_component_read(component, reg);
+
+       val = (sign_extend32(reg_val, mc->sign_bit) / mc->shift) - mc->min;
+
+       return val & GENMASK(mc->sign_bit, 0);
+}
+
+static int q78_get_volsw(struct snd_kcontrol *kcontrol,
+                        struct snd_ctl_elem_value *ucontrol)
+{
+       struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value;
+       struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
+
+       ucontrol->value.integer.value[0] = q78_read(component, mc, mc->reg);
+
+       if (snd_soc_volsw_is_stereo(mc))
+               ucontrol->value.integer.value[1] = q78_read(component, mc, mc->rreg);
+
+       return 0;
+}
+
 static int control_limit_kctl(struct device *dev,
                              struct sdca_entity *entity,
                              struct sdca_control *control,
@@ -845,10 +909,11 @@ static int control_limit_kctl(struct device *dev,
        mc->max = max / step;
        mc->shift = step;
        mc->sign_bit = 15;
-       mc->sdca_q78 = 1;
 
        kctl->tlv.p = tlv;
        kctl->access |= SNDRV_CTL_ELEM_ACCESS_TLV_READ;
+       kctl->get = q78_get_volsw;
+       kctl->put = q78_put_volsw;
 
        return 0;
 }
index 8ae6609ca961818d7d2ae9668b31de974ceebb6e..0d633f38cfdcaecddaf19cc67f37870337499414 100644 (file)
@@ -110,29 +110,6 @@ int snd_soc_put_enum_double(struct snd_kcontrol *kcontrol,
 }
 EXPORT_SYMBOL_GPL(snd_soc_put_enum_double);
 
-static int sdca_soc_q78_reg_to_ctl(struct soc_mixer_control *mc, unsigned int reg_val,
-                                  unsigned int mask, unsigned int shift, int max,
-                                  bool sx)
-{
-       int val = reg_val;
-
-       if (WARN_ON(!mc->shift))
-               return -EINVAL;
-
-       val = sign_extend32(val, mc->sign_bit);
-
-       return ((val / mc->shift) - mc->min) & mask;
-}
-
-static unsigned int sdca_soc_q78_ctl_to_reg(struct soc_mixer_control *mc, int val,
-                                        unsigned int mask, unsigned int shift, int max)
-{
-       if (WARN_ON(!mc->shift))
-               return -EINVAL;
-
-       return ((val + mc->min) * mc->shift) & mask;
-}
-
 static int soc_mixer_reg_to_ctl(struct soc_mixer_control *mc, unsigned int reg_val,
                                unsigned int mask, unsigned int shift, int max,
                                bool sx)
@@ -226,27 +203,19 @@ static int soc_put_volsw(struct snd_kcontrol *kcontrol,
                         struct snd_ctl_elem_value *ucontrol,
                         struct soc_mixer_control *mc, int mask, int max)
 {
-       unsigned int (*ctl_to_reg)(struct soc_mixer_control *, int, unsigned int, unsigned int, int);
        struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
        unsigned int val1, val_mask;
        unsigned int val2 = 0;
        bool double_r = false;
        int ret;
 
-       if (mc->sdca_q78) {
-               ctl_to_reg = sdca_soc_q78_ctl_to_reg;
-               val_mask = mask;
-       } else {
-               ctl_to_reg = soc_mixer_ctl_to_reg;
-               val_mask = mask << mc->shift;
-       }
-
        ret = soc_mixer_valid_ctl(mc, ucontrol->value.integer.value[0], max);
        if (ret)
                return ret;
 
-       val1 = ctl_to_reg(mc, ucontrol->value.integer.value[0],
+       val1 = soc_mixer_ctl_to_reg(mc, ucontrol->value.integer.value[0],
                                    mask, mc->shift, max);
+       val_mask = mask << mc->shift;
 
        if (snd_soc_volsw_is_stereo(mc)) {
                ret = soc_mixer_valid_ctl(mc, ucontrol->value.integer.value[1], max);
@@ -254,10 +223,14 @@ static int soc_put_volsw(struct snd_kcontrol *kcontrol,
                        return ret;
 
                if (mc->reg == mc->rreg) {
-                       val1 |= ctl_to_reg(mc, ucontrol->value.integer.value[1], mask, mc->rshift, max);
+                       val1 |= soc_mixer_ctl_to_reg(mc,
+                                                    ucontrol->value.integer.value[1],
+                                                    mask, mc->rshift, max);
                        val_mask |= mask << mc->rshift;
                } else {
-                       val2 = ctl_to_reg(mc, ucontrol->value.integer.value[1], mask, mc->shift, max);
+                       val2 = soc_mixer_ctl_to_reg(mc,
+                                                   ucontrol->value.integer.value[1],
+                                                   mask, mc->shift, max);
                        double_r = true;
                }
        }
@@ -281,28 +254,21 @@ static int soc_get_volsw(struct snd_kcontrol *kcontrol,
                         struct snd_ctl_elem_value *ucontrol,
                         struct soc_mixer_control *mc, int mask, int max, bool sx)
 {
-       int (*reg_to_ctl)(struct soc_mixer_control *, unsigned int, unsigned int,
-                         unsigned int, int, bool);
        struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
        unsigned int reg_val;
        int val;
 
-       if (mc->sdca_q78)
-               reg_to_ctl = sdca_soc_q78_reg_to_ctl;
-       else
-               reg_to_ctl = soc_mixer_reg_to_ctl;
-
        reg_val = snd_soc_component_read(component, mc->reg);
-       val = reg_to_ctl(mc, reg_val, mask, mc->shift, max, sx);
+       val = soc_mixer_reg_to_ctl(mc, reg_val, mask, mc->shift, max, sx);
 
        ucontrol->value.integer.value[0] = val;
 
        if (snd_soc_volsw_is_stereo(mc)) {
                if (mc->reg == mc->rreg) {
-                       val = reg_to_ctl(mc, reg_val, mask, mc->rshift, max, sx);
+                       val = soc_mixer_reg_to_ctl(mc, reg_val, mask, mc->rshift, max, sx);
                } else {
                        reg_val = snd_soc_component_read(component, mc->rreg);
-                       val = reg_to_ctl(mc, reg_val, mask, mc->shift, max, sx);
+                       val = soc_mixer_reg_to_ctl(mc, reg_val, mask, mc->shift, max, sx);
                }
 
                ucontrol->value.integer.value[1] = val;