diff options
Diffstat (limited to 'sound')
-rw-r--r-- | sound/soc/codecs/tlv320aic23.c | 53 |
1 files changed, 49 insertions, 4 deletions
diff --git a/sound/soc/codecs/tlv320aic23.c b/sound/soc/codecs/tlv320aic23.c index c2d35e9de335..bb7cfb80ed45 100644 --- a/sound/soc/codecs/tlv320aic23.c +++ b/sound/soc/codecs/tlv320aic23.c | |||
@@ -113,7 +113,6 @@ static int tlv320aic23_write(struct snd_soc_codec *codec, unsigned int reg, | |||
113 | 113 | ||
114 | static const char *rec_src_text[] = { "Line", "Mic" }; | 114 | static const char *rec_src_text[] = { "Line", "Mic" }; |
115 | static const char *deemph_text[] = {"None", "32Khz", "44.1Khz", "48Khz"}; | 115 | static const char *deemph_text[] = {"None", "32Khz", "44.1Khz", "48Khz"}; |
116 | static const char *sidetone_text[] = {"-6db", "-9db", "-12db", "-18db", "0db"}; | ||
117 | 116 | ||
118 | static const struct soc_enum rec_src_enum = | 117 | static const struct soc_enum rec_src_enum = |
119 | SOC_ENUM_SINGLE(TLV320AIC23_ANLG, 2, 2, rec_src_text); | 118 | SOC_ENUM_SINGLE(TLV320AIC23_ANLG, 2, 2, rec_src_text); |
@@ -125,11 +124,56 @@ static const struct soc_enum tlv320aic23_rec_src = | |||
125 | SOC_ENUM_SINGLE(TLV320AIC23_ANLG, 2, 2, rec_src_text); | 124 | SOC_ENUM_SINGLE(TLV320AIC23_ANLG, 2, 2, rec_src_text); |
126 | static const struct soc_enum tlv320aic23_deemph = | 125 | static const struct soc_enum tlv320aic23_deemph = |
127 | SOC_ENUM_SINGLE(TLV320AIC23_DIGT, 1, 4, deemph_text); | 126 | SOC_ENUM_SINGLE(TLV320AIC23_DIGT, 1, 4, deemph_text); |
128 | static const struct soc_enum tlv320aic23_sidetone = | ||
129 | SOC_ENUM_SINGLE(TLV320AIC23_ANLG, 6, 5, sidetone_text); | ||
130 | 127 | ||
131 | static const DECLARE_TLV_DB_SCALE(out_gain_tlv, -12100, 100, 0); | 128 | static const DECLARE_TLV_DB_SCALE(out_gain_tlv, -12100, 100, 0); |
132 | static const DECLARE_TLV_DB_SCALE(input_gain_tlv, -1725, 75, 0); | 129 | static const DECLARE_TLV_DB_SCALE(input_gain_tlv, -1725, 75, 0); |
130 | static const DECLARE_TLV_DB_SCALE(sidetone_vol_tlv, -1800, 300, 0); | ||
131 | |||
132 | static int snd_soc_tlv320aic23_put_volsw(struct snd_kcontrol *kcontrol, | ||
133 | struct snd_ctl_elem_value *ucontrol) | ||
134 | { | ||
135 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | ||
136 | u16 val, reg; | ||
137 | |||
138 | val = (ucontrol->value.integer.value[0] & 0x07); | ||
139 | |||
140 | /* linear conversion to userspace | ||
141 | * 000 = -6db | ||
142 | * 001 = -9db | ||
143 | * 010 = -12db | ||
144 | * 011 = -18db (Min) | ||
145 | * 100 = 0db (Max) | ||
146 | */ | ||
147 | val = (val >= 4) ? 4 : (3 - val); | ||
148 | |||
149 | reg = tlv320aic23_read_reg_cache(codec, TLV320AIC23_ANLG) & (~0x1C0); | ||
150 | tlv320aic23_write(codec, TLV320AIC23_ANLG, reg | (val << 6)); | ||
151 | |||
152 | return 0; | ||
153 | } | ||
154 | |||
155 | static int snd_soc_tlv320aic23_get_volsw(struct snd_kcontrol *kcontrol, | ||
156 | struct snd_ctl_elem_value *ucontrol) | ||
157 | { | ||
158 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | ||
159 | u16 val; | ||
160 | |||
161 | val = tlv320aic23_read_reg_cache(codec, TLV320AIC23_ANLG) & (0x1C0); | ||
162 | val = val >> 6; | ||
163 | val = (val >= 4) ? 4 : (3 - val); | ||
164 | ucontrol->value.integer.value[0] = val; | ||
165 | return 0; | ||
166 | |||
167 | } | ||
168 | |||
169 | #define SOC_TLV320AIC23_SINGLE_TLV(xname, reg, shift, max, invert, tlv_array) \ | ||
170 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ | ||
171 | .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\ | ||
172 | SNDRV_CTL_ELEM_ACCESS_READWRITE,\ | ||
173 | .tlv.p = (tlv_array), \ | ||
174 | .info = snd_soc_info_volsw, .get = snd_soc_tlv320aic23_get_volsw,\ | ||
175 | .put = snd_soc_tlv320aic23_put_volsw, \ | ||
176 | .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) } | ||
133 | 177 | ||
134 | static const struct snd_kcontrol_new tlv320aic23_snd_controls[] = { | 178 | static const struct snd_kcontrol_new tlv320aic23_snd_controls[] = { |
135 | SOC_DOUBLE_R_TLV("Digital Playback Volume", TLV320AIC23_LCHNVOL, | 179 | SOC_DOUBLE_R_TLV("Digital Playback Volume", TLV320AIC23_LCHNVOL, |
@@ -141,7 +185,8 @@ static const struct snd_kcontrol_new tlv320aic23_snd_controls[] = { | |||
141 | TLV320AIC23_RINVOL, 0, 31, 0, input_gain_tlv), | 185 | TLV320AIC23_RINVOL, 0, 31, 0, input_gain_tlv), |
142 | SOC_SINGLE("Mic Input Switch", TLV320AIC23_ANLG, 1, 1, 1), | 186 | SOC_SINGLE("Mic Input Switch", TLV320AIC23_ANLG, 1, 1, 1), |
143 | SOC_SINGLE("Mic Booster Switch", TLV320AIC23_ANLG, 0, 1, 0), | 187 | SOC_SINGLE("Mic Booster Switch", TLV320AIC23_ANLG, 0, 1, 0), |
144 | SOC_ENUM("Sidetone Gain", tlv320aic23_sidetone), | 188 | SOC_TLV320AIC23_SINGLE_TLV("Sidetone Volume", TLV320AIC23_ANLG, |
189 | 6, 4, 0, sidetone_vol_tlv), | ||
145 | SOC_ENUM("Playback De-emphasis", tlv320aic23_deemph), | 190 | SOC_ENUM("Playback De-emphasis", tlv320aic23_deemph), |
146 | }; | 191 | }; |
147 | 192 | ||