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