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