~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/sound/soc/mediatek/mt8186/mt8186-dai-i2s.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0
  2 //
  3 // MediaTek ALSA SoC Audio DAI I2S Control
  4 //
  5 // Copyright (c) 2022 MediaTek Inc.
  6 // Author: Jiaxin Yu <jiaxin.yu@mediatek.com>
  7 
  8 #include <linux/bitops.h>
  9 #include <linux/regmap.h>
 10 #include <sound/pcm_params.h>
 11 #include "mt8186-afe-clk.h"
 12 #include "mt8186-afe-common.h"
 13 #include "mt8186-afe-gpio.h"
 14 #include "mt8186-interconnection.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         int master; /* only i2s0 has slave mode*/
 46 
 47         int share_i2s_id;
 48 
 49         int mclk_id;
 50         int mclk_rate;
 51         int mclk_apll;
 52 };
 53 
 54 static unsigned int get_i2s_wlen(snd_pcm_format_t format)
 55 {
 56         return snd_pcm_format_physical_width(format) <= 16 ?
 57                I2S_WLEN_16_BIT : I2S_WLEN_32_BIT;
 58 }
 59 
 60 #define MTK_AFE_I2S0_KCONTROL_NAME "I2S0_HD_Mux"
 61 #define MTK_AFE_I2S1_KCONTROL_NAME "I2S1_HD_Mux"
 62 #define MTK_AFE_I2S2_KCONTROL_NAME "I2S2_HD_Mux"
 63 #define MTK_AFE_I2S3_KCONTROL_NAME "I2S3_HD_Mux"
 64 #define MTK_AFE_I2S0_SRC_KCONTROL_NAME "I2S0_SRC_Mux"
 65 
 66 #define I2S0_HD_EN_W_NAME "I2S0_HD_EN"
 67 #define I2S1_HD_EN_W_NAME "I2S1_HD_EN"
 68 #define I2S2_HD_EN_W_NAME "I2S2_HD_EN"
 69 #define I2S3_HD_EN_W_NAME "I2S3_HD_EN"
 70 
 71 #define I2S0_MCLK_EN_W_NAME "I2S0_MCLK_EN"
 72 #define I2S1_MCLK_EN_W_NAME "I2S1_MCLK_EN"
 73 #define I2S2_MCLK_EN_W_NAME "I2S2_MCLK_EN"
 74 #define I2S3_MCLK_EN_W_NAME "I2S3_MCLK_EN"
 75 
 76 static int get_i2s_id_by_name(struct mtk_base_afe *afe,
 77                               const char *name)
 78 {
 79         if (strncmp(name, "I2S0", 4) == 0)
 80                 return MT8186_DAI_I2S_0;
 81         else if (strncmp(name, "I2S1", 4) == 0)
 82                 return MT8186_DAI_I2S_1;
 83         else if (strncmp(name, "I2S2", 4) == 0)
 84                 return MT8186_DAI_I2S_2;
 85         else if (strncmp(name, "I2S3", 4) == 0)
 86                 return MT8186_DAI_I2S_3;
 87 
 88         return -EINVAL;
 89 }
 90 
 91 static struct mtk_afe_i2s_priv *get_i2s_priv_by_name(struct mtk_base_afe *afe,
 92                                                      const char *name)
 93 {
 94         struct mt8186_afe_private *afe_priv = afe->platform_priv;
 95         int dai_id = get_i2s_id_by_name(afe, name);
 96 
 97         if (dai_id < 0)
 98                 return NULL;
 99 
100         return afe_priv->dai_priv[dai_id];
101 }
102 
103 /* low jitter control */
104 static const char * const mt8186_i2s_hd_str[] = {
105         "Normal", "Low_Jitter"
106 };
107 
108 static const struct soc_enum mt8186_i2s_enum[] = {
109         SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(mt8186_i2s_hd_str),
110                             mt8186_i2s_hd_str),
111 };
112 
113 static int mt8186_i2s_hd_get(struct snd_kcontrol *kcontrol,
114                              struct snd_ctl_elem_value *ucontrol)
115 {
116         struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
117         struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
118         struct mtk_afe_i2s_priv *i2s_priv;
119 
120         i2s_priv = get_i2s_priv_by_name(afe, kcontrol->id.name);
121         ucontrol->value.integer.value[0] = i2s_priv->low_jitter_en;
122 
123         return 0;
124 }
125 
126 static int mt8186_i2s_hd_set(struct snd_kcontrol *kcontrol,
127                              struct snd_ctl_elem_value *ucontrol)
128 {
129         struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
130         struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
131         struct mtk_afe_i2s_priv *i2s_priv;
132         struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
133         int hd_en;
134 
135         if (ucontrol->value.enumerated.item[0] >= e->items)
136                 return -EINVAL;
137 
138         hd_en = ucontrol->value.integer.value[0];
139 
140         dev_dbg(afe->dev, "%s(), kcontrol name %s, hd_en %d\n",
141                 __func__, kcontrol->id.name, hd_en);
142 
143         i2s_priv = get_i2s_priv_by_name(afe, kcontrol->id.name);
144         if (i2s_priv->low_jitter_en == hd_en)
145                 return 0;
146 
147         i2s_priv->low_jitter_en = hd_en;
148 
149         return 1;
150 }
151 
152 static const struct snd_kcontrol_new mtk_dai_i2s_controls[] = {
153         SOC_ENUM_EXT(MTK_AFE_I2S0_KCONTROL_NAME, mt8186_i2s_enum[0],
154                      mt8186_i2s_hd_get, mt8186_i2s_hd_set),
155         SOC_ENUM_EXT(MTK_AFE_I2S1_KCONTROL_NAME, mt8186_i2s_enum[0],
156                      mt8186_i2s_hd_get, mt8186_i2s_hd_set),
157         SOC_ENUM_EXT(MTK_AFE_I2S2_KCONTROL_NAME, mt8186_i2s_enum[0],
158                      mt8186_i2s_hd_get, mt8186_i2s_hd_set),
159         SOC_ENUM_EXT(MTK_AFE_I2S3_KCONTROL_NAME, mt8186_i2s_enum[0],
160                      mt8186_i2s_hd_get, mt8186_i2s_hd_set),
161 };
162 
163 /* dai component */
164 /* i2s virtual mux to output widget */
165 static const char * const i2s_mux_map[] = {
166         "Normal", "Dummy_Widget",
167 };
168 
169 static int i2s_mux_map_value[] = {
170         0, 1,
171 };
172 
173 static SOC_VALUE_ENUM_SINGLE_AUTODISABLE_DECL(i2s_mux_map_enum,
174                                               SND_SOC_NOPM,
175                                               0,
176                                               1,
177                                               i2s_mux_map,
178                                               i2s_mux_map_value);
179 
180 static const struct snd_kcontrol_new i2s0_in_mux_control =
181         SOC_DAPM_ENUM("I2S0 In Select", i2s_mux_map_enum);
182 
183 static const struct snd_kcontrol_new i2s1_out_mux_control =
184         SOC_DAPM_ENUM("I2S1 Out Select", i2s_mux_map_enum);
185 
186 static const struct snd_kcontrol_new i2s2_in_mux_control =
187         SOC_DAPM_ENUM("I2S2 In Select", i2s_mux_map_enum);
188 
189 static const struct snd_kcontrol_new i2s3_out_mux_control =
190         SOC_DAPM_ENUM("I2S3 Out Select", i2s_mux_map_enum);
191 
192 /* i2s in lpbk */
193 static const char * const i2s_lpbk_mux_map[] = {
194         "Normal", "Lpbk",
195 };
196 
197 static int i2s_lpbk_mux_map_value[] = {
198         0, 1,
199 };
200 
201 static SOC_VALUE_ENUM_SINGLE_AUTODISABLE_DECL(i2s0_lpbk_mux_map_enum,
202                                               AFE_I2S_CON,
203                                               I2S_LOOPBACK_SFT,
204                                               1,
205                                               i2s_lpbk_mux_map,
206                                               i2s_lpbk_mux_map_value);
207 
208 static const struct snd_kcontrol_new i2s0_lpbk_mux_control =
209         SOC_DAPM_ENUM("I2S Lpbk Select", i2s0_lpbk_mux_map_enum);
210 
211 static SOC_VALUE_ENUM_SINGLE_AUTODISABLE_DECL(i2s2_lpbk_mux_map_enum,
212                                               AFE_I2S_CON2,
213                                               I2S3_LOOPBACK_SFT,
214                                               1,
215                                               i2s_lpbk_mux_map,
216                                               i2s_lpbk_mux_map_value);
217 
218 static const struct snd_kcontrol_new i2s2_lpbk_mux_control =
219         SOC_DAPM_ENUM("I2S Lpbk Select", i2s2_lpbk_mux_map_enum);
220 
221 /* interconnection */
222 static const struct snd_kcontrol_new mtk_i2s3_ch1_mix[] = {
223         SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1 Switch", AFE_CONN0,
224                                     I_DL1_CH1, 1, 0),
225         SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1 Switch", AFE_CONN0,
226                                     I_DL2_CH1, 1, 0),
227         SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1 Switch", AFE_CONN0,
228                                     I_DL3_CH1, 1, 0),
229         SOC_DAPM_SINGLE_AUTODISABLE("DL12_CH1 Switch", AFE_CONN0,
230                                     I_DL12_CH1, 1, 0),
231         SOC_DAPM_SINGLE_AUTODISABLE("DL12_CH3 Switch", AFE_CONN0,
232                                     I_DL12_CH3, 1, 0),
233         SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH1 Switch", AFE_CONN0_1,
234                                     I_DL6_CH1, 1, 0),
235         SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH1 Switch", AFE_CONN0_1,
236                                     I_DL4_CH1, 1, 0),
237         SOC_DAPM_SINGLE_AUTODISABLE("DL5_CH1 Switch", AFE_CONN0_1,
238                                     I_DL5_CH1, 1, 0),
239         SOC_DAPM_SINGLE_AUTODISABLE("DL8_CH1 Switch", AFE_CONN0_1,
240                                     I_DL8_CH1, 1, 0),
241         SOC_DAPM_SINGLE_AUTODISABLE("GAIN1_OUT_CH1 Switch", AFE_CONN0,
242                                     I_GAIN1_OUT_CH1, 1, 0),
243         SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1 Switch", AFE_CONN0,
244                                     I_ADDA_UL_CH1, 1, 0),
245         SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2 Switch", AFE_CONN0,
246                                     I_ADDA_UL_CH2, 1, 0),
247         SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3 Switch", AFE_CONN0,
248                                     I_ADDA_UL_CH3, 1, 0),
249         SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH1 Switch", AFE_CONN0,
250                                     I_PCM_1_CAP_CH1, 1, 0),
251         SOC_DAPM_SINGLE_AUTODISABLE("SRC_1_OUT_CH1 Switch", AFE_CONN0_1,
252                                     I_SRC_1_OUT_CH1, 1, 0),
253 };
254 
255 static const struct snd_kcontrol_new mtk_i2s3_ch2_mix[] = {
256         SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH2 Switch", AFE_CONN1,
257                                     I_DL1_CH2, 1, 0),
258         SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH2 Switch", AFE_CONN1,
259                                     I_DL2_CH2, 1, 0),
260         SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH2 Switch", AFE_CONN1,
261                                     I_DL3_CH2, 1, 0),
262         SOC_DAPM_SINGLE_AUTODISABLE("DL12_CH2 Switch", AFE_CONN1,
263                                     I_DL12_CH2, 1, 0),
264         SOC_DAPM_SINGLE_AUTODISABLE("DL12_CH4 Switch", AFE_CONN1,
265                                     I_DL12_CH4, 1, 0),
266         SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH2 Switch", AFE_CONN1_1,
267                                     I_DL6_CH2, 1, 0),
268         SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH2 Switch", AFE_CONN1_1,
269                                     I_DL4_CH2, 1, 0),
270         SOC_DAPM_SINGLE_AUTODISABLE("DL5_CH2 Switch", AFE_CONN1_1,
271                                     I_DL5_CH2, 1, 0),
272         SOC_DAPM_SINGLE_AUTODISABLE("DL8_CH2 Switch", AFE_CONN1_1,
273                                     I_DL8_CH2, 1, 0),
274         SOC_DAPM_SINGLE_AUTODISABLE("GAIN1_OUT_CH2 Switch", AFE_CONN1,
275                                     I_GAIN1_OUT_CH2, 1, 0),
276         SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1 Switch", AFE_CONN1,
277                                     I_ADDA_UL_CH1, 1, 0),
278         SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2 Switch", AFE_CONN1,
279                                     I_ADDA_UL_CH2, 1, 0),
280         SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3 Switch", AFE_CONN1,
281                                     I_ADDA_UL_CH3, 1, 0),
282         SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH2 Switch", AFE_CONN1,
283                                     I_PCM_1_CAP_CH2, 1, 0),
284         SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH2 Switch", AFE_CONN1,
285                                     I_PCM_2_CAP_CH2, 1, 0),
286         SOC_DAPM_SINGLE_AUTODISABLE("SRC_1_OUT_CH2 Switch", AFE_CONN1_1,
287                                     I_SRC_1_OUT_CH2, 1, 0),
288 };
289 
290 static const struct snd_kcontrol_new mtk_i2s1_ch1_mix[] = {
291         SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1 Switch", AFE_CONN28,
292                                     I_DL1_CH1, 1, 0),
293         SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1 Switch", AFE_CONN28,
294                                     I_DL2_CH1, 1, 0),
295         SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1 Switch", AFE_CONN28,
296                                     I_DL3_CH1, 1, 0),
297         SOC_DAPM_SINGLE_AUTODISABLE("DL12_CH1 Switch", AFE_CONN28,
298                                     I_DL12_CH1, 1, 0),
299         SOC_DAPM_SINGLE_AUTODISABLE("DL12_CH3 Switch", AFE_CONN28,
300                                     I_DL12_CH3, 1, 0),
301         SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH1 Switch", AFE_CONN28_1,
302                                     I_DL6_CH1, 1, 0),
303         SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH1 Switch", AFE_CONN28_1,
304                                     I_DL4_CH1, 1, 0),
305         SOC_DAPM_SINGLE_AUTODISABLE("DL5_CH1 Switch", AFE_CONN28_1,
306                                     I_DL5_CH1, 1, 0),
307         SOC_DAPM_SINGLE_AUTODISABLE("DL8_CH1 Switch", AFE_CONN28_1,
308                                     I_DL8_CH1, 1, 0),
309         SOC_DAPM_SINGLE_AUTODISABLE("GAIN1_OUT_CH1 Switch", AFE_CONN28,
310                                     I_GAIN1_OUT_CH1, 1, 0),
311         SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1 Switch", AFE_CONN28,
312                                     I_ADDA_UL_CH1, 1, 0),
313         SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH1 Switch", AFE_CONN28,
314                                     I_PCM_1_CAP_CH1, 1, 0),
315         SOC_DAPM_SINGLE_AUTODISABLE("SRC_1_OUT_CH1 Switch", AFE_CONN28_1,
316                                     I_SRC_1_OUT_CH1, 1, 0),
317 };
318 
319 static const struct snd_kcontrol_new mtk_i2s1_ch2_mix[] = {
320         SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH2 Switch", AFE_CONN29,
321                                     I_DL1_CH2, 1, 0),
322         SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH2 Switch", AFE_CONN29,
323                                     I_DL2_CH2, 1, 0),
324         SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH2 Switch", AFE_CONN29,
325                                     I_DL3_CH2, 1, 0),
326         SOC_DAPM_SINGLE_AUTODISABLE("DL12_CH2 Switch", AFE_CONN29,
327                                     I_DL12_CH2, 1, 0),
328         SOC_DAPM_SINGLE_AUTODISABLE("DL12_CH4 Switch", AFE_CONN29,
329                                     I_DL12_CH4, 1, 0),
330         SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH2 Switch", AFE_CONN29_1,
331                                     I_DL6_CH2, 1, 0),
332         SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH2 Switch", AFE_CONN29_1,
333                                     I_DL4_CH2, 1, 0),
334         SOC_DAPM_SINGLE_AUTODISABLE("DL5_CH2 Switch", AFE_CONN29_1,
335                                     I_DL5_CH2, 1, 0),
336         SOC_DAPM_SINGLE_AUTODISABLE("DL8_CH2 Switch", AFE_CONN29_1,
337                                     I_DL8_CH2, 1, 0),
338         SOC_DAPM_SINGLE_AUTODISABLE("GAIN1_OUT_CH2 Switch", AFE_CONN29,
339                                     I_GAIN1_OUT_CH2, 1, 0),
340         SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2 Switch", AFE_CONN29,
341                                     I_ADDA_UL_CH2, 1, 0),
342         SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH2 Switch", AFE_CONN29,
343                                     I_PCM_1_CAP_CH2, 1, 0),
344         SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH2 Switch", AFE_CONN29,
345                                     I_PCM_2_CAP_CH2, 1, 0),
346         SOC_DAPM_SINGLE_AUTODISABLE("SRC_1_OUT_CH2 Switch", AFE_CONN29_1,
347                                     I_SRC_1_OUT_CH2, 1, 0),
348 };
349 
350 enum {
351         SUPPLY_SEQ_APLL,
352         SUPPLY_SEQ_I2S_MCLK_EN,
353         SUPPLY_SEQ_I2S_HD_EN,
354         SUPPLY_SEQ_I2S_EN,
355 };
356 
357 static int mtk_i2s_en_event(struct snd_soc_dapm_widget *w,
358                             struct snd_kcontrol *kcontrol,
359                             int event)
360 {
361         struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
362         struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
363         struct mtk_afe_i2s_priv *i2s_priv;
364 
365         i2s_priv = get_i2s_priv_by_name(afe, w->name);
366 
367         dev_dbg(cmpnt->dev, "%s(), name %s, event 0x%x\n",
368                 __func__, w->name, event);
369 
370         switch (event) {
371         case SND_SOC_DAPM_PRE_PMU:
372                 mt8186_afe_gpio_request(afe->dev, true, i2s_priv->id, 0);
373                 break;
374         case SND_SOC_DAPM_POST_PMD:
375                 mt8186_afe_gpio_request(afe->dev, false, i2s_priv->id, 0);
376                 break;
377         default:
378                 break;
379         }
380 
381         return 0;
382 }
383 
384 static int mtk_apll_event(struct snd_soc_dapm_widget *w,
385                           struct snd_kcontrol *kcontrol,
386                           int event)
387 {
388         struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
389         struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
390 
391         dev_dbg(cmpnt->dev, "%s(), name %s, event 0x%x\n",
392                 __func__, w->name, event);
393 
394         switch (event) {
395         case SND_SOC_DAPM_PRE_PMU:
396                 if (snd_soc_dapm_widget_name_cmp(w, APLL1_W_NAME) == 0)
397                         mt8186_apll1_enable(afe);
398                 else
399                         mt8186_apll2_enable(afe);
400                 break;
401         case SND_SOC_DAPM_POST_PMD:
402                 if (snd_soc_dapm_widget_name_cmp(w, APLL1_W_NAME) == 0)
403                         mt8186_apll1_disable(afe);
404                 else
405                         mt8186_apll2_disable(afe);
406                 break;
407         default:
408                 break;
409         }
410 
411         return 0;
412 }
413 
414 static int mtk_mclk_en_event(struct snd_soc_dapm_widget *w,
415                              struct snd_kcontrol *kcontrol,
416                              int event)
417 {
418         struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
419         struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
420         struct mtk_afe_i2s_priv *i2s_priv;
421 
422         dev_dbg(cmpnt->dev, "%s(), name %s, event 0x%x\n",
423                 __func__, w->name, event);
424 
425         i2s_priv = get_i2s_priv_by_name(afe, w->name);
426 
427         switch (event) {
428         case SND_SOC_DAPM_PRE_PMU:
429                 mt8186_mck_enable(afe, i2s_priv->mclk_id, i2s_priv->mclk_rate);
430                 break;
431         case SND_SOC_DAPM_POST_PMD:
432                 i2s_priv->mclk_rate = 0;
433                 mt8186_mck_disable(afe, i2s_priv->mclk_id);
434                 break;
435         default:
436                 break;
437         }
438 
439         return 0;
440 }
441 
442 static const struct snd_soc_dapm_widget mtk_dai_i2s_widgets[] = {
443         SND_SOC_DAPM_INPUT("CONNSYS"),
444 
445         SND_SOC_DAPM_MIXER("I2S1_CH1", SND_SOC_NOPM, 0, 0,
446                            mtk_i2s1_ch1_mix,
447                            ARRAY_SIZE(mtk_i2s1_ch1_mix)),
448         SND_SOC_DAPM_MIXER("I2S1_CH2", SND_SOC_NOPM, 0, 0,
449                            mtk_i2s1_ch2_mix,
450                            ARRAY_SIZE(mtk_i2s1_ch2_mix)),
451 
452         SND_SOC_DAPM_MIXER("I2S3_CH1", SND_SOC_NOPM, 0, 0,
453                            mtk_i2s3_ch1_mix,
454                            ARRAY_SIZE(mtk_i2s3_ch1_mix)),
455         SND_SOC_DAPM_MIXER("I2S3_CH2", SND_SOC_NOPM, 0, 0,
456                            mtk_i2s3_ch2_mix,
457                            ARRAY_SIZE(mtk_i2s3_ch2_mix)),
458 
459         /* i2s en*/
460         SND_SOC_DAPM_SUPPLY_S("I2S0_EN", SUPPLY_SEQ_I2S_EN,
461                               AFE_I2S_CON, I2S_EN_SFT, 0,
462                               mtk_i2s_en_event,
463                               SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
464         SND_SOC_DAPM_SUPPLY_S("I2S1_EN", SUPPLY_SEQ_I2S_EN,
465                               AFE_I2S_CON1, I2S_EN_SFT, 0,
466                               mtk_i2s_en_event,
467                               SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
468         SND_SOC_DAPM_SUPPLY_S("I2S2_EN", SUPPLY_SEQ_I2S_EN,
469                               AFE_I2S_CON2, I2S_EN_SFT, 0,
470                               mtk_i2s_en_event,
471                               SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
472         SND_SOC_DAPM_SUPPLY_S("I2S3_EN", SUPPLY_SEQ_I2S_EN,
473                               AFE_I2S_CON3, I2S_EN_SFT, 0,
474                               mtk_i2s_en_event,
475                               SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
476         /* i2s hd en */
477         SND_SOC_DAPM_SUPPLY_S(I2S0_HD_EN_W_NAME, SUPPLY_SEQ_I2S_HD_EN,
478                               AFE_I2S_CON, I2S1_HD_EN_SFT, 0, NULL,
479                               SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
480         SND_SOC_DAPM_SUPPLY_S(I2S1_HD_EN_W_NAME, SUPPLY_SEQ_I2S_HD_EN,
481                               AFE_I2S_CON1, I2S2_HD_EN_SFT, 0, NULL,
482                               SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
483         SND_SOC_DAPM_SUPPLY_S(I2S2_HD_EN_W_NAME, SUPPLY_SEQ_I2S_HD_EN,
484                               AFE_I2S_CON2, I2S3_HD_EN_SFT, 0, NULL,
485                               SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
486         SND_SOC_DAPM_SUPPLY_S(I2S3_HD_EN_W_NAME, SUPPLY_SEQ_I2S_HD_EN,
487                               AFE_I2S_CON3, I2S4_HD_EN_SFT, 0, NULL,
488                               SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
489 
490         /* i2s mclk en */
491         SND_SOC_DAPM_SUPPLY_S(I2S0_MCLK_EN_W_NAME, SUPPLY_SEQ_I2S_MCLK_EN,
492                               SND_SOC_NOPM, 0, 0,
493                               mtk_mclk_en_event,
494                               SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
495         SND_SOC_DAPM_SUPPLY_S(I2S1_MCLK_EN_W_NAME, SUPPLY_SEQ_I2S_MCLK_EN,
496                               SND_SOC_NOPM, 0, 0,
497                               mtk_mclk_en_event,
498                               SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
499         SND_SOC_DAPM_SUPPLY_S(I2S2_MCLK_EN_W_NAME, SUPPLY_SEQ_I2S_MCLK_EN,
500                               SND_SOC_NOPM, 0, 0,
501                               mtk_mclk_en_event,
502                               SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
503         SND_SOC_DAPM_SUPPLY_S(I2S3_MCLK_EN_W_NAME, SUPPLY_SEQ_I2S_MCLK_EN,
504                               SND_SOC_NOPM, 0, 0,
505                               mtk_mclk_en_event,
506                               SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
507 
508         /* apll */
509         SND_SOC_DAPM_SUPPLY_S(APLL1_W_NAME, SUPPLY_SEQ_APLL,
510                               SND_SOC_NOPM, 0, 0,
511                               mtk_apll_event,
512                               SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
513         SND_SOC_DAPM_SUPPLY_S(APLL2_W_NAME, SUPPLY_SEQ_APLL,
514                               SND_SOC_NOPM, 0, 0,
515                               mtk_apll_event,
516                               SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
517 
518         /* allow i2s on without codec on */
519         SND_SOC_DAPM_OUTPUT("I2S_DUMMY_OUT"),
520         SND_SOC_DAPM_MUX("I2S1_Out_Mux",
521                          SND_SOC_NOPM, 0, 0, &i2s1_out_mux_control),
522         SND_SOC_DAPM_MUX("I2S3_Out_Mux",
523                          SND_SOC_NOPM, 0, 0, &i2s3_out_mux_control),
524         SND_SOC_DAPM_INPUT("I2S_DUMMY_IN"),
525         SND_SOC_DAPM_MUX("I2S0_In_Mux",
526                          SND_SOC_NOPM, 0, 0, &i2s0_in_mux_control),
527         SND_SOC_DAPM_MUX("I2S2_In_Mux",
528                          SND_SOC_NOPM, 0, 0, &i2s2_in_mux_control),
529 
530         /* i2s in lpbk */
531         SND_SOC_DAPM_MUX("I2S0_Lpbk_Mux",
532                          SND_SOC_NOPM, 0, 0, &i2s0_lpbk_mux_control),
533         SND_SOC_DAPM_MUX("I2S2_Lpbk_Mux",
534                          SND_SOC_NOPM, 0, 0, &i2s2_lpbk_mux_control),
535 };
536 
537 static int mtk_afe_i2s_share_connect(struct snd_soc_dapm_widget *source,
538                                      struct snd_soc_dapm_widget *sink)
539 {
540         struct snd_soc_dapm_widget *w = sink;
541         struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
542         struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
543         struct mtk_afe_i2s_priv *i2s_priv;
544 
545         i2s_priv = get_i2s_priv_by_name(afe, sink->name);
546         if (i2s_priv->share_i2s_id < 0)
547                 return 0;
548 
549         return i2s_priv->share_i2s_id == get_i2s_id_by_name(afe, source->name);
550 }
551 
552 static int mtk_afe_i2s_hd_connect(struct snd_soc_dapm_widget *source,
553                                   struct snd_soc_dapm_widget *sink)
554 {
555         struct snd_soc_dapm_widget *w = sink;
556         struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
557         struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
558         struct mtk_afe_i2s_priv *i2s_priv;
559 
560         i2s_priv = get_i2s_priv_by_name(afe, sink->name);
561         if (get_i2s_id_by_name(afe, sink->name) ==
562             get_i2s_id_by_name(afe, source->name))
563                 return i2s_priv->low_jitter_en;
564 
565         /* check if share i2s need hd en */
566         if (i2s_priv->share_i2s_id < 0)
567                 return 0;
568 
569         if (i2s_priv->share_i2s_id == get_i2s_id_by_name(afe, source->name))
570                 return i2s_priv->low_jitter_en;
571 
572         return 0;
573 }
574 
575 static int mtk_afe_i2s_apll_connect(struct snd_soc_dapm_widget *source,
576                                     struct snd_soc_dapm_widget *sink)
577 {
578         struct snd_soc_dapm_widget *w = sink;
579         struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
580         struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
581         struct mtk_afe_i2s_priv *i2s_priv;
582         int cur_apll;
583         int i2s_need_apll;
584 
585         i2s_priv = get_i2s_priv_by_name(afe, w->name);
586         /* which apll */
587         cur_apll = mt8186_get_apll_by_name(afe, source->name);
588         /* choose APLL from i2s rate */
589         i2s_need_apll = mt8186_get_apll_by_rate(afe, i2s_priv->rate);
590 
591         return (i2s_need_apll == cur_apll) ? 1 : 0;
592 }
593 
594 static int mtk_afe_i2s_mclk_connect(struct snd_soc_dapm_widget *source,
595                                     struct snd_soc_dapm_widget *sink)
596 {
597         struct snd_soc_dapm_widget *w = sink;
598         struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
599         struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
600         struct mtk_afe_i2s_priv *i2s_priv;
601 
602         i2s_priv = get_i2s_priv_by_name(afe, sink->name);
603         if (get_i2s_id_by_name(afe, sink->name) ==
604             get_i2s_id_by_name(afe, source->name))
605                 return (i2s_priv->mclk_rate > 0) ? 1 : 0;
606 
607         /* check if share i2s need mclk */
608         if (i2s_priv->share_i2s_id < 0)
609                 return 0;
610 
611         if (i2s_priv->share_i2s_id == get_i2s_id_by_name(afe, source->name))
612                 return (i2s_priv->mclk_rate > 0) ? 1 : 0;
613 
614         return 0;
615 }
616 
617 static int mtk_afe_mclk_apll_connect(struct snd_soc_dapm_widget *source,
618                                      struct snd_soc_dapm_widget *sink)
619 {
620         struct snd_soc_dapm_widget *w = sink;
621         struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
622         struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
623         struct mtk_afe_i2s_priv *i2s_priv;
624         int cur_apll;
625 
626         i2s_priv = get_i2s_priv_by_name(afe, w->name);
627         /* which apll */
628         cur_apll = mt8186_get_apll_by_name(afe, source->name);
629 
630         return (i2s_priv->mclk_apll == cur_apll) ? 1 : 0;
631 }
632 
633 static const struct snd_soc_dapm_route mtk_dai_i2s_routes[] = {
634         {"Connsys I2S", NULL, "CONNSYS"},
635 
636         /* i2s0 */
637         {"I2S0", NULL, "I2S0_EN"},
638         {"I2S0", NULL, "I2S1_EN", mtk_afe_i2s_share_connect},
639         {"I2S0", NULL, "I2S2_EN", mtk_afe_i2s_share_connect},
640         {"I2S0", NULL, "I2S3_EN", mtk_afe_i2s_share_connect},
641 
642         {"I2S0", NULL, I2S0_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
643         {"I2S0", NULL, I2S1_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
644         {"I2S0", NULL, I2S2_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
645         {"I2S0", NULL, I2S3_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
646         {I2S0_HD_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_i2s_apll_connect},
647         {I2S0_HD_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_i2s_apll_connect},
648 
649         {"I2S0", NULL, I2S0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
650         {"I2S0", NULL, I2S1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
651         {"I2S0", NULL, I2S2_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
652         {"I2S0", NULL, I2S3_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
653         {I2S0_MCLK_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect},
654         {I2S0_MCLK_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect},
655 
656         /* i2s1 */
657         {"I2S1_CH1", "DL1_CH1 Switch", "DL1"},
658         {"I2S1_CH2", "DL1_CH2 Switch", "DL1"},
659 
660         {"I2S1_CH1", "DL1_CH1 Switch", "DSP_DL1_VIRT"},
661         {"I2S1_CH2", "DL1_CH2 Switch", "DSP_DL1_VIRT"},
662 
663         {"I2S1_CH1", "DL2_CH1 Switch", "DL2"},
664         {"I2S1_CH2", "DL2_CH2 Switch", "DL2"},
665 
666         {"I2S1_CH1", "DL2_CH1 Switch", "DSP_DL2_VIRT"},
667         {"I2S1_CH2", "DL2_CH2 Switch", "DSP_DL2_VIRT"},
668 
669         {"I2S1_CH1", "DL3_CH1 Switch", "DL3"},
670         {"I2S1_CH2", "DL3_CH2 Switch", "DL3"},
671 
672         {"I2S1_CH1", "DL12_CH1 Switch", "DL12"},
673         {"I2S1_CH2", "DL12_CH2 Switch", "DL12"},
674 
675         {"I2S1_CH1", "DL12_CH3 Switch", "DL12"},
676         {"I2S1_CH2", "DL12_CH4 Switch", "DL12"},
677 
678         {"I2S1_CH1", "DL6_CH1 Switch", "DL6"},
679         {"I2S1_CH2", "DL6_CH2 Switch", "DL6"},
680 
681         {"I2S1_CH1", "DL4_CH1 Switch", "DL4"},
682         {"I2S1_CH2", "DL4_CH2 Switch", "DL4"},
683 
684         {"I2S1_CH1", "DL5_CH1 Switch", "DL5"},
685         {"I2S1_CH2", "DL5_CH2 Switch", "DL5"},
686 
687         {"I2S1_CH1", "DL8_CH1 Switch", "DL8"},
688         {"I2S1_CH2", "DL8_CH2 Switch", "DL8"},
689 
690         {"I2S1", NULL, "I2S1_CH1"},
691         {"I2S1", NULL, "I2S1_CH2"},
692 
693         {"I2S1", NULL, "I2S0_EN", mtk_afe_i2s_share_connect},
694         {"I2S1", NULL, "I2S1_EN"},
695         {"I2S1", NULL, "I2S2_EN", mtk_afe_i2s_share_connect},
696         {"I2S1", NULL, "I2S3_EN", mtk_afe_i2s_share_connect},
697 
698         {"I2S1", NULL, I2S0_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
699         {"I2S1", NULL, I2S1_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
700         {"I2S1", NULL, I2S2_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
701         {"I2S1", NULL, I2S3_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
702         {I2S1_HD_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_i2s_apll_connect},
703         {I2S1_HD_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_i2s_apll_connect},
704 
705         {"I2S1", NULL, I2S0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
706         {"I2S1", NULL, I2S1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
707         {"I2S1", NULL, I2S2_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
708         {"I2S1", NULL, I2S3_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
709         {I2S1_MCLK_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect},
710         {I2S1_MCLK_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect},
711 
712         /* i2s2 */
713         {"I2S2", NULL, "I2S0_EN", mtk_afe_i2s_share_connect},
714         {"I2S2", NULL, "I2S1_EN", mtk_afe_i2s_share_connect},
715         {"I2S2", NULL, "I2S2_EN"},
716         {"I2S2", NULL, "I2S3_EN", mtk_afe_i2s_share_connect},
717 
718         {"I2S2", NULL, I2S0_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
719         {"I2S2", NULL, I2S1_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
720         {"I2S2", NULL, I2S2_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
721         {"I2S2", NULL, I2S3_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
722         {I2S2_HD_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_i2s_apll_connect},
723         {I2S2_HD_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_i2s_apll_connect},
724 
725         {"I2S2", NULL, I2S0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
726         {"I2S2", NULL, I2S1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
727         {"I2S2", NULL, I2S2_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
728         {"I2S2", NULL, I2S3_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
729         {I2S2_MCLK_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect},
730         {I2S2_MCLK_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect},
731 
732         /* i2s3 */
733         {"I2S3_CH1", "DL1_CH1 Switch", "DL1"},
734         {"I2S3_CH2", "DL1_CH2 Switch", "DL1"},
735 
736         {"I2S3_CH1", "DL1_CH1 Switch", "DSP_DL1_VIRT"},
737         {"I2S3_CH2", "DL1_CH2 Switch", "DSP_DL1_VIRT"},
738 
739         {"I2S3_CH1", "DL2_CH1 Switch", "DL2"},
740         {"I2S3_CH2", "DL2_CH2 Switch", "DL2"},
741 
742         {"I2S3_CH1", "DL2_CH1 Switch", "DSP_DL2_VIRT"},
743         {"I2S3_CH2", "DL2_CH2 Switch", "DSP_DL2_VIRT"},
744 
745         {"I2S3_CH1", "DL3_CH1 Switch", "DL3"},
746         {"I2S3_CH2", "DL3_CH2 Switch", "DL3"},
747 
748         {"I2S3_CH1", "DL12_CH1 Switch", "DL12"},
749         {"I2S3_CH2", "DL12_CH2 Switch", "DL12"},
750 
751         {"I2S3_CH1", "DL12_CH3 Switch", "DL12"},
752         {"I2S3_CH2", "DL12_CH4 Switch", "DL12"},
753 
754         {"I2S3_CH1", "DL6_CH1 Switch", "DL6"},
755         {"I2S3_CH2", "DL6_CH2 Switch", "DL6"},
756 
757         {"I2S3_CH1", "DL4_CH1 Switch", "DL4"},
758         {"I2S3_CH2", "DL4_CH2 Switch", "DL4"},
759 
760         {"I2S3_CH1", "DL5_CH1 Switch", "DL5"},
761         {"I2S3_CH2", "DL5_CH2 Switch", "DL5"},
762 
763         {"I2S3_CH1", "DL8_CH1 Switch", "DL8"},
764         {"I2S3_CH2", "DL8_CH2 Switch", "DL8"},
765 
766         {"I2S3", NULL, "I2S3_CH1"},
767         {"I2S3", NULL, "I2S3_CH2"},
768 
769         {"I2S3", NULL, "I2S0_EN", mtk_afe_i2s_share_connect},
770         {"I2S3", NULL, "I2S1_EN", mtk_afe_i2s_share_connect},
771         {"I2S3", NULL, "I2S2_EN", mtk_afe_i2s_share_connect},
772         {"I2S3", NULL, "I2S3_EN"},
773 
774         {"I2S3", NULL, I2S0_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
775         {"I2S3", NULL, I2S1_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
776         {"I2S3", NULL, I2S2_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
777         {"I2S3", NULL, I2S3_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
778         {I2S3_HD_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_i2s_apll_connect},
779         {I2S3_HD_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_i2s_apll_connect},
780 
781         {"I2S3", NULL, I2S0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
782         {"I2S3", NULL, I2S1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
783         {"I2S3", NULL, I2S2_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
784         {"I2S3", NULL, I2S3_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
785         {I2S3_MCLK_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect},
786         {I2S3_MCLK_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect},
787 
788         /* allow i2s on without codec on */
789         {"I2S0", NULL, "I2S0_In_Mux"},
790         {"I2S0_In_Mux", "Dummy_Widget", "I2S_DUMMY_IN"},
791 
792         {"I2S1_Out_Mux", "Dummy_Widget", "I2S1"},
793         {"I2S_DUMMY_OUT", NULL, "I2S1_Out_Mux"},
794 
795         {"I2S2", NULL, "I2S2_In_Mux"},
796         {"I2S2_In_Mux", "Dummy_Widget", "I2S_DUMMY_IN"},
797 
798         {"I2S3_Out_Mux", "Dummy_Widget", "I2S3"},
799         {"I2S_DUMMY_OUT", NULL, "I2S3_Out_Mux"},
800 
801         /* i2s in lpbk */
802         {"I2S0_Lpbk_Mux", "Lpbk", "I2S3"},
803         {"I2S2_Lpbk_Mux", "Lpbk", "I2S1"},
804         {"I2S0", NULL, "I2S0_Lpbk_Mux"},
805         {"I2S2", NULL, "I2S2_Lpbk_Mux"},
806 };
807 
808 /* dai ops */
809 static int mtk_dai_connsys_i2s_hw_params(struct snd_pcm_substream *substream,
810                                          struct snd_pcm_hw_params *params,
811                                          struct snd_soc_dai *dai)
812 {
813         struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
814         unsigned int rate = params_rate(params);
815         unsigned int rate_reg = mt8186_rate_transform(afe->dev,
816                                                       rate, dai->id);
817         unsigned int i2s_con = 0;
818 
819         dev_dbg(afe->dev, "%s(), id %d, stream %d, rate %d\n",
820                 __func__, dai->id, substream->stream, rate);
821 
822         /* non-inverse, i2s mode, slave, 16bits, from connsys */
823         i2s_con |= 0 << INV_PAD_CTRL_SFT;
824         i2s_con |= I2S_FMT_I2S << I2S_FMT_SFT;
825         i2s_con |= 1 << I2S_SRC_SFT;
826         i2s_con |= get_i2s_wlen(SNDRV_PCM_FORMAT_S16_LE) << I2S_WLEN_SFT;
827         i2s_con |= 0 << I2SIN_PAD_SEL_SFT;
828         regmap_write(afe->regmap, AFE_CONNSYS_I2S_CON, i2s_con);
829 
830         /* use asrc */
831         regmap_update_bits(afe->regmap, AFE_CONNSYS_I2S_CON,
832                            I2S_BYPSRC_MASK_SFT, 0);
833 
834         /* slave mode, set i2s for asrc */
835         regmap_update_bits(afe->regmap, AFE_CONNSYS_I2S_CON,
836                            I2S_MODE_MASK_SFT, rate_reg << I2S_MODE_SFT);
837 
838         if (rate == 44100)
839                 regmap_write(afe->regmap, AFE_ASRC_2CH_CON3, 0x1b9000);
840         else if (rate == 32000)
841                 regmap_write(afe->regmap, AFE_ASRC_2CH_CON3, 0x140000);
842         else
843                 regmap_write(afe->regmap, AFE_ASRC_2CH_CON3, 0x1e0000);
844 
845         /* Calibration setting */
846         regmap_write(afe->regmap, AFE_ASRC_2CH_CON4, 0x140000);
847         regmap_write(afe->regmap, AFE_ASRC_2CH_CON9, 0x36000);
848         regmap_write(afe->regmap, AFE_ASRC_2CH_CON10, 0x2fc00);
849         regmap_write(afe->regmap, AFE_ASRC_2CH_CON6, 0x7ef4);
850         regmap_write(afe->regmap, AFE_ASRC_2CH_CON5, 0xff5986);
851 
852         /* 0:Stereo 1:Mono */
853         regmap_update_bits(afe->regmap, AFE_ASRC_2CH_CON2,
854                            CHSET_IS_MONO_MASK_SFT, 0);
855 
856         return 0;
857 }
858 
859 static int mtk_dai_connsys_i2s_trigger(struct snd_pcm_substream *substream,
860                                        int cmd, struct snd_soc_dai *dai)
861 {
862         struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
863         struct mt8186_afe_private *afe_priv = afe->platform_priv;
864 
865         dev_dbg(afe->dev, "%s(), cmd %d, stream %d\n",
866                 __func__, cmd, substream->stream);
867 
868         switch (cmd) {
869         case SNDRV_PCM_TRIGGER_START:
870         case SNDRV_PCM_TRIGGER_RESUME:
871                 /* i2s enable */
872                 regmap_update_bits(afe->regmap,
873                                    AFE_CONNSYS_I2S_CON,
874                                    I2S_EN_MASK_SFT,
875                                    BIT(I2S_EN_SFT));
876 
877                 /* calibrator enable */
878                 regmap_update_bits(afe->regmap,
879                                    AFE_ASRC_2CH_CON5,
880                                    CALI_EN_MASK_SFT,
881                                    BIT(CALI_EN_SFT));
882 
883                 /* asrc enable */
884                 regmap_update_bits(afe->regmap,
885                                    AFE_ASRC_2CH_CON0,
886                                    CON0_CHSET_STR_CLR_MASK_SFT,
887                                    BIT(CON0_CHSET_STR_CLR_SFT));
888                 regmap_update_bits(afe->regmap,
889                                    AFE_ASRC_2CH_CON0,
890                                    CON0_ASM_ON_MASK_SFT,
891                                    BIT(CON0_ASM_ON_SFT));
892 
893                 afe_priv->dai_on[dai->id] = true;
894                 return 0;
895         case SNDRV_PCM_TRIGGER_STOP:
896         case SNDRV_PCM_TRIGGER_SUSPEND:
897                 regmap_update_bits(afe->regmap, AFE_ASRC_2CH_CON0,
898                                    CON0_ASM_ON_MASK_SFT, 0);
899                 regmap_update_bits(afe->regmap, AFE_ASRC_2CH_CON5,
900                                    CALI_EN_MASK_SFT, 0);
901 
902                 /* i2s disable */
903                 regmap_update_bits(afe->regmap, AFE_CONNSYS_I2S_CON,
904                                    I2S_EN_MASK_SFT, 0);
905 
906                 /* bypass asrc */
907                 regmap_update_bits(afe->regmap, AFE_CONNSYS_I2S_CON,
908                                    I2S_BYPSRC_MASK_SFT, BIT(I2S_BYPSRC_SFT));
909 
910                 afe_priv->dai_on[dai->id] = false;
911                 return 0;
912         default:
913                 return -EINVAL;
914         }
915         return 0;
916 }
917 
918 static const struct snd_soc_dai_ops mtk_dai_connsys_i2s_ops = {
919         .hw_params = mtk_dai_connsys_i2s_hw_params,
920         .trigger = mtk_dai_connsys_i2s_trigger,
921 };
922 
923 /* i2s */
924 static int mtk_dai_i2s_config(struct mtk_base_afe *afe,
925                               struct snd_pcm_hw_params *params,
926                               int i2s_id)
927 {
928         struct mt8186_afe_private *afe_priv = afe->platform_priv;
929         struct mtk_afe_i2s_priv *i2s_priv = afe_priv->dai_priv[i2s_id];
930 
931         unsigned int rate = params_rate(params);
932         unsigned int rate_reg = mt8186_rate_transform(afe->dev,
933                                                       rate, i2s_id);
934         snd_pcm_format_t format = params_format(params);
935         unsigned int i2s_con = 0;
936         int ret;
937 
938         dev_dbg(afe->dev, "%s(), id %d, rate %d, format %d\n",
939                 __func__, i2s_id, rate, format);
940 
941         i2s_priv->rate = rate;
942 
943         switch (i2s_id) {
944         case MT8186_DAI_I2S_0:
945                 i2s_con = I2S_IN_PAD_IO_MUX << I2SIN_PAD_SEL_SFT;
946                 i2s_con |= rate_reg << I2S_OUT_MODE_SFT;
947                 i2s_con |= I2S_FMT_I2S << I2S_FMT_SFT;
948                 i2s_con |= get_i2s_wlen(format) << I2S_WLEN_SFT;
949                 regmap_update_bits(afe->regmap, AFE_I2S_CON,
950                                    0xffffeffa, i2s_con);
951                 break;
952         case MT8186_DAI_I2S_1:
953                 i2s_con = I2S1_SEL_O28_O29 << I2S2_SEL_O03_O04_SFT;
954                 i2s_con |= rate_reg << I2S2_OUT_MODE_SFT;
955                 i2s_con |= I2S_FMT_I2S << I2S2_FMT_SFT;
956                 i2s_con |= get_i2s_wlen(format) << I2S2_WLEN_SFT;
957                 regmap_update_bits(afe->regmap, AFE_I2S_CON1,
958                                    0xffffeffa, i2s_con);
959                 break;
960         case MT8186_DAI_I2S_2:
961                 i2s_con = 8 << I2S3_UPDATE_WORD_SFT;
962                 i2s_con |= rate_reg << I2S3_OUT_MODE_SFT;
963                 i2s_con |= I2S_FMT_I2S << I2S3_FMT_SFT;
964                 i2s_con |= get_i2s_wlen(format) << I2S3_WLEN_SFT;
965                 regmap_update_bits(afe->regmap, AFE_I2S_CON2,
966                                    0xffffeffa, i2s_con);
967                 break;
968         case MT8186_DAI_I2S_3:
969                 i2s_con = rate_reg << I2S4_OUT_MODE_SFT;
970                 i2s_con |= I2S_FMT_I2S << I2S4_FMT_SFT;
971                 i2s_con |= get_i2s_wlen(format) << I2S4_WLEN_SFT;
972                 regmap_update_bits(afe->regmap, AFE_I2S_CON3,
973                                    0xffffeffa, i2s_con);
974                 break;
975         default:
976                 dev_err(afe->dev, "%s(), id %d not support\n",
977                         __func__, i2s_id);
978                 return -EINVAL;
979         }
980 
981         /* set share i2s */
982         if (i2s_priv->share_i2s_id >= 0) {
983                 ret = mtk_dai_i2s_config(afe, params, i2s_priv->share_i2s_id);
984                 if (ret)
985                         return ret;
986         }
987 
988         return 0;
989 }
990 
991 static int mtk_dai_i2s_hw_params(struct snd_pcm_substream *substream,
992                                  struct snd_pcm_hw_params *params,
993                                  struct snd_soc_dai *dai)
994 {
995         struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
996 
997         return mtk_dai_i2s_config(afe, params, dai->id);
998 }
999 
1000 static int mtk_dai_i2s_set_sysclk(struct snd_soc_dai *dai,
1001                                   int clk_id, unsigned int freq, int dir)
1002 {
1003         struct mtk_base_afe *afe = dev_get_drvdata(dai->dev);
1004         struct mt8186_afe_private *afe_priv = afe->platform_priv;
1005         struct mtk_afe_i2s_priv *i2s_priv = afe_priv->dai_priv[dai->id];
1006         int apll;
1007         int apll_rate;
1008 
1009         if (dir != SND_SOC_CLOCK_OUT) {
1010                 dev_err(afe->dev, "%s(), dir != SND_SOC_CLOCK_OUT", __func__);
1011                 return -EINVAL;
1012         }
1013 
1014         dev_dbg(afe->dev, "%s(), freq %d\n", __func__, freq);
1015 
1016         apll = mt8186_get_apll_by_rate(afe, freq);
1017         apll_rate = mt8186_get_apll_rate(afe, apll);
1018 
1019         if (freq > apll_rate) {
1020                 dev_err(afe->dev, "%s(), freq > apll rate", __func__);
1021                 return -EINVAL;
1022         }
1023 
1024         if (apll_rate % freq != 0) {
1025                 dev_err(afe->dev, "%s(), APLL cannot generate freq Hz", __func__);
1026                 return -EINVAL;
1027         }
1028 
1029         i2s_priv->mclk_rate = freq;
1030         i2s_priv->mclk_apll = apll;
1031 
1032         if (i2s_priv->share_i2s_id > 0) {
1033                 struct mtk_afe_i2s_priv *share_i2s_priv;
1034 
1035                 share_i2s_priv = afe_priv->dai_priv[i2s_priv->share_i2s_id];
1036                 if (!share_i2s_priv) {
1037                         dev_err(afe->dev, "%s(), share_i2s_priv == NULL", __func__);
1038                         return -EINVAL;
1039                 }
1040 
1041                 share_i2s_priv->mclk_rate = i2s_priv->mclk_rate;
1042                 share_i2s_priv->mclk_apll = i2s_priv->mclk_apll;
1043         }
1044 
1045         return 0;
1046 }
1047 
1048 static const struct snd_soc_dai_ops mtk_dai_i2s_ops = {
1049         .hw_params = mtk_dai_i2s_hw_params,
1050         .set_sysclk = mtk_dai_i2s_set_sysclk,
1051 };
1052 
1053 /* dai driver */
1054 #define MTK_CONNSYS_I2S_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000)
1055 
1056 #define MTK_I2S_RATES (SNDRV_PCM_RATE_8000_48000 |\
1057                        SNDRV_PCM_RATE_88200 |\
1058                        SNDRV_PCM_RATE_96000 |\
1059                        SNDRV_PCM_RATE_176400 |\
1060                        SNDRV_PCM_RATE_192000)
1061 
1062 #define MTK_I2S_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
1063                          SNDRV_PCM_FMTBIT_S24_LE |\
1064                          SNDRV_PCM_FMTBIT_S32_LE)
1065 
1066 static struct snd_soc_dai_driver mtk_dai_i2s_driver[] = {
1067         {
1068                 .name = "CONNSYS_I2S",
1069                 .id = MT8186_DAI_CONNSYS_I2S,
1070                 .capture = {
1071                         .stream_name = "Connsys I2S",
1072                         .channels_min = 1,
1073                         .channels_max = 2,
1074                         .rates = MTK_CONNSYS_I2S_RATES,
1075                         .formats = MTK_I2S_FORMATS,
1076                 },
1077                 .ops = &mtk_dai_connsys_i2s_ops,
1078         },
1079         {
1080                 .name = "I2S0",
1081                 .id = MT8186_DAI_I2S_0,
1082                 .capture = {
1083                         .stream_name = "I2S0",
1084                         .channels_min = 1,
1085                         .channels_max = 2,
1086                         .rates = MTK_I2S_RATES,
1087                         .formats = MTK_I2S_FORMATS,
1088                 },
1089                 .ops = &mtk_dai_i2s_ops,
1090         },
1091         {
1092                 .name = "I2S1",
1093                 .id = MT8186_DAI_I2S_1,
1094                 .playback = {
1095                         .stream_name = "I2S1",
1096                         .channels_min = 1,
1097                         .channels_max = 2,
1098                         .rates = MTK_I2S_RATES,
1099                         .formats = MTK_I2S_FORMATS,
1100                 },
1101                 .ops = &mtk_dai_i2s_ops,
1102         },
1103         {
1104                 .name = "I2S2",
1105                 .id = MT8186_DAI_I2S_2,
1106                 .capture = {
1107                         .stream_name = "I2S2",
1108                         .channels_min = 1,
1109                         .channels_max = 2,
1110                         .rates = MTK_I2S_RATES,
1111                         .formats = MTK_I2S_FORMATS,
1112                 },
1113                 .ops = &mtk_dai_i2s_ops,
1114         },
1115         {
1116                 .name = "I2S3",
1117                 .id = MT8186_DAI_I2S_3,
1118                 .playback = {
1119                         .stream_name = "I2S3",
1120                         .channels_min = 1,
1121                         .channels_max = 2,
1122                         .rates = MTK_I2S_RATES,
1123                         .formats = MTK_I2S_FORMATS,
1124                 },
1125                 .ops = &mtk_dai_i2s_ops,
1126         }
1127 };
1128 
1129 /* this enum is merely for mtk_afe_i2s_priv declare */
1130 enum {
1131         DAI_I2S0 = 0,
1132         DAI_I2S1,
1133         DAI_I2S2,
1134         DAI_I2S3,
1135         DAI_I2S_NUM,
1136 };
1137 
1138 static const struct mtk_afe_i2s_priv mt8186_i2s_priv[DAI_I2S_NUM] = {
1139         [DAI_I2S0] = {
1140                 .id = MT8186_DAI_I2S_0,
1141                 .mclk_id = MT8186_I2S0_MCK,
1142                 .share_i2s_id = -1,
1143         },
1144         [DAI_I2S1] = {
1145                 .id = MT8186_DAI_I2S_1,
1146                 .mclk_id = MT8186_I2S1_MCK,
1147                 .share_i2s_id = -1,
1148         },
1149         [DAI_I2S2] = {
1150                 .id = MT8186_DAI_I2S_2,
1151                 .mclk_id = MT8186_I2S2_MCK,
1152                 .share_i2s_id = -1,
1153         },
1154         [DAI_I2S3] = {
1155                 .id = MT8186_DAI_I2S_3,
1156                 /*  clock gate naming is hf_faud_i2s4_m_ck*/
1157                 .mclk_id = MT8186_I2S4_MCK,
1158                 .share_i2s_id = -1,
1159         }
1160 };
1161 
1162 /**
1163  * mt8186_dai_i2s_set_share() - Set up I2S ports to share a single clock.
1164  * @afe: Pointer to &struct mtk_base_afe
1165  * @main_i2s_name: The name of the I2S port that will provide the clock
1166  * @secondary_i2s_name: The name of the I2S port that will use this clock
1167  */
1168 int mt8186_dai_i2s_set_share(struct mtk_base_afe *afe, const char *main_i2s_name,
1169                              const char *secondary_i2s_name)
1170 {
1171         struct mtk_afe_i2s_priv *secondary_i2s_priv;
1172         int main_i2s_id;
1173 
1174         secondary_i2s_priv = get_i2s_priv_by_name(afe, secondary_i2s_name);
1175         if (!secondary_i2s_priv)
1176                 return -EINVAL;
1177 
1178         main_i2s_id = get_i2s_id_by_name(afe, main_i2s_name);
1179         if (main_i2s_id < 0)
1180                 return main_i2s_id;
1181 
1182         secondary_i2s_priv->share_i2s_id = main_i2s_id;
1183 
1184         return 0;
1185 }
1186 EXPORT_SYMBOL_GPL(mt8186_dai_i2s_set_share);
1187 
1188 static int mt8186_dai_i2s_set_priv(struct mtk_base_afe *afe)
1189 {
1190         int i;
1191         int ret;
1192 
1193         for (i = 0; i < DAI_I2S_NUM; i++) {
1194                 ret = mt8186_dai_set_priv(afe, mt8186_i2s_priv[i].id,
1195                                           sizeof(struct mtk_afe_i2s_priv),
1196                                           &mt8186_i2s_priv[i]);
1197                 if (ret)
1198                         return ret;
1199         }
1200 
1201         return 0;
1202 }
1203 
1204 int mt8186_dai_i2s_register(struct mtk_base_afe *afe)
1205 {
1206         struct mtk_base_afe_dai *dai;
1207         int ret;
1208 
1209         dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL);
1210         if (!dai)
1211                 return -ENOMEM;
1212 
1213         list_add(&dai->list, &afe->sub_dais);
1214 
1215         dai->dai_drivers = mtk_dai_i2s_driver;
1216         dai->num_dai_drivers = ARRAY_SIZE(mtk_dai_i2s_driver);
1217 
1218         dai->controls = mtk_dai_i2s_controls;
1219         dai->num_controls = ARRAY_SIZE(mtk_dai_i2s_controls);
1220         dai->dapm_widgets = mtk_dai_i2s_widgets;
1221         dai->num_dapm_widgets = ARRAY_SIZE(mtk_dai_i2s_widgets);
1222         dai->dapm_routes = mtk_dai_i2s_routes;
1223         dai->num_dapm_routes = ARRAY_SIZE(mtk_dai_i2s_routes);
1224 
1225         /* set all dai i2s private data */
1226         ret = mt8186_dai_i2s_set_priv(afe);
1227         if (ret)
1228                 return ret;
1229 
1230         return 0;
1231 }
1232 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php