1 // SPDX-License-Identifier: GPL-2.0 2 // 3 // MediaTek ALSA SoC Audio DAI I2S Control 4 // 5 // Copyright (c) 2018 MediaTek Inc. 6 // Author: KaiChieh Chuang <kaichieh.chuang@mediatek.com> 7 8 #include <linux/bitops.h> 9 #include <linux/regmap.h> 10 #include <sound/pcm_params.h> 11 #include "mt8183-afe-clk.h" 12 #include "mt8183-afe-common.h" 13 #include "mt8183-interconnection.h" 14 #include "mt8183-reg.h" 15 16 enum { 17 I2S_FMT_EIAJ = 0, 18 I2S_FMT_I2S = 1, 19 }; 20 21 enum { 22 I2S_WLEN_16_BIT = 0, 23 I2S_WLEN_32_BIT = 1, 24 }; 25 26 enum { 27 I2S_HD_NORMAL = 0, 28 I2S_HD_LOW_JITTER = 1, 29 }; 30 31 enum { 32 I2S1_SEL_O28_O29 = 0, 33 I2S1_SEL_O03_O04 = 1, 34 }; 35 36 enum { 37 I2S_IN_PAD_CONNSYS = 0, 38 I2S_IN_PAD_IO_MUX = 1, 39 }; 40 41 struct mtk_afe_i2s_priv { 42 int id; 43 int rate; /* for determine which apll to use */ 44 int low_jitter_en; 45 46 const char *share_property_name; 47 int share_i2s_id; 48 49 int mclk_id; 50 int mclk_rate; 51 int mclk_apll; 52 }; 53 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_I2S5_KCONTROL_NAME "I2S5_HD_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 #define I2S5_HD_EN_W_NAME "I2S5_HD_EN" 71 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" 77 78 static int get_i2s_id_by_name(struct mtk_base_afe *afe, 79 const char *name) 80 { 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; 91 else 92 return -EINVAL; 93 } 94 95 static struct mtk_afe_i2s_priv *get_i2s_priv_by_name(struct mtk_base_afe *afe, 96 const char *name) 97 { 98 struct mt8183_afe_private *afe_priv = afe->platform_priv; 99 int dai_id = get_i2s_id_by_name(afe, name); 100 101 if (dai_id < 0) 102 return NULL; 103 104 return afe_priv->dai_priv[dai_id]; 105 } 106 107 /* low jitter control */ 108 static const char * const mt8183_i2s_hd_str[] = { 109 "Normal", "Low_Jitter" 110 }; 111 112 static const struct soc_enum mt8183_i2s_enum[] = { 113 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(mt8183_i2s_hd_str), 114 mt8183_i2s_hd_str), 115 }; 116 117 static int mt8183_i2s_hd_get(struct snd_kcontrol *kcontrol, 118 struct snd_ctl_elem_value *ucontrol) 119 { 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; 123 124 i2s_priv = get_i2s_priv_by_name(afe, kcontrol->id.name); 125 126 if (!i2s_priv) { 127 dev_warn(afe->dev, "%s(), i2s_priv == NULL", __func__); 128 return -EINVAL; 129 } 130 131 ucontrol->value.integer.value[0] = i2s_priv->low_jitter_en; 132 133 return 0; 134 } 135 136 static int mt8183_i2s_hd_set(struct snd_kcontrol *kcontrol, 137 struct snd_ctl_elem_value *ucontrol) 138 { 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; 143 int hd_en; 144 145 if (ucontrol->value.enumerated.item[0] >= e->items) 146 return -EINVAL; 147 148 hd_en = ucontrol->value.integer.value[0]; 149 150 dev_info(afe->dev, "%s(), kcontrol name %s, hd_en %d\n", 151 __func__, kcontrol->id.name, hd_en); 152 153 i2s_priv = get_i2s_priv_by_name(afe, kcontrol->id.name); 154 155 if (!i2s_priv) { 156 dev_warn(afe->dev, "%s(), i2s_priv == NULL", __func__); 157 return -EINVAL; 158 } 159 160 i2s_priv->low_jitter_en = hd_en; 161 162 return 0; 163 } 164 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), 176 }; 177 178 /* dai component */ 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), 190 }; 191 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), 206 }; 207 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), 218 }; 219 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), 234 }; 235 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), 246 }; 247 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), 262 }; 263 264 enum { 265 SUPPLY_SEQ_APLL, 266 SUPPLY_SEQ_I2S_MCLK_EN, 267 SUPPLY_SEQ_I2S_HD_EN, 268 SUPPLY_SEQ_I2S_EN, 269 }; 270 271 static int mtk_apll_event(struct snd_soc_dapm_widget *w, 272 struct snd_kcontrol *kcontrol, 273 int event) 274 { 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); 277 278 dev_info(cmpnt->dev, "%s(), name %s, event 0x%x\n", 279 __func__, w->name, event); 280 281 switch (event) { 282 case SND_SOC_DAPM_PRE_PMU: 283 if (strcmp(w->name, APLL1_W_NAME) == 0) 284 mt8183_apll1_enable(afe); 285 else 286 mt8183_apll2_enable(afe); 287 break; 288 case SND_SOC_DAPM_POST_PMD: 289 if (strcmp(w->name, APLL1_W_NAME) == 0) 290 mt8183_apll1_disable(afe); 291 else 292 mt8183_apll2_disable(afe); 293 break; 294 default: 295 break; 296 } 297 298 return 0; 299 } 300 301 static int mtk_mclk_en_event(struct snd_soc_dapm_widget *w, 302 struct snd_kcontrol *kcontrol, 303 int event) 304 { 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; 308 309 dev_info(cmpnt->dev, "%s(), name %s, event 0x%x\n", 310 __func__, w->name, event); 311 312 i2s_priv = get_i2s_priv_by_name(afe, w->name); 313 314 if (!i2s_priv) { 315 dev_warn(afe->dev, "%s(), i2s_priv == NULL", __func__); 316 return -EINVAL; 317 } 318 319 switch (event) { 320 case SND_SOC_DAPM_PRE_PMU: 321 mt8183_mck_enable(afe, i2s_priv->mclk_id, i2s_priv->mclk_rate); 322 break; 323 case SND_SOC_DAPM_POST_PMD: 324 i2s_priv->mclk_rate = 0; 325 mt8183_mck_disable(afe, i2s_priv->mclk_id); 326 break; 327 default: 328 break; 329 } 330 331 return 0; 332 } 333 334 static const struct snd_soc_dapm_widget mtk_dai_i2s_widgets[] = { 335 SND_SOC_DAPM_MIXER("I2S1_CH1", SND_SOC_NOPM, 0, 0, 336 mtk_i2s1_ch1_mix, 337 ARRAY_SIZE(mtk_i2s1_ch1_mix)), 338 SND_SOC_DAPM_MIXER("I2S1_CH2", SND_SOC_NOPM, 0, 0, 339 mtk_i2s1_ch2_mix, 340 ARRAY_SIZE(mtk_i2s1_ch2_mix)), 341 342 SND_SOC_DAPM_MIXER("I2S3_CH1", SND_SOC_NOPM, 0, 0, 343 mtk_i2s3_ch1_mix, 344 ARRAY_SIZE(mtk_i2s3_ch1_mix)), 345 SND_SOC_DAPM_MIXER("I2S3_CH2", SND_SOC_NOPM, 0, 0, 346 mtk_i2s3_ch2_mix, 347 ARRAY_SIZE(mtk_i2s3_ch2_mix)), 348 349 SND_SOC_DAPM_MIXER("I2S5_CH1", SND_SOC_NOPM, 0, 0, 350 mtk_i2s5_ch1_mix, 351 ARRAY_SIZE(mtk_i2s5_ch1_mix)), 352 SND_SOC_DAPM_MIXER("I2S5_CH2", SND_SOC_NOPM, 0, 0, 353 mtk_i2s5_ch2_mix, 354 ARRAY_SIZE(mtk_i2s5_ch2_mix)), 355 356 /* i2s en*/ 357 SND_SOC_DAPM_SUPPLY_S("I2S0_EN", SUPPLY_SEQ_I2S_EN, 358 AFE_I2S_CON, I2S_EN_SFT, 0, 359 NULL, 0), 360 SND_SOC_DAPM_SUPPLY_S("I2S1_EN", SUPPLY_SEQ_I2S_EN, 361 AFE_I2S_CON1, I2S_EN_SFT, 0, 362 NULL, 0), 363 SND_SOC_DAPM_SUPPLY_S("I2S2_EN", SUPPLY_SEQ_I2S_EN, 364 AFE_I2S_CON2, I2S_EN_SFT, 0, 365 NULL, 0), 366 SND_SOC_DAPM_SUPPLY_S("I2S3_EN", SUPPLY_SEQ_I2S_EN, 367 AFE_I2S_CON3, I2S_EN_SFT, 0, 368 NULL, 0), 369 SND_SOC_DAPM_SUPPLY_S("I2S5_EN", SUPPLY_SEQ_I2S_EN, 370 AFE_I2S_CON4, I2S5_EN_SFT, 0, 371 NULL, 0), 372 /* i2s hd en */ 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, 375 NULL, 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, 378 NULL, 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, 381 NULL, 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, 384 NULL, 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, 387 NULL, 0), 388 389 /* i2s mclk en */ 390 SND_SOC_DAPM_SUPPLY_S(I2S0_MCLK_EN_W_NAME, SUPPLY_SEQ_I2S_MCLK_EN, 391 SND_SOC_NOPM, 0, 0, 392 mtk_mclk_en_event, 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, 395 SND_SOC_NOPM, 0, 0, 396 mtk_mclk_en_event, 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, 399 SND_SOC_NOPM, 0, 0, 400 mtk_mclk_en_event, 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, 403 SND_SOC_NOPM, 0, 0, 404 mtk_mclk_en_event, 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, 407 SND_SOC_NOPM, 0, 0, 408 mtk_mclk_en_event, 409 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 410 411 /* apll */ 412 SND_SOC_DAPM_SUPPLY_S(APLL1_W_NAME, SUPPLY_SEQ_APLL, 413 SND_SOC_NOPM, 0, 0, 414 mtk_apll_event, 415 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 416 SND_SOC_DAPM_SUPPLY_S(APLL2_W_NAME, SUPPLY_SEQ_APLL, 417 SND_SOC_NOPM, 0, 0, 418 mtk_apll_event, 419 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 420 }; 421 422 static int mtk_afe_i2s_share_connect(struct snd_soc_dapm_widget *source, 423 struct snd_soc_dapm_widget *sink) 424 { 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; 429 430 i2s_priv = get_i2s_priv_by_name(afe, sink->name); 431 432 if (!i2s_priv) { 433 dev_warn(afe->dev, "%s(), i2s_priv == NULL", __func__); 434 return 0; 435 } 436 437 if (i2s_priv->share_i2s_id < 0) 438 return 0; 439 440 return i2s_priv->share_i2s_id == get_i2s_id_by_name(afe, source->name); 441 } 442 443 static int mtk_afe_i2s_hd_connect(struct snd_soc_dapm_widget *source, 444 struct snd_soc_dapm_widget *sink) 445 { 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; 450 451 i2s_priv = get_i2s_priv_by_name(afe, sink->name); 452 453 if (!i2s_priv) { 454 dev_warn(afe->dev, "%s(), i2s_priv == NULL", __func__); 455 return 0; 456 } 457 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; 461 462 /* check if share i2s need hd en */ 463 if (i2s_priv->share_i2s_id < 0) 464 return 0; 465 466 if (i2s_priv->share_i2s_id == get_i2s_id_by_name(afe, source->name)) 467 return i2s_priv->low_jitter_en; 468 469 return 0; 470 } 471 472 static int mtk_afe_i2s_apll_connect(struct snd_soc_dapm_widget *source, 473 struct snd_soc_dapm_widget *sink) 474 { 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; 479 int cur_apll; 480 int i2s_need_apll; 481 482 i2s_priv = get_i2s_priv_by_name(afe, w->name); 483 484 if (!i2s_priv) { 485 dev_warn(afe->dev, "%s(), i2s_priv == NULL", __func__); 486 return 0; 487 } 488 489 /* which apll */ 490 cur_apll = mt8183_get_apll_by_name(afe, source->name); 491 492 /* choose APLL from i2s rate */ 493 i2s_need_apll = mt8183_get_apll_by_rate(afe, i2s_priv->rate); 494 495 return (i2s_need_apll == cur_apll) ? 1 : 0; 496 } 497 498 static int mtk_afe_i2s_mclk_connect(struct snd_soc_dapm_widget *source, 499 struct snd_soc_dapm_widget *sink) 500 { 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; 505 506 i2s_priv = get_i2s_priv_by_name(afe, sink->name); 507 508 if (!i2s_priv) { 509 dev_warn(afe->dev, "%s(), i2s_priv == NULL", __func__); 510 return 0; 511 } 512 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; 516 517 /* check if share i2s need mclk */ 518 if (i2s_priv->share_i2s_id < 0) 519 return 0; 520 521 if (i2s_priv->share_i2s_id == get_i2s_id_by_name(afe, source->name)) 522 return (i2s_priv->mclk_rate > 0) ? 1 : 0; 523 524 return 0; 525 } 526 527 static int mtk_afe_mclk_apll_connect(struct snd_soc_dapm_widget *source, 528 struct snd_soc_dapm_widget *sink) 529 { 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; 534 int cur_apll; 535 536 i2s_priv = get_i2s_priv_by_name(afe, w->name); 537 538 if (!i2s_priv) { 539 dev_warn(afe->dev, "%s(), i2s_priv == NULL", __func__); 540 return 0; 541 } 542 543 /* which apll */ 544 cur_apll = mt8183_get_apll_by_name(afe, source->name); 545 546 return (i2s_priv->mclk_apll == cur_apll) ? 1 : 0; 547 } 548 549 static const struct snd_soc_dapm_route mtk_dai_i2s_routes[] = { 550 /* i2s0 */ 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}, 556 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}, 564 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}, 572 573 /* i2s1 */ 574 {"I2S1_CH1", "DL1_CH1", "DL1"}, 575 {"I2S1_CH2", "DL1_CH2", "DL1"}, 576 577 {"I2S1_CH1", "DL2_CH1", "DL2"}, 578 {"I2S1_CH2", "DL2_CH2", "DL2"}, 579 580 {"I2S1_CH1", "DL3_CH1", "DL3"}, 581 {"I2S1_CH2", "DL3_CH2", "DL3"}, 582 583 {"I2S1", NULL, "I2S1_CH1"}, 584 {"I2S1", NULL, "I2S1_CH2"}, 585 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}, 591 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}, 599 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}, 607 608 /* i2s2 */ 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}, 614 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}, 622 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}, 630 631 /* i2s3 */ 632 {"I2S3_CH1", "DL1_CH1", "DL1"}, 633 {"I2S3_CH2", "DL1_CH2", "DL1"}, 634 635 {"I2S3_CH1", "DL2_CH1", "DL2"}, 636 {"I2S3_CH2", "DL2_CH2", "DL2"}, 637 638 {"I2S3_CH1", "DL3_CH1", "DL3"}, 639 {"I2S3_CH2", "DL3_CH2", "DL3"}, 640 641 {"I2S3", NULL, "I2S3_CH1"}, 642 {"I2S3", NULL, "I2S3_CH2"}, 643 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}, 649 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}, 657 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}, 665 666 /* i2s5 */ 667 {"I2S5_CH1", "DL1_CH1", "DL1"}, 668 {"I2S5_CH2", "DL1_CH2", "DL1"}, 669 670 {"I2S5_CH1", "DL2_CH1", "DL2"}, 671 {"I2S5_CH2", "DL2_CH2", "DL2"}, 672 673 {"I2S5_CH1", "DL3_CH1", "DL3"}, 674 {"I2S5_CH2", "DL3_CH2", "DL3"}, 675 676 {"I2S5", NULL, "I2S5_CH1"}, 677 {"I2S5", NULL, "I2S5_CH2"}, 678 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"}, 684 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}, 692 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}, 700 }; 701 702 /* dai ops */ 703 static int mtk_dai_i2s_config(struct mtk_base_afe *afe, 704 struct snd_pcm_hw_params *params, 705 int i2s_id) 706 { 707 struct mt8183_afe_private *afe_priv = afe->platform_priv; 708 struct mtk_afe_i2s_priv *i2s_priv = afe_priv->dai_priv[i2s_id]; 709 710 unsigned int rate = params_rate(params); 711 unsigned int rate_reg = mt8183_rate_transform(afe->dev, 712 rate, i2s_id); 713 snd_pcm_format_t format = params_format(params); 714 unsigned int i2s_con = 0; 715 int ret = 0; 716 717 dev_info(afe->dev, "%s(), id %d, rate %d, format %d\n", 718 __func__, 719 i2s_id, 720 rate, format); 721 722 if (i2s_priv) 723 i2s_priv->rate = rate; 724 else 725 dev_warn(afe->dev, "%s(), i2s_priv == NULL", __func__); 726 727 switch (i2s_id) { 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); 736 break; 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); 744 break; 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); 752 break; 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); 759 break; 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); 766 break; 767 default: 768 dev_warn(afe->dev, "%s(), id %d not support\n", 769 __func__, i2s_id); 770 return -EINVAL; 771 } 772 773 /* set share i2s */ 774 if (i2s_priv && i2s_priv->share_i2s_id >= 0) 775 ret = mtk_dai_i2s_config(afe, params, i2s_priv->share_i2s_id); 776 777 return ret; 778 } 779 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) 783 { 784 struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); 785 786 return mtk_dai_i2s_config(afe, params, dai->id); 787 } 788 789 static int mtk_dai_i2s_set_sysclk(struct snd_soc_dai *dai, 790 int clk_id, unsigned int freq, int dir) 791 { 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]; 795 int apll; 796 int apll_rate; 797 798 if (!i2s_priv) { 799 dev_warn(afe->dev, "%s(), i2s_priv == NULL", __func__); 800 return -EINVAL; 801 } 802 803 if (dir != SND_SOC_CLOCK_OUT) { 804 dev_warn(afe->dev, "%s(), dir != SND_SOC_CLOCK_OUT", __func__); 805 return -EINVAL; 806 } 807 808 dev_info(afe->dev, "%s(), freq %d\n", __func__, freq); 809 810 apll = mt8183_get_apll_by_rate(afe, freq); 811 apll_rate = mt8183_get_apll_rate(afe, apll); 812 813 if (freq > apll_rate) { 814 dev_warn(afe->dev, "%s(), freq > apll rate", __func__); 815 return -EINVAL; 816 } 817 818 if (apll_rate % freq != 0) { 819 dev_warn(afe->dev, "%s(), APLL cannot generate freq Hz", 820 __func__); 821 return -EINVAL; 822 } 823 824 i2s_priv->mclk_rate = freq; 825 i2s_priv->mclk_apll = apll; 826 827 if (i2s_priv->share_i2s_id > 0) { 828 struct mtk_afe_i2s_priv *share_i2s_priv; 829 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", 833 __func__); 834 return -EINVAL; 835 } 836 837 share_i2s_priv->mclk_rate = i2s_priv->mclk_rate; 838 share_i2s_priv->mclk_apll = i2s_priv->mclk_apll; 839 } 840 841 return 0; 842 } 843 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, 847 }; 848 849 /* dai driver */ 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) 855 856 #define MTK_I2S_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ 857 SNDRV_PCM_FMTBIT_S24_LE |\ 858 SNDRV_PCM_FMTBIT_S32_LE) 859 860 static struct snd_soc_dai_driver mtk_dai_i2s_driver[] = { 861 { 862 .name = "I2S0", 863 .id = MT8183_DAI_I2S_0, 864 .capture = { 865 .stream_name = "I2S0", 866 .channels_min = 1, 867 .channels_max = 2, 868 .rates = MTK_I2S_RATES, 869 .formats = MTK_I2S_FORMATS, 870 }, 871 .ops = &mtk_dai_i2s_ops, 872 }, 873 { 874 .name = "I2S1", 875 .id = MT8183_DAI_I2S_1, 876 .playback = { 877 .stream_name = "I2S1", 878 .channels_min = 1, 879 .channels_max = 2, 880 .rates = MTK_I2S_RATES, 881 .formats = MTK_I2S_FORMATS, 882 }, 883 .ops = &mtk_dai_i2s_ops, 884 }, 885 { 886 .name = "I2S2", 887 .id = MT8183_DAI_I2S_2, 888 .capture = { 889 .stream_name = "I2S2", 890 .channels_min = 1, 891 .channels_max = 2, 892 .rates = MTK_I2S_RATES, 893 .formats = MTK_I2S_FORMATS, 894 }, 895 .ops = &mtk_dai_i2s_ops, 896 }, 897 { 898 .name = "I2S3", 899 .id = MT8183_DAI_I2S_3, 900 .playback = { 901 .stream_name = "I2S3", 902 .channels_min = 1, 903 .channels_max = 2, 904 .rates = MTK_I2S_RATES, 905 .formats = MTK_I2S_FORMATS, 906 }, 907 .ops = &mtk_dai_i2s_ops, 908 }, 909 { 910 .name = "I2S5", 911 .id = MT8183_DAI_I2S_5, 912 .playback = { 913 .stream_name = "I2S5", 914 .channels_min = 1, 915 .channels_max = 2, 916 .rates = MTK_I2S_RATES, 917 .formats = MTK_I2S_FORMATS, 918 }, 919 .ops = &mtk_dai_i2s_ops, 920 }, 921 }; 922 923 /* this enum is merely for mtk_afe_i2s_priv declare */ 924 enum { 925 DAI_I2S0 = 0, 926 DAI_I2S1, 927 DAI_I2S2, 928 DAI_I2S3, 929 DAI_I2S5, 930 DAI_I2S_NUM, 931 }; 932 933 static const struct mtk_afe_i2s_priv mt8183_i2s_priv[DAI_I2S_NUM] = { 934 [DAI_I2S0] = { 935 .id = MT8183_DAI_I2S_0, 936 .mclk_id = MT8183_I2S0_MCK, 937 .share_property_name = "i2s0-share", 938 .share_i2s_id = -1, 939 }, 940 [DAI_I2S1] = { 941 .id = MT8183_DAI_I2S_1, 942 .mclk_id = MT8183_I2S1_MCK, 943 .share_property_name = "i2s1-share", 944 .share_i2s_id = -1, 945 }, 946 [DAI_I2S2] = { 947 .id = MT8183_DAI_I2S_2, 948 .mclk_id = MT8183_I2S2_MCK, 949 .share_property_name = "i2s2-share", 950 .share_i2s_id = -1, 951 }, 952 [DAI_I2S3] = { 953 .id = MT8183_DAI_I2S_3, 954 .mclk_id = MT8183_I2S3_MCK, 955 .share_property_name = "i2s3-share", 956 .share_i2s_id = -1, 957 }, 958 [DAI_I2S5] = { 959 .id = MT8183_DAI_I2S_5, 960 .mclk_id = MT8183_I2S5_MCK, 961 .share_property_name = "i2s5-share", 962 .share_i2s_id = -1, 963 }, 964 }; 965 966 static int mt8183_dai_i2s_get_share(struct mtk_base_afe *afe) 967 { 968 struct mt8183_afe_private *afe_priv = afe->platform_priv; 969 const struct device_node *of_node = afe->dev->of_node; 970 const char *of_str; 971 const char *property_name; 972 struct mtk_afe_i2s_priv *i2s_priv; 973 int i; 974 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)) 979 continue; 980 i2s_priv->share_i2s_id = get_i2s_id_by_name(afe, of_str); 981 } 982 983 return 0; 984 } 985 986 static int mt8183_dai_i2s_set_priv(struct mtk_base_afe *afe) 987 { 988 struct mt8183_afe_private *afe_priv = afe->platform_priv; 989 struct mtk_afe_i2s_priv *i2s_priv; 990 int i; 991 992 for (i = 0; i < DAI_I2S_NUM; i++) { 993 i2s_priv = devm_kzalloc(afe->dev, 994 sizeof(struct mtk_afe_i2s_priv), 995 GFP_KERNEL); 996 if (!i2s_priv) 997 return -ENOMEM; 998 999 memcpy(i2s_priv, &mt8183_i2s_priv[i], 1000 sizeof(struct mtk_afe_i2s_priv)); 1001 1002 afe_priv->dai_priv[mt8183_i2s_priv[i].id] = i2s_priv; 1003 } 1004 1005 return 0; 1006 } 1007 1008 int mt8183_dai_i2s_register(struct mtk_base_afe *afe) 1009 { 1010 struct mtk_base_afe_dai *dai; 1011 int ret; 1012 1013 dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL); 1014 if (!dai) 1015 return -ENOMEM; 1016 1017 list_add(&dai->list, &afe->sub_dais); 1018 1019 dai->dai_drivers = mtk_dai_i2s_driver; 1020 dai->num_dai_drivers = ARRAY_SIZE(mtk_dai_i2s_driver); 1021 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); 1028 1029 /* set all dai i2s private data */ 1030 ret = mt8183_dai_i2s_set_priv(afe); 1031 if (ret) 1032 return ret; 1033 1034 /* parse share i2s */ 1035 ret = mt8183_dai_i2s_get_share(afe); 1036 if (ret) 1037 return ret; 1038 1039 return 0; 1040 } 1041