1 // SPDX-License-Identifier: GPL-2.0
2 //
3 // MediaTek ALSA SoC Audio DAI I2S Control
4 //
5 // Copyright (c) 2022 MediaTek Inc.
6 // Author: Jiaxin Yu <jiaxin.yu@mediatek.com>
7
8 #include <linux/bitops.h>
9 #include <linux/regmap.h>
10 #include <sound/pcm_params.h>
11 #include "mt8186-afe-clk.h"
12 #include "mt8186-afe-common.h"
13 #include "mt8186-afe-gpio.h"
14 #include "mt8186-interconnection.h"
15
16 enum {
17 I2S_FMT_EIAJ = 0,
18 I2S_FMT_I2S = 1,
19 };
20
21 enum {
22 I2S_WLEN_16_BIT = 0,
23 I2S_WLEN_32_BIT = 1,
24 };
25
26 enum {
27 I2S_HD_NORMAL = 0,
28 I2S_HD_LOW_JITTER = 1,
29 };
30
31 enum {
32 I2S1_SEL_O28_O29 = 0,
33 I2S1_SEL_O03_O04 = 1,
34 };
35
36 enum {
37 I2S_IN_PAD_CONNSYS = 0,
38 I2S_IN_PAD_IO_MUX = 1,
39 };
40
41 struct mtk_afe_i2s_priv {
42 int id;
43 int rate; /* for determine which apll to use */
44 int low_jitter_en;
45 int master; /* only i2s0 has slave mode*/
46
47 int share_i2s_id;
48
49 int mclk_id;
50 int mclk_rate;
51 int mclk_apll;
52 };
53
get_i2s_wlen(snd_pcm_format_t format)54 static unsigned int get_i2s_wlen(snd_pcm_format_t format)
55 {
56 return snd_pcm_format_physical_width(format) <= 16 ?
57 I2S_WLEN_16_BIT : I2S_WLEN_32_BIT;
58 }
59
60 #define MTK_AFE_I2S0_KCONTROL_NAME "I2S0_HD_Mux"
61 #define MTK_AFE_I2S1_KCONTROL_NAME "I2S1_HD_Mux"
62 #define MTK_AFE_I2S2_KCONTROL_NAME "I2S2_HD_Mux"
63 #define MTK_AFE_I2S3_KCONTROL_NAME "I2S3_HD_Mux"
64 #define MTK_AFE_I2S0_SRC_KCONTROL_NAME "I2S0_SRC_Mux"
65
66 #define I2S0_HD_EN_W_NAME "I2S0_HD_EN"
67 #define I2S1_HD_EN_W_NAME "I2S1_HD_EN"
68 #define I2S2_HD_EN_W_NAME "I2S2_HD_EN"
69 #define I2S3_HD_EN_W_NAME "I2S3_HD_EN"
70
71 #define I2S0_MCLK_EN_W_NAME "I2S0_MCLK_EN"
72 #define I2S1_MCLK_EN_W_NAME "I2S1_MCLK_EN"
73 #define I2S2_MCLK_EN_W_NAME "I2S2_MCLK_EN"
74 #define I2S3_MCLK_EN_W_NAME "I2S3_MCLK_EN"
75
get_i2s_id_by_name(struct mtk_base_afe * afe,const char * name)76 static int get_i2s_id_by_name(struct mtk_base_afe *afe,
77 const char *name)
78 {
79 if (strncmp(name, "I2S0", 4) == 0)
80 return MT8186_DAI_I2S_0;
81 else if (strncmp(name, "I2S1", 4) == 0)
82 return MT8186_DAI_I2S_1;
83 else if (strncmp(name, "I2S2", 4) == 0)
84 return MT8186_DAI_I2S_2;
85 else if (strncmp(name, "I2S3", 4) == 0)
86 return MT8186_DAI_I2S_3;
87
88 return -EINVAL;
89 }
90
get_i2s_priv_by_name(struct mtk_base_afe * afe,const char * name)91 static struct mtk_afe_i2s_priv *get_i2s_priv_by_name(struct mtk_base_afe *afe,
92 const char *name)
93 {
94 struct mt8186_afe_private *afe_priv = afe->platform_priv;
95 int dai_id = get_i2s_id_by_name(afe, name);
96
97 if (dai_id < 0)
98 return NULL;
99
100 return afe_priv->dai_priv[dai_id];
101 }
102
103 /* low jitter control */
104 static const char * const mt8186_i2s_hd_str[] = {
105 "Normal", "Low_Jitter"
106 };
107
108 static const struct soc_enum mt8186_i2s_enum[] = {
109 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(mt8186_i2s_hd_str),
110 mt8186_i2s_hd_str),
111 };
112
mt8186_i2s_hd_get(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)113 static int mt8186_i2s_hd_get(struct snd_kcontrol *kcontrol,
114 struct snd_ctl_elem_value *ucontrol)
115 {
116 struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
117 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
118 struct mtk_afe_i2s_priv *i2s_priv;
119
120 i2s_priv = get_i2s_priv_by_name(afe, kcontrol->id.name);
121 ucontrol->value.integer.value[0] = i2s_priv->low_jitter_en;
122
123 return 0;
124 }
125
mt8186_i2s_hd_set(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)126 static int mt8186_i2s_hd_set(struct snd_kcontrol *kcontrol,
127 struct snd_ctl_elem_value *ucontrol)
128 {
129 struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
130 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
131 struct mtk_afe_i2s_priv *i2s_priv;
132 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
133 int hd_en;
134
135 if (ucontrol->value.enumerated.item[0] >= e->items)
136 return -EINVAL;
137
138 hd_en = ucontrol->value.integer.value[0];
139
140 dev_dbg(afe->dev, "%s(), kcontrol name %s, hd_en %d\n",
141 __func__, kcontrol->id.name, hd_en);
142
143 i2s_priv = get_i2s_priv_by_name(afe, kcontrol->id.name);
144 if (i2s_priv->low_jitter_en == hd_en)
145 return 0;
146
147 i2s_priv->low_jitter_en = hd_en;
148
149 return 1;
150 }
151
152 static const struct snd_kcontrol_new mtk_dai_i2s_controls[] = {
153 SOC_ENUM_EXT(MTK_AFE_I2S0_KCONTROL_NAME, mt8186_i2s_enum[0],
154 mt8186_i2s_hd_get, mt8186_i2s_hd_set),
155 SOC_ENUM_EXT(MTK_AFE_I2S1_KCONTROL_NAME, mt8186_i2s_enum[0],
156 mt8186_i2s_hd_get, mt8186_i2s_hd_set),
157 SOC_ENUM_EXT(MTK_AFE_I2S2_KCONTROL_NAME, mt8186_i2s_enum[0],
158 mt8186_i2s_hd_get, mt8186_i2s_hd_set),
159 SOC_ENUM_EXT(MTK_AFE_I2S3_KCONTROL_NAME, mt8186_i2s_enum[0],
160 mt8186_i2s_hd_get, mt8186_i2s_hd_set),
161 };
162
163 /* dai component */
164 /* i2s virtual mux to output widget */
165 static const char * const i2s_mux_map[] = {
166 "Normal", "Dummy_Widget",
167 };
168
169 static int i2s_mux_map_value[] = {
170 0, 1,
171 };
172
173 static SOC_VALUE_ENUM_SINGLE_AUTODISABLE_DECL(i2s_mux_map_enum,
174 SND_SOC_NOPM,
175 0,
176 1,
177 i2s_mux_map,
178 i2s_mux_map_value);
179
180 static const struct snd_kcontrol_new i2s0_in_mux_control =
181 SOC_DAPM_ENUM("I2S0 In Select", i2s_mux_map_enum);
182
183 static const struct snd_kcontrol_new i2s1_out_mux_control =
184 SOC_DAPM_ENUM("I2S1 Out Select", i2s_mux_map_enum);
185
186 static const struct snd_kcontrol_new i2s2_in_mux_control =
187 SOC_DAPM_ENUM("I2S2 In Select", i2s_mux_map_enum);
188
189 static const struct snd_kcontrol_new i2s3_out_mux_control =
190 SOC_DAPM_ENUM("I2S3 Out Select", i2s_mux_map_enum);
191
192 /* i2s in lpbk */
193 static const char * const i2s_lpbk_mux_map[] = {
194 "Normal", "Lpbk",
195 };
196
197 static int i2s_lpbk_mux_map_value[] = {
198 0, 1,
199 };
200
201 static SOC_VALUE_ENUM_SINGLE_AUTODISABLE_DECL(i2s0_lpbk_mux_map_enum,
202 AFE_I2S_CON,
203 I2S_LOOPBACK_SFT,
204 1,
205 i2s_lpbk_mux_map,
206 i2s_lpbk_mux_map_value);
207
208 static const struct snd_kcontrol_new i2s0_lpbk_mux_control =
209 SOC_DAPM_ENUM("I2S Lpbk Select", i2s0_lpbk_mux_map_enum);
210
211 static SOC_VALUE_ENUM_SINGLE_AUTODISABLE_DECL(i2s2_lpbk_mux_map_enum,
212 AFE_I2S_CON2,
213 I2S3_LOOPBACK_SFT,
214 1,
215 i2s_lpbk_mux_map,
216 i2s_lpbk_mux_map_value);
217
218 static const struct snd_kcontrol_new i2s2_lpbk_mux_control =
219 SOC_DAPM_ENUM("I2S Lpbk Select", i2s2_lpbk_mux_map_enum);
220
221 /* interconnection */
222 static const struct snd_kcontrol_new mtk_i2s3_ch1_mix[] = {
223 SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1 Switch", AFE_CONN0,
224 I_DL1_CH1, 1, 0),
225 SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1 Switch", AFE_CONN0,
226 I_DL2_CH1, 1, 0),
227 SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1 Switch", AFE_CONN0,
228 I_DL3_CH1, 1, 0),
229 SOC_DAPM_SINGLE_AUTODISABLE("DL12_CH1 Switch", AFE_CONN0,
230 I_DL12_CH1, 1, 0),
231 SOC_DAPM_SINGLE_AUTODISABLE("DL12_CH3 Switch", AFE_CONN0,
232 I_DL12_CH3, 1, 0),
233 SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH1 Switch", AFE_CONN0_1,
234 I_DL6_CH1, 1, 0),
235 SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH1 Switch", AFE_CONN0_1,
236 I_DL4_CH1, 1, 0),
237 SOC_DAPM_SINGLE_AUTODISABLE("DL5_CH1 Switch", AFE_CONN0_1,
238 I_DL5_CH1, 1, 0),
239 SOC_DAPM_SINGLE_AUTODISABLE("DL8_CH1 Switch", AFE_CONN0_1,
240 I_DL8_CH1, 1, 0),
241 SOC_DAPM_SINGLE_AUTODISABLE("GAIN1_OUT_CH1 Switch", AFE_CONN0,
242 I_GAIN1_OUT_CH1, 1, 0),
243 SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1 Switch", AFE_CONN0,
244 I_ADDA_UL_CH1, 1, 0),
245 SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2 Switch", AFE_CONN0,
246 I_ADDA_UL_CH2, 1, 0),
247 SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3 Switch", AFE_CONN0,
248 I_ADDA_UL_CH3, 1, 0),
249 SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH1 Switch", AFE_CONN0,
250 I_PCM_1_CAP_CH1, 1, 0),
251 SOC_DAPM_SINGLE_AUTODISABLE("SRC_1_OUT_CH1 Switch", AFE_CONN0_1,
252 I_SRC_1_OUT_CH1, 1, 0),
253 };
254
255 static const struct snd_kcontrol_new mtk_i2s3_ch2_mix[] = {
256 SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH2 Switch", AFE_CONN1,
257 I_DL1_CH2, 1, 0),
258 SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH2 Switch", AFE_CONN1,
259 I_DL2_CH2, 1, 0),
260 SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH2 Switch", AFE_CONN1,
261 I_DL3_CH2, 1, 0),
262 SOC_DAPM_SINGLE_AUTODISABLE("DL12_CH2 Switch", AFE_CONN1,
263 I_DL12_CH2, 1, 0),
264 SOC_DAPM_SINGLE_AUTODISABLE("DL12_CH4 Switch", AFE_CONN1,
265 I_DL12_CH4, 1, 0),
266 SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH2 Switch", AFE_CONN1_1,
267 I_DL6_CH2, 1, 0),
268 SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH2 Switch", AFE_CONN1_1,
269 I_DL4_CH2, 1, 0),
270 SOC_DAPM_SINGLE_AUTODISABLE("DL5_CH2 Switch", AFE_CONN1_1,
271 I_DL5_CH2, 1, 0),
272 SOC_DAPM_SINGLE_AUTODISABLE("DL8_CH2 Switch", AFE_CONN1_1,
273 I_DL8_CH2, 1, 0),
274 SOC_DAPM_SINGLE_AUTODISABLE("GAIN1_OUT_CH2 Switch", AFE_CONN1,
275 I_GAIN1_OUT_CH2, 1, 0),
276 SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1 Switch", AFE_CONN1,
277 I_ADDA_UL_CH1, 1, 0),
278 SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2 Switch", AFE_CONN1,
279 I_ADDA_UL_CH2, 1, 0),
280 SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3 Switch", AFE_CONN1,
281 I_ADDA_UL_CH3, 1, 0),
282 SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH2 Switch", AFE_CONN1,
283 I_PCM_1_CAP_CH2, 1, 0),
284 SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH2 Switch", AFE_CONN1,
285 I_PCM_2_CAP_CH2, 1, 0),
286 SOC_DAPM_SINGLE_AUTODISABLE("SRC_1_OUT_CH2 Switch", AFE_CONN1_1,
287 I_SRC_1_OUT_CH2, 1, 0),
288 };
289
290 static const struct snd_kcontrol_new mtk_i2s1_ch1_mix[] = {
291 SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1 Switch", AFE_CONN28,
292 I_DL1_CH1, 1, 0),
293 SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1 Switch", AFE_CONN28,
294 I_DL2_CH1, 1, 0),
295 SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1 Switch", AFE_CONN28,
296 I_DL3_CH1, 1, 0),
297 SOC_DAPM_SINGLE_AUTODISABLE("DL12_CH1 Switch", AFE_CONN28,
298 I_DL12_CH1, 1, 0),
299 SOC_DAPM_SINGLE_AUTODISABLE("DL12_CH3 Switch", AFE_CONN28,
300 I_DL12_CH3, 1, 0),
301 SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH1 Switch", AFE_CONN28_1,
302 I_DL6_CH1, 1, 0),
303 SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH1 Switch", AFE_CONN28_1,
304 I_DL4_CH1, 1, 0),
305 SOC_DAPM_SINGLE_AUTODISABLE("DL5_CH1 Switch", AFE_CONN28_1,
306 I_DL5_CH1, 1, 0),
307 SOC_DAPM_SINGLE_AUTODISABLE("DL8_CH1 Switch", AFE_CONN28_1,
308 I_DL8_CH1, 1, 0),
309 SOC_DAPM_SINGLE_AUTODISABLE("GAIN1_OUT_CH1 Switch", AFE_CONN28,
310 I_GAIN1_OUT_CH1, 1, 0),
311 SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1 Switch", AFE_CONN28,
312 I_ADDA_UL_CH1, 1, 0),
313 SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH1 Switch", AFE_CONN28,
314 I_PCM_1_CAP_CH1, 1, 0),
315 SOC_DAPM_SINGLE_AUTODISABLE("SRC_1_OUT_CH1 Switch", AFE_CONN28_1,
316 I_SRC_1_OUT_CH1, 1, 0),
317 };
318
319 static const struct snd_kcontrol_new mtk_i2s1_ch2_mix[] = {
320 SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH2 Switch", AFE_CONN29,
321 I_DL1_CH2, 1, 0),
322 SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH2 Switch", AFE_CONN29,
323 I_DL2_CH2, 1, 0),
324 SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH2 Switch", AFE_CONN29,
325 I_DL3_CH2, 1, 0),
326 SOC_DAPM_SINGLE_AUTODISABLE("DL12_CH2 Switch", AFE_CONN29,
327 I_DL12_CH2, 1, 0),
328 SOC_DAPM_SINGLE_AUTODISABLE("DL12_CH4 Switch", AFE_CONN29,
329 I_DL12_CH4, 1, 0),
330 SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH2 Switch", AFE_CONN29_1,
331 I_DL6_CH2, 1, 0),
332 SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH2 Switch", AFE_CONN29_1,
333 I_DL4_CH2, 1, 0),
334 SOC_DAPM_SINGLE_AUTODISABLE("DL5_CH2 Switch", AFE_CONN29_1,
335 I_DL5_CH2, 1, 0),
336 SOC_DAPM_SINGLE_AUTODISABLE("DL8_CH2 Switch", AFE_CONN29_1,
337 I_DL8_CH2, 1, 0),
338 SOC_DAPM_SINGLE_AUTODISABLE("GAIN1_OUT_CH2 Switch", AFE_CONN29,
339 I_GAIN1_OUT_CH2, 1, 0),
340 SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2 Switch", AFE_CONN29,
341 I_ADDA_UL_CH2, 1, 0),
342 SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH2 Switch", AFE_CONN29,
343 I_PCM_1_CAP_CH2, 1, 0),
344 SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH2 Switch", AFE_CONN29,
345 I_PCM_2_CAP_CH2, 1, 0),
346 SOC_DAPM_SINGLE_AUTODISABLE("SRC_1_OUT_CH2 Switch", AFE_CONN29_1,
347 I_SRC_1_OUT_CH2, 1, 0),
348 };
349
350 enum {
351 SUPPLY_SEQ_APLL,
352 SUPPLY_SEQ_I2S_MCLK_EN,
353 SUPPLY_SEQ_I2S_HD_EN,
354 SUPPLY_SEQ_I2S_EN,
355 };
356
mtk_i2s_en_event(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)357 static int mtk_i2s_en_event(struct snd_soc_dapm_widget *w,
358 struct snd_kcontrol *kcontrol,
359 int event)
360 {
361 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
362 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
363 struct mtk_afe_i2s_priv *i2s_priv;
364
365 i2s_priv = get_i2s_priv_by_name(afe, w->name);
366
367 dev_dbg(cmpnt->dev, "%s(), name %s, event 0x%x\n",
368 __func__, w->name, event);
369
370 switch (event) {
371 case SND_SOC_DAPM_PRE_PMU:
372 mt8186_afe_gpio_request(afe->dev, true, i2s_priv->id, 0);
373 break;
374 case SND_SOC_DAPM_POST_PMD:
375 mt8186_afe_gpio_request(afe->dev, false, i2s_priv->id, 0);
376 break;
377 default:
378 break;
379 }
380
381 return 0;
382 }
383
mtk_apll_event(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)384 static int mtk_apll_event(struct snd_soc_dapm_widget *w,
385 struct snd_kcontrol *kcontrol,
386 int event)
387 {
388 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
389 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
390
391 dev_dbg(cmpnt->dev, "%s(), name %s, event 0x%x\n",
392 __func__, w->name, event);
393
394 switch (event) {
395 case SND_SOC_DAPM_PRE_PMU:
396 if (snd_soc_dapm_widget_name_cmp(w, APLL1_W_NAME) == 0)
397 mt8186_apll1_enable(afe);
398 else
399 mt8186_apll2_enable(afe);
400 break;
401 case SND_SOC_DAPM_POST_PMD:
402 if (snd_soc_dapm_widget_name_cmp(w, APLL1_W_NAME) == 0)
403 mt8186_apll1_disable(afe);
404 else
405 mt8186_apll2_disable(afe);
406 break;
407 default:
408 break;
409 }
410
411 return 0;
412 }
413
mtk_mclk_en_event(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)414 static int mtk_mclk_en_event(struct snd_soc_dapm_widget *w,
415 struct snd_kcontrol *kcontrol,
416 int event)
417 {
418 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
419 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
420 struct mtk_afe_i2s_priv *i2s_priv;
421
422 dev_dbg(cmpnt->dev, "%s(), name %s, event 0x%x\n",
423 __func__, w->name, event);
424
425 i2s_priv = get_i2s_priv_by_name(afe, w->name);
426
427 switch (event) {
428 case SND_SOC_DAPM_PRE_PMU:
429 mt8186_mck_enable(afe, i2s_priv->mclk_id, i2s_priv->mclk_rate);
430 break;
431 case SND_SOC_DAPM_POST_PMD:
432 i2s_priv->mclk_rate = 0;
433 mt8186_mck_disable(afe, i2s_priv->mclk_id);
434 break;
435 default:
436 break;
437 }
438
439 return 0;
440 }
441
442 static const struct snd_soc_dapm_widget mtk_dai_i2s_widgets[] = {
443 SND_SOC_DAPM_INPUT("CONNSYS"),
444
445 SND_SOC_DAPM_MIXER("I2S1_CH1", SND_SOC_NOPM, 0, 0,
446 mtk_i2s1_ch1_mix,
447 ARRAY_SIZE(mtk_i2s1_ch1_mix)),
448 SND_SOC_DAPM_MIXER("I2S1_CH2", SND_SOC_NOPM, 0, 0,
449 mtk_i2s1_ch2_mix,
450 ARRAY_SIZE(mtk_i2s1_ch2_mix)),
451
452 SND_SOC_DAPM_MIXER("I2S3_CH1", SND_SOC_NOPM, 0, 0,
453 mtk_i2s3_ch1_mix,
454 ARRAY_SIZE(mtk_i2s3_ch1_mix)),
455 SND_SOC_DAPM_MIXER("I2S3_CH2", SND_SOC_NOPM, 0, 0,
456 mtk_i2s3_ch2_mix,
457 ARRAY_SIZE(mtk_i2s3_ch2_mix)),
458
459 /* i2s en*/
460 SND_SOC_DAPM_SUPPLY_S("I2S0_EN", SUPPLY_SEQ_I2S_EN,
461 AFE_I2S_CON, I2S_EN_SFT, 0,
462 mtk_i2s_en_event,
463 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
464 SND_SOC_DAPM_SUPPLY_S("I2S1_EN", SUPPLY_SEQ_I2S_EN,
465 AFE_I2S_CON1, I2S_EN_SFT, 0,
466 mtk_i2s_en_event,
467 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
468 SND_SOC_DAPM_SUPPLY_S("I2S2_EN", SUPPLY_SEQ_I2S_EN,
469 AFE_I2S_CON2, I2S_EN_SFT, 0,
470 mtk_i2s_en_event,
471 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
472 SND_SOC_DAPM_SUPPLY_S("I2S3_EN", SUPPLY_SEQ_I2S_EN,
473 AFE_I2S_CON3, I2S_EN_SFT, 0,
474 mtk_i2s_en_event,
475 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
476 /* i2s hd en */
477 SND_SOC_DAPM_SUPPLY_S(I2S0_HD_EN_W_NAME, SUPPLY_SEQ_I2S_HD_EN,
478 AFE_I2S_CON, I2S1_HD_EN_SFT, 0, NULL,
479 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
480 SND_SOC_DAPM_SUPPLY_S(I2S1_HD_EN_W_NAME, SUPPLY_SEQ_I2S_HD_EN,
481 AFE_I2S_CON1, I2S2_HD_EN_SFT, 0, NULL,
482 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
483 SND_SOC_DAPM_SUPPLY_S(I2S2_HD_EN_W_NAME, SUPPLY_SEQ_I2S_HD_EN,
484 AFE_I2S_CON2, I2S3_HD_EN_SFT, 0, NULL,
485 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
486 SND_SOC_DAPM_SUPPLY_S(I2S3_HD_EN_W_NAME, SUPPLY_SEQ_I2S_HD_EN,
487 AFE_I2S_CON3, I2S4_HD_EN_SFT, 0, NULL,
488 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
489
490 /* i2s mclk en */
491 SND_SOC_DAPM_SUPPLY_S(I2S0_MCLK_EN_W_NAME, SUPPLY_SEQ_I2S_MCLK_EN,
492 SND_SOC_NOPM, 0, 0,
493 mtk_mclk_en_event,
494 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
495 SND_SOC_DAPM_SUPPLY_S(I2S1_MCLK_EN_W_NAME, SUPPLY_SEQ_I2S_MCLK_EN,
496 SND_SOC_NOPM, 0, 0,
497 mtk_mclk_en_event,
498 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
499 SND_SOC_DAPM_SUPPLY_S(I2S2_MCLK_EN_W_NAME, SUPPLY_SEQ_I2S_MCLK_EN,
500 SND_SOC_NOPM, 0, 0,
501 mtk_mclk_en_event,
502 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
503 SND_SOC_DAPM_SUPPLY_S(I2S3_MCLK_EN_W_NAME, SUPPLY_SEQ_I2S_MCLK_EN,
504 SND_SOC_NOPM, 0, 0,
505 mtk_mclk_en_event,
506 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
507
508 /* apll */
509 SND_SOC_DAPM_SUPPLY_S(APLL1_W_NAME, SUPPLY_SEQ_APLL,
510 SND_SOC_NOPM, 0, 0,
511 mtk_apll_event,
512 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
513 SND_SOC_DAPM_SUPPLY_S(APLL2_W_NAME, SUPPLY_SEQ_APLL,
514 SND_SOC_NOPM, 0, 0,
515 mtk_apll_event,
516 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
517
518 /* allow i2s on without codec on */
519 SND_SOC_DAPM_OUTPUT("I2S_DUMMY_OUT"),
520 SND_SOC_DAPM_MUX("I2S1_Out_Mux",
521 SND_SOC_NOPM, 0, 0, &i2s1_out_mux_control),
522 SND_SOC_DAPM_MUX("I2S3_Out_Mux",
523 SND_SOC_NOPM, 0, 0, &i2s3_out_mux_control),
524 SND_SOC_DAPM_INPUT("I2S_DUMMY_IN"),
525 SND_SOC_DAPM_MUX("I2S0_In_Mux",
526 SND_SOC_NOPM, 0, 0, &i2s0_in_mux_control),
527 SND_SOC_DAPM_MUX("I2S2_In_Mux",
528 SND_SOC_NOPM, 0, 0, &i2s2_in_mux_control),
529
530 /* i2s in lpbk */
531 SND_SOC_DAPM_MUX("I2S0_Lpbk_Mux",
532 SND_SOC_NOPM, 0, 0, &i2s0_lpbk_mux_control),
533 SND_SOC_DAPM_MUX("I2S2_Lpbk_Mux",
534 SND_SOC_NOPM, 0, 0, &i2s2_lpbk_mux_control),
535 };
536
mtk_afe_i2s_share_connect(struct snd_soc_dapm_widget * source,struct snd_soc_dapm_widget * sink)537 static int mtk_afe_i2s_share_connect(struct snd_soc_dapm_widget *source,
538 struct snd_soc_dapm_widget *sink)
539 {
540 struct snd_soc_dapm_widget *w = sink;
541 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
542 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
543 struct mtk_afe_i2s_priv *i2s_priv;
544
545 i2s_priv = get_i2s_priv_by_name(afe, sink->name);
546 if (i2s_priv->share_i2s_id < 0)
547 return 0;
548
549 return i2s_priv->share_i2s_id == get_i2s_id_by_name(afe, source->name);
550 }
551
mtk_afe_i2s_hd_connect(struct snd_soc_dapm_widget * source,struct snd_soc_dapm_widget * sink)552 static int mtk_afe_i2s_hd_connect(struct snd_soc_dapm_widget *source,
553 struct snd_soc_dapm_widget *sink)
554 {
555 struct snd_soc_dapm_widget *w = sink;
556 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
557 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
558 struct mtk_afe_i2s_priv *i2s_priv;
559
560 i2s_priv = get_i2s_priv_by_name(afe, sink->name);
561 if (get_i2s_id_by_name(afe, sink->name) ==
562 get_i2s_id_by_name(afe, source->name))
563 return i2s_priv->low_jitter_en;
564
565 /* check if share i2s need hd en */
566 if (i2s_priv->share_i2s_id < 0)
567 return 0;
568
569 if (i2s_priv->share_i2s_id == get_i2s_id_by_name(afe, source->name))
570 return i2s_priv->low_jitter_en;
571
572 return 0;
573 }
574
mtk_afe_i2s_apll_connect(struct snd_soc_dapm_widget * source,struct snd_soc_dapm_widget * sink)575 static int mtk_afe_i2s_apll_connect(struct snd_soc_dapm_widget *source,
576 struct snd_soc_dapm_widget *sink)
577 {
578 struct snd_soc_dapm_widget *w = sink;
579 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
580 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
581 struct mtk_afe_i2s_priv *i2s_priv;
582 int cur_apll;
583 int i2s_need_apll;
584
585 i2s_priv = get_i2s_priv_by_name(afe, w->name);
586 /* which apll */
587 cur_apll = mt8186_get_apll_by_name(afe, source->name);
588 /* choose APLL from i2s rate */
589 i2s_need_apll = mt8186_get_apll_by_rate(afe, i2s_priv->rate);
590
591 return (i2s_need_apll == cur_apll) ? 1 : 0;
592 }
593
mtk_afe_i2s_mclk_connect(struct snd_soc_dapm_widget * source,struct snd_soc_dapm_widget * sink)594 static int mtk_afe_i2s_mclk_connect(struct snd_soc_dapm_widget *source,
595 struct snd_soc_dapm_widget *sink)
596 {
597 struct snd_soc_dapm_widget *w = sink;
598 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
599 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
600 struct mtk_afe_i2s_priv *i2s_priv;
601
602 i2s_priv = get_i2s_priv_by_name(afe, sink->name);
603 if (get_i2s_id_by_name(afe, sink->name) ==
604 get_i2s_id_by_name(afe, source->name))
605 return (i2s_priv->mclk_rate > 0) ? 1 : 0;
606
607 /* check if share i2s need mclk */
608 if (i2s_priv->share_i2s_id < 0)
609 return 0;
610
611 if (i2s_priv->share_i2s_id == get_i2s_id_by_name(afe, source->name))
612 return (i2s_priv->mclk_rate > 0) ? 1 : 0;
613
614 return 0;
615 }
616
mtk_afe_mclk_apll_connect(struct snd_soc_dapm_widget * source,struct snd_soc_dapm_widget * sink)617 static int mtk_afe_mclk_apll_connect(struct snd_soc_dapm_widget *source,
618 struct snd_soc_dapm_widget *sink)
619 {
620 struct snd_soc_dapm_widget *w = sink;
621 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
622 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
623 struct mtk_afe_i2s_priv *i2s_priv;
624 int cur_apll;
625
626 i2s_priv = get_i2s_priv_by_name(afe, w->name);
627 /* which apll */
628 cur_apll = mt8186_get_apll_by_name(afe, source->name);
629
630 return (i2s_priv->mclk_apll == cur_apll) ? 1 : 0;
631 }
632
633 static const struct snd_soc_dapm_route mtk_dai_i2s_routes[] = {
634 {"Connsys I2S", NULL, "CONNSYS"},
635
636 /* i2s0 */
637 {"I2S0", NULL, "I2S0_EN"},
638 {"I2S0", NULL, "I2S1_EN", mtk_afe_i2s_share_connect},
639 {"I2S0", NULL, "I2S2_EN", mtk_afe_i2s_share_connect},
640 {"I2S0", NULL, "I2S3_EN", mtk_afe_i2s_share_connect},
641
642 {"I2S0", NULL, I2S0_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
643 {"I2S0", NULL, I2S1_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
644 {"I2S0", NULL, I2S2_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
645 {"I2S0", NULL, I2S3_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
646 {I2S0_HD_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_i2s_apll_connect},
647 {I2S0_HD_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_i2s_apll_connect},
648
649 {"I2S0", NULL, I2S0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
650 {"I2S0", NULL, I2S1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
651 {"I2S0", NULL, I2S2_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
652 {"I2S0", NULL, I2S3_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
653 {I2S0_MCLK_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect},
654 {I2S0_MCLK_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect},
655
656 /* i2s1 */
657 {"I2S1_CH1", "DL1_CH1 Switch", "DL1"},
658 {"I2S1_CH2", "DL1_CH2 Switch", "DL1"},
659
660 {"I2S1_CH1", "DL1_CH1 Switch", "DSP_DL1_VIRT"},
661 {"I2S1_CH2", "DL1_CH2 Switch", "DSP_DL1_VIRT"},
662
663 {"I2S1_CH1", "DL2_CH1 Switch", "DL2"},
664 {"I2S1_CH2", "DL2_CH2 Switch", "DL2"},
665
666 {"I2S1_CH1", "DL2_CH1 Switch", "DSP_DL2_VIRT"},
667 {"I2S1_CH2", "DL2_CH2 Switch", "DSP_DL2_VIRT"},
668
669 {"I2S1_CH1", "DL3_CH1 Switch", "DL3"},
670 {"I2S1_CH2", "DL3_CH2 Switch", "DL3"},
671
672 {"I2S1_CH1", "DL12_CH1 Switch", "DL12"},
673 {"I2S1_CH2", "DL12_CH2 Switch", "DL12"},
674
675 {"I2S1_CH1", "DL12_CH3 Switch", "DL12"},
676 {"I2S1_CH2", "DL12_CH4 Switch", "DL12"},
677
678 {"I2S1_CH1", "DL6_CH1 Switch", "DL6"},
679 {"I2S1_CH2", "DL6_CH2 Switch", "DL6"},
680
681 {"I2S1_CH1", "DL4_CH1 Switch", "DL4"},
682 {"I2S1_CH2", "DL4_CH2 Switch", "DL4"},
683
684 {"I2S1_CH1", "DL5_CH1 Switch", "DL5"},
685 {"I2S1_CH2", "DL5_CH2 Switch", "DL5"},
686
687 {"I2S1_CH1", "DL8_CH1 Switch", "DL8"},
688 {"I2S1_CH2", "DL8_CH2 Switch", "DL8"},
689
690 {"I2S1", NULL, "I2S1_CH1"},
691 {"I2S1", NULL, "I2S1_CH2"},
692
693 {"I2S1", NULL, "I2S0_EN", mtk_afe_i2s_share_connect},
694 {"I2S1", NULL, "I2S1_EN"},
695 {"I2S1", NULL, "I2S2_EN", mtk_afe_i2s_share_connect},
696 {"I2S1", NULL, "I2S3_EN", mtk_afe_i2s_share_connect},
697
698 {"I2S1", NULL, I2S0_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
699 {"I2S1", NULL, I2S1_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
700 {"I2S1", NULL, I2S2_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
701 {"I2S1", NULL, I2S3_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
702 {I2S1_HD_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_i2s_apll_connect},
703 {I2S1_HD_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_i2s_apll_connect},
704
705 {"I2S1", NULL, I2S0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
706 {"I2S1", NULL, I2S1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
707 {"I2S1", NULL, I2S2_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
708 {"I2S1", NULL, I2S3_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
709 {I2S1_MCLK_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect},
710 {I2S1_MCLK_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect},
711
712 /* i2s2 */
713 {"I2S2", NULL, "I2S0_EN", mtk_afe_i2s_share_connect},
714 {"I2S2", NULL, "I2S1_EN", mtk_afe_i2s_share_connect},
715 {"I2S2", NULL, "I2S2_EN"},
716 {"I2S2", NULL, "I2S3_EN", mtk_afe_i2s_share_connect},
717
718 {"I2S2", NULL, I2S0_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
719 {"I2S2", NULL, I2S1_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
720 {"I2S2", NULL, I2S2_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
721 {"I2S2", NULL, I2S3_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
722 {I2S2_HD_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_i2s_apll_connect},
723 {I2S2_HD_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_i2s_apll_connect},
724
725 {"I2S2", NULL, I2S0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
726 {"I2S2", NULL, I2S1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
727 {"I2S2", NULL, I2S2_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
728 {"I2S2", NULL, I2S3_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
729 {I2S2_MCLK_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect},
730 {I2S2_MCLK_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect},
731
732 /* i2s3 */
733 {"I2S3_CH1", "DL1_CH1 Switch", "DL1"},
734 {"I2S3_CH2", "DL1_CH2 Switch", "DL1"},
735
736 {"I2S3_CH1", "DL1_CH1 Switch", "DSP_DL1_VIRT"},
737 {"I2S3_CH2", "DL1_CH2 Switch", "DSP_DL1_VIRT"},
738
739 {"I2S3_CH1", "DL2_CH1 Switch", "DL2"},
740 {"I2S3_CH2", "DL2_CH2 Switch", "DL2"},
741
742 {"I2S3_CH1", "DL2_CH1 Switch", "DSP_DL2_VIRT"},
743 {"I2S3_CH2", "DL2_CH2 Switch", "DSP_DL2_VIRT"},
744
745 {"I2S3_CH1", "DL3_CH1 Switch", "DL3"},
746 {"I2S3_CH2", "DL3_CH2 Switch", "DL3"},
747
748 {"I2S3_CH1", "DL12_CH1 Switch", "DL12"},
749 {"I2S3_CH2", "DL12_CH2 Switch", "DL12"},
750
751 {"I2S3_CH1", "DL12_CH3 Switch", "DL12"},
752 {"I2S3_CH2", "DL12_CH4 Switch", "DL12"},
753
754 {"I2S3_CH1", "DL6_CH1 Switch", "DL6"},
755 {"I2S3_CH2", "DL6_CH2 Switch", "DL6"},
756
757 {"I2S3_CH1", "DL4_CH1 Switch", "DL4"},
758 {"I2S3_CH2", "DL4_CH2 Switch", "DL4"},
759
760 {"I2S3_CH1", "DL5_CH1 Switch", "DL5"},
761 {"I2S3_CH2", "DL5_CH2 Switch", "DL5"},
762
763 {"I2S3_CH1", "DL8_CH1 Switch", "DL8"},
764 {"I2S3_CH2", "DL8_CH2 Switch", "DL8"},
765
766 {"I2S3", NULL, "I2S3_CH1"},
767 {"I2S3", NULL, "I2S3_CH2"},
768
769 {"I2S3", NULL, "I2S0_EN", mtk_afe_i2s_share_connect},
770 {"I2S3", NULL, "I2S1_EN", mtk_afe_i2s_share_connect},
771 {"I2S3", NULL, "I2S2_EN", mtk_afe_i2s_share_connect},
772 {"I2S3", NULL, "I2S3_EN"},
773
774 {"I2S3", NULL, I2S0_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
775 {"I2S3", NULL, I2S1_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
776 {"I2S3", NULL, I2S2_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
777 {"I2S3", NULL, I2S3_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
778 {I2S3_HD_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_i2s_apll_connect},
779 {I2S3_HD_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_i2s_apll_connect},
780
781 {"I2S3", NULL, I2S0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
782 {"I2S3", NULL, I2S1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
783 {"I2S3", NULL, I2S2_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
784 {"I2S3", NULL, I2S3_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
785 {I2S3_MCLK_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect},
786 {I2S3_MCLK_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect},
787
788 /* allow i2s on without codec on */
789 {"I2S0", NULL, "I2S0_In_Mux"},
790 {"I2S0_In_Mux", "Dummy_Widget", "I2S_DUMMY_IN"},
791
792 {"I2S1_Out_Mux", "Dummy_Widget", "I2S1"},
793 {"I2S_DUMMY_OUT", NULL, "I2S1_Out_Mux"},
794
795 {"I2S2", NULL, "I2S2_In_Mux"},
796 {"I2S2_In_Mux", "Dummy_Widget", "I2S_DUMMY_IN"},
797
798 {"I2S3_Out_Mux", "Dummy_Widget", "I2S3"},
799 {"I2S_DUMMY_OUT", NULL, "I2S3_Out_Mux"},
800
801 /* i2s in lpbk */
802 {"I2S0_Lpbk_Mux", "Lpbk", "I2S3"},
803 {"I2S2_Lpbk_Mux", "Lpbk", "I2S1"},
804 {"I2S0", NULL, "I2S0_Lpbk_Mux"},
805 {"I2S2", NULL, "I2S2_Lpbk_Mux"},
806 };
807
808 /* dai ops */
mtk_dai_connsys_i2s_hw_params(struct snd_pcm_substream * substream,struct snd_pcm_hw_params * params,struct snd_soc_dai * dai)809 static int mtk_dai_connsys_i2s_hw_params(struct snd_pcm_substream *substream,
810 struct snd_pcm_hw_params *params,
811 struct snd_soc_dai *dai)
812 {
813 struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
814 unsigned int rate = params_rate(params);
815 unsigned int rate_reg = mt8186_rate_transform(afe->dev,
816 rate, dai->id);
817 unsigned int i2s_con = 0;
818
819 dev_dbg(afe->dev, "%s(), id %d, stream %d, rate %d\n",
820 __func__, dai->id, substream->stream, rate);
821
822 /* non-inverse, i2s mode, slave, 16bits, from connsys */
823 i2s_con |= 0 << INV_PAD_CTRL_SFT;
824 i2s_con |= I2S_FMT_I2S << I2S_FMT_SFT;
825 i2s_con |= 1 << I2S_SRC_SFT;
826 i2s_con |= get_i2s_wlen(SNDRV_PCM_FORMAT_S16_LE) << I2S_WLEN_SFT;
827 i2s_con |= 0 << I2SIN_PAD_SEL_SFT;
828 regmap_write(afe->regmap, AFE_CONNSYS_I2S_CON, i2s_con);
829
830 /* use asrc */
831 regmap_update_bits(afe->regmap, AFE_CONNSYS_I2S_CON,
832 I2S_BYPSRC_MASK_SFT, 0);
833
834 /* slave mode, set i2s for asrc */
835 regmap_update_bits(afe->regmap, AFE_CONNSYS_I2S_CON,
836 I2S_MODE_MASK_SFT, rate_reg << I2S_MODE_SFT);
837
838 if (rate == 44100)
839 regmap_write(afe->regmap, AFE_ASRC_2CH_CON3, 0x1b9000);
840 else if (rate == 32000)
841 regmap_write(afe->regmap, AFE_ASRC_2CH_CON3, 0x140000);
842 else
843 regmap_write(afe->regmap, AFE_ASRC_2CH_CON3, 0x1e0000);
844
845 /* Calibration setting */
846 regmap_write(afe->regmap, AFE_ASRC_2CH_CON4, 0x140000);
847 regmap_write(afe->regmap, AFE_ASRC_2CH_CON9, 0x36000);
848 regmap_write(afe->regmap, AFE_ASRC_2CH_CON10, 0x2fc00);
849 regmap_write(afe->regmap, AFE_ASRC_2CH_CON6, 0x7ef4);
850 regmap_write(afe->regmap, AFE_ASRC_2CH_CON5, 0xff5986);
851
852 /* 0:Stereo 1:Mono */
853 regmap_update_bits(afe->regmap, AFE_ASRC_2CH_CON2,
854 CHSET_IS_MONO_MASK_SFT, 0);
855
856 return 0;
857 }
858
mtk_dai_connsys_i2s_trigger(struct snd_pcm_substream * substream,int cmd,struct snd_soc_dai * dai)859 static int mtk_dai_connsys_i2s_trigger(struct snd_pcm_substream *substream,
860 int cmd, struct snd_soc_dai *dai)
861 {
862 struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
863 struct mt8186_afe_private *afe_priv = afe->platform_priv;
864
865 dev_dbg(afe->dev, "%s(), cmd %d, stream %d\n",
866 __func__, cmd, substream->stream);
867
868 switch (cmd) {
869 case SNDRV_PCM_TRIGGER_START:
870 case SNDRV_PCM_TRIGGER_RESUME:
871 /* i2s enable */
872 regmap_update_bits(afe->regmap,
873 AFE_CONNSYS_I2S_CON,
874 I2S_EN_MASK_SFT,
875 BIT(I2S_EN_SFT));
876
877 /* calibrator enable */
878 regmap_update_bits(afe->regmap,
879 AFE_ASRC_2CH_CON5,
880 CALI_EN_MASK_SFT,
881 BIT(CALI_EN_SFT));
882
883 /* asrc enable */
884 regmap_update_bits(afe->regmap,
885 AFE_ASRC_2CH_CON0,
886 CON0_CHSET_STR_CLR_MASK_SFT,
887 BIT(CON0_CHSET_STR_CLR_SFT));
888 regmap_update_bits(afe->regmap,
889 AFE_ASRC_2CH_CON0,
890 CON0_ASM_ON_MASK_SFT,
891 BIT(CON0_ASM_ON_SFT));
892
893 afe_priv->dai_on[dai->id] = true;
894 return 0;
895 case SNDRV_PCM_TRIGGER_STOP:
896 case SNDRV_PCM_TRIGGER_SUSPEND:
897 regmap_update_bits(afe->regmap, AFE_ASRC_2CH_CON0,
898 CON0_ASM_ON_MASK_SFT, 0);
899 regmap_update_bits(afe->regmap, AFE_ASRC_2CH_CON5,
900 CALI_EN_MASK_SFT, 0);
901
902 /* i2s disable */
903 regmap_update_bits(afe->regmap, AFE_CONNSYS_I2S_CON,
904 I2S_EN_MASK_SFT, 0);
905
906 /* bypass asrc */
907 regmap_update_bits(afe->regmap, AFE_CONNSYS_I2S_CON,
908 I2S_BYPSRC_MASK_SFT, BIT(I2S_BYPSRC_SFT));
909
910 afe_priv->dai_on[dai->id] = false;
911 return 0;
912 default:
913 return -EINVAL;
914 }
915 return 0;
916 }
917
918 static const struct snd_soc_dai_ops mtk_dai_connsys_i2s_ops = {
919 .hw_params = mtk_dai_connsys_i2s_hw_params,
920 .trigger = mtk_dai_connsys_i2s_trigger,
921 };
922
923 /* i2s */
mtk_dai_i2s_config(struct mtk_base_afe * afe,struct snd_pcm_hw_params * params,int i2s_id)924 static int mtk_dai_i2s_config(struct mtk_base_afe *afe,
925 struct snd_pcm_hw_params *params,
926 int i2s_id)
927 {
928 struct mt8186_afe_private *afe_priv = afe->platform_priv;
929 struct mtk_afe_i2s_priv *i2s_priv = afe_priv->dai_priv[i2s_id];
930
931 unsigned int rate = params_rate(params);
932 unsigned int rate_reg = mt8186_rate_transform(afe->dev,
933 rate, i2s_id);
934 snd_pcm_format_t format = params_format(params);
935 unsigned int i2s_con = 0;
936 int ret;
937
938 dev_dbg(afe->dev, "%s(), id %d, rate %d, format %d\n",
939 __func__, i2s_id, rate, format);
940
941 i2s_priv->rate = rate;
942
943 switch (i2s_id) {
944 case MT8186_DAI_I2S_0:
945 i2s_con = I2S_IN_PAD_IO_MUX << I2SIN_PAD_SEL_SFT;
946 i2s_con |= rate_reg << I2S_OUT_MODE_SFT;
947 i2s_con |= I2S_FMT_I2S << I2S_FMT_SFT;
948 i2s_con |= get_i2s_wlen(format) << I2S_WLEN_SFT;
949 regmap_update_bits(afe->regmap, AFE_I2S_CON,
950 0xffffeffa, i2s_con);
951 break;
952 case MT8186_DAI_I2S_1:
953 i2s_con = I2S1_SEL_O28_O29 << I2S2_SEL_O03_O04_SFT;
954 i2s_con |= rate_reg << I2S2_OUT_MODE_SFT;
955 i2s_con |= I2S_FMT_I2S << I2S2_FMT_SFT;
956 i2s_con |= get_i2s_wlen(format) << I2S2_WLEN_SFT;
957 regmap_update_bits(afe->regmap, AFE_I2S_CON1,
958 0xffffeffa, i2s_con);
959 break;
960 case MT8186_DAI_I2S_2:
961 i2s_con = 8 << I2S3_UPDATE_WORD_SFT;
962 i2s_con |= rate_reg << I2S3_OUT_MODE_SFT;
963 i2s_con |= I2S_FMT_I2S << I2S3_FMT_SFT;
964 i2s_con |= get_i2s_wlen(format) << I2S3_WLEN_SFT;
965 regmap_update_bits(afe->regmap, AFE_I2S_CON2,
966 0xffffeffa, i2s_con);
967 break;
968 case MT8186_DAI_I2S_3:
969 i2s_con = rate_reg << I2S4_OUT_MODE_SFT;
970 i2s_con |= I2S_FMT_I2S << I2S4_FMT_SFT;
971 i2s_con |= get_i2s_wlen(format) << I2S4_WLEN_SFT;
972 regmap_update_bits(afe->regmap, AFE_I2S_CON3,
973 0xffffeffa, i2s_con);
974 break;
975 default:
976 dev_err(afe->dev, "%s(), id %d not support\n",
977 __func__, i2s_id);
978 return -EINVAL;
979 }
980
981 /* set share i2s */
982 if (i2s_priv->share_i2s_id >= 0) {
983 ret = mtk_dai_i2s_config(afe, params, i2s_priv->share_i2s_id);
984 if (ret)
985 return ret;
986 }
987
988 return 0;
989 }
990
mtk_dai_i2s_hw_params(struct snd_pcm_substream * substream,struct snd_pcm_hw_params * params,struct snd_soc_dai * dai)991 static int mtk_dai_i2s_hw_params(struct snd_pcm_substream *substream,
992 struct snd_pcm_hw_params *params,
993 struct snd_soc_dai *dai)
994 {
995 struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
996
997 return mtk_dai_i2s_config(afe, params, dai->id);
998 }
999
mtk_dai_i2s_set_sysclk(struct snd_soc_dai * dai,int clk_id,unsigned int freq,int dir)1000 static int mtk_dai_i2s_set_sysclk(struct snd_soc_dai *dai,
1001 int clk_id, unsigned int freq, int dir)
1002 {
1003 struct mtk_base_afe *afe = dev_get_drvdata(dai->dev);
1004 struct mt8186_afe_private *afe_priv = afe->platform_priv;
1005 struct mtk_afe_i2s_priv *i2s_priv = afe_priv->dai_priv[dai->id];
1006 int apll;
1007 int apll_rate;
1008
1009 if (dir != SND_SOC_CLOCK_OUT) {
1010 dev_err(afe->dev, "%s(), dir != SND_SOC_CLOCK_OUT", __func__);
1011 return -EINVAL;
1012 }
1013
1014 dev_dbg(afe->dev, "%s(), freq %d\n", __func__, freq);
1015
1016 apll = mt8186_get_apll_by_rate(afe, freq);
1017 apll_rate = mt8186_get_apll_rate(afe, apll);
1018
1019 if (freq > apll_rate) {
1020 dev_err(afe->dev, "%s(), freq > apll rate", __func__);
1021 return -EINVAL;
1022 }
1023
1024 if (apll_rate % freq != 0) {
1025 dev_err(afe->dev, "%s(), APLL cannot generate freq Hz", __func__);
1026 return -EINVAL;
1027 }
1028
1029 i2s_priv->mclk_rate = freq;
1030 i2s_priv->mclk_apll = apll;
1031
1032 if (i2s_priv->share_i2s_id > 0) {
1033 struct mtk_afe_i2s_priv *share_i2s_priv;
1034
1035 share_i2s_priv = afe_priv->dai_priv[i2s_priv->share_i2s_id];
1036 if (!share_i2s_priv) {
1037 dev_err(afe->dev, "%s(), share_i2s_priv == NULL", __func__);
1038 return -EINVAL;
1039 }
1040
1041 share_i2s_priv->mclk_rate = i2s_priv->mclk_rate;
1042 share_i2s_priv->mclk_apll = i2s_priv->mclk_apll;
1043 }
1044
1045 return 0;
1046 }
1047
1048 static const struct snd_soc_dai_ops mtk_dai_i2s_ops = {
1049 .hw_params = mtk_dai_i2s_hw_params,
1050 .set_sysclk = mtk_dai_i2s_set_sysclk,
1051 };
1052
1053 /* dai driver */
1054 #define MTK_CONNSYS_I2S_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000)
1055
1056 #define MTK_I2S_RATES (SNDRV_PCM_RATE_8000_48000 |\
1057 SNDRV_PCM_RATE_88200 |\
1058 SNDRV_PCM_RATE_96000 |\
1059 SNDRV_PCM_RATE_176400 |\
1060 SNDRV_PCM_RATE_192000)
1061
1062 #define MTK_I2S_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
1063 SNDRV_PCM_FMTBIT_S24_LE |\
1064 SNDRV_PCM_FMTBIT_S32_LE)
1065
1066 static struct snd_soc_dai_driver mtk_dai_i2s_driver[] = {
1067 {
1068 .name = "CONNSYS_I2S",
1069 .id = MT8186_DAI_CONNSYS_I2S,
1070 .capture = {
1071 .stream_name = "Connsys I2S",
1072 .channels_min = 1,
1073 .channels_max = 2,
1074 .rates = MTK_CONNSYS_I2S_RATES,
1075 .formats = MTK_I2S_FORMATS,
1076 },
1077 .ops = &mtk_dai_connsys_i2s_ops,
1078 },
1079 {
1080 .name = "I2S0",
1081 .id = MT8186_DAI_I2S_0,
1082 .capture = {
1083 .stream_name = "I2S0",
1084 .channels_min = 1,
1085 .channels_max = 2,
1086 .rates = MTK_I2S_RATES,
1087 .formats = MTK_I2S_FORMATS,
1088 },
1089 .ops = &mtk_dai_i2s_ops,
1090 },
1091 {
1092 .name = "I2S1",
1093 .id = MT8186_DAI_I2S_1,
1094 .playback = {
1095 .stream_name = "I2S1",
1096 .channels_min = 1,
1097 .channels_max = 2,
1098 .rates = MTK_I2S_RATES,
1099 .formats = MTK_I2S_FORMATS,
1100 },
1101 .ops = &mtk_dai_i2s_ops,
1102 },
1103 {
1104 .name = "I2S2",
1105 .id = MT8186_DAI_I2S_2,
1106 .capture = {
1107 .stream_name = "I2S2",
1108 .channels_min = 1,
1109 .channels_max = 2,
1110 .rates = MTK_I2S_RATES,
1111 .formats = MTK_I2S_FORMATS,
1112 },
1113 .ops = &mtk_dai_i2s_ops,
1114 },
1115 {
1116 .name = "I2S3",
1117 .id = MT8186_DAI_I2S_3,
1118 .playback = {
1119 .stream_name = "I2S3",
1120 .channels_min = 1,
1121 .channels_max = 2,
1122 .rates = MTK_I2S_RATES,
1123 .formats = MTK_I2S_FORMATS,
1124 },
1125 .ops = &mtk_dai_i2s_ops,
1126 }
1127 };
1128
1129 /* this enum is merely for mtk_afe_i2s_priv declare */
1130 enum {
1131 DAI_I2S0 = 0,
1132 DAI_I2S1,
1133 DAI_I2S2,
1134 DAI_I2S3,
1135 DAI_I2S_NUM,
1136 };
1137
1138 static const struct mtk_afe_i2s_priv mt8186_i2s_priv[DAI_I2S_NUM] = {
1139 [DAI_I2S0] = {
1140 .id = MT8186_DAI_I2S_0,
1141 .mclk_id = MT8186_I2S0_MCK,
1142 .share_i2s_id = -1,
1143 },
1144 [DAI_I2S1] = {
1145 .id = MT8186_DAI_I2S_1,
1146 .mclk_id = MT8186_I2S1_MCK,
1147 .share_i2s_id = -1,
1148 },
1149 [DAI_I2S2] = {
1150 .id = MT8186_DAI_I2S_2,
1151 .mclk_id = MT8186_I2S2_MCK,
1152 .share_i2s_id = -1,
1153 },
1154 [DAI_I2S3] = {
1155 .id = MT8186_DAI_I2S_3,
1156 /* clock gate naming is hf_faud_i2s4_m_ck*/
1157 .mclk_id = MT8186_I2S4_MCK,
1158 .share_i2s_id = -1,
1159 }
1160 };
1161
1162 /**
1163 * mt8186_dai_i2s_set_share() - Set up I2S ports to share a single clock.
1164 * @afe: Pointer to &struct mtk_base_afe
1165 * @main_i2s_name: The name of the I2S port that will provide the clock
1166 * @secondary_i2s_name: The name of the I2S port that will use this clock
1167 */
mt8186_dai_i2s_set_share(struct mtk_base_afe * afe,const char * main_i2s_name,const char * secondary_i2s_name)1168 int mt8186_dai_i2s_set_share(struct mtk_base_afe *afe, const char *main_i2s_name,
1169 const char *secondary_i2s_name)
1170 {
1171 struct mtk_afe_i2s_priv *secondary_i2s_priv;
1172 int main_i2s_id;
1173
1174 secondary_i2s_priv = get_i2s_priv_by_name(afe, secondary_i2s_name);
1175 if (!secondary_i2s_priv)
1176 return -EINVAL;
1177
1178 main_i2s_id = get_i2s_id_by_name(afe, main_i2s_name);
1179 if (main_i2s_id < 0)
1180 return main_i2s_id;
1181
1182 secondary_i2s_priv->share_i2s_id = main_i2s_id;
1183
1184 return 0;
1185 }
1186 EXPORT_SYMBOL_GPL(mt8186_dai_i2s_set_share);
1187
mt8186_dai_i2s_set_priv(struct mtk_base_afe * afe)1188 static int mt8186_dai_i2s_set_priv(struct mtk_base_afe *afe)
1189 {
1190 int i;
1191 int ret;
1192
1193 for (i = 0; i < DAI_I2S_NUM; i++) {
1194 ret = mt8186_dai_set_priv(afe, mt8186_i2s_priv[i].id,
1195 sizeof(struct mtk_afe_i2s_priv),
1196 &mt8186_i2s_priv[i]);
1197 if (ret)
1198 return ret;
1199 }
1200
1201 return 0;
1202 }
1203
mt8186_dai_i2s_register(struct mtk_base_afe * afe)1204 int mt8186_dai_i2s_register(struct mtk_base_afe *afe)
1205 {
1206 struct mtk_base_afe_dai *dai;
1207 int ret;
1208
1209 dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL);
1210 if (!dai)
1211 return -ENOMEM;
1212
1213 list_add(&dai->list, &afe->sub_dais);
1214
1215 dai->dai_drivers = mtk_dai_i2s_driver;
1216 dai->num_dai_drivers = ARRAY_SIZE(mtk_dai_i2s_driver);
1217
1218 dai->controls = mtk_dai_i2s_controls;
1219 dai->num_controls = ARRAY_SIZE(mtk_dai_i2s_controls);
1220 dai->dapm_widgets = mtk_dai_i2s_widgets;
1221 dai->num_dapm_widgets = ARRAY_SIZE(mtk_dai_i2s_widgets);
1222 dai->dapm_routes = mtk_dai_i2s_routes;
1223 dai->num_dapm_routes = ARRAY_SIZE(mtk_dai_i2s_routes);
1224
1225 /* set all dai i2s private data */
1226 ret = mt8186_dai_i2s_set_priv(afe);
1227 if (ret)
1228 return ret;
1229
1230 return 0;
1231 }
1232