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