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