]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
ASoC: SDCA: Export Q7.8 volume control helpers
authorNiranjan H Y <niranjan.hy@ti.com>
Wed, 1 Apr 2026 13:21:45 +0000 (18:51 +0530)
committerMark Brown <broonie@kernel.org>
Fri, 3 Apr 2026 14:12:38 +0000 (15:12 +0100)
Export the Q7.8 volume control helpers to allow reuse
by other ASoC drivers. These functions handle 16-bit
signed Q7.8 fixed-point format values for volume controls.

Changes include:
- Rename q78_get_volsw to sdca_asoc_q78_get_volsw
- Rename q78_put_volsw to sdca_asoc_q78_put_volsw
- Add a convenience macro SDCA_SINGLE_Q78_TLV and
  SDCA_DOUBLE_Q78_TLV for creating mixer controls

This allows other ASoC drivers to easily implement controls
using the Q7.8 fixed-point format without duplicating code.

Signed-off-by: Niranjan H Y <niranjan.hy@ti.com>
Reviewed-by: Charles Keepax <ckeepax@opensource.cirrus.com>
Link: https://patch.msgid.link/20260401132148.2367-1-niranjan.hy@ti.com
Signed-off-by: Mark Brown <broonie@kernel.org>
include/sound/sdca_asoc.h
sound/soc/sdca/sdca_asoc.c

index aa9124f932189b69f19f8847bac4268df5bafbd1..46a61a52decc5b95fcd3a2bb25d3d7d8802f9961 100644 (file)
@@ -13,6 +13,8 @@
 struct device;
 struct regmap;
 struct sdca_function_data;
+struct snd_ctl_elem_value;
+struct snd_kcontrol;
 struct snd_kcontrol_new;
 struct snd_pcm_hw_params;
 struct snd_pcm_substream;
@@ -23,6 +25,42 @@ struct snd_soc_dai_ops;
 struct snd_soc_dapm_route;
 struct snd_soc_dapm_widget;
 
+/* convenient macro to handle the mono volume in 7.8 fixed format representation */
+#define SDCA_SINGLE_Q78_TLV(xname, xreg, xmin, xmax, xstep, tlv_array) \
+{ \
+       .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
+       .name = (xname), \
+       .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | SNDRV_CTL_ELEM_ACCESS_READWRITE, \
+       .tlv.p = (tlv_array), \
+       .info = snd_soc_info_volsw, \
+       .get = sdca_asoc_q78_get_volsw, \
+       .put = sdca_asoc_q78_put_volsw, \
+       .private_value = (unsigned long)&(struct soc_mixer_control) { \
+               .reg = (xreg), .rreg = (xreg), \
+               .min = (xmin), .max = (xmax), \
+               .shift = (xstep), .rshift = (xstep), \
+               .sign_bit = 15 \
+       } \
+}
+
+/* convenient macro for stereo volume in 7.8 fixed format with separate registers for L/R */
+#define SDCA_DOUBLE_Q78_TLV(xname, xreg_l, xreg_r, xmin, xmax, xstep, tlv_array) \
+{ \
+       .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
+       .name = (xname), \
+       .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | SNDRV_CTL_ELEM_ACCESS_READWRITE, \
+       .tlv.p = (tlv_array), \
+       .info = snd_soc_info_volsw, \
+       .get = sdca_asoc_q78_get_volsw, \
+       .put = sdca_asoc_q78_put_volsw, \
+       .private_value = (unsigned long)&(struct soc_mixer_control) { \
+               .reg = (xreg_l), .rreg = (xreg_r), \
+               .min = (xmin), .max = (xmax), \
+               .shift = (xstep), .rshift = (xstep), \
+               .sign_bit = 15 \
+       } \
+}
+
 int sdca_asoc_count_component(struct device *dev, struct sdca_function_data *function,
                              int *num_widgets, int *num_routes, int *num_controls,
                              int *num_dais);
@@ -57,5 +95,8 @@ int sdca_asoc_hw_params(struct device *dev, struct regmap *regmap,
                        struct snd_pcm_substream *substream,
                        struct snd_pcm_hw_params *params,
                        struct snd_soc_dai *dai);
-
+int sdca_asoc_q78_put_volsw(struct snd_kcontrol *kcontrol,
+                           struct snd_ctl_elem_value *ucontrol);
+int sdca_asoc_q78_get_volsw(struct snd_kcontrol *kcontrol,
+                           struct snd_ctl_elem_value *ucontrol);
 #endif // __SDCA_ASOC_H__
index 7709a4ce26e0978c89c998dfdfac78bbac83e516..2bfc8e5aee31d9f48523a078cca65e6ca134951b 100644 (file)
@@ -820,8 +820,8 @@ static int q78_write(struct snd_soc_component *component,
        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)
+int sdca_asoc_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);
@@ -841,6 +841,7 @@ static int q78_put_volsw(struct snd_kcontrol *kcontrol,
 
        return ret;
 }
+EXPORT_SYMBOL_NS(sdca_asoc_q78_put_volsw, "SND_SOC_SDCA");
 
 static int q78_read(struct snd_soc_component *component,
                    struct soc_mixer_control *mc, unsigned int reg)
@@ -855,8 +856,8 @@ static int q78_read(struct snd_soc_component *component,
        return val & GENMASK(mc->sign_bit, 0);
 }
 
-static int q78_get_volsw(struct snd_kcontrol *kcontrol,
-                        struct snd_ctl_elem_value *ucontrol)
+int sdca_asoc_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);
@@ -868,6 +869,7 @@ static int q78_get_volsw(struct snd_kcontrol *kcontrol,
 
        return 0;
 }
+EXPORT_SYMBOL_NS(sdca_asoc_q78_get_volsw, "SND_SOC_SDCA");
 
 static int control_limit_kctl(struct device *dev,
                              struct sdca_entity *entity,
@@ -912,8 +914,8 @@ static int control_limit_kctl(struct device *dev,
 
        kctl->tlv.p = tlv;
        kctl->access |= SNDRV_CTL_ELEM_ACCESS_TLV_READ;
-       kctl->get = q78_get_volsw;
-       kctl->put = q78_put_volsw;
+       kctl->get = sdca_asoc_q78_get_volsw;
+       kctl->put = sdca_asoc_q78_put_volsw;
 
        return 0;
 }