1 // SPDX-License-Identifier: GPL-2.0 2 // 3 // MediaTek ALSA SoC Audio DAI I2S Control 4 // 5 // Copyright (c) 2018 MediaTek Inc. 6 // Author: KaiChieh Chuang <kaichieh.chuang@mediatek.com> 7 8 #include <linux/bitops.h> 9 #include <linux/regmap.h> 10 #include <sound/pcm_params.h> 11 #include "mt8183-afe-clk.h" 12 #include "mt8183-afe-common.h" 13 #include "mt8183-interconnection.h" 14 #include "mt8183-reg.h" 15 16 enum { 17 I2S_FMT_EIAJ = 0, 18 I2S_FMT_I2S = 1, 19 }; 20 21 enum { 22 I2S_WLEN_16_BIT = 0, 23 I2S_WLEN_32_BIT = 1, 24 }; 25 26 enum { 27 I2S_HD_NORMAL = 0, 28 I2S_HD_LOW_JITTER = 1, 29 }; 30 31 enum { 32 I2S1_SEL_O28_O29 = 0, 33 I2S1_SEL_O03_O04 = 1, 34 }; 35 36 enum { 37 I2S_IN_PAD_CONNSYS = 0, 38 I2S_IN_PAD_IO_MUX = 1, 39 }; 40 41 struct mtk_afe_i2s_priv { 42 int id; 43 int rate; /* for determine which apll to use */ 44 int low_jitter_en; 45 46 const char *share_property_name; 47 int share_i2s_id; 48 49 int mclk_id; 50 int mclk_rate; 51 int mclk_apll; 52 53 int use_eiaj; 54 }; 55 56 static unsigned int get_i2s_wlen(snd_pcm_format_t format) 57 { 58 return snd_pcm_format_physical_width(format) <= 16 ? 59 I2S_WLEN_16_BIT : I2S_WLEN_32_BIT; 60 } 61 62 #define MTK_AFE_I2S0_KCONTROL_NAME "I2S0_HD_Mux" 63 #define MTK_AFE_I2S1_KCONTROL_NAME "I2S1_HD_Mux" 64 #define MTK_AFE_I2S2_KCONTROL_NAME "I2S2_HD_Mux" 65 #define MTK_AFE_I2S3_KCONTROL_NAME "I2S3_HD_Mux" 66 #define MTK_AFE_I2S5_KCONTROL_NAME "I2S5_HD_Mux" 67 68 #define I2S0_HD_EN_W_NAME "I2S0_HD_EN" 69 #define I2S1_HD_EN_W_NAME "I2S1_HD_EN" 70 #define I2S2_HD_EN_W_NAME "I2S2_HD_EN" 71 #define I2S3_HD_EN_W_NAME "I2S3_HD_EN" 72 #define I2S5_HD_EN_W_NAME "I2S5_HD_EN" 73 74 #define I2S0_MCLK_EN_W_NAME "I2S0_MCLK_EN" 75 #define I2S1_MCLK_EN_W_NAME "I2S1_MCLK_EN" 76 #define I2S2_MCLK_EN_W_NAME "I2S2_MCLK_EN" 77 #define I2S3_MCLK_EN_W_NAME "I2S3_MCLK_EN" 78 #define I2S5_MCLK_EN_W_NAME "I2S5_MCLK_EN" 79 80 static int get_i2s_id_by_name(struct mtk_base_afe *afe, 81 const char *name) 82 { 83 if (strncmp(name, "I2S0", 4) == 0) 84 return MT8183_DAI_I2S_0; 85 else if (strncmp(name, "I2S1", 4) == 0) 86 return MT8183_DAI_I2S_1; 87 else if (strncmp(name, "I2S2", 4) == 0) 88 return MT8183_DAI_I2S_2; 89 else if (strncmp(name, "I2S3", 4) == 0) 90 return MT8183_DAI_I2S_3; 91 else if (strncmp(name, "I2S5", 4) == 0) 92 return MT8183_DAI_I2S_5; 93 else 94 return -EINVAL; 95 } 96 97 static struct mtk_afe_i2s_priv *get_i2s_priv_by_name(struct mtk_base_afe *afe, 98 const char *name) 99 { 100 struct mt8183_afe_private *afe_priv = afe->platform_priv; 101 int dai_id = get_i2s_id_by_name(afe, name); 102 103 if (dai_id < 0) 104 return NULL; 105 106 return afe_priv->dai_priv[dai_id]; 107 } 108 109 /* low jitter control */ 110 static const char * const mt8183_i2s_hd_str[] = { 111 "Normal", "Low_Jitter" 112 }; 113 114 static const struct soc_enum mt8183_i2s_enum[] = { 115 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(mt8183_i2s_hd_str), 116 mt8183_i2s_hd_str), 117 }; 118 119 static int mt8183_i2s_hd_get(struct snd_kcontrol *kcontrol, 120 struct snd_ctl_elem_value *ucontrol) 121 { 122 struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); 123 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); 124 struct mtk_afe_i2s_priv *i2s_priv; 125 126 i2s_priv = get_i2s_priv_by_name(afe, kcontrol->id.name); 127 128 if (!i2s_priv) { 129 dev_warn(afe->dev, "%s(), i2s_priv == NULL", __func__); 130 return -EINVAL; 131 } 132 133 ucontrol->value.integer.value[0] = i2s_priv->low_jitter_en; 134 135 return 0; 136 } 137 138 static int mt8183_i2s_hd_set(struct snd_kcontrol *kcontrol, 139 struct snd_ctl_elem_value *ucontrol) 140 { 141 struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); 142 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); 143 struct mtk_afe_i2s_priv *i2s_priv; 144 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 145 int hd_en; 146 147 if (ucontrol->value.enumerated.item[0] >= e->items) 148 return -EINVAL; 149 150 hd_en = ucontrol->value.integer.value[0]; 151 152 dev_info(afe->dev, "%s(), kcontrol name %s, hd_en %d\n", 153 __func__, kcontrol->id.name, hd_en); 154 155 i2s_priv = get_i2s_priv_by_name(afe, kcontrol->id.name); 156 157 if (!i2s_priv) { 158 dev_warn(afe->dev, "%s(), i2s_priv == NULL", __func__); 159 return -EINVAL; 160 } 161 162 i2s_priv->low_jitter_en = hd_en; 163 164 return 0; 165 } 166 167 static const struct snd_kcontrol_new mtk_dai_i2s_controls[] = { 168 SOC_ENUM_EXT(MTK_AFE_I2S0_KCONTROL_NAME, mt8183_i2s_enum[0], 169 mt8183_i2s_hd_get, mt8183_i2s_hd_set), 170 SOC_ENUM_EXT(MTK_AFE_I2S1_KCONTROL_NAME, mt8183_i2s_enum[0], 171 mt8183_i2s_hd_get, mt8183_i2s_hd_set), 172 SOC_ENUM_EXT(MTK_AFE_I2S2_KCONTROL_NAME, mt8183_i2s_enum[0], 173 mt8183_i2s_hd_get, mt8183_i2s_hd_set), 174 SOC_ENUM_EXT(MTK_AFE_I2S3_KCONTROL_NAME, mt8183_i2s_enum[0], 175 mt8183_i2s_hd_get, mt8183_i2s_hd_set), 176 SOC_ENUM_EXT(MTK_AFE_I2S5_KCONTROL_NAME, mt8183_i2s_enum[0], 177 mt8183_i2s_hd_get, mt8183_i2s_hd_set), 178 }; 179 180 /* dai component */ 181 /* interconnection */ 182 static const struct snd_kcontrol_new mtk_i2s3_ch1_mix[] = { 183 SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1", AFE_CONN0, I_DL1_CH1, 1, 0), 184 SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1", AFE_CONN0, I_DL2_CH1, 1, 0), 185 SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1", AFE_CONN0, I_DL3_CH1, 1, 0), 186 SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN0, 187 I_ADDA_UL_CH1, 1, 0), 188 SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH1", AFE_CONN0, 189 I_PCM_1_CAP_CH1, 1, 0), 190 SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH1", AFE_CONN0, 191 I_PCM_2_CAP_CH1, 1, 0), 192 }; 193 194 static const struct snd_kcontrol_new mtk_i2s3_ch2_mix[] = { 195 SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH2", AFE_CONN1, I_DL1_CH2, 1, 0), 196 SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH2", AFE_CONN1, I_DL2_CH2, 1, 0), 197 SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH2", AFE_CONN1, I_DL3_CH2, 1, 0), 198 SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN1, 199 I_ADDA_UL_CH2, 1, 0), 200 SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH1", AFE_CONN1, 201 I_PCM_1_CAP_CH1, 1, 0), 202 SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH1", AFE_CONN1, 203 I_PCM_2_CAP_CH1, 1, 0), 204 SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH2", AFE_CONN1, 205 I_PCM_1_CAP_CH2, 1, 0), 206 SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH2", AFE_CONN1, 207 I_PCM_2_CAP_CH2, 1, 0), 208 }; 209 210 static const struct snd_kcontrol_new mtk_i2s1_ch1_mix[] = { 211 SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1", AFE_CONN28, I_DL1_CH1, 1, 0), 212 SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1", AFE_CONN28, I_DL2_CH1, 1, 0), 213 SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1", AFE_CONN28, I_DL3_CH1, 1, 0), 214 SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN28, 215 I_ADDA_UL_CH1, 1, 0), 216 SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH1", AFE_CONN28, 217 I_PCM_1_CAP_CH1, 1, 0), 218 SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH1", AFE_CONN28, 219 I_PCM_2_CAP_CH1, 1, 0), 220 }; 221 222 static const struct snd_kcontrol_new mtk_i2s1_ch2_mix[] = { 223 SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH2", AFE_CONN29, I_DL1_CH2, 1, 0), 224 SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH2", AFE_CONN29, I_DL2_CH2, 1, 0), 225 SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH2", AFE_CONN29, I_DL3_CH2, 1, 0), 226 SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN29, 227 I_ADDA_UL_CH2, 1, 0), 228 SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH1", AFE_CONN29, 229 I_PCM_1_CAP_CH1, 1, 0), 230 SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH1", AFE_CONN29, 231 I_PCM_2_CAP_CH1, 1, 0), 232 SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH2", AFE_CONN29, 233 I_PCM_1_CAP_CH2, 1, 0), 234 SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH2", AFE_CONN29, 235 I_PCM_2_CAP_CH2, 1, 0), 236 }; 237 238 static const struct snd_kcontrol_new mtk_i2s5_ch1_mix[] = { 239 SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1", AFE_CONN30, I_DL1_CH1, 1, 0), 240 SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1", AFE_CONN30, I_DL2_CH1, 1, 0), 241 SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1", AFE_CONN30, I_DL3_CH1, 1, 0), 242 SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN30, 243 I_ADDA_UL_CH1, 1, 0), 244 SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH1", AFE_CONN30, 245 I_PCM_1_CAP_CH1, 1, 0), 246 SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH1", AFE_CONN30, 247 I_PCM_2_CAP_CH1, 1, 0), 248 }; 249 250 static const struct snd_kcontrol_new mtk_i2s5_ch2_mix[] = { 251 SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH2", AFE_CONN31, I_DL1_CH2, 1, 0), 252 SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH2", AFE_CONN31, I_DL2_CH2, 1, 0), 253 SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH2", AFE_CONN31, I_DL3_CH2, 1, 0), 254 SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN31, 255 I_ADDA_UL_CH2, 1, 0), 256 SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH1", AFE_CONN31, 257 I_PCM_1_CAP_CH1, 1, 0), 258 SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH1", AFE_CONN31, 259 I_PCM_2_CAP_CH1, 1, 0), 260 SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH2", AFE_CONN31, 261 I_PCM_1_CAP_CH2, 1, 0), 262 SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH2", AFE_CONN31, 263 I_PCM_2_CAP_CH2, 1, 0), 264 }; 265 266 enum { 267 SUPPLY_SEQ_APLL, 268 SUPPLY_SEQ_I2S_MCLK_EN, 269 SUPPLY_SEQ_I2S_HD_EN, 270 SUPPLY_SEQ_I2S_EN, 271 }; 272 273 static int mtk_apll_event(struct snd_soc_dapm_widget *w, 274 struct snd_kcontrol *kcontrol, 275 int event) 276 { 277 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); 278 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); 279 280 dev_info(cmpnt->dev, "%s(), name %s, event 0x%x\n", 281 __func__, w->name, event); 282 283 switch (event) { 284 case SND_SOC_DAPM_PRE_PMU: 285 if (strcmp(w->name, APLL1_W_NAME) == 0) 286 mt8183_apll1_enable(afe); 287 else 288 mt8183_apll2_enable(afe); 289 break; 290 case SND_SOC_DAPM_POST_PMD: 291 if (strcmp(w->name, APLL1_W_NAME) == 0) 292 mt8183_apll1_disable(afe); 293 else 294 mt8183_apll2_disable(afe); 295 break; 296 default: 297 break; 298 } 299 300 return 0; 301 } 302 303 static int mtk_mclk_en_event(struct snd_soc_dapm_widget *w, 304 struct snd_kcontrol *kcontrol, 305 int event) 306 { 307 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); 308 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); 309 struct mtk_afe_i2s_priv *i2s_priv; 310 311 dev_info(cmpnt->dev, "%s(), name %s, event 0x%x\n", 312 __func__, w->name, event); 313 314 i2s_priv = get_i2s_priv_by_name(afe, w->name); 315 316 if (!i2s_priv) { 317 dev_warn(afe->dev, "%s(), i2s_priv == NULL", __func__); 318 return -EINVAL; 319 } 320 321 switch (event) { 322 case SND_SOC_DAPM_PRE_PMU: 323 mt8183_mck_enable(afe, i2s_priv->mclk_id, i2s_priv->mclk_rate); 324 break; 325 case SND_SOC_DAPM_POST_PMD: 326 i2s_priv->mclk_rate = 0; 327 mt8183_mck_disable(afe, i2s_priv->mclk_id); 328 break; 329 default: 330 break; 331 } 332 333 return 0; 334 } 335 336 static const struct snd_soc_dapm_widget mtk_dai_i2s_widgets[] = { 337 SND_SOC_DAPM_MIXER("I2S1_CH1", SND_SOC_NOPM, 0, 0, 338 mtk_i2s1_ch1_mix, 339 ARRAY_SIZE(mtk_i2s1_ch1_mix)), 340 SND_SOC_DAPM_MIXER("I2S1_CH2", SND_SOC_NOPM, 0, 0, 341 mtk_i2s1_ch2_mix, 342 ARRAY_SIZE(mtk_i2s1_ch2_mix)), 343 344 SND_SOC_DAPM_MIXER("I2S3_CH1", SND_SOC_NOPM, 0, 0, 345 mtk_i2s3_ch1_mix, 346 ARRAY_SIZE(mtk_i2s3_ch1_mix)), 347 SND_SOC_DAPM_MIXER("I2S3_CH2", SND_SOC_NOPM, 0, 0, 348 mtk_i2s3_ch2_mix, 349 ARRAY_SIZE(mtk_i2s3_ch2_mix)), 350 351 SND_SOC_DAPM_MIXER("I2S5_CH1", SND_SOC_NOPM, 0, 0, 352 mtk_i2s5_ch1_mix, 353 ARRAY_SIZE(mtk_i2s5_ch1_mix)), 354 SND_SOC_DAPM_MIXER("I2S5_CH2", SND_SOC_NOPM, 0, 0, 355 mtk_i2s5_ch2_mix, 356 ARRAY_SIZE(mtk_i2s5_ch2_mix)), 357 358 /* i2s en*/ 359 SND_SOC_DAPM_SUPPLY_S("I2S0_EN", SUPPLY_SEQ_I2S_EN, 360 AFE_I2S_CON, I2S_EN_SFT, 0, 361 NULL, 0), 362 SND_SOC_DAPM_SUPPLY_S("I2S1_EN", SUPPLY_SEQ_I2S_EN, 363 AFE_I2S_CON1, I2S_EN_SFT, 0, 364 NULL, 0), 365 SND_SOC_DAPM_SUPPLY_S("I2S2_EN", SUPPLY_SEQ_I2S_EN, 366 AFE_I2S_CON2, I2S_EN_SFT, 0, 367 NULL, 0), 368 SND_SOC_DAPM_SUPPLY_S("I2S3_EN", SUPPLY_SEQ_I2S_EN, 369 AFE_I2S_CON3, I2S_EN_SFT, 0, 370 NULL, 0), 371 SND_SOC_DAPM_SUPPLY_S("I2S5_EN", SUPPLY_SEQ_I2S_EN, 372 AFE_I2S_CON4, I2S5_EN_SFT, 0, 373 NULL, 0), 374 /* i2s hd en */ 375 SND_SOC_DAPM_SUPPLY_S(I2S0_HD_EN_W_NAME, SUPPLY_SEQ_I2S_HD_EN, 376 AFE_I2S_CON, I2S1_HD_EN_SFT, 0, 377 NULL, 0), 378 SND_SOC_DAPM_SUPPLY_S(I2S1_HD_EN_W_NAME, SUPPLY_SEQ_I2S_HD_EN, 379 AFE_I2S_CON1, I2S2_HD_EN_SFT, 0, 380 NULL, 0), 381 SND_SOC_DAPM_SUPPLY_S(I2S2_HD_EN_W_NAME, SUPPLY_SEQ_I2S_HD_EN, 382 AFE_I2S_CON2, I2S3_HD_EN_SFT, 0, 383 NULL, 0), 384 SND_SOC_DAPM_SUPPLY_S(I2S3_HD_EN_W_NAME, SUPPLY_SEQ_I2S_HD_EN, 385 AFE_I2S_CON3, I2S4_HD_EN_SFT, 0, 386 NULL, 0), 387 SND_SOC_DAPM_SUPPLY_S(I2S5_HD_EN_W_NAME, SUPPLY_SEQ_I2S_HD_EN, 388 AFE_I2S_CON4, I2S5_HD_EN_SFT, 0, 389 NULL, 0), 390 391 /* i2s mclk en */ 392 SND_SOC_DAPM_SUPPLY_S(I2S0_MCLK_EN_W_NAME, SUPPLY_SEQ_I2S_MCLK_EN, 393 SND_SOC_NOPM, 0, 0, 394 mtk_mclk_en_event, 395 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 396 SND_SOC_DAPM_SUPPLY_S(I2S1_MCLK_EN_W_NAME, SUPPLY_SEQ_I2S_MCLK_EN, 397 SND_SOC_NOPM, 0, 0, 398 mtk_mclk_en_event, 399 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 400 SND_SOC_DAPM_SUPPLY_S(I2S2_MCLK_EN_W_NAME, SUPPLY_SEQ_I2S_MCLK_EN, 401 SND_SOC_NOPM, 0, 0, 402 mtk_mclk_en_event, 403 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 404 SND_SOC_DAPM_SUPPLY_S(I2S3_MCLK_EN_W_NAME, SUPPLY_SEQ_I2S_MCLK_EN, 405 SND_SOC_NOPM, 0, 0, 406 mtk_mclk_en_event, 407 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 408 SND_SOC_DAPM_SUPPLY_S(I2S5_MCLK_EN_W_NAME, SUPPLY_SEQ_I2S_MCLK_EN, 409 SND_SOC_NOPM, 0, 0, 410 mtk_mclk_en_event, 411 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 412 413 /* apll */ 414 SND_SOC_DAPM_SUPPLY_S(APLL1_W_NAME, SUPPLY_SEQ_APLL, 415 SND_SOC_NOPM, 0, 0, 416 mtk_apll_event, 417 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 418 SND_SOC_DAPM_SUPPLY_S(APLL2_W_NAME, SUPPLY_SEQ_APLL, 419 SND_SOC_NOPM, 0, 0, 420 mtk_apll_event, 421 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 422 }; 423 424 static int mtk_afe_i2s_share_connect(struct snd_soc_dapm_widget *source, 425 struct snd_soc_dapm_widget *sink) 426 { 427 struct snd_soc_dapm_widget *w = sink; 428 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); 429 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); 430 struct mtk_afe_i2s_priv *i2s_priv; 431 432 i2s_priv = get_i2s_priv_by_name(afe, sink->name); 433 434 if (!i2s_priv) { 435 dev_warn(afe->dev, "%s(), i2s_priv == NULL", __func__); 436 return 0; 437 } 438 439 if (i2s_priv->share_i2s_id < 0) 440 return 0; 441 442 return i2s_priv->share_i2s_id == get_i2s_id_by_name(afe, source->name); 443 } 444 445 static int mtk_afe_i2s_hd_connect(struct snd_soc_dapm_widget *source, 446 struct snd_soc_dapm_widget *sink) 447 { 448 struct snd_soc_dapm_widget *w = sink; 449 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); 450 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); 451 struct mtk_afe_i2s_priv *i2s_priv; 452 453 i2s_priv = get_i2s_priv_by_name(afe, sink->name); 454 455 if (!i2s_priv) { 456 dev_warn(afe->dev, "%s(), i2s_priv == NULL", __func__); 457 return 0; 458 } 459 460 if (get_i2s_id_by_name(afe, sink->name) == 461 get_i2s_id_by_name(afe, source->name)) 462 return i2s_priv->low_jitter_en; 463 464 /* check if share i2s need hd en */ 465 if (i2s_priv->share_i2s_id < 0) 466 return 0; 467 468 if (i2s_priv->share_i2s_id == get_i2s_id_by_name(afe, source->name)) 469 return i2s_priv->low_jitter_en; 470 471 return 0; 472 } 473 474 static int mtk_afe_i2s_apll_connect(struct snd_soc_dapm_widget *source, 475 struct snd_soc_dapm_widget *sink) 476 { 477 struct snd_soc_dapm_widget *w = sink; 478 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); 479 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); 480 struct mtk_afe_i2s_priv *i2s_priv; 481 int cur_apll; 482 int i2s_need_apll; 483 484 i2s_priv = get_i2s_priv_by_name(afe, w->name); 485 486 if (!i2s_priv) { 487 dev_warn(afe->dev, "%s(), i2s_priv == NULL", __func__); 488 return 0; 489 } 490 491 /* which apll */ 492 cur_apll = mt8183_get_apll_by_name(afe, source->name); 493 494 /* choose APLL from i2s rate */ 495 i2s_need_apll = mt8183_get_apll_by_rate(afe, i2s_priv->rate); 496 497 return (i2s_need_apll == cur_apll) ? 1 : 0; 498 } 499 500 static int mtk_afe_i2s_mclk_connect(struct snd_soc_dapm_widget *source, 501 struct snd_soc_dapm_widget *sink) 502 { 503 struct snd_soc_dapm_widget *w = sink; 504 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); 505 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); 506 struct mtk_afe_i2s_priv *i2s_priv; 507 508 i2s_priv = get_i2s_priv_by_name(afe, sink->name); 509 510 if (!i2s_priv) { 511 dev_warn(afe->dev, "%s(), i2s_priv == NULL", __func__); 512 return 0; 513 } 514 515 if (get_i2s_id_by_name(afe, sink->name) == 516 get_i2s_id_by_name(afe, source->name)) 517 return (i2s_priv->mclk_rate > 0) ? 1 : 0; 518 519 /* check if share i2s need mclk */ 520 if (i2s_priv->share_i2s_id < 0) 521 return 0; 522 523 if (i2s_priv->share_i2s_id == get_i2s_id_by_name(afe, source->name)) 524 return (i2s_priv->mclk_rate > 0) ? 1 : 0; 525 526 return 0; 527 } 528 529 static int mtk_afe_mclk_apll_connect(struct snd_soc_dapm_widget *source, 530 struct snd_soc_dapm_widget *sink) 531 { 532 struct snd_soc_dapm_widget *w = sink; 533 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); 534 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); 535 struct mtk_afe_i2s_priv *i2s_priv; 536 int cur_apll; 537 538 i2s_priv = get_i2s_priv_by_name(afe, w->name); 539 540 if (!i2s_priv) { 541 dev_warn(afe->dev, "%s(), i2s_priv == NULL", __func__); 542 return 0; 543 } 544 545 /* which apll */ 546 cur_apll = mt8183_get_apll_by_name(afe, source->name); 547 548 return (i2s_priv->mclk_apll == cur_apll) ? 1 : 0; 549 } 550 551 static const struct snd_soc_dapm_route mtk_dai_i2s_routes[] = { 552 /* i2s0 */ 553 {"I2S0", NULL, "I2S0_EN"}, 554 {"I2S0", NULL, "I2S1_EN", mtk_afe_i2s_share_connect}, 555 {"I2S0", NULL, "I2S2_EN", mtk_afe_i2s_share_connect}, 556 {"I2S0", NULL, "I2S3_EN", mtk_afe_i2s_share_connect}, 557 {"I2S0", NULL, "I2S5_EN", mtk_afe_i2s_share_connect}, 558 559 {"I2S0", NULL, I2S0_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, 560 {"I2S0", NULL, I2S1_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, 561 {"I2S0", NULL, I2S2_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, 562 {"I2S0", NULL, I2S3_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, 563 {"I2S0", NULL, I2S5_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, 564 {I2S0_HD_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_i2s_apll_connect}, 565 {I2S0_HD_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_i2s_apll_connect}, 566 567 {"I2S0", NULL, I2S0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, 568 {"I2S0", NULL, I2S1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, 569 {"I2S0", NULL, I2S2_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, 570 {"I2S0", NULL, I2S3_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, 571 {"I2S0", NULL, I2S5_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, 572 {I2S0_MCLK_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect}, 573 {I2S0_MCLK_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect}, 574 575 /* i2s1 */ 576 {"I2S1_CH1", "DL1_CH1", "DL1"}, 577 {"I2S1_CH2", "DL1_CH2", "DL1"}, 578 579 {"I2S1_CH1", "DL2_CH1", "DL2"}, 580 {"I2S1_CH2", "DL2_CH2", "DL2"}, 581 582 {"I2S1_CH1", "DL3_CH1", "DL3"}, 583 {"I2S1_CH2", "DL3_CH2", "DL3"}, 584 585 {"I2S1", NULL, "I2S1_CH1"}, 586 {"I2S1", NULL, "I2S1_CH2"}, 587 588 {"I2S1", NULL, "I2S0_EN", mtk_afe_i2s_share_connect}, 589 {"I2S1", NULL, "I2S1_EN"}, 590 {"I2S1", NULL, "I2S2_EN", mtk_afe_i2s_share_connect}, 591 {"I2S1", NULL, "I2S3_EN", mtk_afe_i2s_share_connect}, 592 {"I2S1", NULL, "I2S5_EN", mtk_afe_i2s_share_connect}, 593 594 {"I2S1", NULL, I2S0_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, 595 {"I2S1", NULL, I2S1_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, 596 {"I2S1", NULL, I2S2_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, 597 {"I2S1", NULL, I2S3_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, 598 {"I2S1", NULL, I2S5_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, 599 {I2S1_HD_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_i2s_apll_connect}, 600 {I2S1_HD_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_i2s_apll_connect}, 601 602 {"I2S1", NULL, I2S0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, 603 {"I2S1", NULL, I2S1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, 604 {"I2S1", NULL, I2S2_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, 605 {"I2S1", NULL, I2S3_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, 606 {"I2S1", NULL, I2S5_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, 607 {I2S1_MCLK_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect}, 608 {I2S1_MCLK_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect}, 609 610 /* i2s2 */ 611 {"I2S2", NULL, "I2S0_EN", mtk_afe_i2s_share_connect}, 612 {"I2S2", NULL, "I2S1_EN", mtk_afe_i2s_share_connect}, 613 {"I2S2", NULL, "I2S2_EN"}, 614 {"I2S2", NULL, "I2S3_EN", mtk_afe_i2s_share_connect}, 615 {"I2S2", NULL, "I2S5_EN", mtk_afe_i2s_share_connect}, 616 617 {"I2S2", NULL, I2S0_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, 618 {"I2S2", NULL, I2S1_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, 619 {"I2S2", NULL, I2S2_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, 620 {"I2S2", NULL, I2S3_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, 621 {"I2S2", NULL, I2S5_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, 622 {I2S2_HD_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_i2s_apll_connect}, 623 {I2S2_HD_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_i2s_apll_connect}, 624 625 {"I2S2", NULL, I2S0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, 626 {"I2S2", NULL, I2S1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, 627 {"I2S2", NULL, I2S2_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, 628 {"I2S2", NULL, I2S3_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, 629 {"I2S2", NULL, I2S5_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, 630 {I2S2_MCLK_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect}, 631 {I2S2_MCLK_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect}, 632 633 /* i2s3 */ 634 {"I2S3_CH1", "DL1_CH1", "DL1"}, 635 {"I2S3_CH2", "DL1_CH2", "DL1"}, 636 637 {"I2S3_CH1", "DL2_CH1", "DL2"}, 638 {"I2S3_CH2", "DL2_CH2", "DL2"}, 639 640 {"I2S3_CH1", "DL3_CH1", "DL3"}, 641 {"I2S3_CH2", "DL3_CH2", "DL3"}, 642 643 {"I2S3", NULL, "I2S3_CH1"}, 644 {"I2S3", NULL, "I2S3_CH2"}, 645 646 {"I2S3", NULL, "I2S0_EN", mtk_afe_i2s_share_connect}, 647 {"I2S3", NULL, "I2S1_EN", mtk_afe_i2s_share_connect}, 648 {"I2S3", NULL, "I2S2_EN", mtk_afe_i2s_share_connect}, 649 {"I2S3", NULL, "I2S3_EN"}, 650 {"I2S3", NULL, "I2S5_EN", mtk_afe_i2s_share_connect}, 651 652 {"I2S3", NULL, I2S0_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, 653 {"I2S3", NULL, I2S1_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, 654 {"I2S3", NULL, I2S2_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, 655 {"I2S3", NULL, I2S3_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, 656 {"I2S3", NULL, I2S5_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, 657 {I2S3_HD_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_i2s_apll_connect}, 658 {I2S3_HD_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_i2s_apll_connect}, 659 660 {"I2S3", NULL, I2S0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, 661 {"I2S3", NULL, I2S1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, 662 {"I2S3", NULL, I2S2_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, 663 {"I2S3", NULL, I2S3_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, 664 {"I2S3", NULL, I2S5_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, 665 {I2S3_MCLK_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect}, 666 {I2S3_MCLK_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect}, 667 668 /* i2s5 */ 669 {"I2S5_CH1", "DL1_CH1", "DL1"}, 670 {"I2S5_CH2", "DL1_CH2", "DL1"}, 671 672 {"I2S5_CH1", "DL2_CH1", "DL2"}, 673 {"I2S5_CH2", "DL2_CH2", "DL2"}, 674 675 {"I2S5_CH1", "DL3_CH1", "DL3"}, 676 {"I2S5_CH2", "DL3_CH2", "DL3"}, 677 678 {"I2S5", NULL, "I2S5_CH1"}, 679 {"I2S5", NULL, "I2S5_CH2"}, 680 681 {"I2S5", NULL, "I2S0_EN", mtk_afe_i2s_share_connect}, 682 {"I2S5", NULL, "I2S1_EN", mtk_afe_i2s_share_connect}, 683 {"I2S5", NULL, "I2S2_EN", mtk_afe_i2s_share_connect}, 684 {"I2S5", NULL, "I2S3_EN", mtk_afe_i2s_share_connect}, 685 {"I2S5", NULL, "I2S5_EN"}, 686 687 {"I2S5", NULL, I2S0_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, 688 {"I2S5", NULL, I2S1_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, 689 {"I2S5", NULL, I2S2_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, 690 {"I2S5", NULL, I2S3_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, 691 {"I2S5", NULL, I2S5_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, 692 {I2S5_HD_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_i2s_apll_connect}, 693 {I2S5_HD_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_i2s_apll_connect}, 694 695 {"I2S5", NULL, I2S0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, 696 {"I2S5", NULL, I2S1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, 697 {"I2S5", NULL, I2S2_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, 698 {"I2S5", NULL, I2S3_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, 699 {"I2S5", NULL, I2S5_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, 700 {I2S5_MCLK_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect}, 701 {I2S5_MCLK_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect}, 702 }; 703 704 /* dai ops */ 705 static int mtk_dai_i2s_config(struct mtk_base_afe *afe, 706 struct snd_pcm_hw_params *params, 707 int i2s_id) 708 { 709 struct mt8183_afe_private *afe_priv = afe->platform_priv; 710 struct mtk_afe_i2s_priv *i2s_priv = afe_priv->dai_priv[i2s_id]; 711 712 unsigned int rate = params_rate(params); 713 unsigned int rate_reg = mt8183_rate_transform(afe->dev, 714 rate, i2s_id); 715 snd_pcm_format_t format = params_format(params); 716 unsigned int i2s_con = 0, fmt_con = I2S_FMT_I2S << I2S_FMT_SFT; 717 int ret = 0; 718 719 dev_info(afe->dev, "%s(), id %d, rate %d, format %d\n", 720 __func__, 721 i2s_id, 722 rate, format); 723 724 if (i2s_priv) { 725 i2s_priv->rate = rate; 726 727 if (i2s_priv->use_eiaj) 728 fmt_con = I2S_FMT_EIAJ << I2S_FMT_SFT; 729 } else { 730 dev_warn(afe->dev, "%s(), i2s_priv == NULL", __func__); 731 } 732 733 switch (i2s_id) { 734 case MT8183_DAI_I2S_0: 735 regmap_update_bits(afe->regmap, AFE_DAC_CON1, 736 I2S_MODE_MASK_SFT, rate_reg << I2S_MODE_SFT); 737 i2s_con = I2S_IN_PAD_IO_MUX << I2SIN_PAD_SEL_SFT; 738 i2s_con |= fmt_con; 739 i2s_con |= get_i2s_wlen(format) << I2S_WLEN_SFT; 740 regmap_update_bits(afe->regmap, AFE_I2S_CON, 741 0xffffeffe, i2s_con); 742 break; 743 case MT8183_DAI_I2S_1: 744 i2s_con = I2S1_SEL_O28_O29 << I2S2_SEL_O03_O04_SFT; 745 i2s_con |= rate_reg << I2S2_OUT_MODE_SFT; 746 i2s_con |= fmt_con; 747 i2s_con |= get_i2s_wlen(format) << I2S2_WLEN_SFT; 748 regmap_update_bits(afe->regmap, AFE_I2S_CON1, 749 0xffffeffe, i2s_con); 750 break; 751 case MT8183_DAI_I2S_2: 752 i2s_con = 8 << I2S3_UPDATE_WORD_SFT; 753 i2s_con |= rate_reg << I2S3_OUT_MODE_SFT; 754 i2s_con |= fmt_con; 755 i2s_con |= get_i2s_wlen(format) << I2S3_WLEN_SFT; 756 regmap_update_bits(afe->regmap, AFE_I2S_CON2, 757 0xffffeffe, i2s_con); 758 break; 759 case MT8183_DAI_I2S_3: 760 i2s_con = rate_reg << I2S4_OUT_MODE_SFT; 761 i2s_con |= fmt_con; 762 i2s_con |= get_i2s_wlen(format) << I2S4_WLEN_SFT; 763 regmap_update_bits(afe->regmap, AFE_I2S_CON3, 764 0xffffeffe, i2s_con); 765 break; 766 case MT8183_DAI_I2S_5: 767 i2s_con = rate_reg << I2S5_OUT_MODE_SFT; 768 i2s_con |= fmt_con; 769 i2s_con |= get_i2s_wlen(format) << I2S5_WLEN_SFT; 770 regmap_update_bits(afe->regmap, AFE_I2S_CON4, 771 0xffffeffe, i2s_con); 772 break; 773 default: 774 dev_warn(afe->dev, "%s(), id %d not support\n", 775 __func__, i2s_id); 776 return -EINVAL; 777 } 778 779 /* set share i2s */ 780 if (i2s_priv && i2s_priv->share_i2s_id >= 0) 781 ret = mtk_dai_i2s_config(afe, params, i2s_priv->share_i2s_id); 782 783 return ret; 784 } 785 786 static int mtk_dai_i2s_hw_params(struct snd_pcm_substream *substream, 787 struct snd_pcm_hw_params *params, 788 struct snd_soc_dai *dai) 789 { 790 struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); 791 792 return mtk_dai_i2s_config(afe, params, dai->id); 793 } 794 795 static int mtk_dai_i2s_set_sysclk(struct snd_soc_dai *dai, 796 int clk_id, unsigned int freq, int dir) 797 { 798 struct mtk_base_afe *afe = dev_get_drvdata(dai->dev); 799 struct mt8183_afe_private *afe_priv = afe->platform_priv; 800 struct mtk_afe_i2s_priv *i2s_priv = afe_priv->dai_priv[dai->id]; 801 int apll; 802 int apll_rate; 803 804 if (!i2s_priv) { 805 dev_warn(afe->dev, "%s(), i2s_priv == NULL", __func__); 806 return -EINVAL; 807 } 808 809 if (dir != SND_SOC_CLOCK_OUT) { 810 dev_warn(afe->dev, "%s(), dir != SND_SOC_CLOCK_OUT", __func__); 811 return -EINVAL; 812 } 813 814 dev_info(afe->dev, "%s(), freq %d\n", __func__, freq); 815 816 apll = mt8183_get_apll_by_rate(afe, freq); 817 apll_rate = mt8183_get_apll_rate(afe, apll); 818 819 if (freq > apll_rate) { 820 dev_warn(afe->dev, "%s(), freq > apll rate", __func__); 821 return -EINVAL; 822 } 823 824 if (apll_rate % freq != 0) { 825 dev_warn(afe->dev, "%s(), APLL cannot generate freq Hz", 826 __func__); 827 return -EINVAL; 828 } 829 830 i2s_priv->mclk_rate = freq; 831 i2s_priv->mclk_apll = apll; 832 833 if (i2s_priv->share_i2s_id > 0) { 834 struct mtk_afe_i2s_priv *share_i2s_priv; 835 836 share_i2s_priv = afe_priv->dai_priv[i2s_priv->share_i2s_id]; 837 if (!share_i2s_priv) { 838 dev_warn(afe->dev, "%s(), share_i2s_priv == NULL", 839 __func__); 840 return -EINVAL; 841 } 842 843 share_i2s_priv->mclk_rate = i2s_priv->mclk_rate; 844 share_i2s_priv->mclk_apll = i2s_priv->mclk_apll; 845 } 846 847 return 0; 848 } 849 850 static int mtk_dai_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) 851 { 852 struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); 853 struct mt8183_afe_private *afe_priv = afe->platform_priv; 854 struct mtk_afe_i2s_priv *i2s_priv; 855 856 switch (dai->id) { 857 case MT8183_DAI_I2S_0: 858 case MT8183_DAI_I2S_1: 859 case MT8183_DAI_I2S_2: 860 case MT8183_DAI_I2S_3: 861 case MT8183_DAI_I2S_5: 862 break; 863 default: 864 dev_warn(afe->dev, "%s(), id %d not support\n", 865 __func__, dai->id); 866 return -EINVAL; 867 } 868 i2s_priv = afe_priv->dai_priv[dai->id]; 869 870 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 871 case SND_SOC_DAIFMT_LEFT_J: 872 i2s_priv->use_eiaj = 1; 873 break; 874 case SND_SOC_DAIFMT_I2S: 875 i2s_priv->use_eiaj = 0; 876 break; 877 default: 878 dev_warn(afe->dev, "%s(), DAI format %d not support\n", 879 __func__, fmt & SND_SOC_DAIFMT_FORMAT_MASK); 880 return -EINVAL; 881 } 882 883 return 0; 884 } 885 886 static const struct snd_soc_dai_ops mtk_dai_i2s_ops = { 887 .hw_params = mtk_dai_i2s_hw_params, 888 .set_sysclk = mtk_dai_i2s_set_sysclk, 889 .set_fmt = mtk_dai_i2s_set_fmt, 890 }; 891 892 /* dai driver */ 893 #define MTK_I2S_RATES (SNDRV_PCM_RATE_8000_48000 |\ 894 SNDRV_PCM_RATE_88200 |\ 895 SNDRV_PCM_RATE_96000 |\ 896 SNDRV_PCM_RATE_176400 |\ 897 SNDRV_PCM_RATE_192000) 898 899 #define MTK_I2S_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ 900 SNDRV_PCM_FMTBIT_S24_LE |\ 901 SNDRV_PCM_FMTBIT_S32_LE) 902 903 static struct snd_soc_dai_driver mtk_dai_i2s_driver[] = { 904 { 905 .name = "I2S0", 906 .id = MT8183_DAI_I2S_0, 907 .capture = { 908 .stream_name = "I2S0", 909 .channels_min = 1, 910 .channels_max = 2, 911 .rates = MTK_I2S_RATES, 912 .formats = MTK_I2S_FORMATS, 913 }, 914 .ops = &mtk_dai_i2s_ops, 915 }, 916 { 917 .name = "I2S1", 918 .id = MT8183_DAI_I2S_1, 919 .playback = { 920 .stream_name = "I2S1", 921 .channels_min = 1, 922 .channels_max = 2, 923 .rates = MTK_I2S_RATES, 924 .formats = MTK_I2S_FORMATS, 925 }, 926 .ops = &mtk_dai_i2s_ops, 927 }, 928 { 929 .name = "I2S2", 930 .id = MT8183_DAI_I2S_2, 931 .capture = { 932 .stream_name = "I2S2", 933 .channels_min = 1, 934 .channels_max = 2, 935 .rates = MTK_I2S_RATES, 936 .formats = MTK_I2S_FORMATS, 937 }, 938 .ops = &mtk_dai_i2s_ops, 939 }, 940 { 941 .name = "I2S3", 942 .id = MT8183_DAI_I2S_3, 943 .playback = { 944 .stream_name = "I2S3", 945 .channels_min = 1, 946 .channels_max = 2, 947 .rates = MTK_I2S_RATES, 948 .formats = MTK_I2S_FORMATS, 949 }, 950 .ops = &mtk_dai_i2s_ops, 951 }, 952 { 953 .name = "I2S5", 954 .id = MT8183_DAI_I2S_5, 955 .playback = { 956 .stream_name = "I2S5", 957 .channels_min = 1, 958 .channels_max = 2, 959 .rates = MTK_I2S_RATES, 960 .formats = MTK_I2S_FORMATS, 961 }, 962 .ops = &mtk_dai_i2s_ops, 963 }, 964 }; 965 966 /* this enum is merely for mtk_afe_i2s_priv declare */ 967 enum { 968 DAI_I2S0 = 0, 969 DAI_I2S1, 970 DAI_I2S2, 971 DAI_I2S3, 972 DAI_I2S5, 973 DAI_I2S_NUM, 974 }; 975 976 static const struct mtk_afe_i2s_priv mt8183_i2s_priv[DAI_I2S_NUM] = { 977 [DAI_I2S0] = { 978 .id = MT8183_DAI_I2S_0, 979 .mclk_id = MT8183_I2S0_MCK, 980 .share_property_name = "i2s0-share", 981 .share_i2s_id = -1, 982 }, 983 [DAI_I2S1] = { 984 .id = MT8183_DAI_I2S_1, 985 .mclk_id = MT8183_I2S1_MCK, 986 .share_property_name = "i2s1-share", 987 .share_i2s_id = -1, 988 }, 989 [DAI_I2S2] = { 990 .id = MT8183_DAI_I2S_2, 991 .mclk_id = MT8183_I2S2_MCK, 992 .share_property_name = "i2s2-share", 993 .share_i2s_id = -1, 994 }, 995 [DAI_I2S3] = { 996 .id = MT8183_DAI_I2S_3, 997 .mclk_id = MT8183_I2S3_MCK, 998 .share_property_name = "i2s3-share", 999 .share_i2s_id = -1, 1000 }, 1001 [DAI_I2S5] = { 1002 .id = MT8183_DAI_I2S_5, 1003 .mclk_id = MT8183_I2S5_MCK, 1004 .share_property_name = "i2s5-share", 1005 .share_i2s_id = -1, 1006 }, 1007 }; 1008 1009 static int mt8183_dai_i2s_get_share(struct mtk_base_afe *afe) 1010 { 1011 struct mt8183_afe_private *afe_priv = afe->platform_priv; 1012 const struct device_node *of_node = afe->dev->of_node; 1013 const char *of_str; 1014 const char *property_name; 1015 struct mtk_afe_i2s_priv *i2s_priv; 1016 int i; 1017 1018 for (i = 0; i < DAI_I2S_NUM; i++) { 1019 i2s_priv = afe_priv->dai_priv[mt8183_i2s_priv[i].id]; 1020 property_name = mt8183_i2s_priv[i].share_property_name; 1021 if (of_property_read_string(of_node, property_name, &of_str)) 1022 continue; 1023 i2s_priv->share_i2s_id = get_i2s_id_by_name(afe, of_str); 1024 } 1025 1026 return 0; 1027 } 1028 1029 static int mt8183_dai_i2s_set_priv(struct mtk_base_afe *afe) 1030 { 1031 struct mt8183_afe_private *afe_priv = afe->platform_priv; 1032 struct mtk_afe_i2s_priv *i2s_priv; 1033 int i; 1034 1035 for (i = 0; i < DAI_I2S_NUM; i++) { 1036 i2s_priv = devm_kzalloc(afe->dev, 1037 sizeof(struct mtk_afe_i2s_priv), 1038 GFP_KERNEL); 1039 if (!i2s_priv) 1040 return -ENOMEM; 1041 1042 memcpy(i2s_priv, &mt8183_i2s_priv[i], 1043 sizeof(struct mtk_afe_i2s_priv)); 1044 1045 afe_priv->dai_priv[mt8183_i2s_priv[i].id] = i2s_priv; 1046 } 1047 1048 return 0; 1049 } 1050 1051 int mt8183_dai_i2s_register(struct mtk_base_afe *afe) 1052 { 1053 struct mtk_base_afe_dai *dai; 1054 int ret; 1055 1056 dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL); 1057 if (!dai) 1058 return -ENOMEM; 1059 1060 list_add(&dai->list, &afe->sub_dais); 1061 1062 dai->dai_drivers = mtk_dai_i2s_driver; 1063 dai->num_dai_drivers = ARRAY_SIZE(mtk_dai_i2s_driver); 1064 1065 dai->controls = mtk_dai_i2s_controls; 1066 dai->num_controls = ARRAY_SIZE(mtk_dai_i2s_controls); 1067 dai->dapm_widgets = mtk_dai_i2s_widgets; 1068 dai->num_dapm_widgets = ARRAY_SIZE(mtk_dai_i2s_widgets); 1069 dai->dapm_routes = mtk_dai_i2s_routes; 1070 dai->num_dapm_routes = ARRAY_SIZE(mtk_dai_i2s_routes); 1071 1072 /* set all dai i2s private data */ 1073 ret = mt8183_dai_i2s_set_priv(afe); 1074 if (ret) 1075 return ret; 1076 1077 /* parse share i2s */ 1078 ret = mt8183_dai_i2s_get_share(afe); 1079 if (ret) 1080 return ret; 1081 1082 return 0; 1083 } 1084