Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/sound/soc/mediatek/mt8186/mt8186-dai-src.c
26488 views
1
// SPDX-License-Identifier: GPL-2.0
2
//
3
// MediaTek ALSA SoC Audio DAI SRC Control
4
//
5
// Copyright (c) 2022 MediaTek Inc.
6
// Author: Jiaxin Yu <[email protected]>
7
8
#include <linux/regmap.h>
9
#include "mt8186-afe-common.h"
10
#include "mt8186-interconnection.h"
11
12
struct mtk_afe_src_priv {
13
int dl_rate;
14
int ul_rate;
15
};
16
17
static const unsigned int src_iir_coeff_32_to_16[] = {
18
0x0dbae6, 0xff9b0a, 0x0dbae6, 0x05e488, 0xe072b9, 0x000002,
19
0x0dbae6, 0x000f3b, 0x0dbae6, 0x06a537, 0xe17d79, 0x000002,
20
0x0dbae6, 0x01246a, 0x0dbae6, 0x087261, 0xe306be, 0x000002,
21
0x0dbae6, 0x03437d, 0x0dbae6, 0x0bc16f, 0xe57c87, 0x000002,
22
0x0dbae6, 0x072981, 0x0dbae6, 0x111dd3, 0xe94f2a, 0x000002,
23
0x0dbae6, 0x0dc4a6, 0x0dbae6, 0x188611, 0xee85a0, 0x000002,
24
0x0dbae6, 0x168b9a, 0x0dbae6, 0x200e8f, 0xf3ccf1, 0x000002,
25
0x000000, 0x1b75cb, 0x1b75cb, 0x2374a2, 0x000000, 0x000001
26
};
27
28
static const unsigned int src_iir_coeff_44_to_16[] = {
29
0x09ae28, 0xf7d97d, 0x09ae28, 0x212a3d, 0xe0ac3a, 0x000002,
30
0x09ae28, 0xf8525a, 0x09ae28, 0x216d72, 0xe234be, 0x000002,
31
0x09ae28, 0xf980f5, 0x09ae28, 0x22a057, 0xe45a81, 0x000002,
32
0x09ae28, 0xfc0a08, 0x09ae28, 0x24d3bd, 0xe7752d, 0x000002,
33
0x09ae28, 0x016162, 0x09ae28, 0x27da01, 0xeb6ea8, 0x000002,
34
0x09ae28, 0x0b67df, 0x09ae28, 0x2aca4a, 0xef34c4, 0x000002,
35
0x000000, 0x135c50, 0x135c50, 0x2c1079, 0x000000, 0x000001
36
};
37
38
static const unsigned int src_iir_coeff_44_to_32[] = {
39
0x096966, 0x0c4d35, 0x096966, 0xedee81, 0xf05070, 0x000003,
40
0x12d2cc, 0x193910, 0x12d2cc, 0xddbf4f, 0xe21e1d, 0x000002,
41
0x12d2cc, 0x1a9e60, 0x12d2cc, 0xe18916, 0xe470fd, 0x000002,
42
0x12d2cc, 0x1d06e0, 0x12d2cc, 0xe8a4a6, 0xe87b24, 0x000002,
43
0x12d2cc, 0x207578, 0x12d2cc, 0xf4fe62, 0xef5917, 0x000002,
44
0x12d2cc, 0x24055f, 0x12d2cc, 0x05ee2b, 0xf8b502, 0x000002,
45
0x000000, 0x25a599, 0x25a599, 0x0fabe2, 0x000000, 0x000001
46
};
47
48
static const unsigned int src_iir_coeff_48_to_16[] = {
49
0x0296a4, 0xfd69dd, 0x0296a4, 0x209439, 0xe01ff9, 0x000002,
50
0x0f4ff3, 0xf0d6d4, 0x0f4ff3, 0x209bc9, 0xe076c3, 0x000002,
51
0x0e8490, 0xf1fe63, 0x0e8490, 0x20cfd6, 0xe12124, 0x000002,
52
0x14852f, 0xed794a, 0x14852f, 0x21503d, 0xe28b32, 0x000002,
53
0x136222, 0xf17677, 0x136222, 0x225be1, 0xe56964, 0x000002,
54
0x0a8d85, 0xfc4a97, 0x0a8d85, 0x24310c, 0xea6952, 0x000002,
55
0x05eff5, 0x043455, 0x05eff5, 0x4ced8f, 0xe134d6, 0x000001,
56
0x000000, 0x3aebe6, 0x3aebe6, 0x04f3b0, 0x000000, 0x000004
57
};
58
59
static const unsigned int src_iir_coeff_48_to_32[] = {
60
0x10c1b8, 0x10a7df, 0x10c1b8, 0xe7514e, 0xe0b41f, 0x000002,
61
0x10c1b8, 0x116257, 0x10c1b8, 0xe9402f, 0xe25aaa, 0x000002,
62
0x10c1b8, 0x130c89, 0x10c1b8, 0xed3cc3, 0xe4dddb, 0x000002,
63
0x10c1b8, 0x1600dd, 0x10c1b8, 0xf48000, 0xe90c55, 0x000002,
64
0x10c1b8, 0x1a672e, 0x10c1b8, 0x00494c, 0xefa807, 0x000002,
65
0x10c1b8, 0x1f38e6, 0x10c1b8, 0x0ee076, 0xf7c5f3, 0x000002,
66
0x000000, 0x218370, 0x218370, 0x168b40, 0x000000, 0x000001
67
};
68
69
static const unsigned int src_iir_coeff_48_to_44[] = {
70
0x0bf71c, 0x170f3f, 0x0bf71c, 0xe3a4c8, 0xf096cb, 0x000003,
71
0x0bf71c, 0x17395e, 0x0bf71c, 0xe58085, 0xf210c8, 0x000003,
72
0x0bf71c, 0x1782bd, 0x0bf71c, 0xe95ef6, 0xf4c899, 0x000003,
73
0x0bf71c, 0x17cd97, 0x0bf71c, 0xf1608a, 0xfa3b18, 0x000003,
74
0x000000, 0x2fdc6f, 0x2fdc6f, 0xf15663, 0x000000, 0x000001
75
};
76
77
static const unsigned int src_iir_coeff_96_to_16[] = {
78
0x0805a1, 0xf21ae3, 0x0805a1, 0x3840bb, 0xe02a2e, 0x000002,
79
0x0d5dd8, 0xe8f259, 0x0d5dd8, 0x1c0af6, 0xf04700, 0x000003,
80
0x0bb422, 0xec08d9, 0x0bb422, 0x1bfccc, 0xf09216, 0x000003,
81
0x08fde6, 0xf108be, 0x08fde6, 0x1bf096, 0xf10ae0, 0x000003,
82
0x0ae311, 0xeeeda3, 0x0ae311, 0x37c646, 0xe385f5, 0x000002,
83
0x044089, 0xfa7242, 0x044089, 0x37a785, 0xe56526, 0x000002,
84
0x00c75c, 0xffb947, 0x00c75c, 0x378ba3, 0xe72c5f, 0x000002,
85
0x000000, 0x0ef76e, 0x0ef76e, 0x377fda, 0x000000, 0x000001,
86
};
87
88
static const unsigned int src_iir_coeff_96_to_44[] = {
89
0x08b543, 0xfd80f4, 0x08b543, 0x0e2332, 0xe06ed0, 0x000002,
90
0x1b6038, 0xf90e7e, 0x1b6038, 0x0ec1ac, 0xe16f66, 0x000002,
91
0x188478, 0xfbb921, 0x188478, 0x105859, 0xe2e596, 0x000002,
92
0x13eff3, 0xffa707, 0x13eff3, 0x13455c, 0xe533b7, 0x000002,
93
0x0dc239, 0x03d458, 0x0dc239, 0x17f120, 0xe8b617, 0x000002,
94
0x0745f1, 0x05d790, 0x0745f1, 0x1e3d75, 0xed5f18, 0x000002,
95
0x05641f, 0x085e2b, 0x05641f, 0x48efd0, 0xe3e9c8, 0x000001,
96
0x000000, 0x28f632, 0x28f632, 0x273905, 0x000000, 0x000001,
97
};
98
99
static unsigned int mtk_get_src_freq_mode(struct mtk_base_afe *afe, int rate)
100
{
101
switch (rate) {
102
case 8000:
103
return 0x50000;
104
case 11025:
105
return 0x6e400;
106
case 12000:
107
return 0x78000;
108
case 16000:
109
return 0xa0000;
110
case 22050:
111
return 0xdc800;
112
case 24000:
113
return 0xf0000;
114
case 32000:
115
return 0x140000;
116
case 44100:
117
return 0x1b9000;
118
case 48000:
119
return 0x1e0000;
120
case 88200:
121
return 0x372000;
122
case 96000:
123
return 0x3c0000;
124
case 176400:
125
return 0x6e4000;
126
case 192000:
127
return 0x780000;
128
default:
129
dev_err(afe->dev, "%s(), rate %d invalid!!!\n",
130
__func__, rate);
131
return 0;
132
}
133
}
134
135
static const unsigned int *get_iir_coeff(unsigned int rate_in,
136
unsigned int rate_out,
137
unsigned int *param_num)
138
{
139
if (rate_in == 32000 && rate_out == 16000) {
140
*param_num = ARRAY_SIZE(src_iir_coeff_32_to_16);
141
return src_iir_coeff_32_to_16;
142
} else if (rate_in == 44100 && rate_out == 16000) {
143
*param_num = ARRAY_SIZE(src_iir_coeff_44_to_16);
144
return src_iir_coeff_44_to_16;
145
} else if (rate_in == 44100 && rate_out == 32000) {
146
*param_num = ARRAY_SIZE(src_iir_coeff_44_to_32);
147
return src_iir_coeff_44_to_32;
148
} else if ((rate_in == 48000 && rate_out == 16000) ||
149
(rate_in == 96000 && rate_out == 32000)) {
150
*param_num = ARRAY_SIZE(src_iir_coeff_48_to_16);
151
return src_iir_coeff_48_to_16;
152
} else if (rate_in == 48000 && rate_out == 32000) {
153
*param_num = ARRAY_SIZE(src_iir_coeff_48_to_32);
154
return src_iir_coeff_48_to_32;
155
} else if (rate_in == 48000 && rate_out == 44100) {
156
*param_num = ARRAY_SIZE(src_iir_coeff_48_to_44);
157
return src_iir_coeff_48_to_44;
158
} else if (rate_in == 96000 && rate_out == 16000) {
159
*param_num = ARRAY_SIZE(src_iir_coeff_96_to_16);
160
return src_iir_coeff_96_to_16;
161
} else if ((rate_in == 96000 && rate_out == 44100) ||
162
(rate_in == 48000 && rate_out == 22050)) {
163
*param_num = ARRAY_SIZE(src_iir_coeff_96_to_44);
164
return src_iir_coeff_96_to_44;
165
}
166
167
*param_num = 0;
168
return NULL;
169
}
170
171
static int mtk_set_src_1_param(struct mtk_base_afe *afe, int id)
172
{
173
struct mt8186_afe_private *afe_priv = afe->platform_priv;
174
struct mtk_afe_src_priv *src_priv = afe_priv->dai_priv[id];
175
unsigned int iir_coeff_num;
176
unsigned int iir_stage;
177
int rate_in = src_priv->dl_rate;
178
int rate_out = src_priv->ul_rate;
179
unsigned int out_freq_mode = mtk_get_src_freq_mode(afe, rate_out);
180
unsigned int in_freq_mode = mtk_get_src_freq_mode(afe, rate_in);
181
182
/* set out freq mode */
183
regmap_update_bits(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON3,
184
G_SRC_ASM_FREQ_4_MASK_SFT,
185
out_freq_mode << G_SRC_ASM_FREQ_4_SFT);
186
187
/* set in freq mode */
188
regmap_update_bits(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON4,
189
G_SRC_ASM_FREQ_5_MASK_SFT,
190
in_freq_mode << G_SRC_ASM_FREQ_5_SFT);
191
192
regmap_write(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON5, 0x3f5986);
193
regmap_write(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON5, 0x3f5987);
194
regmap_write(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON6, 0x1fbd);
195
regmap_write(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON2, 0);
196
197
/* set iir if in_rate > out_rate */
198
if (rate_in > rate_out) {
199
int i;
200
const unsigned int *iir_coeff = get_iir_coeff(rate_in, rate_out,
201
&iir_coeff_num);
202
203
if (iir_coeff_num == 0 || !iir_coeff) {
204
dev_err(afe->dev, "%s(), iir coeff error, num %d, coeff %p\n",
205
__func__, iir_coeff_num, iir_coeff);
206
return -EINVAL;
207
}
208
209
/* COEFF_SRAM_CTRL */
210
regmap_update_bits(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON0,
211
G_SRC_COEFF_SRAM_CTRL_MASK_SFT,
212
BIT(G_SRC_COEFF_SRAM_CTRL_SFT));
213
/* Clear coeff history to r/w coeff from the first position */
214
regmap_update_bits(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON13,
215
G_SRC_COEFF_SRAM_ADR_MASK_SFT, 0);
216
/* Write SRC coeff, should not read the reg during write */
217
for (i = 0; i < iir_coeff_num; i++)
218
regmap_write(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON12,
219
iir_coeff[i]);
220
/* disable sram access */
221
regmap_update_bits(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON0,
222
G_SRC_COEFF_SRAM_CTRL_MASK_SFT, 0);
223
/* CHSET_IIR_STAGE */
224
iir_stage = (iir_coeff_num / 6) - 1;
225
regmap_update_bits(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON2,
226
G_SRC_CHSET_IIR_STAGE_MASK_SFT,
227
iir_stage << G_SRC_CHSET_IIR_STAGE_SFT);
228
/* CHSET_IIR_EN */
229
regmap_update_bits(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON2,
230
G_SRC_CHSET_IIR_EN_MASK_SFT,
231
BIT(G_SRC_CHSET_IIR_EN_SFT));
232
} else {
233
/* CHSET_IIR_EN off */
234
regmap_update_bits(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON2,
235
G_SRC_CHSET_IIR_EN_MASK_SFT, 0);
236
}
237
238
return 0;
239
}
240
241
static int mtk_set_src_2_param(struct mtk_base_afe *afe, int id)
242
{
243
struct mt8186_afe_private *afe_priv = afe->platform_priv;
244
struct mtk_afe_src_priv *src_priv = afe_priv->dai_priv[id];
245
unsigned int iir_coeff_num;
246
unsigned int iir_stage;
247
int rate_in = src_priv->dl_rate;
248
int rate_out = src_priv->ul_rate;
249
unsigned int out_freq_mode = mtk_get_src_freq_mode(afe, rate_out);
250
unsigned int in_freq_mode = mtk_get_src_freq_mode(afe, rate_in);
251
252
/* set out freq mode */
253
regmap_update_bits(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON3,
254
G_SRC_ASM_FREQ_4_MASK_SFT,
255
out_freq_mode << G_SRC_ASM_FREQ_4_SFT);
256
257
/* set in freq mode */
258
regmap_update_bits(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON4,
259
G_SRC_ASM_FREQ_5_MASK_SFT,
260
in_freq_mode << G_SRC_ASM_FREQ_5_SFT);
261
262
regmap_write(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON5, 0x3f5986);
263
regmap_write(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON5, 0x3f5987);
264
regmap_write(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON6, 0x1fbd);
265
regmap_write(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON2, 0);
266
267
/* set iir if in_rate > out_rate */
268
if (rate_in > rate_out) {
269
int i;
270
const unsigned int *iir_coeff = get_iir_coeff(rate_in, rate_out,
271
&iir_coeff_num);
272
273
if (iir_coeff_num == 0 || !iir_coeff) {
274
dev_err(afe->dev, "%s(), iir coeff error, num %d, coeff %p\n",
275
__func__, iir_coeff_num, iir_coeff);
276
return -EINVAL;
277
}
278
279
/* COEFF_SRAM_CTRL */
280
regmap_update_bits(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON0,
281
G_SRC_COEFF_SRAM_CTRL_MASK_SFT,
282
BIT(G_SRC_COEFF_SRAM_CTRL_SFT));
283
/* Clear coeff history to r/w coeff from the first position */
284
regmap_update_bits(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON13,
285
G_SRC_COEFF_SRAM_ADR_MASK_SFT, 0);
286
/* Write SRC coeff, should not read the reg during write */
287
for (i = 0; i < iir_coeff_num; i++)
288
regmap_write(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON12,
289
iir_coeff[i]);
290
/* disable sram access */
291
regmap_update_bits(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON0,
292
G_SRC_COEFF_SRAM_CTRL_MASK_SFT, 0);
293
/* CHSET_IIR_STAGE */
294
iir_stage = (iir_coeff_num / 6) - 1;
295
regmap_update_bits(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON2,
296
G_SRC_CHSET_IIR_STAGE_MASK_SFT,
297
iir_stage << G_SRC_CHSET_IIR_STAGE_SFT);
298
/* CHSET_IIR_EN */
299
regmap_update_bits(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON2,
300
G_SRC_CHSET_IIR_EN_MASK_SFT,
301
BIT(G_SRC_CHSET_IIR_EN_SFT));
302
} else {
303
/* CHSET_IIR_EN off */
304
regmap_update_bits(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON2,
305
G_SRC_CHSET_IIR_EN_MASK_SFT, 0);
306
}
307
308
return 0;
309
}
310
311
#define HW_SRC_1_EN_W_NAME "HW_SRC_1_Enable"
312
#define HW_SRC_2_EN_W_NAME "HW_SRC_2_Enable"
313
314
static int mtk_hw_src_event(struct snd_soc_dapm_widget *w,
315
struct snd_kcontrol *kcontrol,
316
int event)
317
{
318
struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
319
struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
320
struct mt8186_afe_private *afe_priv = afe->platform_priv;
321
int id;
322
struct mtk_afe_src_priv *src_priv;
323
unsigned int reg;
324
325
if (snd_soc_dapm_widget_name_cmp(w, HW_SRC_1_EN_W_NAME) == 0)
326
id = MT8186_DAI_SRC_1;
327
else
328
id = MT8186_DAI_SRC_2;
329
330
src_priv = afe_priv->dai_priv[id];
331
332
dev_dbg(afe->dev,
333
"%s(), name %s, event 0x%x, id %d, src_priv %p, dl_rate %d, ul_rate %d\n",
334
__func__, w->name, event, id, src_priv,
335
src_priv->dl_rate, src_priv->ul_rate);
336
337
switch (event) {
338
case SND_SOC_DAPM_PRE_PMU:
339
if (id == MT8186_DAI_SRC_1)
340
mtk_set_src_1_param(afe, id);
341
else
342
mtk_set_src_2_param(afe, id);
343
break;
344
case SND_SOC_DAPM_POST_PMU:
345
reg = (id == MT8186_DAI_SRC_1) ?
346
AFE_GENERAL1_ASRC_2CH_CON0 : AFE_GENERAL2_ASRC_2CH_CON0;
347
/* ASM_ON */
348
regmap_update_bits(afe->regmap, reg,
349
G_SRC_ASM_ON_MASK_SFT,
350
BIT(G_SRC_ASM_ON_SFT));
351
/* CHSET_ON */
352
regmap_update_bits(afe->regmap, reg,
353
G_SRC_CHSET_ON_MASK_SFT,
354
BIT(G_SRC_CHSET_ON_SFT));
355
/* CHSET_STR_CLR */
356
regmap_update_bits(afe->regmap, reg,
357
G_SRC_CHSET_STR_CLR_MASK_SFT,
358
BIT(G_SRC_CHSET_STR_CLR_SFT));
359
break;
360
case SND_SOC_DAPM_PRE_PMD:
361
reg = (id == MT8186_DAI_SRC_1) ?
362
AFE_GENERAL1_ASRC_2CH_CON0 : AFE_GENERAL2_ASRC_2CH_CON0;
363
/* ASM_OFF */
364
regmap_update_bits(afe->regmap, reg, G_SRC_ASM_ON_MASK_SFT, 0);
365
/* CHSET_OFF */
366
regmap_update_bits(afe->regmap, reg, G_SRC_CHSET_ON_MASK_SFT, 0);
367
/* CHSET_STR_CLR */
368
regmap_update_bits(afe->regmap, reg, G_SRC_CHSET_STR_CLR_MASK_SFT, 0);
369
break;
370
default:
371
break;
372
}
373
374
return 0;
375
}
376
377
/* dai component */
378
static const struct snd_kcontrol_new mtk_hw_src_1_in_ch1_mix[] = {
379
SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1 Switch", AFE_CONN40,
380
I_DL1_CH1, 1, 0),
381
SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1 Switch", AFE_CONN40,
382
I_DL2_CH1, 1, 0),
383
SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1 Switch", AFE_CONN40,
384
I_DL3_CH1, 1, 0),
385
SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH1 Switch", AFE_CONN40_1,
386
I_DL4_CH1, 1, 0),
387
SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH1 Switch", AFE_CONN40_1,
388
I_DL6_CH1, 1, 0),
389
SOC_DAPM_SINGLE_AUTODISABLE("I2S0_CH1 Switch", AFE_CONN40,
390
I_I2S0_CH1, 1, 0),
391
SOC_DAPM_SINGLE_AUTODISABLE("DL5_CH1 Switch", AFE_CONN40_1,
392
I_DL5_CH1, 1, 0),
393
};
394
395
static const struct snd_kcontrol_new mtk_hw_src_1_in_ch2_mix[] = {
396
SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH2 Switch", AFE_CONN41,
397
I_DL1_CH2, 1, 0),
398
SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH2 Switch", AFE_CONN41,
399
I_DL2_CH2, 1, 0),
400
SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH2 Switch", AFE_CONN41,
401
I_DL3_CH2, 1, 0),
402
SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH2 Switch", AFE_CONN41_1,
403
I_DL4_CH2, 1, 0),
404
SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH2 Switch", AFE_CONN41_1,
405
I_DL6_CH2, 1, 0),
406
SOC_DAPM_SINGLE_AUTODISABLE("I2S0_CH2 Switch", AFE_CONN41,
407
I_I2S0_CH2, 1, 0),
408
SOC_DAPM_SINGLE_AUTODISABLE("DL5_CH2 Switch", AFE_CONN41_1,
409
I_DL5_CH2, 1, 0),
410
};
411
412
static const struct snd_kcontrol_new mtk_hw_src_2_in_ch1_mix[] = {
413
SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1 Switch", AFE_CONN42,
414
I_DL1_CH1, 1, 0),
415
SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1 Switch", AFE_CONN42,
416
I_DL2_CH1, 1, 0),
417
SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1 Switch", AFE_CONN42,
418
I_DL3_CH1, 1, 0),
419
SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH1 Switch", AFE_CONN42,
420
I_DL4_CH1, 1, 0),
421
SOC_DAPM_SINGLE_AUTODISABLE("DL5_CH1 Switch", AFE_CONN42_1,
422
I_DL5_CH1, 1, 0),
423
SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH1 Switch", AFE_CONN42_1,
424
I_DL6_CH1, 1, 0),
425
SOC_DAPM_SINGLE_AUTODISABLE("HW_GAIN2_OUT_CH1 Switch", AFE_CONN42,
426
I_GAIN2_OUT_CH1, 1, 0),
427
};
428
429
static const struct snd_kcontrol_new mtk_hw_src_2_in_ch2_mix[] = {
430
SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH2 Switch", AFE_CONN43,
431
I_DL1_CH2, 1, 0),
432
SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH2 Switch", AFE_CONN43,
433
I_DL2_CH2, 1, 0),
434
SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH2 Switch", AFE_CONN43,
435
I_DL3_CH2, 1, 0),
436
SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH2 Switch", AFE_CONN43,
437
I_DL4_CH2, 1, 0),
438
SOC_DAPM_SINGLE_AUTODISABLE("DL5_CH2 Switch", AFE_CONN43_1,
439
I_DL5_CH2, 1, 0),
440
SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH2 Switch", AFE_CONN43_1,
441
I_DL6_CH2, 1, 0),
442
SOC_DAPM_SINGLE_AUTODISABLE("HW_GAIN2_OUT_CH2 Switch", AFE_CONN43,
443
I_GAIN2_OUT_CH2, 1, 0),
444
};
445
446
static const struct snd_soc_dapm_widget mtk_dai_src_widgets[] = {
447
/* inter-connections */
448
SND_SOC_DAPM_MIXER("HW_SRC_1_IN_CH1", SND_SOC_NOPM, 0, 0,
449
mtk_hw_src_1_in_ch1_mix,
450
ARRAY_SIZE(mtk_hw_src_1_in_ch1_mix)),
451
SND_SOC_DAPM_MIXER("HW_SRC_1_IN_CH2", SND_SOC_NOPM, 0, 0,
452
mtk_hw_src_1_in_ch2_mix,
453
ARRAY_SIZE(mtk_hw_src_1_in_ch2_mix)),
454
SND_SOC_DAPM_MIXER("HW_SRC_2_IN_CH1", SND_SOC_NOPM, 0, 0,
455
mtk_hw_src_2_in_ch1_mix,
456
ARRAY_SIZE(mtk_hw_src_2_in_ch1_mix)),
457
SND_SOC_DAPM_MIXER("HW_SRC_2_IN_CH2", SND_SOC_NOPM, 0, 0,
458
mtk_hw_src_2_in_ch2_mix,
459
ARRAY_SIZE(mtk_hw_src_2_in_ch2_mix)),
460
461
SND_SOC_DAPM_SUPPLY(HW_SRC_1_EN_W_NAME,
462
GENERAL_ASRC_EN_ON, GENERAL1_ASRC_EN_ON_SFT, 0,
463
mtk_hw_src_event,
464
SND_SOC_DAPM_PRE_PMU |
465
SND_SOC_DAPM_POST_PMU |
466
SND_SOC_DAPM_PRE_PMD),
467
468
SND_SOC_DAPM_SUPPLY(HW_SRC_2_EN_W_NAME,
469
GENERAL_ASRC_EN_ON, GENERAL2_ASRC_EN_ON_SFT, 0,
470
mtk_hw_src_event,
471
SND_SOC_DAPM_PRE_PMU |
472
SND_SOC_DAPM_POST_PMU |
473
SND_SOC_DAPM_PRE_PMD),
474
475
SND_SOC_DAPM_INPUT("HW SRC 1 Out Endpoint"),
476
SND_SOC_DAPM_INPUT("HW SRC 2 Out Endpoint"),
477
SND_SOC_DAPM_OUTPUT("HW SRC 1 In Endpoint"),
478
SND_SOC_DAPM_OUTPUT("HW SRC 2 In Endpoint"),
479
};
480
481
static int mtk_afe_src_en_connect(struct snd_soc_dapm_widget *source,
482
struct snd_soc_dapm_widget *sink)
483
{
484
struct snd_soc_dapm_widget *w = source;
485
struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
486
struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
487
struct mt8186_afe_private *afe_priv = afe->platform_priv;
488
struct mtk_afe_src_priv *src_priv;
489
490
if (snd_soc_dapm_widget_name_cmp(w, HW_SRC_1_EN_W_NAME) == 0)
491
src_priv = afe_priv->dai_priv[MT8186_DAI_SRC_1];
492
else
493
src_priv = afe_priv->dai_priv[MT8186_DAI_SRC_2];
494
495
dev_dbg(afe->dev,
496
"%s(), source %s, sink %s, dl_rate %d, ul_rate %d\n",
497
__func__, source->name, sink->name,
498
src_priv->dl_rate, src_priv->ul_rate);
499
500
return (src_priv->dl_rate > 0 && src_priv->ul_rate > 0) ? 1 : 0;
501
}
502
503
static const struct snd_soc_dapm_route mtk_dai_src_routes[] = {
504
{"HW_SRC_1_IN_CH1", "DL1_CH1 Switch", "DL1"},
505
{"HW_SRC_1_IN_CH2", "DL1_CH2 Switch", "DL1"},
506
{"HW_SRC_2_IN_CH1", "DL1_CH1 Switch", "DL1"},
507
{"HW_SRC_2_IN_CH2", "DL1_CH2 Switch", "DL1"},
508
{"HW_SRC_1_IN_CH1", "DL2_CH1 Switch", "DL2"},
509
{"HW_SRC_1_IN_CH2", "DL2_CH2 Switch", "DL2"},
510
{"HW_SRC_2_IN_CH1", "DL2_CH1 Switch", "DL2"},
511
{"HW_SRC_2_IN_CH2", "DL2_CH2 Switch", "DL2"},
512
{"HW_SRC_1_IN_CH1", "DL3_CH1 Switch", "DL3"},
513
{"HW_SRC_1_IN_CH2", "DL3_CH2 Switch", "DL3"},
514
{"HW_SRC_2_IN_CH1", "DL3_CH1 Switch", "DL3"},
515
{"HW_SRC_2_IN_CH2", "DL3_CH2 Switch", "DL3"},
516
{"HW_SRC_1_IN_CH1", "DL6_CH1 Switch", "DL6"},
517
{"HW_SRC_1_IN_CH2", "DL6_CH2 Switch", "DL6"},
518
{"HW_SRC_2_IN_CH1", "DL6_CH1 Switch", "DL6"},
519
{"HW_SRC_2_IN_CH2", "DL6_CH2 Switch", "DL6"},
520
{"HW_SRC_1_IN_CH1", "DL5_CH1 Switch", "DL5"},
521
{"HW_SRC_1_IN_CH2", "DL5_CH2 Switch", "DL5"},
522
{"HW_SRC_2_IN_CH1", "DL5_CH1 Switch", "DL5"},
523
{"HW_SRC_2_IN_CH2", "DL5_CH2 Switch", "DL5"},
524
{"HW_SRC_1_IN_CH1", "DL4_CH1 Switch", "DL4"},
525
{"HW_SRC_1_IN_CH2", "DL4_CH2 Switch", "DL4"},
526
{"HW_SRC_2_IN_CH1", "DL4_CH1 Switch", "DL4"},
527
{"HW_SRC_2_IN_CH2", "DL4_CH2 Switch", "DL4"},
528
529
{"HW_SRC_1_In", NULL, "HW_SRC_1_IN_CH1"},
530
{"HW_SRC_1_In", NULL, "HW_SRC_1_IN_CH2"},
531
532
{"HW_SRC_2_In", NULL, "HW_SRC_2_IN_CH1"},
533
{"HW_SRC_2_In", NULL, "HW_SRC_2_IN_CH2"},
534
535
{"HW_SRC_1_In", NULL, HW_SRC_1_EN_W_NAME, mtk_afe_src_en_connect},
536
{"HW_SRC_1_Out", NULL, HW_SRC_1_EN_W_NAME, mtk_afe_src_en_connect},
537
{"HW_SRC_2_In", NULL, HW_SRC_2_EN_W_NAME, mtk_afe_src_en_connect},
538
{"HW_SRC_2_Out", NULL, HW_SRC_2_EN_W_NAME, mtk_afe_src_en_connect},
539
540
{"HW SRC 1 In Endpoint", NULL, "HW_SRC_1_In"},
541
{"HW SRC 2 In Endpoint", NULL, "HW_SRC_2_In"},
542
{"HW_SRC_1_Out", NULL, "HW SRC 1 Out Endpoint"},
543
{"HW_SRC_2_Out", NULL, "HW SRC 2 Out Endpoint"},
544
};
545
546
/* dai ops */
547
static int mtk_dai_src_hw_params(struct snd_pcm_substream *substream,
548
struct snd_pcm_hw_params *params,
549
struct snd_soc_dai *dai)
550
{
551
struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
552
struct mt8186_afe_private *afe_priv = afe->platform_priv;
553
int id = dai->id;
554
struct mtk_afe_src_priv *src_priv = afe_priv->dai_priv[id];
555
unsigned int sft, mask;
556
unsigned int rate = params_rate(params);
557
unsigned int rate_reg = mt8186_rate_transform(afe->dev, rate, id);
558
559
dev_dbg(afe->dev, "%s(), id %d, stream %d, rate %d\n",
560
__func__, id, substream->stream, rate);
561
562
/* rate */
563
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
564
src_priv->dl_rate = rate;
565
if (id == MT8186_DAI_SRC_1) {
566
sft = GENERAL1_ASRCIN_MODE_SFT;
567
mask = GENERAL1_ASRCIN_MODE_MASK;
568
} else {
569
sft = GENERAL2_ASRCIN_MODE_SFT;
570
mask = GENERAL2_ASRCIN_MODE_MASK;
571
}
572
} else {
573
src_priv->ul_rate = rate;
574
if (id == MT8186_DAI_SRC_1) {
575
sft = GENERAL1_ASRCOUT_MODE_SFT;
576
mask = GENERAL1_ASRCOUT_MODE_MASK;
577
} else {
578
sft = GENERAL2_ASRCOUT_MODE_SFT;
579
mask = GENERAL2_ASRCOUT_MODE_MASK;
580
}
581
}
582
583
regmap_update_bits(afe->regmap, GENERAL_ASRC_MODE, mask << sft, rate_reg << sft);
584
585
return 0;
586
}
587
588
static int mtk_dai_src_hw_free(struct snd_pcm_substream *substream,
589
struct snd_soc_dai *dai)
590
{
591
struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
592
struct mt8186_afe_private *afe_priv = afe->platform_priv;
593
int id = dai->id;
594
struct mtk_afe_src_priv *src_priv = afe_priv->dai_priv[id];
595
596
dev_dbg(afe->dev, "%s(), id %d, stream %d\n",
597
__func__, id, substream->stream);
598
599
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
600
src_priv->dl_rate = 0;
601
else
602
src_priv->ul_rate = 0;
603
604
return 0;
605
}
606
607
static const struct snd_soc_dai_ops mtk_dai_src_ops = {
608
.hw_params = mtk_dai_src_hw_params,
609
.hw_free = mtk_dai_src_hw_free,
610
};
611
612
/* dai driver */
613
#define MTK_SRC_RATES (SNDRV_PCM_RATE_8000_48000 |\
614
SNDRV_PCM_RATE_88200 |\
615
SNDRV_PCM_RATE_96000 |\
616
SNDRV_PCM_RATE_176400 |\
617
SNDRV_PCM_RATE_192000)
618
619
#define MTK_SRC_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
620
SNDRV_PCM_FMTBIT_S24_LE |\
621
SNDRV_PCM_FMTBIT_S32_LE)
622
623
static struct snd_soc_dai_driver mtk_dai_src_driver[] = {
624
{
625
.name = "HW_SRC_1",
626
.id = MT8186_DAI_SRC_1,
627
.playback = {
628
.stream_name = "HW_SRC_1_In",
629
.channels_min = 1,
630
.channels_max = 2,
631
.rates = MTK_SRC_RATES,
632
.formats = MTK_SRC_FORMATS,
633
},
634
.capture = {
635
.stream_name = "HW_SRC_1_Out",
636
.channels_min = 1,
637
.channels_max = 2,
638
.rates = MTK_SRC_RATES,
639
.formats = MTK_SRC_FORMATS,
640
},
641
.ops = &mtk_dai_src_ops,
642
},
643
{
644
.name = "HW_SRC_2",
645
.id = MT8186_DAI_SRC_2,
646
.playback = {
647
.stream_name = "HW_SRC_2_In",
648
.channels_min = 1,
649
.channels_max = 2,
650
.rates = MTK_SRC_RATES,
651
.formats = MTK_SRC_FORMATS,
652
},
653
.capture = {
654
.stream_name = "HW_SRC_2_Out",
655
.channels_min = 1,
656
.channels_max = 2,
657
.rates = MTK_SRC_RATES,
658
.formats = MTK_SRC_FORMATS,
659
},
660
.ops = &mtk_dai_src_ops,
661
},
662
};
663
664
int mt8186_dai_src_register(struct mtk_base_afe *afe)
665
{
666
struct mtk_base_afe_dai *dai;
667
int ret;
668
669
dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL);
670
if (!dai)
671
return -ENOMEM;
672
673
list_add(&dai->list, &afe->sub_dais);
674
675
dai->dai_drivers = mtk_dai_src_driver;
676
dai->num_dai_drivers = ARRAY_SIZE(mtk_dai_src_driver);
677
678
dai->dapm_widgets = mtk_dai_src_widgets;
679
dai->num_dapm_widgets = ARRAY_SIZE(mtk_dai_src_widgets);
680
dai->dapm_routes = mtk_dai_src_routes;
681
dai->num_dapm_routes = ARRAY_SIZE(mtk_dai_src_routes);
682
683
/* set dai priv */
684
ret = mt8186_dai_set_priv(afe, MT8186_DAI_SRC_1,
685
sizeof(struct mtk_afe_src_priv), NULL);
686
if (ret)
687
return ret;
688
689
ret = mt8186_dai_set_priv(afe, MT8186_DAI_SRC_2,
690
sizeof(struct mtk_afe_src_priv), NULL);
691
if (ret)
692
return ret;
693
694
return 0;
695
}
696
697