aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sound/soc/codecs/tlv320aic23.c53
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
114static const char *rec_src_text[] = { "Line", "Mic" }; 114static const char *rec_src_text[] = { "Line", "Mic" };
115static const char *deemph_text[] = {"None", "32Khz", "44.1Khz", "48Khz"}; 115static const char *deemph_text[] = {"None", "32Khz", "44.1Khz", "48Khz"};
116static const char *sidetone_text[] = {"-6db", "-9db", "-12db", "-18db", "0db"};
117 116
118static const struct soc_enum rec_src_enum = 117static 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);
126static const struct soc_enum tlv320aic23_deemph = 125static 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);
128static const struct soc_enum tlv320aic23_sidetone =
129 SOC_ENUM_SINGLE(TLV320AIC23_ANLG, 6, 5, sidetone_text);
130 127
131static const DECLARE_TLV_DB_SCALE(out_gain_tlv, -12100, 100, 0); 128static const DECLARE_TLV_DB_SCALE(out_gain_tlv, -12100, 100, 0);
132static const DECLARE_TLV_DB_SCALE(input_gain_tlv, -1725, 75, 0); 129static const DECLARE_TLV_DB_SCALE(input_gain_tlv, -1725, 75, 0);
130static const DECLARE_TLV_DB_SCALE(sidetone_vol_tlv, -1800, 300, 0);
131
132static 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
155static 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
134static const struct snd_kcontrol_new tlv320aic23_snd_controls[] = { 178static 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