1 // SPDX-License-Identifier: GPL-2.0
2 //
3 // MediaTek ALSA SoC Audio DAI I2S Control
4 //
5 // Copyright (c) 2018 MediaTek Inc.
6 // Author: KaiChieh Chuang <kaichieh.chuang@mediatek.com>
7
8 #include <linux/bitops.h>
9 #include <linux/regmap.h>
10 #include <sound/pcm_params.h>
11 #include "mt8183-afe-clk.h"
12 #include "mt8183-afe-common.h"
13 #include "mt8183-interconnection.h"
14 #include "mt8183-reg.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
46 int share_i2s_id;
47
48 int mclk_id;
49 int mclk_rate;
50 int mclk_apll;
51
52 int use_eiaj;
53 };
54
get_i2s_wlen(snd_pcm_format_t format)55 static unsigned int get_i2s_wlen(snd_pcm_format_t format)
56 {
57 return snd_pcm_format_physical_width(format) <= 16 ?
58 I2S_WLEN_16_BIT : I2S_WLEN_32_BIT;
59 }
60
61 #define MTK_AFE_I2S0_KCONTROL_NAME "I2S0_HD_Mux"
62 #define MTK_AFE_I2S1_KCONTROL_NAME "I2S1_HD_Mux"
63 #define MTK_AFE_I2S2_KCONTROL_NAME "I2S2_HD_Mux"
64 #define MTK_AFE_I2S3_KCONTROL_NAME "I2S3_HD_Mux"
65 #define MTK_AFE_I2S5_KCONTROL_NAME "I2S5_HD_Mux"
66
67 #define I2S0_HD_EN_W_NAME "I2S0_HD_EN"
68 #define I2S1_HD_EN_W_NAME "I2S1_HD_EN"
69 #define I2S2_HD_EN_W_NAME "I2S2_HD_EN"
70 #define I2S3_HD_EN_W_NAME "I2S3_HD_EN"
71 #define I2S5_HD_EN_W_NAME "I2S5_HD_EN"
72
73 #define I2S0_MCLK_EN_W_NAME "I2S0_MCLK_EN"
74 #define I2S1_MCLK_EN_W_NAME "I2S1_MCLK_EN"
75 #define I2S2_MCLK_EN_W_NAME "I2S2_MCLK_EN"
76 #define I2S3_MCLK_EN_W_NAME "I2S3_MCLK_EN"
77 #define I2S5_MCLK_EN_W_NAME "I2S5_MCLK_EN"
78
get_i2s_id_by_name(struct mtk_base_afe * afe,const char * name)79 static int get_i2s_id_by_name(struct mtk_base_afe *afe,
80 const char *name)
81 {
82 if (strncmp(name, "I2S0", 4) == 0)
83 return MT8183_DAI_I2S_0;
84 else if (strncmp(name, "I2S1", 4) == 0)
85 return MT8183_DAI_I2S_1;
86 else if (strncmp(name, "I2S2", 4) == 0)
87 return MT8183_DAI_I2S_2;
88 else if (strncmp(name, "I2S3", 4) == 0)
89 return MT8183_DAI_I2S_3;
90 else if (strncmp(name, "I2S5", 4) == 0)
91 return MT8183_DAI_I2S_5;
92 else
93 return -EINVAL;
94 }
95
get_i2s_priv_by_name(struct mtk_base_afe * afe,const char * name)96 static struct mtk_afe_i2s_priv *get_i2s_priv_by_name(struct mtk_base_afe *afe,
97 const char *name)
98 {
99 struct mt8183_afe_private *afe_priv = afe->platform_priv;
100 int dai_id = get_i2s_id_by_name(afe, name);
101
102 if (dai_id < 0)
103 return NULL;
104
105 return afe_priv->dai_priv[dai_id];
106 }
107
108 /* low jitter control */
109 static const char * const mt8183_i2s_hd_str[] = {
110 "Normal", "Low_Jitter"
111 };
112
113 static const struct soc_enum mt8183_i2s_enum[] = {
114 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(mt8183_i2s_hd_str),
115 mt8183_i2s_hd_str),
116 };
117
mt8183_i2s_hd_get(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)118 static int mt8183_i2s_hd_get(struct snd_kcontrol *kcontrol,
119 struct snd_ctl_elem_value *ucontrol)
120 {
121 struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
122 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
123 struct mtk_afe_i2s_priv *i2s_priv;
124
125 i2s_priv = get_i2s_priv_by_name(afe, kcontrol->id.name);
126
127 if (!i2s_priv) {
128 dev_warn(afe->dev, "%s(), i2s_priv == NULL", __func__);
129 return -EINVAL;
130 }
131
132 ucontrol->value.integer.value[0] = i2s_priv->low_jitter_en;
133
134 return 0;
135 }
136
mt8183_i2s_hd_set(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)137 static int mt8183_i2s_hd_set(struct snd_kcontrol *kcontrol,
138 struct snd_ctl_elem_value *ucontrol)
139 {
140 struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
141 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
142 struct mtk_afe_i2s_priv *i2s_priv;
143 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
144 int hd_en;
145
146 if (ucontrol->value.enumerated.item[0] >= e->items)
147 return -EINVAL;
148
149 hd_en = ucontrol->value.integer.value[0];
150
151 dev_info(afe->dev, "%s(), kcontrol name %s, hd_en %d\n",
152 __func__, kcontrol->id.name, hd_en);
153
154 i2s_priv = get_i2s_priv_by_name(afe, kcontrol->id.name);
155
156 if (!i2s_priv) {
157 dev_warn(afe->dev, "%s(), i2s_priv == NULL", __func__);
158 return -EINVAL;
159 }
160
161 i2s_priv->low_jitter_en = hd_en;
162
163 return 0;
164 }
165
166 static const struct snd_kcontrol_new mtk_dai_i2s_controls[] = {
167 SOC_ENUM_EXT(MTK_AFE_I2S0_KCONTROL_NAME, mt8183_i2s_enum[0],
168 mt8183_i2s_hd_get, mt8183_i2s_hd_set),
169 SOC_ENUM_EXT(MTK_AFE_I2S1_KCONTROL_NAME, mt8183_i2s_enum[0],
170 mt8183_i2s_hd_get, mt8183_i2s_hd_set),
171 SOC_ENUM_EXT(MTK_AFE_I2S2_KCONTROL_NAME, mt8183_i2s_enum[0],
172 mt8183_i2s_hd_get, mt8183_i2s_hd_set),
173 SOC_ENUM_EXT(MTK_AFE_I2S3_KCONTROL_NAME, mt8183_i2s_enum[0],
174 mt8183_i2s_hd_get, mt8183_i2s_hd_set),
175 SOC_ENUM_EXT(MTK_AFE_I2S5_KCONTROL_NAME, mt8183_i2s_enum[0],
176 mt8183_i2s_hd_get, mt8183_i2s_hd_set),
177 };
178
179 /* dai component */
180 /* interconnection */
181 static const struct snd_kcontrol_new mtk_i2s3_ch1_mix[] = {
182 SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1", AFE_CONN0, I_DL1_CH1, 1, 0),
183 SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1", AFE_CONN0, I_DL2_CH1, 1, 0),
184 SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1", AFE_CONN0, I_DL3_CH1, 1, 0),
185 SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN0,
186 I_ADDA_UL_CH1, 1, 0),
187 SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH1", AFE_CONN0,
188 I_PCM_1_CAP_CH1, 1, 0),
189 SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH1", AFE_CONN0,
190 I_PCM_2_CAP_CH1, 1, 0),
191 };
192
193 static const struct snd_kcontrol_new mtk_i2s3_ch2_mix[] = {
194 SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH2", AFE_CONN1, I_DL1_CH2, 1, 0),
195 SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH2", AFE_CONN1, I_DL2_CH2, 1, 0),
196 SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH2", AFE_CONN1, I_DL3_CH2, 1, 0),
197 SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN1,
198 I_ADDA_UL_CH2, 1, 0),
199 SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH1", AFE_CONN1,
200 I_PCM_1_CAP_CH1, 1, 0),
201 SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH1", AFE_CONN1,
202 I_PCM_2_CAP_CH1, 1, 0),
203 SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH2", AFE_CONN1,
204 I_PCM_1_CAP_CH2, 1, 0),
205 SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH2", AFE_CONN1,
206 I_PCM_2_CAP_CH2, 1, 0),
207 };
208
209 static const struct snd_kcontrol_new mtk_i2s1_ch1_mix[] = {
210 SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1", AFE_CONN28, I_DL1_CH1, 1, 0),
211 SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1", AFE_CONN28, I_DL2_CH1, 1, 0),
212 SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1", AFE_CONN28, I_DL3_CH1, 1, 0),
213 SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN28,
214 I_ADDA_UL_CH1, 1, 0),
215 SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH1", AFE_CONN28,
216 I_PCM_1_CAP_CH1, 1, 0),
217 SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH1", AFE_CONN28,
218 I_PCM_2_CAP_CH1, 1, 0),
219 };
220
221 static const struct snd_kcontrol_new mtk_i2s1_ch2_mix[] = {
222 SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH2", AFE_CONN29, I_DL1_CH2, 1, 0),
223 SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH2", AFE_CONN29, I_DL2_CH2, 1, 0),
224 SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH2", AFE_CONN29, I_DL3_CH2, 1, 0),
225 SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN29,
226 I_ADDA_UL_CH2, 1, 0),
227 SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH1", AFE_CONN29,
228 I_PCM_1_CAP_CH1, 1, 0),
229 SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH1", AFE_CONN29,
230 I_PCM_2_CAP_CH1, 1, 0),
231 SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH2", AFE_CONN29,
232 I_PCM_1_CAP_CH2, 1, 0),
233 SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH2", AFE_CONN29,
234 I_PCM_2_CAP_CH2, 1, 0),
235 };
236
237 static const struct snd_kcontrol_new mtk_i2s5_ch1_mix[] = {
238 SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1", AFE_CONN30, I_DL1_CH1, 1, 0),
239 SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1", AFE_CONN30, I_DL2_CH1, 1, 0),
240 SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1", AFE_CONN30, I_DL3_CH1, 1, 0),
241 SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN30,
242 I_ADDA_UL_CH1, 1, 0),
243 SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH1", AFE_CONN30,
244 I_PCM_1_CAP_CH1, 1, 0),
245 SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH1", AFE_CONN30,
246 I_PCM_2_CAP_CH1, 1, 0),
247 };
248
249 static const struct snd_kcontrol_new mtk_i2s5_ch2_mix[] = {
250 SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH2", AFE_CONN31, I_DL1_CH2, 1, 0),
251 SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH2", AFE_CONN31, I_DL2_CH2, 1, 0),
252 SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH2", AFE_CONN31, I_DL3_CH2, 1, 0),
253 SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN31,
254 I_ADDA_UL_CH2, 1, 0),
255 SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH1", AFE_CONN31,
256 I_PCM_1_CAP_CH1, 1, 0),
257 SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH1", AFE_CONN31,
258 I_PCM_2_CAP_CH1, 1, 0),
259 SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH2", AFE_CONN31,
260 I_PCM_1_CAP_CH2, 1, 0),
261 SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH2", AFE_CONN31,
262 I_PCM_2_CAP_CH2, 1, 0),
263 };
264
265 enum {
266 SUPPLY_SEQ_APLL,
267 SUPPLY_SEQ_I2S_MCLK_EN,
268 SUPPLY_SEQ_I2S_HD_EN,
269 SUPPLY_SEQ_I2S_EN,
270 };
271
mtk_apll_event(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)272 static int mtk_apll_event(struct snd_soc_dapm_widget *w,
273 struct snd_kcontrol *kcontrol,
274 int event)
275 {
276 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
277 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
278
279 dev_info(cmpnt->dev, "%s(), name %s, event 0x%x\n",
280 __func__, w->name, event);
281
282 switch (event) {
283 case SND_SOC_DAPM_PRE_PMU:
284 if (strcmp(w->name, APLL1_W_NAME) == 0)
285 mt8183_apll1_enable(afe);
286 else
287 mt8183_apll2_enable(afe);
288 break;
289 case SND_SOC_DAPM_POST_PMD:
290 if (strcmp(w->name, APLL1_W_NAME) == 0)
291 mt8183_apll1_disable(afe);
292 else
293 mt8183_apll2_disable(afe);
294 break;
295 default:
296 break;
297 }
298
299 return 0;
300 }
301
mtk_mclk_en_event(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)302 static int mtk_mclk_en_event(struct snd_soc_dapm_widget *w,
303 struct snd_kcontrol *kcontrol,
304 int event)
305 {
306 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
307 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
308 struct mtk_afe_i2s_priv *i2s_priv;
309
310 dev_info(cmpnt->dev, "%s(), name %s, event 0x%x\n",
311 __func__, w->name, event);
312
313 i2s_priv = get_i2s_priv_by_name(afe, w->name);
314
315 if (!i2s_priv) {
316 dev_warn(afe->dev, "%s(), i2s_priv == NULL", __func__);
317 return -EINVAL;
318 }
319
320 switch (event) {
321 case SND_SOC_DAPM_PRE_PMU:
322 mt8183_mck_enable(afe, i2s_priv->mclk_id, i2s_priv->mclk_rate);
323 break;
324 case SND_SOC_DAPM_POST_PMD:
325 i2s_priv->mclk_rate = 0;
326 mt8183_mck_disable(afe, i2s_priv->mclk_id);
327 break;
328 default:
329 break;
330 }
331
332 return 0;
333 }
334
335 static const struct snd_soc_dapm_widget mtk_dai_i2s_widgets[] = {
336 SND_SOC_DAPM_MIXER("I2S1_CH1", SND_SOC_NOPM, 0, 0,
337 mtk_i2s1_ch1_mix,
338 ARRAY_SIZE(mtk_i2s1_ch1_mix)),
339 SND_SOC_DAPM_MIXER("I2S1_CH2", SND_SOC_NOPM, 0, 0,
340 mtk_i2s1_ch2_mix,
341 ARRAY_SIZE(mtk_i2s1_ch2_mix)),
342
343 SND_SOC_DAPM_MIXER("I2S3_CH1", SND_SOC_NOPM, 0, 0,
344 mtk_i2s3_ch1_mix,
345 ARRAY_SIZE(mtk_i2s3_ch1_mix)),
346 SND_SOC_DAPM_MIXER("I2S3_CH2", SND_SOC_NOPM, 0, 0,
347 mtk_i2s3_ch2_mix,
348 ARRAY_SIZE(mtk_i2s3_ch2_mix)),
349
350 SND_SOC_DAPM_MIXER("I2S5_CH1", SND_SOC_NOPM, 0, 0,
351 mtk_i2s5_ch1_mix,
352 ARRAY_SIZE(mtk_i2s5_ch1_mix)),
353 SND_SOC_DAPM_MIXER("I2S5_CH2", SND_SOC_NOPM, 0, 0,
354 mtk_i2s5_ch2_mix,
355 ARRAY_SIZE(mtk_i2s5_ch2_mix)),
356
357 /* i2s en*/
358 SND_SOC_DAPM_SUPPLY_S("I2S0_EN", SUPPLY_SEQ_I2S_EN,
359 AFE_I2S_CON, I2S_EN_SFT, 0,
360 NULL, 0),
361 SND_SOC_DAPM_SUPPLY_S("I2S1_EN", SUPPLY_SEQ_I2S_EN,
362 AFE_I2S_CON1, I2S_EN_SFT, 0,
363 NULL, 0),
364 SND_SOC_DAPM_SUPPLY_S("I2S2_EN", SUPPLY_SEQ_I2S_EN,
365 AFE_I2S_CON2, I2S_EN_SFT, 0,
366 NULL, 0),
367 SND_SOC_DAPM_SUPPLY_S("I2S3_EN", SUPPLY_SEQ_I2S_EN,
368 AFE_I2S_CON3, I2S_EN_SFT, 0,
369 NULL, 0),
370 SND_SOC_DAPM_SUPPLY_S("I2S5_EN", SUPPLY_SEQ_I2S_EN,
371 AFE_I2S_CON4, I2S5_EN_SFT, 0,
372 NULL, 0),
373 /* i2s hd en */
374 SND_SOC_DAPM_SUPPLY_S(I2S0_HD_EN_W_NAME, SUPPLY_SEQ_I2S_HD_EN,
375 AFE_I2S_CON, I2S1_HD_EN_SFT, 0,
376 NULL, 0),
377 SND_SOC_DAPM_SUPPLY_S(I2S1_HD_EN_W_NAME, SUPPLY_SEQ_I2S_HD_EN,
378 AFE_I2S_CON1, I2S2_HD_EN_SFT, 0,
379 NULL, 0),
380 SND_SOC_DAPM_SUPPLY_S(I2S2_HD_EN_W_NAME, SUPPLY_SEQ_I2S_HD_EN,
381 AFE_I2S_CON2, I2S3_HD_EN_SFT, 0,
382 NULL, 0),
383 SND_SOC_DAPM_SUPPLY_S(I2S3_HD_EN_W_NAME, SUPPLY_SEQ_I2S_HD_EN,
384 AFE_I2S_CON3, I2S4_HD_EN_SFT, 0,
385 NULL, 0),
386 SND_SOC_DAPM_SUPPLY_S(I2S5_HD_EN_W_NAME, SUPPLY_SEQ_I2S_HD_EN,
387 AFE_I2S_CON4, I2S5_HD_EN_SFT, 0,
388 NULL, 0),
389
390 /* i2s mclk en */
391 SND_SOC_DAPM_SUPPLY_S(I2S0_MCLK_EN_W_NAME, SUPPLY_SEQ_I2S_MCLK_EN,
392 SND_SOC_NOPM, 0, 0,
393 mtk_mclk_en_event,
394 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
395 SND_SOC_DAPM_SUPPLY_S(I2S1_MCLK_EN_W_NAME, SUPPLY_SEQ_I2S_MCLK_EN,
396 SND_SOC_NOPM, 0, 0,
397 mtk_mclk_en_event,
398 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
399 SND_SOC_DAPM_SUPPLY_S(I2S2_MCLK_EN_W_NAME, SUPPLY_SEQ_I2S_MCLK_EN,
400 SND_SOC_NOPM, 0, 0,
401 mtk_mclk_en_event,
402 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
403 SND_SOC_DAPM_SUPPLY_S(I2S3_MCLK_EN_W_NAME, SUPPLY_SEQ_I2S_MCLK_EN,
404 SND_SOC_NOPM, 0, 0,
405 mtk_mclk_en_event,
406 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
407 SND_SOC_DAPM_SUPPLY_S(I2S5_MCLK_EN_W_NAME, SUPPLY_SEQ_I2S_MCLK_EN,
408 SND_SOC_NOPM, 0, 0,
409 mtk_mclk_en_event,
410 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
411
412 /* apll */
413 SND_SOC_DAPM_SUPPLY_S(APLL1_W_NAME, SUPPLY_SEQ_APLL,
414 SND_SOC_NOPM, 0, 0,
415 mtk_apll_event,
416 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
417 SND_SOC_DAPM_SUPPLY_S(APLL2_W_NAME, SUPPLY_SEQ_APLL,
418 SND_SOC_NOPM, 0, 0,
419 mtk_apll_event,
420 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
421 };
422
mtk_afe_i2s_share_connect(struct snd_soc_dapm_widget * source,struct snd_soc_dapm_widget * sink)423 static int mtk_afe_i2s_share_connect(struct snd_soc_dapm_widget *source,
424 struct snd_soc_dapm_widget *sink)
425 {
426 struct snd_soc_dapm_widget *w = sink;
427 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
428 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
429 struct mtk_afe_i2s_priv *i2s_priv;
430
431 i2s_priv = get_i2s_priv_by_name(afe, sink->name);
432
433 if (!i2s_priv) {
434 dev_warn(afe->dev, "%s(), i2s_priv == NULL", __func__);
435 return 0;
436 }
437
438 if (i2s_priv->share_i2s_id < 0)
439 return 0;
440
441 return i2s_priv->share_i2s_id == get_i2s_id_by_name(afe, source->name);
442 }
443
mtk_afe_i2s_hd_connect(struct snd_soc_dapm_widget * source,struct snd_soc_dapm_widget * sink)444 static int mtk_afe_i2s_hd_connect(struct snd_soc_dapm_widget *source,
445 struct snd_soc_dapm_widget *sink)
446 {
447 struct snd_soc_dapm_widget *w = sink;
448 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
449 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
450 struct mtk_afe_i2s_priv *i2s_priv;
451
452 i2s_priv = get_i2s_priv_by_name(afe, sink->name);
453
454 if (!i2s_priv) {
455 dev_warn(afe->dev, "%s(), i2s_priv == NULL", __func__);
456 return 0;
457 }
458
459 if (get_i2s_id_by_name(afe, sink->name) ==
460 get_i2s_id_by_name(afe, source->name))
461 return i2s_priv->low_jitter_en;
462
463 /* check if share i2s need hd en */
464 if (i2s_priv->share_i2s_id < 0)
465 return 0;
466
467 if (i2s_priv->share_i2s_id == get_i2s_id_by_name(afe, source->name))
468 return i2s_priv->low_jitter_en;
469
470 return 0;
471 }
472
mtk_afe_i2s_apll_connect(struct snd_soc_dapm_widget * source,struct snd_soc_dapm_widget * sink)473 static int mtk_afe_i2s_apll_connect(struct snd_soc_dapm_widget *source,
474 struct snd_soc_dapm_widget *sink)
475 {
476 struct snd_soc_dapm_widget *w = sink;
477 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
478 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
479 struct mtk_afe_i2s_priv *i2s_priv;
480 int cur_apll;
481 int i2s_need_apll;
482
483 i2s_priv = get_i2s_priv_by_name(afe, w->name);
484
485 if (!i2s_priv) {
486 dev_warn(afe->dev, "%s(), i2s_priv == NULL", __func__);
487 return 0;
488 }
489
490 /* which apll */
491 cur_apll = mt8183_get_apll_by_name(afe, source->name);
492
493 /* choose APLL from i2s rate */
494 i2s_need_apll = mt8183_get_apll_by_rate(afe, i2s_priv->rate);
495
496 return (i2s_need_apll == cur_apll) ? 1 : 0;
497 }
498
mtk_afe_i2s_mclk_connect(struct snd_soc_dapm_widget * source,struct snd_soc_dapm_widget * sink)499 static int mtk_afe_i2s_mclk_connect(struct snd_soc_dapm_widget *source,
500 struct snd_soc_dapm_widget *sink)
501 {
502 struct snd_soc_dapm_widget *w = sink;
503 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
504 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
505 struct mtk_afe_i2s_priv *i2s_priv;
506
507 i2s_priv = get_i2s_priv_by_name(afe, sink->name);
508
509 if (!i2s_priv) {
510 dev_warn(afe->dev, "%s(), i2s_priv == NULL", __func__);
511 return 0;
512 }
513
514 if (get_i2s_id_by_name(afe, sink->name) ==
515 get_i2s_id_by_name(afe, source->name))
516 return (i2s_priv->mclk_rate > 0) ? 1 : 0;
517
518 /* check if share i2s need mclk */
519 if (i2s_priv->share_i2s_id < 0)
520 return 0;
521
522 if (i2s_priv->share_i2s_id == get_i2s_id_by_name(afe, source->name))
523 return (i2s_priv->mclk_rate > 0) ? 1 : 0;
524
525 return 0;
526 }
527
mtk_afe_mclk_apll_connect(struct snd_soc_dapm_widget * source,struct snd_soc_dapm_widget * sink)528 static int mtk_afe_mclk_apll_connect(struct snd_soc_dapm_widget *source,
529 struct snd_soc_dapm_widget *sink)
530 {
531 struct snd_soc_dapm_widget *w = sink;
532 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
533 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
534 struct mtk_afe_i2s_priv *i2s_priv;
535 int cur_apll;
536
537 i2s_priv = get_i2s_priv_by_name(afe, w->name);
538
539 if (!i2s_priv) {
540 dev_warn(afe->dev, "%s(), i2s_priv == NULL", __func__);
541 return 0;
542 }
543
544 /* which apll */
545 cur_apll = mt8183_get_apll_by_name(afe, source->name);
546
547 return (i2s_priv->mclk_apll == cur_apll) ? 1 : 0;
548 }
549
550 static const struct snd_soc_dapm_route mtk_dai_i2s_routes[] = {
551 /* i2s0 */
552 {"I2S0", NULL, "I2S0_EN"},
553 {"I2S0", NULL, "I2S1_EN", mtk_afe_i2s_share_connect},
554 {"I2S0", NULL, "I2S2_EN", mtk_afe_i2s_share_connect},
555 {"I2S0", NULL, "I2S3_EN", mtk_afe_i2s_share_connect},
556 {"I2S0", NULL, "I2S5_EN", mtk_afe_i2s_share_connect},
557
558 {"I2S0", NULL, I2S0_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
559 {"I2S0", NULL, I2S1_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
560 {"I2S0", NULL, I2S2_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
561 {"I2S0", NULL, I2S3_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
562 {"I2S0", NULL, I2S5_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
563 {I2S0_HD_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_i2s_apll_connect},
564 {I2S0_HD_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_i2s_apll_connect},
565
566 {"I2S0", NULL, I2S0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
567 {"I2S0", NULL, I2S1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
568 {"I2S0", NULL, I2S2_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
569 {"I2S0", NULL, I2S3_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
570 {"I2S0", NULL, I2S5_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
571 {I2S0_MCLK_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect},
572 {I2S0_MCLK_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect},
573
574 /* i2s1 */
575 {"I2S1_CH1", "DL1_CH1", "DL1"},
576 {"I2S1_CH2", "DL1_CH2", "DL1"},
577
578 {"I2S1_CH1", "DL2_CH1", "DL2"},
579 {"I2S1_CH2", "DL2_CH2", "DL2"},
580
581 {"I2S1_CH1", "DL3_CH1", "DL3"},
582 {"I2S1_CH2", "DL3_CH2", "DL3"},
583
584 {"I2S1", NULL, "I2S1_CH1"},
585 {"I2S1", NULL, "I2S1_CH2"},
586
587 {"I2S1", NULL, "I2S0_EN", mtk_afe_i2s_share_connect},
588 {"I2S1", NULL, "I2S1_EN"},
589 {"I2S1", NULL, "I2S2_EN", mtk_afe_i2s_share_connect},
590 {"I2S1", NULL, "I2S3_EN", mtk_afe_i2s_share_connect},
591 {"I2S1", NULL, "I2S5_EN", mtk_afe_i2s_share_connect},
592
593 {"I2S1", NULL, I2S0_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
594 {"I2S1", NULL, I2S1_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
595 {"I2S1", NULL, I2S2_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
596 {"I2S1", NULL, I2S3_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
597 {"I2S1", NULL, I2S5_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
598 {I2S1_HD_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_i2s_apll_connect},
599 {I2S1_HD_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_i2s_apll_connect},
600
601 {"I2S1", NULL, I2S0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
602 {"I2S1", NULL, I2S1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
603 {"I2S1", NULL, I2S2_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
604 {"I2S1", NULL, I2S3_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
605 {"I2S1", NULL, I2S5_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
606 {I2S1_MCLK_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect},
607 {I2S1_MCLK_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect},
608
609 /* i2s2 */
610 {"I2S2", NULL, "I2S0_EN", mtk_afe_i2s_share_connect},
611 {"I2S2", NULL, "I2S1_EN", mtk_afe_i2s_share_connect},
612 {"I2S2", NULL, "I2S2_EN"},
613 {"I2S2", NULL, "I2S3_EN", mtk_afe_i2s_share_connect},
614 {"I2S2", NULL, "I2S5_EN", mtk_afe_i2s_share_connect},
615
616 {"I2S2", NULL, I2S0_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
617 {"I2S2", NULL, I2S1_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
618 {"I2S2", NULL, I2S2_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
619 {"I2S2", NULL, I2S3_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
620 {"I2S2", NULL, I2S5_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
621 {I2S2_HD_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_i2s_apll_connect},
622 {I2S2_HD_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_i2s_apll_connect},
623
624 {"I2S2", NULL, I2S0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
625 {"I2S2", NULL, I2S1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
626 {"I2S2", NULL, I2S2_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
627 {"I2S2", NULL, I2S3_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
628 {"I2S2", NULL, I2S5_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
629 {I2S2_MCLK_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect},
630 {I2S2_MCLK_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect},
631
632 /* i2s3 */
633 {"I2S3_CH1", "DL1_CH1", "DL1"},
634 {"I2S3_CH2", "DL1_CH2", "DL1"},
635
636 {"I2S3_CH1", "DL2_CH1", "DL2"},
637 {"I2S3_CH2", "DL2_CH2", "DL2"},
638
639 {"I2S3_CH1", "DL3_CH1", "DL3"},
640 {"I2S3_CH2", "DL3_CH2", "DL3"},
641
642 {"I2S3", NULL, "I2S3_CH1"},
643 {"I2S3", NULL, "I2S3_CH2"},
644
645 {"I2S3", NULL, "I2S0_EN", mtk_afe_i2s_share_connect},
646 {"I2S3", NULL, "I2S1_EN", mtk_afe_i2s_share_connect},
647 {"I2S3", NULL, "I2S2_EN", mtk_afe_i2s_share_connect},
648 {"I2S3", NULL, "I2S3_EN"},
649 {"I2S3", NULL, "I2S5_EN", mtk_afe_i2s_share_connect},
650
651 {"I2S3", NULL, I2S0_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
652 {"I2S3", NULL, I2S1_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
653 {"I2S3", NULL, I2S2_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
654 {"I2S3", NULL, I2S3_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
655 {"I2S3", NULL, I2S5_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
656 {I2S3_HD_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_i2s_apll_connect},
657 {I2S3_HD_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_i2s_apll_connect},
658
659 {"I2S3", NULL, I2S0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
660 {"I2S3", NULL, I2S1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
661 {"I2S3", NULL, I2S2_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
662 {"I2S3", NULL, I2S3_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
663 {"I2S3", NULL, I2S5_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
664 {I2S3_MCLK_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect},
665 {I2S3_MCLK_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect},
666
667 /* i2s5 */
668 {"I2S5_CH1", "DL1_CH1", "DL1"},
669 {"I2S5_CH2", "DL1_CH2", "DL1"},
670
671 {"I2S5_CH1", "DL2_CH1", "DL2"},
672 {"I2S5_CH2", "DL2_CH2", "DL2"},
673
674 {"I2S5_CH1", "DL3_CH1", "DL3"},
675 {"I2S5_CH2", "DL3_CH2", "DL3"},
676
677 {"I2S5", NULL, "I2S5_CH1"},
678 {"I2S5", NULL, "I2S5_CH2"},
679
680 {"I2S5", NULL, "I2S0_EN", mtk_afe_i2s_share_connect},
681 {"I2S5", NULL, "I2S1_EN", mtk_afe_i2s_share_connect},
682 {"I2S5", NULL, "I2S2_EN", mtk_afe_i2s_share_connect},
683 {"I2S5", NULL, "I2S3_EN", mtk_afe_i2s_share_connect},
684 {"I2S5", NULL, "I2S5_EN"},
685
686 {"I2S5", NULL, I2S0_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
687 {"I2S5", NULL, I2S1_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
688 {"I2S5", NULL, I2S2_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
689 {"I2S5", NULL, I2S3_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
690 {"I2S5", NULL, I2S5_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
691 {I2S5_HD_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_i2s_apll_connect},
692 {I2S5_HD_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_i2s_apll_connect},
693
694 {"I2S5", NULL, I2S0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
695 {"I2S5", NULL, I2S1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
696 {"I2S5", NULL, I2S2_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
697 {"I2S5", NULL, I2S3_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
698 {"I2S5", NULL, I2S5_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
699 {I2S5_MCLK_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect},
700 {I2S5_MCLK_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect},
701 };
702
703 /* dai ops */
mtk_dai_i2s_config(struct mtk_base_afe * afe,struct snd_pcm_hw_params * params,int i2s_id)704 static int mtk_dai_i2s_config(struct mtk_base_afe *afe,
705 struct snd_pcm_hw_params *params,
706 int i2s_id)
707 {
708 struct mt8183_afe_private *afe_priv = afe->platform_priv;
709 struct mtk_afe_i2s_priv *i2s_priv = afe_priv->dai_priv[i2s_id];
710
711 unsigned int rate = params_rate(params);
712 unsigned int rate_reg = mt8183_rate_transform(afe->dev,
713 rate, i2s_id);
714 snd_pcm_format_t format = params_format(params);
715 unsigned int i2s_con = 0, fmt_con = I2S_FMT_I2S << I2S_FMT_SFT;
716 int ret = 0;
717
718 dev_info(afe->dev, "%s(), id %d, rate %d, format %d\n",
719 __func__,
720 i2s_id,
721 rate, format);
722
723 if (i2s_priv) {
724 i2s_priv->rate = rate;
725
726 if (i2s_priv->use_eiaj)
727 fmt_con = I2S_FMT_EIAJ << I2S_FMT_SFT;
728 } else {
729 dev_warn(afe->dev, "%s(), i2s_priv == NULL", __func__);
730 }
731
732 switch (i2s_id) {
733 case MT8183_DAI_I2S_0:
734 regmap_update_bits(afe->regmap, AFE_DAC_CON1,
735 I2S_MODE_MASK_SFT, rate_reg << I2S_MODE_SFT);
736 i2s_con = I2S_IN_PAD_IO_MUX << I2SIN_PAD_SEL_SFT;
737 i2s_con |= fmt_con;
738 i2s_con |= get_i2s_wlen(format) << I2S_WLEN_SFT;
739 regmap_update_bits(afe->regmap, AFE_I2S_CON,
740 0xffffeffe, i2s_con);
741 break;
742 case MT8183_DAI_I2S_1:
743 i2s_con = I2S1_SEL_O28_O29 << I2S2_SEL_O03_O04_SFT;
744 i2s_con |= rate_reg << I2S2_OUT_MODE_SFT;
745 i2s_con |= fmt_con;
746 i2s_con |= get_i2s_wlen(format) << I2S2_WLEN_SFT;
747 regmap_update_bits(afe->regmap, AFE_I2S_CON1,
748 0xffffeffe, i2s_con);
749 break;
750 case MT8183_DAI_I2S_2:
751 i2s_con = 8 << I2S3_UPDATE_WORD_SFT;
752 i2s_con |= rate_reg << I2S3_OUT_MODE_SFT;
753 i2s_con |= fmt_con;
754 i2s_con |= get_i2s_wlen(format) << I2S3_WLEN_SFT;
755 regmap_update_bits(afe->regmap, AFE_I2S_CON2,
756 0xffffeffe, i2s_con);
757 break;
758 case MT8183_DAI_I2S_3:
759 i2s_con = rate_reg << I2S4_OUT_MODE_SFT;
760 i2s_con |= fmt_con;
761 i2s_con |= get_i2s_wlen(format) << I2S4_WLEN_SFT;
762 regmap_update_bits(afe->regmap, AFE_I2S_CON3,
763 0xffffeffe, i2s_con);
764 break;
765 case MT8183_DAI_I2S_5:
766 i2s_con = rate_reg << I2S5_OUT_MODE_SFT;
767 i2s_con |= fmt_con;
768 i2s_con |= get_i2s_wlen(format) << I2S5_WLEN_SFT;
769 regmap_update_bits(afe->regmap, AFE_I2S_CON4,
770 0xffffeffe, i2s_con);
771 break;
772 default:
773 dev_warn(afe->dev, "%s(), id %d not support\n",
774 __func__, i2s_id);
775 return -EINVAL;
776 }
777
778 /* set share i2s */
779 if (i2s_priv && i2s_priv->share_i2s_id >= 0)
780 ret = mtk_dai_i2s_config(afe, params, i2s_priv->share_i2s_id);
781
782 return ret;
783 }
784
mtk_dai_i2s_hw_params(struct snd_pcm_substream * substream,struct snd_pcm_hw_params * params,struct snd_soc_dai * dai)785 static int mtk_dai_i2s_hw_params(struct snd_pcm_substream *substream,
786 struct snd_pcm_hw_params *params,
787 struct snd_soc_dai *dai)
788 {
789 struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
790
791 return mtk_dai_i2s_config(afe, params, dai->id);
792 }
793
mtk_dai_i2s_set_sysclk(struct snd_soc_dai * dai,int clk_id,unsigned int freq,int dir)794 static int mtk_dai_i2s_set_sysclk(struct snd_soc_dai *dai,
795 int clk_id, unsigned int freq, int dir)
796 {
797 struct mtk_base_afe *afe = dev_get_drvdata(dai->dev);
798 struct mt8183_afe_private *afe_priv = afe->platform_priv;
799 struct mtk_afe_i2s_priv *i2s_priv = afe_priv->dai_priv[dai->id];
800 int apll;
801 int apll_rate;
802
803 if (!i2s_priv) {
804 dev_warn(afe->dev, "%s(), i2s_priv == NULL", __func__);
805 return -EINVAL;
806 }
807
808 if (dir != SND_SOC_CLOCK_OUT) {
809 dev_warn(afe->dev, "%s(), dir != SND_SOC_CLOCK_OUT", __func__);
810 return -EINVAL;
811 }
812
813 dev_info(afe->dev, "%s(), freq %d\n", __func__, freq);
814
815 apll = mt8183_get_apll_by_rate(afe, freq);
816 apll_rate = mt8183_get_apll_rate(afe, apll);
817
818 if (freq > apll_rate) {
819 dev_warn(afe->dev, "%s(), freq > apll rate", __func__);
820 return -EINVAL;
821 }
822
823 if (apll_rate % freq != 0) {
824 dev_warn(afe->dev, "%s(), APLL cannot generate freq Hz",
825 __func__);
826 return -EINVAL;
827 }
828
829 i2s_priv->mclk_rate = freq;
830 i2s_priv->mclk_apll = apll;
831
832 if (i2s_priv->share_i2s_id > 0) {
833 struct mtk_afe_i2s_priv *share_i2s_priv;
834
835 share_i2s_priv = afe_priv->dai_priv[i2s_priv->share_i2s_id];
836 if (!share_i2s_priv) {
837 dev_warn(afe->dev, "%s(), share_i2s_priv == NULL",
838 __func__);
839 return -EINVAL;
840 }
841
842 share_i2s_priv->mclk_rate = i2s_priv->mclk_rate;
843 share_i2s_priv->mclk_apll = i2s_priv->mclk_apll;
844 }
845
846 return 0;
847 }
848
mtk_dai_i2s_set_fmt(struct snd_soc_dai * dai,unsigned int fmt)849 static int mtk_dai_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
850 {
851 struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
852 struct mt8183_afe_private *afe_priv = afe->platform_priv;
853 struct mtk_afe_i2s_priv *i2s_priv;
854
855 switch (dai->id) {
856 case MT8183_DAI_I2S_0:
857 case MT8183_DAI_I2S_1:
858 case MT8183_DAI_I2S_2:
859 case MT8183_DAI_I2S_3:
860 case MT8183_DAI_I2S_5:
861 break;
862 default:
863 dev_warn(afe->dev, "%s(), id %d not support\n",
864 __func__, dai->id);
865 return -EINVAL;
866 }
867 i2s_priv = afe_priv->dai_priv[dai->id];
868
869 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
870 case SND_SOC_DAIFMT_LEFT_J:
871 i2s_priv->use_eiaj = 1;
872 break;
873 case SND_SOC_DAIFMT_I2S:
874 i2s_priv->use_eiaj = 0;
875 break;
876 default:
877 dev_warn(afe->dev, "%s(), DAI format %d not support\n",
878 __func__, fmt & SND_SOC_DAIFMT_FORMAT_MASK);
879 return -EINVAL;
880 }
881
882 return 0;
883 }
884
885 static const struct snd_soc_dai_ops mtk_dai_i2s_ops = {
886 .hw_params = mtk_dai_i2s_hw_params,
887 .set_sysclk = mtk_dai_i2s_set_sysclk,
888 .set_fmt = mtk_dai_i2s_set_fmt,
889 };
890
891 /* dai driver */
892 #define MTK_I2S_RATES (SNDRV_PCM_RATE_8000_48000 |\
893 SNDRV_PCM_RATE_88200 |\
894 SNDRV_PCM_RATE_96000 |\
895 SNDRV_PCM_RATE_176400 |\
896 SNDRV_PCM_RATE_192000)
897
898 #define MTK_I2S_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
899 SNDRV_PCM_FMTBIT_S24_LE |\
900 SNDRV_PCM_FMTBIT_S32_LE)
901
902 static struct snd_soc_dai_driver mtk_dai_i2s_driver[] = {
903 {
904 .name = "I2S0",
905 .id = MT8183_DAI_I2S_0,
906 .capture = {
907 .stream_name = "I2S0",
908 .channels_min = 1,
909 .channels_max = 2,
910 .rates = MTK_I2S_RATES,
911 .formats = MTK_I2S_FORMATS,
912 },
913 .ops = &mtk_dai_i2s_ops,
914 },
915 {
916 .name = "I2S1",
917 .id = MT8183_DAI_I2S_1,
918 .playback = {
919 .stream_name = "I2S1",
920 .channels_min = 1,
921 .channels_max = 2,
922 .rates = MTK_I2S_RATES,
923 .formats = MTK_I2S_FORMATS,
924 },
925 .ops = &mtk_dai_i2s_ops,
926 },
927 {
928 .name = "I2S2",
929 .id = MT8183_DAI_I2S_2,
930 .capture = {
931 .stream_name = "I2S2",
932 .channels_min = 1,
933 .channels_max = 2,
934 .rates = MTK_I2S_RATES,
935 .formats = MTK_I2S_FORMATS,
936 },
937 .ops = &mtk_dai_i2s_ops,
938 },
939 {
940 .name = "I2S3",
941 .id = MT8183_DAI_I2S_3,
942 .playback = {
943 .stream_name = "I2S3",
944 .channels_min = 1,
945 .channels_max = 2,
946 .rates = MTK_I2S_RATES,
947 .formats = MTK_I2S_FORMATS,
948 },
949 .ops = &mtk_dai_i2s_ops,
950 },
951 {
952 .name = "I2S5",
953 .id = MT8183_DAI_I2S_5,
954 .playback = {
955 .stream_name = "I2S5",
956 .channels_min = 1,
957 .channels_max = 2,
958 .rates = MTK_I2S_RATES,
959 .formats = MTK_I2S_FORMATS,
960 },
961 .ops = &mtk_dai_i2s_ops,
962 },
963 };
964
965 /* this enum is merely for mtk_afe_i2s_priv declare */
966 enum {
967 DAI_I2S0 = 0,
968 DAI_I2S1,
969 DAI_I2S2,
970 DAI_I2S3,
971 DAI_I2S5,
972 DAI_I2S_NUM,
973 };
974
975 static const struct mtk_afe_i2s_priv mt8183_i2s_priv[DAI_I2S_NUM] = {
976 [DAI_I2S0] = {
977 .id = MT8183_DAI_I2S_0,
978 .mclk_id = MT8183_I2S0_MCK,
979 .share_i2s_id = -1,
980 },
981 [DAI_I2S1] = {
982 .id = MT8183_DAI_I2S_1,
983 .mclk_id = MT8183_I2S1_MCK,
984 .share_i2s_id = -1,
985 },
986 [DAI_I2S2] = {
987 .id = MT8183_DAI_I2S_2,
988 .mclk_id = MT8183_I2S2_MCK,
989 .share_i2s_id = -1,
990 },
991 [DAI_I2S3] = {
992 .id = MT8183_DAI_I2S_3,
993 .mclk_id = MT8183_I2S3_MCK,
994 .share_i2s_id = -1,
995 },
996 [DAI_I2S5] = {
997 .id = MT8183_DAI_I2S_5,
998 .mclk_id = MT8183_I2S5_MCK,
999 .share_i2s_id = -1,
1000 },
1001 };
1002
1003 /**
1004 * mt8183_dai_i2s_set_share() - Set up I2S ports to share a single clock.
1005 * @afe: Pointer to &struct mtk_base_afe
1006 * @main_i2s_name: The name of the I2S port that will provide the clock
1007 * @secondary_i2s_name: The name of the I2S port that will use this clock
1008 */
mt8183_dai_i2s_set_share(struct mtk_base_afe * afe,const char * main_i2s_name,const char * secondary_i2s_name)1009 int mt8183_dai_i2s_set_share(struct mtk_base_afe *afe, const char *main_i2s_name,
1010 const char *secondary_i2s_name)
1011 {
1012 struct mtk_afe_i2s_priv *secondary_i2s_priv;
1013 int main_i2s_id;
1014
1015 secondary_i2s_priv = get_i2s_priv_by_name(afe, secondary_i2s_name);
1016 if (!secondary_i2s_priv)
1017 return -EINVAL;
1018
1019 main_i2s_id = get_i2s_id_by_name(afe, main_i2s_name);
1020 if (main_i2s_id < 0)
1021 return main_i2s_id;
1022
1023 secondary_i2s_priv->share_i2s_id = main_i2s_id;
1024
1025 return 0;
1026 }
1027 EXPORT_SYMBOL_GPL(mt8183_dai_i2s_set_share);
1028
mt8183_dai_i2s_set_priv(struct mtk_base_afe * afe)1029 static int mt8183_dai_i2s_set_priv(struct mtk_base_afe *afe)
1030 {
1031 struct mt8183_afe_private *afe_priv = afe->platform_priv;
1032 struct mtk_afe_i2s_priv *i2s_priv;
1033 int i;
1034
1035 for (i = 0; i < DAI_I2S_NUM; i++) {
1036 i2s_priv = devm_kzalloc(afe->dev,
1037 sizeof(struct mtk_afe_i2s_priv),
1038 GFP_KERNEL);
1039 if (!i2s_priv)
1040 return -ENOMEM;
1041
1042 memcpy(i2s_priv, &mt8183_i2s_priv[i],
1043 sizeof(struct mtk_afe_i2s_priv));
1044
1045 afe_priv->dai_priv[mt8183_i2s_priv[i].id] = i2s_priv;
1046 }
1047
1048 return 0;
1049 }
1050
mt8183_dai_i2s_register(struct mtk_base_afe * afe)1051 int mt8183_dai_i2s_register(struct mtk_base_afe *afe)
1052 {
1053 struct mtk_base_afe_dai *dai;
1054 int ret;
1055
1056 dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL);
1057 if (!dai)
1058 return -ENOMEM;
1059
1060 list_add(&dai->list, &afe->sub_dais);
1061
1062 dai->dai_drivers = mtk_dai_i2s_driver;
1063 dai->num_dai_drivers = ARRAY_SIZE(mtk_dai_i2s_driver);
1064
1065 dai->controls = mtk_dai_i2s_controls;
1066 dai->num_controls = ARRAY_SIZE(mtk_dai_i2s_controls);
1067 dai->dapm_widgets = mtk_dai_i2s_widgets;
1068 dai->num_dapm_widgets = ARRAY_SIZE(mtk_dai_i2s_widgets);
1069 dai->dapm_routes = mtk_dai_i2s_routes;
1070 dai->num_dapm_routes = ARRAY_SIZE(mtk_dai_i2s_routes);
1071
1072 /* set all dai i2s private data */
1073 ret = mt8183_dai_i2s_set_priv(afe);
1074 if (ret)
1075 return ret;
1076
1077 return 0;
1078 }
1079