diff options
author | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-22 10:38:37 -0500 |
---|---|---|
committer | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-22 10:38:37 -0500 |
commit | fcc9d2e5a6c89d22b8b773a64fb4ad21ac318446 (patch) | |
tree | a57612d1888735a2ec7972891b68c1ac5ec8faea /sound/soc/codecs/rt5640.c | |
parent | 8dea78da5cee153b8af9c07a2745f6c55057fe12 (diff) |
Diffstat (limited to 'sound/soc/codecs/rt5640.c')
-rw-r--r-- | sound/soc/codecs/rt5640.c | 2546 |
1 files changed, 2546 insertions, 0 deletions
diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c new file mode 100644 index 00000000000..e3d0af02e39 --- /dev/null +++ b/sound/soc/codecs/rt5640.c | |||
@@ -0,0 +1,2546 @@ | |||
1 | /* | ||
2 | * rt5640.c -- RT5640 ALSA SoC audio codec driver | ||
3 | * | ||
4 | * Copyright 2011 Realtek Semiconductor Corp. | ||
5 | * Author: Johnny Hsu <johnnyhsu@realtek.com> | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | #include <linux/module.h> | ||
12 | #include <linux/moduleparam.h> | ||
13 | #include <linux/init.h> | ||
14 | #include <linux/delay.h> | ||
15 | #include <linux/pm.h> | ||
16 | #include <linux/i2c.h> | ||
17 | #include <linux/platform_device.h> | ||
18 | #include <linux/spi/spi.h> | ||
19 | #include <sound/core.h> | ||
20 | #include <sound/pcm.h> | ||
21 | #include <sound/pcm_params.h> | ||
22 | #include <sound/soc.h> | ||
23 | #include <sound/soc-dapm.h> | ||
24 | #include <sound/initval.h> | ||
25 | #include <sound/tlv.h> | ||
26 | |||
27 | #include "rt5640.h" | ||
28 | #if (CONFIG_SND_SOC_RT5642_MODULE | CONFIG_SND_SOC_RT5642) | ||
29 | #include "rt5640-dsp.h" | ||
30 | #endif | ||
31 | |||
32 | #define RT5640_DEMO 1 | ||
33 | #define RT5640_REG_RW 1 | ||
34 | #define RT5640_DET_EXT_MIC 0 | ||
35 | |||
36 | #ifdef RT5640_DEMO | ||
37 | struct rt5640_init_reg { | ||
38 | u8 reg; | ||
39 | u16 val; | ||
40 | }; | ||
41 | |||
42 | static struct rt5640_init_reg init_list[] = { | ||
43 | {RT5640_DUMMY1 , 0x3701},/*fa[12:13] = 1'b;fa[8~10]=1;fa[0]=1*/ | ||
44 | {RT5640_DEPOP_M1 , 0x0019},/* 8e[4:3] = 11'b; 8e[0] = 1'b */ | ||
45 | {RT5640_DEPOP_M2 , 0x3100},/* 8f[13] = 1'b */ | ||
46 | {RT5640_ADDA_CLK1 , 0x1114},/* 73[2] = 1'b */ | ||
47 | {RT5640_MICBIAS , 0x3030},/* 93[5:4] = 11'b */ | ||
48 | {RT5640_PRIV_INDEX , 0x003d},/* PR3d[12] = 1'b */ | ||
49 | {RT5640_PRIV_DATA , 0x3600}, | ||
50 | {RT5640_CLS_D_OUT , 0xa000},/* 8d[11] = 0'b */ | ||
51 | {RT5640_PRIV_INDEX , 0x001c},/* PR1c = 0D21'h */ | ||
52 | {RT5640_PRIV_DATA , 0x0D21}, | ||
53 | {RT5640_PRIV_INDEX , 0x001b},/* PR1B = 0D21'h */ | ||
54 | {RT5640_PRIV_DATA , 0x0000}, | ||
55 | {RT5640_PRIV_INDEX , 0x0012},/* PR12 = 0aa8'h */ | ||
56 | {RT5640_PRIV_DATA , 0x0aa8}, | ||
57 | {RT5640_PRIV_INDEX , 0x0014},/* PR14 = 0aaa'h */ | ||
58 | {RT5640_PRIV_DATA , 0x0aaa}, | ||
59 | {RT5640_PRIV_INDEX , 0x0020},/* PR20 = 6110'h */ | ||
60 | {RT5640_PRIV_DATA , 0x6110}, | ||
61 | {RT5640_PRIV_INDEX , 0x0021},/* PR21 = e0e0'h */ | ||
62 | {RT5640_PRIV_DATA , 0xe0e0}, | ||
63 | {RT5640_PRIV_INDEX , 0x0023},/* PR23 = 1804'h */ | ||
64 | {RT5640_PRIV_DATA , 0x1804}, | ||
65 | /*playback*/ | ||
66 | {RT5640_STO_DAC_MIXER , 0x1414},/*Dig inf 1 -> Sto DAC mixer -> DACL*/ | ||
67 | {RT5640_OUT_L3_MIXER , 0x01fe},/*DACL1 -> OUTMIXL*/ | ||
68 | {RT5640_OUT_R3_MIXER , 0x01fe},/*DACR1 -> OUTMIXR */ | ||
69 | {RT5640_HP_VOL , 0x8888},/* OUTMIX -> HPVOL */ | ||
70 | {RT5640_HPO_MIXER , 0xc000},/* HPVOL -> HPOLMIX */ | ||
71 | /* {RT5640_HPO_MIXER , 0xa000},// DAC1 -> HPOLMIX */ | ||
72 | {RT5640_SPK_L_MIXER , 0x0036},/* DACL1 -> SPKMIXL */ | ||
73 | {RT5640_SPK_R_MIXER , 0x0036},/* DACR1 -> SPKMIXR */ | ||
74 | {RT5640_SPK_VOL , 0x8888},/* SPKMIX -> SPKVOL */ | ||
75 | {RT5640_SPO_L_MIXER , 0xe800},/* SPKVOLL -> SPOLMIX */ | ||
76 | {RT5640_SPO_R_MIXER , 0x2800},/* SPKVOLR -> SPORMIX */ | ||
77 | /* {RT5640_SPO_L_MIXER , 0xb800},//DAC -> SPOLMIX */ | ||
78 | /* {RT5640_SPO_R_MIXER , 0x1800},//DAC -> SPORMIX */ | ||
79 | /* {RT5640_I2S1_SDP , 0xD000},//change IIS1 and IIS2 */ | ||
80 | /*record*/ | ||
81 | {RT5640_IN1_IN2 , 0x5080},/*IN1 boost 40db & differential mode*/ | ||
82 | {RT5640_IN3_IN4 , 0x0500},/*IN2 boost 40db & signal ended mode*/ | ||
83 | {RT5640_REC_L2_MIXER , 0x005f},/* enable Mic1 -> RECMIXL */ | ||
84 | {RT5640_REC_R2_MIXER , 0x005f},/* enable Mic1 -> RECMIXR */ | ||
85 | /* {RT5640_REC_L2_MIXER , 0x006f},//Mic2 -> RECMIXL */ | ||
86 | /* {RT5640_REC_R2_MIXER , 0x006f},//Mic2 -> RECMIXR */ | ||
87 | {RT5640_STO_ADC_MIXER , 0x3020},/* ADC -> Sto ADC mixer */ | ||
88 | |||
89 | #if RT5640_DET_EXT_MIC | ||
90 | {RT5640_MICBIAS , 0x3800},/* enable MICBIAS short current */ | ||
91 | {RT5640_GPIO_CTRL1 , 0x8400},/* set GPIO1 to IRQ */ | ||
92 | {RT5640_GPIO_CTRL3 , 0x0004},/* set GPIO1 output */ | ||
93 | {RT5640_IRQ_CTRL2 , 0x8000},/*set MICBIAS short current to IRQ */ | ||
94 | /*( if sticky set regBE : 8800 ) */ | ||
95 | #endif | ||
96 | |||
97 | }; | ||
98 | #define RT5640_INIT_REG_LEN ARRAY_SIZE(init_list) | ||
99 | |||
100 | static int rt5640_reg_init(struct snd_soc_codec *codec) | ||
101 | { | ||
102 | int i; | ||
103 | for (i = 0; i < RT5640_INIT_REG_LEN; i++) | ||
104 | snd_soc_write(codec, init_list[i].reg, init_list[i].val); | ||
105 | return 0; | ||
106 | } | ||
107 | #endif | ||
108 | |||
109 | static const u16 rt5640_reg[RT5640_VENDOR_ID2 + 1] = { | ||
110 | [RT5640_RESET] = 0x000c, | ||
111 | [RT5640_SPK_VOL] = 0xc8c8, | ||
112 | [RT5640_HP_VOL] = 0xc8c8, | ||
113 | [RT5640_OUTPUT] = 0xc8c8, | ||
114 | [RT5640_MONO_OUT] = 0x8000, | ||
115 | [RT5640_INL_INR_VOL] = 0x0808, | ||
116 | [RT5640_DAC1_DIG_VOL] = 0xafaf, | ||
117 | [RT5640_DAC2_DIG_VOL] = 0xafaf, | ||
118 | [RT5640_ADC_DIG_VOL] = 0x2f2f, | ||
119 | [RT5640_ADC_DATA] = 0x2f2f, | ||
120 | [RT5640_STO_ADC_MIXER] = 0x7060, | ||
121 | [RT5640_MONO_ADC_MIXER] = 0x7070, | ||
122 | [RT5640_AD_DA_MIXER] = 0x8080, | ||
123 | [RT5640_STO_DAC_MIXER] = 0x5454, | ||
124 | [RT5640_MONO_DAC_MIXER] = 0x5454, | ||
125 | [RT5640_DIG_MIXER] = 0xaa00, | ||
126 | [RT5640_DSP_PATH2] = 0xa000, | ||
127 | [RT5640_REC_L2_MIXER] = 0x007f, | ||
128 | [RT5640_REC_R2_MIXER] = 0x007f, | ||
129 | [RT5640_HPO_MIXER] = 0xe000, | ||
130 | [RT5640_SPK_L_MIXER] = 0x003e, | ||
131 | [RT5640_SPK_R_MIXER] = 0x003e, | ||
132 | [RT5640_SPO_L_MIXER] = 0xf800, | ||
133 | [RT5640_SPO_R_MIXER] = 0x3800, | ||
134 | [RT5640_SPO_CLSD_RATIO] = 0x0004, | ||
135 | [RT5640_MONO_MIXER] = 0xfc00, | ||
136 | [RT5640_OUT_L3_MIXER] = 0x01ff, | ||
137 | [RT5640_OUT_R3_MIXER] = 0x01ff, | ||
138 | [RT5640_LOUT_MIXER] = 0xf000, | ||
139 | [RT5640_PWR_ANLG1] = 0x00c0, | ||
140 | [RT5640_I2S1_SDP] = 0x8000, | ||
141 | [RT5640_I2S2_SDP] = 0x8000, | ||
142 | [RT5640_I2S3_SDP] = 0x8000, | ||
143 | [RT5640_ADDA_CLK1] = 0x1110, | ||
144 | [RT5640_ADDA_CLK2] = 0x0c00, | ||
145 | [RT5640_DMIC] = 0x1d00, | ||
146 | [RT5640_ASRC_3] = 0x0008, | ||
147 | [RT5640_HP_OVCD] = 0x0600, | ||
148 | [RT5640_CLS_D_OVCD] = 0x0228, | ||
149 | [RT5640_CLS_D_OUT] = 0xa800, | ||
150 | [RT5640_DEPOP_M1] = 0x0004, | ||
151 | [RT5640_DEPOP_M2] = 0x1100, | ||
152 | [RT5640_DEPOP_M3] = 0x0646, | ||
153 | [RT5640_CHARGE_PUMP] = 0x0c00, | ||
154 | [RT5640_MICBIAS] = 0x3000, | ||
155 | [RT5640_EQ_CTRL1] = 0x2080, | ||
156 | [RT5640_DRC_AGC_1] = 0x2206, | ||
157 | [RT5640_DRC_AGC_2] = 0x1f00, | ||
158 | [RT5640_ANC_CTRL1] = 0x034b, | ||
159 | [RT5640_ANC_CTRL2] = 0x0066, | ||
160 | [RT5640_ANC_CTRL3] = 0x000b, | ||
161 | [RT5640_GPIO_CTRL1] = 0x0400, | ||
162 | [RT5640_DSP_CTRL3] = 0x2000, | ||
163 | [RT5640_BASE_BACK] = 0x0013, | ||
164 | [RT5640_MP3_PLUS1] = 0x0680, | ||
165 | [RT5640_MP3_PLUS2] = 0x1c17, | ||
166 | [RT5640_3D_HP] = 0x8c00, | ||
167 | [RT5640_ADJ_HPF] = 0x2a20, | ||
168 | [RT5640_HP_CALIB_AMP_DET] = 0x0400, | ||
169 | [RT5640_SV_ZCD1] = 0x0809, | ||
170 | [RT5640_VENDOR_ID1] = 0x10ec, | ||
171 | [RT5640_VENDOR_ID2] = 0x6231, | ||
172 | }; | ||
173 | |||
174 | static int rt5640_reset(struct snd_soc_codec *codec) | ||
175 | { | ||
176 | return snd_soc_write(codec, RT5640_RESET, 0); | ||
177 | } | ||
178 | |||
179 | /** | ||
180 | * rt5640_index_write - Write private register. | ||
181 | * @codec: SoC audio codec device. | ||
182 | * @reg: Private register index. | ||
183 | * @value: Private register Data. | ||
184 | * | ||
185 | * Modify private register for advanced setting. It can be written through | ||
186 | * private index (0x6a) and data (0x6c) register. | ||
187 | * | ||
188 | * Returns 0 for success or negative error code. | ||
189 | */ | ||
190 | static int rt5640_index_write(struct snd_soc_codec *codec, | ||
191 | unsigned int reg, unsigned int value) | ||
192 | { | ||
193 | int ret; | ||
194 | |||
195 | ret = snd_soc_write(codec, RT5640_PRIV_INDEX, reg); | ||
196 | if (ret < 0) { | ||
197 | dev_err(codec->dev, "Failed to set private addr: %d\n", ret); | ||
198 | goto err; | ||
199 | } | ||
200 | ret = snd_soc_write(codec, RT5640_PRIV_DATA, value); | ||
201 | if (ret < 0) { | ||
202 | dev_err(codec->dev, "Failed to set private value: %d\n", ret); | ||
203 | goto err; | ||
204 | } | ||
205 | return 0; | ||
206 | |||
207 | err: | ||
208 | return ret; | ||
209 | } | ||
210 | |||
211 | /** | ||
212 | * rt5640_index_read - Read private register. | ||
213 | * @codec: SoC audio codec device. | ||
214 | * @reg: Private register index. | ||
215 | * | ||
216 | * Read advanced setting from private register. It can be read through | ||
217 | * private index (0x6a) and data (0x6c) register. | ||
218 | * | ||
219 | * Returns private register value or negative error code. | ||
220 | */ | ||
221 | static unsigned int rt5640_index_read( | ||
222 | struct snd_soc_codec *codec, unsigned int reg) | ||
223 | { | ||
224 | int ret; | ||
225 | |||
226 | ret = snd_soc_write(codec, RT5640_PRIV_INDEX, reg); | ||
227 | if (ret < 0) { | ||
228 | dev_err(codec->dev, "Failed to set private addr: %d\n", ret); | ||
229 | return ret; | ||
230 | } | ||
231 | return snd_soc_read(codec, RT5640_PRIV_DATA); | ||
232 | } | ||
233 | |||
234 | /** | ||
235 | * rt5640_index_update_bits - update private register bits | ||
236 | * @codec: audio codec | ||
237 | * @reg: Private register index. | ||
238 | * @mask: register mask | ||
239 | * @value: new value | ||
240 | * | ||
241 | * Writes new register value. | ||
242 | * | ||
243 | * Returns 1 for change, 0 for no change, or negative error code. | ||
244 | */ | ||
245 | static int rt5640_index_update_bits(struct snd_soc_codec *codec, | ||
246 | unsigned int reg, unsigned int mask, unsigned int value) | ||
247 | { | ||
248 | unsigned int old, new; | ||
249 | int change, ret; | ||
250 | |||
251 | ret = rt5640_index_read(codec, reg); | ||
252 | if (ret < 0) { | ||
253 | dev_err(codec->dev, "Failed to read private reg: %d\n", ret); | ||
254 | goto err; | ||
255 | } | ||
256 | |||
257 | old = ret; | ||
258 | new = (old & ~mask) | (value & mask); | ||
259 | change = old != new; | ||
260 | if (change) { | ||
261 | ret = rt5640_index_write(codec, reg, new); | ||
262 | if (ret < 0) { | ||
263 | dev_err(codec->dev, | ||
264 | "Failed to write private reg: %d\n", ret); | ||
265 | goto err; | ||
266 | } | ||
267 | } | ||
268 | return change; | ||
269 | |||
270 | err: | ||
271 | return ret; | ||
272 | } | ||
273 | |||
274 | static int rt5640_volatile_register( | ||
275 | struct snd_soc_codec *codec, unsigned int reg) | ||
276 | { | ||
277 | switch (reg) { | ||
278 | case RT5640_RESET: | ||
279 | case RT5640_PRIV_DATA: | ||
280 | case RT5640_ASRC_5: | ||
281 | case RT5640_EQ_CTRL1: | ||
282 | case RT5640_DRC_AGC_1: | ||
283 | case RT5640_ANC_CTRL1: | ||
284 | case RT5640_IRQ_CTRL2: | ||
285 | case RT5640_INT_IRQ_ST: | ||
286 | case RT5640_DSP_CTRL2: | ||
287 | case RT5640_DSP_CTRL3: | ||
288 | case RT5640_PGM_REG_ARR1: | ||
289 | case RT5640_PGM_REG_ARR3: | ||
290 | return 1; | ||
291 | default: | ||
292 | return 0; | ||
293 | } | ||
294 | } | ||
295 | |||
296 | static int rt5640_readable_register( | ||
297 | struct snd_soc_codec *codec, unsigned int reg) | ||
298 | { | ||
299 | switch (reg) { | ||
300 | case RT5640_RESET: | ||
301 | case RT5640_SPK_VOL: | ||
302 | case RT5640_HP_VOL: | ||
303 | case RT5640_OUTPUT: | ||
304 | case RT5640_MONO_OUT: | ||
305 | case RT5640_IN1_IN2: | ||
306 | case RT5640_IN3_IN4: | ||
307 | case RT5640_INL_INR_VOL: | ||
308 | case RT5640_DAC1_DIG_VOL: | ||
309 | case RT5640_DAC2_DIG_VOL: | ||
310 | case RT5640_DAC2_CTRL: | ||
311 | case RT5640_ADC_DIG_VOL: | ||
312 | case RT5640_ADC_DATA: | ||
313 | case RT5640_ADC_BST_VOL: | ||
314 | case RT5640_STO_ADC_MIXER: | ||
315 | case RT5640_MONO_ADC_MIXER: | ||
316 | case RT5640_AD_DA_MIXER: | ||
317 | case RT5640_STO_DAC_MIXER: | ||
318 | case RT5640_MONO_DAC_MIXER: | ||
319 | case RT5640_DIG_MIXER: | ||
320 | case RT5640_DSP_PATH1: | ||
321 | case RT5640_DSP_PATH2: | ||
322 | case RT5640_DIG_INF_DATA: | ||
323 | case RT5640_REC_L1_MIXER: | ||
324 | case RT5640_REC_L2_MIXER: | ||
325 | case RT5640_REC_R1_MIXER: | ||
326 | case RT5640_REC_R2_MIXER: | ||
327 | case RT5640_HPO_MIXER: | ||
328 | case RT5640_SPK_L_MIXER: | ||
329 | case RT5640_SPK_R_MIXER: | ||
330 | case RT5640_SPO_L_MIXER: | ||
331 | case RT5640_SPO_R_MIXER: | ||
332 | case RT5640_SPO_CLSD_RATIO: | ||
333 | case RT5640_MONO_MIXER: | ||
334 | case RT5640_OUT_L1_MIXER: | ||
335 | case RT5640_OUT_L2_MIXER: | ||
336 | case RT5640_OUT_L3_MIXER: | ||
337 | case RT5640_OUT_R1_MIXER: | ||
338 | case RT5640_OUT_R2_MIXER: | ||
339 | case RT5640_OUT_R3_MIXER: | ||
340 | case RT5640_LOUT_MIXER: | ||
341 | case RT5640_PWR_DIG1: | ||
342 | case RT5640_PWR_DIG2: | ||
343 | case RT5640_PWR_ANLG1: | ||
344 | case RT5640_PWR_ANLG2: | ||
345 | case RT5640_PWR_MIXER: | ||
346 | case RT5640_PWR_VOL: | ||
347 | case RT5640_PRIV_INDEX: | ||
348 | case RT5640_PRIV_DATA: | ||
349 | case RT5640_I2S1_SDP: | ||
350 | case RT5640_I2S2_SDP: | ||
351 | case RT5640_I2S3_SDP: | ||
352 | case RT5640_ADDA_CLK1: | ||
353 | case RT5640_ADDA_CLK2: | ||
354 | case RT5640_DMIC: | ||
355 | case RT5640_GLB_CLK: | ||
356 | case RT5640_PLL_CTRL1: | ||
357 | case RT5640_PLL_CTRL2: | ||
358 | case RT5640_ASRC_1: | ||
359 | case RT5640_ASRC_2: | ||
360 | case RT5640_ASRC_3: | ||
361 | case RT5640_ASRC_4: | ||
362 | case RT5640_ASRC_5: | ||
363 | case RT5640_HP_OVCD: | ||
364 | case RT5640_CLS_D_OVCD: | ||
365 | case RT5640_CLS_D_OUT: | ||
366 | case RT5640_DEPOP_M1: | ||
367 | case RT5640_DEPOP_M2: | ||
368 | case RT5640_DEPOP_M3: | ||
369 | case RT5640_CHARGE_PUMP: | ||
370 | case RT5640_PV_DET_SPK_G: | ||
371 | case RT5640_MICBIAS: | ||
372 | case RT5640_EQ_CTRL1: | ||
373 | case RT5640_EQ_CTRL2: | ||
374 | case RT5640_WIND_FILTER: | ||
375 | case RT5640_DRC_AGC_1: | ||
376 | case RT5640_DRC_AGC_2: | ||
377 | case RT5640_DRC_AGC_3: | ||
378 | case RT5640_SVOL_ZC: | ||
379 | case RT5640_ANC_CTRL1: | ||
380 | case RT5640_ANC_CTRL2: | ||
381 | case RT5640_ANC_CTRL3: | ||
382 | case RT5640_JD_CTRL: | ||
383 | case RT5640_ANC_JD: | ||
384 | case RT5640_IRQ_CTRL1: | ||
385 | case RT5640_IRQ_CTRL2: | ||
386 | case RT5640_INT_IRQ_ST: | ||
387 | case RT5640_GPIO_CTRL1: | ||
388 | case RT5640_GPIO_CTRL2: | ||
389 | case RT5640_GPIO_CTRL3: | ||
390 | case RT5640_DSP_CTRL1: | ||
391 | case RT5640_DSP_CTRL2: | ||
392 | case RT5640_DSP_CTRL3: | ||
393 | case RT5640_DSP_CTRL4: | ||
394 | case RT5640_PGM_REG_ARR1: | ||
395 | case RT5640_PGM_REG_ARR2: | ||
396 | case RT5640_PGM_REG_ARR3: | ||
397 | case RT5640_PGM_REG_ARR4: | ||
398 | case RT5640_PGM_REG_ARR5: | ||
399 | case RT5640_SCB_FUNC: | ||
400 | case RT5640_SCB_CTRL: | ||
401 | case RT5640_BASE_BACK: | ||
402 | case RT5640_MP3_PLUS1: | ||
403 | case RT5640_MP3_PLUS2: | ||
404 | case RT5640_3D_HP: | ||
405 | case RT5640_ADJ_HPF: | ||
406 | case RT5640_HP_CALIB_AMP_DET: | ||
407 | case RT5640_HP_CALIB2: | ||
408 | case RT5640_SV_ZCD1: | ||
409 | case RT5640_SV_ZCD2: | ||
410 | case RT5640_DUMMY1: | ||
411 | case RT5640_DUMMY2: | ||
412 | case RT5640_DUMMY3: | ||
413 | case RT5640_VENDOR_ID: | ||
414 | case RT5640_VENDOR_ID1: | ||
415 | case RT5640_VENDOR_ID2: | ||
416 | return 1; | ||
417 | default: | ||
418 | return 0; | ||
419 | } | ||
420 | } | ||
421 | |||
422 | int rt5640_headset_detect(struct snd_soc_codec *codec, int jack_insert) | ||
423 | { | ||
424 | int jack_type; | ||
425 | |||
426 | if (jack_insert) { | ||
427 | snd_soc_update_bits(codec, RT5640_PWR_ANLG1, | ||
428 | RT5640_PWR_LDO2, RT5640_PWR_LDO2); | ||
429 | snd_soc_update_bits(codec, RT5640_PWR_ANLG2, | ||
430 | RT5640_PWR_MB1, RT5640_PWR_MB1); | ||
431 | snd_soc_update_bits(codec, RT5640_MICBIAS, | ||
432 | RT5640_MIC1_OVCD_MASK | RT5640_MIC1_OVTH_MASK | | ||
433 | RT5640_PWR_CLK25M_MASK | RT5640_PWR_MB_MASK, | ||
434 | RT5640_MIC1_OVCD_EN | RT5640_MIC1_OVTH_600UA | | ||
435 | RT5640_PWR_MB_PU | RT5640_PWR_CLK25M_PU); | ||
436 | snd_soc_update_bits(codec, RT5640_DUMMY1, | ||
437 | 0x1, 0x1); | ||
438 | msleep(50); | ||
439 | if (snd_soc_read(codec, RT5640_IRQ_CTRL2) & 0x8) | ||
440 | jack_type = RT5640_HEADPHO_DET; | ||
441 | else | ||
442 | jack_type = RT5640_HEADSET_DET; | ||
443 | snd_soc_update_bits(codec, RT5640_IRQ_CTRL2, | ||
444 | RT5640_MB1_OC_CLR, 0); | ||
445 | } else { | ||
446 | snd_soc_update_bits(codec, RT5640_MICBIAS, | ||
447 | RT5640_MIC1_OVCD_MASK, | ||
448 | RT5640_MIC1_OVCD_DIS); | ||
449 | |||
450 | jack_type = RT5640_NO_JACK; | ||
451 | } | ||
452 | |||
453 | return jack_type; | ||
454 | } | ||
455 | EXPORT_SYMBOL(rt5640_headset_detect); | ||
456 | |||
457 | static const DECLARE_TLV_DB_SCALE(out_vol_tlv, -4650, 150, 0); | ||
458 | static const DECLARE_TLV_DB_SCALE(dac_vol_tlv, -65625, 375, 0); | ||
459 | static const DECLARE_TLV_DB_SCALE(in_vol_tlv, -3450, 150, 0); | ||
460 | static const DECLARE_TLV_DB_SCALE(adc_vol_tlv, -17625, 375, 0); | ||
461 | static const DECLARE_TLV_DB_SCALE(adc_bst_tlv, 0, 1200, 0); | ||
462 | |||
463 | /* {0, +20, +24, +30, +35, +40, +44, +50, +52} dB */ | ||
464 | static unsigned int bst_tlv[] = { | ||
465 | TLV_DB_RANGE_HEAD(7), | ||
466 | 0, 0, TLV_DB_SCALE_ITEM(0, 0, 0), | ||
467 | 1, 1, TLV_DB_SCALE_ITEM(2000, 0, 0), | ||
468 | 2, 2, TLV_DB_SCALE_ITEM(2400, 0, 0), | ||
469 | 3, 5, TLV_DB_SCALE_ITEM(3000, 500, 0), | ||
470 | 6, 6, TLV_DB_SCALE_ITEM(4400, 0, 0), | ||
471 | 7, 7, TLV_DB_SCALE_ITEM(5000, 0, 0), | ||
472 | 8, 8, TLV_DB_SCALE_ITEM(5200, 0, 0), | ||
473 | }; | ||
474 | |||
475 | static int rt5640_dmic_get(struct snd_kcontrol *kcontrol, | ||
476 | struct snd_ctl_elem_value *ucontrol) | ||
477 | { | ||
478 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | ||
479 | struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec); | ||
480 | |||
481 | ucontrol->value.integer.value[0] = rt5640->dmic_en; | ||
482 | |||
483 | return 0; | ||
484 | } | ||
485 | |||
486 | static int rt5640_dmic_put(struct snd_kcontrol *kcontrol, | ||
487 | struct snd_ctl_elem_value *ucontrol) | ||
488 | { | ||
489 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | ||
490 | struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec); | ||
491 | |||
492 | if (rt5640->dmic_en == ucontrol->value.integer.value[0]) | ||
493 | return 0; | ||
494 | |||
495 | rt5640->dmic_en = ucontrol->value.integer.value[0]; | ||
496 | switch (rt5640->dmic_en) { | ||
497 | case RT5640_DMIC_DIS: | ||
498 | snd_soc_update_bits(codec, RT5640_GPIO_CTRL1, | ||
499 | RT5640_GP2_PIN_MASK | RT5640_GP3_PIN_MASK | | ||
500 | RT5640_GP4_PIN_MASK, | ||
501 | RT5640_GP2_PIN_GPIO2 | RT5640_GP3_PIN_GPIO3 | | ||
502 | RT5640_GP4_PIN_GPIO4); | ||
503 | snd_soc_update_bits(codec, RT5640_DMIC, | ||
504 | RT5640_DMIC_1_DP_MASK | RT5640_DMIC_2_DP_MASK, | ||
505 | RT5640_DMIC_1_DP_GPIO3 | RT5640_DMIC_2_DP_GPIO4); | ||
506 | snd_soc_update_bits(codec, RT5640_DMIC, | ||
507 | RT5640_DMIC_1_EN_MASK | RT5640_DMIC_2_EN_MASK, | ||
508 | RT5640_DMIC_1_DIS | RT5640_DMIC_2_DIS); | ||
509 | break; | ||
510 | |||
511 | case RT5640_DMIC1: | ||
512 | snd_soc_update_bits(codec, RT5640_GPIO_CTRL1, | ||
513 | RT5640_GP2_PIN_MASK | RT5640_GP3_PIN_MASK, | ||
514 | RT5640_GP2_PIN_DMIC1_SCL | RT5640_GP3_PIN_DMIC1_SDA); | ||
515 | snd_soc_update_bits(codec, RT5640_DMIC, | ||
516 | RT5640_DMIC_1L_LH_MASK | RT5640_DMIC_1R_LH_MASK | | ||
517 | RT5640_DMIC_1_DP_MASK, | ||
518 | RT5640_DMIC_1L_LH_FALLING | RT5640_DMIC_1R_LH_RISING | | ||
519 | RT5640_DMIC_1_DP_IN1P); | ||
520 | snd_soc_update_bits(codec, RT5640_DMIC, | ||
521 | RT5640_DMIC_1_EN_MASK, RT5640_DMIC_1_EN); | ||
522 | break; | ||
523 | |||
524 | case RT5640_DMIC2: | ||
525 | snd_soc_update_bits(codec, RT5640_GPIO_CTRL1, | ||
526 | RT5640_GP2_PIN_MASK | RT5640_GP4_PIN_MASK, | ||
527 | RT5640_GP2_PIN_DMIC1_SCL | RT5640_GP4_PIN_DMIC2_SDA); | ||
528 | snd_soc_update_bits(codec, RT5640_DMIC, | ||
529 | RT5640_DMIC_2L_LH_MASK | RT5640_DMIC_2R_LH_MASK | | ||
530 | RT5640_DMIC_2_DP_MASK, | ||
531 | RT5640_DMIC_2L_LH_FALLING | RT5640_DMIC_2R_LH_RISING | | ||
532 | RT5640_DMIC_2_DP_IN1N); | ||
533 | snd_soc_update_bits(codec, RT5640_DMIC, | ||
534 | RT5640_DMIC_2_EN_MASK, RT5640_DMIC_2_EN); | ||
535 | break; | ||
536 | |||
537 | default: | ||
538 | return -EINVAL; | ||
539 | } | ||
540 | |||
541 | return 0; | ||
542 | } | ||
543 | |||
544 | |||
545 | /* IN1/IN2 Input Type */ | ||
546 | static const char *rt5640_input_mode[] = { | ||
547 | "Single ended", "Differential"}; | ||
548 | |||
549 | static const SOC_ENUM_SINGLE_DECL( | ||
550 | rt5640_in1_mode_enum, RT5640_IN1_IN2, | ||
551 | RT5640_IN_SFT1, rt5640_input_mode); | ||
552 | |||
553 | static const SOC_ENUM_SINGLE_DECL( | ||
554 | rt5640_in2_mode_enum, RT5640_IN3_IN4, | ||
555 | RT5640_IN_SFT2, rt5640_input_mode); | ||
556 | |||
557 | /* Interface data select */ | ||
558 | static const char *rt5640_data_select[] = { | ||
559 | "Normal", "left copy to right", "right copy to left", "Swap"}; | ||
560 | |||
561 | static const SOC_ENUM_SINGLE_DECL(rt5640_if1_dac_enum, RT5640_DIG_INF_DATA, | ||
562 | RT5640_IF1_DAC_SEL_SFT, rt5640_data_select); | ||
563 | |||
564 | static const SOC_ENUM_SINGLE_DECL(rt5640_if1_adc_enum, RT5640_DIG_INF_DATA, | ||
565 | RT5640_IF1_ADC_SEL_SFT, rt5640_data_select); | ||
566 | |||
567 | static const SOC_ENUM_SINGLE_DECL(rt5640_if2_dac_enum, RT5640_DIG_INF_DATA, | ||
568 | RT5640_IF2_DAC_SEL_SFT, rt5640_data_select); | ||
569 | |||
570 | static const SOC_ENUM_SINGLE_DECL(rt5640_if2_adc_enum, RT5640_DIG_INF_DATA, | ||
571 | RT5640_IF2_ADC_SEL_SFT, rt5640_data_select); | ||
572 | |||
573 | static const SOC_ENUM_SINGLE_DECL(rt5640_if3_dac_enum, RT5640_DIG_INF_DATA, | ||
574 | RT5640_IF3_DAC_SEL_SFT, rt5640_data_select); | ||
575 | |||
576 | static const SOC_ENUM_SINGLE_DECL(rt5640_if3_adc_enum, RT5640_DIG_INF_DATA, | ||
577 | RT5640_IF3_ADC_SEL_SFT, rt5640_data_select); | ||
578 | |||
579 | /* Class D speaker gain ratio */ | ||
580 | static const char *rt5640_clsd_spk_ratio[] = {"1.66x", "1.83x", "1.94x", "2x", | ||
581 | "2.11x", "2.22x", "2.33x", "2.44x", "2.55x", "2.66x", "2.77x"}; | ||
582 | |||
583 | static const SOC_ENUM_SINGLE_DECL( | ||
584 | rt5640_clsd_spk_ratio_enum, RT5640_CLS_D_OUT, | ||
585 | RT5640_CLSD_RATIO_SFT, rt5640_clsd_spk_ratio); | ||
586 | |||
587 | /* DMIC */ | ||
588 | static const char *rt5640_dmic_mode[] = {"Disable", "DMIC1", "DMIC2"}; | ||
589 | |||
590 | static const SOC_ENUM_SINGLE_DECL(rt5640_dmic_enum, 0, 0, rt5640_dmic_mode); | ||
591 | |||
592 | |||
593 | |||
594 | #ifdef RT5640_REG_RW | ||
595 | #define REGVAL_MAX 0xffff | ||
596 | static unsigned int regctl_addr; | ||
597 | static int rt5640_regctl_info(struct snd_kcontrol *kcontrol, | ||
598 | struct snd_ctl_elem_info *uinfo) { | ||
599 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | ||
600 | uinfo->count = 2; | ||
601 | uinfo->value.integer.min = 0; | ||
602 | uinfo->value.integer.max = REGVAL_MAX; | ||
603 | return 0; | ||
604 | } | ||
605 | |||
606 | static int rt5640_regctl_get(struct snd_kcontrol *kcontrol, | ||
607 | struct snd_ctl_elem_value *ucontrol) | ||
608 | { | ||
609 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | ||
610 | ucontrol->value.integer.value[0] = regctl_addr; | ||
611 | ucontrol->value.integer.value[1] = snd_soc_read(codec, regctl_addr); | ||
612 | return 0; | ||
613 | } | ||
614 | |||
615 | static int rt5640_regctl_put(struct snd_kcontrol *kcontrol, | ||
616 | struct snd_ctl_elem_value *ucontrol) | ||
617 | { | ||
618 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | ||
619 | regctl_addr = ucontrol->value.integer.value[0]; | ||
620 | if (ucontrol->value.integer.value[1] <= REGVAL_MAX) | ||
621 | snd_soc_write(codec, regctl_addr, | ||
622 | ucontrol->value.integer.value[1]); | ||
623 | return 0; | ||
624 | } | ||
625 | #endif | ||
626 | |||
627 | |||
628 | #define VOL_RESCALE_MAX_VOL 0x27 /* 39 */ | ||
629 | #define VOL_RESCALE_MIX_RANGE 0x1F /* 31 */ | ||
630 | |||
631 | static int rt5640_vol_rescale_get(struct snd_kcontrol *kcontrol, | ||
632 | struct snd_ctl_elem_value *ucontrol) | ||
633 | { | ||
634 | struct soc_mixer_control *mc = | ||
635 | (struct soc_mixer_control *)kcontrol->private_value; | ||
636 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | ||
637 | unsigned int val = snd_soc_read(codec, mc->reg); | ||
638 | |||
639 | ucontrol->value.integer.value[0] = VOL_RESCALE_MAX_VOL - | ||
640 | ((val & RT5640_L_VOL_MASK) >> mc->shift); | ||
641 | ucontrol->value.integer.value[1] = VOL_RESCALE_MAX_VOL - | ||
642 | (val & RT5640_R_VOL_MASK); | ||
643 | |||
644 | return 0; | ||
645 | } | ||
646 | |||
647 | static int rt5640_vol_rescale_put(struct snd_kcontrol *kcontrol, | ||
648 | struct snd_ctl_elem_value *ucontrol) | ||
649 | { | ||
650 | struct soc_mixer_control *mc = | ||
651 | (struct soc_mixer_control *)kcontrol->private_value; | ||
652 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | ||
653 | unsigned int val, val2; | ||
654 | |||
655 | val = VOL_RESCALE_MAX_VOL - ucontrol->value.integer.value[0]; | ||
656 | val2 = VOL_RESCALE_MAX_VOL - ucontrol->value.integer.value[1]; | ||
657 | return snd_soc_update_bits_locked(codec, mc->reg, RT5640_L_VOL_MASK | | ||
658 | RT5640_R_VOL_MASK, val << mc->shift | val2); | ||
659 | } | ||
660 | |||
661 | |||
662 | static const struct snd_kcontrol_new rt5640_snd_controls[] = { | ||
663 | /* Speaker Output Volume */ | ||
664 | SOC_DOUBLE_EXT_TLV("Speaker Playback Volume", RT5640_SPK_VOL, | ||
665 | RT5640_L_VOL_SFT, RT5640_R_VOL_SFT, VOL_RESCALE_MIX_RANGE, 0, | ||
666 | rt5640_vol_rescale_get, rt5640_vol_rescale_put, out_vol_tlv), | ||
667 | |||
668 | /* Headphone Output Volume */ | ||
669 | SOC_DOUBLE("HP Playback Switch", RT5640_HP_VOL, | ||
670 | RT5640_L_MUTE_SFT, RT5640_R_MUTE_SFT, 1, 1), | ||
671 | |||
672 | SOC_DOUBLE_EXT_TLV("HP Playback Volume", RT5640_HP_VOL, | ||
673 | RT5640_L_VOL_SFT, RT5640_R_VOL_SFT, VOL_RESCALE_MIX_RANGE, 0, | ||
674 | rt5640_vol_rescale_get, rt5640_vol_rescale_put, out_vol_tlv), | ||
675 | |||
676 | /* OUTPUT Control */ | ||
677 | SOC_DOUBLE("OUT Playback Switch", RT5640_OUTPUT, | ||
678 | RT5640_L_MUTE_SFT, RT5640_R_MUTE_SFT, 1, 1), | ||
679 | SOC_DOUBLE("OUT Channel Switch", RT5640_OUTPUT, | ||
680 | RT5640_VOL_L_SFT, RT5640_VOL_R_SFT, 1, 1), | ||
681 | SOC_DOUBLE_TLV("OUT Playback Volume", RT5640_OUTPUT, | ||
682 | RT5640_L_VOL_SFT, RT5640_R_VOL_SFT, 39, 1, out_vol_tlv), | ||
683 | /* MONO Output Control */ | ||
684 | SOC_SINGLE("Mono Playback Switch", RT5640_MONO_OUT, | ||
685 | RT5640_L_MUTE_SFT, 1, 1), | ||
686 | /* DAC Digital Volume */ | ||
687 | SOC_DOUBLE("DAC2 Playback Switch", RT5640_DAC2_CTRL, | ||
688 | RT5640_M_DAC_L2_VOL_SFT, RT5640_M_DAC_R2_VOL_SFT, 1, 1), | ||
689 | SOC_DOUBLE_TLV("DAC1 Playback Volume", RT5640_DAC1_DIG_VOL, | ||
690 | RT5640_L_VOL_SFT, RT5640_R_VOL_SFT, | ||
691 | 175, 0, dac_vol_tlv), | ||
692 | SOC_DOUBLE_TLV("Mono DAC Playback Volume", RT5640_DAC2_DIG_VOL, | ||
693 | RT5640_L_VOL_SFT, RT5640_R_VOL_SFT, | ||
694 | 175, 0, dac_vol_tlv), | ||
695 | /* IN1/IN2 Control */ | ||
696 | SOC_ENUM("IN1 Mode Control", rt5640_in1_mode_enum), | ||
697 | SOC_SINGLE_TLV("IN1 Boost", RT5640_IN1_IN2, | ||
698 | RT5640_BST_SFT1, 8, 0, bst_tlv), | ||
699 | SOC_ENUM("IN2 Mode Control", rt5640_in2_mode_enum), | ||
700 | SOC_SINGLE_TLV("IN2 Boost", RT5640_IN3_IN4, | ||
701 | RT5640_BST_SFT2, 8, 0, bst_tlv), | ||
702 | /* INL/INR Volume Control */ | ||
703 | SOC_DOUBLE_TLV("IN Capture Volume", RT5640_INL_INR_VOL, | ||
704 | RT5640_INL_VOL_SFT, RT5640_INR_VOL_SFT, | ||
705 | 31, 1, in_vol_tlv), | ||
706 | /* ADC Digital Volume Control */ | ||
707 | SOC_DOUBLE("ADC Capture Switch", RT5640_ADC_DIG_VOL, | ||
708 | RT5640_L_MUTE_SFT, RT5640_R_MUTE_SFT, 1, 1), | ||
709 | SOC_DOUBLE_TLV("ADC Capture Volume", RT5640_ADC_DIG_VOL, | ||
710 | RT5640_L_VOL_SFT, RT5640_R_VOL_SFT, | ||
711 | 127, 0, adc_vol_tlv), | ||
712 | SOC_DOUBLE_TLV("Mono ADC Capture Volume", RT5640_ADC_DATA, | ||
713 | RT5640_L_VOL_SFT, RT5640_R_VOL_SFT, | ||
714 | 127, 0, adc_vol_tlv), | ||
715 | /* ADC Boost Volume Control */ | ||
716 | SOC_DOUBLE_TLV("ADC Boost Gain", RT5640_ADC_BST_VOL, | ||
717 | RT5640_ADC_L_BST_SFT, RT5640_ADC_R_BST_SFT, | ||
718 | 3, 0, adc_bst_tlv), | ||
719 | /* Class D speaker gain ratio */ | ||
720 | SOC_ENUM("Class D SPK Ratio Control", rt5640_clsd_spk_ratio_enum), | ||
721 | /* DMIC */ | ||
722 | SOC_ENUM_EXT("DMIC Switch", rt5640_dmic_enum, | ||
723 | rt5640_dmic_get, rt5640_dmic_put), | ||
724 | |||
725 | #ifdef RT5640_REG_RW | ||
726 | { | ||
727 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
728 | .name = "Register Control", | ||
729 | .info = rt5640_regctl_info, | ||
730 | .get = rt5640_regctl_get, | ||
731 | .put = rt5640_regctl_put, | ||
732 | }, | ||
733 | #endif | ||
734 | }; | ||
735 | |||
736 | /** | ||
737 | * set_dmic_clk - Set parameter of dmic. | ||
738 | * | ||
739 | * @w: DAPM widget. | ||
740 | * @kcontrol: The kcontrol of this widget. | ||
741 | * @event: Event id. | ||
742 | * | ||
743 | * Choose dmic clock between 1MHz and 3MHz. | ||
744 | * It is better for clock to approximate 3MHz. | ||
745 | */ | ||
746 | static int set_dmic_clk(struct snd_soc_dapm_widget *w, | ||
747 | struct snd_kcontrol *kcontrol, int event) | ||
748 | { | ||
749 | struct snd_soc_codec *codec = w->codec; | ||
750 | struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec); | ||
751 | int div[] = {2, 3, 4, 6, 12}, idx = -EINVAL, i, rate, red, bound, temp; | ||
752 | |||
753 | rate = rt5640->lrck[rt5640->aif_pu] << 8; | ||
754 | red = 3000000 * 12; | ||
755 | for (i = 0; i < ARRAY_SIZE(div); i++) { | ||
756 | bound = div[i] * 3000000; | ||
757 | if (rate > bound) | ||
758 | continue; | ||
759 | temp = bound - rate; | ||
760 | if (temp < red) { | ||
761 | red = temp; | ||
762 | idx = i; | ||
763 | } | ||
764 | } | ||
765 | if (idx < 0) | ||
766 | dev_err(codec->dev, "Failed to set DMIC clock\n"); | ||
767 | else | ||
768 | snd_soc_update_bits(codec, RT5640_DMIC, RT5640_DMIC_CLK_MASK, | ||
769 | idx << RT5640_DMIC_CLK_SFT); | ||
770 | return idx; | ||
771 | } | ||
772 | |||
773 | static int check_sysclk1_source(struct snd_soc_dapm_widget *source, | ||
774 | struct snd_soc_dapm_widget *sink) | ||
775 | { | ||
776 | unsigned int val; | ||
777 | |||
778 | val = snd_soc_read(source->codec, RT5640_GLB_CLK); | ||
779 | val &= RT5640_SCLK_SRC_MASK; | ||
780 | if (val == RT5640_SCLK_SRC_PLL1 || val == RT5640_SCLK_SRC_PLL1T) | ||
781 | return 1; | ||
782 | else | ||
783 | return 0; | ||
784 | } | ||
785 | |||
786 | /* Digital Mixer */ | ||
787 | static const struct snd_kcontrol_new rt5640_sto_adc_l_mix[] = { | ||
788 | SOC_DAPM_SINGLE("ADC1 Switch", RT5640_STO_ADC_MIXER, | ||
789 | RT5640_M_ADC_L1_SFT, 1, 1), | ||
790 | SOC_DAPM_SINGLE("ADC2 Switch", RT5640_STO_ADC_MIXER, | ||
791 | RT5640_M_ADC_L2_SFT, 1, 1), | ||
792 | }; | ||
793 | |||
794 | static const struct snd_kcontrol_new rt5640_sto_adc_r_mix[] = { | ||
795 | SOC_DAPM_SINGLE("ADC1 Switch", RT5640_STO_ADC_MIXER, | ||
796 | RT5640_M_ADC_R1_SFT, 1, 1), | ||
797 | SOC_DAPM_SINGLE("ADC2 Switch", RT5640_STO_ADC_MIXER, | ||
798 | RT5640_M_ADC_R2_SFT, 1, 1), | ||
799 | }; | ||
800 | |||
801 | static const struct snd_kcontrol_new rt5640_mono_adc_l_mix[] = { | ||
802 | SOC_DAPM_SINGLE("ADC1 Switch", RT5640_MONO_ADC_MIXER, | ||
803 | RT5640_M_MONO_ADC_L1_SFT, 1, 1), | ||
804 | SOC_DAPM_SINGLE("ADC2 Switch", RT5640_MONO_ADC_MIXER, | ||
805 | RT5640_M_MONO_ADC_L2_SFT, 1, 1), | ||
806 | }; | ||
807 | |||
808 | static const struct snd_kcontrol_new rt5640_mono_adc_r_mix[] = { | ||
809 | SOC_DAPM_SINGLE("ADC1 Switch", RT5640_MONO_ADC_MIXER, | ||
810 | RT5640_M_MONO_ADC_R1_SFT, 1, 1), | ||
811 | SOC_DAPM_SINGLE("ADC2 Switch", RT5640_MONO_ADC_MIXER, | ||
812 | RT5640_M_MONO_ADC_R2_SFT, 1, 1), | ||
813 | }; | ||
814 | |||
815 | static const struct snd_kcontrol_new rt5640_dac_l_mix[] = { | ||
816 | SOC_DAPM_SINGLE("Stereo ADC Switch", RT5640_AD_DA_MIXER, | ||
817 | RT5640_M_ADCMIX_L_SFT, 1, 1), | ||
818 | SOC_DAPM_SINGLE("INF1 Switch", RT5640_AD_DA_MIXER, | ||
819 | RT5640_M_IF1_DAC_L_SFT, 1, 1), | ||
820 | }; | ||
821 | |||
822 | static const struct snd_kcontrol_new rt5640_dac_r_mix[] = { | ||
823 | SOC_DAPM_SINGLE("Stereo ADC Switch", RT5640_AD_DA_MIXER, | ||
824 | RT5640_M_ADCMIX_R_SFT, 1, 1), | ||
825 | SOC_DAPM_SINGLE("INF1 Switch", RT5640_AD_DA_MIXER, | ||
826 | RT5640_M_IF1_DAC_R_SFT, 1, 1), | ||
827 | }; | ||
828 | |||
829 | static const struct snd_kcontrol_new rt5640_sto_dac_l_mix[] = { | ||
830 | SOC_DAPM_SINGLE("DAC L1 Switch", RT5640_STO_DAC_MIXER, | ||
831 | RT5640_M_DAC_L1_SFT, 1, 1), | ||
832 | SOC_DAPM_SINGLE("DAC L2 Switch", RT5640_STO_DAC_MIXER, | ||
833 | RT5640_M_DAC_L2_SFT, 1, 1), | ||
834 | SOC_DAPM_SINGLE("ANC Switch", RT5640_STO_DAC_MIXER, | ||
835 | RT5640_M_ANC_DAC_L_SFT, 1, 1), | ||
836 | }; | ||
837 | |||
838 | static const struct snd_kcontrol_new rt5640_sto_dac_r_mix[] = { | ||
839 | SOC_DAPM_SINGLE("DAC R1 Switch", RT5640_STO_DAC_MIXER, | ||
840 | RT5640_M_DAC_R1_SFT, 1, 1), | ||
841 | SOC_DAPM_SINGLE("DAC R2 Switch", RT5640_STO_DAC_MIXER, | ||
842 | RT5640_M_DAC_R2_SFT, 1, 1), | ||
843 | SOC_DAPM_SINGLE("ANC Switch", RT5640_STO_DAC_MIXER, | ||
844 | RT5640_M_ANC_DAC_R_SFT, 1, 1), | ||
845 | }; | ||
846 | |||
847 | static const struct snd_kcontrol_new rt5640_mono_dac_l_mix[] = { | ||
848 | SOC_DAPM_SINGLE("DAC L1 Switch", RT5640_MONO_DAC_MIXER, | ||
849 | RT5640_M_DAC_L1_MONO_L_SFT, 1, 1), | ||
850 | SOC_DAPM_SINGLE("DAC L2 Switch", RT5640_MONO_DAC_MIXER, | ||
851 | RT5640_M_DAC_L2_MONO_L_SFT, 1, 1), | ||
852 | SOC_DAPM_SINGLE("DAC R2 Switch", RT5640_MONO_DAC_MIXER, | ||
853 | RT5640_M_DAC_R2_MONO_L_SFT, 1, 1), | ||
854 | }; | ||
855 | |||
856 | static const struct snd_kcontrol_new rt5640_mono_dac_r_mix[] = { | ||
857 | SOC_DAPM_SINGLE("DAC R1 Switch", RT5640_MONO_DAC_MIXER, | ||
858 | RT5640_M_DAC_R1_MONO_R_SFT, 1, 1), | ||
859 | SOC_DAPM_SINGLE("DAC R2 Switch", RT5640_MONO_DAC_MIXER, | ||
860 | RT5640_M_DAC_R2_MONO_R_SFT, 1, 1), | ||
861 | SOC_DAPM_SINGLE("DAC L2 Switch", RT5640_MONO_DAC_MIXER, | ||
862 | RT5640_M_DAC_L2_MONO_R_SFT, 1, 1), | ||
863 | }; | ||
864 | |||
865 | static const struct snd_kcontrol_new rt5640_dig_l_mix[] = { | ||
866 | SOC_DAPM_SINGLE("DAC L1 Switch", RT5640_DIG_MIXER, | ||
867 | RT5640_M_STO_L_DAC_L_SFT, 1, 1), | ||
868 | SOC_DAPM_SINGLE("DAC L2 Switch", RT5640_DIG_MIXER, | ||
869 | RT5640_M_DAC_L2_DAC_L_SFT, 1, 1), | ||
870 | }; | ||
871 | |||
872 | static const struct snd_kcontrol_new rt5640_dig_r_mix[] = { | ||
873 | SOC_DAPM_SINGLE("DAC R1 Switch", RT5640_DIG_MIXER, | ||
874 | RT5640_M_STO_R_DAC_R_SFT, 1, 1), | ||
875 | SOC_DAPM_SINGLE("DAC R2 Switch", RT5640_DIG_MIXER, | ||
876 | RT5640_M_DAC_R2_DAC_R_SFT, 1, 1), | ||
877 | }; | ||
878 | |||
879 | /* Analog Input Mixer */ | ||
880 | static const struct snd_kcontrol_new rt5640_rec_l_mix[] = { | ||
881 | SOC_DAPM_SINGLE("HPOL Switch", RT5640_REC_L2_MIXER, | ||
882 | RT5640_M_HP_L_RM_L_SFT, 1, 1), | ||
883 | SOC_DAPM_SINGLE("INL Switch", RT5640_REC_L2_MIXER, | ||
884 | RT5640_M_IN_L_RM_L_SFT, 1, 1), | ||
885 | SOC_DAPM_SINGLE("BST2 Switch", RT5640_REC_L2_MIXER, | ||
886 | RT5640_M_BST4_RM_L_SFT, 1, 1), | ||
887 | SOC_DAPM_SINGLE("BST1 Switch", RT5640_REC_L2_MIXER, | ||
888 | RT5640_M_BST1_RM_L_SFT, 1, 1), | ||
889 | SOC_DAPM_SINGLE("OUT MIXL Switch", RT5640_REC_L2_MIXER, | ||
890 | RT5640_M_OM_L_RM_L_SFT, 1, 1), | ||
891 | }; | ||
892 | |||
893 | static const struct snd_kcontrol_new rt5640_rec_r_mix[] = { | ||
894 | SOC_DAPM_SINGLE("HPOR Switch", RT5640_REC_R2_MIXER, | ||
895 | RT5640_M_HP_R_RM_R_SFT, 1, 1), | ||
896 | SOC_DAPM_SINGLE("INR Switch", RT5640_REC_R2_MIXER, | ||
897 | RT5640_M_IN_R_RM_R_SFT, 1, 1), | ||
898 | SOC_DAPM_SINGLE("BST2 Switch", RT5640_REC_R2_MIXER, | ||
899 | RT5640_M_BST4_RM_R_SFT, 1, 1), | ||
900 | SOC_DAPM_SINGLE("BST1 Switch", RT5640_REC_R2_MIXER, | ||
901 | RT5640_M_BST1_RM_R_SFT, 1, 1), | ||
902 | SOC_DAPM_SINGLE("OUT MIXR Switch", RT5640_REC_R2_MIXER, | ||
903 | RT5640_M_OM_R_RM_R_SFT, 1, 1), | ||
904 | }; | ||
905 | |||
906 | /* Analog Output Mixer */ | ||
907 | static const struct snd_kcontrol_new rt5640_spk_l_mix[] = { | ||
908 | SOC_DAPM_SINGLE("REC MIXL Switch", RT5640_SPK_L_MIXER, | ||
909 | RT5640_M_RM_L_SM_L_SFT, 1, 1), | ||
910 | SOC_DAPM_SINGLE("INL Switch", RT5640_SPK_L_MIXER, | ||
911 | RT5640_M_IN_L_SM_L_SFT, 1, 1), | ||
912 | SOC_DAPM_SINGLE("DAC L1 Switch", RT5640_SPK_L_MIXER, | ||
913 | RT5640_M_DAC_L1_SM_L_SFT, 1, 1), | ||
914 | SOC_DAPM_SINGLE("DAC L2 Switch", RT5640_SPK_L_MIXER, | ||
915 | RT5640_M_DAC_L2_SM_L_SFT, 1, 1), | ||
916 | SOC_DAPM_SINGLE("OUT MIXL Switch", RT5640_SPK_L_MIXER, | ||
917 | RT5640_M_OM_L_SM_L_SFT, 1, 1), | ||
918 | }; | ||
919 | |||
920 | static const struct snd_kcontrol_new rt5640_spk_r_mix[] = { | ||
921 | SOC_DAPM_SINGLE("REC MIXR Switch", RT5640_SPK_R_MIXER, | ||
922 | RT5640_M_RM_R_SM_R_SFT, 1, 1), | ||
923 | SOC_DAPM_SINGLE("INR Switch", RT5640_SPK_R_MIXER, | ||
924 | RT5640_M_IN_R_SM_R_SFT, 1, 1), | ||
925 | SOC_DAPM_SINGLE("DAC R1 Switch", RT5640_SPK_R_MIXER, | ||
926 | RT5640_M_DAC_R1_SM_R_SFT, 1, 1), | ||
927 | SOC_DAPM_SINGLE("DAC R2 Switch", RT5640_SPK_R_MIXER, | ||
928 | RT5640_M_DAC_R2_SM_R_SFT, 1, 1), | ||
929 | SOC_DAPM_SINGLE("OUT MIXR Switch", RT5640_SPK_R_MIXER, | ||
930 | RT5640_M_OM_R_SM_R_SFT, 1, 1), | ||
931 | }; | ||
932 | |||
933 | static const struct snd_kcontrol_new rt5640_out_l_mix[] = { | ||
934 | SOC_DAPM_SINGLE("SPK MIXL Switch", RT5640_OUT_L3_MIXER, | ||
935 | RT5640_M_SM_L_OM_L_SFT, 1, 1), | ||
936 | SOC_DAPM_SINGLE("BST1 Switch", RT5640_OUT_L3_MIXER, | ||
937 | RT5640_M_BST1_OM_L_SFT, 1, 1), | ||
938 | SOC_DAPM_SINGLE("INL Switch", RT5640_OUT_L3_MIXER, | ||
939 | RT5640_M_IN_L_OM_L_SFT, 1, 1), | ||
940 | SOC_DAPM_SINGLE("REC MIXL Switch", RT5640_OUT_L3_MIXER, | ||
941 | RT5640_M_RM_L_OM_L_SFT, 1, 1), | ||
942 | SOC_DAPM_SINGLE("DAC R2 Switch", RT5640_OUT_L3_MIXER, | ||
943 | RT5640_M_DAC_R2_OM_L_SFT, 1, 1), | ||
944 | SOC_DAPM_SINGLE("DAC L2 Switch", RT5640_OUT_L3_MIXER, | ||
945 | RT5640_M_DAC_L2_OM_L_SFT, 1, 1), | ||
946 | SOC_DAPM_SINGLE("DAC L1 Switch", RT5640_OUT_L3_MIXER, | ||
947 | RT5640_M_DAC_L1_OM_L_SFT, 1, 1), | ||
948 | }; | ||
949 | |||
950 | static const struct snd_kcontrol_new rt5640_out_r_mix[] = { | ||
951 | SOC_DAPM_SINGLE("SPK MIXR Switch", RT5640_OUT_R3_MIXER, | ||
952 | RT5640_M_SM_L_OM_R_SFT, 1, 1), | ||
953 | SOC_DAPM_SINGLE("BST2 Switch", RT5640_OUT_R3_MIXER, | ||
954 | RT5640_M_BST4_OM_R_SFT, 1, 1), | ||
955 | SOC_DAPM_SINGLE("BST1 Switch", RT5640_OUT_R3_MIXER, | ||
956 | RT5640_M_BST1_OM_R_SFT, 1, 1), | ||
957 | SOC_DAPM_SINGLE("INR Switch", RT5640_OUT_R3_MIXER, | ||
958 | RT5640_M_IN_R_OM_R_SFT, 1, 1), | ||
959 | SOC_DAPM_SINGLE("REC MIXR Switch", RT5640_OUT_R3_MIXER, | ||
960 | RT5640_M_RM_R_OM_R_SFT, 1, 1), | ||
961 | SOC_DAPM_SINGLE("DAC L2 Switch", RT5640_OUT_R3_MIXER, | ||
962 | RT5640_M_DAC_L2_OM_R_SFT, 1, 1), | ||
963 | SOC_DAPM_SINGLE("DAC R2 Switch", RT5640_OUT_R3_MIXER, | ||
964 | RT5640_M_DAC_R2_OM_R_SFT, 1, 1), | ||
965 | SOC_DAPM_SINGLE("DAC R1 Switch", RT5640_OUT_R3_MIXER, | ||
966 | RT5640_M_DAC_R1_OM_R_SFT, 1, 1), | ||
967 | }; | ||
968 | |||
969 | static const struct snd_kcontrol_new rt5640_spo_l_mix[] = { | ||
970 | SOC_DAPM_SINGLE("DAC R1 Switch", RT5640_SPO_L_MIXER, | ||
971 | RT5640_M_DAC_R1_SPM_L_SFT, 1, 1), | ||
972 | SOC_DAPM_SINGLE("DAC L1 Switch", RT5640_SPO_L_MIXER, | ||
973 | RT5640_M_DAC_L1_SPM_L_SFT, 1, 1), | ||
974 | SOC_DAPM_SINGLE("SPKVOL R Switch", RT5640_SPO_L_MIXER, | ||
975 | RT5640_M_SV_R_SPM_L_SFT, 1, 1), | ||
976 | SOC_DAPM_SINGLE("SPKVOL L Switch", RT5640_SPO_L_MIXER, | ||
977 | RT5640_M_SV_L_SPM_L_SFT, 1, 1), | ||
978 | SOC_DAPM_SINGLE("BST1 Switch", RT5640_SPO_L_MIXER, | ||
979 | RT5640_M_BST1_SPM_L_SFT, 1, 1), | ||
980 | }; | ||
981 | |||
982 | static const struct snd_kcontrol_new rt5640_spo_r_mix[] = { | ||
983 | SOC_DAPM_SINGLE("DAC R1 Switch", RT5640_SPO_R_MIXER, | ||
984 | RT5640_M_DAC_R1_SPM_R_SFT, 1, 1), | ||
985 | SOC_DAPM_SINGLE("SPKVOL R Switch", RT5640_SPO_R_MIXER, | ||
986 | RT5640_M_SV_R_SPM_R_SFT, 1, 1), | ||
987 | SOC_DAPM_SINGLE("BST1 Switch", RT5640_SPO_R_MIXER, | ||
988 | RT5640_M_BST1_SPM_R_SFT, 1, 1), | ||
989 | }; | ||
990 | |||
991 | static const struct snd_kcontrol_new rt5640_hpo_mix[] = { | ||
992 | SOC_DAPM_SINGLE("DAC2 Switch", RT5640_HPO_MIXER, | ||
993 | RT5640_M_DAC2_HM_SFT, 1, 1), | ||
994 | SOC_DAPM_SINGLE("DAC1 Switch", RT5640_HPO_MIXER, | ||
995 | RT5640_M_DAC1_HM_SFT, 1, 1), | ||
996 | SOC_DAPM_SINGLE("HPVOL Switch", RT5640_HPO_MIXER, | ||
997 | RT5640_M_HPVOL_HM_SFT, 1, 1), | ||
998 | }; | ||
999 | |||
1000 | static const struct snd_kcontrol_new rt5640_lout_mix[] = { | ||
1001 | SOC_DAPM_SINGLE("DAC L1 Switch", RT5640_LOUT_MIXER, | ||
1002 | RT5640_M_DAC_L1_LM_SFT, 1, 1), | ||
1003 | SOC_DAPM_SINGLE("DAC R1 Switch", RT5640_LOUT_MIXER, | ||
1004 | RT5640_M_DAC_R1_LM_SFT, 1, 1), | ||
1005 | SOC_DAPM_SINGLE("OUTVOL L Switch", RT5640_LOUT_MIXER, | ||
1006 | RT5640_M_OV_L_LM_SFT, 1, 1), | ||
1007 | SOC_DAPM_SINGLE("OUTVOL R Switch", RT5640_LOUT_MIXER, | ||
1008 | RT5640_M_OV_R_LM_SFT, 1, 1), | ||
1009 | }; | ||
1010 | |||
1011 | static const struct snd_kcontrol_new rt5640_mono_mix[] = { | ||
1012 | SOC_DAPM_SINGLE("DAC R2 Switch", RT5640_MONO_MIXER, | ||
1013 | RT5640_M_DAC_R2_MM_SFT, 1, 1), | ||
1014 | SOC_DAPM_SINGLE("DAC L2 Switch", RT5640_MONO_MIXER, | ||
1015 | RT5640_M_DAC_L2_MM_SFT, 1, 1), | ||
1016 | SOC_DAPM_SINGLE("OUTVOL R Switch", RT5640_MONO_MIXER, | ||
1017 | RT5640_M_OV_R_MM_SFT, 1, 1), | ||
1018 | SOC_DAPM_SINGLE("OUTVOL L Switch", RT5640_MONO_MIXER, | ||
1019 | RT5640_M_OV_L_MM_SFT, 1, 1), | ||
1020 | SOC_DAPM_SINGLE("BST1 Switch", RT5640_MONO_MIXER, | ||
1021 | RT5640_M_BST1_MM_SFT, 1, 1), | ||
1022 | }; | ||
1023 | |||
1024 | /* INL/R source */ | ||
1025 | static const char *rt5640_inl_src[] = {"IN2P", "MonoP"}; | ||
1026 | |||
1027 | static const SOC_ENUM_SINGLE_DECL( | ||
1028 | rt5640_inl_enum, RT5640_INL_INR_VOL, | ||
1029 | RT5640_INL_SEL_SFT, rt5640_inl_src); | ||
1030 | |||
1031 | static const struct snd_kcontrol_new rt5640_inl_mux = | ||
1032 | SOC_DAPM_ENUM("INL source", rt5640_inl_enum); | ||
1033 | |||
1034 | static const char *rt5640_inr_src[] = {"IN2N", "MonoN"}; | ||
1035 | |||
1036 | static const SOC_ENUM_SINGLE_DECL( | ||
1037 | rt5640_inr_enum, RT5640_INL_INR_VOL, | ||
1038 | RT5640_INR_SEL_SFT, rt5640_inr_src); | ||
1039 | |||
1040 | static const struct snd_kcontrol_new rt5640_inr_mux = | ||
1041 | SOC_DAPM_ENUM("INR source", rt5640_inr_enum); | ||
1042 | |||
1043 | /* Stereo ADC source */ | ||
1044 | static const char *rt5640_stereo_adc1_src[] = {"DIG MIX", "ADC"}; | ||
1045 | |||
1046 | static const SOC_ENUM_SINGLE_DECL( | ||
1047 | rt5640_stereo_adc1_enum, RT5640_STO_ADC_MIXER, | ||
1048 | RT5640_ADC_1_SRC_SFT, rt5640_stereo_adc1_src); | ||
1049 | |||
1050 | static const struct snd_kcontrol_new rt5640_sto_adc_l1_mux = | ||
1051 | SOC_DAPM_ENUM("Stereo ADC L1 source", rt5640_stereo_adc1_enum); | ||
1052 | |||
1053 | static const struct snd_kcontrol_new rt5640_sto_adc_r1_mux = | ||
1054 | SOC_DAPM_ENUM("Stereo ADC R1 source", rt5640_stereo_adc1_enum); | ||
1055 | |||
1056 | static const char *rt5640_stereo_adc2_src[] = {"DMIC1", "DMIC2", "DIG MIX"}; | ||
1057 | |||
1058 | static const SOC_ENUM_SINGLE_DECL( | ||
1059 | rt5640_stereo_adc2_enum, RT5640_STO_ADC_MIXER, | ||
1060 | RT5640_ADC_2_SRC_SFT, rt5640_stereo_adc2_src); | ||
1061 | |||
1062 | static const struct snd_kcontrol_new rt5640_sto_adc_l2_mux = | ||
1063 | SOC_DAPM_ENUM("Stereo ADC L2 source", rt5640_stereo_adc2_enum); | ||
1064 | |||
1065 | static const struct snd_kcontrol_new rt5640_sto_adc_r2_mux = | ||
1066 | SOC_DAPM_ENUM("Stereo ADC R2 source", rt5640_stereo_adc2_enum); | ||
1067 | |||
1068 | /* Mono ADC source */ | ||
1069 | static const char *rt5640_mono_adc_l1_src[] = {"Mono DAC MIXL", "ADCL"}; | ||
1070 | |||
1071 | static const SOC_ENUM_SINGLE_DECL( | ||
1072 | rt5640_mono_adc_l1_enum, RT5640_MONO_ADC_MIXER, | ||
1073 | RT5640_MONO_ADC_L1_SRC_SFT, rt5640_mono_adc_l1_src); | ||
1074 | |||
1075 | static const struct snd_kcontrol_new rt5640_mono_adc_l1_mux = | ||
1076 | SOC_DAPM_ENUM("Mono ADC1 left source", rt5640_mono_adc_l1_enum); | ||
1077 | |||
1078 | static const char *rt5640_mono_adc_l2_src[] = { | ||
1079 | "DMIC L1", "DMIC L2", "Mono DAC MIXL" | ||
1080 | }; | ||
1081 | |||
1082 | static const SOC_ENUM_SINGLE_DECL( | ||
1083 | rt5640_mono_adc_l2_enum, RT5640_MONO_ADC_MIXER, | ||
1084 | RT5640_MONO_ADC_L2_SRC_SFT, rt5640_mono_adc_l2_src); | ||
1085 | |||
1086 | static const struct snd_kcontrol_new rt5640_mono_adc_l2_mux = | ||
1087 | SOC_DAPM_ENUM("Mono ADC2 left source", rt5640_mono_adc_l2_enum); | ||
1088 | |||
1089 | static const char *rt5640_mono_adc_r1_src[] = {"Mono DAC MIXR", "ADCR"}; | ||
1090 | |||
1091 | static const SOC_ENUM_SINGLE_DECL( | ||
1092 | rt5640_mono_adc_r1_enum, RT5640_MONO_ADC_MIXER, | ||
1093 | RT5640_MONO_ADC_R1_SRC_SFT, rt5640_mono_adc_r1_src); | ||
1094 | |||
1095 | static const struct snd_kcontrol_new rt5640_mono_adc_r1_mux = | ||
1096 | SOC_DAPM_ENUM("Mono ADC1 right source", rt5640_mono_adc_r1_enum); | ||
1097 | |||
1098 | static const char *rt5640_mono_adc_r2_src[] = { | ||
1099 | "DMIC R1", "DMIC R2", "Mono DAC MIXR" | ||
1100 | }; | ||
1101 | |||
1102 | static const SOC_ENUM_SINGLE_DECL( | ||
1103 | rt5640_mono_adc_r2_enum, RT5640_MONO_ADC_MIXER, | ||
1104 | RT5640_MONO_ADC_R2_SRC_SFT, rt5640_mono_adc_r2_src); | ||
1105 | |||
1106 | static const struct snd_kcontrol_new rt5640_mono_adc_r2_mux = | ||
1107 | SOC_DAPM_ENUM("Mono ADC2 right source", rt5640_mono_adc_r2_enum); | ||
1108 | |||
1109 | /* DAC2 channel source */ | ||
1110 | static const char *rt5640_dac_l2_src[] = {"IF2", "IF3", "TxDC", "Base L/R"}; | ||
1111 | |||
1112 | static const SOC_ENUM_SINGLE_DECL(rt5640_dac_l2_enum, RT5640_DSP_PATH2, | ||
1113 | RT5640_DAC_L2_SEL_SFT, rt5640_dac_l2_src); | ||
1114 | |||
1115 | static const struct snd_kcontrol_new rt5640_dac_l2_mux = | ||
1116 | SOC_DAPM_ENUM("DAC2 left channel source", rt5640_dac_l2_enum); | ||
1117 | |||
1118 | static const char *rt5640_dac_r2_src[] = {"IF2", "IF3", "TxDC"}; | ||
1119 | |||
1120 | static const SOC_ENUM_SINGLE_DECL( | ||
1121 | rt5640_dac_r2_enum, RT5640_DSP_PATH2, | ||
1122 | RT5640_DAC_R2_SEL_SFT, rt5640_dac_r2_src); | ||
1123 | |||
1124 | static const struct snd_kcontrol_new rt5640_dac_r2_mux = | ||
1125 | SOC_DAPM_ENUM("DAC2 right channel source", rt5640_dac_r2_enum); | ||
1126 | |||
1127 | /* Interface 2 ADC channel source */ | ||
1128 | static const char *rt5640_if2_adc_l_src[] = {"TxDP", "Mono ADC MIXL"}; | ||
1129 | |||
1130 | static const SOC_ENUM_SINGLE_DECL(rt5640_if2_adc_l_enum, RT5640_DSP_PATH2, | ||
1131 | RT5640_IF2_ADC_L_SEL_SFT, rt5640_if2_adc_l_src); | ||
1132 | |||
1133 | static const struct snd_kcontrol_new rt5640_if2_adc_l_mux = | ||
1134 | SOC_DAPM_ENUM("IF2 ADC left channel source", rt5640_if2_adc_l_enum); | ||
1135 | |||
1136 | static const char *rt5640_if2_adc_r_src[] = {"TxDP", "Mono ADC MIXR"}; | ||
1137 | |||
1138 | static const SOC_ENUM_SINGLE_DECL(rt5640_if2_adc_r_enum, RT5640_DSP_PATH2, | ||
1139 | RT5640_IF2_ADC_R_SEL_SFT, rt5640_if2_adc_r_src); | ||
1140 | |||
1141 | static const struct snd_kcontrol_new rt5640_if2_adc_r_mux = | ||
1142 | SOC_DAPM_ENUM("IF2 ADC right channel source", rt5640_if2_adc_r_enum); | ||
1143 | |||
1144 | /* digital interface and iis interface map */ | ||
1145 | static const char *rt5640_dai_iis_map[] = {"1:1|2:2|3:3", "1:1|2:3|3:2", | ||
1146 | "1:3|2:1|3:2", "1:3|2:2|3:1", "1:2|2:3|3:1", | ||
1147 | "1:2|2:1|3:3", "1:1|2:1|3:3", "1:2|2:2|3:3"}; | ||
1148 | |||
1149 | static const SOC_ENUM_SINGLE_DECL( | ||
1150 | rt5640_dai_iis_map_enum, RT5640_I2S1_SDP, | ||
1151 | RT5640_I2S_IF_SFT, rt5640_dai_iis_map); | ||
1152 | |||
1153 | static const struct snd_kcontrol_new rt5640_dai_mux = | ||
1154 | SOC_DAPM_ENUM("DAI select", rt5640_dai_iis_map_enum); | ||
1155 | |||
1156 | /* SDI select */ | ||
1157 | static const char *rt5640_sdi_sel[] = {"IF1", "IF2"}; | ||
1158 | |||
1159 | static const SOC_ENUM_SINGLE_DECL( | ||
1160 | rt5640_sdi_sel_enum, RT5640_I2S2_SDP, | ||
1161 | RT5640_I2S2_SDI_SFT, rt5640_sdi_sel); | ||
1162 | |||
1163 | static const struct snd_kcontrol_new rt5640_sdi_mux = | ||
1164 | SOC_DAPM_ENUM("SDI select", rt5640_sdi_sel_enum); | ||
1165 | |||
1166 | static int spk_event(struct snd_soc_dapm_widget *w, | ||
1167 | struct snd_kcontrol *kcontrol, int event) | ||
1168 | { | ||
1169 | struct snd_soc_codec *codec = w->codec; | ||
1170 | static unsigned int spkl_out_enable; | ||
1171 | static unsigned int spkr_out_enable; | ||
1172 | |||
1173 | switch (event) { | ||
1174 | case SND_SOC_DAPM_POST_PMU: | ||
1175 | pr_info("spk_event --SND_SOC_DAPM_POST_PMU\n"); | ||
1176 | snd_soc_update_bits(codec, RT5640_PWR_DIG1, 0x0001, 0x0001); | ||
1177 | rt5640_index_update_bits(codec, 0x1c, 0xf000, 0xf000); | ||
1178 | /* rt5640_index_write(codec, 0x1c, 0xfd21); */ | ||
1179 | break; | ||
1180 | |||
1181 | case SND_SOC_DAPM_PRE_PMD: | ||
1182 | pr_info("spk_event --SND_SOC_DAPM_POST_PMD\n"); | ||
1183 | /* rt5640_index_write(codec, 0x1c, 0xfd00); */ | ||
1184 | rt5640_index_update_bits(codec, 0x1c, 0xf000, 0x0000); | ||
1185 | snd_soc_update_bits(codec, RT5640_PWR_DIG1, 0x0001, 0x0000); | ||
1186 | break; | ||
1187 | |||
1188 | default: | ||
1189 | return 0; | ||
1190 | } | ||
1191 | return 0; | ||
1192 | } | ||
1193 | |||
1194 | static int hp_event(struct snd_soc_dapm_widget *w, | ||
1195 | struct snd_kcontrol *kcontrol, int event) | ||
1196 | { | ||
1197 | struct snd_soc_codec *codec = w->codec; | ||
1198 | static unsigned int hp_out_enable; | ||
1199 | |||
1200 | switch (event) { | ||
1201 | case SND_SOC_DAPM_POST_PMU: | ||
1202 | pr_info("hp_event --SND_SOC_DAPM_POST_PMU\n"); | ||
1203 | break; | ||
1204 | |||
1205 | case SND_SOC_DAPM_PRE_PMD: | ||
1206 | pr_info("hp_event --SND_SOC_DAPM_POST_PMD\n"); | ||
1207 | break; | ||
1208 | |||
1209 | default: | ||
1210 | return 0; | ||
1211 | } | ||
1212 | return 0; | ||
1213 | } | ||
1214 | |||
1215 | static const struct snd_soc_dapm_widget rt5640_dapm_widgets[] = { | ||
1216 | SND_SOC_DAPM_SUPPLY("PLL1", RT5640_PWR_ANLG2, | ||
1217 | RT5640_PWR_PLL_BIT, 0, NULL, 0), | ||
1218 | /* Input Side */ | ||
1219 | /* micbias */ | ||
1220 | SND_SOC_DAPM_SUPPLY("LDO2", RT5640_PWR_ANLG1, | ||
1221 | RT5640_PWR_LDO2_BIT, 0, NULL, 0), | ||
1222 | SND_SOC_DAPM_MICBIAS("micbias1", RT5640_PWR_ANLG2, | ||
1223 | RT5640_PWR_MB1_BIT, 0), | ||
1224 | SND_SOC_DAPM_MICBIAS("micbias2", RT5640_PWR_ANLG2, | ||
1225 | RT5640_PWR_MB2_BIT, 0), | ||
1226 | /* Input Lines */ | ||
1227 | |||
1228 | SND_SOC_DAPM_INPUT("MIC1"), | ||
1229 | SND_SOC_DAPM_INPUT("MIC2"), | ||
1230 | SND_SOC_DAPM_INPUT("DMIC1"), | ||
1231 | SND_SOC_DAPM_INPUT("DMIC2"), | ||
1232 | SND_SOC_DAPM_INPUT("IN1P"), | ||
1233 | SND_SOC_DAPM_INPUT("IN1N"), | ||
1234 | SND_SOC_DAPM_INPUT("IN2P"), | ||
1235 | SND_SOC_DAPM_INPUT("IN2N"), | ||
1236 | SND_SOC_DAPM_INPUT("DMIC L1"), | ||
1237 | SND_SOC_DAPM_INPUT("DMIC R1"), | ||
1238 | SND_SOC_DAPM_INPUT("DMIC L2"), | ||
1239 | SND_SOC_DAPM_INPUT("DMIC R2"), | ||
1240 | SND_SOC_DAPM_SUPPLY("DMIC CLK", SND_SOC_NOPM, 0, 0, | ||
1241 | set_dmic_clk, SND_SOC_DAPM_PRE_PMU), | ||
1242 | /* Boost */ | ||
1243 | SND_SOC_DAPM_PGA("BST1", RT5640_PWR_ANLG2, | ||
1244 | RT5640_PWR_BST1_BIT, 0, NULL, 0), | ||
1245 | SND_SOC_DAPM_PGA("BST2", RT5640_PWR_ANLG2, | ||
1246 | RT5640_PWR_BST4_BIT, 0, NULL, 0), | ||
1247 | /* Input Volume */ | ||
1248 | SND_SOC_DAPM_PGA("INL VOL", RT5640_PWR_VOL, | ||
1249 | RT5640_PWR_IN_L_BIT, 0, NULL, 0), | ||
1250 | SND_SOC_DAPM_PGA("INR VOL", RT5640_PWR_VOL, | ||
1251 | RT5640_PWR_IN_R_BIT, 0, NULL, 0), | ||
1252 | /* IN Mux */ | ||
1253 | SND_SOC_DAPM_MUX("INL Mux", SND_SOC_NOPM, 0, 0, &rt5640_inl_mux), | ||
1254 | SND_SOC_DAPM_MUX("INR Mux", SND_SOC_NOPM, 0, 0, &rt5640_inr_mux), | ||
1255 | /* REC Mixer */ | ||
1256 | SND_SOC_DAPM_MIXER("RECMIXL", RT5640_PWR_MIXER, RT5640_PWR_RM_L_BIT, 0, | ||
1257 | rt5640_rec_l_mix, ARRAY_SIZE(rt5640_rec_l_mix)), | ||
1258 | SND_SOC_DAPM_MIXER("RECMIXR", RT5640_PWR_MIXER, RT5640_PWR_RM_R_BIT, 0, | ||
1259 | rt5640_rec_r_mix, ARRAY_SIZE(rt5640_rec_r_mix)), | ||
1260 | /* ADCs */ | ||
1261 | SND_SOC_DAPM_ADC("ADC L", NULL, RT5640_PWR_DIG1, | ||
1262 | RT5640_PWR_ADC_L_BIT, 0), | ||
1263 | SND_SOC_DAPM_ADC("ADC R", NULL, RT5640_PWR_DIG1, | ||
1264 | RT5640_PWR_ADC_R_BIT, 0), | ||
1265 | /* ADC Mux */ | ||
1266 | SND_SOC_DAPM_MUX("Stereo ADC L2 Mux", SND_SOC_NOPM, 0, 0, | ||
1267 | &rt5640_sto_adc_l2_mux), | ||
1268 | SND_SOC_DAPM_MUX("Stereo ADC R2 Mux", SND_SOC_NOPM, 0, 0, | ||
1269 | &rt5640_sto_adc_r2_mux), | ||
1270 | SND_SOC_DAPM_MUX("Stereo ADC L1 Mux", SND_SOC_NOPM, 0, 0, | ||
1271 | &rt5640_sto_adc_l1_mux), | ||
1272 | SND_SOC_DAPM_MUX("Stereo ADC R1 Mux", SND_SOC_NOPM, 0, 0, | ||
1273 | &rt5640_sto_adc_r1_mux), | ||
1274 | SND_SOC_DAPM_MUX("Mono ADC L2 Mux", SND_SOC_NOPM, 0, 0, | ||
1275 | &rt5640_mono_adc_l2_mux), | ||
1276 | SND_SOC_DAPM_MUX("Mono ADC L1 Mux", SND_SOC_NOPM, 0, 0, | ||
1277 | &rt5640_mono_adc_l1_mux), | ||
1278 | SND_SOC_DAPM_MUX("Mono ADC R1 Mux", SND_SOC_NOPM, 0, 0, | ||
1279 | &rt5640_mono_adc_r1_mux), | ||
1280 | SND_SOC_DAPM_MUX("Mono ADC R2 Mux", SND_SOC_NOPM, 0, 0, | ||
1281 | &rt5640_mono_adc_r2_mux), | ||
1282 | /* ADC Mixer */ | ||
1283 | SND_SOC_DAPM_SUPPLY("stereo filter", RT5640_PWR_DIG2, | ||
1284 | RT5640_PWR_ADC_SF_BIT, 0, NULL, 0), | ||
1285 | SND_SOC_DAPM_MIXER("Stereo ADC MIXL", SND_SOC_NOPM, 0, 0, | ||
1286 | rt5640_sto_adc_l_mix, ARRAY_SIZE(rt5640_sto_adc_l_mix)), | ||
1287 | SND_SOC_DAPM_MIXER("Stereo ADC MIXR", SND_SOC_NOPM, 0, 0, | ||
1288 | rt5640_sto_adc_r_mix, ARRAY_SIZE(rt5640_sto_adc_r_mix)), | ||
1289 | SND_SOC_DAPM_SUPPLY("mono left filter", RT5640_PWR_DIG2, | ||
1290 | RT5640_PWR_ADC_MF_L_BIT, 0, NULL, 0), | ||
1291 | SND_SOC_DAPM_MIXER("Mono ADC MIXL", SND_SOC_NOPM, 0, 0, | ||
1292 | rt5640_mono_adc_l_mix, ARRAY_SIZE(rt5640_mono_adc_l_mix)), | ||
1293 | SND_SOC_DAPM_SUPPLY("mono right filter", RT5640_PWR_DIG2, | ||
1294 | RT5640_PWR_ADC_MF_R_BIT, 0, NULL, 0), | ||
1295 | SND_SOC_DAPM_MIXER("Mono ADC MIXR", SND_SOC_NOPM, 0, 0, | ||
1296 | rt5640_mono_adc_r_mix, ARRAY_SIZE(rt5640_mono_adc_r_mix)), | ||
1297 | |||
1298 | /* IF2 Mux */ | ||
1299 | SND_SOC_DAPM_MUX("IF2 ADC L Mux", SND_SOC_NOPM, 0, 0, | ||
1300 | &rt5640_if2_adc_l_mux), | ||
1301 | SND_SOC_DAPM_MUX("IF2 ADC R Mux", SND_SOC_NOPM, 0, 0, | ||
1302 | &rt5640_if2_adc_r_mux), | ||
1303 | |||
1304 | /* Digital Interface */ | ||
1305 | SND_SOC_DAPM_SUPPLY("I2S1", RT5640_PWR_DIG1, | ||
1306 | RT5640_PWR_I2S1_BIT, 0, NULL, 0), | ||
1307 | SND_SOC_DAPM_PGA("IF1 DAC", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
1308 | SND_SOC_DAPM_PGA("IF1 DAC L", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
1309 | SND_SOC_DAPM_PGA("IF1 DAC R", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
1310 | SND_SOC_DAPM_PGA("IF1 ADC", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
1311 | SND_SOC_DAPM_PGA("IF1 ADC L", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
1312 | SND_SOC_DAPM_PGA("IF1 ADC R", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
1313 | SND_SOC_DAPM_SUPPLY("I2S2", RT5640_PWR_DIG1, | ||
1314 | RT5640_PWR_I2S2_BIT, 0, NULL, 0), | ||
1315 | SND_SOC_DAPM_PGA("IF2 DAC", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
1316 | SND_SOC_DAPM_PGA("IF2 DAC L", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
1317 | SND_SOC_DAPM_PGA("IF2 DAC R", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
1318 | SND_SOC_DAPM_PGA("IF2 ADC", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
1319 | SND_SOC_DAPM_PGA("IF2 ADC L", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
1320 | SND_SOC_DAPM_PGA("IF2 ADC R", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
1321 | SND_SOC_DAPM_SUPPLY("I2S3", RT5640_PWR_DIG1, | ||
1322 | RT5640_PWR_I2S3_BIT, 0, NULL, 0), | ||
1323 | SND_SOC_DAPM_PGA("IF3 DAC", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
1324 | SND_SOC_DAPM_PGA("IF3 DAC L", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
1325 | SND_SOC_DAPM_PGA("IF3 DAC R", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
1326 | SND_SOC_DAPM_PGA("IF3 ADC", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
1327 | SND_SOC_DAPM_PGA("IF3 ADC L", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
1328 | SND_SOC_DAPM_PGA("IF3 ADC R", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
1329 | |||
1330 | /* Digital Interface Select */ | ||
1331 | SND_SOC_DAPM_MUX("DAI1 RX Mux", SND_SOC_NOPM, 0, 0, &rt5640_dai_mux), | ||
1332 | SND_SOC_DAPM_MUX("DAI1 TX Mux", SND_SOC_NOPM, 0, 0, &rt5640_dai_mux), | ||
1333 | SND_SOC_DAPM_MUX("DAI1 IF1 Mux", SND_SOC_NOPM, 0, 0, &rt5640_dai_mux), | ||
1334 | SND_SOC_DAPM_MUX("DAI1 IF2 Mux", SND_SOC_NOPM, 0, 0, &rt5640_dai_mux), | ||
1335 | SND_SOC_DAPM_MUX("SDI1 TX Mux", SND_SOC_NOPM, 0, 0, &rt5640_sdi_mux), | ||
1336 | |||
1337 | SND_SOC_DAPM_MUX("DAI2 RX Mux", SND_SOC_NOPM, 0, 0, &rt5640_dai_mux), | ||
1338 | SND_SOC_DAPM_MUX("DAI2 TX Mux", SND_SOC_NOPM, 0, 0, &rt5640_dai_mux), | ||
1339 | SND_SOC_DAPM_MUX("DAI2 IF1 Mux", SND_SOC_NOPM, 0, 0, &rt5640_dai_mux), | ||
1340 | SND_SOC_DAPM_MUX("DAI2 IF2 Mux", SND_SOC_NOPM, 0, 0, &rt5640_dai_mux), | ||
1341 | SND_SOC_DAPM_MUX("SDI2 TX Mux", SND_SOC_NOPM, 0, 0, &rt5640_sdi_mux), | ||
1342 | |||
1343 | SND_SOC_DAPM_MUX("DAI3 RX Mux", SND_SOC_NOPM, 0, 0, &rt5640_dai_mux), | ||
1344 | SND_SOC_DAPM_MUX("DAI3 TX Mux", SND_SOC_NOPM, 0, 0, &rt5640_dai_mux), | ||
1345 | |||
1346 | /* Audio Interface */ | ||
1347 | SND_SOC_DAPM_AIF_IN("AIF1RX", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0), | ||
1348 | SND_SOC_DAPM_AIF_OUT("AIF1TX", "AIF1 Capture", 0, SND_SOC_NOPM, 0, 0), | ||
1349 | SND_SOC_DAPM_AIF_IN("AIF2RX", "AIF2 Playback", 0, SND_SOC_NOPM, 0, 0), | ||
1350 | SND_SOC_DAPM_AIF_OUT("AIF2TX", "AIF2 Capture", 0, SND_SOC_NOPM, 0, 0), | ||
1351 | SND_SOC_DAPM_AIF_IN("AIF3RX", "AIF3 Playback", 0, SND_SOC_NOPM, 0, 0), | ||
1352 | SND_SOC_DAPM_AIF_OUT("AIF3TX", "AIF3 Capture", 0, SND_SOC_NOPM, 0, 0), | ||
1353 | |||
1354 | /* Audio DSP */ | ||
1355 | SND_SOC_DAPM_PGA("Audio DSP", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
1356 | |||
1357 | /* ANC */ | ||
1358 | SND_SOC_DAPM_PGA("ANC", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
1359 | |||
1360 | /* Output Side */ | ||
1361 | /* DAC mixer before sound effect */ | ||
1362 | SND_SOC_DAPM_MIXER("DAC MIXL", SND_SOC_NOPM, 0, 0, | ||
1363 | rt5640_dac_l_mix, ARRAY_SIZE(rt5640_dac_l_mix)), | ||
1364 | SND_SOC_DAPM_MIXER("DAC MIXR", SND_SOC_NOPM, 0, 0, | ||
1365 | rt5640_dac_r_mix, ARRAY_SIZE(rt5640_dac_r_mix)), | ||
1366 | |||
1367 | /* DAC2 channel Mux */ | ||
1368 | SND_SOC_DAPM_MUX("DAC L2 Mux", SND_SOC_NOPM, 0, 0, | ||
1369 | &rt5640_dac_l2_mux), | ||
1370 | SND_SOC_DAPM_MUX("DAC R2 Mux", SND_SOC_NOPM, 0, 0, | ||
1371 | &rt5640_dac_r2_mux), | ||
1372 | |||
1373 | /* DAC Mixer */ | ||
1374 | SND_SOC_DAPM_MIXER("Stereo DAC MIXL", SND_SOC_NOPM, 0, 0, | ||
1375 | rt5640_sto_dac_l_mix, ARRAY_SIZE(rt5640_sto_dac_l_mix)), | ||
1376 | SND_SOC_DAPM_MIXER("Stereo DAC MIXR", SND_SOC_NOPM, 0, 0, | ||
1377 | rt5640_sto_dac_r_mix, ARRAY_SIZE(rt5640_sto_dac_r_mix)), | ||
1378 | SND_SOC_DAPM_MIXER("Mono DAC MIXL", SND_SOC_NOPM, 0, 0, | ||
1379 | rt5640_mono_dac_l_mix, ARRAY_SIZE(rt5640_mono_dac_l_mix)), | ||
1380 | SND_SOC_DAPM_MIXER("Mono DAC MIXR", SND_SOC_NOPM, 0, 0, | ||
1381 | rt5640_mono_dac_r_mix, ARRAY_SIZE(rt5640_mono_dac_r_mix)), | ||
1382 | SND_SOC_DAPM_MIXER("DIG MIXL", SND_SOC_NOPM, 0, 0, | ||
1383 | rt5640_dig_l_mix, ARRAY_SIZE(rt5640_dig_l_mix)), | ||
1384 | SND_SOC_DAPM_MIXER("DIG MIXR", SND_SOC_NOPM, 0, 0, | ||
1385 | rt5640_dig_r_mix, ARRAY_SIZE(rt5640_dig_r_mix)), | ||
1386 | /* DACs */ | ||
1387 | SND_SOC_DAPM_DAC("DAC L1", NULL, RT5640_PWR_DIG1, | ||
1388 | RT5640_PWR_DAC_L1_BIT, 0), | ||
1389 | SND_SOC_DAPM_DAC("DAC L2", NULL, RT5640_PWR_DIG1, | ||
1390 | RT5640_PWR_DAC_L2_BIT, 0), | ||
1391 | SND_SOC_DAPM_DAC("DAC R1", NULL, RT5640_PWR_DIG1, | ||
1392 | RT5640_PWR_DAC_R1_BIT, 0), | ||
1393 | SND_SOC_DAPM_DAC("DAC R2", NULL, RT5640_PWR_DIG1, | ||
1394 | RT5640_PWR_DAC_R2_BIT, 0), | ||
1395 | /* SPK/OUT Mixer */ | ||
1396 | SND_SOC_DAPM_MIXER("SPK MIXL", RT5640_PWR_MIXER, RT5640_PWR_SM_L_BIT, | ||
1397 | 0, rt5640_spk_l_mix, ARRAY_SIZE(rt5640_spk_l_mix)), | ||
1398 | SND_SOC_DAPM_MIXER("SPK MIXR", RT5640_PWR_MIXER, RT5640_PWR_SM_R_BIT, | ||
1399 | 0, rt5640_spk_r_mix, ARRAY_SIZE(rt5640_spk_r_mix)), | ||
1400 | SND_SOC_DAPM_MIXER("OUT MIXL", RT5640_PWR_MIXER, RT5640_PWR_OM_L_BIT, | ||
1401 | 0, rt5640_out_l_mix, ARRAY_SIZE(rt5640_out_l_mix)), | ||
1402 | SND_SOC_DAPM_MIXER("OUT MIXR", RT5640_PWR_MIXER, RT5640_PWR_OM_R_BIT, | ||
1403 | 0, rt5640_out_r_mix, ARRAY_SIZE(rt5640_out_r_mix)), | ||
1404 | /* Ouput Volume */ | ||
1405 | SND_SOC_DAPM_PGA("SPKVOL L", RT5640_PWR_VOL, | ||
1406 | RT5640_PWR_SV_L_BIT, 0, NULL, 0), | ||
1407 | SND_SOC_DAPM_PGA("SPKVOL R", RT5640_PWR_VOL, | ||
1408 | RT5640_PWR_SV_R_BIT, 0, NULL, 0), | ||
1409 | SND_SOC_DAPM_PGA("OUTVOL L", RT5640_PWR_VOL, | ||
1410 | RT5640_PWR_OV_L_BIT, 0, NULL, 0), | ||
1411 | SND_SOC_DAPM_PGA("OUTVOL R", RT5640_PWR_VOL, | ||
1412 | RT5640_PWR_OV_R_BIT, 0, NULL, 0), | ||
1413 | SND_SOC_DAPM_PGA("HPOVOL L", RT5640_PWR_VOL, | ||
1414 | RT5640_PWR_HV_L_BIT, 0, NULL, 0), | ||
1415 | SND_SOC_DAPM_PGA("HPOVOL R", RT5640_PWR_VOL, | ||
1416 | RT5640_PWR_HV_R_BIT, 0, NULL, 0), | ||
1417 | /* SPO/HPO/LOUT/Mono Mixer */ | ||
1418 | SND_SOC_DAPM_MIXER("SPOL MIX", SND_SOC_NOPM, 0, | ||
1419 | 0, rt5640_spo_l_mix, ARRAY_SIZE(rt5640_spo_l_mix)), | ||
1420 | SND_SOC_DAPM_MIXER("SPOR MIX", SND_SOC_NOPM, 0, | ||
1421 | 0, rt5640_spo_r_mix, ARRAY_SIZE(rt5640_spo_r_mix)), | ||
1422 | |||
1423 | SND_SOC_DAPM_MIXER("HPOL MIX", SND_SOC_NOPM, 0, 0, | ||
1424 | rt5640_hpo_mix, ARRAY_SIZE(rt5640_hpo_mix)), | ||
1425 | SND_SOC_DAPM_MIXER("HPOR MIX", SND_SOC_NOPM, 0, 0, | ||
1426 | rt5640_hpo_mix, ARRAY_SIZE(rt5640_hpo_mix)), | ||
1427 | SND_SOC_DAPM_MIXER("LOUT MIX", RT5640_PWR_ANLG1, RT5640_PWR_LM_BIT, 0, | ||
1428 | rt5640_lout_mix, ARRAY_SIZE(rt5640_lout_mix)), | ||
1429 | SND_SOC_DAPM_MIXER("Mono MIX", RT5640_PWR_ANLG1, RT5640_PWR_MM_BIT, 0, | ||
1430 | rt5640_mono_mix, ARRAY_SIZE(rt5640_mono_mix)), | ||
1431 | |||
1432 | SND_SOC_DAPM_SUPPLY("Improve mono amp drv", RT5640_PWR_ANLG1, | ||
1433 | RT5640_PWR_MA_BIT, 0, NULL, 0), | ||
1434 | |||
1435 | SND_SOC_DAPM_SUPPLY("Improve HP amp drv", RT5640_PWR_ANLG1, | ||
1436 | SND_SOC_NOPM, 0, hp_event, SND_SOC_DAPM_PRE_PMD | | ||
1437 | SND_SOC_DAPM_POST_PMU), | ||
1438 | |||
1439 | SND_SOC_DAPM_PGA("HP L amp", RT5640_PWR_ANLG1, | ||
1440 | RT5640_PWR_HP_L_BIT, 0, NULL, 0), | ||
1441 | |||
1442 | SND_SOC_DAPM_PGA("HP R amp", RT5640_PWR_ANLG1, | ||
1443 | RT5640_PWR_HP_R_BIT, 0, NULL, 0), | ||
1444 | |||
1445 | SND_SOC_DAPM_SUPPLY("Improve SPK amp drv", RT5640_PWR_DIG1, | ||
1446 | SND_SOC_NOPM, 0, spk_event, | ||
1447 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), | ||
1448 | |||
1449 | /* Output Lines */ | ||
1450 | SND_SOC_DAPM_OUTPUT("SPOLP"), | ||
1451 | SND_SOC_DAPM_OUTPUT("SPOLN"), | ||
1452 | SND_SOC_DAPM_OUTPUT("SPORP"), | ||
1453 | SND_SOC_DAPM_OUTPUT("SPORN"), | ||
1454 | SND_SOC_DAPM_OUTPUT("HPOL"), | ||
1455 | SND_SOC_DAPM_OUTPUT("HPOR"), | ||
1456 | SND_SOC_DAPM_OUTPUT("LOUTL"), | ||
1457 | SND_SOC_DAPM_OUTPUT("LOUTR"), | ||
1458 | SND_SOC_DAPM_OUTPUT("MonoP"), | ||
1459 | SND_SOC_DAPM_OUTPUT("MonoN"), | ||
1460 | }; | ||
1461 | |||
1462 | static const struct snd_soc_dapm_route rt5640_dapm_routes[] = { | ||
1463 | {"IN1P", NULL, "LDO2"}, | ||
1464 | {"IN2P", NULL, "LDO2"}, | ||
1465 | |||
1466 | {"IN1P", NULL, "MIC1"}, | ||
1467 | {"IN1N", NULL, "MIC1"}, | ||
1468 | {"IN2P", NULL, "MIC2"}, | ||
1469 | {"IN2N", NULL, "MIC2"}, | ||
1470 | |||
1471 | {"DMIC L1", NULL, "DMIC1"}, | ||
1472 | {"DMIC R1", NULL, "DMIC1"}, | ||
1473 | {"DMIC L2", NULL, "DMIC2"}, | ||
1474 | {"DMIC R2", NULL, "DMIC2"}, | ||
1475 | |||
1476 | {"BST1", NULL, "IN1P"}, | ||
1477 | {"BST1", NULL, "IN1N"}, | ||
1478 | {"BST2", NULL, "IN2P"}, | ||
1479 | {"BST2", NULL, "IN2N"}, | ||
1480 | |||
1481 | {"INL VOL", NULL, "IN2P"}, | ||
1482 | {"INR VOL", NULL, "IN2N"}, | ||
1483 | |||
1484 | {"RECMIXL", "HPOL Switch", "HPOL"}, | ||
1485 | {"RECMIXL", "INL Switch", "INL VOL"}, | ||
1486 | {"RECMIXL", "BST2 Switch", "BST2"}, | ||
1487 | {"RECMIXL", "BST1 Switch", "BST1"}, | ||
1488 | {"RECMIXL", "OUT MIXL Switch", "OUT MIXL"}, | ||
1489 | |||
1490 | {"RECMIXR", "HPOR Switch", "HPOR"}, | ||
1491 | {"RECMIXR", "INR Switch", "INR VOL"}, | ||
1492 | {"RECMIXR", "BST2 Switch", "BST2"}, | ||
1493 | {"RECMIXR", "BST1 Switch", "BST1"}, | ||
1494 | {"RECMIXR", "OUT MIXR Switch", "OUT MIXR"}, | ||
1495 | |||
1496 | {"ADC L", NULL, "RECMIXL"}, | ||
1497 | {"ADC R", NULL, "RECMIXR"}, | ||
1498 | |||
1499 | {"DMIC L1", NULL, "DMIC CLK"}, | ||
1500 | {"DMIC L2", NULL, "DMIC CLK"}, | ||
1501 | |||
1502 | {"Stereo ADC L2 Mux", "DMIC1", "DMIC L1"}, | ||
1503 | {"Stereo ADC L2 Mux", "DMIC2", "DMIC L2"}, | ||
1504 | {"Stereo ADC L2 Mux", "DIG MIX", "DIG MIXL"}, | ||
1505 | {"Stereo ADC L1 Mux", "ADC", "ADC L"}, | ||
1506 | {"Stereo ADC L1 Mux", "DIG MIX", "DIG MIXL"}, | ||
1507 | |||
1508 | {"Stereo ADC R1 Mux", "ADC", "ADC R"}, | ||
1509 | {"Stereo ADC R1 Mux", "DIG MIX", "DIG MIXR"}, | ||
1510 | {"Stereo ADC R2 Mux", "DMIC1", "DMIC R1"}, | ||
1511 | {"Stereo ADC R2 Mux", "DMIC2", "DMIC R2"}, | ||
1512 | {"Stereo ADC R2 Mux", "DIG MIX", "DIG MIXR"}, | ||
1513 | |||
1514 | {"Mono ADC L2 Mux", "DMIC L1", "DMIC L1"}, | ||
1515 | {"Mono ADC L2 Mux", "DMIC L2", "DMIC L2"}, | ||
1516 | {"Mono ADC L2 Mux", "Mono DAC MIXL", "Mono DAC MIXL"}, | ||
1517 | {"Mono ADC L1 Mux", "Mono DAC MIXL", "Mono DAC MIXL"}, | ||
1518 | {"Mono ADC L1 Mux", "ADCL", "ADC L"}, | ||
1519 | |||
1520 | {"Mono ADC R1 Mux", "Mono DAC MIXR", "Mono DAC MIXR"}, | ||
1521 | {"Mono ADC R1 Mux", "ADCR", "ADC R"}, | ||
1522 | {"Mono ADC R2 Mux", "DMIC R1", "DMIC R1"}, | ||
1523 | {"Mono ADC R2 Mux", "DMIC R2", "DMIC R2"}, | ||
1524 | {"Mono ADC R2 Mux", "Mono DAC MIXR", "Mono DAC MIXR"}, | ||
1525 | |||
1526 | {"Stereo ADC MIXL", "ADC1 Switch", "Stereo ADC L1 Mux"}, | ||
1527 | {"Stereo ADC MIXL", "ADC2 Switch", "Stereo ADC L2 Mux"}, | ||
1528 | {"Stereo ADC MIXL", NULL, "stereo filter"}, | ||
1529 | {"stereo filter", NULL, "PLL1", check_sysclk1_source}, | ||
1530 | |||
1531 | {"Stereo ADC MIXR", "ADC1 Switch", "Stereo ADC R1 Mux"}, | ||
1532 | {"Stereo ADC MIXR", "ADC2 Switch", "Stereo ADC R2 Mux"}, | ||
1533 | {"Stereo ADC MIXR", NULL, "stereo filter"}, | ||
1534 | {"stereo filter", NULL, "PLL1", check_sysclk1_source}, | ||
1535 | |||
1536 | {"Mono ADC MIXL", "ADC1 Switch", "Mono ADC L1 Mux"}, | ||
1537 | {"Mono ADC MIXL", "ADC2 Switch", "Mono ADC L2 Mux"}, | ||
1538 | {"Mono ADC MIXL", NULL, "mono left filter"}, | ||
1539 | {"mono left filter", NULL, "PLL1", check_sysclk1_source}, | ||
1540 | |||
1541 | {"Mono ADC MIXR", "ADC1 Switch", "Mono ADC R1 Mux"}, | ||
1542 | {"Mono ADC MIXR", "ADC2 Switch", "Mono ADC R2 Mux"}, | ||
1543 | {"Mono ADC MIXR", NULL, "mono right filter"}, | ||
1544 | {"mono right filter", NULL, "PLL1", check_sysclk1_source}, | ||
1545 | |||
1546 | {"IF2 ADC L Mux", "Mono ADC MIXL", "Mono ADC MIXL"}, | ||
1547 | {"IF2 ADC R Mux", "Mono ADC MIXR", "Mono ADC MIXR"}, | ||
1548 | |||
1549 | {"IF2 ADC L", NULL, "IF2 ADC L Mux"}, | ||
1550 | {"IF2 ADC R", NULL, "IF2 ADC R Mux"}, | ||
1551 | {"IF3 ADC L", NULL, "Mono ADC MIXL"}, | ||
1552 | {"IF3 ADC R", NULL, "Mono ADC MIXR"}, | ||
1553 | {"IF1 ADC L", NULL, "Stereo ADC MIXL"}, | ||
1554 | {"IF1 ADC R", NULL, "Stereo ADC MIXR"}, | ||
1555 | |||
1556 | {"IF1 ADC", NULL, "I2S1"}, | ||
1557 | {"IF1 ADC", NULL, "IF1 ADC L"}, | ||
1558 | {"IF1 ADC", NULL, "IF1 ADC R"}, | ||
1559 | {"IF2 ADC", NULL, "I2S2"}, | ||
1560 | {"IF2 ADC", NULL, "IF2 ADC L"}, | ||
1561 | {"IF2 ADC", NULL, "IF2 ADC R"}, | ||
1562 | {"IF3 ADC", NULL, "I2S3"}, | ||
1563 | {"IF3 ADC", NULL, "IF3 ADC L"}, | ||
1564 | {"IF3 ADC", NULL, "IF3 ADC R"}, | ||
1565 | |||
1566 | {"DAI1 TX Mux", "1:1|2:2|3:3", "IF1 ADC"}, | ||
1567 | {"DAI1 TX Mux", "1:1|2:3|3:2", "IF1 ADC"}, | ||
1568 | {"DAI1 TX Mux", "1:3|2:1|3:2", "IF2 ADC"}, | ||
1569 | {"DAI1 TX Mux", "1:2|2:1|3:3", "IF2 ADC"}, | ||
1570 | {"DAI1 TX Mux", "1:3|2:2|3:1", "IF3 ADC"}, | ||
1571 | {"DAI1 TX Mux", "1:2|2:3|3:1", "IF3 ADC"}, | ||
1572 | {"DAI1 IF1 Mux", "1:1|2:1|3:3", "IF1 ADC"}, | ||
1573 | {"DAI1 IF2 Mux", "1:1|2:1|3:3", "IF2 ADC"}, | ||
1574 | {"SDI1 TX Mux", "IF1", "DAI1 IF1 Mux"}, | ||
1575 | {"SDI1 TX Mux", "IF2", "DAI1 IF2 Mux"}, | ||
1576 | |||
1577 | {"DAI2 TX Mux", "1:2|2:3|3:1", "IF1 ADC"}, | ||
1578 | {"DAI2 TX Mux", "1:2|2:1|3:3", "IF1 ADC"}, | ||
1579 | {"DAI2 TX Mux", "1:1|2:2|3:3", "IF2 ADC"}, | ||
1580 | {"DAI2 TX Mux", "1:3|2:2|3:1", "IF2 ADC"}, | ||
1581 | {"DAI2 TX Mux", "1:1|2:3|3:2", "IF3 ADC"}, | ||
1582 | {"DAI2 TX Mux", "1:3|2:1|3:2", "IF3 ADC"}, | ||
1583 | {"DAI2 IF1 Mux", "1:2|2:2|3:3", "IF1 ADC"}, | ||
1584 | {"DAI2 IF2 Mux", "1:2|2:2|3:3", "IF2 ADC"}, | ||
1585 | {"SDI2 TX Mux", "IF1", "DAI2 IF1 Mux"}, | ||
1586 | {"SDI2 TX Mux", "IF2", "DAI2 IF2 Mux"}, | ||
1587 | |||
1588 | {"DAI3 TX Mux", "1:3|2:1|3:2", "IF1 ADC"}, | ||
1589 | {"DAI3 TX Mux", "1:3|2:2|3:1", "IF1 ADC"}, | ||
1590 | {"DAI3 TX Mux", "1:1|2:3|3:2", "IF2 ADC"}, | ||
1591 | {"DAI3 TX Mux", "1:2|2:3|3:1", "IF2 ADC"}, | ||
1592 | {"DAI3 TX Mux", "1:1|2:2|3:3", "IF3 ADC"}, | ||
1593 | {"DAI3 TX Mux", "1:2|2:1|3:3", "IF3 ADC"}, | ||
1594 | {"DAI3 TX Mux", "1:1|2:1|3:3", "IF3 ADC"}, | ||
1595 | {"DAI3 TX Mux", "1:2|2:2|3:3", "IF3 ADC"}, | ||
1596 | |||
1597 | {"AIF1TX", NULL, "DAI1 TX Mux"}, | ||
1598 | {"AIF1TX", NULL, "SDI1 TX Mux"}, | ||
1599 | {"AIF2TX", NULL, "DAI2 TX Mux"}, | ||
1600 | {"AIF2TX", NULL, "SDI2 TX Mux"}, | ||
1601 | {"AIF3TX", NULL, "DAI3 TX Mux"}, | ||
1602 | |||
1603 | {"DAI1 RX Mux", "1:1|2:2|3:3", "AIF1RX"}, | ||
1604 | {"DAI1 RX Mux", "1:1|2:3|3:2", "AIF1RX"}, | ||
1605 | {"DAI1 RX Mux", "1:1|2:1|3:3", "AIF1RX"}, | ||
1606 | {"DAI1 RX Mux", "1:2|2:3|3:1", "AIF2RX"}, | ||
1607 | {"DAI1 RX Mux", "1:2|2:1|3:3", "AIF2RX"}, | ||
1608 | {"DAI1 RX Mux", "1:2|2:2|3:3", "AIF2RX"}, | ||
1609 | {"DAI1 RX Mux", "1:3|2:1|3:2", "AIF3RX"}, | ||
1610 | {"DAI1 RX Mux", "1:3|2:2|3:1", "AIF3RX"}, | ||
1611 | |||
1612 | {"DAI2 RX Mux", "1:3|2:1|3:2", "AIF1RX"}, | ||
1613 | {"DAI2 RX Mux", "1:2|2:1|3:3", "AIF1RX"}, | ||
1614 | {"DAI2 RX Mux", "1:1|2:1|3:3", "AIF1RX"}, | ||
1615 | {"DAI2 RX Mux", "1:1|2:2|3:3", "AIF2RX"}, | ||
1616 | {"DAI2 RX Mux", "1:3|2:2|3:1", "AIF2RX"}, | ||
1617 | {"DAI2 RX Mux", "1:2|2:2|3:3", "AIF2RX"}, | ||
1618 | {"DAI2 RX Mux", "1:1|2:3|3:2", "AIF3RX"}, | ||
1619 | {"DAI2 RX Mux", "1:2|2:3|3:1", "AIF3RX"}, | ||
1620 | |||
1621 | {"DAI3 RX Mux", "1:3|2:2|3:1", "AIF1RX"}, | ||
1622 | {"DAI3 RX Mux", "1:2|2:3|3:1", "AIF1RX"}, | ||
1623 | {"DAI3 RX Mux", "1:1|2:3|3:2", "AIF2RX"}, | ||
1624 | {"DAI3 RX Mux", "1:3|2:1|3:2", "AIF2RX"}, | ||
1625 | {"DAI3 RX Mux", "1:1|2:2|3:3", "AIF3RX"}, | ||
1626 | {"DAI3 RX Mux", "1:2|2:1|3:3", "AIF3RX"}, | ||
1627 | {"DAI3 RX Mux", "1:1|2:1|3:3", "AIF3RX"}, | ||
1628 | {"DAI3 RX Mux", "1:2|2:2|3:3", "AIF3RX"}, | ||
1629 | |||
1630 | {"IF1 DAC", NULL, "I2S1"}, | ||
1631 | {"IF1 DAC", NULL, "DAI1 RX Mux"}, | ||
1632 | {"IF2 DAC", NULL, "I2S2"}, | ||
1633 | {"IF2 DAC", NULL, "DAI2 RX Mux"}, | ||
1634 | {"IF3 DAC", NULL, "I2S3"}, | ||
1635 | {"IF3 DAC", NULL, "DAI3 RX Mux"}, | ||
1636 | |||
1637 | {"IF1 DAC L", NULL, "IF1 DAC"}, | ||
1638 | {"IF1 DAC R", NULL, "IF1 DAC"}, | ||
1639 | {"IF2 DAC L", NULL, "IF2 DAC"}, | ||
1640 | {"IF2 DAC R", NULL, "IF2 DAC"}, | ||
1641 | {"IF3 DAC L", NULL, "IF3 DAC"}, | ||
1642 | {"IF3 DAC R", NULL, "IF3 DAC"}, | ||
1643 | |||
1644 | {"DAC MIXL", "Stereo ADC Switch", "Stereo ADC MIXL"}, | ||
1645 | {"DAC MIXL", "INF1 Switch", "IF1 DAC L"}, | ||
1646 | {"DAC MIXR", "Stereo ADC Switch", "Stereo ADC MIXR"}, | ||
1647 | {"DAC MIXR", "INF1 Switch", "IF1 DAC R"}, | ||
1648 | |||
1649 | {"ANC", NULL, "Stereo ADC MIXL"}, | ||
1650 | {"ANC", NULL, "Stereo ADC MIXR"}, | ||
1651 | |||
1652 | {"Audio DSP", NULL, "DAC MIXL"}, | ||
1653 | {"Audio DSP", NULL, "DAC MIXR"}, | ||
1654 | |||
1655 | {"DAC L2 Mux", "IF2", "IF2 DAC L"}, | ||
1656 | {"DAC L2 Mux", "IF3", "IF3 DAC L"}, | ||
1657 | {"DAC L2 Mux", "Base L/R", "Audio DSP"}, | ||
1658 | |||
1659 | {"DAC R2 Mux", "IF2", "IF2 DAC R"}, | ||
1660 | {"DAC R2 Mux", "IF3", "IF3 DAC R"}, | ||
1661 | |||
1662 | {"Stereo DAC MIXL", "DAC L1 Switch", "DAC MIXL"}, | ||
1663 | {"Stereo DAC MIXL", "DAC L2 Switch", "DAC L2 Mux"}, | ||
1664 | {"Stereo DAC MIXL", "ANC Switch", "ANC"}, | ||
1665 | {"Stereo DAC MIXR", "DAC R1 Switch", "DAC MIXR"}, | ||
1666 | {"Stereo DAC MIXR", "DAC R2 Switch", "DAC R2 Mux"}, | ||
1667 | {"Stereo DAC MIXR", "ANC Switch", "ANC"}, | ||
1668 | |||
1669 | {"Mono DAC MIXL", "DAC L1 Switch", "DAC MIXL"}, | ||
1670 | {"Mono DAC MIXL", "DAC L2 Switch", "DAC L2 Mux"}, | ||
1671 | {"Mono DAC MIXL", "DAC R2 Switch", "DAC R2 Mux"}, | ||
1672 | {"Mono DAC MIXR", "DAC R1 Switch", "DAC MIXR"}, | ||
1673 | {"Mono DAC MIXR", "DAC R2 Switch", "DAC R2 Mux"}, | ||
1674 | {"Mono DAC MIXR", "DAC L2 Switch", "DAC L2 Mux"}, | ||
1675 | |||
1676 | {"DIG MIXL", "DAC L1 Switch", "DAC MIXL"}, | ||
1677 | {"DIG MIXL", "DAC L2 Switch", "DAC L2 Mux"}, | ||
1678 | {"DIG MIXR", "DAC R1 Switch", "DAC MIXR"}, | ||
1679 | {"DIG MIXR", "DAC R2 Switch", "DAC R2 Mux"}, | ||
1680 | |||
1681 | {"DAC L1", NULL, "Stereo DAC MIXL"}, | ||
1682 | {"DAC L1", NULL, "PLL1", check_sysclk1_source}, | ||
1683 | {"DAC R1", NULL, "Stereo DAC MIXR"}, | ||
1684 | {"DAC R1", NULL, "PLL1", check_sysclk1_source}, | ||
1685 | {"DAC L2", NULL, "Mono DAC MIXL"}, | ||
1686 | {"DAC L2", NULL, "PLL1", check_sysclk1_source}, | ||
1687 | {"DAC R2", NULL, "Mono DAC MIXR"}, | ||
1688 | {"DAC R2", NULL, "PLL1", check_sysclk1_source}, | ||
1689 | |||
1690 | {"SPK MIXL", "REC MIXL Switch", "RECMIXL"}, | ||
1691 | {"SPK MIXL", "INL Switch", "INL VOL"}, | ||
1692 | {"SPK MIXL", "DAC L1 Switch", "DAC L1"}, | ||
1693 | {"SPK MIXL", "DAC L2 Switch", "DAC L2"}, | ||
1694 | {"SPK MIXL", "OUT MIXL Switch", "OUT MIXL"}, | ||
1695 | {"SPK MIXR", "REC MIXR Switch", "RECMIXR"}, | ||
1696 | {"SPK MIXR", "INR Switch", "INR VOL"}, | ||
1697 | {"SPK MIXR", "DAC R1 Switch", "DAC R1"}, | ||
1698 | {"SPK MIXR", "DAC R2 Switch", "DAC R2"}, | ||
1699 | {"SPK MIXR", "OUT MIXR Switch", "OUT MIXR"}, | ||
1700 | |||
1701 | {"OUT MIXL", "SPK MIXL Switch", "SPK MIXL"}, | ||
1702 | {"OUT MIXL", "BST1 Switch", "BST1"}, | ||
1703 | {"OUT MIXL", "INL Switch", "INL VOL"}, | ||
1704 | {"OUT MIXL", "REC MIXL Switch", "RECMIXL"}, | ||
1705 | {"OUT MIXL", "DAC R2 Switch", "DAC R2"}, | ||
1706 | {"OUT MIXL", "DAC L2 Switch", "DAC L2"}, | ||
1707 | {"OUT MIXL", "DAC L1 Switch", "DAC L1"}, | ||
1708 | |||
1709 | {"OUT MIXR", "SPK MIXR Switch", "SPK MIXR"}, | ||
1710 | {"OUT MIXR", "BST2 Switch", "BST2"}, | ||
1711 | {"OUT MIXR", "BST1 Switch", "BST1"}, | ||
1712 | {"OUT MIXR", "INR Switch", "INR VOL"}, | ||
1713 | {"OUT MIXR", "REC MIXR Switch", "RECMIXR"}, | ||
1714 | {"OUT MIXR", "DAC L2 Switch", "DAC L2"}, | ||
1715 | {"OUT MIXR", "DAC R2 Switch", "DAC R2"}, | ||
1716 | {"OUT MIXR", "DAC R1 Switch", "DAC R1"}, | ||
1717 | |||
1718 | {"SPKVOL L", NULL, "SPK MIXL"}, | ||
1719 | {"SPKVOL R", NULL, "SPK MIXR"}, | ||
1720 | {"HPOVOL L", NULL, "OUT MIXL"}, | ||
1721 | {"HPOVOL R", NULL, "OUT MIXR"}, | ||
1722 | {"OUTVOL L", NULL, "OUT MIXL"}, | ||
1723 | {"OUTVOL R", NULL, "OUT MIXR"}, | ||
1724 | |||
1725 | {"SPOL MIX", "DAC R1 Switch", "DAC R1"}, | ||
1726 | {"SPOL MIX", "DAC L1 Switch", "DAC L1"}, | ||
1727 | {"SPOL MIX", "SPKVOL R Switch", "SPKVOL R"}, | ||
1728 | {"SPOL MIX", "SPKVOL L Switch", "SPKVOL L"}, | ||
1729 | {"SPOL MIX", "BST1 Switch", "BST1"}, | ||
1730 | {"SPOR MIX", "DAC R1 Switch", "DAC R1"}, | ||
1731 | {"SPOR MIX", "SPKVOL R Switch", "SPKVOL R"}, | ||
1732 | {"SPOR MIX", "BST1 Switch", "BST1"}, | ||
1733 | |||
1734 | {"HPOL MIX", "DAC2 Switch", "DAC L2"}, | ||
1735 | {"HPOL MIX", "DAC1 Switch", "DAC L1"}, | ||
1736 | {"HPOL MIX", "HPVOL Switch", "HPOVOL L"}, | ||
1737 | {"HPOR MIX", "DAC2 Switch", "DAC R2"}, | ||
1738 | {"HPOR MIX", "DAC1 Switch", "DAC R1"}, | ||
1739 | {"HPOR MIX", "HPVOL Switch", "HPOVOL R"}, | ||
1740 | |||
1741 | {"LOUT MIX", "DAC L1 Switch", "DAC L1"}, | ||
1742 | {"LOUT MIX", "DAC R1 Switch", "DAC R1"}, | ||
1743 | {"LOUT MIX", "OUTVOL L Switch", "OUTVOL L"}, | ||
1744 | {"LOUT MIX", "OUTVOL R Switch", "OUTVOL R"}, | ||
1745 | |||
1746 | {"Mono MIX", "DAC R2 Switch", "DAC R2"}, | ||
1747 | {"Mono MIX", "DAC L2 Switch", "DAC L2"}, | ||
1748 | {"Mono MIX", "OUTVOL R Switch", "OUTVOL R"}, | ||
1749 | {"Mono MIX", "OUTVOL L Switch", "OUTVOL L"}, | ||
1750 | {"Mono MIX", "BST1 Switch", "BST1"}, | ||
1751 | |||
1752 | {"HP L amp", NULL, "HPOL MIX"}, | ||
1753 | {"HP R amp", NULL, "HPOR MIX"}, | ||
1754 | |||
1755 | /* {"HP L amp", NULL, "Improve HP amp drv"}, | ||
1756 | {"HP R amp", NULL, "Improve HP amp drv"}, */ | ||
1757 | |||
1758 | {"SPOLP", NULL, "SPOL MIX"}, | ||
1759 | {"SPOLN", NULL, "SPOL MIX"}, | ||
1760 | {"SPORP", NULL, "SPOR MIX"}, | ||
1761 | {"SPORN", NULL, "SPOR MIX"}, | ||
1762 | |||
1763 | {"SPOLP", NULL, "Improve SPK amp drv"}, | ||
1764 | {"SPOLN", NULL, "Improve SPK amp drv"}, | ||
1765 | {"SPORP", NULL, "Improve SPK amp drv"}, | ||
1766 | {"SPORN", NULL, "Improve SPK amp drv"}, | ||
1767 | |||
1768 | {"HPOL", NULL, "Improve HP amp drv"}, | ||
1769 | {"HPOR", NULL, "Improve HP amp drv"}, | ||
1770 | |||
1771 | {"HPOL", NULL, "HP L amp"}, | ||
1772 | {"HPOR", NULL, "HP R amp"}, | ||
1773 | {"LOUTL", NULL, "LOUT MIX"}, | ||
1774 | {"LOUTR", NULL, "LOUT MIX"}, | ||
1775 | {"MonoP", NULL, "Mono MIX"}, | ||
1776 | {"MonoN", NULL, "Mono MIX"}, | ||
1777 | {"MonoP", NULL, "Improve mono amp drv"}, | ||
1778 | }; | ||
1779 | |||
1780 | static int get_sdp_info(struct snd_soc_codec *codec, int dai_id) | ||
1781 | { | ||
1782 | int ret = 0, val = snd_soc_read(codec, RT5640_I2S1_SDP); | ||
1783 | |||
1784 | if (codec == NULL) | ||
1785 | return -EINVAL; | ||
1786 | |||
1787 | val = (val & RT5640_I2S_IF_MASK) >> RT5640_I2S_IF_SFT; | ||
1788 | switch (dai_id) { | ||
1789 | case RT5640_AIF1: | ||
1790 | if (val == RT5640_IF_123 || val == RT5640_IF_132 || | ||
1791 | val == RT5640_IF_113) | ||
1792 | ret |= RT5640_U_IF1; | ||
1793 | if (val == RT5640_IF_312 || val == RT5640_IF_213 || | ||
1794 | val == RT5640_IF_113) | ||
1795 | ret |= RT5640_U_IF2; | ||
1796 | if (val == RT5640_IF_321 || val == RT5640_IF_231) | ||
1797 | ret |= RT5640_U_IF3; | ||
1798 | break; | ||
1799 | |||
1800 | case RT5640_AIF2: | ||
1801 | if (val == RT5640_IF_231 || val == RT5640_IF_213 || | ||
1802 | val == RT5640_IF_223) | ||
1803 | ret |= RT5640_U_IF1; | ||
1804 | if (val == RT5640_IF_123 || val == RT5640_IF_321 || | ||
1805 | val == RT5640_IF_223) | ||
1806 | ret |= RT5640_U_IF2; | ||
1807 | if (val == RT5640_IF_132 || val == RT5640_IF_312) | ||
1808 | ret |= RT5640_U_IF3; | ||
1809 | break; | ||
1810 | |||
1811 | #if (CONFIG_SND_SOC_RT5643_MODULE | CONFIG_SND_SOC_RT5643 | \ | ||
1812 | CONFIG_SND_SOC_RT5646_MODULE | CONFIG_SND_SOC_RT5646) | ||
1813 | |||
1814 | case RT5640_AIF3: | ||
1815 | if (val == RT5640_IF_312 || val == RT5640_IF_321) | ||
1816 | ret |= RT5640_U_IF1; | ||
1817 | if (val == RT5640_IF_132 || val == RT5640_IF_231) | ||
1818 | ret |= RT5640_U_IF2; | ||
1819 | if (val == RT5640_IF_123 || val == RT5640_IF_213 || | ||
1820 | val == RT5640_IF_113 || val == RT5640_IF_223) | ||
1821 | ret |= RT5640_U_IF3; | ||
1822 | break; | ||
1823 | #endif | ||
1824 | |||
1825 | default: | ||
1826 | ret = -EINVAL; | ||
1827 | break; | ||
1828 | } | ||
1829 | |||
1830 | return ret; | ||
1831 | } | ||
1832 | |||
1833 | static int get_clk_info(int sclk, int rate) | ||
1834 | { | ||
1835 | int i, pd[] = {1, 2, 3, 4, 6, 8, 12, 16}; | ||
1836 | |||
1837 | if (sclk <= 0 || rate <= 0) | ||
1838 | return -EINVAL; | ||
1839 | |||
1840 | rate = rate << 8; | ||
1841 | for (i = 0; i < ARRAY_SIZE(pd); i++) | ||
1842 | if (sclk == rate * pd[i]) | ||
1843 | return i; | ||
1844 | |||
1845 | return -EINVAL; | ||
1846 | } | ||
1847 | |||
1848 | static int rt5640_hw_params(struct snd_pcm_substream *substream, | ||
1849 | struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) | ||
1850 | { | ||
1851 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
1852 | struct snd_soc_codec *codec = rtd->codec; | ||
1853 | struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec); | ||
1854 | unsigned int val_len = 0, val_clk, mask_clk, dai_sel; | ||
1855 | int pre_div, bclk_ms, frame_size; | ||
1856 | |||
1857 | rt5640->lrck[dai->id] = params_rate(params); | ||
1858 | pre_div = get_clk_info(rt5640->sysclk, rt5640->lrck[dai->id]); | ||
1859 | if (pre_div < 0) { | ||
1860 | dev_err(codec->dev, "Unsupported clock setting\n"); | ||
1861 | return -EINVAL; | ||
1862 | } | ||
1863 | frame_size = snd_soc_params_to_frame_size(params); | ||
1864 | if (frame_size < 0) { | ||
1865 | dev_err(codec->dev, "Unsupported frame size: %d\n", frame_size); | ||
1866 | return -EINVAL; | ||
1867 | } | ||
1868 | bclk_ms = frame_size > 32 ? 1 : 0; | ||
1869 | rt5640->bclk[dai->id] = rt5640->lrck[dai->id] * (32 << bclk_ms); | ||
1870 | |||
1871 | dev_dbg(dai->dev, "bclk is %dHz and lrck is %dHz\n", | ||
1872 | rt5640->bclk[dai->id], rt5640->lrck[dai->id]); | ||
1873 | dev_dbg(dai->dev, "bclk_ms is %d and pre_div is %d for iis %d\n", | ||
1874 | bclk_ms, pre_div, dai->id); | ||
1875 | |||
1876 | switch (params_format(params)) { | ||
1877 | case SNDRV_PCM_FORMAT_S16_LE: | ||
1878 | break; | ||
1879 | case SNDRV_PCM_FORMAT_S20_3LE: | ||
1880 | val_len |= RT5640_I2S_DL_20; | ||
1881 | break; | ||
1882 | case SNDRV_PCM_FORMAT_S24_LE: | ||
1883 | val_len |= RT5640_I2S_DL_24; | ||
1884 | break; | ||
1885 | case SNDRV_PCM_FORMAT_S8: | ||
1886 | val_len |= RT5640_I2S_DL_8; | ||
1887 | break; | ||
1888 | default: | ||
1889 | return -EINVAL; | ||
1890 | } | ||
1891 | |||
1892 | dai_sel = get_sdp_info(codec, dai->id); | ||
1893 | if (dai_sel < 0) { | ||
1894 | dev_err(codec->dev, "Failed to get sdp info: %d\n", dai_sel); | ||
1895 | return -EINVAL; | ||
1896 | } | ||
1897 | if (dai_sel & RT5640_U_IF1) { | ||
1898 | mask_clk = RT5640_I2S_BCLK_MS1_MASK | RT5640_I2S_PD1_MASK; | ||
1899 | val_clk = bclk_ms << RT5640_I2S_BCLK_MS1_SFT | | ||
1900 | pre_div << RT5640_I2S_PD1_SFT; | ||
1901 | snd_soc_update_bits(codec, RT5640_I2S1_SDP, | ||
1902 | RT5640_I2S_DL_MASK, val_len); | ||
1903 | snd_soc_update_bits(codec, RT5640_ADDA_CLK1, mask_clk, val_clk); | ||
1904 | } | ||
1905 | if (dai_sel & RT5640_U_IF2) { | ||
1906 | mask_clk = RT5640_I2S_BCLK_MS2_MASK | RT5640_I2S_PD2_MASK; | ||
1907 | val_clk = bclk_ms << RT5640_I2S_BCLK_MS2_SFT | | ||
1908 | pre_div << RT5640_I2S_PD2_SFT; | ||
1909 | snd_soc_update_bits(codec, RT5640_I2S2_SDP, | ||
1910 | RT5640_I2S_DL_MASK, val_len); | ||
1911 | snd_soc_update_bits(codec, RT5640_ADDA_CLK1, mask_clk, val_clk); | ||
1912 | } | ||
1913 | #if (CONFIG_SND_SOC_RT5643_MODULE | CONFIG_SND_SOC_RT5643 | \ | ||
1914 | CONFIG_SND_SOC_RT5646_MODULE | CONFIG_SND_SOC_RT5646) | ||
1915 | if (dai_sel & RT5640_U_IF3) { | ||
1916 | mask_clk = RT5640_I2S_BCLK_MS3_MASK | RT5640_I2S_PD3_MASK; | ||
1917 | val_clk = bclk_ms << RT5640_I2S_BCLK_MS3_SFT | | ||
1918 | pre_div << RT5640_I2S_PD3_SFT; | ||
1919 | snd_soc_update_bits(codec, RT5640_I2S3_SDP, | ||
1920 | RT5640_I2S_DL_MASK, val_len); | ||
1921 | snd_soc_update_bits(codec, RT5640_ADDA_CLK1, mask_clk, val_clk); | ||
1922 | } | ||
1923 | #endif | ||
1924 | return 0; | ||
1925 | } | ||
1926 | |||
1927 | static int rt5640_prepare(struct snd_pcm_substream *substream, | ||
1928 | struct snd_soc_dai *dai) | ||
1929 | { | ||
1930 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
1931 | struct snd_soc_codec *codec = rtd->codec; | ||
1932 | struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec); | ||
1933 | |||
1934 | rt5640->aif_pu = dai->id; | ||
1935 | return 0; | ||
1936 | } | ||
1937 | |||
1938 | static int rt5640_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) | ||
1939 | { | ||
1940 | struct snd_soc_codec *codec = dai->codec; | ||
1941 | struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec); | ||
1942 | unsigned int reg_val = 0, dai_sel; | ||
1943 | |||
1944 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { | ||
1945 | case SND_SOC_DAIFMT_CBM_CFM: | ||
1946 | rt5640->master[dai->id] = 1; | ||
1947 | break; | ||
1948 | case SND_SOC_DAIFMT_CBS_CFS: | ||
1949 | reg_val |= RT5640_I2S_MS_S; | ||
1950 | rt5640->master[dai->id] = 0; | ||
1951 | break; | ||
1952 | default: | ||
1953 | return -EINVAL; | ||
1954 | } | ||
1955 | |||
1956 | switch (fmt & SND_SOC_DAIFMT_INV_MASK) { | ||
1957 | case SND_SOC_DAIFMT_NB_NF: | ||
1958 | break; | ||
1959 | case SND_SOC_DAIFMT_IB_NF: | ||
1960 | reg_val |= RT5640_I2S_BP_INV; | ||
1961 | break; | ||
1962 | default: | ||
1963 | return -EINVAL; | ||
1964 | } | ||
1965 | |||
1966 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { | ||
1967 | case SND_SOC_DAIFMT_I2S: | ||
1968 | break; | ||
1969 | case SND_SOC_DAIFMT_LEFT_J: | ||
1970 | reg_val |= RT5640_I2S_DF_LEFT; | ||
1971 | break; | ||
1972 | case SND_SOC_DAIFMT_DSP_A: | ||
1973 | reg_val |= RT5640_I2S_DF_PCM_A; | ||
1974 | break; | ||
1975 | case SND_SOC_DAIFMT_DSP_B: | ||
1976 | reg_val |= RT5640_I2S_DF_PCM_B; | ||
1977 | break; | ||
1978 | default: | ||
1979 | return -EINVAL; | ||
1980 | } | ||
1981 | |||
1982 | dai_sel = get_sdp_info(codec, dai->id); | ||
1983 | if (dai_sel < 0) { | ||
1984 | dev_err(codec->dev, "Failed to get sdp info: %d\n", dai_sel); | ||
1985 | return -EINVAL; | ||
1986 | } | ||
1987 | if (dai_sel & RT5640_U_IF1) { | ||
1988 | snd_soc_update_bits(codec, RT5640_I2S1_SDP, | ||
1989 | RT5640_I2S_MS_MASK | RT5640_I2S_BP_MASK | | ||
1990 | RT5640_I2S_DF_MASK, reg_val); | ||
1991 | } | ||
1992 | if (dai_sel & RT5640_U_IF2) { | ||
1993 | snd_soc_update_bits(codec, RT5640_I2S2_SDP, | ||
1994 | RT5640_I2S_MS_MASK | RT5640_I2S_BP_MASK | | ||
1995 | RT5640_I2S_DF_MASK, reg_val); | ||
1996 | } | ||
1997 | #if (CONFIG_SND_SOC_RT5643_MODULE | CONFIG_SND_SOC_RT5643 | \ | ||
1998 | CONFIG_SND_SOC_RT5646_MODULE | CONFIG_SND_SOC_RT5646) | ||
1999 | if (dai_sel & RT5640_U_IF3) { | ||
2000 | snd_soc_update_bits(codec, RT5640_I2S3_SDP, | ||
2001 | RT5640_I2S_MS_MASK | RT5640_I2S_BP_MASK | | ||
2002 | RT5640_I2S_DF_MASK, reg_val); | ||
2003 | } | ||
2004 | #endif | ||
2005 | return 0; | ||
2006 | } | ||
2007 | |||
2008 | static int rt5640_set_dai_sysclk(struct snd_soc_dai *dai, | ||
2009 | int clk_id, unsigned int freq, int dir) | ||
2010 | { | ||
2011 | struct snd_soc_codec *codec = dai->codec; | ||
2012 | struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec); | ||
2013 | unsigned int reg_val = 0; | ||
2014 | |||
2015 | if (freq == rt5640->sysclk && clk_id == rt5640->sysclk_src) | ||
2016 | return 0; | ||
2017 | |||
2018 | switch (clk_id) { | ||
2019 | case RT5640_SCLK_S_MCLK: | ||
2020 | reg_val |= RT5640_SCLK_SRC_MCLK; | ||
2021 | break; | ||
2022 | case RT5640_SCLK_S_PLL1: | ||
2023 | reg_val |= RT5640_SCLK_SRC_PLL1; | ||
2024 | break; | ||
2025 | case RT5640_SCLK_S_PLL1_TK: | ||
2026 | reg_val |= RT5640_SCLK_SRC_PLL1T; | ||
2027 | break; | ||
2028 | case RT5640_SCLK_S_RCCLK: | ||
2029 | reg_val |= RT5640_SCLK_SRC_RCCLK; | ||
2030 | break; | ||
2031 | default: | ||
2032 | dev_err(codec->dev, "Invalid clock id (%d)\n", clk_id); | ||
2033 | return -EINVAL; | ||
2034 | } | ||
2035 | snd_soc_update_bits(codec, RT5640_GLB_CLK, | ||
2036 | RT5640_SCLK_SRC_MASK, reg_val); | ||
2037 | rt5640->sysclk = freq; | ||
2038 | rt5640->sysclk_src = clk_id; | ||
2039 | |||
2040 | dev_dbg(dai->dev, "Sysclk is %dHz and clock id is %d\n", freq, clk_id); | ||
2041 | return 0; | ||
2042 | } | ||
2043 | |||
2044 | /** | ||
2045 | * rt5640_pll_calc - Calcualte PLL M/N/K code. | ||
2046 | * @freq_in: external clock provided to codec. | ||
2047 | * @freq_out: target clock which codec works on. | ||
2048 | * @pll_code: Pointer to structure with M, N, K and bypass flag. | ||
2049 | * | ||
2050 | * Calcualte M/N/K code to configure PLL for codec. And K is assigned to 2 | ||
2051 | * which make calculation more efficiently. | ||
2052 | * | ||
2053 | * Returns 0 for success or negative error code. | ||
2054 | */ | ||
2055 | static int rt5640_pll_calc(const unsigned int freq_in, | ||
2056 | const unsigned int freq_out, struct rt5640_pll_code *pll_code) | ||
2057 | { | ||
2058 | int max_n = RT5640_PLL_N_MAX, max_m = RT5640_PLL_M_MAX; | ||
2059 | int n, m, red, n_t, m_t, in_t, out_t, red_t = abs(freq_out - freq_in); | ||
2060 | bool bypass = false; | ||
2061 | |||
2062 | if (RT5640_PLL_INP_MAX < freq_in || RT5640_PLL_INP_MIN > freq_in) | ||
2063 | return -EINVAL; | ||
2064 | |||
2065 | for (n_t = 0; n_t <= max_n; n_t++) { | ||
2066 | in_t = (freq_in >> 1) + (freq_in >> 2) * n_t; | ||
2067 | if (in_t < 0) | ||
2068 | continue; | ||
2069 | if (in_t == freq_out) { | ||
2070 | bypass = true; | ||
2071 | n = n_t; | ||
2072 | goto code_find; | ||
2073 | } | ||
2074 | for (m_t = 0; m_t <= max_m; m_t++) { | ||
2075 | out_t = in_t / (m_t + 2); | ||
2076 | red = abs(out_t - freq_out); | ||
2077 | if (red < red_t) { | ||
2078 | n = n_t; | ||
2079 | m = m_t; | ||
2080 | if (red == 0) | ||
2081 | goto code_find; | ||
2082 | red_t = red; | ||
2083 | } | ||
2084 | } | ||
2085 | } | ||
2086 | pr_debug("Only get approximation about PLL\n"); | ||
2087 | |||
2088 | code_find: | ||
2089 | |||
2090 | pll_code->m_bp = bypass; | ||
2091 | pll_code->m_code = m; | ||
2092 | pll_code->n_code = n; | ||
2093 | pll_code->k_code = 2; | ||
2094 | return 0; | ||
2095 | } | ||
2096 | |||
2097 | static int rt5640_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source, | ||
2098 | unsigned int freq_in, unsigned int freq_out) | ||
2099 | { | ||
2100 | struct snd_soc_codec *codec = dai->codec; | ||
2101 | struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec); | ||
2102 | struct rt5640_pll_code pll_code; | ||
2103 | int ret, dai_sel; | ||
2104 | |||
2105 | if (source == rt5640->pll_src && freq_in == rt5640->pll_in && | ||
2106 | freq_out == rt5640->pll_out) | ||
2107 | return 0; | ||
2108 | |||
2109 | if (!freq_in || !freq_out) { | ||
2110 | dev_dbg(codec->dev, "PLL disabled\n"); | ||
2111 | |||
2112 | rt5640->pll_in = 0; | ||
2113 | rt5640->pll_out = 0; | ||
2114 | snd_soc_update_bits(codec, RT5640_GLB_CLK, | ||
2115 | RT5640_SCLK_SRC_MASK, RT5640_SCLK_SRC_MCLK); | ||
2116 | return 0; | ||
2117 | } | ||
2118 | |||
2119 | switch (source) { | ||
2120 | case RT5640_PLL1_S_MCLK: | ||
2121 | snd_soc_update_bits(codec, RT5640_GLB_CLK, | ||
2122 | RT5640_PLL1_SRC_MASK, RT5640_PLL1_SRC_MCLK); | ||
2123 | break; | ||
2124 | case RT5640_PLL1_S_BCLK1: | ||
2125 | case RT5640_PLL1_S_BCLK2: | ||
2126 | |||
2127 | #if (CONFIG_SND_SOC_RT5643_MODULE | CONFIG_SND_SOC_RT5643 | \ | ||
2128 | CONFIG_SND_SOC_RT5646_MODULE | CONFIG_SND_SOC_RT5646) | ||
2129 | |||
2130 | case RT5640_PLL1_S_BCLK3: | ||
2131 | |||
2132 | #endif | ||
2133 | dai_sel = get_sdp_info(codec, dai->id); | ||
2134 | if (dai_sel < 0) { | ||
2135 | dev_err(codec->dev, | ||
2136 | "Failed to get sdp info: %d\n", dai_sel); | ||
2137 | return -EINVAL; | ||
2138 | } | ||
2139 | if (dai_sel & RT5640_U_IF1) { | ||
2140 | snd_soc_update_bits(codec, RT5640_GLB_CLK, | ||
2141 | RT5640_PLL1_SRC_MASK, RT5640_PLL1_SRC_BCLK1); | ||
2142 | } | ||
2143 | if (dai_sel & RT5640_U_IF2) { | ||
2144 | snd_soc_update_bits(codec, RT5640_GLB_CLK, | ||
2145 | RT5640_PLL1_SRC_MASK, RT5640_PLL1_SRC_BCLK2); | ||
2146 | } | ||
2147 | if (dai_sel & RT5640_U_IF3) { | ||
2148 | snd_soc_update_bits(codec, RT5640_GLB_CLK, | ||
2149 | RT5640_PLL1_SRC_MASK, RT5640_PLL1_SRC_BCLK3); | ||
2150 | } | ||
2151 | break; | ||
2152 | default: | ||
2153 | dev_err(codec->dev, "Unknown PLL source %d\n", source); | ||
2154 | return -EINVAL; | ||
2155 | } | ||
2156 | |||
2157 | ret = rt5640_pll_calc(freq_in, freq_out, &pll_code); | ||
2158 | if (ret < 0) { | ||
2159 | dev_err(codec->dev, "Unsupport input clock %d\n", freq_in); | ||
2160 | return ret; | ||
2161 | } | ||
2162 | |||
2163 | dev_dbg(codec->dev, "bypass=%d m=%d n=%d k=2\n", pll_code.m_bp, | ||
2164 | (pll_code.m_bp ? 0 : pll_code.m_code), pll_code.n_code); | ||
2165 | |||
2166 | snd_soc_write(codec, RT5640_PLL_CTRL1, | ||
2167 | pll_code.n_code << RT5640_PLL_N_SFT | pll_code.k_code); | ||
2168 | snd_soc_write(codec, RT5640_PLL_CTRL2, | ||
2169 | (pll_code.m_bp ? 0 : pll_code.m_code) << RT5640_PLL_M_SFT | | ||
2170 | pll_code.m_bp << RT5640_PLL_M_BP_SFT); | ||
2171 | |||
2172 | rt5640->pll_in = freq_in; | ||
2173 | rt5640->pll_out = freq_out; | ||
2174 | rt5640->pll_src = source; | ||
2175 | |||
2176 | return 0; | ||
2177 | } | ||
2178 | |||
2179 | /** | ||
2180 | * rt5640_index_show - Dump private registers. | ||
2181 | * @dev: codec device. | ||
2182 | * @attr: device attribute. | ||
2183 | * @buf: buffer for display. | ||
2184 | * | ||
2185 | * To show non-zero values of all private registers. | ||
2186 | * | ||
2187 | * Returns buffer length. | ||
2188 | */ | ||
2189 | static ssize_t rt5640_index_show(struct device *dev, | ||
2190 | struct device_attribute *attr, char *buf) | ||
2191 | { | ||
2192 | struct i2c_client *client = to_i2c_client(dev); | ||
2193 | struct rt5640_priv *rt5640 = i2c_get_clientdata(client); | ||
2194 | struct snd_soc_codec *codec = rt5640->codec; | ||
2195 | unsigned int val; | ||
2196 | int cnt = 0, i; | ||
2197 | |||
2198 | cnt += sprintf(buf, "RT5640 index register\n"); | ||
2199 | for (i = 0; i < 0xb4; i++) { | ||
2200 | if (cnt + 9 >= PAGE_SIZE - 1) | ||
2201 | break; | ||
2202 | val = rt5640_index_read(codec, i); | ||
2203 | if (!val) | ||
2204 | continue; | ||
2205 | cnt += snprintf(buf + cnt, 10, "%02x: %04x\n", i, val); | ||
2206 | } | ||
2207 | |||
2208 | if (cnt >= PAGE_SIZE) | ||
2209 | cnt = PAGE_SIZE - 1; | ||
2210 | |||
2211 | return cnt; | ||
2212 | } | ||
2213 | static DEVICE_ATTR(index_reg, 0444, rt5640_index_show, NULL); | ||
2214 | |||
2215 | static int rt5640_set_bias_level(struct snd_soc_codec *codec, | ||
2216 | enum snd_soc_bias_level level) | ||
2217 | { | ||
2218 | switch (level) { | ||
2219 | case SND_SOC_BIAS_ON: | ||
2220 | #ifdef RT5640_DEMO | ||
2221 | snd_soc_update_bits(codec, RT5640_SPK_VOL, | ||
2222 | RT5640_L_MUTE | RT5640_R_MUTE, 0); | ||
2223 | snd_soc_update_bits(codec, RT5640_HP_VOL, | ||
2224 | RT5640_L_MUTE | RT5640_R_MUTE, 0); | ||
2225 | break; | ||
2226 | #endif | ||
2227 | case SND_SOC_BIAS_PREPARE: | ||
2228 | #ifdef RT5640_DEMO | ||
2229 | snd_soc_update_bits(codec, RT5640_PWR_ANLG1, | ||
2230 | RT5640_PWR_VREF1 | RT5640_PWR_MB | | ||
2231 | RT5640_PWR_BG | RT5640_PWR_VREF2, | ||
2232 | RT5640_PWR_VREF1 | RT5640_PWR_MB | | ||
2233 | RT5640_PWR_BG | RT5640_PWR_VREF2); | ||
2234 | msleep(100); | ||
2235 | |||
2236 | snd_soc_update_bits(codec, RT5640_PWR_ANLG1, | ||
2237 | RT5640_PWR_FV1 | RT5640_PWR_FV2, | ||
2238 | RT5640_PWR_FV1 | RT5640_PWR_FV2); | ||
2239 | |||
2240 | snd_soc_update_bits(codec, RT5640_PWR_ANLG2, | ||
2241 | RT5640_PWR_MB1 | RT5640_PWR_MB2, | ||
2242 | RT5640_PWR_MB1 | RT5640_PWR_MB2); | ||
2243 | #endif | ||
2244 | break; | ||
2245 | |||
2246 | case SND_SOC_BIAS_STANDBY: | ||
2247 | #ifdef RT5640_DEMO | ||
2248 | snd_soc_update_bits(codec, RT5640_SPK_VOL, RT5640_L_MUTE | | ||
2249 | RT5640_R_MUTE, RT5640_L_MUTE | RT5640_R_MUTE); | ||
2250 | snd_soc_update_bits(codec, RT5640_HP_VOL, RT5640_L_MUTE | | ||
2251 | RT5640_R_MUTE, RT5640_L_MUTE | RT5640_R_MUTE); | ||
2252 | |||
2253 | snd_soc_update_bits(codec, RT5640_PWR_ANLG2, | ||
2254 | RT5640_PWR_MB1 | RT5640_PWR_MB2, | ||
2255 | 0); | ||
2256 | #endif | ||
2257 | if (SND_SOC_BIAS_OFF == codec->dapm.bias_level) { | ||
2258 | snd_soc_update_bits(codec, RT5640_PWR_ANLG1, | ||
2259 | RT5640_PWR_VREF1 | RT5640_PWR_MB | | ||
2260 | RT5640_PWR_BG | RT5640_PWR_VREF2, | ||
2261 | RT5640_PWR_VREF1 | RT5640_PWR_MB | | ||
2262 | RT5640_PWR_BG | RT5640_PWR_VREF2); | ||
2263 | msleep(10); | ||
2264 | snd_soc_update_bits(codec, RT5640_PWR_ANLG1, | ||
2265 | RT5640_PWR_FV1 | RT5640_PWR_FV2, | ||
2266 | RT5640_PWR_FV1 | RT5640_PWR_FV2); | ||
2267 | codec->cache_only = false; | ||
2268 | snd_soc_cache_sync(codec); | ||
2269 | } | ||
2270 | break; | ||
2271 | |||
2272 | case SND_SOC_BIAS_OFF: | ||
2273 | #ifdef RT5640_DEMO | ||
2274 | snd_soc_update_bits(codec, RT5640_SPK_VOL, RT5640_L_MUTE | | ||
2275 | RT5640_R_MUTE, RT5640_L_MUTE | RT5640_R_MUTE); | ||
2276 | snd_soc_update_bits(codec, RT5640_HP_VOL, RT5640_L_MUTE | | ||
2277 | RT5640_R_MUTE, RT5640_L_MUTE | RT5640_R_MUTE); | ||
2278 | snd_soc_update_bits(codec, RT5640_OUTPUT, RT5640_L_MUTE | | ||
2279 | RT5640_R_MUTE, RT5640_L_MUTE | RT5640_R_MUTE); | ||
2280 | snd_soc_update_bits(codec, RT5640_MONO_OUT, | ||
2281 | RT5640_L_MUTE, RT5640_L_MUTE); | ||
2282 | #endif | ||
2283 | snd_soc_write(codec, RT5640_PWR_DIG1, 0x0000); | ||
2284 | snd_soc_write(codec, RT5640_PWR_DIG2, 0x0000); | ||
2285 | snd_soc_write(codec, RT5640_PWR_VOL, 0x0000); | ||
2286 | snd_soc_write(codec, RT5640_PWR_MIXER, 0x0000); | ||
2287 | snd_soc_write(codec, RT5640_PWR_ANLG1, 0x0000); | ||
2288 | snd_soc_write(codec, RT5640_PWR_ANLG2, 0x0000); | ||
2289 | break; | ||
2290 | |||
2291 | default: | ||
2292 | break; | ||
2293 | } | ||
2294 | codec->dapm.bias_level = level; | ||
2295 | |||
2296 | return 0; | ||
2297 | } | ||
2298 | |||
2299 | static int rt5640_probe(struct snd_soc_codec *codec) | ||
2300 | { | ||
2301 | struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec); | ||
2302 | int ret; | ||
2303 | u16 val; | ||
2304 | |||
2305 | ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C); | ||
2306 | if (ret != 0) { | ||
2307 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | ||
2308 | return ret; | ||
2309 | } | ||
2310 | |||
2311 | val = snd_soc_read(codec, RT5640_RESET); | ||
2312 | if (val != rt5640_reg[RT5640_RESET]) { | ||
2313 | dev_err(codec->dev, | ||
2314 | "Device with ID register %x is not a rt5640\n", val); | ||
2315 | return -ENODEV; | ||
2316 | } | ||
2317 | |||
2318 | rt5640_reset(codec); | ||
2319 | snd_soc_update_bits(codec, RT5640_PWR_ANLG1, | ||
2320 | RT5640_PWR_VREF1 | RT5640_PWR_MB | | ||
2321 | RT5640_PWR_BG | RT5640_PWR_VREF2, | ||
2322 | RT5640_PWR_VREF1 | RT5640_PWR_MB | | ||
2323 | RT5640_PWR_BG | RT5640_PWR_VREF2); | ||
2324 | msleep(100); | ||
2325 | snd_soc_update_bits(codec, RT5640_PWR_ANLG1, | ||
2326 | RT5640_PWR_FV1 | RT5640_PWR_FV2, | ||
2327 | RT5640_PWR_FV1 | RT5640_PWR_FV2); | ||
2328 | /* DMIC */ | ||
2329 | if (rt5640->dmic_en == RT5640_DMIC1) { | ||
2330 | snd_soc_update_bits(codec, RT5640_GPIO_CTRL1, | ||
2331 | RT5640_GP2_PIN_MASK, RT5640_GP2_PIN_DMIC1_SCL); | ||
2332 | snd_soc_update_bits(codec, RT5640_DMIC, | ||
2333 | RT5640_DMIC_1L_LH_MASK | RT5640_DMIC_1R_LH_MASK, | ||
2334 | RT5640_DMIC_1L_LH_FALLING | RT5640_DMIC_1R_LH_RISING); | ||
2335 | } else if (rt5640->dmic_en == RT5640_DMIC2) { | ||
2336 | snd_soc_update_bits(codec, RT5640_GPIO_CTRL1, | ||
2337 | RT5640_GP2_PIN_MASK, RT5640_GP2_PIN_DMIC1_SCL); | ||
2338 | snd_soc_update_bits(codec, RT5640_DMIC, | ||
2339 | RT5640_DMIC_2L_LH_MASK | RT5640_DMIC_2R_LH_MASK, | ||
2340 | RT5640_DMIC_2L_LH_FALLING | RT5640_DMIC_2R_LH_RISING); | ||
2341 | } | ||
2342 | |||
2343 | #ifdef RT5640_DEMO | ||
2344 | rt5640_reg_init(codec); | ||
2345 | #endif | ||
2346 | |||
2347 | |||
2348 | #if (CONFIG_SND_SOC_RT5642_MODULE | CONFIG_SND_SOC_RT5642) | ||
2349 | rt5640_register_dsp(codec); | ||
2350 | #endif | ||
2351 | |||
2352 | codec->dapm.bias_level = SND_SOC_BIAS_STANDBY; | ||
2353 | |||
2354 | snd_soc_add_controls(codec, rt5640_snd_controls, | ||
2355 | ARRAY_SIZE(rt5640_snd_controls)); | ||
2356 | |||
2357 | rt5640->codec = codec; | ||
2358 | ret = device_create_file(codec->dev, &dev_attr_index_reg); | ||
2359 | if (ret != 0) { | ||
2360 | dev_err(codec->dev, | ||
2361 | "Failed to create index_reg sysfs files: %d\n", ret); | ||
2362 | return ret; | ||
2363 | } | ||
2364 | |||
2365 | return 0; | ||
2366 | } | ||
2367 | |||
2368 | static int rt5640_remove(struct snd_soc_codec *codec) | ||
2369 | { | ||
2370 | rt5640_set_bias_level(codec, SND_SOC_BIAS_OFF); | ||
2371 | rt5640_reset(codec); | ||
2372 | snd_soc_write(codec, RT5640_PWR_ANLG1, 0); | ||
2373 | |||
2374 | return 0; | ||
2375 | } | ||
2376 | #ifdef CONFIG_PM | ||
2377 | static int rt5640_suspend(struct snd_soc_codec *codec, pm_message_t state) | ||
2378 | { | ||
2379 | rt5640_set_bias_level(codec, SND_SOC_BIAS_OFF); | ||
2380 | snd_soc_write(codec, RT5640_PWR_ANLG1, 0); | ||
2381 | |||
2382 | return 0; | ||
2383 | } | ||
2384 | |||
2385 | static int rt5640_resume(struct snd_soc_codec *codec) | ||
2386 | { | ||
2387 | rt5640_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | ||
2388 | |||
2389 | return 0; | ||
2390 | } | ||
2391 | #else | ||
2392 | #define rt5640_suspend NULL | ||
2393 | #define rt5640_resume NULL | ||
2394 | #endif | ||
2395 | |||
2396 | #define RT5640_STEREO_RATES SNDRV_PCM_RATE_8000_96000 | ||
2397 | #define RT5640_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ | ||
2398 | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S8) | ||
2399 | |||
2400 | struct snd_soc_dai_ops rt5640_aif_dai_ops = { | ||
2401 | .hw_params = rt5640_hw_params, | ||
2402 | .prepare = rt5640_prepare, | ||
2403 | .set_fmt = rt5640_set_dai_fmt, | ||
2404 | .set_sysclk = rt5640_set_dai_sysclk, | ||
2405 | .set_pll = rt5640_set_dai_pll, | ||
2406 | }; | ||
2407 | |||
2408 | struct snd_soc_dai_driver rt5640_dai[] = { | ||
2409 | { | ||
2410 | .name = "rt5640-aif1", | ||
2411 | .id = RT5640_AIF1, | ||
2412 | .playback = { | ||
2413 | .stream_name = "AIF1 Playback", | ||
2414 | .channels_min = 1, | ||
2415 | .channels_max = 2, | ||
2416 | .rates = RT5640_STEREO_RATES, | ||
2417 | .formats = RT5640_FORMATS, | ||
2418 | }, | ||
2419 | .capture = { | ||
2420 | .stream_name = "AIF1 Capture", | ||
2421 | .channels_min = 1, | ||
2422 | .channels_max = 2, | ||
2423 | .rates = RT5640_STEREO_RATES, | ||
2424 | .formats = RT5640_FORMATS, | ||
2425 | }, | ||
2426 | .ops = &rt5640_aif_dai_ops, | ||
2427 | }, | ||
2428 | { | ||
2429 | .name = "rt5640-aif2", | ||
2430 | .id = RT5640_AIF2, | ||
2431 | .playback = { | ||
2432 | .stream_name = "AIF2 Playback", | ||
2433 | .channels_min = 1, | ||
2434 | .channels_max = 2, | ||
2435 | .rates = RT5640_STEREO_RATES, | ||
2436 | .formats = RT5640_FORMATS, | ||
2437 | }, | ||
2438 | .capture = { | ||
2439 | .stream_name = "AIF2 Capture", | ||
2440 | .channels_min = 1, | ||
2441 | .channels_max = 2, | ||
2442 | .rates = RT5640_STEREO_RATES, | ||
2443 | .formats = RT5640_FORMATS, | ||
2444 | }, | ||
2445 | .ops = &rt5640_aif_dai_ops, | ||
2446 | }, | ||
2447 | #if (CONFIG_SND_SOC_RT5643_MODULE | CONFIG_SND_SOC_RT5643 | \ | ||
2448 | CONFIG_SND_SOC_RT5646_MODULE | CONFIG_SND_SOC_RT5646) | ||
2449 | { | ||
2450 | .name = "rt5640-aif3", | ||
2451 | .id = RT5640_AIF3, | ||
2452 | .playback = { | ||
2453 | .stream_name = "AIF3 Playback", | ||
2454 | .channels_min = 1, | ||
2455 | .channels_max = 2, | ||
2456 | .rates = RT5640_STEREO_RATES, | ||
2457 | .formats = RT5640_FORMATS, | ||
2458 | }, | ||
2459 | .capture = { | ||
2460 | .stream_name = "AIF3 Capture", | ||
2461 | .channels_min = 1, | ||
2462 | .channels_max = 2, | ||
2463 | .rates = RT5640_STEREO_RATES, | ||
2464 | .formats = RT5640_FORMATS, | ||
2465 | }, | ||
2466 | .ops = &rt5640_aif_dai_ops, | ||
2467 | }, | ||
2468 | #endif | ||
2469 | }; | ||
2470 | |||
2471 | static struct snd_soc_codec_driver soc_codec_dev_rt5640 = { | ||
2472 | .probe = rt5640_probe, | ||
2473 | .remove = rt5640_remove, | ||
2474 | .suspend = rt5640_suspend, | ||
2475 | .resume = rt5640_resume, | ||
2476 | .set_bias_level = rt5640_set_bias_level, | ||
2477 | .reg_cache_size = RT5640_VENDOR_ID2 + 1, | ||
2478 | .reg_word_size = sizeof(u16), | ||
2479 | .reg_cache_default = rt5640_reg, | ||
2480 | .volatile_register = rt5640_volatile_register, | ||
2481 | .readable_register = rt5640_readable_register, | ||
2482 | .reg_cache_step = 1, | ||
2483 | .dapm_widgets = rt5640_dapm_widgets, | ||
2484 | .num_dapm_widgets = ARRAY_SIZE(rt5640_dapm_widgets), | ||
2485 | .dapm_routes = rt5640_dapm_routes, | ||
2486 | .num_dapm_routes = ARRAY_SIZE(rt5640_dapm_routes), | ||
2487 | }; | ||
2488 | |||
2489 | static const struct i2c_device_id rt5640_i2c_id[] = { | ||
2490 | { "rt5640", 0 }, | ||
2491 | { } | ||
2492 | }; | ||
2493 | MODULE_DEVICE_TABLE(i2c, rt5640_i2c_id); | ||
2494 | |||
2495 | static int rt5640_i2c_probe(struct i2c_client *i2c, | ||
2496 | const struct i2c_device_id *id) | ||
2497 | { | ||
2498 | struct rt5640_priv *rt5640; | ||
2499 | int ret; | ||
2500 | |||
2501 | rt5640 = kzalloc(sizeof(struct rt5640_priv), GFP_KERNEL); | ||
2502 | if (NULL == rt5640) | ||
2503 | return -ENOMEM; | ||
2504 | |||
2505 | i2c_set_clientdata(i2c, rt5640); | ||
2506 | |||
2507 | ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5640, | ||
2508 | rt5640_dai, ARRAY_SIZE(rt5640_dai)); | ||
2509 | if (ret < 0) | ||
2510 | kfree(rt5640); | ||
2511 | |||
2512 | return ret; | ||
2513 | } | ||
2514 | |||
2515 | static __devexit int rt5640_i2c_remove(struct i2c_client *i2c) | ||
2516 | { | ||
2517 | snd_soc_unregister_codec(&i2c->dev); | ||
2518 | kfree(i2c_get_clientdata(i2c)); | ||
2519 | return 0; | ||
2520 | } | ||
2521 | |||
2522 | struct i2c_driver rt5640_i2c_driver = { | ||
2523 | .driver = { | ||
2524 | .name = "rt5640", | ||
2525 | .owner = THIS_MODULE, | ||
2526 | }, | ||
2527 | .probe = rt5640_i2c_probe, | ||
2528 | .remove = __devexit_p(rt5640_i2c_remove), | ||
2529 | .id_table = rt5640_i2c_id, | ||
2530 | }; | ||
2531 | |||
2532 | static int __init rt5640_modinit(void) | ||
2533 | { | ||
2534 | return i2c_add_driver(&rt5640_i2c_driver); | ||
2535 | } | ||
2536 | module_init(rt5640_modinit); | ||
2537 | |||
2538 | static void __exit rt5640_modexit(void) | ||
2539 | { | ||
2540 | i2c_del_driver(&rt5640_i2c_driver); | ||
2541 | } | ||
2542 | module_exit(rt5640_modexit); | ||
2543 | |||
2544 | MODULE_DESCRIPTION("ASoC RT5640 driver"); | ||
2545 | MODULE_AUTHOR("Johnny Hsu <johnnyhsu@realtek.com>"); | ||
2546 | MODULE_LICENSE("GPL"); | ||