diff options
-rw-r--r-- | include/sound/soc.h | 23 | ||||
-rw-r--r-- | sound/soc/soc-core.c | 30 |
2 files changed, 33 insertions, 20 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 */ |
574 | struct soc_mixer_control { | 575 | struct 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 | ||
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 34f71bf60140..e1043f644730 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c | |||
@@ -2017,18 +2017,22 @@ int snd_soc_info_volsw(struct snd_kcontrol *kcontrol, | |||
2017 | { | 2017 | { |
2018 | struct soc_mixer_control *mc = | 2018 | struct soc_mixer_control *mc = |
2019 | (struct soc_mixer_control *)kcontrol->private_value; | 2019 | (struct soc_mixer_control *)kcontrol->private_value; |
2020 | int max = mc->max; | 2020 | int platform_max; |
2021 | unsigned int shift = mc->shift; | 2021 | unsigned int shift = mc->shift; |
2022 | unsigned int rshift = mc->rshift; | 2022 | unsigned int rshift = mc->rshift; |
2023 | 2023 | ||
2024 | if (max == 1 && !strstr(kcontrol->id.name, " Volume")) | 2024 | if (!mc->platform_max) |
2025 | mc->platform_max = mc->max; | ||
2026 | platform_max = mc->platform_max; | ||
2027 | |||
2028 | if (platform_max == 1 && !strstr(kcontrol->id.name, " Volume")) | ||
2025 | uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; | 2029 | uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; |
2026 | else | 2030 | else |
2027 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | 2031 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; |
2028 | 2032 | ||
2029 | uinfo->count = shift == rshift ? 1 : 2; | 2033 | uinfo->count = shift == rshift ? 1 : 2; |
2030 | uinfo->value.integer.min = 0; | 2034 | uinfo->value.integer.min = 0; |
2031 | uinfo->value.integer.max = max; | 2035 | uinfo->value.integer.max = platform_max; |
2032 | return 0; | 2036 | return 0; |
2033 | } | 2037 | } |
2034 | EXPORT_SYMBOL_GPL(snd_soc_info_volsw); | 2038 | EXPORT_SYMBOL_GPL(snd_soc_info_volsw); |
@@ -2126,16 +2130,20 @@ int snd_soc_info_volsw_2r(struct snd_kcontrol *kcontrol, | |||
2126 | { | 2130 | { |
2127 | struct soc_mixer_control *mc = | 2131 | struct soc_mixer_control *mc = |
2128 | (struct soc_mixer_control *)kcontrol->private_value; | 2132 | (struct soc_mixer_control *)kcontrol->private_value; |
2129 | int max = mc->max; | 2133 | int platform_max; |
2130 | 2134 | ||
2131 | if (max == 1 && !strstr(kcontrol->id.name, " Volume")) | 2135 | if (!mc->platform_max) |
2136 | mc->platform_max = mc->max; | ||
2137 | platform_max = mc->platform_max; | ||
2138 | |||
2139 | if (platform_max == 1 && !strstr(kcontrol->id.name, " Volume")) | ||
2132 | uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; | 2140 | uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; |
2133 | else | 2141 | else |
2134 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | 2142 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; |
2135 | 2143 | ||
2136 | uinfo->count = 2; | 2144 | uinfo->count = 2; |
2137 | uinfo->value.integer.min = 0; | 2145 | uinfo->value.integer.min = 0; |
2138 | uinfo->value.integer.max = max; | 2146 | uinfo->value.integer.max = platform_max; |
2139 | return 0; | 2147 | return 0; |
2140 | } | 2148 | } |
2141 | EXPORT_SYMBOL_GPL(snd_soc_info_volsw_2r); | 2149 | EXPORT_SYMBOL_GPL(snd_soc_info_volsw_2r); |
@@ -2236,13 +2244,17 @@ int snd_soc_info_volsw_s8(struct snd_kcontrol *kcontrol, | |||
2236 | { | 2244 | { |
2237 | struct soc_mixer_control *mc = | 2245 | struct soc_mixer_control *mc = |
2238 | (struct soc_mixer_control *)kcontrol->private_value; | 2246 | (struct soc_mixer_control *)kcontrol->private_value; |
2239 | int max = mc->max; | 2247 | int platform_max; |
2240 | int min = mc->min; | 2248 | int min = mc->min; |
2241 | 2249 | ||
2250 | if (!mc->platform_max) | ||
2251 | mc->platform_max = mc->max; | ||
2252 | platform_max = mc->platform_max; | ||
2253 | |||
2242 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | 2254 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; |
2243 | uinfo->count = 2; | 2255 | uinfo->count = 2; |
2244 | uinfo->value.integer.min = 0; | 2256 | uinfo->value.integer.min = 0; |
2245 | uinfo->value.integer.max = max-min; | 2257 | uinfo->value.integer.max = platform_max - min; |
2246 | return 0; | 2258 | return 0; |
2247 | } | 2259 | } |
2248 | EXPORT_SYMBOL_GPL(snd_soc_info_volsw_s8); | 2260 | EXPORT_SYMBOL_GPL(snd_soc_info_volsw_s8); |
@@ -2331,7 +2343,7 @@ int snd_soc_limit_volume(struct snd_soc_codec *codec, | |||
2331 | if (found) { | 2343 | if (found) { |
2332 | mc = (struct soc_mixer_control *)kctl->private_value; | 2344 | mc = (struct soc_mixer_control *)kctl->private_value; |
2333 | if (max <= mc->max) { | 2345 | if (max <= mc->max) { |
2334 | mc->max = max; | 2346 | mc->platform_max = max; |
2335 | ret = 0; | 2347 | ret = 0; |
2336 | } | 2348 | } |
2337 | } | 2349 | } |