aboutsummaryrefslogtreecommitdiffstats
path: root/include/sound
diff options
context:
space:
mode:
authorPeter Ujfalusi <peter.ujfalusi@nokia.com>2010-05-10 07:39:24 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2010-05-11 04:34:11 -0400
commitd11bb4a925613fa814ed4ae350440eb24ebff336 (patch)
tree45332b4ea11ef84f6f33a7eb5a7957453de379a7 /include/sound
parent896060c76bdfd8a45eb33b3dd1a8307fe37f6c04 (diff)
ASoC: core: Fix for the volume limiting when invert is in use
If the register for the volume needs invert, than the inversion need to be done from the chip maximum, and not from the platform dependent limit. Introduce soc_mixer_control.platform_max value, which initially equals to chip maximum. The snd_soc_limit_volume function only modify the platform_max, all volsw_info call returns this as well. The .max value holds the chip default (maximum), and it is used for the inversion, if it is needed. Additional check in the volsw_info call has been added to check the validity of the platform_max in case, when custom macros used by codec drivers are not initializing it correctly. Signed-off-by: Peter Ujfalusi <peter.ujfalusi@nokia.com> Acked-by: Liam Girdwood <lrg@slimlogic.co.uk> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'include/sound')
-rw-r--r--include/sound/soc.h23
1 files changed, 12 insertions, 11 deletions
diff --git a/include/sound/soc.h b/include/sound/soc.h
index 8326fc3db1cf..697e7ffe39d7 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -30,10 +30,10 @@
30#define SOC_SINGLE_VALUE(xreg, xshift, xmax, xinvert) \ 30#define SOC_SINGLE_VALUE(xreg, xshift, xmax, xinvert) \
31 ((unsigned long)&(struct soc_mixer_control) \ 31 ((unsigned long)&(struct soc_mixer_control) \
32 {.reg = xreg, .shift = xshift, .rshift = xshift, .max = xmax, \ 32 {.reg = xreg, .shift = xshift, .rshift = xshift, .max = xmax, \
33 .invert = xinvert}) 33 .platform_max = xmax, .invert = xinvert})
34#define SOC_SINGLE_VALUE_EXT(xreg, xmax, xinvert) \ 34#define SOC_SINGLE_VALUE_EXT(xreg, xmax, xinvert) \
35 ((unsigned long)&(struct soc_mixer_control) \ 35 ((unsigned long)&(struct soc_mixer_control) \
36 {.reg = xreg, .max = xmax, .invert = xinvert}) 36 {.reg = xreg, .max = xmax, .platform_max = xmax, .invert = xinvert})
37#define SOC_SINGLE(xname, reg, shift, max, invert) \ 37#define SOC_SINGLE(xname, reg, shift, max, invert) \
38{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ 38{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
39 .info = snd_soc_info_volsw, .get = snd_soc_get_volsw,\ 39 .info = snd_soc_info_volsw, .get = snd_soc_get_volsw,\
@@ -53,14 +53,14 @@
53 .put = snd_soc_put_volsw, \ 53 .put = snd_soc_put_volsw, \
54 .private_value = (unsigned long)&(struct soc_mixer_control) \ 54 .private_value = (unsigned long)&(struct soc_mixer_control) \
55 {.reg = xreg, .shift = shift_left, .rshift = shift_right, \ 55 {.reg = xreg, .shift = shift_left, .rshift = shift_right, \
56 .max = xmax, .invert = xinvert} } 56 .max = xmax, .platform_max = xmax, .invert = xinvert} }
57#define SOC_DOUBLE_R(xname, reg_left, reg_right, xshift, xmax, xinvert) \ 57#define SOC_DOUBLE_R(xname, reg_left, reg_right, xshift, xmax, xinvert) \
58{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ 58{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
59 .info = snd_soc_info_volsw_2r, \ 59 .info = snd_soc_info_volsw_2r, \
60 .get = snd_soc_get_volsw_2r, .put = snd_soc_put_volsw_2r, \ 60 .get = snd_soc_get_volsw_2r, .put = snd_soc_put_volsw_2r, \
61 .private_value = (unsigned long)&(struct soc_mixer_control) \ 61 .private_value = (unsigned long)&(struct soc_mixer_control) \
62 {.reg = reg_left, .rreg = reg_right, .shift = xshift, \ 62 {.reg = reg_left, .rreg = reg_right, .shift = xshift, \
63 .max = xmax, .invert = xinvert} } 63 .max = xmax, .platform_max = xmax, .invert = xinvert} }
64#define SOC_DOUBLE_TLV(xname, xreg, shift_left, shift_right, xmax, xinvert, tlv_array) \ 64#define SOC_DOUBLE_TLV(xname, xreg, shift_left, shift_right, xmax, xinvert, tlv_array) \
65{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\ 65{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\
66 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\ 66 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
@@ -70,7 +70,7 @@
70 .put = snd_soc_put_volsw, \ 70 .put = snd_soc_put_volsw, \
71 .private_value = (unsigned long)&(struct soc_mixer_control) \ 71 .private_value = (unsigned long)&(struct soc_mixer_control) \
72 {.reg = xreg, .shift = shift_left, .rshift = shift_right,\ 72 {.reg = xreg, .shift = shift_left, .rshift = shift_right,\
73 .max = xmax, .invert = xinvert} } 73 .max = xmax, .platform_max = xmax, .invert = xinvert} }
74#define SOC_DOUBLE_R_TLV(xname, reg_left, reg_right, xshift, xmax, xinvert, tlv_array) \ 74#define SOC_DOUBLE_R_TLV(xname, reg_left, reg_right, xshift, xmax, xinvert, tlv_array) \
75{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\ 75{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\
76 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\ 76 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
@@ -80,7 +80,7 @@
80 .get = snd_soc_get_volsw_2r, .put = snd_soc_put_volsw_2r, \ 80 .get = snd_soc_get_volsw_2r, .put = snd_soc_put_volsw_2r, \
81 .private_value = (unsigned long)&(struct soc_mixer_control) \ 81 .private_value = (unsigned long)&(struct soc_mixer_control) \
82 {.reg = reg_left, .rreg = reg_right, .shift = xshift, \ 82 {.reg = reg_left, .rreg = reg_right, .shift = xshift, \
83 .max = xmax, .invert = xinvert} } 83 .max = xmax, .platform_max = xmax, .invert = xinvert} }
84#define SOC_DOUBLE_S8_TLV(xname, xreg, xmin, xmax, tlv_array) \ 84#define SOC_DOUBLE_S8_TLV(xname, xreg, xmin, xmax, tlv_array) \
85{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ 85{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
86 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \ 86 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
@@ -89,7 +89,8 @@
89 .info = snd_soc_info_volsw_s8, .get = snd_soc_get_volsw_s8, \ 89 .info = snd_soc_info_volsw_s8, .get = snd_soc_get_volsw_s8, \
90 .put = snd_soc_put_volsw_s8, \ 90 .put = snd_soc_put_volsw_s8, \
91 .private_value = (unsigned long)&(struct soc_mixer_control) \ 91 .private_value = (unsigned long)&(struct soc_mixer_control) \
92 {.reg = xreg, .min = xmin, .max = xmax} } 92 {.reg = xreg, .min = xmin, .max = xmax, \
93 .platform_max = xmax} }
93#define SOC_ENUM_DOUBLE(xreg, xshift_l, xshift_r, xmax, xtexts) \ 94#define SOC_ENUM_DOUBLE(xreg, xshift_l, xshift_r, xmax, xtexts) \
94{ .reg = xreg, .shift_l = xshift_l, .shift_r = xshift_r, \ 95{ .reg = xreg, .shift_l = xshift_l, .shift_r = xshift_r, \
95 .max = xmax, .texts = xtexts } 96 .max = xmax, .texts = xtexts }
@@ -126,7 +127,7 @@
126 .get = xhandler_get, .put = xhandler_put, \ 127 .get = xhandler_get, .put = xhandler_put, \
127 .private_value = (unsigned long)&(struct soc_mixer_control) \ 128 .private_value = (unsigned long)&(struct soc_mixer_control) \
128 {.reg = xreg, .shift = shift_left, .rshift = shift_right, \ 129 {.reg = xreg, .shift = shift_left, .rshift = shift_right, \
129 .max = xmax, .invert = xinvert} } 130 .max = xmax, .platform_max = xmax, .invert = xinvert} }
130#define SOC_SINGLE_EXT_TLV(xname, xreg, xshift, xmax, xinvert,\ 131#define SOC_SINGLE_EXT_TLV(xname, xreg, xshift, xmax, xinvert,\
131 xhandler_get, xhandler_put, tlv_array) \ 132 xhandler_get, xhandler_put, tlv_array) \
132{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ 133{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
@@ -146,7 +147,7 @@
146 .get = xhandler_get, .put = xhandler_put, \ 147 .get = xhandler_get, .put = xhandler_put, \
147 .private_value = (unsigned long)&(struct soc_mixer_control) \ 148 .private_value = (unsigned long)&(struct soc_mixer_control) \
148 {.reg = xreg, .shift = shift_left, .rshift = shift_right, \ 149 {.reg = xreg, .shift = shift_left, .rshift = shift_right, \
149 .max = xmax, .invert = xinvert} } 150 .max = xmax, .platform_max = xmax, .invert = xinvert} }
150#define SOC_DOUBLE_R_EXT_TLV(xname, reg_left, reg_right, xshift, xmax, xinvert,\ 151#define SOC_DOUBLE_R_EXT_TLV(xname, reg_left, reg_right, xshift, xmax, xinvert,\
151 xhandler_get, xhandler_put, tlv_array) \ 152 xhandler_get, xhandler_put, tlv_array) \
152{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ 153{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
@@ -157,7 +158,7 @@
157 .get = xhandler_get, .put = xhandler_put, \ 158 .get = xhandler_get, .put = xhandler_put, \
158 .private_value = (unsigned long)&(struct soc_mixer_control) \ 159 .private_value = (unsigned long)&(struct soc_mixer_control) \
159 {.reg = reg_left, .rreg = reg_right, .shift = xshift, \ 160 {.reg = reg_left, .rreg = reg_right, .shift = xshift, \
160 .max = xmax, .invert = xinvert} } 161 .max = xmax, .platform_max = xmax, .invert = xinvert} }
161#define SOC_SINGLE_BOOL_EXT(xname, xdata, xhandler_get, xhandler_put) \ 162#define SOC_SINGLE_BOOL_EXT(xname, xdata, xhandler_get, xhandler_put) \
162{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ 163{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
163 .info = snd_soc_info_bool_ext, \ 164 .info = snd_soc_info_bool_ext, \
@@ -572,7 +573,7 @@ struct snd_soc_pcm_runtime {
572 573
573/* mixer control */ 574/* mixer control */
574struct soc_mixer_control { 575struct soc_mixer_control {
575 int min, max; 576 int min, max, platform_max;
576 unsigned int reg, rreg, shift, rshift, invert; 577 unsigned int reg, rreg, shift, rshift, invert;
577}; 578};
578 579