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