1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * MediaTek ALSA SoC Audio DAI DMIC I/F Control
4 *
5 * Copyright (c) 2020 MediaTek Inc.
6 * Author: Bicycle Tsai <bicycle.tsai@mediatek.com>
7 * Trevor Wu <trevor.wu@mediatek.com>
8 * Parker Yang <parker.yang@mediatek.com>
9 */
10
11 #include <linux/delay.h>
12 #include <linux/pm_runtime.h>
13 #include <linux/regmap.h>
14 #include <sound/pcm_params.h>
15 #include "mt8188-afe-clk.h"
16 #include "mt8188-afe-common.h"
17 #include "mt8188-reg.h"
18
19 /* DMIC HW Gain configuration maximum value. */
20 #define DMIC_GAIN_MAX_STEP GENMASK(19, 0)
21 #define DMIC_GAIN_MAX_PER_STEP GENMASK(7, 0)
22 #define DMIC_GAIN_MAX_TARGET GENMASK(27, 0)
23 #define DMIC_GAIN_MAX_CURRENT GENMASK(27, 0)
24
25 #define CLK_PHASE_SEL_CH1 0
26 #define CLK_PHASE_SEL_CH2 ((CLK_PHASE_SEL_CH1) + 4)
27
28 #define DMIC1_SRC_SEL 0
29 #define DMIC2_SRC_SEL 0
30 #define DMIC3_SRC_SEL 2
31 #define DMIC4_SRC_SEL 0
32 #define DMIC5_SRC_SEL 4
33 #define DMIC6_SRC_SEL 0
34 #define DMIC7_SRC_SEL 6
35 #define DMIC8_SRC_SEL 0
36
37 enum {
38 SUPPLY_SEQ_DMIC_GAIN,
39 SUPPLY_SEQ_DMIC_CK,
40 };
41
42 enum {
43 DMIC0,
44 DMIC1,
45 DMIC2,
46 DMIC3,
47 DMIC_NUM,
48 };
49
50 struct mtk_dai_dmic_ctrl_reg {
51 unsigned int con0;
52 };
53
54 struct mtk_dai_dmic_hw_gain_ctrl_reg {
55 unsigned int bypass;
56 unsigned int con0;
57 };
58
59 struct mtk_dai_dmic_priv {
60 unsigned int gain_on[DMIC_NUM];
61 unsigned int channels;
62 bool hires_required;
63 };
64
65 static const struct mtk_dai_dmic_ctrl_reg dmic_ctrl_regs[DMIC_NUM] = {
66 [DMIC0] = {
67 .con0 = AFE_DMIC0_UL_SRC_CON0,
68 },
69 [DMIC1] = {
70 .con0 = AFE_DMIC1_UL_SRC_CON0,
71 },
72 [DMIC2] = {
73 .con0 = AFE_DMIC2_UL_SRC_CON0,
74 },
75 [DMIC3] = {
76 .con0 = AFE_DMIC3_UL_SRC_CON0,
77 },
78 };
79
get_dmic_ctrl_reg(int id)80 static const struct mtk_dai_dmic_ctrl_reg *get_dmic_ctrl_reg(int id)
81 {
82 if (id < 0 || id >= DMIC_NUM)
83 return NULL;
84
85 return &dmic_ctrl_regs[id];
86 }
87
88 static const struct mtk_dai_dmic_hw_gain_ctrl_reg
89 dmic_hw_gain_ctrl_regs[DMIC_NUM] = {
90 [DMIC0] = {
91 .bypass = DMIC_BYPASS_HW_GAIN,
92 .con0 = DMIC_GAIN1_CON0,
93 },
94 [DMIC1] = {
95 .bypass = DMIC_BYPASS_HW_GAIN,
96 .con0 = DMIC_GAIN2_CON0,
97 },
98 [DMIC2] = {
99 .bypass = DMIC_BYPASS_HW_GAIN,
100 .con0 = DMIC_GAIN3_CON0,
101 },
102 [DMIC3] = {
103 .bypass = DMIC_BYPASS_HW_GAIN,
104 .con0 = DMIC_GAIN4_CON0,
105 },
106 };
107
108 static const struct mtk_dai_dmic_hw_gain_ctrl_reg
get_dmic_hw_gain_ctrl_reg(struct mtk_base_afe * afe,int id)109 *get_dmic_hw_gain_ctrl_reg(struct mtk_base_afe *afe, int id)
110 {
111 if ((id < 0) || (id >= DMIC_NUM)) {
112 dev_dbg(afe->dev, "%s invalid id\n", __func__);
113 return NULL;
114 }
115
116 return &dmic_hw_gain_ctrl_regs[id];
117 }
118
mtk_dai_dmic_hw_gain_bypass(struct mtk_base_afe * afe,unsigned int id,bool bypass)119 static void mtk_dai_dmic_hw_gain_bypass(struct mtk_base_afe *afe,
120 unsigned int id, bool bypass)
121 {
122 const struct mtk_dai_dmic_hw_gain_ctrl_reg *reg;
123 unsigned int msk;
124
125 reg = get_dmic_hw_gain_ctrl_reg(afe, id);
126 if (!reg)
127 return;
128
129 switch (id) {
130 case DMIC0:
131 msk = DMIC_BYPASS_HW_GAIN_DMIC1_BYPASS;
132 break;
133 case DMIC1:
134 msk = DMIC_BYPASS_HW_GAIN_DMIC2_BYPASS;
135 break;
136 case DMIC2:
137 msk = DMIC_BYPASS_HW_GAIN_DMIC3_BYPASS;
138 break;
139 case DMIC3:
140 msk = DMIC_BYPASS_HW_GAIN_DMIC4_BYPASS;
141 break;
142 default:
143 return;
144 }
145
146 if (bypass)
147 regmap_set_bits(afe->regmap, reg->bypass, msk);
148 else
149 regmap_clear_bits(afe->regmap, reg->bypass, msk);
150 }
151
mtk_dai_dmic_hw_gain_on(struct mtk_base_afe * afe,unsigned int id,bool on)152 static void mtk_dai_dmic_hw_gain_on(struct mtk_base_afe *afe, unsigned int id,
153 bool on)
154 {
155 const struct mtk_dai_dmic_hw_gain_ctrl_reg *reg = get_dmic_hw_gain_ctrl_reg(afe, id);
156
157 if (!reg)
158 return;
159
160 if (on)
161 regmap_set_bits(afe->regmap, reg->con0, DMIC_GAIN_CON0_GAIN_ON);
162 else
163 regmap_clear_bits(afe->regmap, reg->con0, DMIC_GAIN_CON0_GAIN_ON);
164 }
165
166 static const struct reg_sequence mtk_dai_dmic_iir_coeff_reg_defaults[] = {
167 { AFE_DMIC0_IIR_COEF_02_01, 0x00000000 },
168 { AFE_DMIC0_IIR_COEF_04_03, 0x00003FB8 },
169 { AFE_DMIC0_IIR_COEF_06_05, 0x3FB80000 },
170 { AFE_DMIC0_IIR_COEF_08_07, 0x3FB80000 },
171 { AFE_DMIC0_IIR_COEF_10_09, 0x0000C048 },
172 { AFE_DMIC1_IIR_COEF_02_01, 0x00000000 },
173 { AFE_DMIC1_IIR_COEF_04_03, 0x00003FB8 },
174 { AFE_DMIC1_IIR_COEF_06_05, 0x3FB80000 },
175 { AFE_DMIC1_IIR_COEF_08_07, 0x3FB80000 },
176 { AFE_DMIC1_IIR_COEF_10_09, 0x0000C048 },
177 { AFE_DMIC2_IIR_COEF_02_01, 0x00000000 },
178 { AFE_DMIC2_IIR_COEF_04_03, 0x00003FB8 },
179 { AFE_DMIC2_IIR_COEF_06_05, 0x3FB80000 },
180 { AFE_DMIC2_IIR_COEF_08_07, 0x3FB80000 },
181 { AFE_DMIC2_IIR_COEF_10_09, 0x0000C048 },
182 { AFE_DMIC3_IIR_COEF_02_01, 0x00000000 },
183 { AFE_DMIC3_IIR_COEF_04_03, 0x00003FB8 },
184 { AFE_DMIC3_IIR_COEF_06_05, 0x3FB80000 },
185 { AFE_DMIC3_IIR_COEF_08_07, 0x3FB80000 },
186 { AFE_DMIC3_IIR_COEF_10_09, 0x0000C048 },
187 };
188
mtk_dai_dmic_load_iir_coeff_table(struct mtk_base_afe * afe)189 static int mtk_dai_dmic_load_iir_coeff_table(struct mtk_base_afe *afe)
190 {
191 return regmap_multi_reg_write(afe->regmap,
192 mtk_dai_dmic_iir_coeff_reg_defaults,
193 ARRAY_SIZE(mtk_dai_dmic_iir_coeff_reg_defaults));
194 }
195
mtk_dai_dmic_configure_array(struct snd_soc_dai * dai)196 static int mtk_dai_dmic_configure_array(struct snd_soc_dai *dai)
197 {
198 struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
199 const u32 mask = PWR2_TOP_CON_DMIC8_SRC_SEL_MASK |
200 PWR2_TOP_CON_DMIC7_SRC_SEL_MASK |
201 PWR2_TOP_CON_DMIC6_SRC_SEL_MASK |
202 PWR2_TOP_CON_DMIC5_SRC_SEL_MASK |
203 PWR2_TOP_CON_DMIC4_SRC_SEL_MASK |
204 PWR2_TOP_CON_DMIC3_SRC_SEL_MASK |
205 PWR2_TOP_CON_DMIC2_SRC_SEL_MASK |
206 PWR2_TOP_CON_DMIC1_SRC_SEL_MASK;
207 const u32 val = PWR2_TOP_CON_DMIC8_SRC_SEL_VAL(DMIC8_SRC_SEL) |
208 PWR2_TOP_CON_DMIC7_SRC_SEL_VAL(DMIC7_SRC_SEL) |
209 PWR2_TOP_CON_DMIC6_SRC_SEL_VAL(DMIC6_SRC_SEL) |
210 PWR2_TOP_CON_DMIC5_SRC_SEL_VAL(DMIC5_SRC_SEL) |
211 PWR2_TOP_CON_DMIC4_SRC_SEL_VAL(DMIC4_SRC_SEL) |
212 PWR2_TOP_CON_DMIC3_SRC_SEL_VAL(DMIC3_SRC_SEL) |
213 PWR2_TOP_CON_DMIC2_SRC_SEL_VAL(DMIC2_SRC_SEL) |
214 PWR2_TOP_CON_DMIC1_SRC_SEL_VAL(DMIC1_SRC_SEL);
215
216 return regmap_update_bits(afe->regmap, PWR2_TOP_CON0, mask, val);
217 }
218
219 /* This function assumes that the caller checked that channels is valid */
mtk_dmic_channels_to_dmic_number(unsigned int channels)220 static u8 mtk_dmic_channels_to_dmic_number(unsigned int channels)
221 {
222 switch (channels) {
223 case 1:
224 return DMIC0;
225 case 2:
226 return DMIC1;
227 case 3:
228 return DMIC2;
229 case 4:
230 default:
231 return DMIC3;
232 }
233 }
234
mtk_dai_dmic_hw_gain_enable(struct mtk_base_afe * afe,unsigned int channels,bool enable)235 static void mtk_dai_dmic_hw_gain_enable(struct mtk_base_afe *afe,
236 unsigned int channels, bool enable)
237 {
238 struct mt8188_afe_private *afe_priv = afe->platform_priv;
239 struct mtk_dai_dmic_priv *dmic_priv = afe_priv->dai_priv[MT8188_AFE_IO_DMIC_IN];
240 u8 dmic_num;
241 int i;
242
243 dmic_num = mtk_dmic_channels_to_dmic_number(channels);
244 for (i = dmic_num; i >= DMIC0; i--) {
245 if (enable && dmic_priv->gain_on[i]) {
246 mtk_dai_dmic_hw_gain_bypass(afe, i, false);
247 mtk_dai_dmic_hw_gain_on(afe, i, true);
248 } else {
249 mtk_dai_dmic_hw_gain_on(afe, i, false);
250 mtk_dai_dmic_hw_gain_bypass(afe, i, true);
251 }
252 }
253 }
254
mtk_dmic_gain_event(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)255 static int mtk_dmic_gain_event(struct snd_soc_dapm_widget *w,
256 struct snd_kcontrol *kcontrol,
257 int event)
258 {
259 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
260 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
261 struct mt8188_afe_private *afe_priv = afe->platform_priv;
262 struct mtk_dai_dmic_priv *dmic_priv = afe_priv->dai_priv[MT8188_AFE_IO_DMIC_IN];
263 unsigned int channels = dmic_priv->channels;
264
265 dev_dbg(afe->dev, "%s(), name %s, event 0x%x\n",
266 __func__, w->name, event);
267
268 if (!channels)
269 return -EINVAL;
270
271 switch (event) {
272 case SND_SOC_DAPM_PRE_PMU:
273 mtk_dai_dmic_hw_gain_enable(afe, channels, true);
274 break;
275 case SND_SOC_DAPM_POST_PMD:
276 mtk_dai_dmic_hw_gain_enable(afe, channels, false);
277 break;
278 default:
279 break;
280 }
281
282 return 0;
283 }
284
mtk_dmic_event(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)285 static int mtk_dmic_event(struct snd_soc_dapm_widget *w,
286 struct snd_kcontrol *kcontrol,
287 int event)
288 {
289 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
290 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
291 struct mt8188_afe_private *afe_priv = afe->platform_priv;
292 struct mtk_dai_dmic_priv *dmic_priv = afe_priv->dai_priv[MT8188_AFE_IO_DMIC_IN];
293 const struct mtk_dai_dmic_ctrl_reg *reg = NULL;
294 unsigned int channels = dmic_priv->channels;
295 unsigned int msk;
296 u8 dmic_num;
297 int i;
298
299 dev_dbg(afe->dev, "%s(), name %s, event 0x%x\n",
300 __func__, w->name, event);
301
302 if (!channels)
303 return -EINVAL;
304
305 dmic_num = mtk_dmic_channels_to_dmic_number(channels);
306
307 switch (event) {
308 case SND_SOC_DAPM_PRE_PMU:
309 /* request fifo soft rst */
310 msk = 0;
311 for (i = dmic_num; i >= DMIC0; i--)
312 msk |= PWR2_TOP_CON1_DMIC_FIFO_SOFT_RST_EN(i);
313
314 regmap_set_bits(afe->regmap, PWR2_TOP_CON1, msk);
315
316 msk = AFE_DMIC_UL_SRC_CON0_UL_MODE_3P25M_CH1_CTL |
317 AFE_DMIC_UL_SRC_CON0_UL_MODE_3P25M_CH2_CTL |
318 AFE_DMIC_UL_SRC_CON0_UL_SDM_3_LEVEL_CTL |
319 AFE_DMIC_UL_SRC_CON0_UL_IIR_ON_TMP_CTL;
320
321 for (i = dmic_num; i >= DMIC0; i--) {
322 reg = get_dmic_ctrl_reg(i);
323 if (reg)
324 regmap_set_bits(afe->regmap, reg->con0, msk);
325 }
326 break;
327 case SND_SOC_DAPM_POST_PMU:
328 msk = AFE_DMIC_UL_SRC_CON0_UL_SRC_ON_TMP_CTL;
329
330 for (i = dmic_num; i >= DMIC0; i--) {
331 reg = get_dmic_ctrl_reg(i);
332 if (reg)
333 regmap_set_bits(afe->regmap, reg->con0, msk);
334 }
335
336 if (dmic_priv->hires_required) {
337 mt8188_afe_enable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_DMIC_HIRES1]);
338 mt8188_afe_enable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_DMIC_HIRES2]);
339 mt8188_afe_enable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_DMIC_HIRES3]);
340 mt8188_afe_enable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_DMIC_HIRES4]);
341 }
342
343 mt8188_afe_enable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_AFE_DMIC1]);
344 mt8188_afe_enable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_AFE_DMIC2]);
345 mt8188_afe_enable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_AFE_DMIC3]);
346 mt8188_afe_enable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_AFE_DMIC4]);
347
348 /* release fifo soft rst */
349 msk = 0;
350 for (i = dmic_num; i >= DMIC0; i--)
351 msk |= PWR2_TOP_CON1_DMIC_FIFO_SOFT_RST_EN(i);
352
353 regmap_clear_bits(afe->regmap, PWR2_TOP_CON1, msk);
354 break;
355 case SND_SOC_DAPM_PRE_PMD:
356 msk = AFE_DMIC_UL_SRC_CON0_UL_MODE_3P25M_CH1_CTL |
357 AFE_DMIC_UL_SRC_CON0_UL_MODE_3P25M_CH2_CTL |
358 AFE_DMIC_UL_SRC_CON0_UL_SRC_ON_TMP_CTL |
359 AFE_DMIC_UL_SRC_CON0_UL_IIR_ON_TMP_CTL |
360 AFE_DMIC_UL_SRC_CON0_UL_SDM_3_LEVEL_CTL;
361
362 for (i = dmic_num; i >= DMIC0; i--) {
363 reg = get_dmic_ctrl_reg(i);
364 if (reg)
365 regmap_set_bits(afe->regmap, reg->con0, msk);
366 }
367 break;
368 case SND_SOC_DAPM_POST_PMD:
369 /* should delayed 1/fs(smallest is 8k) = 125us before afe off */
370 usleep_range(125, 126);
371
372 mt8188_afe_disable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_AFE_DMIC1]);
373 mt8188_afe_disable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_AFE_DMIC2]);
374 mt8188_afe_disable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_AFE_DMIC3]);
375 mt8188_afe_disable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_AFE_DMIC4]);
376
377 if (dmic_priv->hires_required) {
378 mt8188_afe_disable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_DMIC_HIRES1]);
379 mt8188_afe_disable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_DMIC_HIRES2]);
380 mt8188_afe_disable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_DMIC_HIRES3]);
381 mt8188_afe_disable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_DMIC_HIRES4]);
382 }
383 break;
384 default:
385 break;
386 }
387
388 return 0;
389 }
390
mtk_dai_dmic_hw_params(struct snd_pcm_substream * substream,struct snd_pcm_hw_params * params,struct snd_soc_dai * dai)391 static int mtk_dai_dmic_hw_params(struct snd_pcm_substream *substream,
392 struct snd_pcm_hw_params *params,
393 struct snd_soc_dai *dai)
394 {
395 struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
396 struct mt8188_afe_private *afe_priv = afe->platform_priv;
397 struct mtk_dai_dmic_priv *dmic_priv = afe_priv->dai_priv[MT8188_AFE_IO_DMIC_IN];
398 unsigned int rate = params_rate(params);
399 unsigned int channels = params_channels(params);
400 const struct mtk_dai_dmic_ctrl_reg *reg = NULL;
401 u32 val = AFE_DMIC_UL_SRC_CON0_UL_PHASE_SEL_CH1(CLK_PHASE_SEL_CH1) |
402 AFE_DMIC_UL_SRC_CON0_UL_PHASE_SEL_CH2(CLK_PHASE_SEL_CH2) |
403 AFE_DMIC_UL_SRC_CON0_UL_IIR_MODE_CTL(0);
404 const u32 msk = AFE_DMIC_UL_SRC_CON0_UL_TWO_WIRE_MODE_CTL |
405 AFE_DMIC_UL_SRC_CON0_UL_PHASE_SEL_MASK |
406 AFE_DMIC_UL_SRC_CON0_UL_IIR_MODE_CTL_MASK |
407 AFE_DMIC_UL_VOICE_MODE_MASK;
408 u8 dmic_num;
409 int ret;
410 int i;
411
412 if (!channels || channels > 8)
413 return -EINVAL;
414
415 ret = mtk_dai_dmic_configure_array(dai);
416 if (ret < 0)
417 return ret;
418
419 ret = mtk_dai_dmic_load_iir_coeff_table(afe);
420 if (ret < 0)
421 return ret;
422
423 switch (rate) {
424 case 96000:
425 val |= AFE_DMIC_UL_CON0_VOCIE_MODE_96K;
426 dmic_priv->hires_required = 1;
427 break;
428 case 48000:
429 val |= AFE_DMIC_UL_CON0_VOCIE_MODE_48K;
430 dmic_priv->hires_required = 0;
431 break;
432 case 32000:
433 val |= AFE_DMIC_UL_CON0_VOCIE_MODE_32K;
434 dmic_priv->hires_required = 0;
435 break;
436 case 16000:
437 val |= AFE_DMIC_UL_CON0_VOCIE_MODE_16K;
438 dmic_priv->hires_required = 0;
439 break;
440 case 8000:
441 val |= AFE_DMIC_UL_CON0_VOCIE_MODE_8K;
442 dmic_priv->hires_required = 0;
443 break;
444 default:
445 dev_dbg(afe->dev, "%s invalid rate %u, use 48000Hz\n", __func__, rate);
446 val |= AFE_DMIC_UL_CON0_VOCIE_MODE_48K;
447 dmic_priv->hires_required = 0;
448 break;
449 }
450
451 dmic_num = mtk_dmic_channels_to_dmic_number(channels);
452 for (i = dmic_num; i >= DMIC0; i--) {
453 reg = get_dmic_ctrl_reg(i);
454 if (reg) {
455 ret = regmap_update_bits(afe->regmap, reg->con0, msk, val);
456 if (ret < 0)
457 return ret;
458 }
459 }
460
461 dmic_priv->channels = channels;
462
463 return 0;
464 }
465
466 static const struct snd_soc_dai_ops mtk_dai_dmic_ops = {
467 .hw_params = mtk_dai_dmic_hw_params,
468 };
469
470 #define MTK_DMIC_RATES (SNDRV_PCM_RATE_8000 |\
471 SNDRV_PCM_RATE_16000 |\
472 SNDRV_PCM_RATE_32000 |\
473 SNDRV_PCM_RATE_48000 |\
474 SNDRV_PCM_RATE_96000)
475
476 #define MTK_DMIC_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
477 SNDRV_PCM_FMTBIT_S32_LE)
478
479 static struct snd_soc_dai_driver mtk_dai_dmic_driver[] = {
480 {
481 .name = "DMIC",
482 .id = MT8188_AFE_IO_DMIC_IN,
483 .capture = {
484 .stream_name = "DMIC Capture",
485 .channels_min = 1,
486 .channels_max = 8,
487 .rates = MTK_DMIC_RATES,
488 .formats = MTK_DMIC_FORMATS,
489 },
490 .ops = &mtk_dai_dmic_ops,
491 },
492 };
493
494 static const struct snd_soc_dapm_widget mtk_dai_dmic_widgets[] = {
495 SND_SOC_DAPM_MIXER("I004", SND_SOC_NOPM, 0, 0, NULL, 0),
496 SND_SOC_DAPM_MIXER("I005", SND_SOC_NOPM, 0, 0, NULL, 0),
497 SND_SOC_DAPM_MIXER("I006", SND_SOC_NOPM, 0, 0, NULL, 0),
498 SND_SOC_DAPM_MIXER("I007", SND_SOC_NOPM, 0, 0, NULL, 0),
499 SND_SOC_DAPM_MIXER("I008", SND_SOC_NOPM, 0, 0, NULL, 0),
500 SND_SOC_DAPM_MIXER("I009", SND_SOC_NOPM, 0, 0, NULL, 0),
501 SND_SOC_DAPM_MIXER("I010", SND_SOC_NOPM, 0, 0, NULL, 0),
502 SND_SOC_DAPM_MIXER("I011", SND_SOC_NOPM, 0, 0, NULL, 0),
503
504 SND_SOC_DAPM_SUPPLY_S("DMIC_GAIN_ON", SUPPLY_SEQ_DMIC_GAIN,
505 SND_SOC_NOPM, 0, 0,
506 mtk_dmic_gain_event,
507 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
508 SND_SOC_DAPM_SUPPLY_S("DMIC_CK_ON", SUPPLY_SEQ_DMIC_CK,
509 PWR2_TOP_CON1,
510 PWR2_TOP_CON1_DMIC_CKDIV_ON_SHIFT, 0,
511 mtk_dmic_event,
512 SND_SOC_DAPM_PRE_POST_PMU |
513 SND_SOC_DAPM_PRE_POST_PMD),
514 SND_SOC_DAPM_INPUT("DMIC_INPUT"),
515 };
516
517 static const struct snd_soc_dapm_route mtk_dai_dmic_routes[] = {
518 {"I004", NULL, "DMIC Capture"},
519 {"I005", NULL, "DMIC Capture"},
520 {"I006", NULL, "DMIC Capture"},
521 {"I007", NULL, "DMIC Capture"},
522 {"I008", NULL, "DMIC Capture"},
523 {"I009", NULL, "DMIC Capture"},
524 {"I010", NULL, "DMIC Capture"},
525 {"I011", NULL, "DMIC Capture"},
526 {"DMIC Capture", NULL, "DMIC_CK_ON"},
527 {"DMIC Capture", NULL, "DMIC_GAIN_ON"},
528 {"DMIC Capture", NULL, "DMIC_INPUT"},
529 };
530
531 static const char * const mt8188_dmic_gain_enable_text[] = {
532 "Bypass", "Connect",
533 };
534
535 static SOC_ENUM_SINGLE_EXT_DECL(dmic_gain_on_enum,
536 mt8188_dmic_gain_enable_text);
537
mtk_dai_dmic_hw_gain_ctrl_put(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)538 static int mtk_dai_dmic_hw_gain_ctrl_put(struct snd_kcontrol *kcontrol,
539 struct snd_ctl_elem_value *ucontrol)
540 {
541 struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
542 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
543 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
544 struct mt8188_afe_private *afe_priv = afe->platform_priv;
545 struct mtk_dai_dmic_priv *dmic_priv = afe_priv->dai_priv[MT8188_AFE_IO_DMIC_IN];
546 unsigned int source = ucontrol->value.enumerated.item[0];
547 unsigned int *cached;
548
549 if (source >= e->items)
550 return -EINVAL;
551
552 if (!strcmp(kcontrol->id.name, "DMIC1_HW_GAIN_EN"))
553 cached = &dmic_priv->gain_on[0];
554 else if (!strcmp(kcontrol->id.name, "DMIC2_HW_GAIN_EN"))
555 cached = &dmic_priv->gain_on[1];
556 else if (!strcmp(kcontrol->id.name, "DMIC3_HW_GAIN_EN"))
557 cached = &dmic_priv->gain_on[2];
558 else if (!strcmp(kcontrol->id.name, "DMIC4_HW_GAIN_EN"))
559 cached = &dmic_priv->gain_on[3];
560 else
561 return -EINVAL;
562
563 if (source == *cached)
564 return 0;
565
566 *cached = source;
567 return 1;
568 }
569
mtk_dai_dmic_hw_gain_ctrl_get(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)570 static int mtk_dai_dmic_hw_gain_ctrl_get(struct snd_kcontrol *kcontrol,
571 struct snd_ctl_elem_value *ucontrol)
572 {
573 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
574 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
575 struct mt8188_afe_private *afe_priv = afe->platform_priv;
576 struct mtk_dai_dmic_priv *dmic_priv = afe_priv->dai_priv[MT8188_AFE_IO_DMIC_IN];
577 unsigned int val;
578
579 if (!strcmp(kcontrol->id.name, "DMIC1_HW_GAIN_EN"))
580 val = dmic_priv->gain_on[0];
581 else if (!strcmp(kcontrol->id.name, "DMIC2_HW_GAIN_EN"))
582 val = dmic_priv->gain_on[1];
583 else if (!strcmp(kcontrol->id.name, "DMIC3_HW_GAIN_EN"))
584 val = dmic_priv->gain_on[2];
585 else if (!strcmp(kcontrol->id.name, "DMIC4_HW_GAIN_EN"))
586 val = dmic_priv->gain_on[3];
587 else
588 return -EINVAL;
589
590 ucontrol->value.enumerated.item[0] = val;
591 return 0;
592 }
593
594 static const struct snd_kcontrol_new mtk_dai_dmic_controls[] = {
595 SOC_ENUM_EXT("DMIC1_HW_GAIN_EN", dmic_gain_on_enum,
596 mtk_dai_dmic_hw_gain_ctrl_get,
597 mtk_dai_dmic_hw_gain_ctrl_put),
598 SOC_ENUM_EXT("DMIC2_HW_GAIN_EN", dmic_gain_on_enum,
599 mtk_dai_dmic_hw_gain_ctrl_get,
600 mtk_dai_dmic_hw_gain_ctrl_put),
601 SOC_ENUM_EXT("DMIC3_HW_GAIN_EN", dmic_gain_on_enum,
602 mtk_dai_dmic_hw_gain_ctrl_get,
603 mtk_dai_dmic_hw_gain_ctrl_put),
604 SOC_ENUM_EXT("DMIC4_HW_GAIN_EN", dmic_gain_on_enum,
605 mtk_dai_dmic_hw_gain_ctrl_get,
606 mtk_dai_dmic_hw_gain_ctrl_put),
607 SOC_SINGLE("DMIC1_HW_GAIN_TARGET", DMIC_GAIN1_CON1,
608 0, DMIC_GAIN_MAX_TARGET, 0),
609 SOC_SINGLE("DMIC2_HW_GAIN_TARGET", DMIC_GAIN2_CON1,
610 0, DMIC_GAIN_MAX_TARGET, 0),
611 SOC_SINGLE("DMIC3_HW_GAIN_TARGET", DMIC_GAIN3_CON1,
612 0, DMIC_GAIN_MAX_TARGET, 0),
613 SOC_SINGLE("DMIC4_HW_GAIN_TARGET", DMIC_GAIN4_CON1,
614 0, DMIC_GAIN_MAX_TARGET, 0),
615 SOC_SINGLE("DMIC1_HW_GAIN_CURRENT", DMIC_GAIN1_CUR,
616 0, DMIC_GAIN_MAX_CURRENT, 0),
617 SOC_SINGLE("DMIC2_HW_GAIN_CURRENT", DMIC_GAIN2_CUR,
618 0, DMIC_GAIN_MAX_CURRENT, 0),
619 SOC_SINGLE("DMIC3_HW_GAIN_CURRENT", DMIC_GAIN3_CUR,
620 0, DMIC_GAIN_MAX_CURRENT, 0),
621 SOC_SINGLE("DMIC4_HW_GAIN_CURRENT", DMIC_GAIN4_CUR,
622 0, DMIC_GAIN_MAX_CURRENT, 0),
623 SOC_SINGLE("DMIC1_HW_GAIN_UP_STEP", DMIC_GAIN1_CON3,
624 0, DMIC_GAIN_MAX_STEP, 0),
625 SOC_SINGLE("DMIC2_HW_GAIN_UP_STEP", DMIC_GAIN2_CON3,
626 0, DMIC_GAIN_MAX_STEP, 0),
627 SOC_SINGLE("DMIC3_HW_GAIN_UP_STEP", DMIC_GAIN3_CON3,
628 0, DMIC_GAIN_MAX_STEP, 0),
629 SOC_SINGLE("DMIC4_HW_GAIN_UP_STEP", DMIC_GAIN4_CON3,
630 0, DMIC_GAIN_MAX_STEP, 0),
631 SOC_SINGLE("DMIC1_HW_GAIN_DOWN_STEP", DMIC_GAIN1_CON2,
632 0, DMIC_GAIN_MAX_STEP, 0),
633 SOC_SINGLE("DMIC2_HW_GAIN_DOWN_STEP", DMIC_GAIN2_CON2,
634 0, DMIC_GAIN_MAX_STEP, 0),
635 SOC_SINGLE("DMIC3_HW_GAIN_DOWN_STEP", DMIC_GAIN3_CON2,
636 0, DMIC_GAIN_MAX_STEP, 0),
637 SOC_SINGLE("DMIC4_HW_GAIN_DOWN_STEP", DMIC_GAIN4_CON2,
638 0, DMIC_GAIN_MAX_STEP, 0),
639 SOC_SINGLE("DMIC1_HW_GAIN_SAMPLE_PER_STEP", DMIC_GAIN1_CON0,
640 DMIC_GAIN_CON0_SAMPLE_PER_STEP_SHIFT, DMIC_GAIN_MAX_PER_STEP, 0),
641 SOC_SINGLE("DMIC2_HW_GAIN_SAMPLE_PER_STEP", DMIC_GAIN2_CON0,
642 DMIC_GAIN_CON0_SAMPLE_PER_STEP_SHIFT, DMIC_GAIN_MAX_PER_STEP, 0),
643 SOC_SINGLE("DMIC3_HW_GAIN_SAMPLE_PER_STEP", DMIC_GAIN3_CON0,
644 DMIC_GAIN_CON0_SAMPLE_PER_STEP_SHIFT, DMIC_GAIN_MAX_PER_STEP, 0),
645 SOC_SINGLE("DMIC4_HW_GAIN_SAMPLE_PER_STEP", DMIC_GAIN4_CON0,
646 DMIC_GAIN_CON0_SAMPLE_PER_STEP_SHIFT, DMIC_GAIN_MAX_PER_STEP, 0),
647 };
648
init_dmic_priv_data(struct mtk_base_afe * afe)649 static int init_dmic_priv_data(struct mtk_base_afe *afe)
650 {
651 struct mt8188_afe_private *afe_priv = afe->platform_priv;
652 struct mtk_dai_dmic_priv *dmic_priv;
653
654 dmic_priv = devm_kzalloc(afe->dev, sizeof(struct mtk_dai_dmic_priv),
655 GFP_KERNEL);
656 if (!dmic_priv)
657 return -ENOMEM;
658
659 afe_priv->dai_priv[MT8188_AFE_IO_DMIC_IN] = dmic_priv;
660 return 0;
661 }
662
mt8188_dai_dmic_register(struct mtk_base_afe * afe)663 int mt8188_dai_dmic_register(struct mtk_base_afe *afe)
664 {
665 struct mtk_base_afe_dai *dai;
666
667 dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL);
668 if (!dai)
669 return -ENOMEM;
670
671 list_add(&dai->list, &afe->sub_dais);
672
673 dai->dai_drivers = mtk_dai_dmic_driver;
674 dai->num_dai_drivers = ARRAY_SIZE(mtk_dai_dmic_driver);
675 dai->dapm_widgets = mtk_dai_dmic_widgets;
676 dai->num_dapm_widgets = ARRAY_SIZE(mtk_dai_dmic_widgets);
677 dai->dapm_routes = mtk_dai_dmic_routes;
678 dai->num_dapm_routes = ARRAY_SIZE(mtk_dai_dmic_routes);
679 dai->controls = mtk_dai_dmic_controls;
680 dai->num_controls = ARRAY_SIZE(mtk_dai_dmic_controls);
681
682 return init_dmic_priv_data(afe);
683 }
684