1 // SPDX-License-Identifier: GPL-2.0
3 // MediaTek ALSA SoC Audio DAI I2S Control
5 // Copyright (c) 2018 MediaTek Inc.
6 // Author: KaiChieh Chuang <kaichieh.chuang@mediatek.com>
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"
28 I2S_HD_LOW_JITTER = 1,
37 I2S_IN_PAD_CONNSYS = 0,
38 I2S_IN_PAD_IO_MUX = 1,
41 struct mtk_afe_i2s_priv {
43 int rate; /* for determine which apll to use */
46 const char *share_property_name;
54 static unsigned int get_i2s_wlen(snd_pcm_format_t format)
56 return snd_pcm_format_physical_width(format) <= 16 ?
57 I2S_WLEN_16_BIT : I2S_WLEN_32_BIT;
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"
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"
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"
78 static int get_i2s_id_by_name(struct mtk_base_afe *afe,
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;
95 static struct mtk_afe_i2s_priv *get_i2s_priv_by_name(struct mtk_base_afe *afe,
98 struct mt8183_afe_private *afe_priv = afe->platform_priv;
99 int dai_id = get_i2s_id_by_name(afe, name);
104 return afe_priv->dai_priv[dai_id];
107 /* low jitter control */
108 static const char * const mt8183_i2s_hd_str[] = {
109 "Normal", "Low_Jitter"
112 static const struct soc_enum mt8183_i2s_enum[] = {
113 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(mt8183_i2s_hd_str),
117 static int mt8183_i2s_hd_get(struct snd_kcontrol *kcontrol,
118 struct snd_ctl_elem_value *ucontrol)
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;
124 i2s_priv = get_i2s_priv_by_name(afe, kcontrol->id.name);
127 dev_warn(afe->dev, "%s(), i2s_priv == NULL", __func__);
131 ucontrol->value.integer.value[0] = i2s_priv->low_jitter_en;
136 static int mt8183_i2s_hd_set(struct snd_kcontrol *kcontrol,
137 struct snd_ctl_elem_value *ucontrol)
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;
145 if (ucontrol->value.enumerated.item[0] >= e->items)
148 hd_en = ucontrol->value.integer.value[0];
150 dev_info(afe->dev, "%s(), kcontrol name %s, hd_en %d\n",
151 __func__, kcontrol->id.name, hd_en);
153 i2s_priv = get_i2s_priv_by_name(afe, kcontrol->id.name);
156 dev_warn(afe->dev, "%s(), i2s_priv == NULL", __func__);
160 i2s_priv->low_jitter_en = hd_en;
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),
179 /* interconnection */
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),
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),
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),
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),
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),
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),
266 SUPPLY_SEQ_I2S_MCLK_EN,
267 SUPPLY_SEQ_I2S_HD_EN,
271 static int mtk_apll_event(struct snd_soc_dapm_widget *w,
272 struct snd_kcontrol *kcontrol,
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);
278 dev_info(cmpnt->dev, "%s(), name %s, event 0x%x\n",
279 __func__, w->name, event);
282 case SND_SOC_DAPM_PRE_PMU:
283 if (strcmp(w->name, APLL1_W_NAME) == 0)
284 mt8183_apll1_enable(afe);
286 mt8183_apll2_enable(afe);
288 case SND_SOC_DAPM_POST_PMD:
289 if (strcmp(w->name, APLL1_W_NAME) == 0)
290 mt8183_apll1_disable(afe);
292 mt8183_apll2_disable(afe);
301 static int mtk_mclk_en_event(struct snd_soc_dapm_widget *w,
302 struct snd_kcontrol *kcontrol,
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;
309 dev_info(cmpnt->dev, "%s(), name %s, event 0x%x\n",
310 __func__, w->name, event);
312 i2s_priv = get_i2s_priv_by_name(afe, w->name);
315 dev_warn(afe->dev, "%s(), i2s_priv == NULL", __func__);
320 case SND_SOC_DAPM_PRE_PMU:
321 mt8183_mck_enable(afe, i2s_priv->mclk_id, i2s_priv->mclk_rate);
323 case SND_SOC_DAPM_POST_PMD:
324 i2s_priv->mclk_rate = 0;
325 mt8183_mck_disable(afe, i2s_priv->mclk_id);
334 static const struct snd_soc_dapm_widget mtk_dai_i2s_widgets[] = {
335 SND_SOC_DAPM_MIXER("I2S1_CH1", SND_SOC_NOPM, 0, 0,
337 ARRAY_SIZE(mtk_i2s1_ch1_mix)),
338 SND_SOC_DAPM_MIXER("I2S1_CH2", SND_SOC_NOPM, 0, 0,
340 ARRAY_SIZE(mtk_i2s1_ch2_mix)),
342 SND_SOC_DAPM_MIXER("I2S3_CH1", SND_SOC_NOPM, 0, 0,
344 ARRAY_SIZE(mtk_i2s3_ch1_mix)),
345 SND_SOC_DAPM_MIXER("I2S3_CH2", SND_SOC_NOPM, 0, 0,
347 ARRAY_SIZE(mtk_i2s3_ch2_mix)),
349 SND_SOC_DAPM_MIXER("I2S5_CH1", SND_SOC_NOPM, 0, 0,
351 ARRAY_SIZE(mtk_i2s5_ch1_mix)),
352 SND_SOC_DAPM_MIXER("I2S5_CH2", SND_SOC_NOPM, 0, 0,
354 ARRAY_SIZE(mtk_i2s5_ch2_mix)),
357 SND_SOC_DAPM_SUPPLY_S("I2S0_EN", SUPPLY_SEQ_I2S_EN,
358 AFE_I2S_CON, I2S_EN_SFT, 0,
360 SND_SOC_DAPM_SUPPLY_S("I2S1_EN", SUPPLY_SEQ_I2S_EN,
361 AFE_I2S_CON1, I2S_EN_SFT, 0,
363 SND_SOC_DAPM_SUPPLY_S("I2S2_EN", SUPPLY_SEQ_I2S_EN,
364 AFE_I2S_CON2, I2S_EN_SFT, 0,
366 SND_SOC_DAPM_SUPPLY_S("I2S3_EN", SUPPLY_SEQ_I2S_EN,
367 AFE_I2S_CON3, I2S_EN_SFT, 0,
369 SND_SOC_DAPM_SUPPLY_S("I2S5_EN", SUPPLY_SEQ_I2S_EN,
370 AFE_I2S_CON4, I2S5_EN_SFT, 0,
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,
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,
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,
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,
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,
390 SND_SOC_DAPM_SUPPLY_S(I2S0_MCLK_EN_W_NAME, SUPPLY_SEQ_I2S_MCLK_EN,
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,
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,
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,
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,
409 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
412 SND_SOC_DAPM_SUPPLY_S(APLL1_W_NAME, SUPPLY_SEQ_APLL,
415 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
416 SND_SOC_DAPM_SUPPLY_S(APLL2_W_NAME, SUPPLY_SEQ_APLL,
419 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
422 static int mtk_afe_i2s_share_connect(struct snd_soc_dapm_widget *source,
423 struct snd_soc_dapm_widget *sink)
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;
430 i2s_priv = get_i2s_priv_by_name(afe, sink->name);
433 dev_warn(afe->dev, "%s(), i2s_priv == NULL", __func__);
437 if (i2s_priv->share_i2s_id < 0)
440 return i2s_priv->share_i2s_id == get_i2s_id_by_name(afe, source->name);
443 static int mtk_afe_i2s_hd_connect(struct snd_soc_dapm_widget *source,
444 struct snd_soc_dapm_widget *sink)
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;
451 i2s_priv = get_i2s_priv_by_name(afe, sink->name);
454 dev_warn(afe->dev, "%s(), i2s_priv == NULL", __func__);
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;
462 /* check if share i2s need hd en */
463 if (i2s_priv->share_i2s_id < 0)
466 if (i2s_priv->share_i2s_id == get_i2s_id_by_name(afe, source->name))
467 return i2s_priv->low_jitter_en;
472 static int mtk_afe_i2s_apll_connect(struct snd_soc_dapm_widget *source,
473 struct snd_soc_dapm_widget *sink)
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;
482 i2s_priv = get_i2s_priv_by_name(afe, w->name);
485 dev_warn(afe->dev, "%s(), i2s_priv == NULL", __func__);
490 cur_apll = mt8183_get_apll_by_name(afe, source->name);
492 /* choose APLL from i2s rate */
493 i2s_need_apll = mt8183_get_apll_by_rate(afe, i2s_priv->rate);
495 return (i2s_need_apll == cur_apll) ? 1 : 0;
498 static int mtk_afe_i2s_mclk_connect(struct snd_soc_dapm_widget *source,
499 struct snd_soc_dapm_widget *sink)
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;
506 i2s_priv = get_i2s_priv_by_name(afe, sink->name);
509 dev_warn(afe->dev, "%s(), i2s_priv == NULL", __func__);
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;
517 /* check if share i2s need mclk */
518 if (i2s_priv->share_i2s_id < 0)
521 if (i2s_priv->share_i2s_id == get_i2s_id_by_name(afe, source->name))
522 return (i2s_priv->mclk_rate > 0) ? 1 : 0;
527 static int mtk_afe_mclk_apll_connect(struct snd_soc_dapm_widget *source,
528 struct snd_soc_dapm_widget *sink)
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;
536 i2s_priv = get_i2s_priv_by_name(afe, w->name);
539 dev_warn(afe->dev, "%s(), i2s_priv == NULL", __func__);
544 cur_apll = mt8183_get_apll_by_name(afe, source->name);
546 return (i2s_priv->mclk_apll == cur_apll) ? 1 : 0;
549 static const struct snd_soc_dapm_route mtk_dai_i2s_routes[] = {
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},
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},
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},
574 {"I2S1_CH1", "DL1_CH1", "DL1"},
575 {"I2S1_CH2", "DL1_CH2", "DL1"},
577 {"I2S1_CH1", "DL2_CH1", "DL2"},
578 {"I2S1_CH2", "DL2_CH2", "DL2"},
580 {"I2S1_CH1", "DL3_CH1", "DL3"},
581 {"I2S1_CH2", "DL3_CH2", "DL3"},
583 {"I2S1", NULL, "I2S1_CH1"},
584 {"I2S1", NULL, "I2S1_CH2"},
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},
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},
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},
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},
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},
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},
632 {"I2S3_CH1", "DL1_CH1", "DL1"},
633 {"I2S3_CH2", "DL1_CH2", "DL1"},
635 {"I2S3_CH1", "DL2_CH1", "DL2"},
636 {"I2S3_CH2", "DL2_CH2", "DL2"},
638 {"I2S3_CH1", "DL3_CH1", "DL3"},
639 {"I2S3_CH2", "DL3_CH2", "DL3"},
641 {"I2S3", NULL, "I2S3_CH1"},
642 {"I2S3", NULL, "I2S3_CH2"},
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},
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},
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},
667 {"I2S5_CH1", "DL1_CH1", "DL1"},
668 {"I2S5_CH2", "DL1_CH2", "DL1"},
670 {"I2S5_CH1", "DL2_CH1", "DL2"},
671 {"I2S5_CH2", "DL2_CH2", "DL2"},
673 {"I2S5_CH1", "DL3_CH1", "DL3"},
674 {"I2S5_CH2", "DL3_CH2", "DL3"},
676 {"I2S5", NULL, "I2S5_CH1"},
677 {"I2S5", NULL, "I2S5_CH2"},
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"},
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},
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},
703 static int mtk_dai_i2s_config(struct mtk_base_afe *afe,
704 struct snd_pcm_hw_params *params,
707 struct mt8183_afe_private *afe_priv = afe->platform_priv;
708 struct mtk_afe_i2s_priv *i2s_priv = afe_priv->dai_priv[i2s_id];
710 unsigned int rate = params_rate(params);
711 unsigned int rate_reg = mt8183_rate_transform(afe->dev,
713 snd_pcm_format_t format = params_format(params);
714 unsigned int i2s_con = 0;
717 dev_info(afe->dev, "%s(), id %d, rate %d, format %d\n",
723 i2s_priv->rate = rate;
725 dev_warn(afe->dev, "%s(), i2s_priv == NULL", __func__);
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);
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);
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);
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);
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);
768 dev_warn(afe->dev, "%s(), id %d not support\n",
774 if (i2s_priv && i2s_priv->share_i2s_id >= 0)
775 ret = mtk_dai_i2s_config(afe, params, i2s_priv->share_i2s_id);
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)
784 struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
786 return mtk_dai_i2s_config(afe, params, dai->id);
789 static int mtk_dai_i2s_set_sysclk(struct snd_soc_dai *dai,
790 int clk_id, unsigned int freq, int dir)
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];
799 dev_warn(afe->dev, "%s(), i2s_priv == NULL", __func__);
803 if (dir != SND_SOC_CLOCK_OUT) {
804 dev_warn(afe->dev, "%s(), dir != SND_SOC_CLOCK_OUT", __func__);
808 dev_info(afe->dev, "%s(), freq %d\n", __func__, freq);
810 apll = mt8183_get_apll_by_rate(afe, freq);
811 apll_rate = mt8183_get_apll_rate(afe, apll);
813 if (freq > apll_rate) {
814 dev_warn(afe->dev, "%s(), freq > apll rate", __func__);
818 if (apll_rate % freq != 0) {
819 dev_warn(afe->dev, "%s(), APLL cannot generate freq Hz",
824 i2s_priv->mclk_rate = freq;
825 i2s_priv->mclk_apll = apll;
827 if (i2s_priv->share_i2s_id > 0) {
828 struct mtk_afe_i2s_priv *share_i2s_priv;
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",
837 share_i2s_priv->mclk_rate = i2s_priv->mclk_rate;
838 share_i2s_priv->mclk_apll = i2s_priv->mclk_apll;
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,
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)
856 #define MTK_I2S_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
857 SNDRV_PCM_FMTBIT_S24_LE |\
858 SNDRV_PCM_FMTBIT_S32_LE)
860 static struct snd_soc_dai_driver mtk_dai_i2s_driver[] = {
863 .id = MT8183_DAI_I2S_0,
865 .stream_name = "I2S0",
868 .rates = MTK_I2S_RATES,
869 .formats = MTK_I2S_FORMATS,
871 .ops = &mtk_dai_i2s_ops,
875 .id = MT8183_DAI_I2S_1,
877 .stream_name = "I2S1",
880 .rates = MTK_I2S_RATES,
881 .formats = MTK_I2S_FORMATS,
883 .ops = &mtk_dai_i2s_ops,
887 .id = MT8183_DAI_I2S_2,
889 .stream_name = "I2S2",
892 .rates = MTK_I2S_RATES,
893 .formats = MTK_I2S_FORMATS,
895 .ops = &mtk_dai_i2s_ops,
899 .id = MT8183_DAI_I2S_3,
901 .stream_name = "I2S3",
904 .rates = MTK_I2S_RATES,
905 .formats = MTK_I2S_FORMATS,
907 .ops = &mtk_dai_i2s_ops,
911 .id = MT8183_DAI_I2S_5,
913 .stream_name = "I2S5",
916 .rates = MTK_I2S_RATES,
917 .formats = MTK_I2S_FORMATS,
919 .ops = &mtk_dai_i2s_ops,
923 /* this enum is merely for mtk_afe_i2s_priv declare */
933 static const struct mtk_afe_i2s_priv mt8183_i2s_priv[DAI_I2S_NUM] = {
935 .id = MT8183_DAI_I2S_0,
936 .mclk_id = MT8183_I2S0_MCK,
937 .share_property_name = "i2s0-share",
941 .id = MT8183_DAI_I2S_1,
942 .mclk_id = MT8183_I2S1_MCK,
943 .share_property_name = "i2s1-share",
947 .id = MT8183_DAI_I2S_2,
948 .mclk_id = MT8183_I2S2_MCK,
949 .share_property_name = "i2s2-share",
953 .id = MT8183_DAI_I2S_3,
954 .mclk_id = MT8183_I2S3_MCK,
955 .share_property_name = "i2s3-share",
959 .id = MT8183_DAI_I2S_5,
960 .mclk_id = MT8183_I2S5_MCK,
961 .share_property_name = "i2s5-share",
966 static int mt8183_dai_i2s_get_share(struct mtk_base_afe *afe)
968 struct mt8183_afe_private *afe_priv = afe->platform_priv;
969 const struct device_node *of_node = afe->dev->of_node;
971 const char *property_name;
972 struct mtk_afe_i2s_priv *i2s_priv;
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))
980 i2s_priv->share_i2s_id = get_i2s_id_by_name(afe, of_str);
986 static int mt8183_dai_i2s_set_priv(struct mtk_base_afe *afe)
988 struct mt8183_afe_private *afe_priv = afe->platform_priv;
989 struct mtk_afe_i2s_priv *i2s_priv;
992 for (i = 0; i < DAI_I2S_NUM; i++) {
993 i2s_priv = devm_kzalloc(afe->dev,
994 sizeof(struct mtk_afe_i2s_priv),
999 memcpy(i2s_priv, &mt8183_i2s_priv[i],
1000 sizeof(struct mtk_afe_i2s_priv));
1002 afe_priv->dai_priv[mt8183_i2s_priv[i].id] = i2s_priv;
1008 int mt8183_dai_i2s_register(struct mtk_base_afe *afe)
1010 struct mtk_base_afe_dai *dai;
1013 dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL);
1017 list_add(&dai->list, &afe->sub_dais);
1019 dai->dai_drivers = mtk_dai_i2s_driver;
1020 dai->num_dai_drivers = ARRAY_SIZE(mtk_dai_i2s_driver);
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);
1029 /* set all dai i2s private data */
1030 ret = mt8183_dai_i2s_set_priv(afe);
1034 /* parse share i2s */
1035 ret = mt8183_dai_i2s_get_share(afe);