1 | // SPDX-License-Identifier: GPL-2.0 |
2 | // |
3 | // mt6351.c -- mt6351 ALSA SoC audio codec driver |
4 | // |
5 | // Copyright (c) 2018 MediaTek Inc. |
6 | // Author: KaiChieh Chuang <kaichieh.chuang@mediatek.com> |
7 | |
8 | #include <linux/dma-mapping.h> |
9 | #include <linux/platform_device.h> |
10 | #include <linux/slab.h> |
11 | #include <linux/mod_devicetable.h> |
12 | #include <linux/module.h> |
13 | #include <linux/delay.h> |
14 | |
15 | #include <sound/core.h> |
16 | #include <sound/pcm.h> |
17 | #include <sound/soc.h> |
18 | #include <sound/tlv.h> |
19 | |
20 | #include "mt6351.h" |
21 | |
22 | /* MT6351_TOP_CLKSQ */ |
23 | #define RG_CLKSQ_EN_AUD_BIT (0) |
24 | |
25 | /* MT6351_TOP_CKPDN_CON0 */ |
26 | #define RG_AUDNCP_CK_PDN_BIT (12) |
27 | #define RG_AUDIF_CK_PDN_BIT (13) |
28 | #define RG_AUD_CK_PDN_BIT (14) |
29 | #define RG_ZCD13M_CK_PDN_BIT (15) |
30 | |
31 | /* MT6351_AUDDEC_ANA_CON0 */ |
32 | #define RG_AUDDACLPWRUP_VAUDP32_BIT (0) |
33 | #define RG_AUDDACRPWRUP_VAUDP32_BIT (1) |
34 | #define RG_AUD_DAC_PWR_UP_VA32_BIT (2) |
35 | #define RG_AUD_DAC_PWL_UP_VA32_BIT (3) |
36 | |
37 | #define RG_AUDHSPWRUP_VAUDP32_BIT (4) |
38 | |
39 | #define RG_AUDHPLPWRUP_VAUDP32_BIT (5) |
40 | #define RG_AUDHPRPWRUP_VAUDP32_BIT (6) |
41 | |
42 | #define RG_AUDHSMUXINPUTSEL_VAUDP32_SFT (7) |
43 | #define RG_AUDHSMUXINPUTSEL_VAUDP32_MASK (0x3) |
44 | |
45 | #define RG_AUDHPLMUXINPUTSEL_VAUDP32_SFT (9) |
46 | #define RG_AUDHPLMUXINPUTSEL_VAUDP32_MASK (0x3) |
47 | |
48 | #define RG_AUDHPRMUXINPUTSEL_VAUDP32_SFT (11) |
49 | #define RG_AUDHPRMUXINPUTSEL_VAUDP32_MASK (0x3) |
50 | |
51 | #define RG_AUDHSSCDISABLE_VAUDP32 (13) |
52 | #define RG_AUDHPLSCDISABLE_VAUDP32_BIT (14) |
53 | #define RG_AUDHPRSCDISABLE_VAUDP32_BIT (15) |
54 | |
55 | /* MT6351_AUDDEC_ANA_CON1 */ |
56 | #define RG_HSOUTPUTSTBENH_VAUDP32_BIT (8) |
57 | |
58 | /* MT6351_AUDDEC_ANA_CON3 */ |
59 | #define RG_AUDLOLPWRUP_VAUDP32_BIT (2) |
60 | |
61 | #define RG_AUDLOLMUXINPUTSEL_VAUDP32_SFT (3) |
62 | #define RG_AUDLOLMUXINPUTSEL_VAUDP32_MASK (0x3) |
63 | |
64 | #define RG_AUDLOLSCDISABLE_VAUDP32_BIT (5) |
65 | #define RG_LOOUTPUTSTBENH_VAUDP32_BIT (9) |
66 | |
67 | /* MT6351_AUDDEC_ANA_CON6 */ |
68 | #define RG_ABIDEC_RSVD0_VAUDP32_HPL_BIT (8) |
69 | #define RG_ABIDEC_RSVD0_VAUDP32_HPR_BIT (9) |
70 | #define RG_ABIDEC_RSVD0_VAUDP32_HS_BIT (10) |
71 | #define RG_ABIDEC_RSVD0_VAUDP32_LOL_BIT (11) |
72 | |
73 | /* MT6351_AUDDEC_ANA_CON9 */ |
74 | #define RG_AUDIBIASPWRDN_VAUDP32_BIT (8) |
75 | #define RG_RSTB_DECODER_VA32_BIT (9) |
76 | #define RG_AUDGLB_PWRDN_VA32_BIT (12) |
77 | |
78 | #define RG_LCLDO_DEC_EN_VA32_BIT (13) |
79 | #define RG_LCLDO_DEC_REMOTE_SENSE_VA18_BIT (15) |
80 | /* MT6351_AUDDEC_ANA_CON10 */ |
81 | #define RG_NVREG_EN_VAUDP32_BIT (8) |
82 | |
83 | #define RG_AUDGLB_LP2_VOW_EN_VA32 10 |
84 | |
85 | /* MT6351_AFE_UL_DL_CON0 */ |
86 | #define RG_AFE_ON_BIT (0) |
87 | |
88 | /* MT6351_AFE_DL_SRC2_CON0_L */ |
89 | #define RG_DL_2_SRC_ON_TMP_CTL_PRE_BIT (0) |
90 | |
91 | /* MT6351_AFE_UL_SRC_CON0_L */ |
92 | #define UL_SRC_ON_TMP_CTL (0) |
93 | |
94 | /* MT6351_AFE_TOP_CON0 */ |
95 | #define RG_DL_SINE_ON_SFT (0) |
96 | #define RG_DL_SINE_ON_MASK (0x1) |
97 | |
98 | #define RG_UL_SINE_ON_SFT (1) |
99 | #define RG_UL_SINE_ON_MASK (0x1) |
100 | |
101 | /* MT6351_AUDIO_TOP_CON0 */ |
102 | #define AUD_TOP_PDN_RESERVED_BIT 0 |
103 | #define AUD_TOP_PWR_CLK_DIS_CTL_BIT 2 |
104 | #define AUD_TOP_PDN_ADC_CTL_BIT 5 |
105 | #define AUD_TOP_PDN_DAC_CTL_BIT 6 |
106 | #define AUD_TOP_PDN_AFE_CTL_BIT 7 |
107 | |
108 | /* MT6351_AFE_SGEN_CFG0 */ |
109 | #define SGEN_C_MUTE_SW_CTL_BIT 6 |
110 | #define SGEN_C_DAC_EN_CTL_BIT 7 |
111 | |
112 | /* MT6351_AFE_NCP_CFG0 */ |
113 | #define RG_NCP_ON_BIT 0 |
114 | |
115 | /* MT6351_LDO_VUSB33_CON0 */ |
116 | #define RG_VUSB33_EN 1 |
117 | #define RG_VUSB33_ON_CTRL 3 |
118 | |
119 | /* MT6351_LDO_VA18_CON0 */ |
120 | #define RG_VA18_EN 1 |
121 | #define RG_VA18_ON_CTRL 3 |
122 | |
123 | /* MT6351_AUDENC_ANA_CON0 */ |
124 | #define RG_AUDPREAMPLON 0 |
125 | #define RG_AUDPREAMPLDCCEN 1 |
126 | #define RG_AUDPREAMPLDCPRECHARGE 2 |
127 | |
128 | #define RG_AUDPREAMPLINPUTSEL_SFT (4) |
129 | #define RG_AUDPREAMPLINPUTSEL_MASK (0x3) |
130 | |
131 | #define RG_AUDADCLPWRUP 12 |
132 | |
133 | #define RG_AUDADCLINPUTSEL_SFT (13) |
134 | #define RG_AUDADCLINPUTSEL_MASK (0x3) |
135 | |
136 | /* MT6351_AUDENC_ANA_CON1 */ |
137 | #define RG_AUDPREAMPRON 0 |
138 | #define RG_AUDPREAMPRDCCEN 1 |
139 | #define RG_AUDPREAMPRDCPRECHARGE 2 |
140 | |
141 | #define RG_AUDPREAMPRINPUTSEL_SFT (4) |
142 | #define RG_AUDPREAMPRINPUTSEL_MASK (0x3) |
143 | |
144 | #define RG_AUDADCRPWRUP 12 |
145 | |
146 | #define RG_AUDADCRINPUTSEL_SFT (13) |
147 | #define RG_AUDADCRINPUTSEL_MASK (0x3) |
148 | |
149 | /* MT6351_AUDENC_ANA_CON3 */ |
150 | #define RG_AUDADCCLKRSTB 6 |
151 | |
152 | /* MT6351_AUDENC_ANA_CON9 */ |
153 | #define RG_AUDPWDBMICBIAS0 0 |
154 | #define RG_AUDMICBIAS0VREF 4 |
155 | #define RG_AUDMICBIAS0LOWPEN 7 |
156 | |
157 | #define RG_AUDPWDBMICBIAS2 8 |
158 | #define RG_AUDMICBIAS2VREF 12 |
159 | #define RG_AUDMICBIAS2LOWPEN 15 |
160 | |
161 | /* MT6351_AUDENC_ANA_CON10 */ |
162 | #define RG_AUDPWDBMICBIAS1 0 |
163 | #define RG_AUDMICBIAS1DCSW1NEN 2 |
164 | #define RG_AUDMICBIAS1VREF 4 |
165 | #define RG_AUDMICBIAS1LOWPEN 7 |
166 | |
167 | enum { |
168 | AUDIO_ANALOG_VOLUME_HSOUTL, |
169 | AUDIO_ANALOG_VOLUME_HSOUTR, |
170 | AUDIO_ANALOG_VOLUME_HPOUTL, |
171 | AUDIO_ANALOG_VOLUME_HPOUTR, |
172 | AUDIO_ANALOG_VOLUME_LINEOUTL, |
173 | AUDIO_ANALOG_VOLUME_LINEOUTR, |
174 | AUDIO_ANALOG_VOLUME_MICAMP1, |
175 | AUDIO_ANALOG_VOLUME_MICAMP2, |
176 | AUDIO_ANALOG_VOLUME_TYPE_MAX |
177 | }; |
178 | |
179 | /* Supply subseq */ |
180 | enum { |
181 | SUPPLY_SUBSEQ_SETTING, |
182 | SUPPLY_SUBSEQ_ENABLE, |
183 | SUPPLY_SUBSEQ_MICBIAS, |
184 | }; |
185 | |
186 | #define REG_STRIDE 2 |
187 | |
188 | struct mt6351_priv { |
189 | struct device *dev; |
190 | struct regmap *regmap; |
191 | |
192 | unsigned int dl_rate; |
193 | unsigned int ul_rate; |
194 | |
195 | int ana_gain[AUDIO_ANALOG_VOLUME_TYPE_MAX]; |
196 | |
197 | int hp_en_counter; |
198 | }; |
199 | |
200 | static void set_hp_gain_zero(struct snd_soc_component *cmpnt) |
201 | { |
202 | regmap_update_bits(map: cmpnt->regmap, MT6351_ZCD_CON2, |
203 | mask: 0x1f << 7, val: 0x8 << 7); |
204 | regmap_update_bits(map: cmpnt->regmap, MT6351_ZCD_CON2, |
205 | mask: 0x1f << 0, val: 0x8 << 0); |
206 | } |
207 | |
208 | static unsigned int get_cap_reg_val(struct snd_soc_component *cmpnt, |
209 | unsigned int rate) |
210 | { |
211 | switch (rate) { |
212 | case 8000: |
213 | return 0; |
214 | case 16000: |
215 | return 1; |
216 | case 32000: |
217 | return 2; |
218 | case 48000: |
219 | return 3; |
220 | case 96000: |
221 | return 4; |
222 | case 192000: |
223 | return 5; |
224 | default: |
225 | dev_warn(cmpnt->dev, "%s(), error rate %d, return 3" , |
226 | __func__, rate); |
227 | return 3; |
228 | } |
229 | } |
230 | |
231 | static unsigned int get_play_reg_val(struct snd_soc_component *cmpnt, |
232 | unsigned int rate) |
233 | { |
234 | switch (rate) { |
235 | case 8000: |
236 | return 0; |
237 | case 11025: |
238 | return 1; |
239 | case 12000: |
240 | return 2; |
241 | case 16000: |
242 | return 3; |
243 | case 22050: |
244 | return 4; |
245 | case 24000: |
246 | return 5; |
247 | case 32000: |
248 | return 6; |
249 | case 44100: |
250 | return 7; |
251 | case 48000: |
252 | case 96000: |
253 | case 192000: |
254 | return 8; |
255 | default: |
256 | dev_warn(cmpnt->dev, "%s(), error rate %d, return 8" , |
257 | __func__, rate); |
258 | return 8; |
259 | } |
260 | } |
261 | |
262 | static int mt6351_codec_dai_hw_params(struct snd_pcm_substream *substream, |
263 | struct snd_pcm_hw_params *params, |
264 | struct snd_soc_dai *dai) |
265 | { |
266 | struct snd_soc_component *cmpnt = dai->component; |
267 | struct mt6351_priv *priv = snd_soc_component_get_drvdata(c: cmpnt); |
268 | unsigned int rate = params_rate(p: params); |
269 | |
270 | dev_dbg(priv->dev, "%s(), substream->stream %d, rate %d\n" , |
271 | __func__, substream->stream, rate); |
272 | |
273 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) |
274 | priv->dl_rate = rate; |
275 | else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) |
276 | priv->ul_rate = rate; |
277 | |
278 | return 0; |
279 | } |
280 | |
281 | static const struct snd_soc_dai_ops mt6351_codec_dai_ops = { |
282 | .hw_params = mt6351_codec_dai_hw_params, |
283 | }; |
284 | |
285 | #define MT6351_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_LE |\ |
286 | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_U24_LE |\ |
287 | SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_U32_LE) |
288 | |
289 | static struct snd_soc_dai_driver mt6351_dai_driver[] = { |
290 | { |
291 | .name = "mt6351-snd-codec-aif1" , |
292 | .playback = { |
293 | .stream_name = "AIF1 Playback" , |
294 | .channels_min = 1, |
295 | .channels_max = 2, |
296 | .rates = SNDRV_PCM_RATE_8000_48000 | |
297 | SNDRV_PCM_RATE_96000 | |
298 | SNDRV_PCM_RATE_192000, |
299 | .formats = MT6351_FORMATS, |
300 | }, |
301 | .capture = { |
302 | .stream_name = "AIF1 Capture" , |
303 | .channels_min = 1, |
304 | .channels_max = 2, |
305 | .rates = SNDRV_PCM_RATE_8000 | |
306 | SNDRV_PCM_RATE_16000 | |
307 | SNDRV_PCM_RATE_32000 | |
308 | SNDRV_PCM_RATE_48000 | |
309 | SNDRV_PCM_RATE_96000 | |
310 | SNDRV_PCM_RATE_192000, |
311 | .formats = MT6351_FORMATS, |
312 | }, |
313 | .ops = &mt6351_codec_dai_ops, |
314 | }, |
315 | }; |
316 | |
317 | enum { |
318 | HP_GAIN_SET_ZERO, |
319 | HP_GAIN_RESTORE, |
320 | }; |
321 | |
322 | static void hp_gain_ramp_set(struct snd_soc_component *cmpnt, int hp_gain_ctl) |
323 | { |
324 | struct mt6351_priv *priv = snd_soc_component_get_drvdata(c: cmpnt); |
325 | int idx, old_idx, offset, reg_idx; |
326 | |
327 | if (hp_gain_ctl == HP_GAIN_SET_ZERO) { |
328 | idx = 8; /* 0dB */ |
329 | old_idx = priv->ana_gain[AUDIO_ANALOG_VOLUME_HPOUTL]; |
330 | } else { |
331 | idx = priv->ana_gain[AUDIO_ANALOG_VOLUME_HPOUTL]; |
332 | old_idx = 8; /* 0dB */ |
333 | } |
334 | dev_dbg(priv->dev, "%s(), idx %d, old_idx %d\n" , |
335 | __func__, idx, old_idx); |
336 | |
337 | if (idx > old_idx) |
338 | offset = idx - old_idx; |
339 | else |
340 | offset = old_idx - idx; |
341 | |
342 | reg_idx = old_idx; |
343 | |
344 | while (offset > 0) { |
345 | reg_idx = idx > old_idx ? reg_idx + 1 : reg_idx - 1; |
346 | |
347 | /* check valid range, and set value */ |
348 | if ((reg_idx >= 0 && reg_idx <= 0x12) || reg_idx == 0x1f) { |
349 | regmap_update_bits(map: cmpnt->regmap, |
350 | MT6351_ZCD_CON2, |
351 | mask: 0xf9f, |
352 | val: (reg_idx << 7) | reg_idx); |
353 | usleep_range(min: 100, max: 120); |
354 | } |
355 | offset--; |
356 | } |
357 | } |
358 | |
359 | static void hp_zcd_enable(struct snd_soc_component *cmpnt) |
360 | { |
361 | /* Enable ZCD, for minimize pop noise */ |
362 | /* when adjust gain during HP buffer on */ |
363 | regmap_update_bits(map: cmpnt->regmap, MT6351_ZCD_CON0, mask: 0x7 << 8, val: 0x1 << 8); |
364 | regmap_update_bits(map: cmpnt->regmap, MT6351_ZCD_CON0, mask: 0x1 << 7, val: 0x0 << 7); |
365 | |
366 | /* timeout, 1=5ms, 0=30ms */ |
367 | regmap_update_bits(map: cmpnt->regmap, MT6351_ZCD_CON0, mask: 0x1 << 6, val: 0x1 << 6); |
368 | |
369 | regmap_update_bits(map: cmpnt->regmap, MT6351_ZCD_CON0, mask: 0x3 << 4, val: 0x0 << 4); |
370 | regmap_update_bits(map: cmpnt->regmap, MT6351_ZCD_CON0, mask: 0x7 << 1, val: 0x5 << 1); |
371 | regmap_update_bits(map: cmpnt->regmap, MT6351_ZCD_CON0, mask: 0x1 << 0, val: 0x1 << 0); |
372 | } |
373 | |
374 | static void hp_zcd_disable(struct snd_soc_component *cmpnt) |
375 | { |
376 | regmap_write(map: cmpnt->regmap, MT6351_ZCD_CON0, val: 0x0000); |
377 | } |
378 | |
379 | static const DECLARE_TLV_DB_SCALE(playback_tlv, -1000, 100, 0); |
380 | static const DECLARE_TLV_DB_SCALE(pga_tlv, 0, 600, 0); |
381 | |
382 | static const struct snd_kcontrol_new mt6351_snd_controls[] = { |
383 | /* dl pga gain */ |
384 | SOC_DOUBLE_TLV("Headphone Volume" , |
385 | MT6351_ZCD_CON2, 0, 7, 0x12, 1, |
386 | playback_tlv), |
387 | SOC_DOUBLE_TLV("Lineout Volume" , |
388 | MT6351_ZCD_CON1, 0, 7, 0x12, 1, |
389 | playback_tlv), |
390 | SOC_SINGLE_TLV("Handset Volume" , |
391 | MT6351_ZCD_CON3, 0, 0x12, 1, |
392 | playback_tlv), |
393 | /* ul pga gain */ |
394 | SOC_DOUBLE_R_TLV("PGA Volume" , |
395 | MT6351_AUDENC_ANA_CON0, MT6351_AUDENC_ANA_CON1, |
396 | 8, 4, 0, |
397 | pga_tlv), |
398 | }; |
399 | |
400 | /* MUX */ |
401 | |
402 | /* LOL MUX */ |
403 | static const char *const lo_in_mux_map[] = { |
404 | "Open" , "Mute" , "Playback" , "Test Mode" , |
405 | }; |
406 | |
407 | static int lo_in_mux_map_value[] = { |
408 | 0x0, 0x1, 0x2, 0x3, |
409 | }; |
410 | |
411 | static SOC_VALUE_ENUM_SINGLE_DECL(lo_in_mux_map_enum, |
412 | MT6351_AUDDEC_ANA_CON3, |
413 | RG_AUDLOLMUXINPUTSEL_VAUDP32_SFT, |
414 | RG_AUDLOLMUXINPUTSEL_VAUDP32_MASK, |
415 | lo_in_mux_map, |
416 | lo_in_mux_map_value); |
417 | |
418 | static const struct snd_kcontrol_new lo_in_mux_control = |
419 | SOC_DAPM_ENUM("In Select" , lo_in_mux_map_enum); |
420 | |
421 | /*HP MUX */ |
422 | static const char *const hp_in_mux_map[] = { |
423 | "Open" , "LoudSPK Playback" , "Audio Playback" , "Test Mode" , |
424 | }; |
425 | |
426 | static int hp_in_mux_map_value[] = { |
427 | 0x0, 0x1, 0x2, 0x3, |
428 | }; |
429 | |
430 | static SOC_VALUE_ENUM_SINGLE_DECL(hpl_in_mux_map_enum, |
431 | MT6351_AUDDEC_ANA_CON0, |
432 | RG_AUDHPLMUXINPUTSEL_VAUDP32_SFT, |
433 | RG_AUDHPLMUXINPUTSEL_VAUDP32_MASK, |
434 | hp_in_mux_map, |
435 | hp_in_mux_map_value); |
436 | |
437 | static const struct snd_kcontrol_new hpl_in_mux_control = |
438 | SOC_DAPM_ENUM("HPL Select" , hpl_in_mux_map_enum); |
439 | |
440 | static SOC_VALUE_ENUM_SINGLE_DECL(hpr_in_mux_map_enum, |
441 | MT6351_AUDDEC_ANA_CON0, |
442 | RG_AUDHPRMUXINPUTSEL_VAUDP32_SFT, |
443 | RG_AUDHPRMUXINPUTSEL_VAUDP32_MASK, |
444 | hp_in_mux_map, |
445 | hp_in_mux_map_value); |
446 | |
447 | static const struct snd_kcontrol_new hpr_in_mux_control = |
448 | SOC_DAPM_ENUM("HPR Select" , hpr_in_mux_map_enum); |
449 | |
450 | /* RCV MUX */ |
451 | static const char *const rcv_in_mux_map[] = { |
452 | "Open" , "Mute" , "Voice Playback" , "Test Mode" , |
453 | }; |
454 | |
455 | static int rcv_in_mux_map_value[] = { |
456 | 0x0, 0x1, 0x2, 0x3, |
457 | }; |
458 | |
459 | static SOC_VALUE_ENUM_SINGLE_DECL(rcv_in_mux_map_enum, |
460 | MT6351_AUDDEC_ANA_CON0, |
461 | RG_AUDHSMUXINPUTSEL_VAUDP32_SFT, |
462 | RG_AUDHSMUXINPUTSEL_VAUDP32_MASK, |
463 | rcv_in_mux_map, |
464 | rcv_in_mux_map_value); |
465 | |
466 | static const struct snd_kcontrol_new rcv_in_mux_control = |
467 | SOC_DAPM_ENUM("RCV Select" , rcv_in_mux_map_enum); |
468 | |
469 | /* DAC In MUX */ |
470 | static const char *const dac_in_mux_map[] = { |
471 | "Normal Path" , "Sgen" , |
472 | }; |
473 | |
474 | static int dac_in_mux_map_value[] = { |
475 | 0x0, 0x1, |
476 | }; |
477 | |
478 | static SOC_VALUE_ENUM_SINGLE_DECL(dac_in_mux_map_enum, |
479 | MT6351_AFE_TOP_CON0, |
480 | RG_DL_SINE_ON_SFT, |
481 | RG_DL_SINE_ON_MASK, |
482 | dac_in_mux_map, |
483 | dac_in_mux_map_value); |
484 | |
485 | static const struct snd_kcontrol_new dac_in_mux_control = |
486 | SOC_DAPM_ENUM("DAC Select" , dac_in_mux_map_enum); |
487 | |
488 | /* AIF Out MUX */ |
489 | static SOC_VALUE_ENUM_SINGLE_DECL(aif_out_mux_map_enum, |
490 | MT6351_AFE_TOP_CON0, |
491 | RG_UL_SINE_ON_SFT, |
492 | RG_UL_SINE_ON_MASK, |
493 | dac_in_mux_map, |
494 | dac_in_mux_map_value); |
495 | |
496 | static const struct snd_kcontrol_new aif_out_mux_control = |
497 | SOC_DAPM_ENUM("AIF Out Select" , aif_out_mux_map_enum); |
498 | |
499 | /* ADC L MUX */ |
500 | static const char *const adc_left_mux_map[] = { |
501 | "Idle" , "AIN0" , "Left Preamplifier" , "Idle_1" , |
502 | }; |
503 | |
504 | static int adc_left_mux_map_value[] = { |
505 | 0x0, 0x1, 0x2, 0x3, |
506 | }; |
507 | |
508 | static SOC_VALUE_ENUM_SINGLE_DECL(adc_left_mux_map_enum, |
509 | MT6351_AUDENC_ANA_CON0, |
510 | RG_AUDADCLINPUTSEL_SFT, |
511 | RG_AUDADCLINPUTSEL_MASK, |
512 | adc_left_mux_map, |
513 | adc_left_mux_map_value); |
514 | |
515 | static const struct snd_kcontrol_new adc_left_mux_control = |
516 | SOC_DAPM_ENUM("ADC L Select" , adc_left_mux_map_enum); |
517 | |
518 | /* ADC R MUX */ |
519 | static const char *const adc_right_mux_map[] = { |
520 | "Idle" , "AIN0" , "Right Preamplifier" , "Idle_1" , |
521 | }; |
522 | |
523 | static int adc_right_mux_map_value[] = { |
524 | 0x0, 0x1, 0x2, 0x3, |
525 | }; |
526 | |
527 | static SOC_VALUE_ENUM_SINGLE_DECL(adc_right_mux_map_enum, |
528 | MT6351_AUDENC_ANA_CON1, |
529 | RG_AUDADCRINPUTSEL_SFT, |
530 | RG_AUDADCRINPUTSEL_MASK, |
531 | adc_right_mux_map, |
532 | adc_right_mux_map_value); |
533 | |
534 | static const struct snd_kcontrol_new adc_right_mux_control = |
535 | SOC_DAPM_ENUM("ADC R Select" , adc_right_mux_map_enum); |
536 | |
537 | /* PGA L MUX */ |
538 | static const char *const pga_left_mux_map[] = { |
539 | "None" , "AIN0" , "AIN1" , "AIN2" , |
540 | }; |
541 | |
542 | static int pga_left_mux_map_value[] = { |
543 | 0x0, 0x1, 0x2, 0x3, |
544 | }; |
545 | |
546 | static SOC_VALUE_ENUM_SINGLE_DECL(pga_left_mux_map_enum, |
547 | MT6351_AUDENC_ANA_CON0, |
548 | RG_AUDPREAMPLINPUTSEL_SFT, |
549 | RG_AUDPREAMPLINPUTSEL_MASK, |
550 | pga_left_mux_map, |
551 | pga_left_mux_map_value); |
552 | |
553 | static const struct snd_kcontrol_new pga_left_mux_control = |
554 | SOC_DAPM_ENUM("PGA L Select" , pga_left_mux_map_enum); |
555 | |
556 | /* PGA R MUX */ |
557 | static const char *const pga_right_mux_map[] = { |
558 | "None" , "AIN0" , "AIN3" , "AIN2" , |
559 | }; |
560 | |
561 | static int pga_right_mux_map_value[] = { |
562 | 0x0, 0x1, 0x2, 0x3, |
563 | }; |
564 | |
565 | static SOC_VALUE_ENUM_SINGLE_DECL(pga_right_mux_map_enum, |
566 | MT6351_AUDENC_ANA_CON1, |
567 | RG_AUDPREAMPRINPUTSEL_SFT, |
568 | RG_AUDPREAMPRINPUTSEL_MASK, |
569 | pga_right_mux_map, |
570 | pga_right_mux_map_value); |
571 | |
572 | static const struct snd_kcontrol_new pga_right_mux_control = |
573 | SOC_DAPM_ENUM("PGA R Select" , pga_right_mux_map_enum); |
574 | |
575 | static int mt_reg_set_clr_event(struct snd_soc_dapm_widget *w, |
576 | struct snd_kcontrol *kcontrol, |
577 | int event) |
578 | { |
579 | struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(dapm: w->dapm); |
580 | |
581 | switch (event) { |
582 | case SND_SOC_DAPM_POST_PMU: |
583 | if (w->on_val) { |
584 | /* SET REG */ |
585 | regmap_update_bits(map: cmpnt->regmap, |
586 | reg: w->reg + REG_STRIDE, |
587 | mask: 0x1 << w->shift, |
588 | val: 0x1 << w->shift); |
589 | } else { |
590 | /* CLR REG */ |
591 | regmap_update_bits(map: cmpnt->regmap, |
592 | reg: w->reg + REG_STRIDE * 2, |
593 | mask: 0x1 << w->shift, |
594 | val: 0x1 << w->shift); |
595 | } |
596 | break; |
597 | case SND_SOC_DAPM_PRE_PMD: |
598 | if (w->off_val) { |
599 | /* SET REG */ |
600 | regmap_update_bits(map: cmpnt->regmap, |
601 | reg: w->reg + REG_STRIDE, |
602 | mask: 0x1 << w->shift, |
603 | val: 0x1 << w->shift); |
604 | } else { |
605 | /* CLR REG */ |
606 | regmap_update_bits(map: cmpnt->regmap, |
607 | reg: w->reg + REG_STRIDE * 2, |
608 | mask: 0x1 << w->shift, |
609 | val: 0x1 << w->shift); |
610 | } |
611 | break; |
612 | default: |
613 | break; |
614 | } |
615 | |
616 | return 0; |
617 | } |
618 | |
619 | static int mt_ncp_event(struct snd_soc_dapm_widget *w, |
620 | struct snd_kcontrol *kcontrol, |
621 | int event) |
622 | { |
623 | struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(dapm: w->dapm); |
624 | |
625 | switch (event) { |
626 | case SND_SOC_DAPM_PRE_PMU: |
627 | regmap_update_bits(map: cmpnt->regmap, MT6351_AFE_NCP_CFG1, |
628 | mask: 0xffff, val: 0x1515); |
629 | /* NCP: ck1 and ck2 clock frequecy adjust configure */ |
630 | regmap_update_bits(map: cmpnt->regmap, MT6351_AFE_NCP_CFG0, |
631 | mask: 0xfffe, val: 0x8C00); |
632 | break; |
633 | case SND_SOC_DAPM_POST_PMU: |
634 | usleep_range(min: 250, max: 270); |
635 | break; |
636 | default: |
637 | break; |
638 | } |
639 | |
640 | return 0; |
641 | } |
642 | |
643 | static int mt_sgen_event(struct snd_soc_dapm_widget *w, |
644 | struct snd_kcontrol *kcontrol, |
645 | int event) |
646 | { |
647 | struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(dapm: w->dapm); |
648 | |
649 | switch (event) { |
650 | case SND_SOC_DAPM_PRE_PMU: |
651 | regmap_update_bits(map: cmpnt->regmap, MT6351_AFE_SGEN_CFG0, |
652 | mask: 0xffef, val: 0x0008); |
653 | regmap_update_bits(map: cmpnt->regmap, MT6351_AFE_SGEN_CFG1, |
654 | mask: 0xffff, val: 0x0101); |
655 | break; |
656 | default: |
657 | break; |
658 | } |
659 | |
660 | return 0; |
661 | } |
662 | |
663 | static int mt_aif_in_event(struct snd_soc_dapm_widget *w, |
664 | struct snd_kcontrol *kcontrol, |
665 | int event) |
666 | { |
667 | struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(dapm: w->dapm); |
668 | struct mt6351_priv *priv = snd_soc_component_get_drvdata(c: cmpnt); |
669 | |
670 | dev_dbg(priv->dev, "%s(), event 0x%x, rate %d\n" , |
671 | __func__, event, priv->dl_rate); |
672 | |
673 | switch (event) { |
674 | case SND_SOC_DAPM_PRE_PMU: |
675 | /* sdm audio fifo clock power on */ |
676 | regmap_update_bits(map: cmpnt->regmap, MT6351_AFUNC_AUD_CON2, |
677 | mask: 0xffff, val: 0x0006); |
678 | /* scrambler clock on enable */ |
679 | regmap_update_bits(map: cmpnt->regmap, MT6351_AFUNC_AUD_CON0, |
680 | mask: 0xffff, val: 0xC3A1); |
681 | /* sdm power on */ |
682 | regmap_update_bits(map: cmpnt->regmap, MT6351_AFUNC_AUD_CON2, |
683 | mask: 0xffff, val: 0x0003); |
684 | /* sdm fifo enable */ |
685 | regmap_update_bits(map: cmpnt->regmap, MT6351_AFUNC_AUD_CON2, |
686 | mask: 0xffff, val: 0x000B); |
687 | /* set attenuation gain */ |
688 | regmap_update_bits(map: cmpnt->regmap, MT6351_AFE_DL_SDM_CON1, |
689 | mask: 0xffff, val: 0x001E); |
690 | |
691 | regmap_write(map: cmpnt->regmap, MT6351_AFE_PMIC_NEWIF_CFG0, |
692 | val: (get_play_reg_val(cmpnt, rate: priv->dl_rate) << 12) | |
693 | 0x330); |
694 | regmap_write(map: cmpnt->regmap, MT6351_AFE_DL_SRC2_CON0_H, |
695 | val: (get_play_reg_val(cmpnt, rate: priv->dl_rate) << 12) | |
696 | 0x300); |
697 | |
698 | regmap_update_bits(map: cmpnt->regmap, MT6351_AFE_PMIC_NEWIF_CFG2, |
699 | mask: 0x8000, val: 0x8000); |
700 | break; |
701 | default: |
702 | break; |
703 | } |
704 | |
705 | return 0; |
706 | } |
707 | |
708 | static int mt_hp_event(struct snd_soc_dapm_widget *w, |
709 | struct snd_kcontrol *kcontrol, |
710 | int event) |
711 | { |
712 | struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(dapm: w->dapm); |
713 | struct mt6351_priv *priv = snd_soc_component_get_drvdata(c: cmpnt); |
714 | int reg; |
715 | |
716 | dev_dbg(priv->dev, "%s(), event 0x%x, hp_en_counter %d\n" , |
717 | __func__, event, priv->hp_en_counter); |
718 | |
719 | switch (event) { |
720 | case SND_SOC_DAPM_PRE_PMU: |
721 | priv->hp_en_counter++; |
722 | if (priv->hp_en_counter > 1) |
723 | break; /* already enabled, do nothing */ |
724 | else if (priv->hp_en_counter <= 0) |
725 | dev_err(priv->dev, "%s(), hp_en_counter %d <= 0\n" , |
726 | __func__, |
727 | priv->hp_en_counter); |
728 | |
729 | hp_zcd_disable(cmpnt); |
730 | |
731 | /* from yoyo HQA script */ |
732 | regmap_update_bits(map: cmpnt->regmap, MT6351_AUDDEC_ANA_CON6, |
733 | mask: 0x0700, val: 0x0700); |
734 | |
735 | /* save target gain to restore after hardware open complete */ |
736 | regmap_read(map: cmpnt->regmap, MT6351_ZCD_CON2, val: ®); |
737 | priv->ana_gain[AUDIO_ANALOG_VOLUME_HPOUTL] = reg & 0x1f; |
738 | priv->ana_gain[AUDIO_ANALOG_VOLUME_HPOUTR] = (reg >> 7) & 0x1f; |
739 | |
740 | /* Set HPR/HPL gain as minimum (~ -40dB) */ |
741 | regmap_update_bits(map: cmpnt->regmap, |
742 | MT6351_ZCD_CON2, mask: 0xffff, val: 0x0F9F); |
743 | /* Set HS gain as minimum (~ -40dB) */ |
744 | regmap_update_bits(map: cmpnt->regmap, |
745 | MT6351_ZCD_CON3, mask: 0xffff, val: 0x001F); |
746 | /* De_OSC of HP */ |
747 | regmap_update_bits(map: cmpnt->regmap, MT6351_AUDDEC_ANA_CON2, |
748 | mask: 0x0001, val: 0x0001); |
749 | /* enable output STBENH */ |
750 | regmap_update_bits(map: cmpnt->regmap, MT6351_AUDDEC_ANA_CON1, |
751 | mask: 0xffff, val: 0x2000); |
752 | /* De_OSC of voice, enable output STBENH */ |
753 | regmap_update_bits(map: cmpnt->regmap, MT6351_AUDDEC_ANA_CON1, |
754 | mask: 0xffff, val: 0x2100); |
755 | /* Enable voice driver */ |
756 | regmap_update_bits(map: cmpnt->regmap, MT6351_AUDDEC_ANA_CON0, |
757 | mask: 0x0010, val: 0xE090); |
758 | /* Enable pre-charge buffer */ |
759 | regmap_update_bits(map: cmpnt->regmap, MT6351_AUDDEC_ANA_CON1, |
760 | mask: 0xffff, val: 0x2140); |
761 | |
762 | usleep_range(min: 50, max: 60); |
763 | |
764 | /* Apply digital DC compensation value to DAC */ |
765 | set_hp_gain_zero(cmpnt); |
766 | |
767 | /* Enable HPR/HPL */ |
768 | regmap_update_bits(map: cmpnt->regmap, MT6351_AUDDEC_ANA_CON1, |
769 | mask: 0xffff, val: 0x2100); |
770 | /* Disable pre-charge buffer */ |
771 | regmap_update_bits(map: cmpnt->regmap, MT6351_AUDDEC_ANA_CON1, |
772 | mask: 0xffff, val: 0x2000); |
773 | /* Disable De_OSC of voice */ |
774 | regmap_update_bits(map: cmpnt->regmap, MT6351_AUDDEC_ANA_CON0, |
775 | mask: 0x0010, val: 0xF4EF); |
776 | /* Disable voice buffer */ |
777 | |
778 | /* from yoyo HQ */ |
779 | regmap_update_bits(map: cmpnt->regmap, MT6351_AUDDEC_ANA_CON6, |
780 | mask: 0x0700, val: 0x0300); |
781 | |
782 | /* Enable ZCD, for minimize pop noise */ |
783 | /* when adjust gain during HP buffer on */ |
784 | hp_zcd_enable(cmpnt); |
785 | |
786 | /* apply volume setting */ |
787 | hp_gain_ramp_set(cmpnt, hp_gain_ctl: HP_GAIN_RESTORE); |
788 | |
789 | break; |
790 | case SND_SOC_DAPM_PRE_PMD: |
791 | priv->hp_en_counter--; |
792 | if (priv->hp_en_counter > 0) |
793 | break; /* still being used, don't close */ |
794 | else if (priv->hp_en_counter < 0) |
795 | dev_err(priv->dev, "%s(), hp_en_counter %d <= 0\n" , |
796 | __func__, |
797 | priv->hp_en_counter); |
798 | |
799 | /* Disable AUD_ZCD */ |
800 | hp_zcd_disable(cmpnt); |
801 | |
802 | /* Set HPR/HPL gain as -1dB, step by step */ |
803 | hp_gain_ramp_set(cmpnt, hp_gain_ctl: HP_GAIN_SET_ZERO); |
804 | |
805 | set_hp_gain_zero(cmpnt); |
806 | break; |
807 | case SND_SOC_DAPM_POST_PMD: |
808 | if (priv->hp_en_counter > 0) |
809 | break; /* still being used, don't close */ |
810 | else if (priv->hp_en_counter < 0) |
811 | dev_err(priv->dev, "%s(), hp_en_counter %d <= 0\n" , |
812 | __func__, |
813 | priv->hp_en_counter); |
814 | |
815 | /* reset*/ |
816 | regmap_update_bits(map: cmpnt->regmap, |
817 | MT6351_AUDDEC_ANA_CON6, |
818 | mask: 0x0700, |
819 | val: 0x0000); |
820 | /* De_OSC of HP */ |
821 | regmap_update_bits(map: cmpnt->regmap, |
822 | MT6351_AUDDEC_ANA_CON2, |
823 | mask: 0x0001, |
824 | val: 0x0000); |
825 | |
826 | /* apply volume setting */ |
827 | hp_gain_ramp_set(cmpnt, hp_gain_ctl: HP_GAIN_RESTORE); |
828 | break; |
829 | default: |
830 | break; |
831 | } |
832 | |
833 | return 0; |
834 | } |
835 | |
836 | static int mt_aif_out_event(struct snd_soc_dapm_widget *w, |
837 | struct snd_kcontrol *kcontrol, |
838 | int event) |
839 | { |
840 | struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(dapm: w->dapm); |
841 | struct mt6351_priv *priv = snd_soc_component_get_drvdata(c: cmpnt); |
842 | |
843 | dev_dbg(priv->dev, "%s(), event 0x%x, rate %d\n" , |
844 | __func__, event, priv->ul_rate); |
845 | |
846 | switch (event) { |
847 | case SND_SOC_DAPM_PRE_PMU: |
848 | /* dcclk_div=11'b00100000011, dcclk_ref_ck_sel=2'b00 */ |
849 | regmap_update_bits(map: cmpnt->regmap, MT6351_AFE_DCCLK_CFG0, |
850 | mask: 0xffff, val: 0x2062); |
851 | /* dcclk_pdn=1'b0 */ |
852 | regmap_update_bits(map: cmpnt->regmap, MT6351_AFE_DCCLK_CFG0, |
853 | mask: 0xffff, val: 0x2060); |
854 | /* dcclk_gen_on=1'b1 */ |
855 | regmap_update_bits(map: cmpnt->regmap, MT6351_AFE_DCCLK_CFG0, |
856 | mask: 0xffff, val: 0x2061); |
857 | |
858 | /* UL sample rate and mode configure */ |
859 | regmap_update_bits(map: cmpnt->regmap, MT6351_AFE_UL_SRC_CON0_H, |
860 | mask: 0x000E, |
861 | val: get_cap_reg_val(cmpnt, rate: priv->ul_rate) << 1); |
862 | |
863 | /* fixed 260k path for 8/16/32/48 */ |
864 | if (priv->ul_rate <= 48000) { |
865 | /* anc ul path src on */ |
866 | regmap_update_bits(map: cmpnt->regmap, |
867 | MT6351_AFE_HPANC_CFG0, |
868 | mask: 0x1 << 1, |
869 | val: 0x1 << 1); |
870 | /* ANC clk pdn release */ |
871 | regmap_update_bits(map: cmpnt->regmap, |
872 | MT6351_AFE_HPANC_CFG0, |
873 | mask: 0x1 << 0, |
874 | val: 0x0 << 0); |
875 | } |
876 | break; |
877 | case SND_SOC_DAPM_PRE_PMD: |
878 | /* fixed 260k path for 8/16/32/48 */ |
879 | if (priv->ul_rate <= 48000) { |
880 | /* anc ul path src on */ |
881 | regmap_update_bits(map: cmpnt->regmap, |
882 | MT6351_AFE_HPANC_CFG0, |
883 | mask: 0x1 << 1, |
884 | val: 0x0 << 1); |
885 | /* ANC clk pdn release */ |
886 | regmap_update_bits(map: cmpnt->regmap, |
887 | MT6351_AFE_HPANC_CFG0, |
888 | mask: 0x1 << 0, |
889 | val: 0x1 << 0); |
890 | } |
891 | break; |
892 | default: |
893 | break; |
894 | } |
895 | |
896 | return 0; |
897 | } |
898 | |
899 | static int mt_adc_clkgen_event(struct snd_soc_dapm_widget *w, |
900 | struct snd_kcontrol *kcontrol, |
901 | int event) |
902 | { |
903 | struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(dapm: w->dapm); |
904 | |
905 | switch (event) { |
906 | case SND_SOC_DAPM_PRE_PMU: |
907 | /* Audio ADC clock gen. mode: 00_divided by 2 (Normal) */ |
908 | regmap_update_bits(map: cmpnt->regmap, MT6351_AUDENC_ANA_CON3, |
909 | mask: 0x3 << 4, val: 0x0); |
910 | break; |
911 | case SND_SOC_DAPM_POST_PMU: |
912 | /* ADC CLK from: 00_13MHz from CLKSQ (Default) */ |
913 | regmap_update_bits(map: cmpnt->regmap, MT6351_AUDENC_ANA_CON3, |
914 | mask: 0x3 << 2, val: 0x0); |
915 | break; |
916 | default: |
917 | break; |
918 | } |
919 | return 0; |
920 | } |
921 | |
922 | static int mt_pga_left_event(struct snd_soc_dapm_widget *w, |
923 | struct snd_kcontrol *kcontrol, |
924 | int event) |
925 | { |
926 | struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(dapm: w->dapm); |
927 | |
928 | switch (event) { |
929 | case SND_SOC_DAPM_PRE_PMU: |
930 | /* Audio L PGA precharge on */ |
931 | regmap_update_bits(map: cmpnt->regmap, MT6351_AUDENC_ANA_CON0, |
932 | mask: 0x3 << RG_AUDPREAMPLDCPRECHARGE, |
933 | val: 0x1 << RG_AUDPREAMPLDCPRECHARGE); |
934 | /* Audio L PGA mode: 1_DCC */ |
935 | regmap_update_bits(map: cmpnt->regmap, MT6351_AUDENC_ANA_CON0, |
936 | mask: 0x3 << RG_AUDPREAMPLDCCEN, |
937 | val: 0x1 << RG_AUDPREAMPLDCCEN); |
938 | break; |
939 | case SND_SOC_DAPM_POST_PMU: |
940 | usleep_range(min: 100, max: 120); |
941 | /* Audio L PGA precharge off */ |
942 | regmap_update_bits(map: cmpnt->regmap, MT6351_AUDENC_ANA_CON0, |
943 | mask: 0x3 << RG_AUDPREAMPLDCPRECHARGE, |
944 | val: 0x0 << RG_AUDPREAMPLDCPRECHARGE); |
945 | break; |
946 | default: |
947 | break; |
948 | } |
949 | return 0; |
950 | } |
951 | |
952 | static int mt_pga_right_event(struct snd_soc_dapm_widget *w, |
953 | struct snd_kcontrol *kcontrol, |
954 | int event) |
955 | { |
956 | struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(dapm: w->dapm); |
957 | |
958 | switch (event) { |
959 | case SND_SOC_DAPM_PRE_PMU: |
960 | /* Audio R PGA precharge on */ |
961 | regmap_update_bits(map: cmpnt->regmap, MT6351_AUDENC_ANA_CON1, |
962 | mask: 0x3 << RG_AUDPREAMPRDCPRECHARGE, |
963 | val: 0x1 << RG_AUDPREAMPRDCPRECHARGE); |
964 | /* Audio R PGA mode: 1_DCC */ |
965 | regmap_update_bits(map: cmpnt->regmap, MT6351_AUDENC_ANA_CON1, |
966 | mask: 0x3 << RG_AUDPREAMPRDCCEN, |
967 | val: 0x1 << RG_AUDPREAMPRDCCEN); |
968 | break; |
969 | case SND_SOC_DAPM_POST_PMU: |
970 | usleep_range(min: 100, max: 120); |
971 | /* Audio R PGA precharge off */ |
972 | regmap_update_bits(map: cmpnt->regmap, MT6351_AUDENC_ANA_CON1, |
973 | mask: 0x3 << RG_AUDPREAMPRDCPRECHARGE, |
974 | val: 0x0 << RG_AUDPREAMPRDCPRECHARGE); |
975 | break; |
976 | default: |
977 | break; |
978 | } |
979 | return 0; |
980 | } |
981 | |
982 | static int mt_mic_bias_0_event(struct snd_soc_dapm_widget *w, |
983 | struct snd_kcontrol *kcontrol, |
984 | int event) |
985 | { |
986 | struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(dapm: w->dapm); |
987 | |
988 | switch (event) { |
989 | case SND_SOC_DAPM_PRE_PMU: |
990 | /* MIC Bias 0 LowPower: 0_Normal */ |
991 | regmap_update_bits(map: cmpnt->regmap, MT6351_AUDENC_ANA_CON9, |
992 | mask: 0x3 << RG_AUDMICBIAS0LOWPEN, val: 0x0); |
993 | /* MISBIAS0 = 1P9V */ |
994 | regmap_update_bits(map: cmpnt->regmap, MT6351_AUDENC_ANA_CON9, |
995 | mask: 0x7 << RG_AUDMICBIAS0VREF, |
996 | val: 0x2 << RG_AUDMICBIAS0VREF); |
997 | break; |
998 | case SND_SOC_DAPM_POST_PMD: |
999 | /* MISBIAS0 = 1P97 */ |
1000 | regmap_update_bits(map: cmpnt->regmap, MT6351_AUDENC_ANA_CON9, |
1001 | mask: 0x7 << RG_AUDMICBIAS0VREF, |
1002 | val: 0x0 << RG_AUDMICBIAS0VREF); |
1003 | break; |
1004 | default: |
1005 | break; |
1006 | } |
1007 | return 0; |
1008 | } |
1009 | |
1010 | static int mt_mic_bias_1_event(struct snd_soc_dapm_widget *w, |
1011 | struct snd_kcontrol *kcontrol, |
1012 | int event) |
1013 | { |
1014 | struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(dapm: w->dapm); |
1015 | |
1016 | switch (event) { |
1017 | case SND_SOC_DAPM_PRE_PMU: |
1018 | /* MIC Bias 1 LowPower: 0_Normal */ |
1019 | regmap_update_bits(map: cmpnt->regmap, MT6351_AUDENC_ANA_CON10, |
1020 | mask: 0x3 << RG_AUDMICBIAS1LOWPEN, val: 0x0); |
1021 | /* MISBIAS1 = 2P7V */ |
1022 | regmap_update_bits(map: cmpnt->regmap, MT6351_AUDENC_ANA_CON10, |
1023 | mask: 0x7 << RG_AUDMICBIAS1VREF, |
1024 | val: 0x7 << RG_AUDMICBIAS1VREF); |
1025 | break; |
1026 | case SND_SOC_DAPM_POST_PMD: |
1027 | /* MISBIAS1 = 1P7V */ |
1028 | regmap_update_bits(map: cmpnt->regmap, MT6351_AUDENC_ANA_CON10, |
1029 | mask: 0x7 << RG_AUDMICBIAS1VREF, |
1030 | val: 0x0 << RG_AUDMICBIAS1VREF); |
1031 | break; |
1032 | default: |
1033 | break; |
1034 | } |
1035 | return 0; |
1036 | } |
1037 | |
1038 | static int mt_mic_bias_2_event(struct snd_soc_dapm_widget *w, |
1039 | struct snd_kcontrol *kcontrol, |
1040 | int event) |
1041 | { |
1042 | struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(dapm: w->dapm); |
1043 | |
1044 | switch (event) { |
1045 | case SND_SOC_DAPM_PRE_PMU: |
1046 | /* MIC Bias 2 LowPower: 0_Normal */ |
1047 | regmap_update_bits(map: cmpnt->regmap, MT6351_AUDENC_ANA_CON9, |
1048 | mask: 0x3 << RG_AUDMICBIAS2LOWPEN, val: 0x0); |
1049 | /* MISBIAS2 = 1P9V */ |
1050 | regmap_update_bits(map: cmpnt->regmap, MT6351_AUDENC_ANA_CON9, |
1051 | mask: 0x7 << RG_AUDMICBIAS2VREF, |
1052 | val: 0x2 << RG_AUDMICBIAS2VREF); |
1053 | break; |
1054 | case SND_SOC_DAPM_POST_PMD: |
1055 | /* MISBIAS2 = 1P97 */ |
1056 | regmap_update_bits(map: cmpnt->regmap, MT6351_AUDENC_ANA_CON9, |
1057 | mask: 0x7 << RG_AUDMICBIAS2VREF, |
1058 | val: 0x0 << RG_AUDMICBIAS2VREF); |
1059 | break; |
1060 | default: |
1061 | break; |
1062 | } |
1063 | return 0; |
1064 | } |
1065 | |
1066 | /* DAPM Widgets */ |
1067 | static const struct snd_soc_dapm_widget mt6351_dapm_widgets[] = { |
1068 | /* Digital Clock */ |
1069 | SND_SOC_DAPM_SUPPLY("AUDIO_TOP_AFE_CTL" , MT6351_AUDIO_TOP_CON0, |
1070 | AUD_TOP_PDN_AFE_CTL_BIT, 1, NULL, 0), |
1071 | SND_SOC_DAPM_SUPPLY("AUDIO_TOP_DAC_CTL" , MT6351_AUDIO_TOP_CON0, |
1072 | AUD_TOP_PDN_DAC_CTL_BIT, 1, NULL, 0), |
1073 | SND_SOC_DAPM_SUPPLY("AUDIO_TOP_ADC_CTL" , MT6351_AUDIO_TOP_CON0, |
1074 | AUD_TOP_PDN_ADC_CTL_BIT, 1, NULL, 0), |
1075 | SND_SOC_DAPM_SUPPLY("AUDIO_TOP_PWR_CLK" , MT6351_AUDIO_TOP_CON0, |
1076 | AUD_TOP_PWR_CLK_DIS_CTL_BIT, 1, NULL, 0), |
1077 | SND_SOC_DAPM_SUPPLY("AUDIO_TOP_PDN_RESERVED" , MT6351_AUDIO_TOP_CON0, |
1078 | AUD_TOP_PDN_RESERVED_BIT, 1, NULL, 0), |
1079 | |
1080 | SND_SOC_DAPM_SUPPLY("NCP" , MT6351_AFE_NCP_CFG0, |
1081 | RG_NCP_ON_BIT, 0, |
1082 | mt_ncp_event, |
1083 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), |
1084 | |
1085 | SND_SOC_DAPM_SUPPLY("DL Digital Clock" , SND_SOC_NOPM, |
1086 | 0, 0, NULL, 0), |
1087 | |
1088 | /* Global Supply*/ |
1089 | SND_SOC_DAPM_SUPPLY("AUDGLB" , MT6351_AUDDEC_ANA_CON9, |
1090 | RG_AUDGLB_PWRDN_VA32_BIT, 1, NULL, 0), |
1091 | SND_SOC_DAPM_SUPPLY("CLKSQ Audio" , MT6351_TOP_CLKSQ, |
1092 | RG_CLKSQ_EN_AUD_BIT, 0, |
1093 | mt_reg_set_clr_event, |
1094 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), |
1095 | SND_SOC_DAPM_SUPPLY("ZCD13M_CK" , MT6351_TOP_CKPDN_CON0, |
1096 | RG_ZCD13M_CK_PDN_BIT, 1, |
1097 | mt_reg_set_clr_event, |
1098 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), |
1099 | SND_SOC_DAPM_SUPPLY("AUD_CK" , MT6351_TOP_CKPDN_CON0, |
1100 | RG_AUD_CK_PDN_BIT, 1, |
1101 | mt_reg_set_clr_event, |
1102 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), |
1103 | SND_SOC_DAPM_SUPPLY("AUDIF_CK" , MT6351_TOP_CKPDN_CON0, |
1104 | RG_AUDIF_CK_PDN_BIT, 1, |
1105 | mt_reg_set_clr_event, |
1106 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), |
1107 | SND_SOC_DAPM_SUPPLY("AUDNCP_CK" , MT6351_TOP_CKPDN_CON0, |
1108 | RG_AUDNCP_CK_PDN_BIT, 1, |
1109 | mt_reg_set_clr_event, |
1110 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), |
1111 | |
1112 | SND_SOC_DAPM_SUPPLY("AFE_ON" , MT6351_AFE_UL_DL_CON0, RG_AFE_ON_BIT, 0, |
1113 | NULL, 0), |
1114 | |
1115 | /* AIF Rx*/ |
1116 | SND_SOC_DAPM_AIF_IN_E("AIF_RX" , "AIF1 Playback" , 0, |
1117 | MT6351_AFE_DL_SRC2_CON0_L, |
1118 | RG_DL_2_SRC_ON_TMP_CTL_PRE_BIT, 0, |
1119 | mt_aif_in_event, SND_SOC_DAPM_PRE_PMU), |
1120 | |
1121 | /* DL Supply */ |
1122 | SND_SOC_DAPM_SUPPLY("DL Power Supply" , SND_SOC_NOPM, |
1123 | 0, 0, NULL, 0), |
1124 | SND_SOC_DAPM_SUPPLY("NV Regulator" , MT6351_AUDDEC_ANA_CON10, |
1125 | RG_NVREG_EN_VAUDP32_BIT, 0, NULL, 0), |
1126 | SND_SOC_DAPM_SUPPLY("AUD_CLK" , MT6351_AUDDEC_ANA_CON9, |
1127 | RG_RSTB_DECODER_VA32_BIT, 0, NULL, 0), |
1128 | SND_SOC_DAPM_SUPPLY("IBIST" , MT6351_AUDDEC_ANA_CON9, |
1129 | RG_AUDIBIASPWRDN_VAUDP32_BIT, 1, NULL, 0), |
1130 | SND_SOC_DAPM_SUPPLY("LDO" , MT6351_AUDDEC_ANA_CON9, |
1131 | RG_LCLDO_DEC_EN_VA32_BIT, 0, NULL, 0), |
1132 | SND_SOC_DAPM_SUPPLY("LDO_REMOTE_SENSE" , MT6351_AUDDEC_ANA_CON9, |
1133 | RG_LCLDO_DEC_REMOTE_SENSE_VA18_BIT, 0, NULL, 0), |
1134 | |
1135 | /* DAC */ |
1136 | SND_SOC_DAPM_MUX("DAC In Mux" , SND_SOC_NOPM, 0, 0, &dac_in_mux_control), |
1137 | |
1138 | SND_SOC_DAPM_DAC("DACL" , NULL, MT6351_AUDDEC_ANA_CON0, |
1139 | RG_AUDDACLPWRUP_VAUDP32_BIT, 0), |
1140 | SND_SOC_DAPM_SUPPLY("DACL_BIASGEN" , MT6351_AUDDEC_ANA_CON0, |
1141 | RG_AUD_DAC_PWL_UP_VA32_BIT, 0, NULL, 0), |
1142 | |
1143 | SND_SOC_DAPM_DAC("DACR" , NULL, MT6351_AUDDEC_ANA_CON0, |
1144 | RG_AUDDACRPWRUP_VAUDP32_BIT, 0), |
1145 | SND_SOC_DAPM_SUPPLY("DACR_BIASGEN" , MT6351_AUDDEC_ANA_CON0, |
1146 | RG_AUD_DAC_PWR_UP_VA32_BIT, 0, NULL, 0), |
1147 | /* LOL */ |
1148 | SND_SOC_DAPM_MUX("LOL Mux" , SND_SOC_NOPM, 0, 0, &lo_in_mux_control), |
1149 | |
1150 | SND_SOC_DAPM_SUPPLY("LO Stability Enh" , MT6351_AUDDEC_ANA_CON3, |
1151 | RG_LOOUTPUTSTBENH_VAUDP32_BIT, 0, NULL, 0), |
1152 | SND_SOC_DAPM_SUPPLY("LOL Bias Gen" , MT6351_AUDDEC_ANA_CON6, |
1153 | RG_ABIDEC_RSVD0_VAUDP32_LOL_BIT, 0, NULL, 0), |
1154 | |
1155 | SND_SOC_DAPM_OUT_DRV("LOL Buffer" , MT6351_AUDDEC_ANA_CON3, |
1156 | RG_AUDLOLPWRUP_VAUDP32_BIT, 0, NULL, 0), |
1157 | |
1158 | /* Headphone */ |
1159 | SND_SOC_DAPM_MUX("HPL Mux" , SND_SOC_NOPM, 0, 0, &hpl_in_mux_control), |
1160 | SND_SOC_DAPM_MUX("HPR Mux" , SND_SOC_NOPM, 0, 0, &hpr_in_mux_control), |
1161 | |
1162 | SND_SOC_DAPM_OUT_DRV_E("HPL Power" , MT6351_AUDDEC_ANA_CON0, |
1163 | RG_AUDHPLPWRUP_VAUDP32_BIT, 0, NULL, 0, |
1164 | mt_hp_event, |
1165 | SND_SOC_DAPM_PRE_PMU | |
1166 | SND_SOC_DAPM_PRE_PMD | |
1167 | SND_SOC_DAPM_POST_PMD), |
1168 | SND_SOC_DAPM_OUT_DRV_E("HPR Power" , MT6351_AUDDEC_ANA_CON0, |
1169 | RG_AUDHPRPWRUP_VAUDP32_BIT, 0, NULL, 0, |
1170 | mt_hp_event, |
1171 | SND_SOC_DAPM_PRE_PMU | |
1172 | SND_SOC_DAPM_PRE_PMD | |
1173 | SND_SOC_DAPM_POST_PMD), |
1174 | |
1175 | /* Receiver */ |
1176 | SND_SOC_DAPM_MUX("RCV Mux" , SND_SOC_NOPM, 0, 0, &rcv_in_mux_control), |
1177 | |
1178 | SND_SOC_DAPM_SUPPLY("RCV Stability Enh" , MT6351_AUDDEC_ANA_CON1, |
1179 | RG_HSOUTPUTSTBENH_VAUDP32_BIT, 0, NULL, 0), |
1180 | SND_SOC_DAPM_SUPPLY("RCV Bias Gen" , MT6351_AUDDEC_ANA_CON6, |
1181 | RG_ABIDEC_RSVD0_VAUDP32_HS_BIT, 0, NULL, 0), |
1182 | |
1183 | SND_SOC_DAPM_OUT_DRV("RCV Buffer" , MT6351_AUDDEC_ANA_CON0, |
1184 | RG_AUDHSPWRUP_VAUDP32_BIT, 0, NULL, 0), |
1185 | |
1186 | /* Outputs */ |
1187 | SND_SOC_DAPM_OUTPUT("Receiver" ), |
1188 | SND_SOC_DAPM_OUTPUT("Headphone L" ), |
1189 | SND_SOC_DAPM_OUTPUT("Headphone R" ), |
1190 | SND_SOC_DAPM_OUTPUT("LINEOUT L" ), |
1191 | |
1192 | /* SGEN */ |
1193 | SND_SOC_DAPM_SUPPLY("SGEN DL Enable" , MT6351_AFE_SGEN_CFG0, |
1194 | SGEN_C_DAC_EN_CTL_BIT, 0, NULL, 0), |
1195 | SND_SOC_DAPM_SUPPLY("SGEN MUTE" , MT6351_AFE_SGEN_CFG0, |
1196 | SGEN_C_MUTE_SW_CTL_BIT, 1, |
1197 | mt_sgen_event, SND_SOC_DAPM_PRE_PMU), |
1198 | SND_SOC_DAPM_SUPPLY("SGEN DL SRC" , MT6351_AFE_DL_SRC2_CON0_L, |
1199 | RG_DL_2_SRC_ON_TMP_CTL_PRE_BIT, 0, NULL, 0), |
1200 | |
1201 | SND_SOC_DAPM_INPUT("SGEN DL" ), |
1202 | |
1203 | /* Uplinks */ |
1204 | SND_SOC_DAPM_AIF_OUT_E("AIF1TX" , "AIF1 Capture" , 0, |
1205 | MT6351_AFE_UL_SRC_CON0_L, |
1206 | UL_SRC_ON_TMP_CTL, 0, |
1207 | mt_aif_out_event, |
1208 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), |
1209 | |
1210 | SND_SOC_DAPM_SUPPLY_S("VUSB33_LDO" , SUPPLY_SUBSEQ_ENABLE, |
1211 | MT6351_LDO_VUSB33_CON0, RG_VUSB33_EN, 0, |
1212 | NULL, 0), |
1213 | SND_SOC_DAPM_SUPPLY_S("VUSB33_LDO_CTRL" , SUPPLY_SUBSEQ_SETTING, |
1214 | MT6351_LDO_VUSB33_CON0, RG_VUSB33_ON_CTRL, 1, |
1215 | NULL, 0), |
1216 | |
1217 | SND_SOC_DAPM_SUPPLY_S("VA18_LDO" , SUPPLY_SUBSEQ_ENABLE, |
1218 | MT6351_LDO_VA18_CON0, RG_VA18_EN, 0, NULL, 0), |
1219 | SND_SOC_DAPM_SUPPLY_S("VA18_LDO_CTRL" , SUPPLY_SUBSEQ_SETTING, |
1220 | MT6351_LDO_VA18_CON0, RG_VA18_ON_CTRL, 1, |
1221 | NULL, 0), |
1222 | |
1223 | SND_SOC_DAPM_SUPPLY_S("ADC CLKGEN" , SUPPLY_SUBSEQ_ENABLE, |
1224 | MT6351_AUDENC_ANA_CON3, RG_AUDADCCLKRSTB, 0, |
1225 | mt_adc_clkgen_event, |
1226 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), |
1227 | |
1228 | /* Uplinks MUX */ |
1229 | SND_SOC_DAPM_MUX("AIF Out Mux" , SND_SOC_NOPM, 0, 0, |
1230 | &aif_out_mux_control), |
1231 | |
1232 | SND_SOC_DAPM_MUX("ADC L Mux" , SND_SOC_NOPM, 0, 0, |
1233 | &adc_left_mux_control), |
1234 | SND_SOC_DAPM_MUX("ADC R Mux" , SND_SOC_NOPM, 0, 0, |
1235 | &adc_right_mux_control), |
1236 | |
1237 | SND_SOC_DAPM_ADC("ADC L" , NULL, |
1238 | MT6351_AUDENC_ANA_CON0, RG_AUDADCLPWRUP, 0), |
1239 | SND_SOC_DAPM_ADC("ADC R" , NULL, |
1240 | MT6351_AUDENC_ANA_CON1, RG_AUDADCRPWRUP, 0), |
1241 | |
1242 | SND_SOC_DAPM_MUX("PGA L Mux" , SND_SOC_NOPM, 0, 0, |
1243 | &pga_left_mux_control), |
1244 | SND_SOC_DAPM_MUX("PGA R Mux" , SND_SOC_NOPM, 0, 0, |
1245 | &pga_right_mux_control), |
1246 | |
1247 | SND_SOC_DAPM_PGA_E("PGA L" , MT6351_AUDENC_ANA_CON0, RG_AUDPREAMPLON, 0, |
1248 | NULL, 0, |
1249 | mt_pga_left_event, |
1250 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), |
1251 | SND_SOC_DAPM_PGA_E("PGA R" , MT6351_AUDENC_ANA_CON1, RG_AUDPREAMPRON, 0, |
1252 | NULL, 0, |
1253 | mt_pga_right_event, |
1254 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), |
1255 | |
1256 | /* main mic mic bias */ |
1257 | SND_SOC_DAPM_SUPPLY_S("Mic Bias 0" , SUPPLY_SUBSEQ_MICBIAS, |
1258 | MT6351_AUDENC_ANA_CON9, RG_AUDPWDBMICBIAS0, 0, |
1259 | mt_mic_bias_0_event, |
1260 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), |
1261 | /* ref mic mic bias */ |
1262 | SND_SOC_DAPM_SUPPLY_S("Mic Bias 2" , SUPPLY_SUBSEQ_MICBIAS, |
1263 | MT6351_AUDENC_ANA_CON9, RG_AUDPWDBMICBIAS2, 0, |
1264 | mt_mic_bias_2_event, |
1265 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), |
1266 | /* headset mic1/2 mic bias */ |
1267 | SND_SOC_DAPM_SUPPLY_S("Mic Bias 1" , SUPPLY_SUBSEQ_MICBIAS, |
1268 | MT6351_AUDENC_ANA_CON10, RG_AUDPWDBMICBIAS1, 0, |
1269 | mt_mic_bias_1_event, |
1270 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), |
1271 | SND_SOC_DAPM_SUPPLY_S("Mic Bias 1 DCC pull high" , SUPPLY_SUBSEQ_MICBIAS, |
1272 | MT6351_AUDENC_ANA_CON10, |
1273 | RG_AUDMICBIAS1DCSW1NEN, 0, |
1274 | NULL, 0), |
1275 | |
1276 | /* UL input */ |
1277 | SND_SOC_DAPM_INPUT("AIN0" ), |
1278 | SND_SOC_DAPM_INPUT("AIN1" ), |
1279 | SND_SOC_DAPM_INPUT("AIN2" ), |
1280 | SND_SOC_DAPM_INPUT("AIN3" ), |
1281 | }; |
1282 | |
1283 | static const struct snd_soc_dapm_route mt6351_dapm_routes[] = { |
1284 | /* Capture */ |
1285 | {"AIF1TX" , NULL, "AIF Out Mux" }, |
1286 | {"AIF1TX" , NULL, "VUSB33_LDO" }, |
1287 | {"VUSB33_LDO" , NULL, "VUSB33_LDO_CTRL" }, |
1288 | {"AIF1TX" , NULL, "VA18_LDO" }, |
1289 | {"VA18_LDO" , NULL, "VA18_LDO_CTRL" }, |
1290 | |
1291 | {"AIF1TX" , NULL, "AUDGLB" }, |
1292 | {"AIF1TX" , NULL, "CLKSQ Audio" }, |
1293 | |
1294 | {"AIF1TX" , NULL, "AFE_ON" }, |
1295 | |
1296 | {"AIF1TX" , NULL, "AUDIO_TOP_AFE_CTL" }, |
1297 | {"AIF1TX" , NULL, "AUDIO_TOP_ADC_CTL" }, |
1298 | {"AIF1TX" , NULL, "AUDIO_TOP_PWR_CLK" }, |
1299 | {"AIF1TX" , NULL, "AUDIO_TOP_PDN_RESERVED" }, |
1300 | |
1301 | {"AIF Out Mux" , "Normal Path" , "ADC L" }, |
1302 | {"AIF Out Mux" , "Normal Path" , "ADC R" }, |
1303 | |
1304 | {"ADC L" , NULL, "ADC L Mux" }, |
1305 | {"ADC L" , NULL, "AUD_CK" }, |
1306 | {"ADC L" , NULL, "AUDIF_CK" }, |
1307 | {"ADC L" , NULL, "ADC CLKGEN" }, |
1308 | {"ADC R" , NULL, "ADC R Mux" }, |
1309 | {"ADC R" , NULL, "AUD_CK" }, |
1310 | {"ADC R" , NULL, "AUDIF_CK" }, |
1311 | {"ADC R" , NULL, "ADC CLKGEN" }, |
1312 | |
1313 | {"ADC L Mux" , "AIN0" , "AIN0" }, |
1314 | {"ADC L Mux" , "Left Preamplifier" , "PGA L" }, |
1315 | |
1316 | {"ADC R Mux" , "AIN0" , "AIN0" }, |
1317 | {"ADC R Mux" , "Right Preamplifier" , "PGA R" }, |
1318 | |
1319 | {"PGA L" , NULL, "PGA L Mux" }, |
1320 | {"PGA R" , NULL, "PGA R Mux" }, |
1321 | |
1322 | {"PGA L Mux" , "AIN0" , "AIN0" }, |
1323 | {"PGA L Mux" , "AIN1" , "AIN1" }, |
1324 | {"PGA L Mux" , "AIN2" , "AIN2" }, |
1325 | |
1326 | {"PGA R Mux" , "AIN0" , "AIN0" }, |
1327 | {"PGA R Mux" , "AIN3" , "AIN3" }, |
1328 | {"PGA R Mux" , "AIN2" , "AIN2" }, |
1329 | |
1330 | {"AIN0" , NULL, "Mic Bias 0" }, |
1331 | {"AIN2" , NULL, "Mic Bias 2" }, |
1332 | |
1333 | {"AIN1" , NULL, "Mic Bias 1" }, |
1334 | {"AIN1" , NULL, "Mic Bias 1 DCC pull high" }, |
1335 | |
1336 | /* DL Supply */ |
1337 | {"DL Power Supply" , NULL, "AUDGLB" }, |
1338 | {"DL Power Supply" , NULL, "CLKSQ Audio" }, |
1339 | {"DL Power Supply" , NULL, "ZCD13M_CK" }, |
1340 | {"DL Power Supply" , NULL, "AUD_CK" }, |
1341 | {"DL Power Supply" , NULL, "AUDIF_CK" }, |
1342 | {"DL Power Supply" , NULL, "AUDNCP_CK" }, |
1343 | |
1344 | {"DL Power Supply" , NULL, "NV Regulator" }, |
1345 | {"DL Power Supply" , NULL, "AUD_CLK" }, |
1346 | {"DL Power Supply" , NULL, "IBIST" }, |
1347 | {"DL Power Supply" , NULL, "LDO" }, |
1348 | {"LDO" , NULL, "LDO_REMOTE_SENSE" }, |
1349 | |
1350 | /* DL Digital Supply */ |
1351 | {"DL Digital Clock" , NULL, "AUDIO_TOP_AFE_CTL" }, |
1352 | {"DL Digital Clock" , NULL, "AUDIO_TOP_DAC_CTL" }, |
1353 | {"DL Digital Clock" , NULL, "AUDIO_TOP_PWR_CLK" }, |
1354 | {"DL Digital Clock" , NULL, "AUDIO_TOP_PDN_RESERVED" }, |
1355 | {"DL Digital Clock" , NULL, "NCP" }, |
1356 | {"DL Digital Clock" , NULL, "AFE_ON" }, |
1357 | |
1358 | {"AIF_RX" , NULL, "DL Digital Clock" }, |
1359 | |
1360 | /* DL Path */ |
1361 | {"DAC In Mux" , "Normal Path" , "AIF_RX" }, |
1362 | |
1363 | {"DAC In Mux" , "Sgen" , "SGEN DL" }, |
1364 | {"SGEN DL" , NULL, "SGEN DL SRC" }, |
1365 | {"SGEN DL" , NULL, "SGEN MUTE" }, |
1366 | {"SGEN DL" , NULL, "SGEN DL Enable" }, |
1367 | {"SGEN DL" , NULL, "DL Digital Clock" }, |
1368 | |
1369 | {"DACL" , NULL, "DAC In Mux" }, |
1370 | {"DACL" , NULL, "DL Power Supply" }, |
1371 | {"DACL" , NULL, "DACL_BIASGEN" }, |
1372 | |
1373 | {"DACR" , NULL, "DAC In Mux" }, |
1374 | {"DACR" , NULL, "DL Power Supply" }, |
1375 | {"DACR" , NULL, "DACR_BIASGEN" }, |
1376 | |
1377 | {"LOL Mux" , "Playback" , "DACL" }, |
1378 | |
1379 | {"LOL Buffer" , NULL, "LOL Mux" }, |
1380 | {"LOL Buffer" , NULL, "LO Stability Enh" }, |
1381 | {"LOL Buffer" , NULL, "LOL Bias Gen" }, |
1382 | |
1383 | {"LINEOUT L" , NULL, "LOL Buffer" }, |
1384 | |
1385 | /* Headphone Path */ |
1386 | {"HPL Mux" , "Audio Playback" , "DACL" }, |
1387 | {"HPR Mux" , "Audio Playback" , "DACR" }, |
1388 | |
1389 | {"HPL Mux" , "LoudSPK Playback" , "DACL" }, |
1390 | {"HPR Mux" , "LoudSPK Playback" , "DACR" }, |
1391 | |
1392 | {"HPL Power" , NULL, "HPL Mux" }, |
1393 | {"HPR Power" , NULL, "HPR Mux" }, |
1394 | |
1395 | {"Headphone L" , NULL, "HPL Power" }, |
1396 | {"Headphone R" , NULL, "HPR Power" }, |
1397 | |
1398 | /* Receiver Path */ |
1399 | {"RCV Mux" , "Voice Playback" , "DACL" }, |
1400 | |
1401 | {"RCV Buffer" , NULL, "RCV Mux" }, |
1402 | {"RCV Buffer" , NULL, "RCV Stability Enh" }, |
1403 | {"RCV Buffer" , NULL, "RCV Bias Gen" }, |
1404 | |
1405 | {"Receiver" , NULL, "RCV Buffer" }, |
1406 | }; |
1407 | |
1408 | static int mt6351_codec_init_reg(struct snd_soc_component *cmpnt) |
1409 | { |
1410 | /* Disable CLKSQ 26MHz */ |
1411 | regmap_update_bits(map: cmpnt->regmap, MT6351_TOP_CLKSQ, mask: 0x0001, val: 0x0); |
1412 | /* disable AUDGLB */ |
1413 | regmap_update_bits(map: cmpnt->regmap, MT6351_AUDDEC_ANA_CON9, |
1414 | mask: 0x1000, val: 0x1000); |
1415 | /* Turn off AUDNCP_CLKDIV engine clock,Turn off AUD 26M */ |
1416 | regmap_update_bits(map: cmpnt->regmap, MT6351_TOP_CKPDN_CON0_SET, |
1417 | mask: 0x3800, val: 0x3800); |
1418 | /* Disable HeadphoneL/HeadphoneR/voice short circuit protection */ |
1419 | regmap_update_bits(map: cmpnt->regmap, MT6351_AUDDEC_ANA_CON0, |
1420 | mask: 0xe000, val: 0xe000); |
1421 | /* [5] = 1, disable LO buffer left short circuit protection */ |
1422 | regmap_update_bits(map: cmpnt->regmap, MT6351_AUDDEC_ANA_CON3, |
1423 | mask: 0x20, val: 0x20); |
1424 | /* Reverse the PMIC clock*/ |
1425 | regmap_update_bits(map: cmpnt->regmap, MT6351_AFE_PMIC_NEWIF_CFG2, |
1426 | mask: 0x8000, val: 0x8000); |
1427 | return 0; |
1428 | } |
1429 | |
1430 | static int mt6351_codec_probe(struct snd_soc_component *cmpnt) |
1431 | { |
1432 | struct mt6351_priv *priv = snd_soc_component_get_drvdata(c: cmpnt); |
1433 | |
1434 | snd_soc_component_init_regmap(component: cmpnt, regmap: priv->regmap); |
1435 | |
1436 | mt6351_codec_init_reg(cmpnt); |
1437 | return 0; |
1438 | } |
1439 | |
1440 | static const struct snd_soc_component_driver mt6351_soc_component_driver = { |
1441 | .probe = mt6351_codec_probe, |
1442 | .controls = mt6351_snd_controls, |
1443 | .num_controls = ARRAY_SIZE(mt6351_snd_controls), |
1444 | .dapm_widgets = mt6351_dapm_widgets, |
1445 | .num_dapm_widgets = ARRAY_SIZE(mt6351_dapm_widgets), |
1446 | .dapm_routes = mt6351_dapm_routes, |
1447 | .num_dapm_routes = ARRAY_SIZE(mt6351_dapm_routes), |
1448 | .endianness = 1, |
1449 | }; |
1450 | |
1451 | static int mt6351_codec_driver_probe(struct platform_device *pdev) |
1452 | { |
1453 | struct mt6351_priv *priv; |
1454 | |
1455 | priv = devm_kzalloc(dev: &pdev->dev, |
1456 | size: sizeof(struct mt6351_priv), |
1457 | GFP_KERNEL); |
1458 | if (!priv) |
1459 | return -ENOMEM; |
1460 | |
1461 | dev_set_drvdata(dev: &pdev->dev, data: priv); |
1462 | |
1463 | priv->dev = &pdev->dev; |
1464 | |
1465 | priv->regmap = dev_get_regmap(dev: pdev->dev.parent, NULL); |
1466 | if (!priv->regmap) |
1467 | return -ENODEV; |
1468 | |
1469 | dev_dbg(priv->dev, "%s(), dev name %s\n" , |
1470 | __func__, dev_name(&pdev->dev)); |
1471 | |
1472 | return devm_snd_soc_register_component(dev: &pdev->dev, |
1473 | component_driver: &mt6351_soc_component_driver, |
1474 | dai_drv: mt6351_dai_driver, |
1475 | ARRAY_SIZE(mt6351_dai_driver)); |
1476 | } |
1477 | |
1478 | static const struct of_device_id mt6351_of_match[] = { |
1479 | {.compatible = "mediatek,mt6351-sound" ,}, |
1480 | {} |
1481 | }; |
1482 | |
1483 | static struct platform_driver mt6351_codec_driver = { |
1484 | .driver = { |
1485 | .name = "mt6351-sound" , |
1486 | .of_match_table = mt6351_of_match, |
1487 | }, |
1488 | .probe = mt6351_codec_driver_probe, |
1489 | }; |
1490 | |
1491 | module_platform_driver(mt6351_codec_driver) |
1492 | |
1493 | /* Module information */ |
1494 | MODULE_DESCRIPTION("MT6351 ALSA SoC codec driver" ); |
1495 | MODULE_AUTHOR("KaiChieh Chuang <kaichieh.chuang@mediatek.com>" ); |
1496 | MODULE_LICENSE("GPL v2" ); |
1497 | |