diff options
author | Ola Lilja <ola.o.lilja@stericsson.com> | 2012-06-07 08:00:21 -0400 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2012-06-11 01:19:02 -0400 |
commit | 679d7abdc7543e56abc41b8f4858f31a91259b29 (patch) | |
tree | ba0bf27bf4d20edc6241098720fd1146facf2f0c /sound/soc/codecs/ab8500-codec.c | |
parent | d633edd95dc938f3f5f0d4e431932f4ca042bffb (diff) |
ASoC: codecs: Add AB8500 codec-driver
Add codec-driver for ST-Ericsson AB8500 mixed-signal ASIC.
Signed-off-by: Ola Lilja <ola.o.lilja@stericsson.com>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc/codecs/ab8500-codec.c')
-rw-r--r-- | sound/soc/codecs/ab8500-codec.c | 2521 |
1 files changed, 2521 insertions, 0 deletions
diff --git a/sound/soc/codecs/ab8500-codec.c b/sound/soc/codecs/ab8500-codec.c new file mode 100644 index 000000000000..95dc7d5bb076 --- /dev/null +++ b/sound/soc/codecs/ab8500-codec.c | |||
@@ -0,0 +1,2521 @@ | |||
1 | /* | ||
2 | * Copyright (C) ST-Ericsson SA 2012 | ||
3 | * | ||
4 | * Author: Ola Lilja <ola.o.lilja@stericsson.com>, | ||
5 | * Kristoffer Karlsson <kristoffer.karlsson@stericsson.com>, | ||
6 | * Roger Nilsson <roger.xr.nilsson@stericsson.com>, | ||
7 | * for ST-Ericsson. | ||
8 | * | ||
9 | * Based on the early work done by: | ||
10 | * Mikko J. Lehto <mikko.lehto@symbio.com>, | ||
11 | * Mikko Sarmanne <mikko.sarmanne@symbio.com>, | ||
12 | * Jarmo K. Kuronen <jarmo.kuronen@symbio.com>, | ||
13 | * for ST-Ericsson. | ||
14 | * | ||
15 | * License terms: | ||
16 | * | ||
17 | * This program is free software; you can redistribute it and/or modify it | ||
18 | * under the terms of the GNU General Public License version 2 as published | ||
19 | * by the Free Software Foundation. | ||
20 | */ | ||
21 | |||
22 | #include <linux/kernel.h> | ||
23 | #include <linux/module.h> | ||
24 | #include <linux/device.h> | ||
25 | #include <linux/slab.h> | ||
26 | #include <linux/moduleparam.h> | ||
27 | #include <linux/init.h> | ||
28 | #include <linux/delay.h> | ||
29 | #include <linux/pm.h> | ||
30 | #include <linux/platform_device.h> | ||
31 | #include <linux/mutex.h> | ||
32 | #include <linux/mfd/abx500/ab8500.h> | ||
33 | #include <linux/mfd/abx500.h> | ||
34 | #include <linux/mfd/abx500/ab8500-sysctrl.h> | ||
35 | #include <linux/mfd/abx500/ab8500-codec.h> | ||
36 | #include <linux/regulator/consumer.h> | ||
37 | |||
38 | #include <sound/core.h> | ||
39 | #include <sound/pcm.h> | ||
40 | #include <sound/pcm_params.h> | ||
41 | #include <sound/initval.h> | ||
42 | #include <sound/soc.h> | ||
43 | #include <sound/soc-dapm.h> | ||
44 | #include <sound/tlv.h> | ||
45 | |||
46 | #include "ab8500-codec.h" | ||
47 | |||
48 | /* Macrocell value definitions */ | ||
49 | #define CLK_32K_OUT2_DISABLE 0x01 | ||
50 | #define INACTIVE_RESET_AUDIO 0x02 | ||
51 | #define ENABLE_AUDIO_CLK_TO_AUDIO_BLK 0x10 | ||
52 | #define ENABLE_VINTCORE12_SUPPLY 0x04 | ||
53 | #define GPIO27_DIR_OUTPUT 0x04 | ||
54 | #define GPIO29_DIR_OUTPUT 0x10 | ||
55 | #define GPIO31_DIR_OUTPUT 0x40 | ||
56 | |||
57 | /* Macrocell register definitions */ | ||
58 | #define AB8500_CTRL3_REG 0x0200 | ||
59 | #define AB8500_GPIO_DIR4_REG 0x1013 | ||
60 | |||
61 | /* Nr of FIR/IIR-coeff banks in ANC-block */ | ||
62 | #define AB8500_NR_OF_ANC_COEFF_BANKS 2 | ||
63 | |||
64 | /* Minimum duration to keep ANC IIR Init bit high or | ||
65 | low before proceeding with the configuration sequence */ | ||
66 | #define AB8500_ANC_SM_DELAY 2000 | ||
67 | |||
68 | #define AB8500_FILTER_CONTROL(xname, xcount, xmin, xmax) \ | ||
69 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ | ||
70 | .info = filter_control_info, \ | ||
71 | .get = filter_control_get, .put = filter_control_put, \ | ||
72 | .private_value = (unsigned long)&(struct filter_control) \ | ||
73 | {.count = xcount, .min = xmin, .max = xmax} } | ||
74 | |||
75 | struct filter_control { | ||
76 | long min, max; | ||
77 | unsigned int count; | ||
78 | long value[128]; | ||
79 | }; | ||
80 | |||
81 | /* Sidetone states */ | ||
82 | static const char * const enum_sid_state[] = { | ||
83 | "Unconfigured", | ||
84 | "Apply FIR", | ||
85 | "FIR is configured", | ||
86 | }; | ||
87 | enum sid_state { | ||
88 | SID_UNCONFIGURED = 0, | ||
89 | SID_APPLY_FIR = 1, | ||
90 | SID_FIR_CONFIGURED = 2, | ||
91 | }; | ||
92 | |||
93 | static const char * const enum_anc_state[] = { | ||
94 | "Unconfigured", | ||
95 | "Apply FIR and IIR", | ||
96 | "FIR and IIR are configured", | ||
97 | "Apply FIR", | ||
98 | "FIR is configured", | ||
99 | "Apply IIR", | ||
100 | "IIR is configured" | ||
101 | }; | ||
102 | enum anc_state { | ||
103 | ANC_UNCONFIGURED = 0, | ||
104 | ANC_APPLY_FIR_IIR = 1, | ||
105 | ANC_FIR_IIR_CONFIGURED = 2, | ||
106 | ANC_APPLY_FIR = 3, | ||
107 | ANC_FIR_CONFIGURED = 4, | ||
108 | ANC_APPLY_IIR = 5, | ||
109 | ANC_IIR_CONFIGURED = 6 | ||
110 | }; | ||
111 | |||
112 | /* Analog microphones */ | ||
113 | enum amic_idx { | ||
114 | AMIC_IDX_1A, | ||
115 | AMIC_IDX_1B, | ||
116 | AMIC_IDX_2 | ||
117 | }; | ||
118 | |||
119 | struct ab8500_codec_drvdata_dbg { | ||
120 | struct regulator *vaud; | ||
121 | struct regulator *vamic1; | ||
122 | struct regulator *vamic2; | ||
123 | struct regulator *vdmic; | ||
124 | }; | ||
125 | |||
126 | /* Private data for AB8500 device-driver */ | ||
127 | struct ab8500_codec_drvdata { | ||
128 | /* Sidetone */ | ||
129 | long *sid_fir_values; | ||
130 | enum sid_state sid_status; | ||
131 | |||
132 | /* ANC */ | ||
133 | struct mutex anc_lock; | ||
134 | long *anc_fir_values; | ||
135 | long *anc_iir_values; | ||
136 | enum anc_state anc_status; | ||
137 | }; | ||
138 | |||
139 | static inline const char *amic_micbias_str(enum amic_micbias micbias) | ||
140 | { | ||
141 | switch (micbias) { | ||
142 | case AMIC_MICBIAS_VAMIC1: | ||
143 | return "VAMIC1"; | ||
144 | case AMIC_MICBIAS_VAMIC2: | ||
145 | return "VAMIC2"; | ||
146 | default: | ||
147 | return "Unknown"; | ||
148 | } | ||
149 | } | ||
150 | |||
151 | static inline const char *amic_type_str(enum amic_type type) | ||
152 | { | ||
153 | switch (type) { | ||
154 | case AMIC_TYPE_DIFFERENTIAL: | ||
155 | return "DIFFERENTIAL"; | ||
156 | case AMIC_TYPE_SINGLE_ENDED: | ||
157 | return "SINGLE ENDED"; | ||
158 | default: | ||
159 | return "Unknown"; | ||
160 | } | ||
161 | } | ||
162 | |||
163 | /* | ||
164 | * Read'n'write functions | ||
165 | */ | ||
166 | |||
167 | /* Read a register from the audio-bank of AB8500 */ | ||
168 | static unsigned int ab8500_codec_read_reg(struct snd_soc_codec *codec, | ||
169 | unsigned int reg) | ||
170 | { | ||
171 | int status; | ||
172 | unsigned int value = 0; | ||
173 | |||
174 | u8 value8; | ||
175 | status = abx500_get_register_interruptible(codec->dev, AB8500_AUDIO, | ||
176 | reg, &value8); | ||
177 | if (status < 0) { | ||
178 | dev_err(codec->dev, | ||
179 | "%s: ERROR: Register (0x%02x:0x%02x) read failed (%d).\n", | ||
180 | __func__, (u8)AB8500_AUDIO, (u8)reg, status); | ||
181 | } else { | ||
182 | dev_dbg(codec->dev, | ||
183 | "%s: Read 0x%02x from register 0x%02x:0x%02x\n", | ||
184 | __func__, value8, (u8)AB8500_AUDIO, (u8)reg); | ||
185 | value = (unsigned int)value8; | ||
186 | } | ||
187 | |||
188 | return value; | ||
189 | } | ||
190 | |||
191 | /* Write to a register in the audio-bank of AB8500 */ | ||
192 | static int ab8500_codec_write_reg(struct snd_soc_codec *codec, | ||
193 | unsigned int reg, unsigned int value) | ||
194 | { | ||
195 | int status; | ||
196 | |||
197 | status = abx500_set_register_interruptible(codec->dev, AB8500_AUDIO, | ||
198 | reg, value); | ||
199 | if (status < 0) | ||
200 | dev_err(codec->dev, | ||
201 | "%s: ERROR: Register (%02x:%02x) write failed (%d).\n", | ||
202 | __func__, (u8)AB8500_AUDIO, (u8)reg, status); | ||
203 | else | ||
204 | dev_dbg(codec->dev, | ||
205 | "%s: Wrote 0x%02x into register %02x:%02x\n", | ||
206 | __func__, (u8)value, (u8)AB8500_AUDIO, (u8)reg); | ||
207 | |||
208 | return status; | ||
209 | } | ||
210 | |||
211 | /* | ||
212 | * Controls - DAPM | ||
213 | */ | ||
214 | |||
215 | /* Earpiece */ | ||
216 | |||
217 | /* Earpiece source selector */ | ||
218 | static const char * const enum_ear_lineout_source[] = {"Headset Left", | ||
219 | "Speaker Left"}; | ||
220 | static SOC_ENUM_SINGLE_DECL(dapm_enum_ear_lineout_source, AB8500_DMICFILTCONF, | ||
221 | AB8500_DMICFILTCONF_DA3TOEAR, enum_ear_lineout_source); | ||
222 | static const struct snd_kcontrol_new dapm_ear_lineout_source = | ||
223 | SOC_DAPM_ENUM("Earpiece or LineOut Mono Source", | ||
224 | dapm_enum_ear_lineout_source); | ||
225 | |||
226 | /* LineOut */ | ||
227 | |||
228 | /* LineOut source selector */ | ||
229 | static const char * const enum_lineout_source[] = {"Mono Path", "Stereo Path"}; | ||
230 | static SOC_ENUM_DOUBLE_DECL(dapm_enum_lineout_source, AB8500_ANACONF5, | ||
231 | AB8500_ANACONF5_HSLDACTOLOL, | ||
232 | AB8500_ANACONF5_HSRDACTOLOR, enum_lineout_source); | ||
233 | static const struct snd_kcontrol_new dapm_lineout_source[] = { | ||
234 | SOC_DAPM_ENUM("LineOut Source", dapm_enum_lineout_source), | ||
235 | }; | ||
236 | |||
237 | /* Handsfree */ | ||
238 | |||
239 | /* Speaker Left - ANC selector */ | ||
240 | static const char * const enum_HFx_sel[] = {"Audio Path", "ANC"}; | ||
241 | static SOC_ENUM_SINGLE_DECL(dapm_enum_HFl_sel, AB8500_DIGMULTCONF2, | ||
242 | AB8500_DIGMULTCONF2_HFLSEL, enum_HFx_sel); | ||
243 | static const struct snd_kcontrol_new dapm_HFl_select[] = { | ||
244 | SOC_DAPM_ENUM("Speaker Left Source", dapm_enum_HFl_sel), | ||
245 | }; | ||
246 | |||
247 | /* Speaker Right - ANC selector */ | ||
248 | static SOC_ENUM_SINGLE_DECL(dapm_enum_HFr_sel, AB8500_DIGMULTCONF2, | ||
249 | AB8500_DIGMULTCONF2_HFRSEL, enum_HFx_sel); | ||
250 | static const struct snd_kcontrol_new dapm_HFr_select[] = { | ||
251 | SOC_DAPM_ENUM("Speaker Right Source", dapm_enum_HFr_sel), | ||
252 | }; | ||
253 | |||
254 | /* Mic 1 */ | ||
255 | |||
256 | /* Mic 1 - Mic 1a or 1b selector */ | ||
257 | static const char * const enum_mic1ab_sel[] = {"Mic 1b", "Mic 1a"}; | ||
258 | static SOC_ENUM_SINGLE_DECL(dapm_enum_mic1ab_sel, AB8500_ANACONF3, | ||
259 | AB8500_ANACONF3_MIC1SEL, enum_mic1ab_sel); | ||
260 | static const struct snd_kcontrol_new dapm_mic1ab_mux[] = { | ||
261 | SOC_DAPM_ENUM("Mic 1a or 1b Select", dapm_enum_mic1ab_sel), | ||
262 | }; | ||
263 | |||
264 | /* Mic 1 - AD3 - Mic 1 or DMic 3 selector */ | ||
265 | static const char * const enum_ad3_sel[] = {"Mic 1", "DMic 3"}; | ||
266 | static SOC_ENUM_SINGLE_DECL(dapm_enum_ad3_sel, AB8500_DIGMULTCONF1, | ||
267 | AB8500_DIGMULTCONF1_AD3SEL, enum_ad3_sel); | ||
268 | static const struct snd_kcontrol_new dapm_ad3_select[] = { | ||
269 | SOC_DAPM_ENUM("AD3 Source Select", dapm_enum_ad3_sel), | ||
270 | }; | ||
271 | |||
272 | /* Mic 1 - AD6 - Mic 1 or DMic 6 selector */ | ||
273 | static const char * const enum_ad6_sel[] = {"Mic 1", "DMic 6"}; | ||
274 | static SOC_ENUM_SINGLE_DECL(dapm_enum_ad6_sel, AB8500_DIGMULTCONF1, | ||
275 | AB8500_DIGMULTCONF1_AD6SEL, enum_ad6_sel); | ||
276 | static const struct snd_kcontrol_new dapm_ad6_select[] = { | ||
277 | SOC_DAPM_ENUM("AD6 Source Select", dapm_enum_ad6_sel), | ||
278 | }; | ||
279 | |||
280 | /* Mic 2 */ | ||
281 | |||
282 | /* Mic 2 - AD5 - Mic 2 or DMic 5 selector */ | ||
283 | static const char * const enum_ad5_sel[] = {"Mic 2", "DMic 5"}; | ||
284 | static SOC_ENUM_SINGLE_DECL(dapm_enum_ad5_sel, AB8500_DIGMULTCONF1, | ||
285 | AB8500_DIGMULTCONF1_AD5SEL, enum_ad5_sel); | ||
286 | static const struct snd_kcontrol_new dapm_ad5_select[] = { | ||
287 | SOC_DAPM_ENUM("AD5 Source Select", dapm_enum_ad5_sel), | ||
288 | }; | ||
289 | |||
290 | /* LineIn */ | ||
291 | |||
292 | /* LineIn left - AD1 - LineIn Left or DMic 1 selector */ | ||
293 | static const char * const enum_ad1_sel[] = {"LineIn Left", "DMic 1"}; | ||
294 | static SOC_ENUM_SINGLE_DECL(dapm_enum_ad1_sel, AB8500_DIGMULTCONF1, | ||
295 | AB8500_DIGMULTCONF1_AD1SEL, enum_ad1_sel); | ||
296 | static const struct snd_kcontrol_new dapm_ad1_select[] = { | ||
297 | SOC_DAPM_ENUM("AD1 Source Select", dapm_enum_ad1_sel), | ||
298 | }; | ||
299 | |||
300 | /* LineIn right - Mic 2 or LineIn Right selector */ | ||
301 | static const char * const enum_mic2lr_sel[] = {"Mic 2", "LineIn Right"}; | ||
302 | static SOC_ENUM_SINGLE_DECL(dapm_enum_mic2lr_sel, AB8500_ANACONF3, | ||
303 | AB8500_ANACONF3_LINRSEL, enum_mic2lr_sel); | ||
304 | static const struct snd_kcontrol_new dapm_mic2lr_select[] = { | ||
305 | SOC_DAPM_ENUM("Mic 2 or LINR Select", dapm_enum_mic2lr_sel), | ||
306 | }; | ||
307 | |||
308 | /* LineIn right - AD2 - LineIn Right or DMic2 selector */ | ||
309 | static const char * const enum_ad2_sel[] = {"LineIn Right", "DMic 2"}; | ||
310 | static SOC_ENUM_SINGLE_DECL(dapm_enum_ad2_sel, AB8500_DIGMULTCONF1, | ||
311 | AB8500_DIGMULTCONF1_AD2SEL, enum_ad2_sel); | ||
312 | static const struct snd_kcontrol_new dapm_ad2_select[] = { | ||
313 | SOC_DAPM_ENUM("AD2 Source Select", dapm_enum_ad2_sel), | ||
314 | }; | ||
315 | |||
316 | |||
317 | /* ANC */ | ||
318 | |||
319 | static const char * const enum_anc_in_sel[] = {"Mic 1 / DMic 6", | ||
320 | "Mic 2 / DMic 5"}; | ||
321 | static SOC_ENUM_SINGLE_DECL(dapm_enum_anc_in_sel, AB8500_DMICFILTCONF, | ||
322 | AB8500_DMICFILTCONF_ANCINSEL, enum_anc_in_sel); | ||
323 | static const struct snd_kcontrol_new dapm_anc_in_select[] = { | ||
324 | SOC_DAPM_ENUM("ANC Source", dapm_enum_anc_in_sel), | ||
325 | }; | ||
326 | |||
327 | /* ANC - Enable/Disable */ | ||
328 | static const struct snd_kcontrol_new dapm_anc_enable[] = { | ||
329 | SOC_DAPM_SINGLE("Switch", AB8500_ANCCONF1, | ||
330 | AB8500_ANCCONF1_ENANC, 0, 0), | ||
331 | }; | ||
332 | |||
333 | /* ANC to Earpiece - Mute */ | ||
334 | static const struct snd_kcontrol_new dapm_anc_ear_mute[] = { | ||
335 | SOC_DAPM_SINGLE("Switch", AB8500_DIGMULTCONF1, | ||
336 | AB8500_DIGMULTCONF1_ANCSEL, 1, 0), | ||
337 | }; | ||
338 | |||
339 | |||
340 | |||
341 | /* Sidetone left */ | ||
342 | |||
343 | /* Sidetone left - Input selector */ | ||
344 | static const char * const enum_stfir1_in_sel[] = { | ||
345 | "LineIn Left", "LineIn Right", "Mic 1", "Headset Left" | ||
346 | }; | ||
347 | static SOC_ENUM_SINGLE_DECL(dapm_enum_stfir1_in_sel, AB8500_DIGMULTCONF2, | ||
348 | AB8500_DIGMULTCONF2_FIRSID1SEL, enum_stfir1_in_sel); | ||
349 | static const struct snd_kcontrol_new dapm_stfir1_in_select[] = { | ||
350 | SOC_DAPM_ENUM("Sidetone Left Source", dapm_enum_stfir1_in_sel), | ||
351 | }; | ||
352 | |||
353 | /* Sidetone right path */ | ||
354 | |||
355 | /* Sidetone right - Input selector */ | ||
356 | static const char * const enum_stfir2_in_sel[] = { | ||
357 | "LineIn Right", "Mic 1", "DMic 4", "Headset Right" | ||
358 | }; | ||
359 | static SOC_ENUM_SINGLE_DECL(dapm_enum_stfir2_in_sel, AB8500_DIGMULTCONF2, | ||
360 | AB8500_DIGMULTCONF2_FIRSID2SEL, enum_stfir2_in_sel); | ||
361 | static const struct snd_kcontrol_new dapm_stfir2_in_select[] = { | ||
362 | SOC_DAPM_ENUM("Sidetone Right Source", dapm_enum_stfir2_in_sel), | ||
363 | }; | ||
364 | |||
365 | /* Vibra */ | ||
366 | |||
367 | static const char * const enum_pwm2vibx[] = {"Audio Path", "PWM Generator"}; | ||
368 | |||
369 | static SOC_ENUM_SINGLE_DECL(dapm_enum_pwm2vib1, AB8500_PWMGENCONF1, | ||
370 | AB8500_PWMGENCONF1_PWMTOVIB1, enum_pwm2vibx); | ||
371 | |||
372 | static const struct snd_kcontrol_new dapm_pwm2vib1[] = { | ||
373 | SOC_DAPM_ENUM("Vibra 1 Controller", dapm_enum_pwm2vib1), | ||
374 | }; | ||
375 | |||
376 | static SOC_ENUM_SINGLE_DECL(dapm_enum_pwm2vib2, AB8500_PWMGENCONF1, | ||
377 | AB8500_PWMGENCONF1_PWMTOVIB2, enum_pwm2vibx); | ||
378 | |||
379 | static const struct snd_kcontrol_new dapm_pwm2vib2[] = { | ||
380 | SOC_DAPM_ENUM("Vibra 2 Controller", dapm_enum_pwm2vib2), | ||
381 | }; | ||
382 | |||
383 | /* | ||
384 | * DAPM-widgets | ||
385 | */ | ||
386 | |||
387 | static const struct snd_soc_dapm_widget ab8500_dapm_widgets[] = { | ||
388 | |||
389 | /* Clocks */ | ||
390 | SND_SOC_DAPM_CLOCK_SUPPLY("audioclk"), | ||
391 | |||
392 | /* Regulators */ | ||
393 | SND_SOC_DAPM_REGULATOR_SUPPLY("V-AUD", 0), | ||
394 | SND_SOC_DAPM_REGULATOR_SUPPLY("V-AMIC1", 0), | ||
395 | SND_SOC_DAPM_REGULATOR_SUPPLY("V-AMIC2", 0), | ||
396 | SND_SOC_DAPM_REGULATOR_SUPPLY("V-DMIC", 0), | ||
397 | |||
398 | /* Power */ | ||
399 | SND_SOC_DAPM_SUPPLY("Audio Power", | ||
400 | AB8500_POWERUP, AB8500_POWERUP_POWERUP, 0, | ||
401 | NULL, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | ||
402 | SND_SOC_DAPM_SUPPLY("Audio Analog Power", | ||
403 | AB8500_POWERUP, AB8500_POWERUP_ENANA, 0, | ||
404 | NULL, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | ||
405 | |||
406 | /* Main supply node */ | ||
407 | SND_SOC_DAPM_SUPPLY("Main Supply", SND_SOC_NOPM, 0, 0, | ||
408 | NULL, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | ||
409 | |||
410 | /* DA/AD */ | ||
411 | |||
412 | SND_SOC_DAPM_INPUT("ADC Input"), | ||
413 | SND_SOC_DAPM_ADC("ADC", "ab8500_0c", SND_SOC_NOPM, 0, 0), | ||
414 | |||
415 | SND_SOC_DAPM_DAC("DAC", NULL, SND_SOC_NOPM, 0, 0), | ||
416 | SND_SOC_DAPM_OUTPUT("DAC Output"), | ||
417 | |||
418 | SND_SOC_DAPM_AIF_IN("DA_IN1", NULL, 0, SND_SOC_NOPM, 0, 0), | ||
419 | SND_SOC_DAPM_AIF_IN("DA_IN2", NULL, 0, SND_SOC_NOPM, 0, 0), | ||
420 | SND_SOC_DAPM_AIF_IN("DA_IN3", NULL, 0, SND_SOC_NOPM, 0, 0), | ||
421 | SND_SOC_DAPM_AIF_IN("DA_IN4", NULL, 0, SND_SOC_NOPM, 0, 0), | ||
422 | SND_SOC_DAPM_AIF_IN("DA_IN5", NULL, 0, SND_SOC_NOPM, 0, 0), | ||
423 | SND_SOC_DAPM_AIF_IN("DA_IN6", NULL, 0, SND_SOC_NOPM, 0, 0), | ||
424 | SND_SOC_DAPM_AIF_OUT("AD_OUT1", NULL, 0, SND_SOC_NOPM, 0, 0), | ||
425 | SND_SOC_DAPM_AIF_OUT("AD_OUT2", NULL, 0, SND_SOC_NOPM, 0, 0), | ||
426 | SND_SOC_DAPM_AIF_OUT("AD_OUT3", NULL, 0, SND_SOC_NOPM, 0, 0), | ||
427 | SND_SOC_DAPM_AIF_OUT("AD_OUT4", NULL, 0, SND_SOC_NOPM, 0, 0), | ||
428 | SND_SOC_DAPM_AIF_OUT("AD_OUT57", NULL, 0, SND_SOC_NOPM, 0, 0), | ||
429 | SND_SOC_DAPM_AIF_OUT("AD_OUT68", NULL, 0, SND_SOC_NOPM, 0, 0), | ||
430 | |||
431 | /* Headset path */ | ||
432 | |||
433 | SND_SOC_DAPM_SUPPLY("Charge Pump", AB8500_ANACONF5, | ||
434 | AB8500_ANACONF5_ENCPHS, 0, NULL, 0), | ||
435 | |||
436 | SND_SOC_DAPM_DAC("DA1 Enable", "ab8500_0p", | ||
437 | AB8500_DAPATHENA, AB8500_DAPATHENA_ENDA1, 0), | ||
438 | SND_SOC_DAPM_DAC("DA2 Enable", "ab8500_0p", | ||
439 | AB8500_DAPATHENA, AB8500_DAPATHENA_ENDA2, 0), | ||
440 | |||
441 | SND_SOC_DAPM_PGA("HSL Digital Volume", SND_SOC_NOPM, 0, 0, | ||
442 | NULL, 0), | ||
443 | SND_SOC_DAPM_PGA("HSR Digital Volume", SND_SOC_NOPM, 0, 0, | ||
444 | NULL, 0), | ||
445 | |||
446 | SND_SOC_DAPM_DAC("HSL DAC", "ab8500_0p", | ||
447 | AB8500_DAPATHCONF, AB8500_DAPATHCONF_ENDACHSL, 0), | ||
448 | SND_SOC_DAPM_DAC("HSR DAC", "ab8500_0p", | ||
449 | AB8500_DAPATHCONF, AB8500_DAPATHCONF_ENDACHSR, 0), | ||
450 | SND_SOC_DAPM_MIXER("HSL DAC Mute", AB8500_MUTECONF, | ||
451 | AB8500_MUTECONF_MUTDACHSL, 1, | ||
452 | NULL, 0), | ||
453 | SND_SOC_DAPM_MIXER("HSR DAC Mute", AB8500_MUTECONF, | ||
454 | AB8500_MUTECONF_MUTDACHSR, 1, | ||
455 | NULL, 0), | ||
456 | SND_SOC_DAPM_DAC("HSL DAC Driver", "ab8500_0p", | ||
457 | AB8500_ANACONF3, AB8500_ANACONF3_ENDRVHSL, 0), | ||
458 | SND_SOC_DAPM_DAC("HSR DAC Driver", "ab8500_0p", | ||
459 | AB8500_ANACONF3, AB8500_ANACONF3_ENDRVHSR, 0), | ||
460 | |||
461 | SND_SOC_DAPM_MIXER("HSL Mute", | ||
462 | AB8500_MUTECONF, AB8500_MUTECONF_MUTHSL, 1, | ||
463 | NULL, 0), | ||
464 | SND_SOC_DAPM_MIXER("HSR Mute", | ||
465 | AB8500_MUTECONF, AB8500_MUTECONF_MUTHSR, 1, | ||
466 | NULL, 0), | ||
467 | SND_SOC_DAPM_MIXER("HSL Enable", | ||
468 | AB8500_ANACONF4, AB8500_ANACONF4_ENHSL, 0, | ||
469 | NULL, 0), | ||
470 | SND_SOC_DAPM_MIXER("HSR Enable", | ||
471 | AB8500_ANACONF4, AB8500_ANACONF4_ENHSR, 0, | ||
472 | NULL, 0), | ||
473 | SND_SOC_DAPM_PGA("HSL Volume", | ||
474 | SND_SOC_NOPM, 0, 0, | ||
475 | NULL, 0), | ||
476 | SND_SOC_DAPM_PGA("HSR Volume", | ||
477 | SND_SOC_NOPM, 0, 0, | ||
478 | NULL, 0), | ||
479 | |||
480 | SND_SOC_DAPM_OUTPUT("Headset Left"), | ||
481 | SND_SOC_DAPM_OUTPUT("Headset Right"), | ||
482 | |||
483 | /* LineOut path */ | ||
484 | |||
485 | SND_SOC_DAPM_MUX("LineOut Source", | ||
486 | SND_SOC_NOPM, 0, 0, dapm_lineout_source), | ||
487 | |||
488 | SND_SOC_DAPM_MIXER("LOL Disable HFL", | ||
489 | AB8500_ANACONF4, AB8500_ANACONF4_ENHFL, 1, | ||
490 | NULL, 0), | ||
491 | SND_SOC_DAPM_MIXER("LOR Disable HFR", | ||
492 | AB8500_ANACONF4, AB8500_ANACONF4_ENHFR, 1, | ||
493 | NULL, 0), | ||
494 | |||
495 | SND_SOC_DAPM_MIXER("LOL Enable", | ||
496 | AB8500_ANACONF5, AB8500_ANACONF5_ENLOL, 0, | ||
497 | NULL, 0), | ||
498 | SND_SOC_DAPM_MIXER("LOR Enable", | ||
499 | AB8500_ANACONF5, AB8500_ANACONF5_ENLOR, 0, | ||
500 | NULL, 0), | ||
501 | |||
502 | SND_SOC_DAPM_OUTPUT("LineOut Left"), | ||
503 | SND_SOC_DAPM_OUTPUT("LineOut Right"), | ||
504 | |||
505 | /* Earpiece path */ | ||
506 | |||
507 | SND_SOC_DAPM_MUX("Earpiece or LineOut Mono Source", | ||
508 | SND_SOC_NOPM, 0, 0, &dapm_ear_lineout_source), | ||
509 | SND_SOC_DAPM_MIXER("EAR DAC", | ||
510 | AB8500_DAPATHCONF, AB8500_DAPATHCONF_ENDACEAR, 0, | ||
511 | NULL, 0), | ||
512 | SND_SOC_DAPM_MIXER("EAR Mute", | ||
513 | AB8500_MUTECONF, AB8500_MUTECONF_MUTEAR, 1, | ||
514 | NULL, 0), | ||
515 | SND_SOC_DAPM_MIXER("EAR Enable", | ||
516 | AB8500_ANACONF4, AB8500_ANACONF4_ENEAR, 0, | ||
517 | NULL, 0), | ||
518 | |||
519 | SND_SOC_DAPM_OUTPUT("Earpiece"), | ||
520 | |||
521 | /* Handsfree path */ | ||
522 | |||
523 | SND_SOC_DAPM_MIXER("DA3 Channel Volume", | ||
524 | AB8500_DAPATHENA, AB8500_DAPATHENA_ENDA3, 0, | ||
525 | NULL, 0), | ||
526 | SND_SOC_DAPM_MIXER("DA4 Channel Volume", | ||
527 | AB8500_DAPATHENA, AB8500_DAPATHENA_ENDA4, 0, | ||
528 | NULL, 0), | ||
529 | SND_SOC_DAPM_MUX("Speaker Left Source", | ||
530 | SND_SOC_NOPM, 0, 0, dapm_HFl_select), | ||
531 | SND_SOC_DAPM_MUX("Speaker Right Source", | ||
532 | SND_SOC_NOPM, 0, 0, dapm_HFr_select), | ||
533 | SND_SOC_DAPM_MIXER("HFL DAC", AB8500_DAPATHCONF, | ||
534 | AB8500_DAPATHCONF_ENDACHFL, 0, | ||
535 | NULL, 0), | ||
536 | SND_SOC_DAPM_MIXER("HFR DAC", | ||
537 | AB8500_DAPATHCONF, AB8500_DAPATHCONF_ENDACHFR, 0, | ||
538 | NULL, 0), | ||
539 | SND_SOC_DAPM_MIXER("DA4 or ANC path to HfR", | ||
540 | AB8500_DIGMULTCONF2, AB8500_DIGMULTCONF2_DATOHFREN, 0, | ||
541 | NULL, 0), | ||
542 | SND_SOC_DAPM_MIXER("DA3 or ANC path to HfL", | ||
543 | AB8500_DIGMULTCONF2, AB8500_DIGMULTCONF2_DATOHFLEN, 0, | ||
544 | NULL, 0), | ||
545 | SND_SOC_DAPM_MIXER("HFL Enable", | ||
546 | AB8500_ANACONF4, AB8500_ANACONF4_ENHFL, 0, | ||
547 | NULL, 0), | ||
548 | SND_SOC_DAPM_MIXER("HFR Enable", | ||
549 | AB8500_ANACONF4, AB8500_ANACONF4_ENHFR, 0, | ||
550 | NULL, 0), | ||
551 | |||
552 | SND_SOC_DAPM_OUTPUT("Speaker Left"), | ||
553 | SND_SOC_DAPM_OUTPUT("Speaker Right"), | ||
554 | |||
555 | /* Vibrator path */ | ||
556 | |||
557 | SND_SOC_DAPM_INPUT("PWMGEN1"), | ||
558 | SND_SOC_DAPM_INPUT("PWMGEN2"), | ||
559 | |||
560 | SND_SOC_DAPM_MIXER("DA5 Channel Volume", | ||
561 | AB8500_DAPATHENA, AB8500_DAPATHENA_ENDA5, 0, | ||
562 | NULL, 0), | ||
563 | SND_SOC_DAPM_MIXER("DA6 Channel Volume", | ||
564 | AB8500_DAPATHENA, AB8500_DAPATHENA_ENDA6, 0, | ||
565 | NULL, 0), | ||
566 | SND_SOC_DAPM_MIXER("VIB1 DAC", | ||
567 | AB8500_DAPATHCONF, AB8500_DAPATHCONF_ENDACVIB1, 0, | ||
568 | NULL, 0), | ||
569 | SND_SOC_DAPM_MIXER("VIB2 DAC", | ||
570 | AB8500_DAPATHCONF, AB8500_DAPATHCONF_ENDACVIB2, 0, | ||
571 | NULL, 0), | ||
572 | SND_SOC_DAPM_MUX("Vibra 1 Controller", | ||
573 | SND_SOC_NOPM, 0, 0, dapm_pwm2vib1), | ||
574 | SND_SOC_DAPM_MUX("Vibra 2 Controller", | ||
575 | SND_SOC_NOPM, 0, 0, dapm_pwm2vib2), | ||
576 | SND_SOC_DAPM_MIXER("VIB1 Enable", | ||
577 | AB8500_ANACONF4, AB8500_ANACONF4_ENVIB1, 0, | ||
578 | NULL, 0), | ||
579 | SND_SOC_DAPM_MIXER("VIB2 Enable", | ||
580 | AB8500_ANACONF4, AB8500_ANACONF4_ENVIB2, 0, | ||
581 | NULL, 0), | ||
582 | |||
583 | SND_SOC_DAPM_OUTPUT("Vibra 1"), | ||
584 | SND_SOC_DAPM_OUTPUT("Vibra 2"), | ||
585 | |||
586 | /* Mic 1 */ | ||
587 | |||
588 | SND_SOC_DAPM_INPUT("Mic 1"), | ||
589 | |||
590 | SND_SOC_DAPM_MUX("Mic 1a or 1b Select", | ||
591 | SND_SOC_NOPM, 0, 0, dapm_mic1ab_mux), | ||
592 | SND_SOC_DAPM_MIXER("MIC1 Mute", | ||
593 | AB8500_ANACONF2, AB8500_ANACONF2_MUTMIC1, 1, | ||
594 | NULL, 0), | ||
595 | SND_SOC_DAPM_MIXER("MIC1A V-AMICx Enable", | ||
596 | AB8500_ANACONF2, AB8500_ANACONF2_ENMIC1, 0, | ||
597 | NULL, 0), | ||
598 | SND_SOC_DAPM_MIXER("MIC1B V-AMICx Enable", | ||
599 | AB8500_ANACONF2, AB8500_ANACONF2_ENMIC1, 0, | ||
600 | NULL, 0), | ||
601 | SND_SOC_DAPM_MIXER("MIC1 ADC", | ||
602 | AB8500_ANACONF3, AB8500_ANACONF3_ENADCMIC, 0, | ||
603 | NULL, 0), | ||
604 | SND_SOC_DAPM_MUX("AD3 Source Select", | ||
605 | SND_SOC_NOPM, 0, 0, dapm_ad3_select), | ||
606 | SND_SOC_DAPM_MIXER("AD3 Channel Volume", | ||
607 | SND_SOC_NOPM, 0, 0, | ||
608 | NULL, 0), | ||
609 | SND_SOC_DAPM_MIXER("AD3 Enable", | ||
610 | AB8500_ADPATHENA, AB8500_ADPATHENA_ENAD34, 0, | ||
611 | NULL, 0), | ||
612 | |||
613 | /* Mic 2 */ | ||
614 | |||
615 | SND_SOC_DAPM_INPUT("Mic 2"), | ||
616 | |||
617 | SND_SOC_DAPM_MIXER("MIC2 Mute", | ||
618 | AB8500_ANACONF2, AB8500_ANACONF2_MUTMIC2, 1, | ||
619 | NULL, 0), | ||
620 | SND_SOC_DAPM_MIXER("MIC2 V-AMICx Enable", AB8500_ANACONF2, | ||
621 | AB8500_ANACONF2_ENMIC2, 0, | ||
622 | NULL, 0), | ||
623 | |||
624 | /* LineIn */ | ||
625 | |||
626 | SND_SOC_DAPM_INPUT("LineIn Left"), | ||
627 | SND_SOC_DAPM_INPUT("LineIn Right"), | ||
628 | |||
629 | SND_SOC_DAPM_MIXER("LINL Mute", | ||
630 | AB8500_ANACONF2, AB8500_ANACONF2_MUTLINL, 1, | ||
631 | NULL, 0), | ||
632 | SND_SOC_DAPM_MIXER("LINR Mute", | ||
633 | AB8500_ANACONF2, AB8500_ANACONF2_MUTLINR, 1, | ||
634 | NULL, 0), | ||
635 | SND_SOC_DAPM_MIXER("LINL Enable", AB8500_ANACONF2, | ||
636 | AB8500_ANACONF2_ENLINL, 0, | ||
637 | NULL, 0), | ||
638 | SND_SOC_DAPM_MIXER("LINR Enable", AB8500_ANACONF2, | ||
639 | AB8500_ANACONF2_ENLINR, 0, | ||
640 | NULL, 0), | ||
641 | |||
642 | /* LineIn Bypass path */ | ||
643 | SND_SOC_DAPM_MIXER("LINL to HSL Volume", | ||
644 | SND_SOC_NOPM, 0, 0, | ||
645 | NULL, 0), | ||
646 | SND_SOC_DAPM_MIXER("LINR to HSR Volume", | ||
647 | SND_SOC_NOPM, 0, 0, | ||
648 | NULL, 0), | ||
649 | |||
650 | /* LineIn, Mic 2 */ | ||
651 | SND_SOC_DAPM_MUX("Mic 2 or LINR Select", | ||
652 | SND_SOC_NOPM, 0, 0, dapm_mic2lr_select), | ||
653 | SND_SOC_DAPM_MIXER("LINL ADC", AB8500_ANACONF3, | ||
654 | AB8500_ANACONF3_ENADCLINL, 0, | ||
655 | NULL, 0), | ||
656 | SND_SOC_DAPM_MIXER("LINR ADC", AB8500_ANACONF3, | ||
657 | AB8500_ANACONF3_ENADCLINR, 0, | ||
658 | NULL, 0), | ||
659 | SND_SOC_DAPM_MUX("AD1 Source Select", | ||
660 | SND_SOC_NOPM, 0, 0, dapm_ad1_select), | ||
661 | SND_SOC_DAPM_MUX("AD2 Source Select", | ||
662 | SND_SOC_NOPM, 0, 0, dapm_ad2_select), | ||
663 | SND_SOC_DAPM_MIXER("AD1 Channel Volume", | ||
664 | SND_SOC_NOPM, 0, 0, | ||
665 | NULL, 0), | ||
666 | SND_SOC_DAPM_MIXER("AD2 Channel Volume", | ||
667 | SND_SOC_NOPM, 0, 0, | ||
668 | NULL, 0), | ||
669 | |||
670 | SND_SOC_DAPM_MIXER("AD12 Enable", | ||
671 | AB8500_ADPATHENA, AB8500_ADPATHENA_ENAD12, 0, | ||
672 | NULL, 0), | ||
673 | |||
674 | /* HD Capture path */ | ||
675 | |||
676 | SND_SOC_DAPM_MUX("AD5 Source Select", | ||
677 | SND_SOC_NOPM, 0, 0, dapm_ad5_select), | ||
678 | SND_SOC_DAPM_MUX("AD6 Source Select", | ||
679 | SND_SOC_NOPM, 0, 0, dapm_ad6_select), | ||
680 | SND_SOC_DAPM_MIXER("AD5 Channel Volume", | ||
681 | SND_SOC_NOPM, 0, 0, | ||
682 | NULL, 0), | ||
683 | SND_SOC_DAPM_MIXER("AD6 Channel Volume", | ||
684 | SND_SOC_NOPM, 0, 0, | ||
685 | NULL, 0), | ||
686 | SND_SOC_DAPM_MIXER("AD57 Enable", | ||
687 | AB8500_ADPATHENA, AB8500_ADPATHENA_ENAD5768, 0, | ||
688 | NULL, 0), | ||
689 | SND_SOC_DAPM_MIXER("AD68 Enable", | ||
690 | AB8500_ADPATHENA, AB8500_ADPATHENA_ENAD5768, 0, | ||
691 | NULL, 0), | ||
692 | |||
693 | /* Digital Microphone path */ | ||
694 | |||
695 | SND_SOC_DAPM_INPUT("DMic 1"), | ||
696 | SND_SOC_DAPM_INPUT("DMic 2"), | ||
697 | SND_SOC_DAPM_INPUT("DMic 3"), | ||
698 | SND_SOC_DAPM_INPUT("DMic 4"), | ||
699 | SND_SOC_DAPM_INPUT("DMic 5"), | ||
700 | SND_SOC_DAPM_INPUT("DMic 6"), | ||
701 | |||
702 | SND_SOC_DAPM_MIXER("DMIC1", | ||
703 | AB8500_DIGMICCONF, AB8500_DIGMICCONF_ENDMIC1, 0, | ||
704 | NULL, 0), | ||
705 | SND_SOC_DAPM_MIXER("DMIC2", | ||
706 | AB8500_DIGMICCONF, AB8500_DIGMICCONF_ENDMIC2, 0, | ||
707 | NULL, 0), | ||
708 | SND_SOC_DAPM_MIXER("DMIC3", | ||
709 | AB8500_DIGMICCONF, AB8500_DIGMICCONF_ENDMIC3, 0, | ||
710 | NULL, 0), | ||
711 | SND_SOC_DAPM_MIXER("DMIC4", | ||
712 | AB8500_DIGMICCONF, AB8500_DIGMICCONF_ENDMIC4, 0, | ||
713 | NULL, 0), | ||
714 | SND_SOC_DAPM_MIXER("DMIC5", | ||
715 | AB8500_DIGMICCONF, AB8500_DIGMICCONF_ENDMIC5, 0, | ||
716 | NULL, 0), | ||
717 | SND_SOC_DAPM_MIXER("DMIC6", | ||
718 | AB8500_DIGMICCONF, AB8500_DIGMICCONF_ENDMIC6, 0, | ||
719 | NULL, 0), | ||
720 | SND_SOC_DAPM_MIXER("AD4 Channel Volume", | ||
721 | SND_SOC_NOPM, 0, 0, | ||
722 | NULL, 0), | ||
723 | SND_SOC_DAPM_MIXER("AD4 Enable", | ||
724 | AB8500_ADPATHENA, AB8500_ADPATHENA_ENAD34, | ||
725 | 0, NULL, 0), | ||
726 | |||
727 | /* Acoustical Noise Cancellation path */ | ||
728 | |||
729 | SND_SOC_DAPM_INPUT("ANC Configure Input"), | ||
730 | SND_SOC_DAPM_OUTPUT("ANC Configure Output"), | ||
731 | |||
732 | SND_SOC_DAPM_MUX("ANC Source", | ||
733 | SND_SOC_NOPM, 0, 0, | ||
734 | dapm_anc_in_select), | ||
735 | SND_SOC_DAPM_SWITCH("ANC", | ||
736 | SND_SOC_NOPM, 0, 0, | ||
737 | dapm_anc_enable), | ||
738 | SND_SOC_DAPM_SWITCH("ANC to Earpiece", | ||
739 | SND_SOC_NOPM, 0, 0, | ||
740 | dapm_anc_ear_mute), | ||
741 | |||
742 | /* Sidetone Filter path */ | ||
743 | |||
744 | SND_SOC_DAPM_MUX("Sidetone Left Source", | ||
745 | SND_SOC_NOPM, 0, 0, | ||
746 | dapm_stfir1_in_select), | ||
747 | SND_SOC_DAPM_MUX("Sidetone Right Source", | ||
748 | SND_SOC_NOPM, 0, 0, | ||
749 | dapm_stfir2_in_select), | ||
750 | SND_SOC_DAPM_MIXER("STFIR1 Control", | ||
751 | SND_SOC_NOPM, 0, 0, | ||
752 | NULL, 0), | ||
753 | SND_SOC_DAPM_MIXER("STFIR2 Control", | ||
754 | SND_SOC_NOPM, 0, 0, | ||
755 | NULL, 0), | ||
756 | SND_SOC_DAPM_MIXER("STFIR1 Volume", | ||
757 | SND_SOC_NOPM, 0, 0, | ||
758 | NULL, 0), | ||
759 | SND_SOC_DAPM_MIXER("STFIR2 Volume", | ||
760 | SND_SOC_NOPM, 0, 0, | ||
761 | NULL, 0), | ||
762 | }; | ||
763 | |||
764 | /* | ||
765 | * DAPM-routes | ||
766 | */ | ||
767 | static const struct snd_soc_dapm_route ab8500_dapm_routes[] = { | ||
768 | /* Power AB8500 audio-block when AD/DA is active */ | ||
769 | {"Main Supply", NULL, "V-AUD"}, | ||
770 | {"Main Supply", NULL, "audioclk"}, | ||
771 | {"Main Supply", NULL, "Audio Power"}, | ||
772 | {"Main Supply", NULL, "Audio Analog Power"}, | ||
773 | |||
774 | {"DAC", NULL, "ab8500_0p"}, | ||
775 | {"DAC", NULL, "Main Supply"}, | ||
776 | {"ADC", NULL, "ab8500_0c"}, | ||
777 | {"ADC", NULL, "Main Supply"}, | ||
778 | |||
779 | /* ANC Configure */ | ||
780 | {"ANC Configure Input", NULL, "Main Supply"}, | ||
781 | {"ANC Configure Output", NULL, "ANC Configure Input"}, | ||
782 | |||
783 | /* AD/DA */ | ||
784 | {"ADC", NULL, "ADC Input"}, | ||
785 | {"DAC Output", NULL, "DAC"}, | ||
786 | |||
787 | /* Powerup charge pump if DA1/2 is in use */ | ||
788 | |||
789 | {"DA_IN1", NULL, "ab8500_0p"}, | ||
790 | {"DA_IN1", NULL, "Charge Pump"}, | ||
791 | {"DA_IN2", NULL, "ab8500_0p"}, | ||
792 | {"DA_IN2", NULL, "Charge Pump"}, | ||
793 | |||
794 | /* Headset path */ | ||
795 | |||
796 | {"DA1 Enable", NULL, "DA_IN1"}, | ||
797 | {"DA2 Enable", NULL, "DA_IN2"}, | ||
798 | |||
799 | {"HSL Digital Volume", NULL, "DA1 Enable"}, | ||
800 | {"HSR Digital Volume", NULL, "DA2 Enable"}, | ||
801 | |||
802 | {"HSL DAC", NULL, "HSL Digital Volume"}, | ||
803 | {"HSR DAC", NULL, "HSR Digital Volume"}, | ||
804 | |||
805 | {"HSL DAC Mute", NULL, "HSL DAC"}, | ||
806 | {"HSR DAC Mute", NULL, "HSR DAC"}, | ||
807 | |||
808 | {"HSL DAC Driver", NULL, "HSL DAC Mute"}, | ||
809 | {"HSR DAC Driver", NULL, "HSR DAC Mute"}, | ||
810 | |||
811 | {"HSL Mute", NULL, "HSL DAC Driver"}, | ||
812 | {"HSR Mute", NULL, "HSR DAC Driver"}, | ||
813 | |||
814 | {"HSL Enable", NULL, "HSL Mute"}, | ||
815 | {"HSR Enable", NULL, "HSR Mute"}, | ||
816 | |||
817 | {"HSL Volume", NULL, "HSL Enable"}, | ||
818 | {"HSR Volume", NULL, "HSR Enable"}, | ||
819 | |||
820 | {"Headset Left", NULL, "HSL Volume"}, | ||
821 | {"Headset Right", NULL, "HSR Volume"}, | ||
822 | |||
823 | /* HF or LineOut path */ | ||
824 | |||
825 | {"DA_IN3", NULL, "ab8500_0p"}, | ||
826 | {"DA3 Channel Volume", NULL, "DA_IN3"}, | ||
827 | {"DA_IN4", NULL, "ab8500_0p"}, | ||
828 | {"DA4 Channel Volume", NULL, "DA_IN4"}, | ||
829 | |||
830 | {"Speaker Left Source", "Audio Path", "DA3 Channel Volume"}, | ||
831 | {"Speaker Right Source", "Audio Path", "DA4 Channel Volume"}, | ||
832 | |||
833 | {"DA3 or ANC path to HfL", NULL, "Speaker Left Source"}, | ||
834 | {"DA4 or ANC path to HfR", NULL, "Speaker Right Source"}, | ||
835 | |||
836 | /* HF path */ | ||
837 | |||
838 | {"HFL DAC", NULL, "DA3 or ANC path to HfL"}, | ||
839 | {"HFR DAC", NULL, "DA4 or ANC path to HfR"}, | ||
840 | |||
841 | {"HFL Enable", NULL, "HFL DAC"}, | ||
842 | {"HFR Enable", NULL, "HFR DAC"}, | ||
843 | |||
844 | {"Speaker Left", NULL, "HFL Enable"}, | ||
845 | {"Speaker Right", NULL, "HFR Enable"}, | ||
846 | |||
847 | /* Earpiece path */ | ||
848 | |||
849 | {"Earpiece or LineOut Mono Source", "Headset Left", | ||
850 | "HSL Digital Volume"}, | ||
851 | {"Earpiece or LineOut Mono Source", "Speaker Left", | ||
852 | "DA3 or ANC path to HfL"}, | ||
853 | |||
854 | {"EAR DAC", NULL, "Earpiece or LineOut Mono Source"}, | ||
855 | |||
856 | {"EAR Mute", NULL, "EAR DAC"}, | ||
857 | |||
858 | {"EAR Enable", NULL, "EAR Mute"}, | ||
859 | |||
860 | {"Earpiece", NULL, "EAR Enable"}, | ||
861 | |||
862 | /* LineOut path stereo */ | ||
863 | |||
864 | {"LineOut Source", "Stereo Path", "HSL DAC Driver"}, | ||
865 | {"LineOut Source", "Stereo Path", "HSR DAC Driver"}, | ||
866 | |||
867 | /* LineOut path mono */ | ||
868 | |||
869 | {"LineOut Source", "Mono Path", "EAR DAC"}, | ||
870 | |||
871 | /* LineOut path */ | ||
872 | |||
873 | {"LOL Disable HFL", NULL, "LineOut Source"}, | ||
874 | {"LOR Disable HFR", NULL, "LineOut Source"}, | ||
875 | |||
876 | {"LOL Enable", NULL, "LOL Disable HFL"}, | ||
877 | {"LOR Enable", NULL, "LOR Disable HFR"}, | ||
878 | |||
879 | {"LineOut Left", NULL, "LOL Enable"}, | ||
880 | {"LineOut Right", NULL, "LOR Enable"}, | ||
881 | |||
882 | /* Vibrator path */ | ||
883 | |||
884 | {"DA_IN5", NULL, "ab8500_0p"}, | ||
885 | {"DA5 Channel Volume", NULL, "DA_IN5"}, | ||
886 | {"DA_IN6", NULL, "ab8500_0p"}, | ||
887 | {"DA6 Channel Volume", NULL, "DA_IN6"}, | ||
888 | |||
889 | {"VIB1 DAC", NULL, "DA5 Channel Volume"}, | ||
890 | {"VIB2 DAC", NULL, "DA6 Channel Volume"}, | ||
891 | |||
892 | {"Vibra 1 Controller", "Audio Path", "VIB1 DAC"}, | ||
893 | {"Vibra 2 Controller", "Audio Path", "VIB2 DAC"}, | ||
894 | {"Vibra 1 Controller", "PWM Generator", "PWMGEN1"}, | ||
895 | {"Vibra 2 Controller", "PWM Generator", "PWMGEN2"}, | ||
896 | |||
897 | {"VIB1 Enable", NULL, "Vibra 1 Controller"}, | ||
898 | {"VIB2 Enable", NULL, "Vibra 2 Controller"}, | ||
899 | |||
900 | {"Vibra 1", NULL, "VIB1 Enable"}, | ||
901 | {"Vibra 2", NULL, "VIB2 Enable"}, | ||
902 | |||
903 | |||
904 | /* Mic 2 */ | ||
905 | |||
906 | {"MIC2 V-AMICx Enable", NULL, "Mic 2"}, | ||
907 | |||
908 | /* LineIn */ | ||
909 | {"LINL Mute", NULL, "LineIn Left"}, | ||
910 | {"LINR Mute", NULL, "LineIn Right"}, | ||
911 | |||
912 | {"LINL Enable", NULL, "LINL Mute"}, | ||
913 | {"LINR Enable", NULL, "LINR Mute"}, | ||
914 | |||
915 | /* LineIn, Mic 2 */ | ||
916 | {"Mic 2 or LINR Select", "LineIn Right", "LINR Enable"}, | ||
917 | {"Mic 2 or LINR Select", "Mic 2", "MIC2 V-AMICx Enable"}, | ||
918 | |||
919 | {"LINL ADC", NULL, "LINL Enable"}, | ||
920 | {"LINR ADC", NULL, "Mic 2 or LINR Select"}, | ||
921 | |||
922 | {"AD1 Source Select", "LineIn Left", "LINL ADC"}, | ||
923 | {"AD2 Source Select", "LineIn Right", "LINR ADC"}, | ||
924 | |||
925 | {"AD1 Channel Volume", NULL, "AD1 Source Select"}, | ||
926 | {"AD2 Channel Volume", NULL, "AD2 Source Select"}, | ||
927 | |||
928 | {"AD12 Enable", NULL, "AD1 Channel Volume"}, | ||
929 | {"AD12 Enable", NULL, "AD2 Channel Volume"}, | ||
930 | |||
931 | {"AD_OUT1", NULL, "ab8500_0c"}, | ||
932 | {"AD_OUT1", NULL, "AD12 Enable"}, | ||
933 | {"AD_OUT2", NULL, "ab8500_0c"}, | ||
934 | {"AD_OUT2", NULL, "AD12 Enable"}, | ||
935 | |||
936 | /* Mic 1 */ | ||
937 | |||
938 | {"MIC1 Mute", NULL, "Mic 1"}, | ||
939 | |||
940 | {"MIC1A V-AMICx Enable", NULL, "MIC1 Mute"}, | ||
941 | {"MIC1B V-AMICx Enable", NULL, "MIC1 Mute"}, | ||
942 | |||
943 | {"Mic 1a or 1b Select", "Mic 1a", "MIC1A V-AMICx Enable"}, | ||
944 | {"Mic 1a or 1b Select", "Mic 1b", "MIC1B V-AMICx Enable"}, | ||
945 | |||
946 | {"MIC1 ADC", NULL, "Mic 1a or 1b Select"}, | ||
947 | |||
948 | {"AD3 Source Select", "Mic 1", "MIC1 ADC"}, | ||
949 | |||
950 | {"AD3 Channel Volume", NULL, "AD3 Source Select"}, | ||
951 | |||
952 | {"AD3 Enable", NULL, "AD3 Channel Volume"}, | ||
953 | |||
954 | {"AD_OUT3", NULL, "ab8500_0c"}, | ||
955 | {"AD_OUT3", NULL, "AD3 Enable"}, | ||
956 | |||
957 | /* HD Capture path */ | ||
958 | |||
959 | {"AD5 Source Select", "Mic 2", "LINR ADC"}, | ||
960 | {"AD6 Source Select", "Mic 1", "MIC1 ADC"}, | ||
961 | |||
962 | {"AD5 Channel Volume", NULL, "AD5 Source Select"}, | ||
963 | {"AD6 Channel Volume", NULL, "AD6 Source Select"}, | ||
964 | |||
965 | {"AD57 Enable", NULL, "AD5 Channel Volume"}, | ||
966 | {"AD68 Enable", NULL, "AD6 Channel Volume"}, | ||
967 | |||
968 | {"AD_OUT57", NULL, "ab8500_0c"}, | ||
969 | {"AD_OUT57", NULL, "AD57 Enable"}, | ||
970 | {"AD_OUT68", NULL, "ab8500_0c"}, | ||
971 | {"AD_OUT68", NULL, "AD68 Enable"}, | ||
972 | |||
973 | /* Digital Microphone path */ | ||
974 | |||
975 | {"DMic 1", NULL, "V-DMIC"}, | ||
976 | {"DMic 2", NULL, "V-DMIC"}, | ||
977 | {"DMic 3", NULL, "V-DMIC"}, | ||
978 | {"DMic 4", NULL, "V-DMIC"}, | ||
979 | {"DMic 5", NULL, "V-DMIC"}, | ||
980 | {"DMic 6", NULL, "V-DMIC"}, | ||
981 | |||
982 | {"AD1 Source Select", NULL, "DMic 1"}, | ||
983 | {"AD2 Source Select", NULL, "DMic 2"}, | ||
984 | {"AD3 Source Select", NULL, "DMic 3"}, | ||
985 | {"AD5 Source Select", NULL, "DMic 5"}, | ||
986 | {"AD6 Source Select", NULL, "DMic 6"}, | ||
987 | |||
988 | {"AD4 Channel Volume", NULL, "DMic 4"}, | ||
989 | {"AD4 Enable", NULL, "AD4 Channel Volume"}, | ||
990 | |||
991 | {"AD_OUT4", NULL, "ab8500_0c"}, | ||
992 | {"AD_OUT4", NULL, "AD4 Enable"}, | ||
993 | |||
994 | /* LineIn Bypass path */ | ||
995 | |||
996 | {"LINL to HSL Volume", NULL, "LINL Enable"}, | ||
997 | {"LINR to HSR Volume", NULL, "LINR Enable"}, | ||
998 | |||
999 | {"HSL DAC Driver", NULL, "LINL to HSL Volume"}, | ||
1000 | {"HSR DAC Driver", NULL, "LINR to HSR Volume"}, | ||
1001 | |||
1002 | /* ANC path (Acoustic Noise Cancellation) */ | ||
1003 | |||
1004 | {"ANC Source", "Mic 2 / DMic 5", "AD5 Channel Volume"}, | ||
1005 | {"ANC Source", "Mic 1 / DMic 6", "AD6 Channel Volume"}, | ||
1006 | |||
1007 | {"ANC", "Switch", "ANC Source"}, | ||
1008 | |||
1009 | {"Speaker Left Source", "ANC", "ANC"}, | ||
1010 | {"Speaker Right Source", "ANC", "ANC"}, | ||
1011 | {"ANC to Earpiece", "Switch", "ANC"}, | ||
1012 | |||
1013 | {"HSL Digital Volume", NULL, "ANC to Earpiece"}, | ||
1014 | |||
1015 | /* Sidetone Filter path */ | ||
1016 | |||
1017 | {"Sidetone Left Source", "LineIn Left", "AD12 Enable"}, | ||
1018 | {"Sidetone Left Source", "LineIn Right", "AD12 Enable"}, | ||
1019 | {"Sidetone Left Source", "Mic 1", "AD3 Enable"}, | ||
1020 | {"Sidetone Left Source", "Headset Left", "DA_IN1"}, | ||
1021 | {"Sidetone Right Source", "LineIn Right", "AD12 Enable"}, | ||
1022 | {"Sidetone Right Source", "Mic 1", "AD3 Enable"}, | ||
1023 | {"Sidetone Right Source", "DMic 4", "AD4 Enable"}, | ||
1024 | {"Sidetone Right Source", "Headset Right", "DA_IN2"}, | ||
1025 | |||
1026 | {"STFIR1 Control", NULL, "Sidetone Left Source"}, | ||
1027 | {"STFIR2 Control", NULL, "Sidetone Right Source"}, | ||
1028 | |||
1029 | {"STFIR1 Volume", NULL, "STFIR1 Control"}, | ||
1030 | {"STFIR2 Volume", NULL, "STFIR2 Control"}, | ||
1031 | |||
1032 | {"DA1 Enable", NULL, "STFIR1 Volume"}, | ||
1033 | {"DA2 Enable", NULL, "STFIR2 Volume"}, | ||
1034 | }; | ||
1035 | |||
1036 | static const struct snd_soc_dapm_route ab8500_dapm_routes_mic1a_vamicx[] = { | ||
1037 | {"MIC1A V-AMICx Enable", NULL, "V-AMIC1"}, | ||
1038 | {"MIC1A V-AMICx Enable", NULL, "V-AMIC2"}, | ||
1039 | }; | ||
1040 | |||
1041 | static const struct snd_soc_dapm_route ab8500_dapm_routes_mic1b_vamicx[] = { | ||
1042 | {"MIC1B V-AMICx Enable", NULL, "V-AMIC1"}, | ||
1043 | {"MIC1B V-AMICx Enable", NULL, "V-AMIC2"}, | ||
1044 | }; | ||
1045 | |||
1046 | static const struct snd_soc_dapm_route ab8500_dapm_routes_mic2_vamicx[] = { | ||
1047 | {"MIC2 V-AMICx Enable", NULL, "V-AMIC1"}, | ||
1048 | {"MIC2 V-AMICx Enable", NULL, "V-AMIC2"}, | ||
1049 | }; | ||
1050 | |||
1051 | /* ANC FIR-coefficients configuration sequence */ | ||
1052 | static void anc_fir(struct snd_soc_codec *codec, | ||
1053 | unsigned int bnk, unsigned int par, unsigned int val) | ||
1054 | { | ||
1055 | if (par == 0 && bnk == 0) | ||
1056 | snd_soc_update_bits(codec, AB8500_ANCCONF1, | ||
1057 | BIT(AB8500_ANCCONF1_ANCFIRUPDATE), | ||
1058 | BIT(AB8500_ANCCONF1_ANCFIRUPDATE)); | ||
1059 | |||
1060 | snd_soc_write(codec, AB8500_ANCCONF5, val >> 8 & 0xff); | ||
1061 | snd_soc_write(codec, AB8500_ANCCONF6, val & 0xff); | ||
1062 | |||
1063 | if (par == AB8500_ANC_FIR_COEFFS - 1 && bnk == 1) | ||
1064 | snd_soc_update_bits(codec, AB8500_ANCCONF1, | ||
1065 | BIT(AB8500_ANCCONF1_ANCFIRUPDATE), 0); | ||
1066 | } | ||
1067 | |||
1068 | /* ANC IIR-coefficients configuration sequence */ | ||
1069 | static void anc_iir(struct snd_soc_codec *codec, unsigned int bnk, | ||
1070 | unsigned int par, unsigned int val) | ||
1071 | { | ||
1072 | if (par == 0) { | ||
1073 | if (bnk == 0) { | ||
1074 | snd_soc_update_bits(codec, AB8500_ANCCONF1, | ||
1075 | BIT(AB8500_ANCCONF1_ANCIIRINIT), | ||
1076 | BIT(AB8500_ANCCONF1_ANCIIRINIT)); | ||
1077 | usleep_range(AB8500_ANC_SM_DELAY, AB8500_ANC_SM_DELAY); | ||
1078 | snd_soc_update_bits(codec, AB8500_ANCCONF1, | ||
1079 | BIT(AB8500_ANCCONF1_ANCIIRINIT), 0); | ||
1080 | usleep_range(AB8500_ANC_SM_DELAY, AB8500_ANC_SM_DELAY); | ||
1081 | } else { | ||
1082 | snd_soc_update_bits(codec, AB8500_ANCCONF1, | ||
1083 | BIT(AB8500_ANCCONF1_ANCIIRUPDATE), | ||
1084 | BIT(AB8500_ANCCONF1_ANCIIRUPDATE)); | ||
1085 | } | ||
1086 | } else if (par > 3) { | ||
1087 | snd_soc_write(codec, AB8500_ANCCONF7, 0); | ||
1088 | snd_soc_write(codec, AB8500_ANCCONF8, val >> 16 & 0xff); | ||
1089 | } | ||
1090 | |||
1091 | snd_soc_write(codec, AB8500_ANCCONF7, val >> 8 & 0xff); | ||
1092 | snd_soc_write(codec, AB8500_ANCCONF8, val & 0xff); | ||
1093 | |||
1094 | if (par == AB8500_ANC_IIR_COEFFS - 1 && bnk == 1) | ||
1095 | snd_soc_update_bits(codec, AB8500_ANCCONF1, | ||
1096 | BIT(AB8500_ANCCONF1_ANCIIRUPDATE), 0); | ||
1097 | } | ||
1098 | |||
1099 | /* ANC IIR-/FIR-coefficients configuration sequence */ | ||
1100 | static void anc_configure(struct snd_soc_codec *codec, | ||
1101 | bool apply_fir, bool apply_iir) | ||
1102 | { | ||
1103 | struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(codec->dev); | ||
1104 | unsigned int bnk, par, val; | ||
1105 | |||
1106 | dev_dbg(codec->dev, "%s: Enter.\n", __func__); | ||
1107 | |||
1108 | if (apply_fir) | ||
1109 | snd_soc_update_bits(codec, AB8500_ANCCONF1, | ||
1110 | BIT(AB8500_ANCCONF1_ENANC), 0); | ||
1111 | |||
1112 | snd_soc_update_bits(codec, AB8500_ANCCONF1, | ||
1113 | BIT(AB8500_ANCCONF1_ENANC), BIT(AB8500_ANCCONF1_ENANC)); | ||
1114 | |||
1115 | if (apply_fir) | ||
1116 | for (bnk = 0; bnk < AB8500_NR_OF_ANC_COEFF_BANKS; bnk++) | ||
1117 | for (par = 0; par < AB8500_ANC_FIR_COEFFS; par++) { | ||
1118 | val = snd_soc_read(codec, | ||
1119 | drvdata->anc_fir_values[par]); | ||
1120 | anc_fir(codec, bnk, par, val); | ||
1121 | } | ||
1122 | |||
1123 | if (apply_iir) | ||
1124 | for (bnk = 0; bnk < AB8500_NR_OF_ANC_COEFF_BANKS; bnk++) | ||
1125 | for (par = 0; par < AB8500_ANC_IIR_COEFFS; par++) { | ||
1126 | val = snd_soc_read(codec, | ||
1127 | drvdata->anc_iir_values[par]); | ||
1128 | anc_iir(codec, bnk, par, val); | ||
1129 | } | ||
1130 | |||
1131 | dev_dbg(codec->dev, "%s: Exit.\n", __func__); | ||
1132 | } | ||
1133 | |||
1134 | /* | ||
1135 | * Control-events | ||
1136 | */ | ||
1137 | |||
1138 | static int sid_status_control_get(struct snd_kcontrol *kcontrol, | ||
1139 | struct snd_ctl_elem_value *ucontrol) | ||
1140 | { | ||
1141 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | ||
1142 | struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(codec->dev); | ||
1143 | |||
1144 | mutex_lock(&codec->mutex); | ||
1145 | ucontrol->value.integer.value[0] = drvdata->sid_status; | ||
1146 | mutex_unlock(&codec->mutex); | ||
1147 | |||
1148 | return 0; | ||
1149 | } | ||
1150 | |||
1151 | /* Write sidetone FIR-coefficients configuration sequence */ | ||
1152 | static int sid_status_control_put(struct snd_kcontrol *kcontrol, | ||
1153 | struct snd_ctl_elem_value *ucontrol) | ||
1154 | { | ||
1155 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | ||
1156 | struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(codec->dev); | ||
1157 | unsigned int param, sidconf, val; | ||
1158 | int status = 1; | ||
1159 | |||
1160 | dev_dbg(codec->dev, "%s: Enter\n", __func__); | ||
1161 | |||
1162 | if (ucontrol->value.integer.value[0] != SID_APPLY_FIR) { | ||
1163 | dev_err(codec->dev, | ||
1164 | "%s: ERROR: This control supports '%s' only!\n", | ||
1165 | __func__, enum_sid_state[SID_APPLY_FIR]); | ||
1166 | return -EIO; | ||
1167 | } | ||
1168 | |||
1169 | mutex_lock(&codec->mutex); | ||
1170 | |||
1171 | sidconf = snd_soc_read(codec, AB8500_SIDFIRCONF); | ||
1172 | if (((sidconf & BIT(AB8500_SIDFIRCONF_FIRSIDBUSY)) != 0)) { | ||
1173 | if ((sidconf & BIT(AB8500_SIDFIRCONF_ENFIRSIDS)) == 0) { | ||
1174 | dev_err(codec->dev, "%s: Sidetone busy while off!\n", | ||
1175 | __func__); | ||
1176 | status = -EPERM; | ||
1177 | } else { | ||
1178 | status = -EBUSY; | ||
1179 | } | ||
1180 | goto out; | ||
1181 | } | ||
1182 | |||
1183 | snd_soc_write(codec, AB8500_SIDFIRADR, 0); | ||
1184 | |||
1185 | for (param = 0; param < AB8500_SID_FIR_COEFFS; param++) { | ||
1186 | val = snd_soc_read(codec, drvdata->sid_fir_values[param]); | ||
1187 | snd_soc_write(codec, AB8500_SIDFIRCOEF1, val >> 8 & 0xff); | ||
1188 | snd_soc_write(codec, AB8500_SIDFIRCOEF2, val & 0xff); | ||
1189 | } | ||
1190 | |||
1191 | snd_soc_update_bits(codec, AB8500_SIDFIRADR, | ||
1192 | BIT(AB8500_SIDFIRADR_FIRSIDSET), | ||
1193 | BIT(AB8500_SIDFIRADR_FIRSIDSET)); | ||
1194 | snd_soc_update_bits(codec, AB8500_SIDFIRADR, | ||
1195 | BIT(AB8500_SIDFIRADR_FIRSIDSET), 0); | ||
1196 | |||
1197 | drvdata->sid_status = SID_FIR_CONFIGURED; | ||
1198 | |||
1199 | out: | ||
1200 | mutex_unlock(&codec->mutex); | ||
1201 | |||
1202 | dev_dbg(codec->dev, "%s: Exit\n", __func__); | ||
1203 | |||
1204 | return status; | ||
1205 | } | ||
1206 | |||
1207 | static int anc_status_control_get(struct snd_kcontrol *kcontrol, | ||
1208 | struct snd_ctl_elem_value *ucontrol) | ||
1209 | { | ||
1210 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | ||
1211 | struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(codec->dev); | ||
1212 | |||
1213 | mutex_lock(&codec->mutex); | ||
1214 | ucontrol->value.integer.value[0] = drvdata->anc_status; | ||
1215 | mutex_unlock(&codec->mutex); | ||
1216 | |||
1217 | return 0; | ||
1218 | } | ||
1219 | |||
1220 | static int anc_status_control_put(struct snd_kcontrol *kcontrol, | ||
1221 | struct snd_ctl_elem_value *ucontrol) | ||
1222 | { | ||
1223 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | ||
1224 | struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(codec->dev); | ||
1225 | struct device *dev = codec->dev; | ||
1226 | bool apply_fir, apply_iir; | ||
1227 | int req, status; | ||
1228 | |||
1229 | dev_dbg(dev, "%s: Enter.\n", __func__); | ||
1230 | |||
1231 | mutex_lock(&drvdata->anc_lock); | ||
1232 | |||
1233 | req = ucontrol->value.integer.value[0]; | ||
1234 | if (req != ANC_APPLY_FIR_IIR && req != ANC_APPLY_FIR && | ||
1235 | req != ANC_APPLY_IIR) { | ||
1236 | dev_err(dev, "%s: ERROR: Unsupported status to set '%s'!\n", | ||
1237 | __func__, enum_anc_state[req]); | ||
1238 | return -EINVAL; | ||
1239 | } | ||
1240 | apply_fir = req == ANC_APPLY_FIR || req == ANC_APPLY_FIR_IIR; | ||
1241 | apply_iir = req == ANC_APPLY_IIR || req == ANC_APPLY_FIR_IIR; | ||
1242 | |||
1243 | status = snd_soc_dapm_force_enable_pin(&codec->dapm, | ||
1244 | "ANC Configure Input"); | ||
1245 | if (status < 0) { | ||
1246 | dev_err(dev, | ||
1247 | "%s: ERROR: Failed to enable power (status = %d)!\n", | ||
1248 | __func__, status); | ||
1249 | goto cleanup; | ||
1250 | } | ||
1251 | snd_soc_dapm_sync(&codec->dapm); | ||
1252 | |||
1253 | mutex_lock(&codec->mutex); | ||
1254 | anc_configure(codec, apply_fir, apply_iir); | ||
1255 | mutex_unlock(&codec->mutex); | ||
1256 | |||
1257 | if (apply_fir) { | ||
1258 | if (drvdata->anc_status == ANC_IIR_CONFIGURED) | ||
1259 | drvdata->anc_status = ANC_FIR_IIR_CONFIGURED; | ||
1260 | else if (drvdata->anc_status != ANC_FIR_IIR_CONFIGURED) | ||
1261 | drvdata->anc_status = ANC_FIR_CONFIGURED; | ||
1262 | } | ||
1263 | if (apply_iir) { | ||
1264 | if (drvdata->anc_status == ANC_FIR_CONFIGURED) | ||
1265 | drvdata->anc_status = ANC_FIR_IIR_CONFIGURED; | ||
1266 | else if (drvdata->anc_status != ANC_FIR_IIR_CONFIGURED) | ||
1267 | drvdata->anc_status = ANC_IIR_CONFIGURED; | ||
1268 | } | ||
1269 | |||
1270 | status = snd_soc_dapm_disable_pin(&codec->dapm, "ANC Configure Input"); | ||
1271 | snd_soc_dapm_sync(&codec->dapm); | ||
1272 | |||
1273 | cleanup: | ||
1274 | mutex_unlock(&drvdata->anc_lock); | ||
1275 | |||
1276 | if (status < 0) | ||
1277 | dev_err(dev, "%s: Unable to configure ANC! (status = %d)\n", | ||
1278 | __func__, status); | ||
1279 | |||
1280 | dev_dbg(dev, "%s: Exit.\n", __func__); | ||
1281 | |||
1282 | return (status < 0) ? status : 1; | ||
1283 | } | ||
1284 | |||
1285 | static int filter_control_info(struct snd_kcontrol *kcontrol, | ||
1286 | struct snd_ctl_elem_info *uinfo) | ||
1287 | { | ||
1288 | struct filter_control *fc = | ||
1289 | (struct filter_control *)kcontrol->private_value; | ||
1290 | |||
1291 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | ||
1292 | uinfo->count = fc->count; | ||
1293 | uinfo->value.integer.min = fc->min; | ||
1294 | uinfo->value.integer.max = fc->max; | ||
1295 | |||
1296 | return 0; | ||
1297 | } | ||
1298 | |||
1299 | static int filter_control_get(struct snd_kcontrol *kcontrol, | ||
1300 | struct snd_ctl_elem_value *ucontrol) | ||
1301 | { | ||
1302 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | ||
1303 | struct filter_control *fc = | ||
1304 | (struct filter_control *)kcontrol->private_value; | ||
1305 | unsigned int i; | ||
1306 | |||
1307 | mutex_lock(&codec->mutex); | ||
1308 | for (i = 0; i < fc->count; i++) | ||
1309 | ucontrol->value.integer.value[i] = fc->value[i]; | ||
1310 | mutex_unlock(&codec->mutex); | ||
1311 | |||
1312 | return 0; | ||
1313 | } | ||
1314 | |||
1315 | static int filter_control_put(struct snd_kcontrol *kcontrol, | ||
1316 | struct snd_ctl_elem_value *ucontrol) | ||
1317 | { | ||
1318 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | ||
1319 | struct filter_control *fc = | ||
1320 | (struct filter_control *)kcontrol->private_value; | ||
1321 | unsigned int i; | ||
1322 | |||
1323 | mutex_lock(&codec->mutex); | ||
1324 | for (i = 0; i < fc->count; i++) | ||
1325 | fc->value[i] = ucontrol->value.integer.value[i]; | ||
1326 | mutex_unlock(&codec->mutex); | ||
1327 | |||
1328 | return 0; | ||
1329 | } | ||
1330 | |||
1331 | /* | ||
1332 | * Controls - Non-DAPM ASoC | ||
1333 | */ | ||
1334 | |||
1335 | static DECLARE_TLV_DB_SCALE(adx_dig_gain_tlv, -3200, 100, 1); | ||
1336 | /* -32dB = Mute */ | ||
1337 | |||
1338 | static DECLARE_TLV_DB_SCALE(dax_dig_gain_tlv, -6300, 100, 1); | ||
1339 | /* -63dB = Mute */ | ||
1340 | |||
1341 | static DECLARE_TLV_DB_SCALE(hs_ear_dig_gain_tlv, -100, 100, 1); | ||
1342 | /* -1dB = Mute */ | ||
1343 | |||
1344 | static const unsigned int hs_gain_tlv[] = { | ||
1345 | TLV_DB_RANGE_HEAD(2), | ||
1346 | 0, 3, TLV_DB_SCALE_ITEM(-3200, 400, 0), | ||
1347 | 4, 15, TLV_DB_SCALE_ITEM(-1800, 200, 0), | ||
1348 | }; | ||
1349 | |||
1350 | static DECLARE_TLV_DB_SCALE(mic_gain_tlv, 0, 100, 0); | ||
1351 | |||
1352 | static DECLARE_TLV_DB_SCALE(lin_gain_tlv, -1000, 200, 0); | ||
1353 | |||
1354 | static DECLARE_TLV_DB_SCALE(lin2hs_gain_tlv, -3800, 200, 1); | ||
1355 | /* -38dB = Mute */ | ||
1356 | |||
1357 | static const char * const enum_hsfadspeed[] = {"2ms", "0.5ms", "10.6ms", | ||
1358 | "5ms"}; | ||
1359 | static SOC_ENUM_SINGLE_DECL(soc_enum_hsfadspeed, | ||
1360 | AB8500_DIGMICCONF, AB8500_DIGMICCONF_HSFADSPEED, enum_hsfadspeed); | ||
1361 | |||
1362 | static const char * const enum_envdetthre[] = { | ||
1363 | "250mV", "300mV", "350mV", "400mV", | ||
1364 | "450mV", "500mV", "550mV", "600mV", | ||
1365 | "650mV", "700mV", "750mV", "800mV", | ||
1366 | "850mV", "900mV", "950mV", "1.00V" }; | ||
1367 | static SOC_ENUM_SINGLE_DECL(soc_enum_envdeththre, | ||
1368 | AB8500_ENVCPCONF, AB8500_ENVCPCONF_ENVDETHTHRE, enum_envdetthre); | ||
1369 | static SOC_ENUM_SINGLE_DECL(soc_enum_envdetlthre, | ||
1370 | AB8500_ENVCPCONF, AB8500_ENVCPCONF_ENVDETLTHRE, enum_envdetthre); | ||
1371 | static const char * const enum_envdettime[] = { | ||
1372 | "26.6us", "53.2us", "106us", "213us", | ||
1373 | "426us", "851us", "1.70ms", "3.40ms", | ||
1374 | "6.81ms", "13.6ms", "27.2ms", "54.5ms", | ||
1375 | "109ms", "218ms", "436ms", "872ms" }; | ||
1376 | static SOC_ENUM_SINGLE_DECL(soc_enum_envdettime, | ||
1377 | AB8500_SIGENVCONF, AB8500_SIGENVCONF_ENVDETTIME, enum_envdettime); | ||
1378 | |||
1379 | static const char * const enum_sinc31[] = {"Sinc 3", "Sinc 1"}; | ||
1380 | static SOC_ENUM_SINGLE_DECL(soc_enum_hsesinc, AB8500_HSLEARDIGGAIN, | ||
1381 | AB8500_HSLEARDIGGAIN_HSSINC1, enum_sinc31); | ||
1382 | |||
1383 | static const char * const enum_fadespeed[] = {"1ms", "4ms", "8ms", "16ms"}; | ||
1384 | static SOC_ENUM_SINGLE_DECL(soc_enum_fadespeed, AB8500_HSRDIGGAIN, | ||
1385 | AB8500_HSRDIGGAIN_FADESPEED, enum_fadespeed); | ||
1386 | |||
1387 | /* Earpiece */ | ||
1388 | |||
1389 | static const char * const enum_lowpow[] = {"Normal", "Low Power"}; | ||
1390 | static SOC_ENUM_SINGLE_DECL(soc_enum_eardaclowpow, AB8500_ANACONF1, | ||
1391 | AB8500_ANACONF1_EARDACLOWPOW, enum_lowpow); | ||
1392 | static SOC_ENUM_SINGLE_DECL(soc_enum_eardrvlowpow, AB8500_ANACONF1, | ||
1393 | AB8500_ANACONF1_EARDRVLOWPOW, enum_lowpow); | ||
1394 | |||
1395 | static const char * const enum_av_mode[] = {"Audio", "Voice"}; | ||
1396 | static SOC_ENUM_DOUBLE_DECL(soc_enum_ad12voice, AB8500_ADFILTCONF, | ||
1397 | AB8500_ADFILTCONF_AD1VOICE, AB8500_ADFILTCONF_AD2VOICE, enum_av_mode); | ||
1398 | static SOC_ENUM_DOUBLE_DECL(soc_enum_ad34voice, AB8500_ADFILTCONF, | ||
1399 | AB8500_ADFILTCONF_AD3VOICE, AB8500_ADFILTCONF_AD4VOICE, enum_av_mode); | ||
1400 | |||
1401 | /* DA */ | ||
1402 | |||
1403 | static SOC_ENUM_SINGLE_DECL(soc_enum_da12voice, | ||
1404 | AB8500_DASLOTCONF1, AB8500_DASLOTCONF1_DA12VOICE, | ||
1405 | enum_av_mode); | ||
1406 | static SOC_ENUM_SINGLE_DECL(soc_enum_da34voice, | ||
1407 | AB8500_DASLOTCONF3, AB8500_DASLOTCONF3_DA34VOICE, | ||
1408 | enum_av_mode); | ||
1409 | static SOC_ENUM_SINGLE_DECL(soc_enum_da56voice, | ||
1410 | AB8500_DASLOTCONF5, AB8500_DASLOTCONF5_DA56VOICE, | ||
1411 | enum_av_mode); | ||
1412 | |||
1413 | static const char * const enum_da2hslr[] = {"Sidetone", "Audio Path"}; | ||
1414 | static SOC_ENUM_DOUBLE_DECL(soc_enum_da2hslr, AB8500_DIGMULTCONF1, | ||
1415 | AB8500_DIGMULTCONF1_DATOHSLEN, | ||
1416 | AB8500_DIGMULTCONF1_DATOHSREN, enum_da2hslr); | ||
1417 | |||
1418 | static const char * const enum_sinc53[] = {"Sinc 5", "Sinc 3"}; | ||
1419 | static SOC_ENUM_DOUBLE_DECL(soc_enum_dmic12sinc, AB8500_DMICFILTCONF, | ||
1420 | AB8500_DMICFILTCONF_DMIC1SINC3, | ||
1421 | AB8500_DMICFILTCONF_DMIC2SINC3, enum_sinc53); | ||
1422 | static SOC_ENUM_DOUBLE_DECL(soc_enum_dmic34sinc, AB8500_DMICFILTCONF, | ||
1423 | AB8500_DMICFILTCONF_DMIC3SINC3, | ||
1424 | AB8500_DMICFILTCONF_DMIC4SINC3, enum_sinc53); | ||
1425 | static SOC_ENUM_DOUBLE_DECL(soc_enum_dmic56sinc, AB8500_DMICFILTCONF, | ||
1426 | AB8500_DMICFILTCONF_DMIC5SINC3, | ||
1427 | AB8500_DMICFILTCONF_DMIC6SINC3, enum_sinc53); | ||
1428 | |||
1429 | /* Digital interface - DA from slot mapping */ | ||
1430 | static const char * const enum_da_from_slot_map[] = {"SLOT0", | ||
1431 | "SLOT1", | ||
1432 | "SLOT2", | ||
1433 | "SLOT3", | ||
1434 | "SLOT4", | ||
1435 | "SLOT5", | ||
1436 | "SLOT6", | ||
1437 | "SLOT7", | ||
1438 | "SLOT8", | ||
1439 | "SLOT9", | ||
1440 | "SLOT10", | ||
1441 | "SLOT11", | ||
1442 | "SLOT12", | ||
1443 | "SLOT13", | ||
1444 | "SLOT14", | ||
1445 | "SLOT15", | ||
1446 | "SLOT16", | ||
1447 | "SLOT17", | ||
1448 | "SLOT18", | ||
1449 | "SLOT19", | ||
1450 | "SLOT20", | ||
1451 | "SLOT21", | ||
1452 | "SLOT22", | ||
1453 | "SLOT23", | ||
1454 | "SLOT24", | ||
1455 | "SLOT25", | ||
1456 | "SLOT26", | ||
1457 | "SLOT27", | ||
1458 | "SLOT28", | ||
1459 | "SLOT29", | ||
1460 | "SLOT30", | ||
1461 | "SLOT31"}; | ||
1462 | static SOC_ENUM_SINGLE_DECL(soc_enum_da1slotmap, | ||
1463 | AB8500_DASLOTCONF1, AB8500_DASLOTCONFX_SLTODAX_SHIFT, | ||
1464 | enum_da_from_slot_map); | ||
1465 | static SOC_ENUM_SINGLE_DECL(soc_enum_da2slotmap, | ||
1466 | AB8500_DASLOTCONF2, AB8500_DASLOTCONFX_SLTODAX_SHIFT, | ||
1467 | enum_da_from_slot_map); | ||
1468 | static SOC_ENUM_SINGLE_DECL(soc_enum_da3slotmap, | ||
1469 | AB8500_DASLOTCONF3, AB8500_DASLOTCONFX_SLTODAX_SHIFT, | ||
1470 | enum_da_from_slot_map); | ||
1471 | static SOC_ENUM_SINGLE_DECL(soc_enum_da4slotmap, | ||
1472 | AB8500_DASLOTCONF4, AB8500_DASLOTCONFX_SLTODAX_SHIFT, | ||
1473 | enum_da_from_slot_map); | ||
1474 | static SOC_ENUM_SINGLE_DECL(soc_enum_da5slotmap, | ||
1475 | AB8500_DASLOTCONF5, AB8500_DASLOTCONFX_SLTODAX_SHIFT, | ||
1476 | enum_da_from_slot_map); | ||
1477 | static SOC_ENUM_SINGLE_DECL(soc_enum_da6slotmap, | ||
1478 | AB8500_DASLOTCONF6, AB8500_DASLOTCONFX_SLTODAX_SHIFT, | ||
1479 | enum_da_from_slot_map); | ||
1480 | static SOC_ENUM_SINGLE_DECL(soc_enum_da7slotmap, | ||
1481 | AB8500_DASLOTCONF7, AB8500_DASLOTCONFX_SLTODAX_SHIFT, | ||
1482 | enum_da_from_slot_map); | ||
1483 | static SOC_ENUM_SINGLE_DECL(soc_enum_da8slotmap, | ||
1484 | AB8500_DASLOTCONF8, AB8500_DASLOTCONFX_SLTODAX_SHIFT, | ||
1485 | enum_da_from_slot_map); | ||
1486 | |||
1487 | /* Digital interface - AD to slot mapping */ | ||
1488 | static const char * const enum_ad_to_slot_map[] = {"AD_OUT1", | ||
1489 | "AD_OUT2", | ||
1490 | "AD_OUT3", | ||
1491 | "AD_OUT4", | ||
1492 | "AD_OUT5", | ||
1493 | "AD_OUT6", | ||
1494 | "AD_OUT7", | ||
1495 | "AD_OUT8", | ||
1496 | "zeroes", | ||
1497 | "tristate"}; | ||
1498 | static SOC_ENUM_SINGLE_DECL(soc_enum_adslot0map, | ||
1499 | AB8500_ADSLOTSEL1, AB8500_ADSLOTSELX_EVEN_SHIFT, | ||
1500 | enum_ad_to_slot_map); | ||
1501 | static SOC_ENUM_SINGLE_DECL(soc_enum_adslot1map, | ||
1502 | AB8500_ADSLOTSEL1, AB8500_ADSLOTSELX_ODD_SHIFT, | ||
1503 | enum_ad_to_slot_map); | ||
1504 | static SOC_ENUM_SINGLE_DECL(soc_enum_adslot2map, | ||
1505 | AB8500_ADSLOTSEL2, AB8500_ADSLOTSELX_EVEN_SHIFT, | ||
1506 | enum_ad_to_slot_map); | ||
1507 | static SOC_ENUM_SINGLE_DECL(soc_enum_adslot3map, | ||
1508 | AB8500_ADSLOTSEL2, AB8500_ADSLOTSELX_ODD_SHIFT, | ||
1509 | enum_ad_to_slot_map); | ||
1510 | static SOC_ENUM_SINGLE_DECL(soc_enum_adslot4map, | ||
1511 | AB8500_ADSLOTSEL3, AB8500_ADSLOTSELX_EVEN_SHIFT, | ||
1512 | enum_ad_to_slot_map); | ||
1513 | static SOC_ENUM_SINGLE_DECL(soc_enum_adslot5map, | ||
1514 | AB8500_ADSLOTSEL3, AB8500_ADSLOTSELX_ODD_SHIFT, | ||
1515 | enum_ad_to_slot_map); | ||
1516 | static SOC_ENUM_SINGLE_DECL(soc_enum_adslot6map, | ||
1517 | AB8500_ADSLOTSEL4, AB8500_ADSLOTSELX_EVEN_SHIFT, | ||
1518 | enum_ad_to_slot_map); | ||
1519 | static SOC_ENUM_SINGLE_DECL(soc_enum_adslot7map, | ||
1520 | AB8500_ADSLOTSEL4, AB8500_ADSLOTSELX_ODD_SHIFT, | ||
1521 | enum_ad_to_slot_map); | ||
1522 | static SOC_ENUM_SINGLE_DECL(soc_enum_adslot8map, | ||
1523 | AB8500_ADSLOTSEL5, AB8500_ADSLOTSELX_EVEN_SHIFT, | ||
1524 | enum_ad_to_slot_map); | ||
1525 | static SOC_ENUM_SINGLE_DECL(soc_enum_adslot9map, | ||
1526 | AB8500_ADSLOTSEL5, AB8500_ADSLOTSELX_ODD_SHIFT, | ||
1527 | enum_ad_to_slot_map); | ||
1528 | static SOC_ENUM_SINGLE_DECL(soc_enum_adslot10map, | ||
1529 | AB8500_ADSLOTSEL6, AB8500_ADSLOTSELX_EVEN_SHIFT, | ||
1530 | enum_ad_to_slot_map); | ||
1531 | static SOC_ENUM_SINGLE_DECL(soc_enum_adslot11map, | ||
1532 | AB8500_ADSLOTSEL6, AB8500_ADSLOTSELX_ODD_SHIFT, | ||
1533 | enum_ad_to_slot_map); | ||
1534 | static SOC_ENUM_SINGLE_DECL(soc_enum_adslot12map, | ||
1535 | AB8500_ADSLOTSEL7, AB8500_ADSLOTSELX_EVEN_SHIFT, | ||
1536 | enum_ad_to_slot_map); | ||
1537 | static SOC_ENUM_SINGLE_DECL(soc_enum_adslot13map, | ||
1538 | AB8500_ADSLOTSEL7, AB8500_ADSLOTSELX_ODD_SHIFT, | ||
1539 | enum_ad_to_slot_map); | ||
1540 | static SOC_ENUM_SINGLE_DECL(soc_enum_adslot14map, | ||
1541 | AB8500_ADSLOTSEL8, AB8500_ADSLOTSELX_EVEN_SHIFT, | ||
1542 | enum_ad_to_slot_map); | ||
1543 | static SOC_ENUM_SINGLE_DECL(soc_enum_adslot15map, | ||
1544 | AB8500_ADSLOTSEL8, AB8500_ADSLOTSELX_ODD_SHIFT, | ||
1545 | enum_ad_to_slot_map); | ||
1546 | static SOC_ENUM_SINGLE_DECL(soc_enum_adslot16map, | ||
1547 | AB8500_ADSLOTSEL9, AB8500_ADSLOTSELX_EVEN_SHIFT, | ||
1548 | enum_ad_to_slot_map); | ||
1549 | static SOC_ENUM_SINGLE_DECL(soc_enum_adslot17map, | ||
1550 | AB8500_ADSLOTSEL9, AB8500_ADSLOTSELX_ODD_SHIFT, | ||
1551 | enum_ad_to_slot_map); | ||
1552 | static SOC_ENUM_SINGLE_DECL(soc_enum_adslot18map, | ||
1553 | AB8500_ADSLOTSEL10, AB8500_ADSLOTSELX_EVEN_SHIFT, | ||
1554 | enum_ad_to_slot_map); | ||
1555 | static SOC_ENUM_SINGLE_DECL(soc_enum_adslot19map, | ||
1556 | AB8500_ADSLOTSEL10, AB8500_ADSLOTSELX_ODD_SHIFT, | ||
1557 | enum_ad_to_slot_map); | ||
1558 | static SOC_ENUM_SINGLE_DECL(soc_enum_adslot20map, | ||
1559 | AB8500_ADSLOTSEL11, AB8500_ADSLOTSELX_EVEN_SHIFT, | ||
1560 | enum_ad_to_slot_map); | ||
1561 | static SOC_ENUM_SINGLE_DECL(soc_enum_adslot21map, | ||
1562 | AB8500_ADSLOTSEL11, AB8500_ADSLOTSELX_ODD_SHIFT, | ||
1563 | enum_ad_to_slot_map); | ||
1564 | static SOC_ENUM_SINGLE_DECL(soc_enum_adslot22map, | ||
1565 | AB8500_ADSLOTSEL12, AB8500_ADSLOTSELX_EVEN_SHIFT, | ||
1566 | enum_ad_to_slot_map); | ||
1567 | static SOC_ENUM_SINGLE_DECL(soc_enum_adslot23map, | ||
1568 | AB8500_ADSLOTSEL12, AB8500_ADSLOTSELX_ODD_SHIFT, | ||
1569 | enum_ad_to_slot_map); | ||
1570 | static SOC_ENUM_SINGLE_DECL(soc_enum_adslot24map, | ||
1571 | AB8500_ADSLOTSEL13, AB8500_ADSLOTSELX_EVEN_SHIFT, | ||
1572 | enum_ad_to_slot_map); | ||
1573 | static SOC_ENUM_SINGLE_DECL(soc_enum_adslot25map, | ||
1574 | AB8500_ADSLOTSEL13, AB8500_ADSLOTSELX_ODD_SHIFT, | ||
1575 | enum_ad_to_slot_map); | ||
1576 | static SOC_ENUM_SINGLE_DECL(soc_enum_adslot26map, | ||
1577 | AB8500_ADSLOTSEL14, AB8500_ADSLOTSELX_EVEN_SHIFT, | ||
1578 | enum_ad_to_slot_map); | ||
1579 | static SOC_ENUM_SINGLE_DECL(soc_enum_adslot27map, | ||
1580 | AB8500_ADSLOTSEL14, AB8500_ADSLOTSELX_ODD_SHIFT, | ||
1581 | enum_ad_to_slot_map); | ||
1582 | static SOC_ENUM_SINGLE_DECL(soc_enum_adslot28map, | ||
1583 | AB8500_ADSLOTSEL15, AB8500_ADSLOTSELX_EVEN_SHIFT, | ||
1584 | enum_ad_to_slot_map); | ||
1585 | static SOC_ENUM_SINGLE_DECL(soc_enum_adslot29map, | ||
1586 | AB8500_ADSLOTSEL15, AB8500_ADSLOTSELX_ODD_SHIFT, | ||
1587 | enum_ad_to_slot_map); | ||
1588 | static SOC_ENUM_SINGLE_DECL(soc_enum_adslot30map, | ||
1589 | AB8500_ADSLOTSEL16, AB8500_ADSLOTSELX_EVEN_SHIFT, | ||
1590 | enum_ad_to_slot_map); | ||
1591 | static SOC_ENUM_SINGLE_DECL(soc_enum_adslot31map, | ||
1592 | AB8500_ADSLOTSEL16, AB8500_ADSLOTSELX_ODD_SHIFT, | ||
1593 | enum_ad_to_slot_map); | ||
1594 | |||
1595 | /* Digital interface - Burst mode */ | ||
1596 | static const char * const enum_mask[] = {"Unmasked", "Masked"}; | ||
1597 | static SOC_ENUM_SINGLE_DECL(soc_enum_bfifomask, | ||
1598 | AB8500_FIFOCONF1, AB8500_FIFOCONF1_BFIFOMASK, | ||
1599 | enum_mask); | ||
1600 | static const char * const enum_bitclk0[] = {"19_2_MHz", "38_4_MHz"}; | ||
1601 | static SOC_ENUM_SINGLE_DECL(soc_enum_bfifo19m2, | ||
1602 | AB8500_FIFOCONF1, AB8500_FIFOCONF1_BFIFO19M2, | ||
1603 | enum_bitclk0); | ||
1604 | static const char * const enum_slavemaster[] = {"Slave", "Master"}; | ||
1605 | static SOC_ENUM_SINGLE_DECL(soc_enum_bfifomast, | ||
1606 | AB8500_FIFOCONF3, AB8500_FIFOCONF3_BFIFOMAST_SHIFT, | ||
1607 | enum_slavemaster); | ||
1608 | |||
1609 | /* Sidetone */ | ||
1610 | static SOC_ENUM_SINGLE_EXT_DECL(soc_enum_sidstate, enum_sid_state); | ||
1611 | |||
1612 | /* ANC */ | ||
1613 | static SOC_ENUM_SINGLE_EXT_DECL(soc_enum_ancstate, enum_anc_state); | ||
1614 | |||
1615 | static struct snd_kcontrol_new ab8500_ctrls[] = { | ||
1616 | /* Charge pump */ | ||
1617 | SOC_ENUM("Charge Pump High Threshold For Low Voltage", | ||
1618 | soc_enum_envdeththre), | ||
1619 | SOC_ENUM("Charge Pump Low Threshold For Low Voltage", | ||
1620 | soc_enum_envdetlthre), | ||
1621 | SOC_SINGLE("Charge Pump Envelope Detection Switch", | ||
1622 | AB8500_SIGENVCONF, AB8500_SIGENVCONF_ENVDETCPEN, | ||
1623 | 1, 0), | ||
1624 | SOC_ENUM("Charge Pump Envelope Detection Decay Time", | ||
1625 | soc_enum_envdettime), | ||
1626 | |||
1627 | /* Headset */ | ||
1628 | SOC_ENUM("Headset Mode", soc_enum_da12voice), | ||
1629 | SOC_SINGLE("Headset High Pass Switch", | ||
1630 | AB8500_ANACONF1, AB8500_ANACONF1_HSHPEN, | ||
1631 | 1, 0), | ||
1632 | SOC_SINGLE("Headset Low Power Switch", | ||
1633 | AB8500_ANACONF1, AB8500_ANACONF1_HSLOWPOW, | ||
1634 | 1, 0), | ||
1635 | SOC_SINGLE("Headset DAC Low Power Switch", | ||
1636 | AB8500_ANACONF1, AB8500_ANACONF1_DACLOWPOW1, | ||
1637 | 1, 0), | ||
1638 | SOC_SINGLE("Headset DAC Drv Low Power Switch", | ||
1639 | AB8500_ANACONF1, AB8500_ANACONF1_DACLOWPOW0, | ||
1640 | 1, 0), | ||
1641 | SOC_ENUM("Headset Fade Speed", soc_enum_hsfadspeed), | ||
1642 | SOC_ENUM("Headset Source", soc_enum_da2hslr), | ||
1643 | SOC_ENUM("Headset Filter", soc_enum_hsesinc), | ||
1644 | SOC_DOUBLE_R_TLV("Headset Master Volume", | ||
1645 | AB8500_DADIGGAIN1, AB8500_DADIGGAIN2, | ||
1646 | 0, AB8500_DADIGGAINX_DAXGAIN_MAX, 1, dax_dig_gain_tlv), | ||
1647 | SOC_DOUBLE_R_TLV("Headset Digital Volume", | ||
1648 | AB8500_HSLEARDIGGAIN, AB8500_HSRDIGGAIN, | ||
1649 | 0, AB8500_HSLEARDIGGAIN_HSLDGAIN_MAX, 1, hs_ear_dig_gain_tlv), | ||
1650 | SOC_DOUBLE_TLV("Headset Volume", | ||
1651 | AB8500_ANAGAIN3, | ||
1652 | AB8500_ANAGAIN3_HSLGAIN, AB8500_ANAGAIN3_HSRGAIN, | ||
1653 | AB8500_ANAGAIN3_HSXGAIN_MAX, 1, hs_gain_tlv), | ||
1654 | |||
1655 | /* Earpiece */ | ||
1656 | SOC_ENUM("Earpiece DAC Mode", | ||
1657 | soc_enum_eardaclowpow), | ||
1658 | SOC_ENUM("Earpiece DAC Drv Mode", | ||
1659 | soc_enum_eardrvlowpow), | ||
1660 | |||
1661 | /* HandsFree */ | ||
1662 | SOC_ENUM("HF Mode", soc_enum_da34voice), | ||
1663 | SOC_SINGLE("HF and Headset Swap Switch", | ||
1664 | AB8500_DASLOTCONF1, AB8500_DASLOTCONF1_SWAPDA12_34, | ||
1665 | 1, 0), | ||
1666 | SOC_DOUBLE("HF Low EMI Mode Switch", | ||
1667 | AB8500_CLASSDCONF1, | ||
1668 | AB8500_CLASSDCONF1_HFLSWAPEN, AB8500_CLASSDCONF1_HFRSWAPEN, | ||
1669 | 1, 0), | ||
1670 | SOC_DOUBLE("HF FIR Bypass Switch", | ||
1671 | AB8500_CLASSDCONF2, | ||
1672 | AB8500_CLASSDCONF2_FIRBYP0, AB8500_CLASSDCONF2_FIRBYP1, | ||
1673 | 1, 0), | ||
1674 | SOC_DOUBLE("HF High Volume Switch", | ||
1675 | AB8500_CLASSDCONF2, | ||
1676 | AB8500_CLASSDCONF2_HIGHVOLEN0, AB8500_CLASSDCONF2_HIGHVOLEN1, | ||
1677 | 1, 0), | ||
1678 | SOC_SINGLE("HF L and R Bridge Switch", | ||
1679 | AB8500_CLASSDCONF1, AB8500_CLASSDCONF1_PARLHF, | ||
1680 | 1, 0), | ||
1681 | SOC_DOUBLE_R_TLV("HF Master Volume", | ||
1682 | AB8500_DADIGGAIN3, AB8500_DADIGGAIN4, | ||
1683 | 0, AB8500_DADIGGAINX_DAXGAIN_MAX, 1, dax_dig_gain_tlv), | ||
1684 | |||
1685 | /* Vibra */ | ||
1686 | SOC_DOUBLE("Vibra High Volume Switch", | ||
1687 | AB8500_CLASSDCONF2, | ||
1688 | AB8500_CLASSDCONF2_HIGHVOLEN2, AB8500_CLASSDCONF2_HIGHVOLEN3, | ||
1689 | 1, 0), | ||
1690 | SOC_DOUBLE("Vibra Low EMI Mode Switch", | ||
1691 | AB8500_CLASSDCONF1, | ||
1692 | AB8500_CLASSDCONF1_VIB1SWAPEN, AB8500_CLASSDCONF1_VIB2SWAPEN, | ||
1693 | 1, 0), | ||
1694 | SOC_DOUBLE("Vibra FIR Bypass Switch", | ||
1695 | AB8500_CLASSDCONF2, | ||
1696 | AB8500_CLASSDCONF2_FIRBYP2, AB8500_CLASSDCONF2_FIRBYP3, | ||
1697 | 1, 0), | ||
1698 | SOC_ENUM("Vibra Mode", soc_enum_da56voice), | ||
1699 | SOC_DOUBLE_R("Vibra PWM Duty Cycle N", | ||
1700 | AB8500_PWMGENCONF3, AB8500_PWMGENCONF5, | ||
1701 | AB8500_PWMGENCONFX_PWMVIBXDUTCYC, | ||
1702 | AB8500_PWMGENCONFX_PWMVIBXDUTCYC_MAX, 0), | ||
1703 | SOC_DOUBLE_R("Vibra PWM Duty Cycle P", | ||
1704 | AB8500_PWMGENCONF2, AB8500_PWMGENCONF4, | ||
1705 | AB8500_PWMGENCONFX_PWMVIBXDUTCYC, | ||
1706 | AB8500_PWMGENCONFX_PWMVIBXDUTCYC_MAX, 0), | ||
1707 | SOC_SINGLE("Vibra 1 and 2 Bridge Switch", | ||
1708 | AB8500_CLASSDCONF1, AB8500_CLASSDCONF1_PARLVIB, | ||
1709 | 1, 0), | ||
1710 | SOC_DOUBLE_R_TLV("Vibra Master Volume", | ||
1711 | AB8500_DADIGGAIN5, AB8500_DADIGGAIN6, | ||
1712 | 0, AB8500_DADIGGAINX_DAXGAIN_MAX, 1, dax_dig_gain_tlv), | ||
1713 | |||
1714 | /* HandsFree, Vibra */ | ||
1715 | SOC_SINGLE("ClassD High Pass Volume", | ||
1716 | AB8500_CLASSDCONF3, AB8500_CLASSDCONF3_DITHHPGAIN, | ||
1717 | AB8500_CLASSDCONF3_DITHHPGAIN_MAX, 0), | ||
1718 | SOC_SINGLE("ClassD White Volume", | ||
1719 | AB8500_CLASSDCONF3, AB8500_CLASSDCONF3_DITHWGAIN, | ||
1720 | AB8500_CLASSDCONF3_DITHWGAIN_MAX, 0), | ||
1721 | |||
1722 | /* Mic 1, Mic 2, LineIn */ | ||
1723 | SOC_DOUBLE_R_TLV("Mic Master Volume", | ||
1724 | AB8500_ADDIGGAIN3, AB8500_ADDIGGAIN4, | ||
1725 | 0, AB8500_ADDIGGAINX_ADXGAIN_MAX, 1, adx_dig_gain_tlv), | ||
1726 | |||
1727 | /* Mic 1 */ | ||
1728 | SOC_SINGLE_TLV("Mic 1", | ||
1729 | AB8500_ANAGAIN1, | ||
1730 | AB8500_ANAGAINX_MICXGAIN, | ||
1731 | AB8500_ANAGAINX_MICXGAIN_MAX, 0, mic_gain_tlv), | ||
1732 | SOC_SINGLE("Mic 1 Low Power Switch", | ||
1733 | AB8500_ANAGAIN1, AB8500_ANAGAINX_LOWPOWMICX, | ||
1734 | 1, 0), | ||
1735 | |||
1736 | /* Mic 2 */ | ||
1737 | SOC_DOUBLE("Mic High Pass Switch", | ||
1738 | AB8500_ADFILTCONF, | ||
1739 | AB8500_ADFILTCONF_AD3NH, AB8500_ADFILTCONF_AD4NH, | ||
1740 | 1, 1), | ||
1741 | SOC_ENUM("Mic Mode", soc_enum_ad34voice), | ||
1742 | SOC_ENUM("Mic Filter", soc_enum_dmic34sinc), | ||
1743 | SOC_SINGLE_TLV("Mic 2", | ||
1744 | AB8500_ANAGAIN2, | ||
1745 | AB8500_ANAGAINX_MICXGAIN, | ||
1746 | AB8500_ANAGAINX_MICXGAIN_MAX, 0, mic_gain_tlv), | ||
1747 | SOC_SINGLE("Mic 2 Low Power Switch", | ||
1748 | AB8500_ANAGAIN2, AB8500_ANAGAINX_LOWPOWMICX, | ||
1749 | 1, 0), | ||
1750 | |||
1751 | /* LineIn */ | ||
1752 | SOC_DOUBLE("LineIn High Pass Switch", | ||
1753 | AB8500_ADFILTCONF, | ||
1754 | AB8500_ADFILTCONF_AD1NH, AB8500_ADFILTCONF_AD2NH, | ||
1755 | 1, 1), | ||
1756 | SOC_ENUM("LineIn Filter", soc_enum_dmic12sinc), | ||
1757 | SOC_ENUM("LineIn Mode", soc_enum_ad12voice), | ||
1758 | SOC_DOUBLE_R_TLV("LineIn Master Volume", | ||
1759 | AB8500_ADDIGGAIN1, AB8500_ADDIGGAIN2, | ||
1760 | 0, AB8500_ADDIGGAINX_ADXGAIN_MAX, 1, adx_dig_gain_tlv), | ||
1761 | SOC_DOUBLE_TLV("LineIn", | ||
1762 | AB8500_ANAGAIN4, | ||
1763 | AB8500_ANAGAIN4_LINLGAIN, AB8500_ANAGAIN4_LINRGAIN, | ||
1764 | AB8500_ANAGAIN4_LINXGAIN_MAX, 0, lin_gain_tlv), | ||
1765 | SOC_DOUBLE_R_TLV("LineIn to Headset Volume", | ||
1766 | AB8500_DIGLINHSLGAIN, AB8500_DIGLINHSRGAIN, | ||
1767 | AB8500_DIGLINHSXGAIN_LINTOHSXGAIN, | ||
1768 | AB8500_DIGLINHSXGAIN_LINTOHSXGAIN_MAX, | ||
1769 | 1, lin2hs_gain_tlv), | ||
1770 | |||
1771 | /* DMic */ | ||
1772 | SOC_ENUM("DMic Filter", soc_enum_dmic56sinc), | ||
1773 | SOC_DOUBLE_R_TLV("DMic Master Volume", | ||
1774 | AB8500_ADDIGGAIN5, AB8500_ADDIGGAIN6, | ||
1775 | 0, AB8500_ADDIGGAINX_ADXGAIN_MAX, 1, adx_dig_gain_tlv), | ||
1776 | |||
1777 | /* Digital gains */ | ||
1778 | SOC_ENUM("Digital Gain Fade Speed", soc_enum_fadespeed), | ||
1779 | |||
1780 | /* Analog loopback */ | ||
1781 | SOC_DOUBLE_R_TLV("Analog Loopback Volume", | ||
1782 | AB8500_ADDIGLOOPGAIN1, AB8500_ADDIGLOOPGAIN2, | ||
1783 | 0, AB8500_ADDIGLOOPGAINX_ADXLBGAIN_MAX, 1, dax_dig_gain_tlv), | ||
1784 | |||
1785 | /* Digital interface - DA from slot mapping */ | ||
1786 | SOC_ENUM("Digital Interface DA 1 From Slot Map", soc_enum_da1slotmap), | ||
1787 | SOC_ENUM("Digital Interface DA 2 From Slot Map", soc_enum_da2slotmap), | ||
1788 | SOC_ENUM("Digital Interface DA 3 From Slot Map", soc_enum_da3slotmap), | ||
1789 | SOC_ENUM("Digital Interface DA 4 From Slot Map", soc_enum_da4slotmap), | ||
1790 | SOC_ENUM("Digital Interface DA 5 From Slot Map", soc_enum_da5slotmap), | ||
1791 | SOC_ENUM("Digital Interface DA 6 From Slot Map", soc_enum_da6slotmap), | ||
1792 | SOC_ENUM("Digital Interface DA 7 From Slot Map", soc_enum_da7slotmap), | ||
1793 | SOC_ENUM("Digital Interface DA 8 From Slot Map", soc_enum_da8slotmap), | ||
1794 | |||
1795 | /* Digital interface - AD to slot mapping */ | ||
1796 | SOC_ENUM("Digital Interface AD To Slot 0 Map", soc_enum_adslot0map), | ||
1797 | SOC_ENUM("Digital Interface AD To Slot 1 Map", soc_enum_adslot1map), | ||
1798 | SOC_ENUM("Digital Interface AD To Slot 2 Map", soc_enum_adslot2map), | ||
1799 | SOC_ENUM("Digital Interface AD To Slot 3 Map", soc_enum_adslot3map), | ||
1800 | SOC_ENUM("Digital Interface AD To Slot 4 Map", soc_enum_adslot4map), | ||
1801 | SOC_ENUM("Digital Interface AD To Slot 5 Map", soc_enum_adslot5map), | ||
1802 | SOC_ENUM("Digital Interface AD To Slot 6 Map", soc_enum_adslot6map), | ||
1803 | SOC_ENUM("Digital Interface AD To Slot 7 Map", soc_enum_adslot7map), | ||
1804 | SOC_ENUM("Digital Interface AD To Slot 8 Map", soc_enum_adslot8map), | ||
1805 | SOC_ENUM("Digital Interface AD To Slot 9 Map", soc_enum_adslot9map), | ||
1806 | SOC_ENUM("Digital Interface AD To Slot 10 Map", soc_enum_adslot10map), | ||
1807 | SOC_ENUM("Digital Interface AD To Slot 11 Map", soc_enum_adslot11map), | ||
1808 | SOC_ENUM("Digital Interface AD To Slot 12 Map", soc_enum_adslot12map), | ||
1809 | SOC_ENUM("Digital Interface AD To Slot 13 Map", soc_enum_adslot13map), | ||
1810 | SOC_ENUM("Digital Interface AD To Slot 14 Map", soc_enum_adslot14map), | ||
1811 | SOC_ENUM("Digital Interface AD To Slot 15 Map", soc_enum_adslot15map), | ||
1812 | SOC_ENUM("Digital Interface AD To Slot 16 Map", soc_enum_adslot16map), | ||
1813 | SOC_ENUM("Digital Interface AD To Slot 17 Map", soc_enum_adslot17map), | ||
1814 | SOC_ENUM("Digital Interface AD To Slot 18 Map", soc_enum_adslot18map), | ||
1815 | SOC_ENUM("Digital Interface AD To Slot 19 Map", soc_enum_adslot19map), | ||
1816 | SOC_ENUM("Digital Interface AD To Slot 20 Map", soc_enum_adslot20map), | ||
1817 | SOC_ENUM("Digital Interface AD To Slot 21 Map", soc_enum_adslot21map), | ||
1818 | SOC_ENUM("Digital Interface AD To Slot 22 Map", soc_enum_adslot22map), | ||
1819 | SOC_ENUM("Digital Interface AD To Slot 23 Map", soc_enum_adslot23map), | ||
1820 | SOC_ENUM("Digital Interface AD To Slot 24 Map", soc_enum_adslot24map), | ||
1821 | SOC_ENUM("Digital Interface AD To Slot 25 Map", soc_enum_adslot25map), | ||
1822 | SOC_ENUM("Digital Interface AD To Slot 26 Map", soc_enum_adslot26map), | ||
1823 | SOC_ENUM("Digital Interface AD To Slot 27 Map", soc_enum_adslot27map), | ||
1824 | SOC_ENUM("Digital Interface AD To Slot 28 Map", soc_enum_adslot28map), | ||
1825 | SOC_ENUM("Digital Interface AD To Slot 29 Map", soc_enum_adslot29map), | ||
1826 | SOC_ENUM("Digital Interface AD To Slot 30 Map", soc_enum_adslot30map), | ||
1827 | SOC_ENUM("Digital Interface AD To Slot 31 Map", soc_enum_adslot31map), | ||
1828 | |||
1829 | /* Digital interface - Loopback */ | ||
1830 | SOC_SINGLE("Digital Interface AD 1 Loopback Switch", | ||
1831 | AB8500_DASLOTCONF1, AB8500_DASLOTCONF1_DAI7TOADO1, | ||
1832 | 1, 0), | ||
1833 | SOC_SINGLE("Digital Interface AD 2 Loopback Switch", | ||
1834 | AB8500_DASLOTCONF2, AB8500_DASLOTCONF2_DAI8TOADO2, | ||
1835 | 1, 0), | ||
1836 | SOC_SINGLE("Digital Interface AD 3 Loopback Switch", | ||
1837 | AB8500_DASLOTCONF3, AB8500_DASLOTCONF3_DAI7TOADO3, | ||
1838 | 1, 0), | ||
1839 | SOC_SINGLE("Digital Interface AD 4 Loopback Switch", | ||
1840 | AB8500_DASLOTCONF4, AB8500_DASLOTCONF4_DAI8TOADO4, | ||
1841 | 1, 0), | ||
1842 | SOC_SINGLE("Digital Interface AD 5 Loopback Switch", | ||
1843 | AB8500_DASLOTCONF5, AB8500_DASLOTCONF5_DAI7TOADO5, | ||
1844 | 1, 0), | ||
1845 | SOC_SINGLE("Digital Interface AD 6 Loopback Switch", | ||
1846 | AB8500_DASLOTCONF6, AB8500_DASLOTCONF6_DAI8TOADO6, | ||
1847 | 1, 0), | ||
1848 | SOC_SINGLE("Digital Interface AD 7 Loopback Switch", | ||
1849 | AB8500_DASLOTCONF7, AB8500_DASLOTCONF7_DAI8TOADO7, | ||
1850 | 1, 0), | ||
1851 | SOC_SINGLE("Digital Interface AD 8 Loopback Switch", | ||
1852 | AB8500_DASLOTCONF8, AB8500_DASLOTCONF8_DAI7TOADO8, | ||
1853 | 1, 0), | ||
1854 | |||
1855 | /* Digital interface - Burst FIFO */ | ||
1856 | SOC_SINGLE("Digital Interface 0 FIFO Enable Switch", | ||
1857 | AB8500_DIGIFCONF3, AB8500_DIGIFCONF3_IF0BFIFOEN, | ||
1858 | 1, 0), | ||
1859 | SOC_ENUM("Burst FIFO Mask", soc_enum_bfifomask), | ||
1860 | SOC_ENUM("Burst FIFO Bit-clock Frequency", soc_enum_bfifo19m2), | ||
1861 | SOC_SINGLE("Burst FIFO Threshold", | ||
1862 | AB8500_FIFOCONF1, AB8500_FIFOCONF1_BFIFOINT_SHIFT, | ||
1863 | AB8500_FIFOCONF1_BFIFOINT_MAX, 0), | ||
1864 | SOC_SINGLE("Burst FIFO Length", | ||
1865 | AB8500_FIFOCONF2, AB8500_FIFOCONF2_BFIFOTX_SHIFT, | ||
1866 | AB8500_FIFOCONF2_BFIFOTX_MAX, 0), | ||
1867 | SOC_SINGLE("Burst FIFO EOS Extra Slots", | ||
1868 | AB8500_FIFOCONF3, AB8500_FIFOCONF3_BFIFOEXSL_SHIFT, | ||
1869 | AB8500_FIFOCONF3_BFIFOEXSL_MAX, 0), | ||
1870 | SOC_SINGLE("Burst FIFO FS Extra Bit-clocks", | ||
1871 | AB8500_FIFOCONF3, AB8500_FIFOCONF3_PREBITCLK0_SHIFT, | ||
1872 | AB8500_FIFOCONF3_PREBITCLK0_MAX, 0), | ||
1873 | SOC_ENUM("Burst FIFO Interface Mode", soc_enum_bfifomast), | ||
1874 | |||
1875 | SOC_SINGLE("Burst FIFO Interface Switch", | ||
1876 | AB8500_FIFOCONF3, AB8500_FIFOCONF3_BFIFORUN_SHIFT, | ||
1877 | 1, 0), | ||
1878 | SOC_SINGLE("Burst FIFO Switch Frame Number", | ||
1879 | AB8500_FIFOCONF4, AB8500_FIFOCONF4_BFIFOFRAMSW_SHIFT, | ||
1880 | AB8500_FIFOCONF4_BFIFOFRAMSW_MAX, 0), | ||
1881 | SOC_SINGLE("Burst FIFO Wake Up Delay", | ||
1882 | AB8500_FIFOCONF5, AB8500_FIFOCONF5_BFIFOWAKEUP_SHIFT, | ||
1883 | AB8500_FIFOCONF5_BFIFOWAKEUP_MAX, 0), | ||
1884 | SOC_SINGLE("Burst FIFO Samples In FIFO", | ||
1885 | AB8500_FIFOCONF6, AB8500_FIFOCONF6_BFIFOSAMPLE_SHIFT, | ||
1886 | AB8500_FIFOCONF6_BFIFOSAMPLE_MAX, 0), | ||
1887 | |||
1888 | /* ANC */ | ||
1889 | SOC_ENUM_EXT("ANC Status", soc_enum_ancstate, | ||
1890 | anc_status_control_get, anc_status_control_put), | ||
1891 | SOC_SINGLE_XR_SX("ANC Warp Delay Shift", | ||
1892 | AB8500_ANCCONF2, 1, AB8500_ANCCONF2_SHIFT, | ||
1893 | AB8500_ANCCONF2_MIN, AB8500_ANCCONF2_MAX, 0), | ||
1894 | SOC_SINGLE_XR_SX("ANC FIR Output Shift", | ||
1895 | AB8500_ANCCONF3, 1, AB8500_ANCCONF3_SHIFT, | ||
1896 | AB8500_ANCCONF3_MIN, AB8500_ANCCONF3_MAX, 0), | ||
1897 | SOC_SINGLE_XR_SX("ANC IIR Output Shift", | ||
1898 | AB8500_ANCCONF4, 1, AB8500_ANCCONF4_SHIFT, | ||
1899 | AB8500_ANCCONF4_MIN, AB8500_ANCCONF4_MAX, 0), | ||
1900 | SOC_SINGLE_XR_SX("ANC Warp Delay", | ||
1901 | AB8500_ANCCONF9, 2, AB8500_ANC_WARP_DELAY_SHIFT, | ||
1902 | AB8500_ANC_WARP_DELAY_MIN, AB8500_ANC_WARP_DELAY_MAX, 0), | ||
1903 | |||
1904 | /* Sidetone */ | ||
1905 | SOC_ENUM_EXT("Sidetone Status", soc_enum_sidstate, | ||
1906 | sid_status_control_get, sid_status_control_put), | ||
1907 | SOC_SINGLE_STROBE("Sidetone Reset", | ||
1908 | AB8500_SIDFIRADR, AB8500_SIDFIRADR_FIRSIDSET, 0), | ||
1909 | }; | ||
1910 | |||
1911 | static struct snd_kcontrol_new ab8500_filter_controls[] = { | ||
1912 | AB8500_FILTER_CONTROL("ANC FIR Coefficients", AB8500_ANC_FIR_COEFFS, | ||
1913 | AB8500_ANC_FIR_COEFF_MIN, AB8500_ANC_FIR_COEFF_MAX), | ||
1914 | AB8500_FILTER_CONTROL("ANC IIR Coefficients", AB8500_ANC_IIR_COEFFS, | ||
1915 | AB8500_ANC_IIR_COEFF_MIN, AB8500_ANC_IIR_COEFF_MAX), | ||
1916 | AB8500_FILTER_CONTROL("Sidetone FIR Coefficients", | ||
1917 | AB8500_SID_FIR_COEFFS, AB8500_SID_FIR_COEFF_MIN, | ||
1918 | AB8500_SID_FIR_COEFF_MAX) | ||
1919 | }; | ||
1920 | enum ab8500_filter { | ||
1921 | AB8500_FILTER_ANC_FIR = 0, | ||
1922 | AB8500_FILTER_ANC_IIR = 1, | ||
1923 | AB8500_FILTER_SID_FIR = 2, | ||
1924 | }; | ||
1925 | |||
1926 | /* | ||
1927 | * Extended interface for codec-driver | ||
1928 | */ | ||
1929 | |||
1930 | static int ab8500_audio_init_audioblock(struct snd_soc_codec *codec) | ||
1931 | { | ||
1932 | int status; | ||
1933 | |||
1934 | dev_dbg(codec->dev, "%s: Enter.\n", __func__); | ||
1935 | |||
1936 | /* Reset audio-registers and disable 32kHz-clock output 2 */ | ||
1937 | status = ab8500_sysctrl_write(AB8500_STW4500CTRL3, | ||
1938 | AB8500_STW4500CTRL3_CLK32KOUT2DIS | | ||
1939 | AB8500_STW4500CTRL3_RESETAUDN, | ||
1940 | AB8500_STW4500CTRL3_RESETAUDN); | ||
1941 | if (status < 0) | ||
1942 | return status; | ||
1943 | |||
1944 | return 0; | ||
1945 | } | ||
1946 | |||
1947 | static int ab8500_audio_setup_mics(struct snd_soc_codec *codec, | ||
1948 | struct amic_settings *amics) | ||
1949 | { | ||
1950 | u8 value8; | ||
1951 | unsigned int value; | ||
1952 | int status; | ||
1953 | const struct snd_soc_dapm_route *route; | ||
1954 | |||
1955 | dev_dbg(codec->dev, "%s: Enter.\n", __func__); | ||
1956 | |||
1957 | /* Set DMic-clocks to outputs */ | ||
1958 | status = abx500_get_register_interruptible(codec->dev, (u8)AB8500_MISC, | ||
1959 | (u8)AB8500_GPIO_DIR4_REG, | ||
1960 | &value8); | ||
1961 | if (status < 0) | ||
1962 | return status; | ||
1963 | value = value8 | GPIO27_DIR_OUTPUT | GPIO29_DIR_OUTPUT | | ||
1964 | GPIO31_DIR_OUTPUT; | ||
1965 | status = abx500_set_register_interruptible(codec->dev, | ||
1966 | (u8)AB8500_MISC, | ||
1967 | (u8)AB8500_GPIO_DIR4_REG, | ||
1968 | value); | ||
1969 | if (status < 0) | ||
1970 | return status; | ||
1971 | |||
1972 | /* Attach regulators to AMic DAPM-paths */ | ||
1973 | dev_dbg(codec->dev, "%s: Mic 1a regulator: %s\n", __func__, | ||
1974 | amic_micbias_str(amics->mic1a_micbias)); | ||
1975 | route = &ab8500_dapm_routes_mic1a_vamicx[amics->mic1a_micbias]; | ||
1976 | status = snd_soc_dapm_add_routes(&codec->dapm, route, 1); | ||
1977 | dev_dbg(codec->dev, "%s: Mic 1b regulator: %s\n", __func__, | ||
1978 | amic_micbias_str(amics->mic1b_micbias)); | ||
1979 | route = &ab8500_dapm_routes_mic1b_vamicx[amics->mic1b_micbias]; | ||
1980 | status |= snd_soc_dapm_add_routes(&codec->dapm, route, 1); | ||
1981 | dev_dbg(codec->dev, "%s: Mic 2 regulator: %s\n", __func__, | ||
1982 | amic_micbias_str(amics->mic2_micbias)); | ||
1983 | route = &ab8500_dapm_routes_mic2_vamicx[amics->mic2_micbias]; | ||
1984 | status |= snd_soc_dapm_add_routes(&codec->dapm, route, 1); | ||
1985 | if (status < 0) { | ||
1986 | dev_err(codec->dev, | ||
1987 | "%s: Failed to add AMic-regulator DAPM-routes (%d).\n", | ||
1988 | __func__, status); | ||
1989 | return status; | ||
1990 | } | ||
1991 | |||
1992 | /* Set AMic-configuration */ | ||
1993 | dev_dbg(codec->dev, "%s: Mic 1 mic-type: %s\n", __func__, | ||
1994 | amic_type_str(amics->mic1_type)); | ||
1995 | snd_soc_update_bits(codec, AB8500_ANAGAIN1, AB8500_ANAGAINX_ENSEMICX, | ||
1996 | amics->mic1_type == AMIC_TYPE_DIFFERENTIAL ? | ||
1997 | 0 : AB8500_ANAGAINX_ENSEMICX); | ||
1998 | dev_dbg(codec->dev, "%s: Mic 2 mic-type: %s\n", __func__, | ||
1999 | amic_type_str(amics->mic2_type)); | ||
2000 | snd_soc_update_bits(codec, AB8500_ANAGAIN2, AB8500_ANAGAINX_ENSEMICX, | ||
2001 | amics->mic2_type == AMIC_TYPE_DIFFERENTIAL ? | ||
2002 | 0 : AB8500_ANAGAINX_ENSEMICX); | ||
2003 | |||
2004 | return 0; | ||
2005 | } | ||
2006 | EXPORT_SYMBOL_GPL(ab8500_audio_setup_mics); | ||
2007 | |||
2008 | static int ab8500_audio_set_ear_cmv(struct snd_soc_codec *codec, | ||
2009 | enum ear_cm_voltage ear_cmv) | ||
2010 | { | ||
2011 | char *cmv_str; | ||
2012 | |||
2013 | switch (ear_cmv) { | ||
2014 | case EAR_CMV_0_95V: | ||
2015 | cmv_str = "0.95V"; | ||
2016 | break; | ||
2017 | case EAR_CMV_1_10V: | ||
2018 | cmv_str = "1.10V"; | ||
2019 | break; | ||
2020 | case EAR_CMV_1_27V: | ||
2021 | cmv_str = "1.27V"; | ||
2022 | break; | ||
2023 | case EAR_CMV_1_58V: | ||
2024 | cmv_str = "1.58V"; | ||
2025 | break; | ||
2026 | default: | ||
2027 | dev_err(codec->dev, | ||
2028 | "%s: Unknown earpiece CM-voltage (%d)!\n", | ||
2029 | __func__, (int)ear_cmv); | ||
2030 | return -EINVAL; | ||
2031 | } | ||
2032 | dev_dbg(codec->dev, "%s: Earpiece CM-voltage: %s\n", __func__, | ||
2033 | cmv_str); | ||
2034 | snd_soc_update_bits(codec, AB8500_ANACONF1, AB8500_ANACONF1_EARSELCM, | ||
2035 | ear_cmv); | ||
2036 | |||
2037 | return 0; | ||
2038 | } | ||
2039 | EXPORT_SYMBOL_GPL(ab8500_audio_set_ear_cmv); | ||
2040 | |||
2041 | static int ab8500_audio_set_bit_delay(struct snd_soc_dai *dai, | ||
2042 | unsigned int delay) | ||
2043 | { | ||
2044 | unsigned int mask, val; | ||
2045 | struct snd_soc_codec *codec = dai->codec; | ||
2046 | |||
2047 | mask = BIT(AB8500_DIGIFCONF2_IF0DEL); | ||
2048 | val = 0; | ||
2049 | |||
2050 | switch (delay) { | ||
2051 | case 0: | ||
2052 | break; | ||
2053 | case 1: | ||
2054 | val |= BIT(AB8500_DIGIFCONF2_IF0DEL); | ||
2055 | break; | ||
2056 | default: | ||
2057 | dev_err(dai->codec->dev, | ||
2058 | "%s: ERROR: Unsupported bit-delay (0x%x)!\n", | ||
2059 | __func__, delay); | ||
2060 | return -EINVAL; | ||
2061 | } | ||
2062 | |||
2063 | dev_dbg(dai->codec->dev, "%s: IF0 Bit-delay: %d bits.\n", | ||
2064 | __func__, delay); | ||
2065 | snd_soc_update_bits(codec, AB8500_DIGIFCONF2, mask, val); | ||
2066 | |||
2067 | return 0; | ||
2068 | } | ||
2069 | |||
2070 | /* Gates clocking according format mask */ | ||
2071 | static int ab8500_codec_set_dai_clock_gate(struct snd_soc_codec *codec, | ||
2072 | unsigned int fmt) | ||
2073 | { | ||
2074 | unsigned int mask; | ||
2075 | unsigned int val; | ||
2076 | |||
2077 | mask = BIT(AB8500_DIGIFCONF1_ENMASTGEN) | | ||
2078 | BIT(AB8500_DIGIFCONF1_ENFSBITCLK0); | ||
2079 | |||
2080 | val = BIT(AB8500_DIGIFCONF1_ENMASTGEN); | ||
2081 | |||
2082 | switch (fmt & SND_SOC_DAIFMT_CLOCK_MASK) { | ||
2083 | case SND_SOC_DAIFMT_CONT: /* continuous clock */ | ||
2084 | dev_dbg(codec->dev, "%s: IF0 Clock is continuous.\n", | ||
2085 | __func__); | ||
2086 | val |= BIT(AB8500_DIGIFCONF1_ENFSBITCLK0); | ||
2087 | break; | ||
2088 | case SND_SOC_DAIFMT_GATED: /* clock is gated */ | ||
2089 | dev_dbg(codec->dev, "%s: IF0 Clock is gated.\n", | ||
2090 | __func__); | ||
2091 | break; | ||
2092 | default: | ||
2093 | dev_err(codec->dev, | ||
2094 | "%s: ERROR: Unsupported clock mask (0x%x)!\n", | ||
2095 | __func__, fmt & SND_SOC_DAIFMT_CLOCK_MASK); | ||
2096 | return -EINVAL; | ||
2097 | } | ||
2098 | |||
2099 | snd_soc_update_bits(codec, AB8500_DIGIFCONF1, mask, val); | ||
2100 | |||
2101 | return 0; | ||
2102 | } | ||
2103 | |||
2104 | static int ab8500_codec_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) | ||
2105 | { | ||
2106 | unsigned int mask; | ||
2107 | unsigned int val; | ||
2108 | struct snd_soc_codec *codec = dai->codec; | ||
2109 | int status; | ||
2110 | |||
2111 | dev_dbg(codec->dev, "%s: Enter (fmt = 0x%x)\n", __func__, fmt); | ||
2112 | |||
2113 | mask = BIT(AB8500_DIGIFCONF3_IF1DATOIF0AD) | | ||
2114 | BIT(AB8500_DIGIFCONF3_IF1CLKTOIF0CLK) | | ||
2115 | BIT(AB8500_DIGIFCONF3_IF0BFIFOEN) | | ||
2116 | BIT(AB8500_DIGIFCONF3_IF0MASTER); | ||
2117 | val = 0; | ||
2118 | |||
2119 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { | ||
2120 | case SND_SOC_DAIFMT_CBM_CFM: /* codec clk & FRM master */ | ||
2121 | dev_dbg(dai->codec->dev, | ||
2122 | "%s: IF0 Master-mode: AB8500 master.\n", __func__); | ||
2123 | val |= BIT(AB8500_DIGIFCONF3_IF0MASTER); | ||
2124 | break; | ||
2125 | case SND_SOC_DAIFMT_CBS_CFS: /* codec clk & FRM slave */ | ||
2126 | dev_dbg(dai->codec->dev, | ||
2127 | "%s: IF0 Master-mode: AB8500 slave.\n", __func__); | ||
2128 | break; | ||
2129 | case SND_SOC_DAIFMT_CBS_CFM: /* codec clk slave & FRM master */ | ||
2130 | case SND_SOC_DAIFMT_CBM_CFS: /* codec clk master & frame slave */ | ||
2131 | dev_err(dai->codec->dev, | ||
2132 | "%s: ERROR: The device is either a master or a slave.\n", | ||
2133 | __func__); | ||
2134 | default: | ||
2135 | dev_err(dai->codec->dev, | ||
2136 | "%s: ERROR: Unsupporter master mask 0x%x\n", | ||
2137 | __func__, fmt & SND_SOC_DAIFMT_MASTER_MASK); | ||
2138 | return -EINVAL; | ||
2139 | break; | ||
2140 | } | ||
2141 | |||
2142 | snd_soc_update_bits(codec, AB8500_DIGIFCONF3, mask, val); | ||
2143 | |||
2144 | /* Set clock gating */ | ||
2145 | status = ab8500_codec_set_dai_clock_gate(codec, fmt); | ||
2146 | if (status) { | ||
2147 | dev_err(dai->codec->dev, | ||
2148 | "%s: ERRROR: Failed to set clock gate (%d).\n", | ||
2149 | __func__, status); | ||
2150 | return status; | ||
2151 | } | ||
2152 | |||
2153 | /* Setting data transfer format */ | ||
2154 | |||
2155 | mask = BIT(AB8500_DIGIFCONF2_IF0FORMAT0) | | ||
2156 | BIT(AB8500_DIGIFCONF2_IF0FORMAT1) | | ||
2157 | BIT(AB8500_DIGIFCONF2_FSYNC0P) | | ||
2158 | BIT(AB8500_DIGIFCONF2_BITCLK0P); | ||
2159 | val = 0; | ||
2160 | |||
2161 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { | ||
2162 | case SND_SOC_DAIFMT_I2S: /* I2S mode */ | ||
2163 | dev_dbg(dai->codec->dev, "%s: IF0 Protocol: I2S\n", __func__); | ||
2164 | val |= BIT(AB8500_DIGIFCONF2_IF0FORMAT1); | ||
2165 | ab8500_audio_set_bit_delay(dai, 0); | ||
2166 | break; | ||
2167 | |||
2168 | case SND_SOC_DAIFMT_DSP_A: /* L data MSB after FRM LRC */ | ||
2169 | dev_dbg(dai->codec->dev, | ||
2170 | "%s: IF0 Protocol: DSP A (TDM)\n", __func__); | ||
2171 | val |= BIT(AB8500_DIGIFCONF2_IF0FORMAT0); | ||
2172 | ab8500_audio_set_bit_delay(dai, 1); | ||
2173 | break; | ||
2174 | |||
2175 | case SND_SOC_DAIFMT_DSP_B: /* L data MSB during FRM LRC */ | ||
2176 | dev_dbg(dai->codec->dev, | ||
2177 | "%s: IF0 Protocol: DSP B (TDM)\n", __func__); | ||
2178 | val |= BIT(AB8500_DIGIFCONF2_IF0FORMAT0); | ||
2179 | ab8500_audio_set_bit_delay(dai, 0); | ||
2180 | break; | ||
2181 | |||
2182 | default: | ||
2183 | dev_err(dai->codec->dev, | ||
2184 | "%s: ERROR: Unsupported format (0x%x)!\n", | ||
2185 | __func__, fmt & SND_SOC_DAIFMT_FORMAT_MASK); | ||
2186 | return -EINVAL; | ||
2187 | } | ||
2188 | |||
2189 | switch (fmt & SND_SOC_DAIFMT_INV_MASK) { | ||
2190 | case SND_SOC_DAIFMT_NB_NF: /* normal bit clock + frame */ | ||
2191 | dev_dbg(dai->codec->dev, | ||
2192 | "%s: IF0: Normal bit clock, normal frame\n", | ||
2193 | __func__); | ||
2194 | break; | ||
2195 | case SND_SOC_DAIFMT_NB_IF: /* normal BCLK + inv FRM */ | ||
2196 | dev_dbg(dai->codec->dev, | ||
2197 | "%s: IF0: Normal bit clock, inverted frame\n", | ||
2198 | __func__); | ||
2199 | val |= BIT(AB8500_DIGIFCONF2_FSYNC0P); | ||
2200 | break; | ||
2201 | case SND_SOC_DAIFMT_IB_NF: /* invert BCLK + nor FRM */ | ||
2202 | dev_dbg(dai->codec->dev, | ||
2203 | "%s: IF0: Inverted bit clock, normal frame\n", | ||
2204 | __func__); | ||
2205 | val |= BIT(AB8500_DIGIFCONF2_BITCLK0P); | ||
2206 | break; | ||
2207 | case SND_SOC_DAIFMT_IB_IF: /* invert BCLK + FRM */ | ||
2208 | dev_dbg(dai->codec->dev, | ||
2209 | "%s: IF0: Inverted bit clock, inverted frame\n", | ||
2210 | __func__); | ||
2211 | val |= BIT(AB8500_DIGIFCONF2_FSYNC0P); | ||
2212 | val |= BIT(AB8500_DIGIFCONF2_BITCLK0P); | ||
2213 | break; | ||
2214 | default: | ||
2215 | dev_err(dai->codec->dev, | ||
2216 | "%s: ERROR: Unsupported INV mask 0x%x\n", | ||
2217 | __func__, fmt & SND_SOC_DAIFMT_INV_MASK); | ||
2218 | return -EINVAL; | ||
2219 | } | ||
2220 | |||
2221 | snd_soc_update_bits(codec, AB8500_DIGIFCONF2, mask, val); | ||
2222 | |||
2223 | return 0; | ||
2224 | } | ||
2225 | |||
2226 | static int ab8500_codec_set_dai_tdm_slot(struct snd_soc_dai *dai, | ||
2227 | unsigned int tx_mask, unsigned int rx_mask, | ||
2228 | int slots, int slot_width) | ||
2229 | { | ||
2230 | struct snd_soc_codec *codec = dai->codec; | ||
2231 | unsigned int val, mask, slots_active; | ||
2232 | |||
2233 | mask = BIT(AB8500_DIGIFCONF2_IF0WL0) | | ||
2234 | BIT(AB8500_DIGIFCONF2_IF0WL1); | ||
2235 | val = 0; | ||
2236 | |||
2237 | switch (slot_width) { | ||
2238 | case 16: | ||
2239 | break; | ||
2240 | case 20: | ||
2241 | val |= BIT(AB8500_DIGIFCONF2_IF0WL0); | ||
2242 | break; | ||
2243 | case 24: | ||
2244 | val |= BIT(AB8500_DIGIFCONF2_IF0WL1); | ||
2245 | break; | ||
2246 | case 32: | ||
2247 | val |= BIT(AB8500_DIGIFCONF2_IF0WL1) | | ||
2248 | BIT(AB8500_DIGIFCONF2_IF0WL0); | ||
2249 | break; | ||
2250 | default: | ||
2251 | dev_err(dai->codec->dev, "%s: Unsupported slot-width 0x%x\n", | ||
2252 | __func__, slot_width); | ||
2253 | return -EINVAL; | ||
2254 | } | ||
2255 | |||
2256 | dev_dbg(dai->codec->dev, "%s: IF0 slot-width: %d bits.\n", | ||
2257 | __func__, slot_width); | ||
2258 | snd_soc_update_bits(codec, AB8500_DIGIFCONF2, mask, val); | ||
2259 | |||
2260 | /* Setup TDM clocking according to slot count */ | ||
2261 | dev_dbg(dai->codec->dev, "%s: Slots, total: %d\n", __func__, slots); | ||
2262 | mask = BIT(AB8500_DIGIFCONF1_IF0BITCLKOS0) | | ||
2263 | BIT(AB8500_DIGIFCONF1_IF0BITCLKOS1); | ||
2264 | switch (slots) { | ||
2265 | case 2: | ||
2266 | val = AB8500_MASK_NONE; | ||
2267 | break; | ||
2268 | case 4: | ||
2269 | val = BIT(AB8500_DIGIFCONF1_IF0BITCLKOS0); | ||
2270 | break; | ||
2271 | case 8: | ||
2272 | val = BIT(AB8500_DIGIFCONF1_IF0BITCLKOS1); | ||
2273 | break; | ||
2274 | case 16: | ||
2275 | val = BIT(AB8500_DIGIFCONF1_IF0BITCLKOS0) | | ||
2276 | BIT(AB8500_DIGIFCONF1_IF0BITCLKOS1); | ||
2277 | break; | ||
2278 | default: | ||
2279 | dev_err(dai->codec->dev, | ||
2280 | "%s: ERROR: Unsupported number of slots (%d)!\n", | ||
2281 | __func__, slots); | ||
2282 | return -EINVAL; | ||
2283 | } | ||
2284 | snd_soc_update_bits(codec, AB8500_DIGIFCONF1, mask, val); | ||
2285 | |||
2286 | /* Setup TDM DA according to active tx slots */ | ||
2287 | mask = AB8500_DASLOTCONFX_SLTODAX_MASK; | ||
2288 | slots_active = hweight32(tx_mask); | ||
2289 | dev_dbg(dai->codec->dev, "%s: Slots, active, TX: %d\n", __func__, | ||
2290 | slots_active); | ||
2291 | switch (slots_active) { | ||
2292 | case 0: | ||
2293 | break; | ||
2294 | case 1: | ||
2295 | /* Slot 9 -> DA_IN1 & DA_IN3 */ | ||
2296 | snd_soc_update_bits(codec, AB8500_DASLOTCONF1, mask, 11); | ||
2297 | snd_soc_update_bits(codec, AB8500_DASLOTCONF3, mask, 11); | ||
2298 | snd_soc_update_bits(codec, AB8500_DASLOTCONF2, mask, 11); | ||
2299 | snd_soc_update_bits(codec, AB8500_DASLOTCONF4, mask, 11); | ||
2300 | break; | ||
2301 | case 2: | ||
2302 | /* Slot 9 -> DA_IN1 & DA_IN3, Slot 11 -> DA_IN2 & DA_IN4 */ | ||
2303 | snd_soc_update_bits(codec, AB8500_DASLOTCONF1, mask, 9); | ||
2304 | snd_soc_update_bits(codec, AB8500_DASLOTCONF3, mask, 9); | ||
2305 | snd_soc_update_bits(codec, AB8500_DASLOTCONF2, mask, 11); | ||
2306 | snd_soc_update_bits(codec, AB8500_DASLOTCONF4, mask, 11); | ||
2307 | |||
2308 | break; | ||
2309 | case 8: | ||
2310 | dev_dbg(dai->codec->dev, | ||
2311 | "%s: In 8-channel mode DA-from-slot mapping is set manually.", | ||
2312 | __func__); | ||
2313 | break; | ||
2314 | default: | ||
2315 | dev_err(dai->codec->dev, | ||
2316 | "%s: Unsupported number of active TX-slots (%d)!\n", | ||
2317 | __func__, slots_active); | ||
2318 | return -EINVAL; | ||
2319 | } | ||
2320 | |||
2321 | /* Setup TDM AD according to active RX-slots */ | ||
2322 | slots_active = hweight32(rx_mask); | ||
2323 | dev_dbg(dai->codec->dev, "%s: Slots, active, RX: %d\n", __func__, | ||
2324 | slots_active); | ||
2325 | switch (slots_active) { | ||
2326 | case 0: | ||
2327 | break; | ||
2328 | case 1: | ||
2329 | /* AD_OUT3 -> slot 0 & 1 */ | ||
2330 | snd_soc_update_bits(codec, AB8500_ADSLOTSEL1, AB8500_MASK_ALL, | ||
2331 | AB8500_ADSLOTSELX_AD_OUT3_TO_SLOT_EVEN | | ||
2332 | AB8500_ADSLOTSELX_AD_OUT3_TO_SLOT_ODD); | ||
2333 | break; | ||
2334 | case 2: | ||
2335 | /* AD_OUT3 -> slot 0, AD_OUT2 -> slot 1 */ | ||
2336 | snd_soc_update_bits(codec, | ||
2337 | AB8500_ADSLOTSEL1, | ||
2338 | AB8500_MASK_ALL, | ||
2339 | AB8500_ADSLOTSELX_AD_OUT3_TO_SLOT_EVEN | | ||
2340 | AB8500_ADSLOTSELX_AD_OUT2_TO_SLOT_ODD); | ||
2341 | break; | ||
2342 | case 8: | ||
2343 | dev_dbg(dai->codec->dev, | ||
2344 | "%s: In 8-channel mode AD-to-slot mapping is set manually.", | ||
2345 | __func__); | ||
2346 | break; | ||
2347 | default: | ||
2348 | dev_err(dai->codec->dev, | ||
2349 | "%s: Unsupported number of active RX-slots (%d)!\n", | ||
2350 | __func__, slots_active); | ||
2351 | return -EINVAL; | ||
2352 | } | ||
2353 | |||
2354 | return 0; | ||
2355 | } | ||
2356 | |||
2357 | struct snd_soc_dai_driver ab8500_codec_dai[] = { | ||
2358 | { | ||
2359 | .name = "ab8500-codec-dai.0", | ||
2360 | .id = 0, | ||
2361 | .playback = { | ||
2362 | .stream_name = "ab8500_0p", | ||
2363 | .channels_min = 1, | ||
2364 | .channels_max = 8, | ||
2365 | .rates = AB8500_SUPPORTED_RATE, | ||
2366 | .formats = AB8500_SUPPORTED_FMT, | ||
2367 | }, | ||
2368 | .ops = (struct snd_soc_dai_ops[]) { | ||
2369 | { | ||
2370 | .set_tdm_slot = ab8500_codec_set_dai_tdm_slot, | ||
2371 | .set_fmt = ab8500_codec_set_dai_fmt, | ||
2372 | } | ||
2373 | }, | ||
2374 | .symmetric_rates = 1 | ||
2375 | }, | ||
2376 | { | ||
2377 | .name = "ab8500-codec-dai.1", | ||
2378 | .id = 1, | ||
2379 | .capture = { | ||
2380 | .stream_name = "ab8500_0c", | ||
2381 | .channels_min = 1, | ||
2382 | .channels_max = 8, | ||
2383 | .rates = AB8500_SUPPORTED_RATE, | ||
2384 | .formats = AB8500_SUPPORTED_FMT, | ||
2385 | }, | ||
2386 | .ops = (struct snd_soc_dai_ops[]) { | ||
2387 | { | ||
2388 | .set_tdm_slot = ab8500_codec_set_dai_tdm_slot, | ||
2389 | .set_fmt = ab8500_codec_set_dai_fmt, | ||
2390 | } | ||
2391 | }, | ||
2392 | .symmetric_rates = 1 | ||
2393 | } | ||
2394 | }; | ||
2395 | |||
2396 | static int ab8500_codec_probe(struct snd_soc_codec *codec) | ||
2397 | { | ||
2398 | struct device *dev = codec->dev; | ||
2399 | struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(dev); | ||
2400 | struct ab8500_platform_data *pdata; | ||
2401 | struct filter_control *fc; | ||
2402 | int status; | ||
2403 | |||
2404 | dev_dbg(dev, "%s: Enter.\n", __func__); | ||
2405 | |||
2406 | /* Setup AB8500 according to board-settings */ | ||
2407 | pdata = (struct ab8500_platform_data *)dev_get_platdata(dev->parent); | ||
2408 | status = ab8500_audio_setup_mics(codec, &pdata->codec->amics); | ||
2409 | if (status < 0) { | ||
2410 | pr_err("%s: Failed to setup mics (%d)!\n", __func__, status); | ||
2411 | return status; | ||
2412 | } | ||
2413 | status = ab8500_audio_set_ear_cmv(codec, pdata->codec->ear_cmv); | ||
2414 | if (status < 0) { | ||
2415 | pr_err("%s: Failed to set earpiece CM-voltage (%d)!\n", | ||
2416 | __func__, status); | ||
2417 | return status; | ||
2418 | } | ||
2419 | |||
2420 | status = ab8500_audio_init_audioblock(codec); | ||
2421 | if (status < 0) { | ||
2422 | dev_err(dev, "%s: failed to init audio-block (%d)!\n", | ||
2423 | __func__, status); | ||
2424 | return status; | ||
2425 | } | ||
2426 | |||
2427 | /* Override HW-defaults */ | ||
2428 | ab8500_codec_write_reg(codec, | ||
2429 | AB8500_ANACONF5, | ||
2430 | BIT(AB8500_ANACONF5_HSAUTOEN)); | ||
2431 | ab8500_codec_write_reg(codec, | ||
2432 | AB8500_SHORTCIRCONF, | ||
2433 | BIT(AB8500_SHORTCIRCONF_HSZCDDIS)); | ||
2434 | |||
2435 | /* Add filter controls */ | ||
2436 | status = snd_soc_add_codec_controls(codec, ab8500_filter_controls, | ||
2437 | ARRAY_SIZE(ab8500_filter_controls)); | ||
2438 | if (status < 0) { | ||
2439 | dev_err(dev, | ||
2440 | "%s: failed to add ab8500 filter controls (%d).\n", | ||
2441 | __func__, status); | ||
2442 | return status; | ||
2443 | } | ||
2444 | fc = (struct filter_control *) | ||
2445 | &ab8500_filter_controls[AB8500_FILTER_ANC_FIR].private_value; | ||
2446 | drvdata->anc_fir_values = (long *)fc->value; | ||
2447 | fc = (struct filter_control *) | ||
2448 | &ab8500_filter_controls[AB8500_FILTER_ANC_IIR].private_value; | ||
2449 | drvdata->anc_iir_values = (long *)fc->value; | ||
2450 | fc = (struct filter_control *) | ||
2451 | &ab8500_filter_controls[AB8500_FILTER_SID_FIR].private_value; | ||
2452 | drvdata->sid_fir_values = (long *)fc->value; | ||
2453 | |||
2454 | (void)snd_soc_dapm_disable_pin(&codec->dapm, "ANC Configure Input"); | ||
2455 | |||
2456 | mutex_init(&drvdata->anc_lock); | ||
2457 | |||
2458 | return status; | ||
2459 | } | ||
2460 | |||
2461 | static struct snd_soc_codec_driver ab8500_codec_driver = { | ||
2462 | .probe = ab8500_codec_probe, | ||
2463 | .read = ab8500_codec_read_reg, | ||
2464 | .write = ab8500_codec_write_reg, | ||
2465 | .reg_word_size = sizeof(u8), | ||
2466 | .controls = ab8500_ctrls, | ||
2467 | .num_controls = ARRAY_SIZE(ab8500_ctrls), | ||
2468 | .dapm_widgets = ab8500_dapm_widgets, | ||
2469 | .num_dapm_widgets = ARRAY_SIZE(ab8500_dapm_widgets), | ||
2470 | .dapm_routes = ab8500_dapm_routes, | ||
2471 | .num_dapm_routes = ARRAY_SIZE(ab8500_dapm_routes), | ||
2472 | }; | ||
2473 | |||
2474 | static int __devinit ab8500_codec_driver_probe(struct platform_device *pdev) | ||
2475 | { | ||
2476 | int status; | ||
2477 | struct ab8500_codec_drvdata *drvdata; | ||
2478 | |||
2479 | dev_dbg(&pdev->dev, "%s: Enter.\n", __func__); | ||
2480 | |||
2481 | /* Create driver private-data struct */ | ||
2482 | drvdata = devm_kzalloc(&pdev->dev, sizeof(struct ab8500_codec_drvdata), | ||
2483 | GFP_KERNEL); | ||
2484 | drvdata->sid_status = SID_UNCONFIGURED; | ||
2485 | drvdata->anc_status = ANC_UNCONFIGURED; | ||
2486 | dev_set_drvdata(&pdev->dev, drvdata); | ||
2487 | |||
2488 | dev_dbg(&pdev->dev, "%s: Register codec.\n", __func__); | ||
2489 | status = snd_soc_register_codec(&pdev->dev, &ab8500_codec_driver, | ||
2490 | ab8500_codec_dai, | ||
2491 | ARRAY_SIZE(ab8500_codec_dai)); | ||
2492 | if (status < 0) | ||
2493 | dev_err(&pdev->dev, | ||
2494 | "%s: Error: Failed to register codec (%d).\n", | ||
2495 | __func__, status); | ||
2496 | |||
2497 | return status; | ||
2498 | } | ||
2499 | |||
2500 | static int __devexit ab8500_codec_driver_remove(struct platform_device *pdev) | ||
2501 | { | ||
2502 | dev_info(&pdev->dev, "%s Enter.\n", __func__); | ||
2503 | |||
2504 | snd_soc_unregister_codec(&pdev->dev); | ||
2505 | |||
2506 | return 0; | ||
2507 | } | ||
2508 | |||
2509 | static struct platform_driver ab8500_codec_platform_driver = { | ||
2510 | .driver = { | ||
2511 | .name = "ab8500-codec", | ||
2512 | .owner = THIS_MODULE, | ||
2513 | }, | ||
2514 | .probe = ab8500_codec_driver_probe, | ||
2515 | .remove = __devexit_p(ab8500_codec_driver_remove), | ||
2516 | .suspend = NULL, | ||
2517 | .resume = NULL, | ||
2518 | }; | ||
2519 | module_platform_driver(ab8500_codec_platform_driver); | ||
2520 | |||
2521 | MODULE_LICENSE("GPLv2"); | ||