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 <jiaxin.yu@mediatek.com>
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
mtk_get_src_freq_mode(struct mtk_base_afe * afe,int rate)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
get_iir_coeff(unsigned int rate_in,unsigned int rate_out,unsigned int * param_num)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
mtk_set_src_1_param(struct mtk_base_afe * afe,int id)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
mtk_set_src_2_param(struct mtk_base_afe * afe,int id)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
mtk_hw_src_event(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)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
mtk_afe_src_en_connect(struct snd_soc_dapm_widget * source,struct snd_soc_dapm_widget * sink)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 */
mtk_dai_src_hw_params(struct snd_pcm_substream * substream,struct snd_pcm_hw_params * params,struct snd_soc_dai * dai)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
mtk_dai_src_hw_free(struct snd_pcm_substream * substream,struct snd_soc_dai * dai)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
mt8186_dai_src_register(struct mtk_base_afe * afe)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