• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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