Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/sound/soc/mediatek/mt8188/mt8188-dai-dmic.c
26488 views
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 <[email protected]>
7
* Trevor Wu <[email protected]>
8
* Parker Yang <[email protected]>
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
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
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
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
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
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
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 */
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
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
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
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
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
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
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
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
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
685