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
37enum {
38 SUPPLY_SEQ_DMIC_GAIN,
39 SUPPLY_SEQ_DMIC_CK,
40};
41
42enum {
43 DMIC0,
44 DMIC1,
45 DMIC2,
46 DMIC3,
47 DMIC_NUM,
48};
49
50struct mtk_dai_dmic_ctrl_reg {
51 unsigned int con0;
52};
53
54struct mtk_dai_dmic_hw_gain_ctrl_reg {
55 unsigned int bypass;
56 unsigned int con0;
57};
58
59struct mtk_dai_dmic_priv {
60 unsigned int gain_on[DMIC_NUM];
61 unsigned int channels;
62 bool hires_required;
63};
64
65static 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
80static 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
88static 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
108static const struct mtk_dai_dmic_hw_gain_ctrl_reg
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
119static 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(map: afe->regmap, reg: reg->bypass, bits: msk);
148 else
149 regmap_clear_bits(map: afe->regmap, reg: reg->bypass, bits: msk);
150}
151
152static 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(map: afe->regmap, reg: reg->con0, DMIC_GAIN_CON0_GAIN_ON);
162 else
163 regmap_clear_bits(map: afe->regmap, reg: reg->con0, DMIC_GAIN_CON0_GAIN_ON);
164}
165
166static 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
189static int mtk_dai_dmic_load_iir_coeff_table(struct mtk_base_afe *afe)
190{
191 return regmap_multi_reg_write(map: afe->regmap,
192 regs: mtk_dai_dmic_iir_coeff_reg_defaults,
193 ARRAY_SIZE(mtk_dai_dmic_iir_coeff_reg_defaults));
194}
195
196static 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(map: afe->regmap, PWR2_TOP_CON0, mask, val);
217}
218
219/* This function assumes that the caller checked that channels is valid */
220static 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
235static 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, id: i, bypass: false);
247 mtk_dai_dmic_hw_gain_on(afe, id: i, on: true);
248 } else {
249 mtk_dai_dmic_hw_gain_on(afe, id: i, on: false);
250 mtk_dai_dmic_hw_gain_bypass(afe, id: i, bypass: true);
251 }
252 }
253}
254
255static 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(dapm: w->dapm);
260 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(c: 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, enable: true);
274 break;
275 case SND_SOC_DAPM_POST_PMD:
276 mtk_dai_dmic_hw_gain_enable(afe, channels, enable: false);
277 break;
278 default:
279 break;
280 }
281
282 return 0;
283}
284
285static 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(dapm: w->dapm);
290 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(c: 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(map: afe->regmap, PWR2_TOP_CON1, bits: 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(id: i);
323 if (reg)
324 regmap_set_bits(map: afe->regmap, reg: reg->con0, bits: 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(id: i);
332 if (reg)
333 regmap_set_bits(map: afe->regmap, reg: reg->con0, bits: msk);
334 }
335
336 if (dmic_priv->hires_required) {
337 mt8188_afe_enable_clk(afe, clk: afe_priv->clk[MT8188_CLK_AUD_DMIC_HIRES1]);
338 mt8188_afe_enable_clk(afe, clk: afe_priv->clk[MT8188_CLK_AUD_DMIC_HIRES2]);
339 mt8188_afe_enable_clk(afe, clk: afe_priv->clk[MT8188_CLK_AUD_DMIC_HIRES3]);
340 mt8188_afe_enable_clk(afe, clk: afe_priv->clk[MT8188_CLK_AUD_DMIC_HIRES4]);
341 }
342
343 mt8188_afe_enable_clk(afe, clk: afe_priv->clk[MT8188_CLK_AUD_AFE_DMIC1]);
344 mt8188_afe_enable_clk(afe, clk: afe_priv->clk[MT8188_CLK_AUD_AFE_DMIC2]);
345 mt8188_afe_enable_clk(afe, clk: afe_priv->clk[MT8188_CLK_AUD_AFE_DMIC3]);
346 mt8188_afe_enable_clk(afe, clk: 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(map: afe->regmap, PWR2_TOP_CON1, bits: 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(id: i);
364 if (reg)
365 regmap_set_bits(map: afe->regmap, reg: reg->con0, bits: 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(min: 125, max: 126);
371
372 mt8188_afe_disable_clk(afe, clk: afe_priv->clk[MT8188_CLK_AUD_AFE_DMIC1]);
373 mt8188_afe_disable_clk(afe, clk: afe_priv->clk[MT8188_CLK_AUD_AFE_DMIC2]);
374 mt8188_afe_disable_clk(afe, clk: afe_priv->clk[MT8188_CLK_AUD_AFE_DMIC3]);
375 mt8188_afe_disable_clk(afe, clk: afe_priv->clk[MT8188_CLK_AUD_AFE_DMIC4]);
376
377 if (dmic_priv->hires_required) {
378 mt8188_afe_disable_clk(afe, clk: afe_priv->clk[MT8188_CLK_AUD_DMIC_HIRES1]);
379 mt8188_afe_disable_clk(afe, clk: afe_priv->clk[MT8188_CLK_AUD_DMIC_HIRES2]);
380 mt8188_afe_disable_clk(afe, clk: afe_priv->clk[MT8188_CLK_AUD_DMIC_HIRES3]);
381 mt8188_afe_disable_clk(afe, clk: afe_priv->clk[MT8188_CLK_AUD_DMIC_HIRES4]);
382 }
383 break;
384 default:
385 break;
386 }
387
388 return 0;
389}
390
391static 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(p: params);
399 unsigned int channels = params_channels(p: 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(id: i);
454 if (reg) {
455 ret = regmap_update_bits(map: afe->regmap, reg: reg->con0, mask: msk, val);
456 if (ret < 0)
457 return ret;
458 }
459 }
460
461 dmic_priv->channels = channels;
462
463 return 0;
464}
465
466static 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
479static 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
494static 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
517static 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
531static const char * const mt8188_dmic_gain_enable_text[] = {
532 "Bypass", "Connect",
533};
534
535static SOC_ENUM_SINGLE_EXT_DECL(dmic_gain_on_enum,
536 mt8188_dmic_gain_enable_text);
537
538static 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(c: 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
570static 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_kcontrol_chip(kcontrol);
574 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(c: 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
594static 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
649static 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(dev: afe->dev, size: 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
663int mt8188_dai_dmic_register(struct mtk_base_afe *afe)
664{
665 struct mtk_base_afe_dai *dai;
666
667 dai = devm_kzalloc(dev: afe->dev, size: sizeof(*dai), GFP_KERNEL);
668 if (!dai)
669 return -ENOMEM;
670
671 list_add(new: &dai->list, head: &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

source code of linux/sound/soc/mediatek/mt8188/mt8188-dai-dmic.c