1 | // SPDX-License-Identifier: GPL-2.0 |
2 | // |
3 | // mt6359.c -- mt6359 ALSA SoC audio codec driver |
4 | // |
5 | // Copyright (c) 2020 MediaTek Inc. |
6 | // Author: KaiChieh Chuang <kaichieh.chuang@mediatek.com> |
7 | |
8 | #include <linux/delay.h> |
9 | #include <linux/kthread.h> |
10 | #include <linux/mfd/mt6397/core.h> |
11 | #include <linux/module.h> |
12 | #include <linux/of.h> |
13 | #include <linux/platform_device.h> |
14 | #include <linux/regulator/consumer.h> |
15 | #include <linux/sched.h> |
16 | #include <sound/soc.h> |
17 | #include <sound/tlv.h> |
18 | |
19 | #include "mt6359.h" |
20 | |
21 | static void mt6359_set_gpio_smt(struct mt6359_priv *priv) |
22 | { |
23 | /* set gpio SMT mode */ |
24 | regmap_update_bits(map: priv->regmap, MT6359_SMT_CON1, mask: 0x3ff0, val: 0x3ff0); |
25 | } |
26 | |
27 | static void mt6359_set_gpio_driving(struct mt6359_priv *priv) |
28 | { |
29 | /* 8:4mA(default), a:8mA, c:12mA, e:16mA */ |
30 | regmap_update_bits(map: priv->regmap, MT6359_DRV_CON2, mask: 0xffff, val: 0x8888); |
31 | regmap_update_bits(map: priv->regmap, MT6359_DRV_CON3, mask: 0xffff, val: 0x8888); |
32 | regmap_update_bits(map: priv->regmap, MT6359_DRV_CON4, mask: 0x00ff, val: 0x88); |
33 | } |
34 | |
35 | static void mt6359_set_playback_gpio(struct mt6359_priv *priv) |
36 | { |
37 | /* set gpio mosi mode, clk / data mosi */ |
38 | regmap_write(map: priv->regmap, MT6359_GPIO_MODE2_CLR, val: 0x0ffe); |
39 | regmap_write(map: priv->regmap, MT6359_GPIO_MODE2_SET, val: 0x0249); |
40 | |
41 | /* sync mosi */ |
42 | regmap_write(map: priv->regmap, MT6359_GPIO_MODE3_CLR, val: 0x6); |
43 | regmap_write(map: priv->regmap, MT6359_GPIO_MODE3_SET, val: 0x1); |
44 | } |
45 | |
46 | static void mt6359_reset_playback_gpio(struct mt6359_priv *priv) |
47 | { |
48 | /* set pad_aud_*_mosi to GPIO mode and dir input |
49 | * reason: |
50 | * pad_aud_dat_mosi*, because the pin is used as boot strap |
51 | * don't clean clk/sync, for mtkaif protocol 2 |
52 | */ |
53 | regmap_write(map: priv->regmap, MT6359_GPIO_MODE2_CLR, val: 0x0ff8); |
54 | regmap_update_bits(map: priv->regmap, MT6359_GPIO_DIR0, mask: 0x7 << 9, val: 0x0); |
55 | } |
56 | |
57 | static void mt6359_set_capture_gpio(struct mt6359_priv *priv) |
58 | { |
59 | /* set gpio miso mode */ |
60 | regmap_write(map: priv->regmap, MT6359_GPIO_MODE3_CLR, val: 0x0e00); |
61 | regmap_write(map: priv->regmap, MT6359_GPIO_MODE3_SET, val: 0x0200); |
62 | |
63 | regmap_write(map: priv->regmap, MT6359_GPIO_MODE4_CLR, val: 0x003f); |
64 | regmap_write(map: priv->regmap, MT6359_GPIO_MODE4_SET, val: 0x0009); |
65 | } |
66 | |
67 | static void mt6359_reset_capture_gpio(struct mt6359_priv *priv) |
68 | { |
69 | /* set pad_aud_*_miso to GPIO mode and dir input |
70 | * reason: |
71 | * pad_aud_clk_miso, because when playback only the miso_clk |
72 | * will also have 26m, so will have power leak |
73 | * pad_aud_dat_miso*, because the pin is used as boot strap |
74 | */ |
75 | regmap_write(map: priv->regmap, MT6359_GPIO_MODE3_CLR, val: 0x0e00); |
76 | |
77 | regmap_write(map: priv->regmap, MT6359_GPIO_MODE4_CLR, val: 0x003f); |
78 | |
79 | regmap_update_bits(map: priv->regmap, MT6359_GPIO_DIR0, |
80 | mask: 0x7 << 13, val: 0x0); |
81 | regmap_update_bits(map: priv->regmap, MT6359_GPIO_DIR1, |
82 | mask: 0x3 << 0, val: 0x0); |
83 | } |
84 | |
85 | /* use only when doing mtkaif calibraiton at the boot time */ |
86 | static void mt6359_set_dcxo(struct mt6359_priv *priv, bool enable) |
87 | { |
88 | regmap_update_bits(map: priv->regmap, MT6359_DCXO_CW12, |
89 | mask: 0x1 << RG_XO_AUDIO_EN_M_SFT, |
90 | val: (enable ? 1 : 0) << RG_XO_AUDIO_EN_M_SFT); |
91 | } |
92 | |
93 | /* use only when doing mtkaif calibraiton at the boot time */ |
94 | static void mt6359_set_clksq(struct mt6359_priv *priv, bool enable) |
95 | { |
96 | /* Enable/disable CLKSQ 26MHz */ |
97 | regmap_update_bits(map: priv->regmap, MT6359_AUDENC_ANA_CON23, |
98 | RG_CLKSQ_EN_MASK_SFT, |
99 | val: (enable ? 1 : 0) << RG_CLKSQ_EN_SFT); |
100 | } |
101 | |
102 | /* use only when doing mtkaif calibraiton at the boot time */ |
103 | static void mt6359_set_aud_global_bias(struct mt6359_priv *priv, bool enable) |
104 | { |
105 | regmap_update_bits(map: priv->regmap, MT6359_AUDDEC_ANA_CON13, |
106 | RG_AUDGLB_PWRDN_VA32_MASK_SFT, |
107 | val: (enable ? 0 : 1) << RG_AUDGLB_PWRDN_VA32_SFT); |
108 | } |
109 | |
110 | /* use only when doing mtkaif calibraiton at the boot time */ |
111 | static void mt6359_set_topck(struct mt6359_priv *priv, bool enable) |
112 | { |
113 | regmap_update_bits(map: priv->regmap, MT6359_AUD_TOP_CKPDN_CON0, |
114 | mask: 0x0066, val: enable ? 0x0 : 0x66); |
115 | } |
116 | |
117 | static void mt6359_set_decoder_clk(struct mt6359_priv *priv, bool enable) |
118 | { |
119 | regmap_update_bits(map: priv->regmap, MT6359_AUDDEC_ANA_CON13, |
120 | RG_RSTB_DECODER_VA32_MASK_SFT, |
121 | val: (enable ? 1 : 0) << RG_RSTB_DECODER_VA32_SFT); |
122 | } |
123 | |
124 | static void mt6359_mtkaif_tx_enable(struct mt6359_priv *priv) |
125 | { |
126 | switch (priv->mtkaif_protocol) { |
127 | case MT6359_MTKAIF_PROTOCOL_2_CLK_P2: |
128 | /* MTKAIF TX format setting */ |
129 | regmap_update_bits(map: priv->regmap, |
130 | MT6359_AFE_ADDA_MTKAIF_CFG0, |
131 | mask: 0xffff, val: 0x0210); |
132 | /* enable aud_pad TX fifos */ |
133 | regmap_update_bits(map: priv->regmap, |
134 | MT6359_AFE_AUD_PAD_TOP, |
135 | mask: 0xff00, val: 0x3800); |
136 | regmap_update_bits(map: priv->regmap, |
137 | MT6359_AFE_AUD_PAD_TOP, |
138 | mask: 0xff00, val: 0x3900); |
139 | break; |
140 | case MT6359_MTKAIF_PROTOCOL_2: |
141 | /* MTKAIF TX format setting */ |
142 | regmap_update_bits(map: priv->regmap, |
143 | MT6359_AFE_ADDA_MTKAIF_CFG0, |
144 | mask: 0xffff, val: 0x0210); |
145 | /* enable aud_pad TX fifos */ |
146 | regmap_update_bits(map: priv->regmap, |
147 | MT6359_AFE_AUD_PAD_TOP, |
148 | mask: 0xff00, val: 0x3100); |
149 | break; |
150 | case MT6359_MTKAIF_PROTOCOL_1: |
151 | default: |
152 | /* MTKAIF TX format setting */ |
153 | regmap_update_bits(map: priv->regmap, |
154 | MT6359_AFE_ADDA_MTKAIF_CFG0, |
155 | mask: 0xffff, val: 0x0000); |
156 | /* enable aud_pad TX fifos */ |
157 | regmap_update_bits(map: priv->regmap, |
158 | MT6359_AFE_AUD_PAD_TOP, |
159 | mask: 0xff00, val: 0x3100); |
160 | break; |
161 | } |
162 | } |
163 | |
164 | static void mt6359_mtkaif_tx_disable(struct mt6359_priv *priv) |
165 | { |
166 | /* disable aud_pad TX fifos */ |
167 | regmap_update_bits(map: priv->regmap, MT6359_AFE_AUD_PAD_TOP, |
168 | mask: 0xff00, val: 0x3000); |
169 | } |
170 | |
171 | void mt6359_set_mtkaif_protocol(struct snd_soc_component *cmpnt, |
172 | int mtkaif_protocol) |
173 | { |
174 | struct mt6359_priv *priv = snd_soc_component_get_drvdata(c: cmpnt); |
175 | |
176 | priv->mtkaif_protocol = mtkaif_protocol; |
177 | } |
178 | EXPORT_SYMBOL_GPL(mt6359_set_mtkaif_protocol); |
179 | |
180 | void mt6359_mtkaif_calibration_enable(struct snd_soc_component *cmpnt) |
181 | { |
182 | struct mt6359_priv *priv = snd_soc_component_get_drvdata(c: cmpnt); |
183 | |
184 | mt6359_set_playback_gpio(priv); |
185 | mt6359_set_capture_gpio(priv); |
186 | mt6359_mtkaif_tx_enable(priv); |
187 | |
188 | mt6359_set_dcxo(priv, enable: true); |
189 | mt6359_set_aud_global_bias(priv, enable: true); |
190 | mt6359_set_clksq(priv, enable: true); |
191 | mt6359_set_topck(priv, enable: true); |
192 | |
193 | /* set dat_miso_loopback on */ |
194 | regmap_update_bits(map: priv->regmap, MT6359_AUDIO_DIG_CFG, |
195 | RG_AUD_PAD_TOP_DAT_MISO2_LOOPBACK_MASK_SFT, |
196 | val: 1 << RG_AUD_PAD_TOP_DAT_MISO2_LOOPBACK_SFT); |
197 | regmap_update_bits(map: priv->regmap, MT6359_AUDIO_DIG_CFG, |
198 | RG_AUD_PAD_TOP_DAT_MISO_LOOPBACK_MASK_SFT, |
199 | val: 1 << RG_AUD_PAD_TOP_DAT_MISO_LOOPBACK_SFT); |
200 | regmap_update_bits(map: priv->regmap, MT6359_AUDIO_DIG_CFG1, |
201 | RG_AUD_PAD_TOP_DAT_MISO3_LOOPBACK_MASK_SFT, |
202 | val: 1 << RG_AUD_PAD_TOP_DAT_MISO3_LOOPBACK_SFT); |
203 | } |
204 | EXPORT_SYMBOL_GPL(mt6359_mtkaif_calibration_enable); |
205 | |
206 | void mt6359_mtkaif_calibration_disable(struct snd_soc_component *cmpnt) |
207 | { |
208 | struct mt6359_priv *priv = snd_soc_component_get_drvdata(c: cmpnt); |
209 | |
210 | /* set dat_miso_loopback off */ |
211 | regmap_update_bits(map: priv->regmap, MT6359_AUDIO_DIG_CFG, |
212 | RG_AUD_PAD_TOP_DAT_MISO2_LOOPBACK_MASK_SFT, |
213 | val: 0 << RG_AUD_PAD_TOP_DAT_MISO2_LOOPBACK_SFT); |
214 | regmap_update_bits(map: priv->regmap, MT6359_AUDIO_DIG_CFG, |
215 | RG_AUD_PAD_TOP_DAT_MISO_LOOPBACK_MASK_SFT, |
216 | val: 0 << RG_AUD_PAD_TOP_DAT_MISO_LOOPBACK_SFT); |
217 | regmap_update_bits(map: priv->regmap, MT6359_AUDIO_DIG_CFG1, |
218 | RG_AUD_PAD_TOP_DAT_MISO3_LOOPBACK_MASK_SFT, |
219 | val: 0 << RG_AUD_PAD_TOP_DAT_MISO3_LOOPBACK_SFT); |
220 | |
221 | mt6359_set_topck(priv, enable: false); |
222 | mt6359_set_clksq(priv, enable: false); |
223 | mt6359_set_aud_global_bias(priv, enable: false); |
224 | mt6359_set_dcxo(priv, enable: false); |
225 | |
226 | mt6359_mtkaif_tx_disable(priv); |
227 | mt6359_reset_playback_gpio(priv); |
228 | mt6359_reset_capture_gpio(priv); |
229 | } |
230 | EXPORT_SYMBOL_GPL(mt6359_mtkaif_calibration_disable); |
231 | |
232 | void mt6359_set_mtkaif_calibration_phase(struct snd_soc_component *cmpnt, |
233 | int phase_1, int phase_2, int phase_3) |
234 | { |
235 | struct mt6359_priv *priv = snd_soc_component_get_drvdata(c: cmpnt); |
236 | |
237 | regmap_update_bits(map: priv->regmap, MT6359_AUDIO_DIG_CFG, |
238 | RG_AUD_PAD_TOP_PHASE_MODE_MASK_SFT, |
239 | val: phase_1 << RG_AUD_PAD_TOP_PHASE_MODE_SFT); |
240 | regmap_update_bits(map: priv->regmap, MT6359_AUDIO_DIG_CFG, |
241 | RG_AUD_PAD_TOP_PHASE_MODE2_MASK_SFT, |
242 | val: phase_2 << RG_AUD_PAD_TOP_PHASE_MODE2_SFT); |
243 | regmap_update_bits(map: priv->regmap, MT6359_AUDIO_DIG_CFG1, |
244 | RG_AUD_PAD_TOP_PHASE_MODE3_MASK_SFT, |
245 | val: phase_3 << RG_AUD_PAD_TOP_PHASE_MODE3_SFT); |
246 | } |
247 | EXPORT_SYMBOL_GPL(mt6359_set_mtkaif_calibration_phase); |
248 | |
249 | static void zcd_disable(struct mt6359_priv *priv) |
250 | { |
251 | regmap_write(map: priv->regmap, MT6359_ZCD_CON0, val: 0x0000); |
252 | } |
253 | |
254 | static void hp_main_output_ramp(struct mt6359_priv *priv, bool up) |
255 | { |
256 | int i, stage; |
257 | int target = 7; |
258 | |
259 | /* Enable/Reduce HPL/R main output stage step by step */ |
260 | for (i = 0; i <= target; i++) { |
261 | stage = up ? i : target - i; |
262 | regmap_update_bits(map: priv->regmap, MT6359_AUDDEC_ANA_CON1, |
263 | RG_HPLOUTSTGCTRL_VAUDP32_MASK_SFT, |
264 | val: stage << RG_HPLOUTSTGCTRL_VAUDP32_SFT); |
265 | regmap_update_bits(map: priv->regmap, MT6359_AUDDEC_ANA_CON1, |
266 | RG_HPROUTSTGCTRL_VAUDP32_MASK_SFT, |
267 | val: stage << RG_HPROUTSTGCTRL_VAUDP32_SFT); |
268 | usleep_range(min: 600, max: 650); |
269 | } |
270 | } |
271 | |
272 | static void hp_aux_feedback_loop_gain_ramp(struct mt6359_priv *priv, bool up) |
273 | { |
274 | int i, stage; |
275 | int target = 0xf; |
276 | |
277 | /* Enable/Reduce HP aux feedback loop gain step by step */ |
278 | for (i = 0; i <= target; i++) { |
279 | stage = up ? i : target - i; |
280 | regmap_update_bits(map: priv->regmap, MT6359_AUDDEC_ANA_CON9, |
281 | mask: 0xf << 12, val: stage << 12); |
282 | usleep_range(min: 600, max: 650); |
283 | } |
284 | } |
285 | |
286 | static void hp_in_pair_current(struct mt6359_priv *priv, bool increase) |
287 | { |
288 | int i, stage; |
289 | int target = 0x3; |
290 | |
291 | /* Set input diff pair bias select (Hi-Fi mode) */ |
292 | if (priv->hp_hifi_mode) { |
293 | /* Reduce HP aux feedback loop gain step by step */ |
294 | for (i = 0; i <= target; i++) { |
295 | stage = increase ? i : target - i; |
296 | regmap_update_bits(map: priv->regmap, |
297 | MT6359_AUDDEC_ANA_CON10, |
298 | mask: 0x3 << 3, val: stage << 3); |
299 | usleep_range(min: 100, max: 150); |
300 | } |
301 | } |
302 | } |
303 | |
304 | static void hp_pull_down(struct mt6359_priv *priv, bool enable) |
305 | { |
306 | int i; |
307 | |
308 | if (enable) { |
309 | for (i = 0x0; i <= 0x7; i++) { |
310 | regmap_update_bits(map: priv->regmap, MT6359_AUDDEC_ANA_CON2, |
311 | RG_HPPSHORT2VCM_VAUDP32_MASK_SFT, |
312 | val: i << RG_HPPSHORT2VCM_VAUDP32_SFT); |
313 | usleep_range(min: 100, max: 150); |
314 | } |
315 | } else { |
316 | for (i = 0x7; i >= 0x0; i--) { |
317 | regmap_update_bits(map: priv->regmap, MT6359_AUDDEC_ANA_CON2, |
318 | RG_HPPSHORT2VCM_VAUDP32_MASK_SFT, |
319 | val: i << RG_HPPSHORT2VCM_VAUDP32_SFT); |
320 | usleep_range(min: 100, max: 150); |
321 | } |
322 | } |
323 | } |
324 | |
325 | static bool is_valid_hp_pga_idx(int reg_idx) |
326 | { |
327 | return (reg_idx >= DL_GAIN_8DB && reg_idx <= DL_GAIN_N_22DB) || |
328 | reg_idx == DL_GAIN_N_40DB; |
329 | } |
330 | |
331 | static void headset_volume_ramp(struct mt6359_priv *priv, |
332 | int from, int to) |
333 | { |
334 | int offset = 0, count = 1, reg_idx; |
335 | |
336 | if (!is_valid_hp_pga_idx(reg_idx: from) || !is_valid_hp_pga_idx(reg_idx: to)) { |
337 | dev_warn(priv->dev, "%s(), volume index is not valid, from %d, to %d\n" , |
338 | __func__, from, to); |
339 | return; |
340 | } |
341 | |
342 | dev_dbg(priv->dev, "%s(), from %d, to %d\n" , __func__, from, to); |
343 | |
344 | if (to > from) |
345 | offset = to - from; |
346 | else |
347 | offset = from - to; |
348 | |
349 | while (offset > 0) { |
350 | if (to > from) |
351 | reg_idx = from + count; |
352 | else |
353 | reg_idx = from - count; |
354 | |
355 | if (is_valid_hp_pga_idx(reg_idx)) { |
356 | regmap_update_bits(map: priv->regmap, |
357 | MT6359_ZCD_CON2, |
358 | DL_GAIN_REG_MASK, |
359 | val: (reg_idx << 7) | reg_idx); |
360 | usleep_range(min: 600, max: 650); |
361 | } |
362 | offset--; |
363 | count++; |
364 | } |
365 | } |
366 | |
367 | static int mt6359_put_volsw(struct snd_kcontrol *kcontrol, |
368 | struct snd_ctl_elem_value *ucontrol) |
369 | { |
370 | struct snd_soc_component *component = |
371 | snd_soc_kcontrol_component(kcontrol); |
372 | struct mt6359_priv *priv = snd_soc_component_get_drvdata(c: component); |
373 | struct soc_mixer_control *mc = |
374 | (struct soc_mixer_control *)kcontrol->private_value; |
375 | unsigned int reg = 0; |
376 | int index = ucontrol->value.integer.value[0]; |
377 | int orig_gain[2], new_gain[2]; |
378 | int ret; |
379 | |
380 | switch (mc->reg) { |
381 | case MT6359_ZCD_CON2: |
382 | orig_gain[0] = priv->ana_gain[AUDIO_ANALOG_VOLUME_HPOUTL]; |
383 | orig_gain[1] = priv->ana_gain[AUDIO_ANALOG_VOLUME_HPOUTR]; |
384 | break; |
385 | case MT6359_ZCD_CON1: |
386 | orig_gain[0] = priv->ana_gain[AUDIO_ANALOG_VOLUME_LINEOUTL]; |
387 | orig_gain[1] = priv->ana_gain[AUDIO_ANALOG_VOLUME_LINEOUTR]; |
388 | break; |
389 | case MT6359_ZCD_CON3: |
390 | orig_gain[0] = priv->ana_gain[AUDIO_ANALOG_VOLUME_HSOUTL]; |
391 | break; |
392 | case MT6359_AUDENC_ANA_CON0: |
393 | orig_gain[0] = priv->ana_gain[AUDIO_ANALOG_VOLUME_MICAMP1]; |
394 | break; |
395 | case MT6359_AUDENC_ANA_CON1: |
396 | orig_gain[0] = priv->ana_gain[AUDIO_ANALOG_VOLUME_MICAMP2]; |
397 | break; |
398 | case MT6359_AUDENC_ANA_CON2: |
399 | orig_gain[0] = priv->ana_gain[AUDIO_ANALOG_VOLUME_MICAMP3]; |
400 | break; |
401 | default: |
402 | return -EINVAL; |
403 | } |
404 | |
405 | ret = snd_soc_put_volsw(kcontrol, ucontrol); |
406 | if (ret < 0) |
407 | return ret; |
408 | |
409 | switch (mc->reg) { |
410 | case MT6359_ZCD_CON2: |
411 | regmap_read(map: priv->regmap, MT6359_ZCD_CON2, val: ®); |
412 | priv->ana_gain[AUDIO_ANALOG_VOLUME_HPOUTL] = |
413 | (reg >> RG_AUDHPLGAIN_SFT) & RG_AUDHPLGAIN_MASK; |
414 | priv->ana_gain[AUDIO_ANALOG_VOLUME_HPOUTR] = |
415 | (reg >> RG_AUDHPRGAIN_SFT) & RG_AUDHPRGAIN_MASK; |
416 | new_gain[0] = priv->ana_gain[AUDIO_ANALOG_VOLUME_HPOUTL]; |
417 | new_gain[1] = priv->ana_gain[AUDIO_ANALOG_VOLUME_HPOUTR]; |
418 | break; |
419 | case MT6359_ZCD_CON1: |
420 | regmap_read(map: priv->regmap, MT6359_ZCD_CON1, val: ®); |
421 | priv->ana_gain[AUDIO_ANALOG_VOLUME_LINEOUTL] = |
422 | (reg >> RG_AUDLOLGAIN_SFT) & RG_AUDLOLGAIN_MASK; |
423 | priv->ana_gain[AUDIO_ANALOG_VOLUME_LINEOUTR] = |
424 | (reg >> RG_AUDLORGAIN_SFT) & RG_AUDLORGAIN_MASK; |
425 | new_gain[0] = priv->ana_gain[AUDIO_ANALOG_VOLUME_LINEOUTL]; |
426 | new_gain[1] = priv->ana_gain[AUDIO_ANALOG_VOLUME_LINEOUTR]; |
427 | break; |
428 | case MT6359_ZCD_CON3: |
429 | regmap_read(map: priv->regmap, MT6359_ZCD_CON3, val: ®); |
430 | priv->ana_gain[AUDIO_ANALOG_VOLUME_HSOUTL] = |
431 | (reg >> RG_AUDHSGAIN_SFT) & RG_AUDHSGAIN_MASK; |
432 | new_gain[0] = priv->ana_gain[AUDIO_ANALOG_VOLUME_HSOUTL]; |
433 | break; |
434 | case MT6359_AUDENC_ANA_CON0: |
435 | regmap_read(map: priv->regmap, MT6359_AUDENC_ANA_CON0, val: ®); |
436 | priv->ana_gain[AUDIO_ANALOG_VOLUME_MICAMP1] = |
437 | (reg >> RG_AUDPREAMPLGAIN_SFT) & RG_AUDPREAMPLGAIN_MASK; |
438 | new_gain[0] = priv->ana_gain[AUDIO_ANALOG_VOLUME_MICAMP1]; |
439 | break; |
440 | case MT6359_AUDENC_ANA_CON1: |
441 | regmap_read(map: priv->regmap, MT6359_AUDENC_ANA_CON1, val: ®); |
442 | priv->ana_gain[AUDIO_ANALOG_VOLUME_MICAMP2] = |
443 | (reg >> RG_AUDPREAMPRGAIN_SFT) & RG_AUDPREAMPRGAIN_MASK; |
444 | new_gain[0] = priv->ana_gain[AUDIO_ANALOG_VOLUME_MICAMP2]; |
445 | break; |
446 | case MT6359_AUDENC_ANA_CON2: |
447 | regmap_read(map: priv->regmap, MT6359_AUDENC_ANA_CON2, val: ®); |
448 | priv->ana_gain[AUDIO_ANALOG_VOLUME_MICAMP3] = |
449 | (reg >> RG_AUDPREAMP3GAIN_SFT) & RG_AUDPREAMP3GAIN_MASK; |
450 | new_gain[0] = priv->ana_gain[AUDIO_ANALOG_VOLUME_MICAMP3]; |
451 | break; |
452 | } |
453 | |
454 | ret = 0; |
455 | if (orig_gain[0] != new_gain[0]) { |
456 | ret = 1; |
457 | } else if (snd_soc_volsw_is_stereo(mc)) { |
458 | if (orig_gain[1] != new_gain[1]) |
459 | ret = 1; |
460 | } |
461 | |
462 | dev_dbg(priv->dev, "%s(), name %s, reg(0x%x) = 0x%x, set index = %x\n" , |
463 | __func__, kcontrol->id.name, mc->reg, reg, index); |
464 | |
465 | return ret; |
466 | } |
467 | |
468 | static int mt6359_get_playback_volsw(struct snd_kcontrol *kcontrol, |
469 | struct snd_ctl_elem_value *ucontrol) |
470 | { |
471 | struct snd_soc_component *component = |
472 | snd_soc_kcontrol_component(kcontrol); |
473 | struct mt6359_priv *priv = snd_soc_component_get_drvdata(c: component); |
474 | struct soc_mixer_control *mc = |
475 | (struct soc_mixer_control *)kcontrol->private_value; |
476 | |
477 | switch (mc->reg) { |
478 | case MT6359_ZCD_CON2: |
479 | ucontrol->value.integer.value[0] = |
480 | priv->ana_gain[AUDIO_ANALOG_VOLUME_HPOUTL]; |
481 | ucontrol->value.integer.value[1] = |
482 | priv->ana_gain[AUDIO_ANALOG_VOLUME_HPOUTR]; |
483 | break; |
484 | case MT6359_ZCD_CON1: |
485 | ucontrol->value.integer.value[0] = |
486 | priv->ana_gain[AUDIO_ANALOG_VOLUME_LINEOUTL]; |
487 | ucontrol->value.integer.value[1] = |
488 | priv->ana_gain[AUDIO_ANALOG_VOLUME_LINEOUTR]; |
489 | break; |
490 | case MT6359_ZCD_CON3: |
491 | ucontrol->value.integer.value[0] = |
492 | priv->ana_gain[AUDIO_ANALOG_VOLUME_HSOUTL]; |
493 | break; |
494 | default: |
495 | return -EINVAL; |
496 | } |
497 | |
498 | return 0; |
499 | } |
500 | |
501 | /* MUX */ |
502 | |
503 | /* LOL MUX */ |
504 | static const char * const lo_in_mux_map[] = { |
505 | "Open" , "Playback_L_DAC" , "Playback" , "Test Mode" |
506 | }; |
507 | |
508 | static SOC_ENUM_SINGLE_DECL(lo_in_mux_map_enum, SND_SOC_NOPM, 0, lo_in_mux_map); |
509 | |
510 | static const struct snd_kcontrol_new lo_in_mux_control = |
511 | SOC_DAPM_ENUM("LO Select" , lo_in_mux_map_enum); |
512 | |
513 | /*HP MUX */ |
514 | static const char * const hp_in_mux_map[] = { |
515 | "Open" , |
516 | "LoudSPK Playback" , |
517 | "Audio Playback" , |
518 | "Test Mode" , |
519 | "HP Impedance" , |
520 | }; |
521 | |
522 | static SOC_ENUM_SINGLE_DECL(hp_in_mux_map_enum, |
523 | SND_SOC_NOPM, |
524 | 0, |
525 | hp_in_mux_map); |
526 | |
527 | static const struct snd_kcontrol_new hp_in_mux_control = |
528 | SOC_DAPM_ENUM("HP Select" , hp_in_mux_map_enum); |
529 | |
530 | /* RCV MUX */ |
531 | static const char * const rcv_in_mux_map[] = { |
532 | "Open" , "Mute" , "Voice Playback" , "Test Mode" |
533 | }; |
534 | |
535 | static SOC_ENUM_SINGLE_DECL(rcv_in_mux_map_enum, |
536 | SND_SOC_NOPM, |
537 | 0, |
538 | rcv_in_mux_map); |
539 | |
540 | static const struct snd_kcontrol_new rcv_in_mux_control = |
541 | SOC_DAPM_ENUM("RCV Select" , rcv_in_mux_map_enum); |
542 | |
543 | /* DAC In MUX */ |
544 | static const char * const dac_in_mux_map[] = { |
545 | "Normal Path" , "Sgen" |
546 | }; |
547 | |
548 | static int dac_in_mux_map_value[] = { |
549 | 0x0, 0x1, |
550 | }; |
551 | |
552 | static SOC_VALUE_ENUM_SINGLE_DECL(dac_in_mux_map_enum, |
553 | MT6359_AFE_TOP_CON0, |
554 | DL_SINE_ON_SFT, |
555 | DL_SINE_ON_MASK, |
556 | dac_in_mux_map, |
557 | dac_in_mux_map_value); |
558 | |
559 | static const struct snd_kcontrol_new dac_in_mux_control = |
560 | SOC_DAPM_ENUM("DAC Select" , dac_in_mux_map_enum); |
561 | |
562 | /* AIF Out MUX */ |
563 | static SOC_VALUE_ENUM_SINGLE_DECL(aif_out_mux_map_enum, |
564 | MT6359_AFE_TOP_CON0, |
565 | UL_SINE_ON_SFT, |
566 | UL_SINE_ON_MASK, |
567 | dac_in_mux_map, |
568 | dac_in_mux_map_value); |
569 | |
570 | static const struct snd_kcontrol_new aif_out_mux_control = |
571 | SOC_DAPM_ENUM("AIF Out Select" , aif_out_mux_map_enum); |
572 | |
573 | static SOC_VALUE_ENUM_SINGLE_DECL(aif2_out_mux_map_enum, |
574 | MT6359_AFE_TOP_CON0, |
575 | ADDA6_UL_SINE_ON_SFT, |
576 | ADDA6_UL_SINE_ON_MASK, |
577 | dac_in_mux_map, |
578 | dac_in_mux_map_value); |
579 | |
580 | static const struct snd_kcontrol_new aif2_out_mux_control = |
581 | SOC_DAPM_ENUM("AIF Out Select" , aif2_out_mux_map_enum); |
582 | |
583 | static const char * const ul_src_mux_map[] = { |
584 | "AMIC" , |
585 | "DMIC" , |
586 | }; |
587 | |
588 | static int ul_src_mux_map_value[] = { |
589 | UL_SRC_MUX_AMIC, |
590 | UL_SRC_MUX_DMIC, |
591 | }; |
592 | |
593 | static SOC_VALUE_ENUM_SINGLE_DECL(ul_src_mux_map_enum, |
594 | MT6359_AFE_UL_SRC_CON0_L, |
595 | UL_SDM_3_LEVEL_CTL_SFT, |
596 | UL_SDM_3_LEVEL_CTL_MASK, |
597 | ul_src_mux_map, |
598 | ul_src_mux_map_value); |
599 | |
600 | static const struct snd_kcontrol_new ul_src_mux_control = |
601 | SOC_DAPM_ENUM("UL_SRC_MUX Select" , ul_src_mux_map_enum); |
602 | |
603 | static SOC_VALUE_ENUM_SINGLE_DECL(ul2_src_mux_map_enum, |
604 | MT6359_AFE_ADDA6_UL_SRC_CON0_L, |
605 | ADDA6_UL_SDM_3_LEVEL_CTL_SFT, |
606 | ADDA6_UL_SDM_3_LEVEL_CTL_MASK, |
607 | ul_src_mux_map, |
608 | ul_src_mux_map_value); |
609 | |
610 | static const struct snd_kcontrol_new ul2_src_mux_control = |
611 | SOC_DAPM_ENUM("UL_SRC_MUX Select" , ul2_src_mux_map_enum); |
612 | |
613 | static const char * const miso_mux_map[] = { |
614 | "UL1_CH1" , |
615 | "UL1_CH2" , |
616 | "UL2_CH1" , |
617 | "UL2_CH2" , |
618 | }; |
619 | |
620 | static int miso_mux_map_value[] = { |
621 | MISO_MUX_UL1_CH1, |
622 | MISO_MUX_UL1_CH2, |
623 | MISO_MUX_UL2_CH1, |
624 | MISO_MUX_UL2_CH2, |
625 | }; |
626 | |
627 | static SOC_VALUE_ENUM_SINGLE_DECL(miso0_mux_map_enum, |
628 | MT6359_AFE_MTKAIF_MUX_CFG, |
629 | RG_ADDA_CH1_SEL_SFT, |
630 | RG_ADDA_CH1_SEL_MASK, |
631 | miso_mux_map, |
632 | miso_mux_map_value); |
633 | |
634 | static const struct snd_kcontrol_new miso0_mux_control = |
635 | SOC_DAPM_ENUM("MISO_MUX Select" , miso0_mux_map_enum); |
636 | |
637 | static SOC_VALUE_ENUM_SINGLE_DECL(miso1_mux_map_enum, |
638 | MT6359_AFE_MTKAIF_MUX_CFG, |
639 | RG_ADDA_CH2_SEL_SFT, |
640 | RG_ADDA_CH2_SEL_MASK, |
641 | miso_mux_map, |
642 | miso_mux_map_value); |
643 | |
644 | static const struct snd_kcontrol_new miso1_mux_control = |
645 | SOC_DAPM_ENUM("MISO_MUX Select" , miso1_mux_map_enum); |
646 | |
647 | static SOC_VALUE_ENUM_SINGLE_DECL(miso2_mux_map_enum, |
648 | MT6359_AFE_MTKAIF_MUX_CFG, |
649 | RG_ADDA6_CH1_SEL_SFT, |
650 | RG_ADDA6_CH1_SEL_MASK, |
651 | miso_mux_map, |
652 | miso_mux_map_value); |
653 | |
654 | static const struct snd_kcontrol_new miso2_mux_control = |
655 | SOC_DAPM_ENUM("MISO_MUX Select" , miso2_mux_map_enum); |
656 | |
657 | static const char * const dmic_mux_map[] = { |
658 | "DMIC_DATA0" , |
659 | "DMIC_DATA1_L" , |
660 | "DMIC_DATA1_L_1" , |
661 | "DMIC_DATA1_R" , |
662 | }; |
663 | |
664 | static int dmic_mux_map_value[] = { |
665 | DMIC_MUX_DMIC_DATA0, |
666 | DMIC_MUX_DMIC_DATA1_L, |
667 | DMIC_MUX_DMIC_DATA1_L_1, |
668 | DMIC_MUX_DMIC_DATA1_R, |
669 | }; |
670 | |
671 | static SOC_VALUE_ENUM_SINGLE_DECL(dmic0_mux_map_enum, |
672 | MT6359_AFE_MIC_ARRAY_CFG, |
673 | RG_DMIC_ADC1_SOURCE_SEL_SFT, |
674 | RG_DMIC_ADC1_SOURCE_SEL_MASK, |
675 | dmic_mux_map, |
676 | dmic_mux_map_value); |
677 | |
678 | static const struct snd_kcontrol_new dmic0_mux_control = |
679 | SOC_DAPM_ENUM("DMIC_MUX Select" , dmic0_mux_map_enum); |
680 | |
681 | /* ul1 ch2 use RG_DMIC_ADC3_SOURCE_SEL */ |
682 | static SOC_VALUE_ENUM_SINGLE_DECL(dmic1_mux_map_enum, |
683 | MT6359_AFE_MIC_ARRAY_CFG, |
684 | RG_DMIC_ADC3_SOURCE_SEL_SFT, |
685 | RG_DMIC_ADC3_SOURCE_SEL_MASK, |
686 | dmic_mux_map, |
687 | dmic_mux_map_value); |
688 | |
689 | static const struct snd_kcontrol_new dmic1_mux_control = |
690 | SOC_DAPM_ENUM("DMIC_MUX Select" , dmic1_mux_map_enum); |
691 | |
692 | /* ul2 ch1 use RG_DMIC_ADC2_SOURCE_SEL */ |
693 | static SOC_VALUE_ENUM_SINGLE_DECL(dmic2_mux_map_enum, |
694 | MT6359_AFE_MIC_ARRAY_CFG, |
695 | RG_DMIC_ADC2_SOURCE_SEL_SFT, |
696 | RG_DMIC_ADC2_SOURCE_SEL_MASK, |
697 | dmic_mux_map, |
698 | dmic_mux_map_value); |
699 | |
700 | static const struct snd_kcontrol_new dmic2_mux_control = |
701 | SOC_DAPM_ENUM("DMIC_MUX Select" , dmic2_mux_map_enum); |
702 | |
703 | /* ADC L MUX */ |
704 | static const char * const adc_left_mux_map[] = { |
705 | "Idle" , "AIN0" , "Left Preamplifier" , "Idle_1" |
706 | }; |
707 | |
708 | static int adc_mux_map_value[] = { |
709 | ADC_MUX_IDLE, |
710 | ADC_MUX_AIN0, |
711 | ADC_MUX_PREAMPLIFIER, |
712 | ADC_MUX_IDLE1, |
713 | }; |
714 | |
715 | static SOC_VALUE_ENUM_SINGLE_DECL(adc_left_mux_map_enum, |
716 | MT6359_AUDENC_ANA_CON0, |
717 | RG_AUDADCLINPUTSEL_SFT, |
718 | RG_AUDADCLINPUTSEL_MASK, |
719 | adc_left_mux_map, |
720 | adc_mux_map_value); |
721 | |
722 | static const struct snd_kcontrol_new adc_left_mux_control = |
723 | SOC_DAPM_ENUM("ADC L Select" , adc_left_mux_map_enum); |
724 | |
725 | /* ADC R MUX */ |
726 | static const char * const adc_right_mux_map[] = { |
727 | "Idle" , "AIN0" , "Right Preamplifier" , "Idle_1" |
728 | }; |
729 | |
730 | static SOC_VALUE_ENUM_SINGLE_DECL(adc_right_mux_map_enum, |
731 | MT6359_AUDENC_ANA_CON1, |
732 | RG_AUDADCRINPUTSEL_SFT, |
733 | RG_AUDADCRINPUTSEL_MASK, |
734 | adc_right_mux_map, |
735 | adc_mux_map_value); |
736 | |
737 | static const struct snd_kcontrol_new adc_right_mux_control = |
738 | SOC_DAPM_ENUM("ADC R Select" , adc_right_mux_map_enum); |
739 | |
740 | /* ADC 3 MUX */ |
741 | static const char * const adc_3_mux_map[] = { |
742 | "Idle" , "AIN0" , "Preamplifier" , "Idle_1" |
743 | }; |
744 | |
745 | static SOC_VALUE_ENUM_SINGLE_DECL(adc_3_mux_map_enum, |
746 | MT6359_AUDENC_ANA_CON2, |
747 | RG_AUDADC3INPUTSEL_SFT, |
748 | RG_AUDADC3INPUTSEL_MASK, |
749 | adc_3_mux_map, |
750 | adc_mux_map_value); |
751 | |
752 | static const struct snd_kcontrol_new adc_3_mux_control = |
753 | SOC_DAPM_ENUM("ADC 3 Select" , adc_3_mux_map_enum); |
754 | |
755 | static const char * const pga_l_mux_map[] = { |
756 | "None" , "AIN0" , "AIN1" |
757 | }; |
758 | |
759 | static int pga_l_mux_map_value[] = { |
760 | PGA_L_MUX_NONE, |
761 | PGA_L_MUX_AIN0, |
762 | PGA_L_MUX_AIN1 |
763 | }; |
764 | |
765 | static SOC_VALUE_ENUM_SINGLE_DECL(pga_left_mux_map_enum, |
766 | MT6359_AUDENC_ANA_CON0, |
767 | RG_AUDPREAMPLINPUTSEL_SFT, |
768 | RG_AUDPREAMPLINPUTSEL_MASK, |
769 | pga_l_mux_map, |
770 | pga_l_mux_map_value); |
771 | |
772 | static const struct snd_kcontrol_new pga_left_mux_control = |
773 | SOC_DAPM_ENUM("PGA L Select" , pga_left_mux_map_enum); |
774 | |
775 | static const char * const pga_r_mux_map[] = { |
776 | "None" , "AIN2" , "AIN3" , "AIN0" |
777 | }; |
778 | |
779 | static int pga_r_mux_map_value[] = { |
780 | PGA_R_MUX_NONE, |
781 | PGA_R_MUX_AIN2, |
782 | PGA_R_MUX_AIN3, |
783 | PGA_R_MUX_AIN0 |
784 | }; |
785 | |
786 | static SOC_VALUE_ENUM_SINGLE_DECL(pga_right_mux_map_enum, |
787 | MT6359_AUDENC_ANA_CON1, |
788 | RG_AUDPREAMPRINPUTSEL_SFT, |
789 | RG_AUDPREAMPRINPUTSEL_MASK, |
790 | pga_r_mux_map, |
791 | pga_r_mux_map_value); |
792 | |
793 | static const struct snd_kcontrol_new pga_right_mux_control = |
794 | SOC_DAPM_ENUM("PGA R Select" , pga_right_mux_map_enum); |
795 | |
796 | static const char * const pga_3_mux_map[] = { |
797 | "None" , "AIN3" , "AIN2" |
798 | }; |
799 | |
800 | static int pga_3_mux_map_value[] = { |
801 | PGA_3_MUX_NONE, |
802 | PGA_3_MUX_AIN3, |
803 | PGA_3_MUX_AIN2 |
804 | }; |
805 | |
806 | static SOC_VALUE_ENUM_SINGLE_DECL(pga_3_mux_map_enum, |
807 | MT6359_AUDENC_ANA_CON2, |
808 | RG_AUDPREAMP3INPUTSEL_SFT, |
809 | RG_AUDPREAMP3INPUTSEL_MASK, |
810 | pga_3_mux_map, |
811 | pga_3_mux_map_value); |
812 | |
813 | static const struct snd_kcontrol_new pga_3_mux_control = |
814 | SOC_DAPM_ENUM("PGA 3 Select" , pga_3_mux_map_enum); |
815 | |
816 | static int mt_sgen_event(struct snd_soc_dapm_widget *w, |
817 | struct snd_kcontrol *kcontrol, |
818 | int event) |
819 | { |
820 | struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(dapm: w->dapm); |
821 | struct mt6359_priv *priv = snd_soc_component_get_drvdata(c: cmpnt); |
822 | |
823 | dev_dbg(priv->dev, "%s(), event = 0x%x\n" , __func__, event); |
824 | |
825 | switch (event) { |
826 | case SND_SOC_DAPM_PRE_PMU: |
827 | /* sdm audio fifo clock power on */ |
828 | regmap_write(map: priv->regmap, MT6359_AFUNC_AUD_CON2, val: 0x0006); |
829 | /* scrambler clock on enable */ |
830 | regmap_write(map: priv->regmap, MT6359_AFUNC_AUD_CON0, val: 0xcba1); |
831 | /* sdm power on */ |
832 | regmap_write(map: priv->regmap, MT6359_AFUNC_AUD_CON2, val: 0x0003); |
833 | /* sdm fifo enable */ |
834 | regmap_write(map: priv->regmap, MT6359_AFUNC_AUD_CON2, val: 0x000b); |
835 | |
836 | regmap_update_bits(map: priv->regmap, MT6359_AFE_SGEN_CFG0, |
837 | mask: 0xff3f, |
838 | val: 0x0000); |
839 | regmap_update_bits(map: priv->regmap, MT6359_AFE_SGEN_CFG1, |
840 | mask: 0xffff, |
841 | val: 0x0001); |
842 | break; |
843 | case SND_SOC_DAPM_POST_PMD: |
844 | /* DL scrambler disabling sequence */ |
845 | regmap_write(map: priv->regmap, MT6359_AFUNC_AUD_CON2, val: 0x0000); |
846 | regmap_write(map: priv->regmap, MT6359_AFUNC_AUD_CON0, val: 0xcba0); |
847 | break; |
848 | default: |
849 | break; |
850 | } |
851 | |
852 | return 0; |
853 | } |
854 | |
855 | static void mtk_hp_enable(struct mt6359_priv *priv) |
856 | { |
857 | if (priv->hp_hifi_mode) { |
858 | /* Set HP DR bias current optimization, 010: 6uA */ |
859 | regmap_update_bits(map: priv->regmap, MT6359_AUDDEC_ANA_CON11, |
860 | DRBIAS_HP_MASK_SFT, |
861 | val: DRBIAS_6UA << DRBIAS_HP_SFT); |
862 | /* Set HP & ZCD bias current optimization */ |
863 | /* 01: ZCD: 4uA, HP/HS/LO: 5uA */ |
864 | regmap_update_bits(map: priv->regmap, MT6359_AUDDEC_ANA_CON12, |
865 | IBIAS_ZCD_MASK_SFT, |
866 | val: IBIAS_ZCD_4UA << IBIAS_ZCD_SFT); |
867 | regmap_update_bits(map: priv->regmap, MT6359_AUDDEC_ANA_CON12, |
868 | IBIAS_HP_MASK_SFT, |
869 | val: IBIAS_5UA << IBIAS_HP_SFT); |
870 | } else { |
871 | /* Set HP DR bias current optimization, 001: 5uA */ |
872 | regmap_update_bits(map: priv->regmap, MT6359_AUDDEC_ANA_CON11, |
873 | DRBIAS_HP_MASK_SFT, |
874 | val: DRBIAS_5UA << DRBIAS_HP_SFT); |
875 | /* Set HP & ZCD bias current optimization */ |
876 | /* 00: ZCD: 3uA, HP/HS/LO: 4uA */ |
877 | regmap_update_bits(map: priv->regmap, MT6359_AUDDEC_ANA_CON12, |
878 | IBIAS_ZCD_MASK_SFT, |
879 | val: IBIAS_ZCD_3UA << IBIAS_ZCD_SFT); |
880 | regmap_update_bits(map: priv->regmap, MT6359_AUDDEC_ANA_CON12, |
881 | IBIAS_HP_MASK_SFT, |
882 | val: IBIAS_4UA << IBIAS_HP_SFT); |
883 | } |
884 | |
885 | /* HP damp circuit enable */ |
886 | /* Enable HPRN/HPLN output 4K to VCM */ |
887 | regmap_write(map: priv->regmap, MT6359_AUDDEC_ANA_CON10, val: 0x0087); |
888 | |
889 | /* HP Feedback Cap select 2'b00: 15pF */ |
890 | /* for >= 96KHz sampling rate: 2'b01: 10.5pF */ |
891 | if (priv->dl_rate[MT6359_AIF_1] >= 96000) |
892 | regmap_update_bits(map: priv->regmap, |
893 | MT6359_AUDDEC_ANA_CON4, |
894 | RG_AUDHPHFCOMPBUFGAINSEL_VAUDP32_MASK_SFT, |
895 | val: 0x1 << RG_AUDHPHFCOMPBUFGAINSEL_VAUDP32_SFT); |
896 | else |
897 | regmap_write(map: priv->regmap, MT6359_AUDDEC_ANA_CON4, val: 0x0000); |
898 | |
899 | /* Set HPP/N STB enhance circuits */ |
900 | regmap_write(map: priv->regmap, MT6359_AUDDEC_ANA_CON2, val: 0xf133); |
901 | |
902 | /* Enable HP aux output stage */ |
903 | regmap_write(map: priv->regmap, MT6359_AUDDEC_ANA_CON1, val: 0x000c); |
904 | /* Enable HP aux feedback loop */ |
905 | regmap_write(map: priv->regmap, MT6359_AUDDEC_ANA_CON1, val: 0x003c); |
906 | /* Enable HP aux CMFB loop */ |
907 | regmap_write(map: priv->regmap, MT6359_AUDDEC_ANA_CON9, val: 0x0c00); |
908 | /* Enable HP driver bias circuits */ |
909 | regmap_write(map: priv->regmap, MT6359_AUDDEC_ANA_CON0, val: 0x30c0); |
910 | /* Enable HP driver core circuits */ |
911 | regmap_write(map: priv->regmap, MT6359_AUDDEC_ANA_CON0, val: 0x30f0); |
912 | /* Short HP main output to HP aux output stage */ |
913 | regmap_write(map: priv->regmap, MT6359_AUDDEC_ANA_CON1, val: 0x00fc); |
914 | |
915 | /* Increase HP input pair current to HPM step by step */ |
916 | hp_in_pair_current(priv, increase: true); |
917 | |
918 | /* Enable HP main CMFB loop */ |
919 | regmap_write(map: priv->regmap, MT6359_AUDDEC_ANA_CON9, val: 0x0e00); |
920 | /* Disable HP aux CMFB loop */ |
921 | regmap_write(map: priv->regmap, MT6359_AUDDEC_ANA_CON9, val: 0x0200); |
922 | |
923 | /* Enable HP main output stage */ |
924 | regmap_write(map: priv->regmap, MT6359_AUDDEC_ANA_CON1, val: 0x00ff); |
925 | /* Enable HPR/L main output stage step by step */ |
926 | hp_main_output_ramp(priv, up: true); |
927 | |
928 | /* Reduce HP aux feedback loop gain */ |
929 | hp_aux_feedback_loop_gain_ramp(priv, up: true); |
930 | /* Disable HP aux feedback loop */ |
931 | regmap_write(map: priv->regmap, MT6359_AUDDEC_ANA_CON1, val: 0x77cf); |
932 | |
933 | /* apply volume setting */ |
934 | headset_volume_ramp(priv, |
935 | from: DL_GAIN_N_22DB, |
936 | to: priv->ana_gain[AUDIO_ANALOG_VOLUME_HPOUTL]); |
937 | |
938 | /* Disable HP aux output stage */ |
939 | regmap_write(map: priv->regmap, MT6359_AUDDEC_ANA_CON1, val: 0x77c3); |
940 | /* Unshort HP main output to HP aux output stage */ |
941 | regmap_write(map: priv->regmap, MT6359_AUDDEC_ANA_CON1, val: 0x7703); |
942 | usleep_range(min: 100, max: 120); |
943 | |
944 | /* Enable AUD_CLK */ |
945 | mt6359_set_decoder_clk(priv, enable: true); |
946 | |
947 | /* Enable Audio DAC */ |
948 | regmap_write(map: priv->regmap, MT6359_AUDDEC_ANA_CON0, val: 0x30ff); |
949 | if (priv->hp_hifi_mode) { |
950 | /* Enable low-noise mode of DAC */ |
951 | regmap_write(map: priv->regmap, MT6359_AUDDEC_ANA_CON9, val: 0xf201); |
952 | } else { |
953 | /* Disable low-noise mode of DAC */ |
954 | regmap_write(map: priv->regmap, MT6359_AUDDEC_ANA_CON9, val: 0xf200); |
955 | } |
956 | usleep_range(min: 100, max: 120); |
957 | |
958 | /* Switch HPL MUX to audio DAC */ |
959 | regmap_write(map: priv->regmap, MT6359_AUDDEC_ANA_CON0, val: 0x32ff); |
960 | /* Switch HPR MUX to audio DAC */ |
961 | regmap_write(map: priv->regmap, MT6359_AUDDEC_ANA_CON0, val: 0x3aff); |
962 | |
963 | /* Disable Pull-down HPL/R to AVSS28_AUD */ |
964 | hp_pull_down(priv, enable: false); |
965 | } |
966 | |
967 | static void mtk_hp_disable(struct mt6359_priv *priv) |
968 | { |
969 | /* Pull-down HPL/R to AVSS28_AUD */ |
970 | hp_pull_down(priv, enable: true); |
971 | |
972 | /* HPR/HPL mux to open */ |
973 | regmap_update_bits(map: priv->regmap, MT6359_AUDDEC_ANA_CON0, |
974 | mask: 0x0f00, val: 0x0000); |
975 | |
976 | /* Disable low-noise mode of DAC */ |
977 | regmap_update_bits(map: priv->regmap, MT6359_AUDDEC_ANA_CON9, |
978 | mask: 0x0001, val: 0x0000); |
979 | |
980 | /* Disable Audio DAC */ |
981 | regmap_update_bits(map: priv->regmap, MT6359_AUDDEC_ANA_CON0, |
982 | mask: 0x000f, val: 0x0000); |
983 | |
984 | /* Disable AUD_CLK */ |
985 | mt6359_set_decoder_clk(priv, enable: false); |
986 | |
987 | /* Short HP main output to HP aux output stage */ |
988 | regmap_write(map: priv->regmap, MT6359_AUDDEC_ANA_CON1, val: 0x77c3); |
989 | /* Enable HP aux output stage */ |
990 | regmap_write(map: priv->regmap, MT6359_AUDDEC_ANA_CON1, val: 0x77cf); |
991 | |
992 | /* decrease HPL/R gain to normal gain step by step */ |
993 | headset_volume_ramp(priv, |
994 | from: priv->ana_gain[AUDIO_ANALOG_VOLUME_HPOUTL], |
995 | to: DL_GAIN_N_22DB); |
996 | |
997 | /* Enable HP aux feedback loop */ |
998 | regmap_write(map: priv->regmap, MT6359_AUDDEC_ANA_CON1, val: 0x77ff); |
999 | |
1000 | /* Reduce HP aux feedback loop gain */ |
1001 | hp_aux_feedback_loop_gain_ramp(priv, up: false); |
1002 | |
1003 | /* decrease HPR/L main output stage step by step */ |
1004 | hp_main_output_ramp(priv, up: false); |
1005 | |
1006 | /* Disable HP main output stage */ |
1007 | regmap_update_bits(map: priv->regmap, MT6359_AUDDEC_ANA_CON1, mask: 0x3, val: 0x0); |
1008 | |
1009 | /* Enable HP aux CMFB loop */ |
1010 | regmap_write(map: priv->regmap, MT6359_AUDDEC_ANA_CON9, val: 0x0e01); |
1011 | |
1012 | /* Disable HP main CMFB loop */ |
1013 | regmap_write(map: priv->regmap, MT6359_AUDDEC_ANA_CON9, val: 0x0c01); |
1014 | |
1015 | /* Decrease HP input pair current to 2'b00 step by step */ |
1016 | hp_in_pair_current(priv, increase: false); |
1017 | |
1018 | /* Unshort HP main output to HP aux output stage */ |
1019 | regmap_update_bits(map: priv->regmap, MT6359_AUDDEC_ANA_CON1, |
1020 | mask: 0x3 << 6, val: 0x0); |
1021 | |
1022 | /* Disable HP driver core circuits */ |
1023 | regmap_update_bits(map: priv->regmap, MT6359_AUDDEC_ANA_CON0, |
1024 | mask: 0x3 << 4, val: 0x0); |
1025 | |
1026 | /* Disable HP driver bias circuits */ |
1027 | regmap_update_bits(map: priv->regmap, MT6359_AUDDEC_ANA_CON0, |
1028 | mask: 0x3 << 6, val: 0x0); |
1029 | |
1030 | /* Disable HP aux CMFB loop */ |
1031 | regmap_write(map: priv->regmap, MT6359_AUDDEC_ANA_CON9, val: 0x201); |
1032 | |
1033 | /* Disable HP aux feedback loop */ |
1034 | regmap_update_bits(map: priv->regmap, MT6359_AUDDEC_ANA_CON1, |
1035 | mask: 0x3 << 4, val: 0x0); |
1036 | |
1037 | /* Disable HP aux output stage */ |
1038 | regmap_update_bits(map: priv->regmap, MT6359_AUDDEC_ANA_CON1, |
1039 | mask: 0x3 << 2, val: 0x0); |
1040 | } |
1041 | |
1042 | static int mt_hp_event(struct snd_soc_dapm_widget *w, |
1043 | struct snd_kcontrol *kcontrol, |
1044 | int event) |
1045 | { |
1046 | struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(dapm: w->dapm); |
1047 | struct mt6359_priv *priv = snd_soc_component_get_drvdata(c: cmpnt); |
1048 | unsigned int mux = dapm_kcontrol_get_value(kcontrol: w->kcontrols[0]); |
1049 | int device = DEVICE_HP; |
1050 | |
1051 | dev_dbg(priv->dev, "%s(), event 0x%x, dev_counter[DEV_HP] %d, mux %u\n" , |
1052 | __func__, event, priv->dev_counter[device], mux); |
1053 | |
1054 | switch (event) { |
1055 | case SND_SOC_DAPM_PRE_PMU: |
1056 | priv->dev_counter[device]++; |
1057 | if (mux == HP_MUX_HP) |
1058 | mtk_hp_enable(priv); |
1059 | break; |
1060 | case SND_SOC_DAPM_PRE_PMD: |
1061 | priv->dev_counter[device]--; |
1062 | if (mux == HP_MUX_HP) |
1063 | mtk_hp_disable(priv); |
1064 | break; |
1065 | default: |
1066 | break; |
1067 | } |
1068 | |
1069 | return 0; |
1070 | } |
1071 | |
1072 | static int mt_rcv_event(struct snd_soc_dapm_widget *w, |
1073 | struct snd_kcontrol *kcontrol, |
1074 | int event) |
1075 | { |
1076 | struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(dapm: w->dapm); |
1077 | struct mt6359_priv *priv = snd_soc_component_get_drvdata(c: cmpnt); |
1078 | |
1079 | dev_dbg(priv->dev, "%s(), event 0x%x, mux %u\n" , |
1080 | __func__, event, dapm_kcontrol_get_value(w->kcontrols[0])); |
1081 | |
1082 | switch (event) { |
1083 | case SND_SOC_DAPM_PRE_PMU: |
1084 | /* Disable handset short-circuit protection */ |
1085 | regmap_write(map: priv->regmap, MT6359_AUDDEC_ANA_CON6, val: 0x0010); |
1086 | |
1087 | /* Set RCV DR bias current optimization, 010: 6uA */ |
1088 | regmap_update_bits(map: priv->regmap, MT6359_AUDDEC_ANA_CON11, |
1089 | DRBIAS_HS_MASK_SFT, |
1090 | val: DRBIAS_6UA << DRBIAS_HS_SFT); |
1091 | /* Set RCV & ZCD bias current optimization */ |
1092 | /* 01: ZCD: 4uA, HP/HS/LO: 5uA */ |
1093 | regmap_update_bits(map: priv->regmap, MT6359_AUDDEC_ANA_CON12, |
1094 | IBIAS_ZCD_MASK_SFT, |
1095 | val: IBIAS_ZCD_4UA << IBIAS_ZCD_SFT); |
1096 | regmap_update_bits(map: priv->regmap, MT6359_AUDDEC_ANA_CON12, |
1097 | IBIAS_HS_MASK_SFT, |
1098 | val: IBIAS_5UA << IBIAS_HS_SFT); |
1099 | |
1100 | /* Set HS STB enhance circuits */ |
1101 | regmap_write(map: priv->regmap, MT6359_AUDDEC_ANA_CON6, val: 0x0090); |
1102 | |
1103 | /* Set HS output stage (3'b111 = 8x) */ |
1104 | regmap_write(map: priv->regmap, MT6359_AUDDEC_ANA_CON10, val: 0x7000); |
1105 | |
1106 | /* Enable HS driver bias circuits */ |
1107 | regmap_write(map: priv->regmap, MT6359_AUDDEC_ANA_CON6, val: 0x0092); |
1108 | /* Enable HS driver core circuits */ |
1109 | regmap_write(map: priv->regmap, MT6359_AUDDEC_ANA_CON6, val: 0x0093); |
1110 | |
1111 | /* Set HS gain to normal gain step by step */ |
1112 | regmap_write(map: priv->regmap, MT6359_ZCD_CON3, |
1113 | val: priv->ana_gain[AUDIO_ANALOG_VOLUME_HSOUTL]); |
1114 | |
1115 | /* Enable AUD_CLK */ |
1116 | mt6359_set_decoder_clk(priv, enable: true); |
1117 | |
1118 | /* Enable Audio DAC */ |
1119 | regmap_write(map: priv->regmap, MT6359_AUDDEC_ANA_CON0, val: 0x0009); |
1120 | /* Enable low-noise mode of DAC */ |
1121 | regmap_write(map: priv->regmap, MT6359_AUDDEC_ANA_CON9, val: 0x0001); |
1122 | /* Switch HS MUX to audio DAC */ |
1123 | regmap_write(map: priv->regmap, MT6359_AUDDEC_ANA_CON6, val: 0x009b); |
1124 | break; |
1125 | case SND_SOC_DAPM_PRE_PMD: |
1126 | /* HS mux to open */ |
1127 | regmap_update_bits(map: priv->regmap, MT6359_AUDDEC_ANA_CON6, |
1128 | RG_AUDHSMUXINPUTSEL_VAUDP32_MASK_SFT, |
1129 | val: RCV_MUX_OPEN); |
1130 | |
1131 | /* Disable Audio DAC */ |
1132 | regmap_update_bits(map: priv->regmap, MT6359_AUDDEC_ANA_CON0, |
1133 | mask: 0x000f, val: 0x0000); |
1134 | |
1135 | /* Disable AUD_CLK */ |
1136 | mt6359_set_decoder_clk(priv, enable: false); |
1137 | |
1138 | /* decrease HS gain to minimum gain step by step */ |
1139 | regmap_write(map: priv->regmap, MT6359_ZCD_CON3, val: DL_GAIN_N_40DB); |
1140 | |
1141 | /* Disable HS driver core circuits */ |
1142 | regmap_update_bits(map: priv->regmap, MT6359_AUDDEC_ANA_CON6, |
1143 | RG_AUDHSPWRUP_VAUDP32_MASK_SFT, val: 0x0); |
1144 | |
1145 | /* Disable HS driver bias circuits */ |
1146 | regmap_update_bits(map: priv->regmap, MT6359_AUDDEC_ANA_CON6, |
1147 | RG_AUDHSPWRUP_IBIAS_VAUDP32_MASK_SFT, val: 0x0); |
1148 | break; |
1149 | default: |
1150 | break; |
1151 | } |
1152 | |
1153 | return 0; |
1154 | } |
1155 | |
1156 | static int mt_lo_event(struct snd_soc_dapm_widget *w, |
1157 | struct snd_kcontrol *kcontrol, |
1158 | int event) |
1159 | { |
1160 | struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(dapm: w->dapm); |
1161 | struct mt6359_priv *priv = snd_soc_component_get_drvdata(c: cmpnt); |
1162 | unsigned int mux = dapm_kcontrol_get_value(kcontrol: w->kcontrols[0]); |
1163 | |
1164 | dev_dbg(priv->dev, "%s(), event 0x%x, mux %u\n" , |
1165 | __func__, event, mux); |
1166 | |
1167 | switch (event) { |
1168 | case SND_SOC_DAPM_PRE_PMU: |
1169 | /* Disable handset short-circuit protection */ |
1170 | regmap_write(map: priv->regmap, MT6359_AUDDEC_ANA_CON7, val: 0x0010); |
1171 | |
1172 | /* Set LO DR bias current optimization, 010: 6uA */ |
1173 | regmap_update_bits(map: priv->regmap, MT6359_AUDDEC_ANA_CON11, |
1174 | DRBIAS_LO_MASK_SFT, |
1175 | val: DRBIAS_6UA << DRBIAS_LO_SFT); |
1176 | /* Set LO & ZCD bias current optimization */ |
1177 | /* 01: ZCD: 4uA, HP/HS/LO: 5uA */ |
1178 | if (priv->dev_counter[DEVICE_HP] == 0) |
1179 | regmap_update_bits(map: priv->regmap, |
1180 | MT6359_AUDDEC_ANA_CON12, |
1181 | IBIAS_ZCD_MASK_SFT, |
1182 | val: IBIAS_ZCD_4UA << IBIAS_ZCD_SFT); |
1183 | |
1184 | regmap_update_bits(map: priv->regmap, MT6359_AUDDEC_ANA_CON12, |
1185 | IBIAS_LO_MASK_SFT, |
1186 | val: IBIAS_5UA << IBIAS_LO_SFT); |
1187 | |
1188 | /* Set LO STB enhance circuits */ |
1189 | regmap_write(map: priv->regmap, MT6359_AUDDEC_ANA_CON7, val: 0x0110); |
1190 | |
1191 | /* Enable LO driver bias circuits */ |
1192 | regmap_write(map: priv->regmap, MT6359_AUDDEC_ANA_CON7, val: 0x0112); |
1193 | /* Enable LO driver core circuits */ |
1194 | regmap_write(map: priv->regmap, MT6359_AUDDEC_ANA_CON7, val: 0x0113); |
1195 | |
1196 | /* Set LO gain to normal gain step by step */ |
1197 | regmap_write(map: priv->regmap, MT6359_ZCD_CON1, |
1198 | val: priv->ana_gain[AUDIO_ANALOG_VOLUME_LINEOUTL]); |
1199 | |
1200 | /* Enable AUD_CLK */ |
1201 | mt6359_set_decoder_clk(priv, enable: true); |
1202 | |
1203 | /* Switch LOL MUX to audio DAC */ |
1204 | if (mux == LO_MUX_L_DAC) { |
1205 | if (priv->dev_counter[DEVICE_HP] > 0) { |
1206 | dev_info(priv->dev, "%s(), can not enable DAC, hp count %d\n" , |
1207 | __func__, priv->dev_counter[DEVICE_HP]); |
1208 | break; |
1209 | } |
1210 | /* Enable DACL and switch HP MUX to open*/ |
1211 | regmap_write(map: priv->regmap, MT6359_AUDDEC_ANA_CON0, val: 0x3009); |
1212 | /* Disable low-noise mode of DAC */ |
1213 | regmap_write(map: priv->regmap, MT6359_AUDDEC_ANA_CON9, val: 0xf200); |
1214 | usleep_range(min: 100, max: 120); |
1215 | /* Switch LOL MUX to DACL */ |
1216 | regmap_write(map: priv->regmap, MT6359_AUDDEC_ANA_CON7, val: 0x0117); |
1217 | } else if (mux == LO_MUX_3RD_DAC) { |
1218 | /* Enable Audio DAC (3rd DAC) */ |
1219 | regmap_write(map: priv->regmap, MT6359_AUDDEC_ANA_CON7, val: 0x3113); |
1220 | /* Enable low-noise mode of DAC */ |
1221 | if (priv->dev_counter[DEVICE_HP] == 0) |
1222 | regmap_write(map: priv->regmap, MT6359_AUDDEC_ANA_CON9, val: 0x0001); |
1223 | /* Switch LOL MUX to audio 3rd DAC */ |
1224 | regmap_write(map: priv->regmap, MT6359_AUDDEC_ANA_CON7, val: 0x311b); |
1225 | } |
1226 | break; |
1227 | case SND_SOC_DAPM_PRE_PMD: |
1228 | /* Switch LOL MUX to open */ |
1229 | regmap_update_bits(map: priv->regmap, MT6359_AUDDEC_ANA_CON7, |
1230 | RG_AUDLOLMUXINPUTSEL_VAUDP32_MASK_SFT, |
1231 | val: LO_MUX_OPEN); |
1232 | |
1233 | /* Disable Audio DAC */ |
1234 | regmap_update_bits(map: priv->regmap, MT6359_AUDDEC_ANA_CON0, |
1235 | mask: 0x000f, val: 0x0000); |
1236 | |
1237 | if (mux == LO_MUX_L_DAC) { |
1238 | /* Disable HP driver core circuits */ |
1239 | regmap_update_bits(map: priv->regmap, MT6359_AUDDEC_ANA_CON0, |
1240 | mask: 0x3 << 4, val: 0x0); |
1241 | /* Disable HP driver bias circuits */ |
1242 | regmap_update_bits(map: priv->regmap, MT6359_AUDDEC_ANA_CON0, |
1243 | mask: 0x3 << 6, val: 0x0); |
1244 | } |
1245 | |
1246 | /* Disable AUD_CLK */ |
1247 | mt6359_set_decoder_clk(priv, enable: false); |
1248 | |
1249 | /* decrease LO gain to minimum gain step by step */ |
1250 | regmap_write(map: priv->regmap, MT6359_ZCD_CON1, val: DL_GAIN_N_40DB); |
1251 | |
1252 | /* Disable LO driver core circuits */ |
1253 | regmap_update_bits(map: priv->regmap, MT6359_AUDDEC_ANA_CON7, |
1254 | RG_AUDLOLPWRUP_VAUDP32_MASK_SFT, val: 0x0); |
1255 | |
1256 | /* Disable LO driver bias circuits */ |
1257 | regmap_update_bits(map: priv->regmap, MT6359_AUDDEC_ANA_CON7, |
1258 | RG_AUDLOLPWRUP_IBIAS_VAUDP32_MASK_SFT, val: 0x0); |
1259 | break; |
1260 | default: |
1261 | break; |
1262 | } |
1263 | |
1264 | return 0; |
1265 | } |
1266 | |
1267 | static int mt_adc_clk_gen_event(struct snd_soc_dapm_widget *w, |
1268 | struct snd_kcontrol *kcontrol, |
1269 | int event) |
1270 | { |
1271 | struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(dapm: w->dapm); |
1272 | struct mt6359_priv *priv = snd_soc_component_get_drvdata(c: cmpnt); |
1273 | |
1274 | dev_dbg(priv->dev, "%s(), event 0x%x\n" , __func__, event); |
1275 | |
1276 | switch (event) { |
1277 | case SND_SOC_DAPM_POST_PMU: |
1278 | /* ADC CLK from CLKGEN (6.5MHz) */ |
1279 | regmap_update_bits(map: priv->regmap, MT6359_AUDENC_ANA_CON5, |
1280 | RG_AUDADCCLKRSTB_MASK_SFT, |
1281 | val: 0x1 << RG_AUDADCCLKRSTB_SFT); |
1282 | regmap_update_bits(map: priv->regmap, MT6359_AUDENC_ANA_CON5, |
1283 | RG_AUDADCCLKSOURCE_MASK_SFT, val: 0x0); |
1284 | regmap_update_bits(map: priv->regmap, MT6359_AUDENC_ANA_CON5, |
1285 | RG_AUDADCCLKSEL_MASK_SFT, val: 0x0); |
1286 | regmap_update_bits(map: priv->regmap, MT6359_AUDENC_ANA_CON5, |
1287 | RG_AUDADCCLKGENMODE_MASK_SFT, |
1288 | val: 0x1 << RG_AUDADCCLKGENMODE_SFT); |
1289 | break; |
1290 | case SND_SOC_DAPM_PRE_PMD: |
1291 | regmap_update_bits(map: priv->regmap, MT6359_AUDENC_ANA_CON5, |
1292 | RG_AUDADCCLKSOURCE_MASK_SFT, val: 0x0); |
1293 | regmap_update_bits(map: priv->regmap, MT6359_AUDENC_ANA_CON5, |
1294 | RG_AUDADCCLKSEL_MASK_SFT, val: 0x0); |
1295 | regmap_update_bits(map: priv->regmap, MT6359_AUDENC_ANA_CON5, |
1296 | RG_AUDADCCLKGENMODE_MASK_SFT, val: 0x0); |
1297 | regmap_update_bits(map: priv->regmap, MT6359_AUDENC_ANA_CON5, |
1298 | RG_AUDADCCLKRSTB_MASK_SFT, val: 0x0); |
1299 | break; |
1300 | default: |
1301 | break; |
1302 | } |
1303 | |
1304 | return 0; |
1305 | } |
1306 | |
1307 | static int mt_dcc_clk_event(struct snd_soc_dapm_widget *w, |
1308 | struct snd_kcontrol *kcontrol, |
1309 | int event) |
1310 | { |
1311 | struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(dapm: w->dapm); |
1312 | struct mt6359_priv *priv = snd_soc_component_get_drvdata(c: cmpnt); |
1313 | |
1314 | dev_dbg(priv->dev, "%s(), event 0x%x\n" , __func__, event); |
1315 | |
1316 | switch (event) { |
1317 | case SND_SOC_DAPM_PRE_PMU: |
1318 | /* DCC 50k CLK (from 26M) */ |
1319 | /* MT6359_AFE_DCCLK_CFG0, bit 3 for dm ck swap */ |
1320 | regmap_update_bits(map: priv->regmap, MT6359_AFE_DCCLK_CFG0, |
1321 | mask: 0xfff7, val: 0x2062); |
1322 | regmap_update_bits(map: priv->regmap, MT6359_AFE_DCCLK_CFG0, |
1323 | mask: 0xfff7, val: 0x2060); |
1324 | regmap_update_bits(map: priv->regmap, MT6359_AFE_DCCLK_CFG0, |
1325 | mask: 0xfff7, val: 0x2061); |
1326 | |
1327 | regmap_write(map: priv->regmap, MT6359_AFE_DCCLK_CFG1, val: 0x0100); |
1328 | break; |
1329 | case SND_SOC_DAPM_POST_PMD: |
1330 | regmap_update_bits(map: priv->regmap, MT6359_AFE_DCCLK_CFG0, |
1331 | mask: 0xfff7, val: 0x2060); |
1332 | regmap_update_bits(map: priv->regmap, MT6359_AFE_DCCLK_CFG0, |
1333 | mask: 0xfff7, val: 0x2062); |
1334 | break; |
1335 | default: |
1336 | break; |
1337 | } |
1338 | |
1339 | return 0; |
1340 | } |
1341 | |
1342 | static int mt_mic_bias_0_event(struct snd_soc_dapm_widget *w, |
1343 | struct snd_kcontrol *kcontrol, |
1344 | int event) |
1345 | { |
1346 | struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(dapm: w->dapm); |
1347 | struct mt6359_priv *priv = snd_soc_component_get_drvdata(c: cmpnt); |
1348 | unsigned int mic_type = priv->mux_select[MUX_MIC_TYPE_0]; |
1349 | |
1350 | dev_dbg(priv->dev, "%s(), event 0x%x, mic_type %d\n" , |
1351 | __func__, event, mic_type); |
1352 | |
1353 | switch (event) { |
1354 | case SND_SOC_DAPM_PRE_PMU: |
1355 | switch (mic_type) { |
1356 | case MIC_TYPE_MUX_DCC_ECM_DIFF: |
1357 | regmap_update_bits(map: priv->regmap, |
1358 | MT6359_AUDENC_ANA_CON15, |
1359 | mask: 0xff00, val: 0x7700); |
1360 | break; |
1361 | case MIC_TYPE_MUX_DCC_ECM_SINGLE: |
1362 | regmap_update_bits(map: priv->regmap, |
1363 | MT6359_AUDENC_ANA_CON15, |
1364 | mask: 0xff00, val: 0x1100); |
1365 | break; |
1366 | default: |
1367 | regmap_update_bits(map: priv->regmap, |
1368 | MT6359_AUDENC_ANA_CON15, |
1369 | mask: 0xff00, val: 0x0000); |
1370 | break; |
1371 | } |
1372 | |
1373 | /* DMIC enable */ |
1374 | regmap_write(map: priv->regmap, |
1375 | MT6359_AUDENC_ANA_CON14, val: 0x0004); |
1376 | /* MISBIAS0 = 1P9V */ |
1377 | regmap_update_bits(map: priv->regmap, MT6359_AUDENC_ANA_CON15, |
1378 | RG_AUDMICBIAS0VREF_MASK_SFT, |
1379 | val: MIC_BIAS_1P9 << RG_AUDMICBIAS0VREF_SFT); |
1380 | /* normal power select */ |
1381 | regmap_update_bits(map: priv->regmap, MT6359_AUDENC_ANA_CON15, |
1382 | RG_AUDMICBIAS0LOWPEN_MASK_SFT, |
1383 | val: 0 << RG_AUDMICBIAS0LOWPEN_SFT); |
1384 | break; |
1385 | case SND_SOC_DAPM_POST_PMD: |
1386 | /* Disable MICBIAS0, MISBIAS0 = 1P7V */ |
1387 | regmap_write(map: priv->regmap, MT6359_AUDENC_ANA_CON15, val: 0x0000); |
1388 | break; |
1389 | default: |
1390 | break; |
1391 | } |
1392 | |
1393 | return 0; |
1394 | } |
1395 | |
1396 | static int mt_mic_bias_1_event(struct snd_soc_dapm_widget *w, |
1397 | struct snd_kcontrol *kcontrol, |
1398 | int event) |
1399 | { |
1400 | struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(dapm: w->dapm); |
1401 | struct mt6359_priv *priv = snd_soc_component_get_drvdata(c: cmpnt); |
1402 | unsigned int mic_type = priv->mux_select[MUX_MIC_TYPE_1]; |
1403 | |
1404 | dev_dbg(priv->dev, "%s(), event 0x%x, mic_type %d\n" , |
1405 | __func__, event, mic_type); |
1406 | |
1407 | switch (event) { |
1408 | case SND_SOC_DAPM_PRE_PMU: |
1409 | /* MISBIAS1 = 2P6V */ |
1410 | if (mic_type == MIC_TYPE_MUX_DCC_ECM_SINGLE) |
1411 | regmap_write(map: priv->regmap, |
1412 | MT6359_AUDENC_ANA_CON16, val: 0x0160); |
1413 | else |
1414 | regmap_write(map: priv->regmap, |
1415 | MT6359_AUDENC_ANA_CON16, val: 0x0060); |
1416 | |
1417 | /* normal power select */ |
1418 | regmap_update_bits(map: priv->regmap, MT6359_AUDENC_ANA_CON16, |
1419 | RG_AUDMICBIAS1LOWPEN_MASK_SFT, |
1420 | val: 0 << RG_AUDMICBIAS1LOWPEN_SFT); |
1421 | break; |
1422 | default: |
1423 | break; |
1424 | } |
1425 | |
1426 | return 0; |
1427 | } |
1428 | |
1429 | static int mt_mic_bias_2_event(struct snd_soc_dapm_widget *w, |
1430 | struct snd_kcontrol *kcontrol, |
1431 | int event) |
1432 | { |
1433 | struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(dapm: w->dapm); |
1434 | struct mt6359_priv *priv = snd_soc_component_get_drvdata(c: cmpnt); |
1435 | unsigned int mic_type = priv->mux_select[MUX_MIC_TYPE_2]; |
1436 | |
1437 | dev_dbg(priv->dev, "%s(), event 0x%x, mic_type %d\n" , |
1438 | __func__, event, mic_type); |
1439 | |
1440 | switch (event) { |
1441 | case SND_SOC_DAPM_PRE_PMU: |
1442 | switch (mic_type) { |
1443 | case MIC_TYPE_MUX_DCC_ECM_DIFF: |
1444 | regmap_update_bits(map: priv->regmap, |
1445 | MT6359_AUDENC_ANA_CON17, |
1446 | mask: 0xff00, val: 0x7700); |
1447 | break; |
1448 | case MIC_TYPE_MUX_DCC_ECM_SINGLE: |
1449 | regmap_update_bits(map: priv->regmap, |
1450 | MT6359_AUDENC_ANA_CON17, |
1451 | mask: 0xff00, val: 0x1100); |
1452 | break; |
1453 | default: |
1454 | regmap_update_bits(map: priv->regmap, |
1455 | MT6359_AUDENC_ANA_CON17, |
1456 | mask: 0xff00, val: 0x0000); |
1457 | break; |
1458 | } |
1459 | |
1460 | /* MISBIAS2 = 1P9V */ |
1461 | regmap_update_bits(map: priv->regmap, MT6359_AUDENC_ANA_CON17, |
1462 | RG_AUDMICBIAS2VREF_MASK_SFT, |
1463 | val: MIC_BIAS_1P9 << RG_AUDMICBIAS2VREF_SFT); |
1464 | /* normal power select */ |
1465 | regmap_update_bits(map: priv->regmap, MT6359_AUDENC_ANA_CON17, |
1466 | RG_AUDMICBIAS2LOWPEN_MASK_SFT, |
1467 | val: 0 << RG_AUDMICBIAS2LOWPEN_SFT); |
1468 | break; |
1469 | case SND_SOC_DAPM_POST_PMD: |
1470 | /* Disable MICBIAS2, MISBIAS0 = 1P7V */ |
1471 | regmap_write(map: priv->regmap, MT6359_AUDENC_ANA_CON17, val: 0x0000); |
1472 | break; |
1473 | default: |
1474 | break; |
1475 | } |
1476 | |
1477 | return 0; |
1478 | } |
1479 | |
1480 | static int mt_mtkaif_tx_event(struct snd_soc_dapm_widget *w, |
1481 | struct snd_kcontrol *kcontrol, |
1482 | int event) |
1483 | { |
1484 | struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(dapm: w->dapm); |
1485 | struct mt6359_priv *priv = snd_soc_component_get_drvdata(c: cmpnt); |
1486 | |
1487 | dev_dbg(priv->dev, "%s(), event = 0x%x\n" , __func__, event); |
1488 | |
1489 | switch (event) { |
1490 | case SND_SOC_DAPM_PRE_PMU: |
1491 | mt6359_mtkaif_tx_enable(priv); |
1492 | break; |
1493 | case SND_SOC_DAPM_POST_PMD: |
1494 | mt6359_mtkaif_tx_disable(priv); |
1495 | break; |
1496 | default: |
1497 | break; |
1498 | } |
1499 | |
1500 | return 0; |
1501 | } |
1502 | |
1503 | static int mt_ul_src_dmic_event(struct snd_soc_dapm_widget *w, |
1504 | struct snd_kcontrol *kcontrol, |
1505 | int event) |
1506 | { |
1507 | struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(dapm: w->dapm); |
1508 | struct mt6359_priv *priv = snd_soc_component_get_drvdata(c: cmpnt); |
1509 | |
1510 | dev_dbg(priv->dev, "%s(), event = 0x%x\n" , __func__, event); |
1511 | |
1512 | switch (event) { |
1513 | case SND_SOC_DAPM_PRE_PMU: |
1514 | /* UL dmic setting */ |
1515 | if (priv->dmic_one_wire_mode) |
1516 | regmap_write(map: priv->regmap, MT6359_AFE_UL_SRC_CON0_H, |
1517 | val: 0x0400); |
1518 | else |
1519 | regmap_write(map: priv->regmap, MT6359_AFE_UL_SRC_CON0_H, |
1520 | val: 0x0080); |
1521 | /* default one wire, 3.25M */ |
1522 | regmap_update_bits(map: priv->regmap, MT6359_AFE_UL_SRC_CON0_L, |
1523 | mask: 0xfffc, val: 0x0000); |
1524 | break; |
1525 | case SND_SOC_DAPM_POST_PMD: |
1526 | regmap_write(map: priv->regmap, |
1527 | MT6359_AFE_UL_SRC_CON0_H, val: 0x0000); |
1528 | break; |
1529 | default: |
1530 | break; |
1531 | } |
1532 | |
1533 | return 0; |
1534 | } |
1535 | |
1536 | static int mt_ul_src_34_dmic_event(struct snd_soc_dapm_widget *w, |
1537 | struct snd_kcontrol *kcontrol, |
1538 | int event) |
1539 | { |
1540 | struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(dapm: w->dapm); |
1541 | struct mt6359_priv *priv = snd_soc_component_get_drvdata(c: cmpnt); |
1542 | |
1543 | dev_dbg(priv->dev, "%s(), event = 0x%x\n" , __func__, event); |
1544 | |
1545 | switch (event) { |
1546 | case SND_SOC_DAPM_PRE_PMU: |
1547 | /* default two wire, 3.25M */ |
1548 | regmap_write(map: priv->regmap, |
1549 | MT6359_AFE_ADDA6_L_SRC_CON0_H, val: 0x0080); |
1550 | regmap_update_bits(map: priv->regmap, MT6359_AFE_ADDA6_UL_SRC_CON0_L, |
1551 | mask: 0xfffc, val: 0x0000); |
1552 | break; |
1553 | case SND_SOC_DAPM_POST_PMD: |
1554 | regmap_write(map: priv->regmap, |
1555 | MT6359_AFE_ADDA6_L_SRC_CON0_H, val: 0x0000); |
1556 | break; |
1557 | default: |
1558 | break; |
1559 | } |
1560 | |
1561 | return 0; |
1562 | } |
1563 | |
1564 | static int mt_adc_l_event(struct snd_soc_dapm_widget *w, |
1565 | struct snd_kcontrol *kcontrol, |
1566 | int event) |
1567 | { |
1568 | struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(dapm: w->dapm); |
1569 | struct mt6359_priv *priv = snd_soc_component_get_drvdata(c: cmpnt); |
1570 | |
1571 | dev_dbg(priv->dev, "%s(), event = 0x%x\n" , __func__, event); |
1572 | |
1573 | switch (event) { |
1574 | case SND_SOC_DAPM_POST_PMU: |
1575 | usleep_range(min: 100, max: 120); |
1576 | /* Audio L preamplifier DCC precharge off */ |
1577 | regmap_update_bits(map: priv->regmap, MT6359_AUDENC_ANA_CON0, |
1578 | RG_AUDPREAMPLDCPRECHARGE_MASK_SFT, |
1579 | val: 0x0); |
1580 | break; |
1581 | default: |
1582 | break; |
1583 | } |
1584 | |
1585 | return 0; |
1586 | } |
1587 | |
1588 | static int mt_adc_r_event(struct snd_soc_dapm_widget *w, |
1589 | struct snd_kcontrol *kcontrol, |
1590 | int event) |
1591 | { |
1592 | struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(dapm: w->dapm); |
1593 | struct mt6359_priv *priv = snd_soc_component_get_drvdata(c: cmpnt); |
1594 | |
1595 | dev_dbg(priv->dev, "%s(), event = 0x%x\n" , __func__, event); |
1596 | |
1597 | switch (event) { |
1598 | case SND_SOC_DAPM_POST_PMU: |
1599 | usleep_range(min: 100, max: 120); |
1600 | /* Audio R preamplifier DCC precharge off */ |
1601 | regmap_update_bits(map: priv->regmap, MT6359_AUDENC_ANA_CON1, |
1602 | RG_AUDPREAMPRDCPRECHARGE_MASK_SFT, |
1603 | val: 0x0); |
1604 | break; |
1605 | default: |
1606 | break; |
1607 | } |
1608 | |
1609 | return 0; |
1610 | } |
1611 | |
1612 | static int mt_adc_3_event(struct snd_soc_dapm_widget *w, |
1613 | struct snd_kcontrol *kcontrol, |
1614 | int event) |
1615 | { |
1616 | struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(dapm: w->dapm); |
1617 | struct mt6359_priv *priv = snd_soc_component_get_drvdata(c: cmpnt); |
1618 | |
1619 | dev_dbg(priv->dev, "%s(), event = 0x%x\n" , __func__, event); |
1620 | |
1621 | switch (event) { |
1622 | case SND_SOC_DAPM_POST_PMU: |
1623 | usleep_range(min: 100, max: 120); |
1624 | /* Audio R preamplifier DCC precharge off */ |
1625 | regmap_update_bits(map: priv->regmap, MT6359_AUDENC_ANA_CON2, |
1626 | RG_AUDPREAMP3DCPRECHARGE_MASK_SFT, |
1627 | val: 0x0); |
1628 | break; |
1629 | default: |
1630 | break; |
1631 | } |
1632 | |
1633 | return 0; |
1634 | } |
1635 | |
1636 | static int mt_pga_l_mux_event(struct snd_soc_dapm_widget *w, |
1637 | struct snd_kcontrol *kcontrol, |
1638 | int event) |
1639 | { |
1640 | struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(dapm: w->dapm); |
1641 | struct mt6359_priv *priv = snd_soc_component_get_drvdata(c: cmpnt); |
1642 | unsigned int mux = dapm_kcontrol_get_value(kcontrol: w->kcontrols[0]); |
1643 | |
1644 | dev_dbg(priv->dev, "%s(), mux %d\n" , __func__, mux); |
1645 | priv->mux_select[MUX_PGA_L] = mux >> RG_AUDPREAMPLINPUTSEL_SFT; |
1646 | return 0; |
1647 | } |
1648 | |
1649 | static int mt_pga_r_mux_event(struct snd_soc_dapm_widget *w, |
1650 | struct snd_kcontrol *kcontrol, |
1651 | int event) |
1652 | { |
1653 | struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(dapm: w->dapm); |
1654 | struct mt6359_priv *priv = snd_soc_component_get_drvdata(c: cmpnt); |
1655 | unsigned int mux = dapm_kcontrol_get_value(kcontrol: w->kcontrols[0]); |
1656 | |
1657 | dev_dbg(priv->dev, "%s(), mux %d\n" , __func__, mux); |
1658 | priv->mux_select[MUX_PGA_R] = mux >> RG_AUDPREAMPRINPUTSEL_SFT; |
1659 | return 0; |
1660 | } |
1661 | |
1662 | static int mt_pga_3_mux_event(struct snd_soc_dapm_widget *w, |
1663 | struct snd_kcontrol *kcontrol, |
1664 | int event) |
1665 | { |
1666 | struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(dapm: w->dapm); |
1667 | struct mt6359_priv *priv = snd_soc_component_get_drvdata(c: cmpnt); |
1668 | unsigned int mux = dapm_kcontrol_get_value(kcontrol: w->kcontrols[0]); |
1669 | |
1670 | dev_dbg(priv->dev, "%s(), mux %d\n" , __func__, mux); |
1671 | priv->mux_select[MUX_PGA_3] = mux >> RG_AUDPREAMP3INPUTSEL_SFT; |
1672 | return 0; |
1673 | } |
1674 | |
1675 | static int mt_pga_l_event(struct snd_soc_dapm_widget *w, |
1676 | struct snd_kcontrol *kcontrol, |
1677 | int event) |
1678 | { |
1679 | struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(dapm: w->dapm); |
1680 | struct mt6359_priv *priv = snd_soc_component_get_drvdata(c: cmpnt); |
1681 | int mic_gain_l = priv->ana_gain[AUDIO_ANALOG_VOLUME_MICAMP1]; |
1682 | unsigned int mux_pga = priv->mux_select[MUX_PGA_L]; |
1683 | unsigned int mic_type; |
1684 | |
1685 | switch (mux_pga) { |
1686 | case PGA_L_MUX_AIN0: |
1687 | mic_type = priv->mux_select[MUX_MIC_TYPE_0]; |
1688 | break; |
1689 | case PGA_L_MUX_AIN1: |
1690 | mic_type = priv->mux_select[MUX_MIC_TYPE_1]; |
1691 | break; |
1692 | default: |
1693 | dev_err(priv->dev, "%s(), invalid pga mux %d\n" , |
1694 | __func__, mux_pga); |
1695 | return -EINVAL; |
1696 | } |
1697 | |
1698 | switch (event) { |
1699 | case SND_SOC_DAPM_PRE_PMU: |
1700 | if (IS_DCC_BASE(mic_type)) { |
1701 | /* Audio L preamplifier DCC precharge */ |
1702 | regmap_update_bits(map: priv->regmap, MT6359_AUDENC_ANA_CON0, |
1703 | RG_AUDPREAMPLDCPRECHARGE_MASK_SFT, |
1704 | val: 0x1 << RG_AUDPREAMPLDCPRECHARGE_SFT); |
1705 | } |
1706 | break; |
1707 | case SND_SOC_DAPM_POST_PMU: |
1708 | /* set mic pga gain */ |
1709 | regmap_update_bits(map: priv->regmap, MT6359_AUDENC_ANA_CON0, |
1710 | RG_AUDPREAMPLGAIN_MASK_SFT, |
1711 | val: mic_gain_l << RG_AUDPREAMPLGAIN_SFT); |
1712 | |
1713 | if (IS_DCC_BASE(mic_type)) { |
1714 | /* L preamplifier DCCEN */ |
1715 | regmap_update_bits(map: priv->regmap, MT6359_AUDENC_ANA_CON0, |
1716 | RG_AUDPREAMPLDCCEN_MASK_SFT, |
1717 | val: 0x1 << RG_AUDPREAMPLDCCEN_SFT); |
1718 | } |
1719 | break; |
1720 | case SND_SOC_DAPM_POST_PMD: |
1721 | /* L preamplifier DCCEN */ |
1722 | regmap_update_bits(map: priv->regmap, MT6359_AUDENC_ANA_CON0, |
1723 | RG_AUDPREAMPLDCCEN_MASK_SFT, |
1724 | val: 0x0 << RG_AUDPREAMPLDCCEN_SFT); |
1725 | break; |
1726 | default: |
1727 | break; |
1728 | } |
1729 | |
1730 | return 0; |
1731 | } |
1732 | |
1733 | static int mt_pga_r_event(struct snd_soc_dapm_widget *w, |
1734 | struct snd_kcontrol *kcontrol, |
1735 | int event) |
1736 | { |
1737 | struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(dapm: w->dapm); |
1738 | struct mt6359_priv *priv = snd_soc_component_get_drvdata(c: cmpnt); |
1739 | int mic_gain_r = priv->ana_gain[AUDIO_ANALOG_VOLUME_MICAMP2]; |
1740 | unsigned int mux_pga = priv->mux_select[MUX_PGA_R]; |
1741 | unsigned int mic_type; |
1742 | |
1743 | switch (mux_pga) { |
1744 | case PGA_R_MUX_AIN0: |
1745 | mic_type = priv->mux_select[MUX_MIC_TYPE_0]; |
1746 | break; |
1747 | case PGA_R_MUX_AIN2: |
1748 | case PGA_R_MUX_AIN3: |
1749 | mic_type = priv->mux_select[MUX_MIC_TYPE_2]; |
1750 | break; |
1751 | default: |
1752 | dev_err(priv->dev, "%s(), invalid pga mux %d\n" , |
1753 | __func__, mux_pga); |
1754 | return -EINVAL; |
1755 | } |
1756 | |
1757 | switch (event) { |
1758 | case SND_SOC_DAPM_PRE_PMU: |
1759 | if (IS_DCC_BASE(mic_type)) { |
1760 | /* Audio R preamplifier DCC precharge */ |
1761 | regmap_update_bits(map: priv->regmap, MT6359_AUDENC_ANA_CON1, |
1762 | RG_AUDPREAMPRDCPRECHARGE_MASK_SFT, |
1763 | val: 0x1 << RG_AUDPREAMPRDCPRECHARGE_SFT); |
1764 | } |
1765 | break; |
1766 | case SND_SOC_DAPM_POST_PMU: |
1767 | /* set mic pga gain */ |
1768 | regmap_update_bits(map: priv->regmap, MT6359_AUDENC_ANA_CON1, |
1769 | RG_AUDPREAMPRGAIN_MASK_SFT, |
1770 | val: mic_gain_r << RG_AUDPREAMPRGAIN_SFT); |
1771 | |
1772 | if (IS_DCC_BASE(mic_type)) { |
1773 | /* R preamplifier DCCEN */ |
1774 | regmap_update_bits(map: priv->regmap, MT6359_AUDENC_ANA_CON1, |
1775 | RG_AUDPREAMPRDCCEN_MASK_SFT, |
1776 | val: 0x1 << RG_AUDPREAMPRDCCEN_SFT); |
1777 | } |
1778 | break; |
1779 | case SND_SOC_DAPM_POST_PMD: |
1780 | /* R preamplifier DCCEN */ |
1781 | regmap_update_bits(map: priv->regmap, MT6359_AUDENC_ANA_CON1, |
1782 | RG_AUDPREAMPRDCCEN_MASK_SFT, |
1783 | val: 0x0 << RG_AUDPREAMPRDCCEN_SFT); |
1784 | break; |
1785 | default: |
1786 | break; |
1787 | } |
1788 | |
1789 | return 0; |
1790 | } |
1791 | |
1792 | static int mt_pga_3_event(struct snd_soc_dapm_widget *w, |
1793 | struct snd_kcontrol *kcontrol, |
1794 | int event) |
1795 | { |
1796 | struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(dapm: w->dapm); |
1797 | struct mt6359_priv *priv = snd_soc_component_get_drvdata(c: cmpnt); |
1798 | int mic_gain_3 = priv->ana_gain[AUDIO_ANALOG_VOLUME_MICAMP3]; |
1799 | unsigned int mux_pga = priv->mux_select[MUX_PGA_3]; |
1800 | unsigned int mic_type; |
1801 | |
1802 | switch (mux_pga) { |
1803 | case PGA_3_MUX_AIN2: |
1804 | case PGA_3_MUX_AIN3: |
1805 | mic_type = priv->mux_select[MUX_MIC_TYPE_2]; |
1806 | break; |
1807 | default: |
1808 | dev_err(priv->dev, "%s(), invalid pga mux %d\n" , |
1809 | __func__, mux_pga); |
1810 | return -EINVAL; |
1811 | } |
1812 | |
1813 | switch (event) { |
1814 | case SND_SOC_DAPM_PRE_PMU: |
1815 | if (IS_DCC_BASE(mic_type)) { |
1816 | /* Audio 3 preamplifier DCC precharge */ |
1817 | regmap_update_bits(map: priv->regmap, MT6359_AUDENC_ANA_CON2, |
1818 | RG_AUDPREAMP3DCPRECHARGE_MASK_SFT, |
1819 | val: 0x1 << RG_AUDPREAMP3DCPRECHARGE_SFT); |
1820 | } |
1821 | break; |
1822 | case SND_SOC_DAPM_POST_PMU: |
1823 | /* set mic pga gain */ |
1824 | regmap_update_bits(map: priv->regmap, MT6359_AUDENC_ANA_CON2, |
1825 | RG_AUDPREAMP3GAIN_MASK_SFT, |
1826 | val: mic_gain_3 << RG_AUDPREAMP3GAIN_SFT); |
1827 | |
1828 | if (IS_DCC_BASE(mic_type)) { |
1829 | /* 3 preamplifier DCCEN */ |
1830 | regmap_update_bits(map: priv->regmap, MT6359_AUDENC_ANA_CON2, |
1831 | RG_AUDPREAMP3DCCEN_MASK_SFT, |
1832 | val: 0x1 << RG_AUDPREAMP3DCCEN_SFT); |
1833 | } |
1834 | break; |
1835 | case SND_SOC_DAPM_POST_PMD: |
1836 | /* 3 preamplifier DCCEN */ |
1837 | regmap_update_bits(map: priv->regmap, MT6359_AUDENC_ANA_CON2, |
1838 | RG_AUDPREAMP3DCCEN_MASK_SFT, |
1839 | val: 0x0 << RG_AUDPREAMP3DCCEN_SFT); |
1840 | break; |
1841 | default: |
1842 | break; |
1843 | } |
1844 | |
1845 | return 0; |
1846 | } |
1847 | |
1848 | /* It is based on hw's control sequenece to add some delay when PMU/PMD */ |
1849 | static int mt_delay_250_event(struct snd_soc_dapm_widget *w, |
1850 | struct snd_kcontrol *kcontrol, |
1851 | int event) |
1852 | { |
1853 | switch (event) { |
1854 | case SND_SOC_DAPM_POST_PMU: |
1855 | case SND_SOC_DAPM_PRE_PMD: |
1856 | usleep_range(min: 250, max: 270); |
1857 | break; |
1858 | default: |
1859 | break; |
1860 | } |
1861 | |
1862 | return 0; |
1863 | } |
1864 | |
1865 | static int mt_delay_100_event(struct snd_soc_dapm_widget *w, |
1866 | struct snd_kcontrol *kcontrol, |
1867 | int event) |
1868 | { |
1869 | switch (event) { |
1870 | case SND_SOC_DAPM_POST_PMU: |
1871 | case SND_SOC_DAPM_PRE_PMD: |
1872 | usleep_range(min: 100, max: 120); |
1873 | break; |
1874 | default: |
1875 | break; |
1876 | } |
1877 | |
1878 | return 0; |
1879 | } |
1880 | |
1881 | static int mt_hp_pull_down_event(struct snd_soc_dapm_widget *w, |
1882 | struct snd_kcontrol *kcontrol, |
1883 | int event) |
1884 | { |
1885 | struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(dapm: w->dapm); |
1886 | struct mt6359_priv *priv = snd_soc_component_get_drvdata(c: cmpnt); |
1887 | |
1888 | switch (event) { |
1889 | case SND_SOC_DAPM_PRE_PMU: |
1890 | hp_pull_down(priv, enable: true); |
1891 | break; |
1892 | case SND_SOC_DAPM_POST_PMD: |
1893 | hp_pull_down(priv, enable: false); |
1894 | break; |
1895 | default: |
1896 | break; |
1897 | } |
1898 | |
1899 | return 0; |
1900 | } |
1901 | |
1902 | static int mt_hp_mute_event(struct snd_soc_dapm_widget *w, |
1903 | struct snd_kcontrol *kcontrol, |
1904 | int event) |
1905 | { |
1906 | struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(dapm: w->dapm); |
1907 | struct mt6359_priv *priv = snd_soc_component_get_drvdata(c: cmpnt); |
1908 | |
1909 | switch (event) { |
1910 | case SND_SOC_DAPM_PRE_PMU: |
1911 | /* Set HPR/HPL gain to -22dB */ |
1912 | regmap_write(map: priv->regmap, MT6359_ZCD_CON2, DL_GAIN_N_22DB_REG); |
1913 | break; |
1914 | case SND_SOC_DAPM_POST_PMD: |
1915 | /* Set HPL/HPR gain to mute */ |
1916 | regmap_write(map: priv->regmap, MT6359_ZCD_CON2, DL_GAIN_N_40DB_REG); |
1917 | break; |
1918 | default: |
1919 | break; |
1920 | } |
1921 | |
1922 | return 0; |
1923 | } |
1924 | |
1925 | static int mt_hp_damp_event(struct snd_soc_dapm_widget *w, |
1926 | struct snd_kcontrol *kcontrol, |
1927 | int event) |
1928 | { |
1929 | struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(dapm: w->dapm); |
1930 | struct mt6359_priv *priv = snd_soc_component_get_drvdata(c: cmpnt); |
1931 | |
1932 | switch (event) { |
1933 | case SND_SOC_DAPM_POST_PMD: |
1934 | /* Disable HP damping circuit & HPN 4K load */ |
1935 | /* reset CMFB PW level */ |
1936 | regmap_write(map: priv->regmap, MT6359_AUDDEC_ANA_CON10, val: 0x0000); |
1937 | break; |
1938 | default: |
1939 | break; |
1940 | } |
1941 | |
1942 | return 0; |
1943 | } |
1944 | |
1945 | static int mt_esd_resist_event(struct snd_soc_dapm_widget *w, |
1946 | struct snd_kcontrol *kcontrol, |
1947 | int event) |
1948 | { |
1949 | struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(dapm: w->dapm); |
1950 | struct mt6359_priv *priv = snd_soc_component_get_drvdata(c: cmpnt); |
1951 | |
1952 | switch (event) { |
1953 | case SND_SOC_DAPM_PRE_PMU: |
1954 | /* Reduce ESD resistance of AU_REFN */ |
1955 | regmap_update_bits(map: priv->regmap, MT6359_AUDDEC_ANA_CON2, |
1956 | RG_AUDREFN_DERES_EN_VAUDP32_MASK_SFT, |
1957 | val: 0x1 << RG_AUDREFN_DERES_EN_VAUDP32_SFT); |
1958 | usleep_range(min: 250, max: 270); |
1959 | break; |
1960 | case SND_SOC_DAPM_POST_PMD: |
1961 | /* Increase ESD resistance of AU_REFN */ |
1962 | regmap_update_bits(map: priv->regmap, MT6359_AUDDEC_ANA_CON2, |
1963 | RG_AUDREFN_DERES_EN_VAUDP32_MASK_SFT, val: 0x0); |
1964 | break; |
1965 | default: |
1966 | break; |
1967 | } |
1968 | |
1969 | return 0; |
1970 | } |
1971 | |
1972 | static int mt_sdm_event(struct snd_soc_dapm_widget *w, |
1973 | struct snd_kcontrol *kcontrol, |
1974 | int event) |
1975 | { |
1976 | struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(dapm: w->dapm); |
1977 | struct mt6359_priv *priv = snd_soc_component_get_drvdata(c: cmpnt); |
1978 | |
1979 | switch (event) { |
1980 | case SND_SOC_DAPM_PRE_PMU: |
1981 | /* sdm audio fifo clock power on */ |
1982 | regmap_update_bits(map: priv->regmap, MT6359_AFUNC_AUD_CON2, |
1983 | mask: 0xfffd, val: 0x0006); |
1984 | /* scrambler clock on enable */ |
1985 | regmap_write(map: priv->regmap, MT6359_AFUNC_AUD_CON0, val: 0xcba1); |
1986 | /* sdm power on */ |
1987 | regmap_update_bits(map: priv->regmap, MT6359_AFUNC_AUD_CON2, |
1988 | mask: 0xfffd, val: 0x0003); |
1989 | /* sdm fifo enable */ |
1990 | regmap_update_bits(map: priv->regmap, MT6359_AFUNC_AUD_CON2, |
1991 | mask: 0xfffd, val: 0x000B); |
1992 | break; |
1993 | case SND_SOC_DAPM_POST_PMD: |
1994 | /* DL scrambler disabling sequence */ |
1995 | regmap_update_bits(map: priv->regmap, MT6359_AFUNC_AUD_CON2, |
1996 | mask: 0xfffd, val: 0x0000); |
1997 | regmap_write(map: priv->regmap, MT6359_AFUNC_AUD_CON0, val: 0xcba0); |
1998 | break; |
1999 | default: |
2000 | break; |
2001 | } |
2002 | |
2003 | return 0; |
2004 | } |
2005 | |
2006 | static int mt_sdm_3rd_event(struct snd_soc_dapm_widget *w, |
2007 | struct snd_kcontrol *kcontrol, |
2008 | int event) |
2009 | { |
2010 | struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(dapm: w->dapm); |
2011 | struct mt6359_priv *priv = snd_soc_component_get_drvdata(c: cmpnt); |
2012 | |
2013 | switch (event) { |
2014 | case SND_SOC_DAPM_PRE_PMU: |
2015 | /* sdm audio fifo clock power on */ |
2016 | regmap_write(map: priv->regmap, MT6359_AFUNC_AUD_CON11, val: 0x0006); |
2017 | /* scrambler clock on enable */ |
2018 | regmap_write(map: priv->regmap, MT6359_AFUNC_AUD_CON9, val: 0xcba1); |
2019 | /* sdm power on */ |
2020 | regmap_write(map: priv->regmap, MT6359_AFUNC_AUD_CON11, val: 0x0003); |
2021 | /* sdm fifo enable */ |
2022 | regmap_write(map: priv->regmap, MT6359_AFUNC_AUD_CON11, val: 0x000b); |
2023 | break; |
2024 | case SND_SOC_DAPM_POST_PMD: |
2025 | /* DL scrambler disabling sequence */ |
2026 | regmap_write(map: priv->regmap, MT6359_AFUNC_AUD_CON11, val: 0x0000); |
2027 | regmap_write(map: priv->regmap, MT6359_AFUNC_AUD_CON9, val: 0xcba0); |
2028 | break; |
2029 | default: |
2030 | break; |
2031 | } |
2032 | |
2033 | return 0; |
2034 | } |
2035 | |
2036 | static int mt_ncp_event(struct snd_soc_dapm_widget *w, |
2037 | struct snd_kcontrol *kcontrol, |
2038 | int event) |
2039 | { |
2040 | struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(dapm: w->dapm); |
2041 | struct mt6359_priv *priv = snd_soc_component_get_drvdata(c: cmpnt); |
2042 | |
2043 | switch (event) { |
2044 | case SND_SOC_DAPM_PRE_PMU: |
2045 | regmap_write(map: priv->regmap, MT6359_AFE_NCP_CFG0, val: 0xc800); |
2046 | break; |
2047 | default: |
2048 | break; |
2049 | } |
2050 | |
2051 | return 0; |
2052 | } |
2053 | |
2054 | /* DAPM Widgets */ |
2055 | static const struct snd_soc_dapm_widget mt6359_dapm_widgets[] = { |
2056 | /* Global Supply*/ |
2057 | SND_SOC_DAPM_SUPPLY_S("CLK_BUF" , SUPPLY_SEQ_CLK_BUF, |
2058 | MT6359_DCXO_CW12, |
2059 | RG_XO_AUDIO_EN_M_SFT, 0, NULL, 0), |
2060 | SND_SOC_DAPM_SUPPLY_S("AUDGLB" , SUPPLY_SEQ_AUD_GLB, |
2061 | MT6359_AUDDEC_ANA_CON13, |
2062 | RG_AUDGLB_PWRDN_VA32_SFT, 1, NULL, 0), |
2063 | SND_SOC_DAPM_SUPPLY_S("CLKSQ Audio" , SUPPLY_SEQ_CLKSQ, |
2064 | MT6359_AUDENC_ANA_CON23, |
2065 | RG_CLKSQ_EN_SFT, 0, NULL, SND_SOC_DAPM_PRE_PMU), |
2066 | SND_SOC_DAPM_SUPPLY_S("AUDNCP_CK" , SUPPLY_SEQ_TOP_CK, |
2067 | MT6359_AUD_TOP_CKPDN_CON0, |
2068 | RG_AUDNCP_CK_PDN_SFT, 1, NULL, 0), |
2069 | SND_SOC_DAPM_SUPPLY_S("ZCD13M_CK" , SUPPLY_SEQ_TOP_CK, |
2070 | MT6359_AUD_TOP_CKPDN_CON0, |
2071 | RG_ZCD13M_CK_PDN_SFT, 1, NULL, 0), |
2072 | SND_SOC_DAPM_SUPPLY_S("AUD_CK" , SUPPLY_SEQ_TOP_CK_LAST, |
2073 | MT6359_AUD_TOP_CKPDN_CON0, |
2074 | RG_AUD_CK_PDN_SFT, 1, mt_delay_250_event, |
2075 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), |
2076 | SND_SOC_DAPM_SUPPLY_S("AUDIF_CK" , SUPPLY_SEQ_TOP_CK, |
2077 | MT6359_AUD_TOP_CKPDN_CON0, |
2078 | RG_AUDIF_CK_PDN_SFT, 1, NULL, 0), |
2079 | SND_SOC_DAPM_REGULATOR_SUPPLY("vaud18" , 0, 0), |
2080 | |
2081 | /* Digital Clock */ |
2082 | SND_SOC_DAPM_SUPPLY_S("AUDIO_TOP_AFE_CTL" , SUPPLY_SEQ_AUD_TOP_LAST, |
2083 | MT6359_AUDIO_TOP_CON0, |
2084 | PDN_AFE_CTL_SFT, 1, |
2085 | mt_delay_250_event, |
2086 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), |
2087 | SND_SOC_DAPM_SUPPLY_S("AUDIO_TOP_DAC_CTL" , SUPPLY_SEQ_AUD_TOP, |
2088 | MT6359_AUDIO_TOP_CON0, |
2089 | PDN_DAC_CTL_SFT, 1, NULL, 0), |
2090 | SND_SOC_DAPM_SUPPLY_S("AUDIO_TOP_ADC_CTL" , SUPPLY_SEQ_AUD_TOP, |
2091 | MT6359_AUDIO_TOP_CON0, |
2092 | PDN_ADC_CTL_SFT, 1, NULL, 0), |
2093 | SND_SOC_DAPM_SUPPLY_S("AUDIO_TOP_ADDA6_ADC_CTL" , SUPPLY_SEQ_AUD_TOP, |
2094 | MT6359_AUDIO_TOP_CON0, |
2095 | PDN_ADDA6_ADC_CTL_SFT, 1, NULL, 0), |
2096 | SND_SOC_DAPM_SUPPLY_S("AUDIO_TOP_I2S_DL" , SUPPLY_SEQ_AUD_TOP, |
2097 | MT6359_AUDIO_TOP_CON0, |
2098 | PDN_I2S_DL_CTL_SFT, 1, NULL, 0), |
2099 | SND_SOC_DAPM_SUPPLY_S("AUDIO_TOP_PWR_CLK" , SUPPLY_SEQ_AUD_TOP, |
2100 | MT6359_AUDIO_TOP_CON0, |
2101 | PWR_CLK_DIS_CTL_SFT, 1, NULL, 0), |
2102 | SND_SOC_DAPM_SUPPLY_S("AUDIO_TOP_PDN_AFE_TESTMODEL" , SUPPLY_SEQ_AUD_TOP, |
2103 | MT6359_AUDIO_TOP_CON0, |
2104 | PDN_AFE_TESTMODEL_CTL_SFT, 1, NULL, 0), |
2105 | SND_SOC_DAPM_SUPPLY_S("AUDIO_TOP_PDN_RESERVED" , SUPPLY_SEQ_AUD_TOP, |
2106 | MT6359_AUDIO_TOP_CON0, |
2107 | PDN_RESERVED_SFT, 1, NULL, 0), |
2108 | |
2109 | SND_SOC_DAPM_SUPPLY_S("SDM" , SUPPLY_SEQ_DL_SDM, |
2110 | SND_SOC_NOPM, 0, 0, |
2111 | mt_sdm_event, |
2112 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), |
2113 | SND_SOC_DAPM_SUPPLY_S("SDM_3RD" , SUPPLY_SEQ_DL_SDM, |
2114 | SND_SOC_NOPM, 0, 0, |
2115 | mt_sdm_3rd_event, |
2116 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), |
2117 | |
2118 | /* ch123 share SDM FIFO CLK */ |
2119 | SND_SOC_DAPM_SUPPLY_S("SDM_FIFO_CLK" , SUPPLY_SEQ_DL_SDM_FIFO_CLK, |
2120 | MT6359_AFUNC_AUD_CON2, |
2121 | CCI_AFIFO_CLK_PWDB_SFT, 0, |
2122 | NULL, 0), |
2123 | |
2124 | SND_SOC_DAPM_SUPPLY_S("NCP" , SUPPLY_SEQ_DL_NCP, |
2125 | MT6359_AFE_NCP_CFG0, |
2126 | RG_NCP_ON_SFT, 0, |
2127 | mt_ncp_event, |
2128 | SND_SOC_DAPM_PRE_PMU), |
2129 | |
2130 | SND_SOC_DAPM_SUPPLY("DL Digital Clock" , SND_SOC_NOPM, |
2131 | 0, 0, NULL, 0), |
2132 | SND_SOC_DAPM_SUPPLY("DL Digital Clock CH_1_2" , SND_SOC_NOPM, |
2133 | 0, 0, NULL, 0), |
2134 | SND_SOC_DAPM_SUPPLY("DL Digital Clock CH_3" , SND_SOC_NOPM, |
2135 | 0, 0, NULL, 0), |
2136 | |
2137 | /* AFE ON */ |
2138 | SND_SOC_DAPM_SUPPLY_S("AFE_ON" , SUPPLY_SEQ_AFE, |
2139 | MT6359_AFE_UL_DL_CON0, AFE_ON_SFT, 0, |
2140 | NULL, 0), |
2141 | |
2142 | /* AIF Rx*/ |
2143 | SND_SOC_DAPM_AIF_IN("AIF_RX" , "AIF1 Playback" , 0, |
2144 | SND_SOC_NOPM, 0, 0), |
2145 | |
2146 | SND_SOC_DAPM_AIF_IN("AIF2_RX" , "AIF2 Playback" , 0, |
2147 | SND_SOC_NOPM, 0, 0), |
2148 | |
2149 | SND_SOC_DAPM_SUPPLY_S("AFE_DL_SRC" , SUPPLY_SEQ_DL_SRC, |
2150 | MT6359_AFE_DL_SRC2_CON0_L, |
2151 | DL_2_SRC_ON_TMP_CTL_PRE_SFT, 0, |
2152 | NULL, 0), |
2153 | |
2154 | /* DL Supply */ |
2155 | SND_SOC_DAPM_SUPPLY("DL Power Supply" , SND_SOC_NOPM, |
2156 | 0, 0, NULL, 0), |
2157 | |
2158 | SND_SOC_DAPM_SUPPLY_S("ESD_RESIST" , SUPPLY_SEQ_DL_ESD_RESIST, |
2159 | SND_SOC_NOPM, |
2160 | 0, 0, |
2161 | mt_esd_resist_event, |
2162 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), |
2163 | SND_SOC_DAPM_SUPPLY_S("LDO" , SUPPLY_SEQ_DL_LDO, |
2164 | MT6359_AUDDEC_ANA_CON14, |
2165 | RG_LCLDO_DEC_EN_VA32_SFT, 0, |
2166 | NULL, 0), |
2167 | SND_SOC_DAPM_SUPPLY_S("LDO_REMOTE" , SUPPLY_SEQ_DL_LDO_REMOTE_SENSE, |
2168 | MT6359_AUDDEC_ANA_CON14, |
2169 | RG_LCLDO_DEC_REMOTE_SENSE_VA18_SFT, 0, |
2170 | NULL, 0), |
2171 | SND_SOC_DAPM_SUPPLY_S("NV_REGULATOR" , SUPPLY_SEQ_DL_NV, |
2172 | MT6359_AUDDEC_ANA_CON14, |
2173 | RG_NVREG_EN_VAUDP32_SFT, 0, |
2174 | mt_delay_100_event, SND_SOC_DAPM_POST_PMU), |
2175 | SND_SOC_DAPM_SUPPLY_S("IBIST" , SUPPLY_SEQ_DL_IBIST, |
2176 | MT6359_AUDDEC_ANA_CON12, |
2177 | RG_AUDIBIASPWRDN_VAUDP32_SFT, 1, |
2178 | NULL, 0), |
2179 | |
2180 | /* DAC */ |
2181 | SND_SOC_DAPM_MUX("DAC In Mux" , SND_SOC_NOPM, 0, 0, &dac_in_mux_control), |
2182 | |
2183 | SND_SOC_DAPM_DAC("DACL" , NULL, SND_SOC_NOPM, 0, 0), |
2184 | |
2185 | SND_SOC_DAPM_DAC("DACR" , NULL, SND_SOC_NOPM, 0, 0), |
2186 | |
2187 | SND_SOC_DAPM_DAC("DAC_3RD" , NULL, SND_SOC_NOPM, 0, 0), |
2188 | |
2189 | /* Headphone */ |
2190 | SND_SOC_DAPM_MUX_E("HP Mux" , SND_SOC_NOPM, 0, 0, |
2191 | &hp_in_mux_control, |
2192 | mt_hp_event, |
2193 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), |
2194 | |
2195 | SND_SOC_DAPM_SUPPLY("HP_Supply" , SND_SOC_NOPM, |
2196 | 0, 0, NULL, 0), |
2197 | SND_SOC_DAPM_SUPPLY_S("HP_PULL_DOWN" , SUPPLY_SEQ_HP_PULL_DOWN, |
2198 | SND_SOC_NOPM, |
2199 | 0, 0, |
2200 | mt_hp_pull_down_event, |
2201 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), |
2202 | SND_SOC_DAPM_SUPPLY_S("HP_MUTE" , SUPPLY_SEQ_HP_MUTE, |
2203 | SND_SOC_NOPM, |
2204 | 0, 0, |
2205 | mt_hp_mute_event, |
2206 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), |
2207 | SND_SOC_DAPM_SUPPLY_S("HP_DAMP" , SUPPLY_SEQ_HP_DAMPING_OFF_RESET_CMFB, |
2208 | SND_SOC_NOPM, |
2209 | 0, 0, |
2210 | mt_hp_damp_event, |
2211 | SND_SOC_DAPM_POST_PMD), |
2212 | |
2213 | /* Receiver */ |
2214 | SND_SOC_DAPM_MUX_E("RCV Mux" , SND_SOC_NOPM, 0, 0, |
2215 | &rcv_in_mux_control, |
2216 | mt_rcv_event, |
2217 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), |
2218 | |
2219 | /* LOL */ |
2220 | SND_SOC_DAPM_MUX_E("LOL Mux" , SND_SOC_NOPM, 0, 0, |
2221 | &lo_in_mux_control, |
2222 | mt_lo_event, |
2223 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), |
2224 | |
2225 | /* Outputs */ |
2226 | SND_SOC_DAPM_OUTPUT("Receiver" ), |
2227 | SND_SOC_DAPM_OUTPUT("Headphone L" ), |
2228 | SND_SOC_DAPM_OUTPUT("Headphone R" ), |
2229 | SND_SOC_DAPM_OUTPUT("Headphone L Ext Spk Amp" ), |
2230 | SND_SOC_DAPM_OUTPUT("Headphone R Ext Spk Amp" ), |
2231 | SND_SOC_DAPM_OUTPUT("LINEOUT L" ), |
2232 | |
2233 | /* SGEN */ |
2234 | SND_SOC_DAPM_SUPPLY("SGEN DL Enable" , MT6359_AFE_SGEN_CFG0, |
2235 | SGEN_DAC_EN_CTL_SFT, 0, NULL, 0), |
2236 | SND_SOC_DAPM_SUPPLY("SGEN MUTE" , MT6359_AFE_SGEN_CFG0, |
2237 | SGEN_MUTE_SW_CTL_SFT, 1, |
2238 | mt_sgen_event, |
2239 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), |
2240 | SND_SOC_DAPM_SUPPLY("SGEN DL SRC" , MT6359_AFE_DL_SRC2_CON0_L, |
2241 | DL_2_SRC_ON_TMP_CTL_PRE_SFT, 0, NULL, 0), |
2242 | |
2243 | SND_SOC_DAPM_INPUT("SGEN DL" ), |
2244 | |
2245 | /* Uplinks */ |
2246 | SND_SOC_DAPM_AIF_OUT("AIF1TX" , "AIF1 Capture" , 0, |
2247 | SND_SOC_NOPM, 0, 0), |
2248 | SND_SOC_DAPM_AIF_OUT("AIF2TX" , "AIF2 Capture" , 0, |
2249 | SND_SOC_NOPM, 0, 0), |
2250 | |
2251 | SND_SOC_DAPM_SUPPLY_S("ADC_CLKGEN" , SUPPLY_SEQ_ADC_CLKGEN, |
2252 | SND_SOC_NOPM, 0, 0, |
2253 | mt_adc_clk_gen_event, |
2254 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), |
2255 | |
2256 | SND_SOC_DAPM_SUPPLY_S("DCC_CLK" , SUPPLY_SEQ_DCC_CLK, |
2257 | SND_SOC_NOPM, 0, 0, |
2258 | mt_dcc_clk_event, |
2259 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), |
2260 | |
2261 | /* Uplinks MUX */ |
2262 | SND_SOC_DAPM_MUX("AIF Out Mux" , SND_SOC_NOPM, 0, 0, |
2263 | &aif_out_mux_control), |
2264 | |
2265 | SND_SOC_DAPM_MUX("AIF2 Out Mux" , SND_SOC_NOPM, 0, 0, |
2266 | &aif2_out_mux_control), |
2267 | |
2268 | SND_SOC_DAPM_SUPPLY("AIFTX_Supply" , SND_SOC_NOPM, 0, 0, NULL, 0), |
2269 | |
2270 | SND_SOC_DAPM_SUPPLY_S("MTKAIF_TX" , SUPPLY_SEQ_UL_MTKAIF, |
2271 | SND_SOC_NOPM, 0, 0, |
2272 | mt_mtkaif_tx_event, |
2273 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), |
2274 | |
2275 | SND_SOC_DAPM_SUPPLY_S("UL_SRC" , SUPPLY_SEQ_UL_SRC, |
2276 | MT6359_AFE_UL_SRC_CON0_L, |
2277 | UL_SRC_ON_TMP_CTL_SFT, 0, |
2278 | NULL, 0), |
2279 | |
2280 | SND_SOC_DAPM_SUPPLY_S("UL_SRC_DMIC" , SUPPLY_SEQ_UL_SRC_DMIC, |
2281 | SND_SOC_NOPM, 0, 0, |
2282 | mt_ul_src_dmic_event, |
2283 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), |
2284 | |
2285 | SND_SOC_DAPM_SUPPLY_S("UL_SRC_34" , SUPPLY_SEQ_UL_SRC, |
2286 | MT6359_AFE_ADDA6_UL_SRC_CON0_L, |
2287 | ADDA6_UL_SRC_ON_TMP_CTL_SFT, 0, |
2288 | NULL, 0), |
2289 | |
2290 | SND_SOC_DAPM_SUPPLY_S("UL_SRC_34_DMIC" , SUPPLY_SEQ_UL_SRC_DMIC, |
2291 | SND_SOC_NOPM, 0, 0, |
2292 | mt_ul_src_34_dmic_event, |
2293 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), |
2294 | |
2295 | SND_SOC_DAPM_MUX("MISO0_MUX" , SND_SOC_NOPM, 0, 0, &miso0_mux_control), |
2296 | SND_SOC_DAPM_MUX("MISO1_MUX" , SND_SOC_NOPM, 0, 0, &miso1_mux_control), |
2297 | SND_SOC_DAPM_MUX("MISO2_MUX" , SND_SOC_NOPM, 0, 0, &miso2_mux_control), |
2298 | |
2299 | SND_SOC_DAPM_MUX("UL_SRC_MUX" , SND_SOC_NOPM, 0, 0, |
2300 | &ul_src_mux_control), |
2301 | SND_SOC_DAPM_MUX("UL2_SRC_MUX" , SND_SOC_NOPM, 0, 0, |
2302 | &ul2_src_mux_control), |
2303 | |
2304 | SND_SOC_DAPM_MUX("DMIC0_MUX" , SND_SOC_NOPM, 0, 0, &dmic0_mux_control), |
2305 | SND_SOC_DAPM_MUX("DMIC1_MUX" , SND_SOC_NOPM, 0, 0, &dmic1_mux_control), |
2306 | SND_SOC_DAPM_MUX("DMIC2_MUX" , SND_SOC_NOPM, 0, 0, &dmic2_mux_control), |
2307 | |
2308 | SND_SOC_DAPM_MUX_E("ADC_L_Mux" , SND_SOC_NOPM, 0, 0, |
2309 | &adc_left_mux_control, NULL, 0), |
2310 | SND_SOC_DAPM_MUX_E("ADC_R_Mux" , SND_SOC_NOPM, 0, 0, |
2311 | &adc_right_mux_control, NULL, 0), |
2312 | SND_SOC_DAPM_MUX_E("ADC_3_Mux" , SND_SOC_NOPM, 0, 0, |
2313 | &adc_3_mux_control, NULL, 0), |
2314 | |
2315 | SND_SOC_DAPM_ADC("ADC_L" , NULL, SND_SOC_NOPM, 0, 0), |
2316 | SND_SOC_DAPM_ADC("ADC_R" , NULL, SND_SOC_NOPM, 0, 0), |
2317 | SND_SOC_DAPM_ADC("ADC_3" , NULL, SND_SOC_NOPM, 0, 0), |
2318 | |
2319 | SND_SOC_DAPM_SUPPLY_S("ADC_L_EN" , SUPPLY_SEQ_UL_ADC, |
2320 | MT6359_AUDENC_ANA_CON0, |
2321 | RG_AUDADCLPWRUP_SFT, 0, |
2322 | mt_adc_l_event, |
2323 | SND_SOC_DAPM_POST_PMU), |
2324 | SND_SOC_DAPM_SUPPLY_S("ADC_R_EN" , SUPPLY_SEQ_UL_ADC, |
2325 | MT6359_AUDENC_ANA_CON1, |
2326 | RG_AUDADCRPWRUP_SFT, 0, |
2327 | mt_adc_r_event, |
2328 | SND_SOC_DAPM_POST_PMU), |
2329 | SND_SOC_DAPM_SUPPLY_S("ADC_3_EN" , SUPPLY_SEQ_UL_ADC, |
2330 | MT6359_AUDENC_ANA_CON2, |
2331 | RG_AUDADC3PWRUP_SFT, 0, |
2332 | mt_adc_3_event, |
2333 | SND_SOC_DAPM_POST_PMU), |
2334 | |
2335 | SND_SOC_DAPM_MUX_E("PGA_L_Mux" , SND_SOC_NOPM, 0, 0, |
2336 | &pga_left_mux_control, |
2337 | mt_pga_l_mux_event, |
2338 | SND_SOC_DAPM_WILL_PMU), |
2339 | SND_SOC_DAPM_MUX_E("PGA_R_Mux" , SND_SOC_NOPM, 0, 0, |
2340 | &pga_right_mux_control, |
2341 | mt_pga_r_mux_event, |
2342 | SND_SOC_DAPM_WILL_PMU), |
2343 | SND_SOC_DAPM_MUX_E("PGA_3_Mux" , SND_SOC_NOPM, 0, 0, |
2344 | &pga_3_mux_control, |
2345 | mt_pga_3_mux_event, |
2346 | SND_SOC_DAPM_WILL_PMU), |
2347 | |
2348 | SND_SOC_DAPM_PGA("PGA_L" , SND_SOC_NOPM, 0, 0, NULL, 0), |
2349 | SND_SOC_DAPM_PGA("PGA_R" , SND_SOC_NOPM, 0, 0, NULL, 0), |
2350 | SND_SOC_DAPM_PGA("PGA_3" , SND_SOC_NOPM, 0, 0, NULL, 0), |
2351 | |
2352 | SND_SOC_DAPM_SUPPLY_S("PGA_L_EN" , SUPPLY_SEQ_UL_PGA, |
2353 | MT6359_AUDENC_ANA_CON0, |
2354 | RG_AUDPREAMPLON_SFT, 0, |
2355 | mt_pga_l_event, |
2356 | SND_SOC_DAPM_PRE_PMU | |
2357 | SND_SOC_DAPM_POST_PMU | |
2358 | SND_SOC_DAPM_POST_PMD), |
2359 | SND_SOC_DAPM_SUPPLY_S("PGA_R_EN" , SUPPLY_SEQ_UL_PGA, |
2360 | MT6359_AUDENC_ANA_CON1, |
2361 | RG_AUDPREAMPRON_SFT, 0, |
2362 | mt_pga_r_event, |
2363 | SND_SOC_DAPM_PRE_PMU | |
2364 | SND_SOC_DAPM_POST_PMU | |
2365 | SND_SOC_DAPM_POST_PMD), |
2366 | SND_SOC_DAPM_SUPPLY_S("PGA_3_EN" , SUPPLY_SEQ_UL_PGA, |
2367 | MT6359_AUDENC_ANA_CON2, |
2368 | RG_AUDPREAMP3ON_SFT, 0, |
2369 | mt_pga_3_event, |
2370 | SND_SOC_DAPM_PRE_PMU | |
2371 | SND_SOC_DAPM_POST_PMU | |
2372 | SND_SOC_DAPM_POST_PMD), |
2373 | |
2374 | /* UL input */ |
2375 | SND_SOC_DAPM_INPUT("AIN0" ), |
2376 | SND_SOC_DAPM_INPUT("AIN1" ), |
2377 | SND_SOC_DAPM_INPUT("AIN2" ), |
2378 | SND_SOC_DAPM_INPUT("AIN3" ), |
2379 | |
2380 | SND_SOC_DAPM_INPUT("AIN0_DMIC" ), |
2381 | SND_SOC_DAPM_INPUT("AIN2_DMIC" ), |
2382 | SND_SOC_DAPM_INPUT("AIN3_DMIC" ), |
2383 | |
2384 | /* mic bias */ |
2385 | SND_SOC_DAPM_SUPPLY_S("MIC_BIAS_0" , SUPPLY_SEQ_MIC_BIAS, |
2386 | MT6359_AUDENC_ANA_CON15, |
2387 | RG_AUDPWDBMICBIAS0_SFT, 0, |
2388 | mt_mic_bias_0_event, |
2389 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), |
2390 | SND_SOC_DAPM_SUPPLY_S("MIC_BIAS_1" , SUPPLY_SEQ_MIC_BIAS, |
2391 | MT6359_AUDENC_ANA_CON16, |
2392 | RG_AUDPWDBMICBIAS1_SFT, 0, |
2393 | mt_mic_bias_1_event, |
2394 | SND_SOC_DAPM_PRE_PMU), |
2395 | SND_SOC_DAPM_SUPPLY_S("MIC_BIAS_2" , SUPPLY_SEQ_MIC_BIAS, |
2396 | MT6359_AUDENC_ANA_CON17, |
2397 | RG_AUDPWDBMICBIAS2_SFT, 0, |
2398 | mt_mic_bias_2_event, |
2399 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), |
2400 | |
2401 | /* dmic */ |
2402 | SND_SOC_DAPM_SUPPLY_S("DMIC_0" , SUPPLY_SEQ_DMIC, |
2403 | MT6359_AUDENC_ANA_CON13, |
2404 | RG_AUDDIGMICEN_SFT, 0, |
2405 | NULL, 0), |
2406 | SND_SOC_DAPM_SUPPLY_S("DMIC_1" , SUPPLY_SEQ_DMIC, |
2407 | MT6359_AUDENC_ANA_CON14, |
2408 | RG_AUDDIGMIC1EN_SFT, 0, |
2409 | NULL, 0), |
2410 | }; |
2411 | |
2412 | static int mt_dcc_clk_connect(struct snd_soc_dapm_widget *source, |
2413 | struct snd_soc_dapm_widget *sink) |
2414 | { |
2415 | struct snd_soc_dapm_widget *w = sink; |
2416 | struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(dapm: w->dapm); |
2417 | struct mt6359_priv *priv = snd_soc_component_get_drvdata(c: cmpnt); |
2418 | |
2419 | if (IS_DCC_BASE(priv->mux_select[MUX_MIC_TYPE_0]) || |
2420 | IS_DCC_BASE(priv->mux_select[MUX_MIC_TYPE_1]) || |
2421 | IS_DCC_BASE(priv->mux_select[MUX_MIC_TYPE_2])) |
2422 | return 1; |
2423 | else |
2424 | return 0; |
2425 | } |
2426 | |
2427 | static const struct snd_soc_dapm_route mt6359_dapm_routes[] = { |
2428 | /* Capture */ |
2429 | {"AIFTX_Supply" , NULL, "CLK_BUF" }, |
2430 | {"AIFTX_Supply" , NULL, "vaud18" }, |
2431 | {"AIFTX_Supply" , NULL, "AUDGLB" }, |
2432 | {"AIFTX_Supply" , NULL, "CLKSQ Audio" }, |
2433 | {"AIFTX_Supply" , NULL, "AUD_CK" }, |
2434 | {"AIFTX_Supply" , NULL, "AUDIF_CK" }, |
2435 | {"AIFTX_Supply" , NULL, "AUDIO_TOP_AFE_CTL" }, |
2436 | {"AIFTX_Supply" , NULL, "AUDIO_TOP_PWR_CLK" }, |
2437 | {"AIFTX_Supply" , NULL, "AUDIO_TOP_PDN_RESERVED" }, |
2438 | {"AIFTX_Supply" , NULL, "AUDIO_TOP_I2S_DL" }, |
2439 | /* |
2440 | * *_ADC_CTL should enable only if UL_SRC in use, |
2441 | * but dm ck may be needed even UL_SRC_x not in use |
2442 | */ |
2443 | {"AIFTX_Supply" , NULL, "AUDIO_TOP_ADC_CTL" }, |
2444 | {"AIFTX_Supply" , NULL, "AUDIO_TOP_ADDA6_ADC_CTL" }, |
2445 | {"AIFTX_Supply" , NULL, "AFE_ON" }, |
2446 | |
2447 | /* ul ch 12 */ |
2448 | {"AIF1TX" , NULL, "AIF Out Mux" }, |
2449 | {"AIF1TX" , NULL, "AIFTX_Supply" }, |
2450 | {"AIF1TX" , NULL, "MTKAIF_TX" }, |
2451 | |
2452 | {"AIF2TX" , NULL, "AIF2 Out Mux" }, |
2453 | {"AIF2TX" , NULL, "AIFTX_Supply" }, |
2454 | {"AIF2TX" , NULL, "MTKAIF_TX" }, |
2455 | |
2456 | {"AIF Out Mux" , "Normal Path" , "MISO0_MUX" }, |
2457 | {"AIF Out Mux" , "Normal Path" , "MISO1_MUX" }, |
2458 | {"AIF2 Out Mux" , "Normal Path" , "MISO2_MUX" }, |
2459 | |
2460 | {"MISO0_MUX" , "UL1_CH1" , "UL_SRC_MUX" }, |
2461 | {"MISO0_MUX" , "UL1_CH2" , "UL_SRC_MUX" }, |
2462 | {"MISO0_MUX" , "UL2_CH1" , "UL2_SRC_MUX" }, |
2463 | {"MISO0_MUX" , "UL2_CH2" , "UL2_SRC_MUX" }, |
2464 | |
2465 | {"MISO1_MUX" , "UL1_CH1" , "UL_SRC_MUX" }, |
2466 | {"MISO1_MUX" , "UL1_CH2" , "UL_SRC_MUX" }, |
2467 | {"MISO1_MUX" , "UL2_CH1" , "UL2_SRC_MUX" }, |
2468 | {"MISO1_MUX" , "UL2_CH2" , "UL2_SRC_MUX" }, |
2469 | |
2470 | {"MISO2_MUX" , "UL1_CH1" , "UL_SRC_MUX" }, |
2471 | {"MISO2_MUX" , "UL1_CH2" , "UL_SRC_MUX" }, |
2472 | {"MISO2_MUX" , "UL2_CH1" , "UL2_SRC_MUX" }, |
2473 | {"MISO2_MUX" , "UL2_CH2" , "UL2_SRC_MUX" }, |
2474 | |
2475 | {"MISO0_MUX" , NULL, "UL_SRC" }, |
2476 | {"MISO1_MUX" , NULL, "UL_SRC" }, |
2477 | {"MISO2_MUX" , NULL, "UL_SRC_34" }, |
2478 | |
2479 | {"UL_SRC_MUX" , "AMIC" , "ADC_L" }, |
2480 | {"UL_SRC_MUX" , "AMIC" , "ADC_R" }, |
2481 | {"UL_SRC_MUX" , "DMIC" , "DMIC0_MUX" }, |
2482 | {"UL_SRC_MUX" , "DMIC" , "DMIC1_MUX" }, |
2483 | {"UL_SRC_MUX" , NULL, "UL_SRC" }, |
2484 | |
2485 | {"UL2_SRC_MUX" , "AMIC" , "ADC_3" }, |
2486 | {"UL2_SRC_MUX" , "DMIC" , "DMIC2_MUX" }, |
2487 | {"UL2_SRC_MUX" , NULL, "UL_SRC_34" }, |
2488 | |
2489 | {"DMIC0_MUX" , "DMIC_DATA0" , "AIN0_DMIC" }, |
2490 | {"DMIC0_MUX" , "DMIC_DATA1_L" , "AIN2_DMIC" }, |
2491 | {"DMIC0_MUX" , "DMIC_DATA1_L_1" , "AIN2_DMIC" }, |
2492 | {"DMIC0_MUX" , "DMIC_DATA1_R" , "AIN3_DMIC" }, |
2493 | {"DMIC1_MUX" , "DMIC_DATA0" , "AIN0_DMIC" }, |
2494 | {"DMIC1_MUX" , "DMIC_DATA1_L" , "AIN2_DMIC" }, |
2495 | {"DMIC1_MUX" , "DMIC_DATA1_L_1" , "AIN2_DMIC" }, |
2496 | {"DMIC1_MUX" , "DMIC_DATA1_R" , "AIN3_DMIC" }, |
2497 | {"DMIC2_MUX" , "DMIC_DATA0" , "AIN0_DMIC" }, |
2498 | {"DMIC2_MUX" , "DMIC_DATA1_L" , "AIN2_DMIC" }, |
2499 | {"DMIC2_MUX" , "DMIC_DATA1_L_1" , "AIN2_DMIC" }, |
2500 | {"DMIC2_MUX" , "DMIC_DATA1_R" , "AIN3_DMIC" }, |
2501 | |
2502 | {"DMIC0_MUX" , NULL, "UL_SRC_DMIC" }, |
2503 | {"DMIC1_MUX" , NULL, "UL_SRC_DMIC" }, |
2504 | {"DMIC2_MUX" , NULL, "UL_SRC_34_DMIC" }, |
2505 | |
2506 | {"AIN0_DMIC" , NULL, "DMIC_0" }, |
2507 | {"AIN2_DMIC" , NULL, "DMIC_1" }, |
2508 | {"AIN3_DMIC" , NULL, "DMIC_1" }, |
2509 | {"AIN0_DMIC" , NULL, "MIC_BIAS_0" }, |
2510 | {"AIN2_DMIC" , NULL, "MIC_BIAS_2" }, |
2511 | {"AIN3_DMIC" , NULL, "MIC_BIAS_2" }, |
2512 | |
2513 | /* adc */ |
2514 | {"ADC_L" , NULL, "ADC_L_Mux" }, |
2515 | {"ADC_L" , NULL, "ADC_CLKGEN" }, |
2516 | {"ADC_L" , NULL, "ADC_L_EN" }, |
2517 | {"ADC_R" , NULL, "ADC_R_Mux" }, |
2518 | {"ADC_R" , NULL, "ADC_CLKGEN" }, |
2519 | {"ADC_R" , NULL, "ADC_R_EN" }, |
2520 | /* |
2521 | * amic fifo ch1/2 clk from ADC_L, |
2522 | * enable ADC_L even use ADC_R only |
2523 | */ |
2524 | {"ADC_R" , NULL, "ADC_L_EN" }, |
2525 | {"ADC_3" , NULL, "ADC_3_Mux" }, |
2526 | {"ADC_3" , NULL, "ADC_CLKGEN" }, |
2527 | {"ADC_3" , NULL, "ADC_3_EN" }, |
2528 | |
2529 | {"ADC_L_Mux" , "Left Preamplifier" , "PGA_L" }, |
2530 | {"ADC_R_Mux" , "Right Preamplifier" , "PGA_R" }, |
2531 | {"ADC_3_Mux" , "Preamplifier" , "PGA_3" }, |
2532 | |
2533 | {"PGA_L" , NULL, "PGA_L_Mux" }, |
2534 | {"PGA_L" , NULL, "PGA_L_EN" }, |
2535 | {"PGA_R" , NULL, "PGA_R_Mux" }, |
2536 | {"PGA_R" , NULL, "PGA_R_EN" }, |
2537 | {"PGA_3" , NULL, "PGA_3_Mux" }, |
2538 | {"PGA_3" , NULL, "PGA_3_EN" }, |
2539 | |
2540 | {"PGA_L" , NULL, "DCC_CLK" , mt_dcc_clk_connect}, |
2541 | {"PGA_R" , NULL, "DCC_CLK" , mt_dcc_clk_connect}, |
2542 | {"PGA_3" , NULL, "DCC_CLK" , mt_dcc_clk_connect}, |
2543 | |
2544 | {"PGA_L_Mux" , "AIN0" , "AIN0" }, |
2545 | {"PGA_L_Mux" , "AIN1" , "AIN1" }, |
2546 | |
2547 | {"PGA_R_Mux" , "AIN0" , "AIN0" }, |
2548 | {"PGA_R_Mux" , "AIN2" , "AIN2" }, |
2549 | {"PGA_R_Mux" , "AIN3" , "AIN3" }, |
2550 | |
2551 | {"PGA_3_Mux" , "AIN2" , "AIN2" }, |
2552 | {"PGA_3_Mux" , "AIN3" , "AIN3" }, |
2553 | |
2554 | {"AIN0" , NULL, "MIC_BIAS_0" }, |
2555 | {"AIN1" , NULL, "MIC_BIAS_1" }, |
2556 | {"AIN2" , NULL, "MIC_BIAS_0" }, |
2557 | {"AIN2" , NULL, "MIC_BIAS_2" }, |
2558 | {"AIN3" , NULL, "MIC_BIAS_2" }, |
2559 | |
2560 | /* DL Supply */ |
2561 | {"DL Power Supply" , NULL, "CLK_BUF" }, |
2562 | {"DL Power Supply" , NULL, "vaud18" }, |
2563 | {"DL Power Supply" , NULL, "AUDGLB" }, |
2564 | {"DL Power Supply" , NULL, "CLKSQ Audio" }, |
2565 | {"DL Power Supply" , NULL, "AUDNCP_CK" }, |
2566 | {"DL Power Supply" , NULL, "ZCD13M_CK" }, |
2567 | {"DL Power Supply" , NULL, "AUD_CK" }, |
2568 | {"DL Power Supply" , NULL, "AUDIF_CK" }, |
2569 | {"DL Power Supply" , NULL, "ESD_RESIST" }, |
2570 | {"DL Power Supply" , NULL, "LDO" }, |
2571 | {"DL Power Supply" , NULL, "LDO_REMOTE" }, |
2572 | {"DL Power Supply" , NULL, "NV_REGULATOR" }, |
2573 | {"DL Power Supply" , NULL, "IBIST" }, |
2574 | |
2575 | /* DL Digital Supply */ |
2576 | {"DL Digital Clock" , NULL, "AUDIO_TOP_AFE_CTL" }, |
2577 | {"DL Digital Clock" , NULL, "AUDIO_TOP_DAC_CTL" }, |
2578 | {"DL Digital Clock" , NULL, "AUDIO_TOP_PWR_CLK" }, |
2579 | {"DL Digital Clock" , NULL, "AUDIO_TOP_PDN_RESERVED" }, |
2580 | {"DL Digital Clock" , NULL, "SDM_FIFO_CLK" }, |
2581 | {"DL Digital Clock" , NULL, "NCP" }, |
2582 | {"DL Digital Clock" , NULL, "AFE_ON" }, |
2583 | {"DL Digital Clock" , NULL, "AFE_DL_SRC" }, |
2584 | |
2585 | {"DL Digital Clock CH_1_2" , NULL, "DL Digital Clock" }, |
2586 | {"DL Digital Clock CH_1_2" , NULL, "SDM" }, |
2587 | |
2588 | {"DL Digital Clock CH_3" , NULL, "DL Digital Clock" }, |
2589 | {"DL Digital Clock CH_3" , NULL, "SDM_3RD" }, |
2590 | |
2591 | {"AIF_RX" , NULL, "DL Digital Clock CH_1_2" }, |
2592 | |
2593 | {"AIF2_RX" , NULL, "DL Digital Clock CH_3" }, |
2594 | |
2595 | /* DL Path */ |
2596 | {"DAC In Mux" , "Normal Path" , "AIF_RX" }, |
2597 | {"DAC In Mux" , "Sgen" , "SGEN DL" }, |
2598 | {"SGEN DL" , NULL, "SGEN DL SRC" }, |
2599 | {"SGEN DL" , NULL, "SGEN MUTE" }, |
2600 | {"SGEN DL" , NULL, "SGEN DL Enable" }, |
2601 | {"SGEN DL" , NULL, "DL Digital Clock CH_1_2" }, |
2602 | {"SGEN DL" , NULL, "DL Digital Clock CH_3" }, |
2603 | {"SGEN DL" , NULL, "AUDIO_TOP_PDN_AFE_TESTMODEL" }, |
2604 | |
2605 | {"DACL" , NULL, "DAC In Mux" }, |
2606 | {"DACL" , NULL, "DL Power Supply" }, |
2607 | |
2608 | {"DACR" , NULL, "DAC In Mux" }, |
2609 | {"DACR" , NULL, "DL Power Supply" }, |
2610 | |
2611 | /* DAC 3RD */ |
2612 | {"DAC In Mux" , "Normal Path" , "AIF2_RX" }, |
2613 | {"DAC_3RD" , NULL, "DAC In Mux" }, |
2614 | {"DAC_3RD" , NULL, "DL Power Supply" }, |
2615 | |
2616 | /* Lineout Path */ |
2617 | {"LOL Mux" , "Playback" , "DAC_3RD" }, |
2618 | {"LOL Mux" , "Playback_L_DAC" , "DACL" }, |
2619 | {"LINEOUT L" , NULL, "LOL Mux" }, |
2620 | |
2621 | /* Headphone Path */ |
2622 | {"HP_Supply" , NULL, "HP_PULL_DOWN" }, |
2623 | {"HP_Supply" , NULL, "HP_MUTE" }, |
2624 | {"HP_Supply" , NULL, "HP_DAMP" }, |
2625 | {"HP Mux" , NULL, "HP_Supply" }, |
2626 | |
2627 | {"HP Mux" , "Audio Playback" , "DACL" }, |
2628 | {"HP Mux" , "Audio Playback" , "DACR" }, |
2629 | {"HP Mux" , "HP Impedance" , "DACL" }, |
2630 | {"HP Mux" , "HP Impedance" , "DACR" }, |
2631 | {"HP Mux" , "LoudSPK Playback" , "DACL" }, |
2632 | {"HP Mux" , "LoudSPK Playback" , "DACR" }, |
2633 | |
2634 | {"Headphone L" , NULL, "HP Mux" }, |
2635 | {"Headphone R" , NULL, "HP Mux" }, |
2636 | {"Headphone L Ext Spk Amp" , NULL, "HP Mux" }, |
2637 | {"Headphone R Ext Spk Amp" , NULL, "HP Mux" }, |
2638 | |
2639 | /* Receiver Path */ |
2640 | {"RCV Mux" , "Voice Playback" , "DACL" }, |
2641 | {"Receiver" , NULL, "RCV Mux" }, |
2642 | }; |
2643 | |
2644 | static int mt6359_codec_dai_hw_params(struct snd_pcm_substream *substream, |
2645 | struct snd_pcm_hw_params *params, |
2646 | struct snd_soc_dai *dai) |
2647 | { |
2648 | struct snd_soc_component *cmpnt = dai->component; |
2649 | struct mt6359_priv *priv = snd_soc_component_get_drvdata(c: cmpnt); |
2650 | unsigned int rate = params_rate(p: params); |
2651 | int id = dai->id; |
2652 | |
2653 | dev_dbg(priv->dev, "%s(), id %d, substream->stream %d, rate %d, number %d\n" , |
2654 | __func__, id, substream->stream, rate, substream->number); |
2655 | |
2656 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) |
2657 | priv->dl_rate[id] = rate; |
2658 | else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) |
2659 | priv->ul_rate[id] = rate; |
2660 | |
2661 | return 0; |
2662 | } |
2663 | |
2664 | static int mt6359_codec_dai_startup(struct snd_pcm_substream *substream, |
2665 | struct snd_soc_dai *dai) |
2666 | { |
2667 | struct snd_soc_component *cmpnt = dai->component; |
2668 | struct mt6359_priv *priv = snd_soc_component_get_drvdata(c: cmpnt); |
2669 | |
2670 | dev_dbg(priv->dev, "%s stream %d\n" , __func__, substream->stream); |
2671 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) |
2672 | mt6359_set_playback_gpio(priv); |
2673 | else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) |
2674 | mt6359_set_capture_gpio(priv); |
2675 | |
2676 | return 0; |
2677 | } |
2678 | |
2679 | static void mt6359_codec_dai_shutdown(struct snd_pcm_substream *substream, |
2680 | struct snd_soc_dai *dai) |
2681 | { |
2682 | struct snd_soc_component *cmpnt = dai->component; |
2683 | struct mt6359_priv *priv = snd_soc_component_get_drvdata(c: cmpnt); |
2684 | |
2685 | dev_dbg(priv->dev, "%s stream %d\n" , __func__, substream->stream); |
2686 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) |
2687 | mt6359_reset_playback_gpio(priv); |
2688 | else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) |
2689 | mt6359_reset_capture_gpio(priv); |
2690 | } |
2691 | |
2692 | static const struct snd_soc_dai_ops mt6359_codec_dai_ops = { |
2693 | .hw_params = mt6359_codec_dai_hw_params, |
2694 | .startup = mt6359_codec_dai_startup, |
2695 | .shutdown = mt6359_codec_dai_shutdown, |
2696 | }; |
2697 | |
2698 | #define MT6359_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_LE |\ |
2699 | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_U24_LE |\ |
2700 | SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_U32_LE) |
2701 | |
2702 | static struct snd_soc_dai_driver mt6359_dai_driver[] = { |
2703 | { |
2704 | .id = MT6359_AIF_1, |
2705 | .name = "mt6359-snd-codec-aif1" , |
2706 | .playback = { |
2707 | .stream_name = "AIF1 Playback" , |
2708 | .channels_min = 1, |
2709 | .channels_max = 2, |
2710 | .rates = SNDRV_PCM_RATE_8000_48000 | |
2711 | SNDRV_PCM_RATE_96000 | |
2712 | SNDRV_PCM_RATE_192000, |
2713 | .formats = MT6359_FORMATS, |
2714 | }, |
2715 | .capture = { |
2716 | .stream_name = "AIF1 Capture" , |
2717 | .channels_min = 1, |
2718 | .channels_max = 2, |
2719 | .rates = SNDRV_PCM_RATE_8000 | |
2720 | SNDRV_PCM_RATE_16000 | |
2721 | SNDRV_PCM_RATE_32000 | |
2722 | SNDRV_PCM_RATE_48000 | |
2723 | SNDRV_PCM_RATE_96000 | |
2724 | SNDRV_PCM_RATE_192000, |
2725 | .formats = MT6359_FORMATS, |
2726 | }, |
2727 | .ops = &mt6359_codec_dai_ops, |
2728 | }, |
2729 | { |
2730 | .id = MT6359_AIF_2, |
2731 | .name = "mt6359-snd-codec-aif2" , |
2732 | .playback = { |
2733 | .stream_name = "AIF2 Playback" , |
2734 | .channels_min = 1, |
2735 | .channels_max = 2, |
2736 | .rates = SNDRV_PCM_RATE_8000_48000 | |
2737 | SNDRV_PCM_RATE_96000 | |
2738 | SNDRV_PCM_RATE_192000, |
2739 | .formats = MT6359_FORMATS, |
2740 | }, |
2741 | .capture = { |
2742 | .stream_name = "AIF2 Capture" , |
2743 | .channels_min = 1, |
2744 | .channels_max = 2, |
2745 | .rates = SNDRV_PCM_RATE_8000 | |
2746 | SNDRV_PCM_RATE_16000 | |
2747 | SNDRV_PCM_RATE_32000 | |
2748 | SNDRV_PCM_RATE_48000, |
2749 | .formats = MT6359_FORMATS, |
2750 | }, |
2751 | .ops = &mt6359_codec_dai_ops, |
2752 | }, |
2753 | }; |
2754 | |
2755 | static int mt6359_codec_init_reg(struct snd_soc_component *cmpnt) |
2756 | { |
2757 | struct mt6359_priv *priv = snd_soc_component_get_drvdata(c: cmpnt); |
2758 | |
2759 | /* enable clk buf */ |
2760 | regmap_update_bits(map: priv->regmap, MT6359_DCXO_CW12, |
2761 | mask: 0x1 << RG_XO_AUDIO_EN_M_SFT, |
2762 | val: 0x1 << RG_XO_AUDIO_EN_M_SFT); |
2763 | |
2764 | /* set those not controlled by dapm widget */ |
2765 | |
2766 | /* audio clk source from internal dcxo */ |
2767 | regmap_update_bits(map: priv->regmap, MT6359_AUDENC_ANA_CON23, |
2768 | RG_CLKSQ_IN_SEL_TEST_MASK_SFT, |
2769 | val: 0x0); |
2770 | |
2771 | /* Disable HeadphoneL/HeadphoneR short circuit protection */ |
2772 | regmap_update_bits(map: priv->regmap, MT6359_AUDDEC_ANA_CON0, |
2773 | RG_AUDHPLSCDISABLE_VAUDP32_MASK_SFT, |
2774 | val: 0x1 << RG_AUDHPLSCDISABLE_VAUDP32_SFT); |
2775 | regmap_update_bits(map: priv->regmap, MT6359_AUDDEC_ANA_CON0, |
2776 | RG_AUDHPRSCDISABLE_VAUDP32_MASK_SFT, |
2777 | val: 0x1 << RG_AUDHPRSCDISABLE_VAUDP32_SFT); |
2778 | /* Disable voice short circuit protection */ |
2779 | regmap_update_bits(map: priv->regmap, MT6359_AUDDEC_ANA_CON6, |
2780 | RG_AUDHSSCDISABLE_VAUDP32_MASK_SFT, |
2781 | val: 0x1 << RG_AUDHSSCDISABLE_VAUDP32_SFT); |
2782 | /* disable LO buffer left short circuit protection */ |
2783 | regmap_update_bits(map: priv->regmap, MT6359_AUDDEC_ANA_CON7, |
2784 | RG_AUDLOLSCDISABLE_VAUDP32_MASK_SFT, |
2785 | val: 0x1 << RG_AUDLOLSCDISABLE_VAUDP32_SFT); |
2786 | |
2787 | /* set gpio */ |
2788 | mt6359_set_gpio_smt(priv); |
2789 | mt6359_set_gpio_driving(priv); |
2790 | mt6359_reset_playback_gpio(priv); |
2791 | mt6359_reset_capture_gpio(priv); |
2792 | |
2793 | /* hp hifi mode, default normal mode */ |
2794 | priv->hp_hifi_mode = 0; |
2795 | |
2796 | /* Disable AUD_ZCD */ |
2797 | zcd_disable(priv); |
2798 | |
2799 | /* disable clk buf */ |
2800 | regmap_update_bits(map: priv->regmap, MT6359_DCXO_CW12, |
2801 | mask: 0x1 << RG_XO_AUDIO_EN_M_SFT, |
2802 | val: 0x0 << RG_XO_AUDIO_EN_M_SFT); |
2803 | |
2804 | return 0; |
2805 | } |
2806 | |
2807 | static int mt6359_codec_probe(struct snd_soc_component *cmpnt) |
2808 | { |
2809 | struct mt6359_priv *priv = snd_soc_component_get_drvdata(c: cmpnt); |
2810 | |
2811 | snd_soc_component_init_regmap(component: cmpnt, regmap: priv->regmap); |
2812 | |
2813 | return mt6359_codec_init_reg(cmpnt); |
2814 | } |
2815 | |
2816 | static void mt6359_codec_remove(struct snd_soc_component *cmpnt) |
2817 | { |
2818 | cmpnt->regmap = NULL; |
2819 | } |
2820 | |
2821 | static const DECLARE_TLV_DB_SCALE(playback_tlv, -1000, 100, 0); |
2822 | static const DECLARE_TLV_DB_SCALE(capture_tlv, 0, 600, 0); |
2823 | |
2824 | static const struct snd_kcontrol_new mt6359_snd_controls[] = { |
2825 | /* dl pga gain */ |
2826 | SOC_DOUBLE_EXT_TLV("Headset Volume" , |
2827 | MT6359_ZCD_CON2, 0, 7, 0x12, 0, |
2828 | mt6359_get_playback_volsw, mt6359_put_volsw, |
2829 | playback_tlv), |
2830 | SOC_DOUBLE_EXT_TLV("Lineout Volume" , |
2831 | MT6359_ZCD_CON1, 0, 7, 0x12, 0, |
2832 | mt6359_get_playback_volsw, mt6359_put_volsw, |
2833 | playback_tlv), |
2834 | SOC_SINGLE_EXT_TLV("Handset Volume" , |
2835 | MT6359_ZCD_CON3, 0, 0x12, 0, |
2836 | mt6359_get_playback_volsw, mt6359_put_volsw, |
2837 | playback_tlv), |
2838 | |
2839 | /* ul pga gain */ |
2840 | SOC_SINGLE_EXT_TLV("PGA1 Volume" , |
2841 | MT6359_AUDENC_ANA_CON0, RG_AUDPREAMPLGAIN_SFT, 4, 0, |
2842 | snd_soc_get_volsw, mt6359_put_volsw, capture_tlv), |
2843 | SOC_SINGLE_EXT_TLV("PGA2 Volume" , |
2844 | MT6359_AUDENC_ANA_CON1, RG_AUDPREAMPRGAIN_SFT, 4, 0, |
2845 | snd_soc_get_volsw, mt6359_put_volsw, capture_tlv), |
2846 | SOC_SINGLE_EXT_TLV("PGA3 Volume" , |
2847 | MT6359_AUDENC_ANA_CON2, RG_AUDPREAMP3GAIN_SFT, 4, 0, |
2848 | snd_soc_get_volsw, mt6359_put_volsw, capture_tlv), |
2849 | }; |
2850 | |
2851 | static const struct snd_soc_component_driver mt6359_soc_component_driver = { |
2852 | .name = CODEC_MT6359_NAME, |
2853 | .probe = mt6359_codec_probe, |
2854 | .remove = mt6359_codec_remove, |
2855 | .controls = mt6359_snd_controls, |
2856 | .num_controls = ARRAY_SIZE(mt6359_snd_controls), |
2857 | .dapm_widgets = mt6359_dapm_widgets, |
2858 | .num_dapm_widgets = ARRAY_SIZE(mt6359_dapm_widgets), |
2859 | .dapm_routes = mt6359_dapm_routes, |
2860 | .num_dapm_routes = ARRAY_SIZE(mt6359_dapm_routes), |
2861 | .endianness = 1, |
2862 | }; |
2863 | |
2864 | static int mt6359_parse_dt(struct mt6359_priv *priv) |
2865 | { |
2866 | int ret; |
2867 | struct device *dev = priv->dev; |
2868 | struct device_node *np; |
2869 | |
2870 | np = of_get_child_by_name(node: dev->parent->of_node, name: "mt6359codec" ); |
2871 | if (!np) |
2872 | return -EINVAL; |
2873 | |
2874 | ret = of_property_read_u32(np, propname: "mediatek,dmic-mode" , |
2875 | out_value: &priv->dmic_one_wire_mode); |
2876 | if (ret) { |
2877 | dev_info(priv->dev, |
2878 | "%s() failed to read dmic-mode, use default (0)\n" , |
2879 | __func__); |
2880 | priv->dmic_one_wire_mode = 0; |
2881 | } |
2882 | |
2883 | ret = of_property_read_u32(np, propname: "mediatek,mic-type-0" , |
2884 | out_value: &priv->mux_select[MUX_MIC_TYPE_0]); |
2885 | if (ret) { |
2886 | dev_info(priv->dev, |
2887 | "%s() failed to read mic-type-0, use default (%d)\n" , |
2888 | __func__, MIC_TYPE_MUX_IDLE); |
2889 | priv->mux_select[MUX_MIC_TYPE_0] = MIC_TYPE_MUX_IDLE; |
2890 | } |
2891 | |
2892 | ret = of_property_read_u32(np, propname: "mediatek,mic-type-1" , |
2893 | out_value: &priv->mux_select[MUX_MIC_TYPE_1]); |
2894 | if (ret) { |
2895 | dev_info(priv->dev, |
2896 | "%s() failed to read mic-type-1, use default (%d)\n" , |
2897 | __func__, MIC_TYPE_MUX_IDLE); |
2898 | priv->mux_select[MUX_MIC_TYPE_1] = MIC_TYPE_MUX_IDLE; |
2899 | } |
2900 | |
2901 | ret = of_property_read_u32(np, propname: "mediatek,mic-type-2" , |
2902 | out_value: &priv->mux_select[MUX_MIC_TYPE_2]); |
2903 | of_node_put(node: np); |
2904 | if (ret) { |
2905 | dev_info(priv->dev, |
2906 | "%s() failed to read mic-type-2, use default (%d)\n" , |
2907 | __func__, MIC_TYPE_MUX_IDLE); |
2908 | priv->mux_select[MUX_MIC_TYPE_2] = MIC_TYPE_MUX_IDLE; |
2909 | } |
2910 | |
2911 | return 0; |
2912 | } |
2913 | |
2914 | static int mt6359_platform_driver_probe(struct platform_device *pdev) |
2915 | { |
2916 | struct mt6359_priv *priv; |
2917 | int ret; |
2918 | struct mt6397_chip *mt6397 = dev_get_drvdata(dev: pdev->dev.parent); |
2919 | |
2920 | dev_dbg(&pdev->dev, "%s(), dev name %s\n" , |
2921 | __func__, dev_name(&pdev->dev)); |
2922 | |
2923 | priv = devm_kzalloc(dev: &pdev->dev, size: sizeof(*priv), GFP_KERNEL); |
2924 | if (!priv) |
2925 | return -ENOMEM; |
2926 | |
2927 | priv->regmap = mt6397->regmap; |
2928 | if (IS_ERR(ptr: priv->regmap)) |
2929 | return PTR_ERR(ptr: priv->regmap); |
2930 | |
2931 | dev_set_drvdata(dev: &pdev->dev, data: priv); |
2932 | priv->dev = &pdev->dev; |
2933 | |
2934 | ret = mt6359_parse_dt(priv); |
2935 | if (ret) { |
2936 | dev_warn(&pdev->dev, "%s() failed to parse dts\n" , __func__); |
2937 | return ret; |
2938 | } |
2939 | |
2940 | return devm_snd_soc_register_component(dev: &pdev->dev, |
2941 | component_driver: &mt6359_soc_component_driver, |
2942 | dai_drv: mt6359_dai_driver, |
2943 | ARRAY_SIZE(mt6359_dai_driver)); |
2944 | } |
2945 | |
2946 | static struct platform_driver mt6359_platform_driver = { |
2947 | .driver = { |
2948 | .name = "mt6359-sound" , |
2949 | }, |
2950 | .probe = mt6359_platform_driver_probe, |
2951 | }; |
2952 | |
2953 | module_platform_driver(mt6359_platform_driver) |
2954 | |
2955 | /* Module information */ |
2956 | MODULE_DESCRIPTION("MT6359 ALSA SoC codec driver" ); |
2957 | MODULE_AUTHOR("KaiChieh Chuang <kaichieh.chuang@mediatek.com>" ); |
2958 | MODULE_AUTHOR("Eason Yen <eason.yen@mediatek.com>" ); |
2959 | MODULE_LICENSE("GPL v2" ); |
2960 | |