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.
Unified · Split
| @@ -13,6 +13,8 @@ · 12 unmodified lines | |||
| 13 | struct device; | 13 | struct device; |
| 14 | struct regmap; | 14 | struct regmap; |
| 15 | struct sdca_function_data; | 15 | struct sdca_function_data; |
| 16 | struct snd_ctl_elem_value; | ||
| 17 | struct snd_kcontrol; | ||
| 16 | struct snd_kcontrol_new; | 18 | struct snd_kcontrol_new; |
| 17 | struct snd_pcm_hw_params; | 19 | struct snd_pcm_hw_params; |
| 18 | struct snd_pcm_substream; | 20 | struct snd_pcm_substream; |
| @@ -23,6 +25,42 @@ struct snd_soc_dai_ops; · 4 unmodified lines | |||
| 23 | struct snd_soc_dapm_route; | 25 | struct snd_soc_dapm_route; |
| 24 | struct snd_soc_dapm_widget; | 26 | struct snd_soc_dapm_widget; |
| 25 | 27 | ||
| 28 | /* convenient macro to handle the mono volume in 7.8 fixed format representation */ | ||
| 29 | #define SDCA_SINGLE_Q78_TLV(xname, xreg, xmin, xmax, xstep, tlv_array) \ | ||
| 30 | { \ | ||
| 31 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ | ||
| 32 | .name = (xname), \ | ||
| 33 | .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | SNDRV_CTL_ELEM_ACCESS_READWRITE, \ | ||
| 34 | .tlv.p = (tlv_array), \ | ||
| 35 | .info = snd_soc_info_volsw, \ | ||
| 36 | .get = sdca_asoc_q78_get_volsw, \ | ||
| 37 | .put = sdca_asoc_q78_put_volsw, \ | ||
| 38 | .private_value = (unsigned long)&(struct soc_mixer_control) { \ | ||
| 39 | .reg = (xreg), .rreg = (xreg), \ | ||
| 40 | .min = (xmin), .max = (xmax), \ | ||
| 41 | .shift = (xstep), .rshift = (xstep), \ | ||
| 42 | .sign_bit = 15 \ | ||
| 43 | } \ | ||
| 44 | } | ||
| 45 | |||
| 46 | /* convenient macro for stereo volume in 7.8 fixed format with separate registers for L/R */ | ||
| 47 | #define SDCA_DOUBLE_Q78_TLV(xname, xreg_l, xreg_r, xmin, xmax, xstep, tlv_array) \ | ||
| 48 | { \ | ||
| 49 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ | ||
| 50 | .name = (xname), \ | ||
| 51 | .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | SNDRV_CTL_ELEM_ACCESS_READWRITE, \ | ||
| 52 | .tlv.p = (tlv_array), \ | ||
| 53 | .info = snd_soc_info_volsw, \ | ||
| 54 | .get = sdca_asoc_q78_get_volsw, \ | ||
| 55 | .put = sdca_asoc_q78_put_volsw, \ | ||
| 56 | .private_value = (unsigned long)&(struct soc_mixer_control) { \ | ||
| 57 | .reg = (xreg_l), .rreg = (xreg_r), \ | ||
| 58 | .min = (xmin), .max = (xmax), \ | ||
| 59 | .shift = (xstep), .rshift = (xstep), \ | ||
| 60 | .sign_bit = 15 \ | ||
| 61 | } \ | ||
| 62 | } | ||
| 63 | |||
| 26 | int sdca_asoc_count_component(struct device *dev, struct sdca_function_data *function, | 64 | int sdca_asoc_count_component(struct device *dev, struct sdca_function_data *function, |
| 27 | int *num_widgets, int *num_routes, int *num_controls, | 65 | int *num_widgets, int *num_routes, int *num_controls, |
| 28 | int *num_dais); | 66 | int *num_dais); |
| @@ -57,5 +95,8 @@ int sdca_asoc_hw_params(struct device *dev, struct regmap *regmap, · 28 unmodified lines | |||
| 57 | struct snd_pcm_substream *substream, | 95 | struct snd_pcm_substream *substream, |
| 58 | struct snd_pcm_hw_params *params, | 96 | struct snd_pcm_hw_params *params, |
| 59 | struct snd_soc_dai *dai); | 97 | struct snd_soc_dai *dai); |
| 60 | 98 | int sdca_asoc_q78_put_volsw(struct snd_kcontrol *kcontrol, | |
| 99 | struct snd_ctl_elem_value *ucontrol); | ||
| 100 | int sdca_asoc_q78_get_volsw(struct snd_kcontrol *kcontrol, | ||
| 101 | struct snd_ctl_elem_value *ucontrol); | ||
| 61 | #endif // __SDCA_ASOC_H__ | 102 | #endif // __SDCA_ASOC_H__ |
| @@ -820,8 +820,8 @@ static int q78_write(struct snd_soc_component *component, · 819 unmodified lines | |||
| 820 | return snd_soc_component_update_bits(component, reg, mask, reg_val); | 820 | return snd_soc_component_update_bits(component, reg, mask, reg_val); |
| 821 | } | 821 | } |
| 822 | 822 | ||
| 823 | static int q78_put_volsw(struct snd_kcontrol *kcontrol, | 823 | int sdca_asoc_q78_put_volsw(struct snd_kcontrol *kcontrol, |
| 824 | struct snd_ctl_elem_value *ucontrol) | 824 | struct snd_ctl_elem_value *ucontrol) |
| 825 | { | 825 | { |
| 826 | struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; | 826 | struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; |
| 827 | struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); | 827 | struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); |
| @@ -841,6 +841,7 @@ static int q78_put_volsw(struct snd_kcontrol *kcontrol, · 13 unmodified lines | |||
| 841 | 841 | ||
| 842 | return ret; | 842 | return ret; |
| 843 | } | 843 | } |
| 844 | EXPORT_SYMBOL_NS(sdca_asoc_q78_put_volsw, "SND_SOC_SDCA"); | ||
| 844 | 845 | ||
| 845 | static int q78_read(struct snd_soc_component *component, | 846 | static int q78_read(struct snd_soc_component *component, |
| 846 | struct soc_mixer_control *mc, unsigned int reg) | 847 | struct soc_mixer_control *mc, unsigned int reg) |
| @@ -855,8 +856,8 @@ static int q78_read(struct snd_soc_component *component, · 8 unmodified lines | |||
| 855 | return val & GENMASK(mc->sign_bit, 0); | 856 | return val & GENMASK(mc->sign_bit, 0); |
| 856 | } | 857 | } |
| 857 | 858 | ||
| 858 | static int q78_get_volsw(struct snd_kcontrol *kcontrol, | 859 | int sdca_asoc_q78_get_volsw(struct snd_kcontrol *kcontrol, |
| 859 | struct snd_ctl_elem_value *ucontrol) | 860 | struct snd_ctl_elem_value *ucontrol) |
| 860 | { | 861 | { |
| 861 | struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; | 862 | struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; |
| 862 | struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); | 863 | struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); |
| @@ -868,6 +869,7 @@ static int q78_get_volsw(struct snd_kcontrol *kcontrol, · 5 unmodified lines | |||
| 868 | 869 | ||
| 869 | return 0; | 870 | return 0; |
| 870 | } | 871 | } |
| 872 | EXPORT_SYMBOL_NS(sdca_asoc_q78_get_volsw, "SND_SOC_SDCA"); | ||
| 871 | 873 | ||
| 872 | static int control_limit_kctl(struct device *dev, | 874 | static int control_limit_kctl(struct device *dev, |
| 873 | struct sdca_entity *entity, | 875 | struct sdca_entity *entity, |
| @@ -912,8 +914,8 @@ static int control_limit_kctl(struct device *dev, · 38 unmodified lines | |||
| 912 | 914 | ||
| 913 | kctl->tlv.p = tlv; | 915 | kctl->tlv.p = tlv; |
| 914 | kctl->access |= SNDRV_CTL_ELEM_ACCESS_TLV_READ; | 916 | kctl->access |= SNDRV_CTL_ELEM_ACCESS_TLV_READ; |
| 915 | kctl->get = q78_get_volsw; | 917 | kctl->get = sdca_asoc_q78_get_volsw; |
| 916 | kctl->put = q78_put_volsw; | 918 | kctl->put = sdca_asoc_q78_put_volsw; |
| 917 | 919 | ||
| 918 | return 0; | 920 | return 0; |
| 919 | } | 921 | } |