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
;
56 static unsigned int get_i2s_wlen(snd_pcm_format_t format
)
58 return snd_pcm_format_physical_width(format
) <= 16 ?
59 I2S_WLEN_16_BIT
: I2S_WLEN_32_BIT
;
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"
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"
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"
80 static int get_i2s_id_by_name(struct mtk_base_afe
*afe
,
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
;
97 static struct mtk_afe_i2s_priv
*get_i2s_priv_by_name(struct mtk_base_afe
*afe
,
100 struct mt8183_afe_private
*afe_priv
= afe
->platform_priv
;
101 int dai_id
= get_i2s_id_by_name(afe
, name
);
106 return afe_priv
->dai_priv
[dai_id
];
109 /* low jitter control */
110 static const char * const mt8183_i2s_hd_str
[] = {
111 "Normal", "Low_Jitter"
114 static const struct soc_enum mt8183_i2s_enum
[] = {
115 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(mt8183_i2s_hd_str
),
119 static int mt8183_i2s_hd_get(struct snd_kcontrol
*kcontrol
,
120 struct snd_ctl_elem_value
*ucontrol
)
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
;
126 i2s_priv
= get_i2s_priv_by_name(afe
, kcontrol
->id
.name
);
129 dev_warn(afe
->dev
, "%s(), i2s_priv == NULL", __func__
);
133 ucontrol
->value
.integer
.value
[0] = i2s_priv
->low_jitter_en
;
138 static int mt8183_i2s_hd_set(struct snd_kcontrol
*kcontrol
,
139 struct snd_ctl_elem_value
*ucontrol
)
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
;
147 if (ucontrol
->value
.enumerated
.item
[0] >= e
->items
)
150 hd_en
= ucontrol
->value
.integer
.value
[0];
152 dev_info(afe
->dev
, "%s(), kcontrol name %s, hd_en %d\n",
153 __func__
, kcontrol
->id
.name
, hd_en
);
155 i2s_priv
= get_i2s_priv_by_name(afe
, kcontrol
->id
.name
);
158 dev_warn(afe
->dev
, "%s(), i2s_priv == NULL", __func__
);
162 i2s_priv
->low_jitter_en
= hd_en
;
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
),
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),
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),
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),
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),
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),
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),
268 SUPPLY_SEQ_I2S_MCLK_EN
,
269 SUPPLY_SEQ_I2S_HD_EN
,
273 static int mtk_apll_event(struct snd_soc_dapm_widget
*w
,
274 struct snd_kcontrol
*kcontrol
,
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
);
280 dev_info(cmpnt
->dev
, "%s(), name %s, event 0x%x\n",
281 __func__
, w
->name
, event
);
284 case SND_SOC_DAPM_PRE_PMU
:
285 if (strcmp(w
->name
, APLL1_W_NAME
) == 0)
286 mt8183_apll1_enable(afe
);
288 mt8183_apll2_enable(afe
);
290 case SND_SOC_DAPM_POST_PMD
:
291 if (strcmp(w
->name
, APLL1_W_NAME
) == 0)
292 mt8183_apll1_disable(afe
);
294 mt8183_apll2_disable(afe
);
303 static int mtk_mclk_en_event(struct snd_soc_dapm_widget
*w
,
304 struct snd_kcontrol
*kcontrol
,
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
;
311 dev_info(cmpnt
->dev
, "%s(), name %s, event 0x%x\n",
312 __func__
, w
->name
, event
);
314 i2s_priv
= get_i2s_priv_by_name(afe
, w
->name
);
317 dev_warn(afe
->dev
, "%s(), i2s_priv == NULL", __func__
);
322 case SND_SOC_DAPM_PRE_PMU
:
323 mt8183_mck_enable(afe
, i2s_priv
->mclk_id
, i2s_priv
->mclk_rate
);
325 case SND_SOC_DAPM_POST_PMD
:
326 i2s_priv
->mclk_rate
= 0;
327 mt8183_mck_disable(afe
, i2s_priv
->mclk_id
);
336 static const struct snd_soc_dapm_widget mtk_dai_i2s_widgets
[] = {
337 SND_SOC_DAPM_MIXER("I2S1_CH1", SND_SOC_NOPM
, 0, 0,
339 ARRAY_SIZE(mtk_i2s1_ch1_mix
)),
340 SND_SOC_DAPM_MIXER("I2S1_CH2", SND_SOC_NOPM
, 0, 0,
342 ARRAY_SIZE(mtk_i2s1_ch2_mix
)),
344 SND_SOC_DAPM_MIXER("I2S3_CH1", SND_SOC_NOPM
, 0, 0,
346 ARRAY_SIZE(mtk_i2s3_ch1_mix
)),
347 SND_SOC_DAPM_MIXER("I2S3_CH2", SND_SOC_NOPM
, 0, 0,
349 ARRAY_SIZE(mtk_i2s3_ch2_mix
)),
351 SND_SOC_DAPM_MIXER("I2S5_CH1", SND_SOC_NOPM
, 0, 0,
353 ARRAY_SIZE(mtk_i2s5_ch1_mix
)),
354 SND_SOC_DAPM_MIXER("I2S5_CH2", SND_SOC_NOPM
, 0, 0,
356 ARRAY_SIZE(mtk_i2s5_ch2_mix
)),
359 SND_SOC_DAPM_SUPPLY_S("I2S0_EN", SUPPLY_SEQ_I2S_EN
,
360 AFE_I2S_CON
, I2S_EN_SFT
, 0,
362 SND_SOC_DAPM_SUPPLY_S("I2S1_EN", SUPPLY_SEQ_I2S_EN
,
363 AFE_I2S_CON1
, I2S_EN_SFT
, 0,
365 SND_SOC_DAPM_SUPPLY_S("I2S2_EN", SUPPLY_SEQ_I2S_EN
,
366 AFE_I2S_CON2
, I2S_EN_SFT
, 0,
368 SND_SOC_DAPM_SUPPLY_S("I2S3_EN", SUPPLY_SEQ_I2S_EN
,
369 AFE_I2S_CON3
, I2S_EN_SFT
, 0,
371 SND_SOC_DAPM_SUPPLY_S("I2S5_EN", SUPPLY_SEQ_I2S_EN
,
372 AFE_I2S_CON4
, I2S5_EN_SFT
, 0,
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,
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,
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,
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,
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,
392 SND_SOC_DAPM_SUPPLY_S(I2S0_MCLK_EN_W_NAME
, SUPPLY_SEQ_I2S_MCLK_EN
,
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
,
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
,
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
,
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
,
411 SND_SOC_DAPM_PRE_PMU
| SND_SOC_DAPM_POST_PMD
),
414 SND_SOC_DAPM_SUPPLY_S(APLL1_W_NAME
, SUPPLY_SEQ_APLL
,
417 SND_SOC_DAPM_PRE_PMU
| SND_SOC_DAPM_POST_PMD
),
418 SND_SOC_DAPM_SUPPLY_S(APLL2_W_NAME
, SUPPLY_SEQ_APLL
,
421 SND_SOC_DAPM_PRE_PMU
| SND_SOC_DAPM_POST_PMD
),
424 static int mtk_afe_i2s_share_connect(struct snd_soc_dapm_widget
*source
,
425 struct snd_soc_dapm_widget
*sink
)
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
;
432 i2s_priv
= get_i2s_priv_by_name(afe
, sink
->name
);
435 dev_warn(afe
->dev
, "%s(), i2s_priv == NULL", __func__
);
439 if (i2s_priv
->share_i2s_id
< 0)
442 return i2s_priv
->share_i2s_id
== get_i2s_id_by_name(afe
, source
->name
);
445 static int mtk_afe_i2s_hd_connect(struct snd_soc_dapm_widget
*source
,
446 struct snd_soc_dapm_widget
*sink
)
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
;
453 i2s_priv
= get_i2s_priv_by_name(afe
, sink
->name
);
456 dev_warn(afe
->dev
, "%s(), i2s_priv == NULL", __func__
);
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
;
464 /* check if share i2s need hd en */
465 if (i2s_priv
->share_i2s_id
< 0)
468 if (i2s_priv
->share_i2s_id
== get_i2s_id_by_name(afe
, source
->name
))
469 return i2s_priv
->low_jitter_en
;
474 static int mtk_afe_i2s_apll_connect(struct snd_soc_dapm_widget
*source
,
475 struct snd_soc_dapm_widget
*sink
)
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
;
484 i2s_priv
= get_i2s_priv_by_name(afe
, w
->name
);
487 dev_warn(afe
->dev
, "%s(), i2s_priv == NULL", __func__
);
492 cur_apll
= mt8183_get_apll_by_name(afe
, source
->name
);
494 /* choose APLL from i2s rate */
495 i2s_need_apll
= mt8183_get_apll_by_rate(afe
, i2s_priv
->rate
);
497 return (i2s_need_apll
== cur_apll
) ? 1 : 0;
500 static int mtk_afe_i2s_mclk_connect(struct snd_soc_dapm_widget
*source
,
501 struct snd_soc_dapm_widget
*sink
)
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
;
508 i2s_priv
= get_i2s_priv_by_name(afe
, sink
->name
);
511 dev_warn(afe
->dev
, "%s(), i2s_priv == NULL", __func__
);
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;
519 /* check if share i2s need mclk */
520 if (i2s_priv
->share_i2s_id
< 0)
523 if (i2s_priv
->share_i2s_id
== get_i2s_id_by_name(afe
, source
->name
))
524 return (i2s_priv
->mclk_rate
> 0) ? 1 : 0;
529 static int mtk_afe_mclk_apll_connect(struct snd_soc_dapm_widget
*source
,
530 struct snd_soc_dapm_widget
*sink
)
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
;
538 i2s_priv
= get_i2s_priv_by_name(afe
, w
->name
);
541 dev_warn(afe
->dev
, "%s(), i2s_priv == NULL", __func__
);
546 cur_apll
= mt8183_get_apll_by_name(afe
, source
->name
);
548 return (i2s_priv
->mclk_apll
== cur_apll
) ? 1 : 0;
551 static const struct snd_soc_dapm_route mtk_dai_i2s_routes
[] = {
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
},
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
},
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
},
576 {"I2S1_CH1", "DL1_CH1", "DL1"},
577 {"I2S1_CH2", "DL1_CH2", "DL1"},
579 {"I2S1_CH1", "DL2_CH1", "DL2"},
580 {"I2S1_CH2", "DL2_CH2", "DL2"},
582 {"I2S1_CH1", "DL3_CH1", "DL3"},
583 {"I2S1_CH2", "DL3_CH2", "DL3"},
585 {"I2S1", NULL
, "I2S1_CH1"},
586 {"I2S1", NULL
, "I2S1_CH2"},
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
},
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
},
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
},
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
},
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
},
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
},
634 {"I2S3_CH1", "DL1_CH1", "DL1"},
635 {"I2S3_CH2", "DL1_CH2", "DL1"},
637 {"I2S3_CH1", "DL2_CH1", "DL2"},
638 {"I2S3_CH2", "DL2_CH2", "DL2"},
640 {"I2S3_CH1", "DL3_CH1", "DL3"},
641 {"I2S3_CH2", "DL3_CH2", "DL3"},
643 {"I2S3", NULL
, "I2S3_CH1"},
644 {"I2S3", NULL
, "I2S3_CH2"},
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
},
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
},
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
},
669 {"I2S5_CH1", "DL1_CH1", "DL1"},
670 {"I2S5_CH2", "DL1_CH2", "DL1"},
672 {"I2S5_CH1", "DL2_CH1", "DL2"},
673 {"I2S5_CH2", "DL2_CH2", "DL2"},
675 {"I2S5_CH1", "DL3_CH1", "DL3"},
676 {"I2S5_CH2", "DL3_CH2", "DL3"},
678 {"I2S5", NULL
, "I2S5_CH1"},
679 {"I2S5", NULL
, "I2S5_CH2"},
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"},
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
},
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
},
705 static int mtk_dai_i2s_config(struct mtk_base_afe
*afe
,
706 struct snd_pcm_hw_params
*params
,
709 struct mt8183_afe_private
*afe_priv
= afe
->platform_priv
;
710 struct mtk_afe_i2s_priv
*i2s_priv
= afe_priv
->dai_priv
[i2s_id
];
712 unsigned int rate
= params_rate(params
);
713 unsigned int rate_reg
= mt8183_rate_transform(afe
->dev
,
715 snd_pcm_format_t format
= params_format(params
);
716 unsigned int i2s_con
= 0, fmt_con
= I2S_FMT_I2S
<< I2S_FMT_SFT
;
719 dev_info(afe
->dev
, "%s(), id %d, rate %d, format %d\n",
725 i2s_priv
->rate
= rate
;
727 if (i2s_priv
->use_eiaj
)
728 fmt_con
= I2S_FMT_EIAJ
<< I2S_FMT_SFT
;
730 dev_warn(afe
->dev
, "%s(), i2s_priv == NULL", __func__
);
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
;
739 i2s_con
|= get_i2s_wlen(format
) << I2S_WLEN_SFT
;
740 regmap_update_bits(afe
->regmap
, AFE_I2S_CON
,
741 0xffffeffe, i2s_con
);
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
;
747 i2s_con
|= get_i2s_wlen(format
) << I2S2_WLEN_SFT
;
748 regmap_update_bits(afe
->regmap
, AFE_I2S_CON1
,
749 0xffffeffe, i2s_con
);
751 case MT8183_DAI_I2S_2
:
752 i2s_con
= 8 << I2S3_UPDATE_WORD_SFT
;
753 i2s_con
|= rate_reg
<< I2S3_OUT_MODE_SFT
;
755 i2s_con
|= get_i2s_wlen(format
) << I2S3_WLEN_SFT
;
756 regmap_update_bits(afe
->regmap
, AFE_I2S_CON2
,
757 0xffffeffe, i2s_con
);
759 case MT8183_DAI_I2S_3
:
760 i2s_con
= rate_reg
<< I2S4_OUT_MODE_SFT
;
762 i2s_con
|= get_i2s_wlen(format
) << I2S4_WLEN_SFT
;
763 regmap_update_bits(afe
->regmap
, AFE_I2S_CON3
,
764 0xffffeffe, i2s_con
);
766 case MT8183_DAI_I2S_5
:
767 i2s_con
= rate_reg
<< I2S5_OUT_MODE_SFT
;
769 i2s_con
|= get_i2s_wlen(format
) << I2S5_WLEN_SFT
;
770 regmap_update_bits(afe
->regmap
, AFE_I2S_CON4
,
771 0xffffeffe, i2s_con
);
774 dev_warn(afe
->dev
, "%s(), id %d not support\n",
780 if (i2s_priv
&& i2s_priv
->share_i2s_id
>= 0)
781 ret
= mtk_dai_i2s_config(afe
, params
, i2s_priv
->share_i2s_id
);
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
)
790 struct mtk_base_afe
*afe
= snd_soc_dai_get_drvdata(dai
);
792 return mtk_dai_i2s_config(afe
, params
, dai
->id
);
795 static int mtk_dai_i2s_set_sysclk(struct snd_soc_dai
*dai
,
796 int clk_id
, unsigned int freq
, int dir
)
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
];
805 dev_warn(afe
->dev
, "%s(), i2s_priv == NULL", __func__
);
809 if (dir
!= SND_SOC_CLOCK_OUT
) {
810 dev_warn(afe
->dev
, "%s(), dir != SND_SOC_CLOCK_OUT", __func__
);
814 dev_info(afe
->dev
, "%s(), freq %d\n", __func__
, freq
);
816 apll
= mt8183_get_apll_by_rate(afe
, freq
);
817 apll_rate
= mt8183_get_apll_rate(afe
, apll
);
819 if (freq
> apll_rate
) {
820 dev_warn(afe
->dev
, "%s(), freq > apll rate", __func__
);
824 if (apll_rate
% freq
!= 0) {
825 dev_warn(afe
->dev
, "%s(), APLL cannot generate freq Hz",
830 i2s_priv
->mclk_rate
= freq
;
831 i2s_priv
->mclk_apll
= apll
;
833 if (i2s_priv
->share_i2s_id
> 0) {
834 struct mtk_afe_i2s_priv
*share_i2s_priv
;
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",
843 share_i2s_priv
->mclk_rate
= i2s_priv
->mclk_rate
;
844 share_i2s_priv
->mclk_apll
= i2s_priv
->mclk_apll
;
850 static int mtk_dai_i2s_set_fmt(struct snd_soc_dai
*dai
, unsigned int fmt
)
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
;
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
:
864 dev_warn(afe
->dev
, "%s(), id %d not support\n",
868 i2s_priv
= afe_priv
->dai_priv
[dai
->id
];
870 switch (fmt
& SND_SOC_DAIFMT_FORMAT_MASK
) {
871 case SND_SOC_DAIFMT_LEFT_J
:
872 i2s_priv
->use_eiaj
= 1;
874 case SND_SOC_DAIFMT_I2S
:
875 i2s_priv
->use_eiaj
= 0;
878 dev_warn(afe
->dev
, "%s(), DAI format %d not support\n",
879 __func__
, fmt
& SND_SOC_DAIFMT_FORMAT_MASK
);
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
,
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)
899 #define MTK_I2S_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
900 SNDRV_PCM_FMTBIT_S24_LE |\
901 SNDRV_PCM_FMTBIT_S32_LE)
903 static struct snd_soc_dai_driver mtk_dai_i2s_driver
[] = {
906 .id
= MT8183_DAI_I2S_0
,
908 .stream_name
= "I2S0",
911 .rates
= MTK_I2S_RATES
,
912 .formats
= MTK_I2S_FORMATS
,
914 .ops
= &mtk_dai_i2s_ops
,
918 .id
= MT8183_DAI_I2S_1
,
920 .stream_name
= "I2S1",
923 .rates
= MTK_I2S_RATES
,
924 .formats
= MTK_I2S_FORMATS
,
926 .ops
= &mtk_dai_i2s_ops
,
930 .id
= MT8183_DAI_I2S_2
,
932 .stream_name
= "I2S2",
935 .rates
= MTK_I2S_RATES
,
936 .formats
= MTK_I2S_FORMATS
,
938 .ops
= &mtk_dai_i2s_ops
,
942 .id
= MT8183_DAI_I2S_3
,
944 .stream_name
= "I2S3",
947 .rates
= MTK_I2S_RATES
,
948 .formats
= MTK_I2S_FORMATS
,
950 .ops
= &mtk_dai_i2s_ops
,
954 .id
= MT8183_DAI_I2S_5
,
956 .stream_name
= "I2S5",
959 .rates
= MTK_I2S_RATES
,
960 .formats
= MTK_I2S_FORMATS
,
962 .ops
= &mtk_dai_i2s_ops
,
966 /* this enum is merely for mtk_afe_i2s_priv declare */
976 static const struct mtk_afe_i2s_priv mt8183_i2s_priv
[DAI_I2S_NUM
] = {
978 .id
= MT8183_DAI_I2S_0
,
979 .mclk_id
= MT8183_I2S0_MCK
,
980 .share_property_name
= "i2s0-share",
984 .id
= MT8183_DAI_I2S_1
,
985 .mclk_id
= MT8183_I2S1_MCK
,
986 .share_property_name
= "i2s1-share",
990 .id
= MT8183_DAI_I2S_2
,
991 .mclk_id
= MT8183_I2S2_MCK
,
992 .share_property_name
= "i2s2-share",
996 .id
= MT8183_DAI_I2S_3
,
997 .mclk_id
= MT8183_I2S3_MCK
,
998 .share_property_name
= "i2s3-share",
1002 .id
= MT8183_DAI_I2S_5
,
1003 .mclk_id
= MT8183_I2S5_MCK
,
1004 .share_property_name
= "i2s5-share",
1009 static int mt8183_dai_i2s_get_share(struct mtk_base_afe
*afe
)
1011 struct mt8183_afe_private
*afe_priv
= afe
->platform_priv
;
1012 const struct device_node
*of_node
= afe
->dev
->of_node
;
1014 const char *property_name
;
1015 struct mtk_afe_i2s_priv
*i2s_priv
;
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
))
1023 i2s_priv
->share_i2s_id
= get_i2s_id_by_name(afe
, of_str
);
1029 static int mt8183_dai_i2s_set_priv(struct mtk_base_afe
*afe
)
1031 struct mt8183_afe_private
*afe_priv
= afe
->platform_priv
;
1032 struct mtk_afe_i2s_priv
*i2s_priv
;
1035 for (i
= 0; i
< DAI_I2S_NUM
; i
++) {
1036 i2s_priv
= devm_kzalloc(afe
->dev
,
1037 sizeof(struct mtk_afe_i2s_priv
),
1042 memcpy(i2s_priv
, &mt8183_i2s_priv
[i
],
1043 sizeof(struct mtk_afe_i2s_priv
));
1045 afe_priv
->dai_priv
[mt8183_i2s_priv
[i
].id
] = i2s_priv
;
1051 int mt8183_dai_i2s_register(struct mtk_base_afe
*afe
)
1053 struct mtk_base_afe_dai
*dai
;
1056 dai
= devm_kzalloc(afe
->dev
, sizeof(*dai
), GFP_KERNEL
);
1060 list_add(&dai
->list
, &afe
->sub_dais
);
1062 dai
->dai_drivers
= mtk_dai_i2s_driver
;
1063 dai
->num_dai_drivers
= ARRAY_SIZE(mtk_dai_i2s_driver
);
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
);
1072 /* set all dai i2s private data */
1073 ret
= mt8183_dai_i2s_set_priv(afe
);
1077 /* parse share i2s */
1078 ret
= mt8183_dai_i2s_get_share(afe
);