Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

ASoC: mediatek: mt8189: support I2S in platform driver

Add mt8189 I2S DAI driver support.

Signed-off-by: Cyril Chao <Cyril.Chao@mediatek.com>
Link: https://patch.msgid.link/20251031073216.8662-5-Cyril.Chao@mediatek.com
Signed-off-by: Mark Brown <broonie@kernel.org>

authored by

Cyril Chao and committed by
Mark Brown
34e43709 e3acef6e

+1463
+1463
sound/soc/mediatek/mt8189/mt8189-dai-i2s.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * MediaTek ALSA SoC Audio DAI I2S Control 4 + * 5 + * Copyright (c) 2025 MediaTek Inc. 6 + * Author: Darren Ye <darren.ye@mediatek.com> 7 + */ 8 + 9 + #include <linux/bitops.h> 10 + #include <linux/regmap.h> 11 + 12 + #include <sound/pcm_params.h> 13 + 14 + #include "mt8189-afe-clk.h" 15 + #include "mt8189-afe-common.h" 16 + #include "mt8189-interconnection.h" 17 + 18 + #include "../common/mtk-afe-fe-dai.h" 19 + 20 + #define I2SIN0_MCLK_EN_W_NAME "I2SIN0_MCLK_EN" 21 + #define I2SIN1_MCLK_EN_W_NAME "I2SIN1_MCLK_EN" 22 + #define I2SOUT0_MCLK_EN_W_NAME "I2SOUT0_MCLK_EN" 23 + #define I2SOUT1_MCLK_EN_W_NAME "I2SOUT1_MCLK_EN" 24 + #define I2SOUT4_MCLK_EN_W_NAME "I2SOUT4_MCLK_EN" 25 + 26 + enum { 27 + SUPPLY_SEQ_APLL, 28 + SUPPLY_SEQ_I2S_MCLK_EN, 29 + SUPPLY_SEQ_I2S_CG_EN, 30 + SUPPLY_SEQ_I2S_EN, 31 + }; 32 + 33 + /* this enum is merely for mtk_afe_i2s_priv declare */ 34 + enum { 35 + DAI_I2SIN0, 36 + DAI_I2SIN1, 37 + DAI_I2SOUT0, 38 + DAI_I2SOUT1, 39 + DAI_I2SOUT4, 40 + DAI_I2S_NUM, 41 + }; 42 + 43 + enum { 44 + ETDM_CLK_SOURCE_H26M, 45 + ETDM_CLK_SOURCE_APLL, 46 + ETDM_CLK_SOURCE_SPDIF, 47 + ETDM_CLK_SOURCE_HDMI, 48 + ETDM_CLK_SOURCE_EARC, 49 + ETDM_CLK_SOURCE_LINEIN, 50 + }; 51 + 52 + enum { 53 + ETDM_RELATCH_SEL_H26M, 54 + ETDM_RELATCH_SEL_APLL, 55 + }; 56 + 57 + enum { 58 + ETDM_RATE_8K, 59 + ETDM_RATE_12K, 60 + ETDM_RATE_16K, 61 + ETDM_RATE_24K, 62 + ETDM_RATE_32K, 63 + ETDM_RATE_48K, 64 + ETDM_RATE_64K, 65 + ETDM_RATE_96K, 66 + ETDM_RATE_128K, 67 + ETDM_RATE_192K, 68 + ETDM_RATE_256K, 69 + ETDM_RATE_384K, 70 + ETDM_RATE_11025 = 16, 71 + ETDM_RATE_22050, 72 + ETDM_RATE_44100, 73 + ETDM_RATE_88200, 74 + ETDM_RATE_176400, 75 + ETDM_RATE_352800, 76 + }; 77 + 78 + enum { 79 + ETDM_CONN_8K, 80 + ETDM_CONN_11K, 81 + ETDM_CONN_12K, 82 + ETDM_CONN_16K = 4, 83 + ETDM_CONN_22K, 84 + ETDM_CONN_24K, 85 + ETDM_CONN_32K = 8, 86 + ETDM_CONN_44K, 87 + ETDM_CONN_48K, 88 + ETDM_CONN_88K = 13, 89 + ETDM_CONN_96K, 90 + ETDM_CONN_176K = 17, 91 + ETDM_CONN_192K, 92 + ETDM_CONN_352K = 21, 93 + ETDM_CONN_384K, 94 + }; 95 + 96 + enum { 97 + ETDM_WLEN_8_BIT = 0x7, 98 + ETDM_WLEN_16_BIT = 0xf, 99 + ETDM_WLEN_32_BIT = 0x1f, 100 + }; 101 + 102 + enum { 103 + ETDM_SLAVE_SEL_ETDMIN0_MASTER, 104 + ETDM_SLAVE_SEL_ETDMIN0_SLAVE, 105 + ETDM_SLAVE_SEL_ETDMIN1_MASTER, 106 + ETDM_SLAVE_SEL_ETDMIN1_SLAVE, 107 + ETDM_SLAVE_SEL_ETDMIN2_MASTER, 108 + ETDM_SLAVE_SEL_ETDMIN2_SLAVE, 109 + ETDM_SLAVE_SEL_ETDMIN3_MASTER, 110 + ETDM_SLAVE_SEL_ETDMIN3_SLAVE, 111 + ETDM_SLAVE_SEL_ETDMOUT0_MASTER, 112 + ETDM_SLAVE_SEL_ETDMOUT0_SLAVE, 113 + ETDM_SLAVE_SEL_ETDMOUT1_MASTER, 114 + ETDM_SLAVE_SEL_ETDMOUT1_SLAVE, 115 + ETDM_SLAVE_SEL_ETDMOUT2_MASTER, 116 + ETDM_SLAVE_SEL_ETDMOUT2_SLAVE, 117 + ETDM_SLAVE_SEL_ETDMOUT3_MASTER, 118 + ETDM_SLAVE_SEL_ETDMOUT3_SLAVE, 119 + }; 120 + 121 + struct mtk_afe_i2s_priv { 122 + int id; 123 + int rate; /* for determine which apll to use */ 124 + int low_jitter_en; 125 + unsigned int i2s_low_power_mask; 126 + const char *share_property_name; 127 + int share_i2s_id; 128 + 129 + int mclk_id; 130 + int mclk_rate; 131 + int mclk_apll; 132 + 133 + int ch_num; 134 + int sync; 135 + int ip_mode; 136 + int slave_mode; 137 + int lpbk_mode; 138 + }; 139 + 140 + static unsigned int get_etdm_wlen(snd_pcm_format_t format) 141 + { 142 + return snd_pcm_format_physical_width(format) <= 16 ? 143 + ETDM_WLEN_16_BIT : ETDM_WLEN_32_BIT; 144 + } 145 + 146 + static unsigned int get_etdm_lrck_width(snd_pcm_format_t format) 147 + { 148 + if (snd_pcm_format_physical_width(format) <= 1) 149 + return 0; 150 + 151 + /* The valid data bit number should be larger than 7 due to hardware limitation. */ 152 + return snd_pcm_format_physical_width(format) - 1; 153 + } 154 + 155 + static unsigned int get_etdm_rate(unsigned int rate) 156 + { 157 + switch (rate) { 158 + case 8000: 159 + return ETDM_RATE_8K; 160 + case 12000: 161 + return ETDM_RATE_12K; 162 + case 16000: 163 + return ETDM_RATE_16K; 164 + case 24000: 165 + return ETDM_RATE_24K; 166 + case 32000: 167 + return ETDM_RATE_32K; 168 + case 48000: 169 + return ETDM_RATE_48K; 170 + case 64000: 171 + return ETDM_RATE_64K; 172 + case 96000: 173 + return ETDM_RATE_96K; 174 + case 128000: 175 + return ETDM_RATE_128K; 176 + case 192000: 177 + return ETDM_RATE_192K; 178 + case 256000: 179 + return ETDM_RATE_256K; 180 + case 384000: 181 + return ETDM_RATE_384K; 182 + case 11025: 183 + return ETDM_RATE_11025; 184 + case 22050: 185 + return ETDM_RATE_22050; 186 + case 44100: 187 + return ETDM_RATE_44100; 188 + case 88200: 189 + return ETDM_RATE_88200; 190 + case 176400: 191 + return ETDM_RATE_176400; 192 + case 352800: 193 + return ETDM_RATE_352800; 194 + default: 195 + return 0; 196 + } 197 + } 198 + 199 + static unsigned int get_etdm_inconn_rate(unsigned int rate) 200 + { 201 + switch (rate) { 202 + case 8000: 203 + return ETDM_CONN_8K; 204 + case 12000: 205 + return ETDM_CONN_12K; 206 + case 16000: 207 + return ETDM_CONN_16K; 208 + case 24000: 209 + return ETDM_CONN_24K; 210 + case 32000: 211 + return ETDM_CONN_32K; 212 + case 48000: 213 + return ETDM_CONN_48K; 214 + case 96000: 215 + return ETDM_CONN_96K; 216 + case 192000: 217 + return ETDM_CONN_192K; 218 + case 384000: 219 + return ETDM_CONN_384K; 220 + case 11025: 221 + return ETDM_CONN_11K; 222 + case 22050: 223 + return ETDM_CONN_22K; 224 + case 44100: 225 + return ETDM_CONN_44K; 226 + case 88200: 227 + return ETDM_CONN_88K; 228 + case 176400: 229 + return ETDM_CONN_176K; 230 + case 352800: 231 + return ETDM_CONN_352K; 232 + default: 233 + return 0; 234 + } 235 + } 236 + 237 + static int get_i2s_id_by_name(struct mtk_base_afe *afe, 238 + const char *name) 239 + { 240 + if (strncmp(name, "I2SIN0", 6) == 0) 241 + return MT8189_DAI_I2S_IN0; 242 + else if (strncmp(name, "I2SIN1", 6) == 0) 243 + return MT8189_DAI_I2S_IN1; 244 + else if (strncmp(name, "I2SOUT0", 7) == 0) 245 + return MT8189_DAI_I2S_OUT0; 246 + else if (strncmp(name, "I2SOUT1", 7) == 0) 247 + return MT8189_DAI_I2S_OUT1; 248 + else if (strncmp(name, "I2SOUT4", 7) == 0) 249 + return MT8189_DAI_I2S_OUT4; 250 + else 251 + return -EINVAL; 252 + } 253 + 254 + static struct mtk_afe_i2s_priv *get_i2s_priv_by_name(struct mtk_base_afe *afe, 255 + const char *name) 256 + { 257 + struct mt8189_afe_private *afe_priv = afe->platform_priv; 258 + int dai_id = get_i2s_id_by_name(afe, name); 259 + 260 + if (dai_id < 0) 261 + return NULL; 262 + 263 + return afe_priv->dai_priv[dai_id]; 264 + } 265 + 266 + static const char * const etdm_0_3_loopback_texts[] = { 267 + "etdmin0", "etdmin1", "etdmout0", "etdmout1" 268 + }; 269 + 270 + static const u32 etdm_loopback_values[] = { 271 + 0, 2, 8, 10 272 + }; 273 + 274 + static SOC_VALUE_ENUM_SINGLE_DECL(i2sin0_loopback_enum, 275 + ETDM_0_3_COWORK_CON1, 276 + ETDM_IN0_SDATA0_SEL_SFT, 277 + ETDM_IN0_SDATA0_SEL_MASK, 278 + etdm_0_3_loopback_texts, 279 + etdm_loopback_values); 280 + 281 + static SOC_VALUE_ENUM_SINGLE_DECL(i2sin1_loopback_enum, 282 + ETDM_0_3_COWORK_CON1, 283 + ETDM_IN1_SDATA0_SEL_SFT, 284 + ETDM_IN1_SDATA0_SEL_MASK, 285 + etdm_0_3_loopback_texts, 286 + etdm_loopback_values); 287 + 288 + static const struct snd_kcontrol_new mtk_dai_i2s_controls[] = { 289 + SOC_ENUM("I2SIN0 Loopback", i2sin0_loopback_enum), 290 + SOC_ENUM("I2SIN1 Loopback", i2sin1_loopback_enum), 291 + }; 292 + 293 + /* 294 + * I2S virtual mux to output widget 295 + * If the I2S interface is required but not connected to an actual codec dai, 296 + * a Dummy_Widget must be used to establish the connection. 297 + */ 298 + static const char *const i2s_mux_map[] = { 299 + "Normal", "Dummy_Widget", 300 + }; 301 + 302 + static int i2s_mux_map_value[] = { 303 + 0, 1, 304 + }; 305 + 306 + static SOC_VALUE_ENUM_SINGLE_AUTODISABLE_DECL(i2s_mux_map_enum, 307 + SND_SOC_NOPM, 308 + 0, 309 + 1, 310 + i2s_mux_map, 311 + i2s_mux_map_value); 312 + 313 + static const struct snd_kcontrol_new i2s_in0_mux_control = 314 + SOC_DAPM_ENUM("I2S IN0 Select", i2s_mux_map_enum); 315 + static const struct snd_kcontrol_new i2s_in1_mux_control = 316 + SOC_DAPM_ENUM("I2S IN1 Select", i2s_mux_map_enum); 317 + static const struct snd_kcontrol_new i2s_out0_mux_control = 318 + SOC_DAPM_ENUM("I2S OUT0 Select", i2s_mux_map_enum); 319 + static const struct snd_kcontrol_new i2s_out1_mux_control = 320 + SOC_DAPM_ENUM("I2S OUT1 Select", i2s_mux_map_enum); 321 + static const struct snd_kcontrol_new i2s_out4_mux_control = 322 + SOC_DAPM_ENUM("I2S OUT4 Select", i2s_mux_map_enum); 323 + 324 + static const struct snd_kcontrol_new mtk_i2sout0_ch1_mix[] = { 325 + SOC_DAPM_SINGLE_AUTODISABLE("DL0_CH1", AFE_CONN108_1, I_DL0_CH1, 1, 0), 326 + SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1", AFE_CONN108_1, I_DL1_CH1, 1, 0), 327 + SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1", AFE_CONN108_1, I_DL2_CH1, 1, 0), 328 + SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1", AFE_CONN108_1, I_DL3_CH1, 1, 0), 329 + SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH1", AFE_CONN108_1, I_DL4_CH1, 1, 0), 330 + SOC_DAPM_SINGLE_AUTODISABLE("DL5_CH1", AFE_CONN108_1, I_DL5_CH1, 1, 0), 331 + SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH1", AFE_CONN108_1, I_DL6_CH1, 1, 0), 332 + SOC_DAPM_SINGLE_AUTODISABLE("DL7_CH1", AFE_CONN108_1, I_DL7_CH1, 1, 0), 333 + SOC_DAPM_SINGLE_AUTODISABLE("DL8_CH1", AFE_CONN108_1, I_DL8_CH1, 1, 0), 334 + SOC_DAPM_SINGLE_AUTODISABLE("DL_24CH_CH1", AFE_CONN108_1, I_DL_24CH_CH1, 1, 0), 335 + SOC_DAPM_SINGLE_AUTODISABLE("HW_GAIN0_OUT_CH1", AFE_CONN108_0, 336 + I_GAIN0_OUT_CH1, 1, 0), 337 + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN108_0, 338 + I_ADDA_UL_CH1, 1, 0), 339 + SOC_DAPM_SINGLE_AUTODISABLE("PCM_0_CAP_CH1", AFE_CONN108_4, 340 + I_PCM_0_CAP_CH1, 1, 0), 341 + }; 342 + 343 + static const struct snd_kcontrol_new mtk_i2sout0_ch2_mix[] = { 344 + SOC_DAPM_SINGLE_AUTODISABLE("DL0_CH2", AFE_CONN109_1, I_DL0_CH2, 1, 0), 345 + SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH2", AFE_CONN109_1, I_DL1_CH2, 1, 0), 346 + SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH2", AFE_CONN109_1, I_DL2_CH2, 1, 0), 347 + SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH2", AFE_CONN109_1, I_DL3_CH2, 1, 0), 348 + SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH2", AFE_CONN109_1, I_DL4_CH2, 1, 0), 349 + SOC_DAPM_SINGLE_AUTODISABLE("DL5_CH2", AFE_CONN109_1, I_DL5_CH2, 1, 0), 350 + SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH2", AFE_CONN109_1, I_DL6_CH2, 1, 0), 351 + SOC_DAPM_SINGLE_AUTODISABLE("DL7_CH2", AFE_CONN109_1, I_DL7_CH2, 1, 0), 352 + SOC_DAPM_SINGLE_AUTODISABLE("DL8_CH2", AFE_CONN109_1, I_DL8_CH2, 1, 0), 353 + SOC_DAPM_SINGLE_AUTODISABLE("DL_24CH_CH2", AFE_CONN109_1, I_DL_24CH_CH2, 1, 0), 354 + SOC_DAPM_SINGLE_AUTODISABLE("HW_GAIN0_OUT_CH2", AFE_CONN109_0, 355 + I_GAIN0_OUT_CH2, 1, 0), 356 + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN109_0, 357 + I_ADDA_UL_CH2, 1, 0), 358 + SOC_DAPM_SINGLE_AUTODISABLE("PCM_0_CAP_CH1", AFE_CONN109_4, 359 + I_PCM_0_CAP_CH1, 1, 0), 360 + SOC_DAPM_SINGLE_AUTODISABLE("PCM_0_CAP_CH2", AFE_CONN109_4, 361 + I_PCM_0_CAP_CH2, 1, 0), 362 + }; 363 + 364 + static const struct snd_kcontrol_new mtk_i2sout1_ch1_mix[] = { 365 + SOC_DAPM_SINGLE_AUTODISABLE("DL0_CH1", AFE_CONN110_1, I_DL0_CH1, 1, 0), 366 + SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1", AFE_CONN110_1, I_DL1_CH1, 1, 0), 367 + SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1", AFE_CONN110_1, I_DL2_CH1, 1, 0), 368 + SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1", AFE_CONN110_1, I_DL3_CH1, 1, 0), 369 + SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH1", AFE_CONN110_1, I_DL4_CH1, 1, 0), 370 + SOC_DAPM_SINGLE_AUTODISABLE("DL5_CH1", AFE_CONN110_1, I_DL5_CH1, 1, 0), 371 + SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH1", AFE_CONN110_1, I_DL6_CH1, 1, 0), 372 + SOC_DAPM_SINGLE_AUTODISABLE("DL7_CH1", AFE_CONN110_1, I_DL7_CH1, 1, 0), 373 + SOC_DAPM_SINGLE_AUTODISABLE("DL8_CH1", AFE_CONN110_1, I_DL8_CH1, 1, 0), 374 + SOC_DAPM_SINGLE_AUTODISABLE("DL_24CH_CH1", AFE_CONN110_1, I_DL_24CH_CH1, 1, 0), 375 + SOC_DAPM_SINGLE_AUTODISABLE("HW_GAIN0_OUT_CH1", AFE_CONN110_0, 376 + I_GAIN0_OUT_CH1, 1, 0), 377 + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN110_0, 378 + I_ADDA_UL_CH1, 1, 0), 379 + SOC_DAPM_SINGLE_AUTODISABLE("PCM_0_CAP_CH1", AFE_CONN110_4, 380 + I_PCM_0_CAP_CH1, 1, 0), 381 + }; 382 + 383 + static const struct snd_kcontrol_new mtk_i2sout1_ch2_mix[] = { 384 + SOC_DAPM_SINGLE_AUTODISABLE("DL0_CH2", AFE_CONN111_1, I_DL0_CH2, 1, 0), 385 + SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH2", AFE_CONN111_1, I_DL1_CH2, 1, 0), 386 + SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH2", AFE_CONN111_1, I_DL2_CH2, 1, 0), 387 + SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH2", AFE_CONN111_1, I_DL3_CH2, 1, 0), 388 + SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH2", AFE_CONN111_1, I_DL4_CH2, 1, 0), 389 + SOC_DAPM_SINGLE_AUTODISABLE("DL5_CH2", AFE_CONN111_1, I_DL5_CH2, 1, 0), 390 + SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH2", AFE_CONN111_1, I_DL6_CH2, 1, 0), 391 + SOC_DAPM_SINGLE_AUTODISABLE("DL7_CH2", AFE_CONN111_1, I_DL7_CH2, 1, 0), 392 + SOC_DAPM_SINGLE_AUTODISABLE("DL8_CH2", AFE_CONN111_1, I_DL8_CH2, 1, 0), 393 + SOC_DAPM_SINGLE_AUTODISABLE("DL_24CH_CH2", AFE_CONN111_1, I_DL_24CH_CH2, 1, 0), 394 + SOC_DAPM_SINGLE_AUTODISABLE("HW_GAIN0_OUT_CH2", AFE_CONN111_0, 395 + I_GAIN0_OUT_CH2, 1, 0), 396 + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN111_0, 397 + I_ADDA_UL_CH2, 1, 0), 398 + SOC_DAPM_SINGLE_AUTODISABLE("PCM_0_CAP_CH1", AFE_CONN111_4, 399 + I_PCM_0_CAP_CH1, 1, 0), 400 + SOC_DAPM_SINGLE_AUTODISABLE("PCM_0_CAP_CH2", AFE_CONN111_4, 401 + I_PCM_0_CAP_CH2, 1, 0), 402 + }; 403 + 404 + static const struct snd_kcontrol_new mtk_i2sout4_ch1_mix[] = { 405 + SOC_DAPM_SINGLE_AUTODISABLE("DL0_CH1", AFE_CONN116_1, I_DL0_CH1, 1, 0), 406 + SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1", AFE_CONN116_1, I_DL1_CH1, 1, 0), 407 + SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1", AFE_CONN116_1, I_DL2_CH1, 1, 0), 408 + SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1", AFE_CONN116_1, I_DL3_CH1, 1, 0), 409 + SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH1", AFE_CONN116_1, I_DL4_CH1, 1, 0), 410 + SOC_DAPM_SINGLE_AUTODISABLE("DL5_CH1", AFE_CONN116_1, I_DL5_CH1, 1, 0), 411 + SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH1", AFE_CONN116_1, I_DL6_CH1, 1, 0), 412 + SOC_DAPM_SINGLE_AUTODISABLE("DL7_CH1", AFE_CONN116_1, I_DL7_CH1, 1, 0), 413 + SOC_DAPM_SINGLE_AUTODISABLE("DL8_CH1", AFE_CONN116_1, I_DL8_CH1, 1, 0), 414 + SOC_DAPM_SINGLE_AUTODISABLE("DL_24CH_CH1", AFE_CONN116_1, I_DL_24CH_CH1, 1, 0), 415 + SOC_DAPM_SINGLE_AUTODISABLE("DL24_CH1", AFE_CONN116_2, I_DL24_CH1, 1, 0), 416 + SOC_DAPM_SINGLE_AUTODISABLE("HW_GAIN0_OUT_CH1", AFE_CONN116_0, 417 + I_GAIN0_OUT_CH1, 1, 0), 418 + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN116_0, 419 + I_ADDA_UL_CH1, 1, 0), 420 + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN116_0, 421 + I_ADDA_UL_CH2, 1, 0), 422 + SOC_DAPM_SINGLE_AUTODISABLE("PCM_0_CAP_CH1", AFE_CONN116_4, 423 + I_PCM_0_CAP_CH1, 1, 0), 424 + SOC_DAPM_SINGLE_AUTODISABLE("HW_SRC_2_OUT_CH1", AFE_CONN116_6, 425 + I_SRC_2_OUT_CH1, 1, 0), 426 + }; 427 + 428 + static const struct snd_kcontrol_new mtk_i2sout4_ch2_mix[] = { 429 + SOC_DAPM_SINGLE_AUTODISABLE("DL0_CH2", AFE_CONN117_1, I_DL0_CH2, 1, 0), 430 + SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH2", AFE_CONN117_1, I_DL1_CH2, 1, 0), 431 + SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH2", AFE_CONN117_1, I_DL2_CH2, 1, 0), 432 + SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH2", AFE_CONN117_1, I_DL3_CH2, 1, 0), 433 + SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH2", AFE_CONN117_1, I_DL4_CH2, 1, 0), 434 + SOC_DAPM_SINGLE_AUTODISABLE("DL5_CH2", AFE_CONN117_1, I_DL5_CH2, 1, 0), 435 + SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH2", AFE_CONN117_1, I_DL6_CH2, 1, 0), 436 + SOC_DAPM_SINGLE_AUTODISABLE("DL7_CH2", AFE_CONN117_1, I_DL7_CH2, 1, 0), 437 + SOC_DAPM_SINGLE_AUTODISABLE("DL8_CH2", AFE_CONN117_1, I_DL8_CH2, 1, 0), 438 + SOC_DAPM_SINGLE_AUTODISABLE("DL_24CH_CH2", AFE_CONN117_1, I_DL_24CH_CH2, 1, 0), 439 + SOC_DAPM_SINGLE_AUTODISABLE("DL24_CH2", AFE_CONN117_2, I_DL24_CH2, 1, 0), 440 + SOC_DAPM_SINGLE_AUTODISABLE("HW_GAIN0_OUT_CH2", AFE_CONN117_0, 441 + I_GAIN0_OUT_CH2, 1, 0), 442 + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN117_0, 443 + I_ADDA_UL_CH1, 1, 0), 444 + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN117_0, 445 + I_ADDA_UL_CH2, 1, 0), 446 + SOC_DAPM_SINGLE_AUTODISABLE("PCM_0_CAP_CH1", AFE_CONN117_4, 447 + I_PCM_0_CAP_CH1, 1, 0), 448 + SOC_DAPM_SINGLE_AUTODISABLE("PCM_0_CAP_CH2", AFE_CONN117_4, 449 + I_PCM_0_CAP_CH2, 1, 0), 450 + SOC_DAPM_SINGLE_AUTODISABLE("HW_SRC_2_OUT_CH2", AFE_CONN117_6, 451 + I_SRC_2_OUT_CH2, 1, 0), 452 + }; 453 + 454 + static const struct snd_kcontrol_new mtk_i2sout4_ch3_mix[] = { 455 + SOC_DAPM_SINGLE_AUTODISABLE("DL_24CH_CH3", AFE_CONN118_1, I_DL_24CH_CH3, 1, 0), 456 + SOC_DAPM_SINGLE_AUTODISABLE("PCM_0_CAP_CH1", AFE_CONN118_4, 457 + I_PCM_0_CAP_CH1, 1, 0), 458 + }; 459 + 460 + static const struct snd_kcontrol_new mtk_i2sout4_ch4_mix[] = { 461 + SOC_DAPM_SINGLE_AUTODISABLE("DL_24CH_CH4", AFE_CONN119_1, I_DL_24CH_CH4, 1, 0), 462 + SOC_DAPM_SINGLE_AUTODISABLE("PCM_0_CAP_CH1", AFE_CONN118_4, 463 + I_PCM_0_CAP_CH1, 1, 0), 464 + }; 465 + 466 + static const struct snd_kcontrol_new mtk_i2sout4_ch5_mix[] = { 467 + SOC_DAPM_SINGLE_AUTODISABLE("DL_24CH_CH5", AFE_CONN120_1, I_DL_24CH_CH5, 1, 0), 468 + }; 469 + 470 + static const struct snd_kcontrol_new mtk_i2sout4_ch6_mix[] = { 471 + SOC_DAPM_SINGLE_AUTODISABLE("DL_24CH_CH6", AFE_CONN121_1, I_DL_24CH_CH6, 1, 0), 472 + }; 473 + 474 + static const struct snd_kcontrol_new mtk_i2sout4_ch7_mix[] = { 475 + SOC_DAPM_SINGLE_AUTODISABLE("DL_24CH_CH7", AFE_CONN122_1, I_DL_24CH_CH7, 1, 0), 476 + }; 477 + 478 + static const struct snd_kcontrol_new mtk_i2sout4_ch8_mix[] = { 479 + SOC_DAPM_SINGLE_AUTODISABLE("DL_24CH_CH8", AFE_CONN123_1, I_DL_24CH_CH8, 1, 0), 480 + }; 481 + 482 + static int mtk_apll_event(struct snd_soc_dapm_widget *w, 483 + struct snd_kcontrol *kcontrol, 484 + int event) 485 + { 486 + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); 487 + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); 488 + 489 + dev_dbg(cmpnt->dev, "%s(), name %s, event 0x%x\n", 490 + __func__, w->name, event); 491 + 492 + switch (event) { 493 + case SND_SOC_DAPM_PRE_PMU: 494 + if (strcmp(w->name, APLL1_W_NAME) == 0) 495 + mt8189_apll1_enable(afe); 496 + else 497 + mt8189_apll2_enable(afe); 498 + break; 499 + case SND_SOC_DAPM_POST_PMD: 500 + if (strcmp(w->name, APLL1_W_NAME) == 0) 501 + mt8189_apll1_disable(afe); 502 + else 503 + mt8189_apll2_disable(afe); 504 + break; 505 + default: 506 + break; 507 + } 508 + 509 + return 0; 510 + } 511 + 512 + static int mtk_mclk_en_event(struct snd_soc_dapm_widget *w, 513 + struct snd_kcontrol *kcontrol, 514 + int event) 515 + { 516 + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); 517 + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); 518 + struct mtk_afe_i2s_priv *i2s_priv; 519 + 520 + dev_dbg(cmpnt->dev, "%s(), name %s, event 0x%x\n", 521 + __func__, w->name, event); 522 + 523 + i2s_priv = get_i2s_priv_by_name(afe, w->name); 524 + if (!i2s_priv) 525 + return -EINVAL; 526 + 527 + switch (event) { 528 + case SND_SOC_DAPM_PRE_PMU: 529 + mt8189_mck_enable(afe, i2s_priv->mclk_id, i2s_priv->mclk_rate); 530 + break; 531 + case SND_SOC_DAPM_POST_PMD: 532 + i2s_priv->mclk_rate = 0; 533 + mt8189_mck_disable(afe, i2s_priv->mclk_id); 534 + break; 535 + default: 536 + break; 537 + } 538 + 539 + return 0; 540 + } 541 + 542 + static const struct snd_soc_dapm_widget mtk_dai_i2s_widgets[] = { 543 + SND_SOC_DAPM_MIXER("I2SOUT0_CH1", SND_SOC_NOPM, 0, 0, 544 + mtk_i2sout0_ch1_mix, 545 + ARRAY_SIZE(mtk_i2sout0_ch1_mix)), 546 + SND_SOC_DAPM_MIXER("I2SOUT0_CH2", SND_SOC_NOPM, 0, 0, 547 + mtk_i2sout0_ch2_mix, 548 + ARRAY_SIZE(mtk_i2sout0_ch2_mix)), 549 + 550 + SND_SOC_DAPM_MIXER("I2SOUT1_CH1", SND_SOC_NOPM, 0, 0, 551 + mtk_i2sout1_ch1_mix, 552 + ARRAY_SIZE(mtk_i2sout1_ch1_mix)), 553 + SND_SOC_DAPM_MIXER("I2SOUT1_CH2", SND_SOC_NOPM, 0, 0, 554 + mtk_i2sout1_ch2_mix, 555 + ARRAY_SIZE(mtk_i2sout1_ch2_mix)), 556 + 557 + SND_SOC_DAPM_MIXER("I2SOUT4_CH1", SND_SOC_NOPM, 0, 0, 558 + mtk_i2sout4_ch1_mix, 559 + ARRAY_SIZE(mtk_i2sout4_ch1_mix)), 560 + SND_SOC_DAPM_MIXER("I2SOUT4_CH2", SND_SOC_NOPM, 0, 0, 561 + mtk_i2sout4_ch2_mix, 562 + ARRAY_SIZE(mtk_i2sout4_ch2_mix)), 563 + SND_SOC_DAPM_MIXER("I2SOUT4_CH3", SND_SOC_NOPM, 0, 0, 564 + mtk_i2sout4_ch3_mix, 565 + ARRAY_SIZE(mtk_i2sout4_ch3_mix)), 566 + SND_SOC_DAPM_MIXER("I2SOUT4_CH4", SND_SOC_NOPM, 0, 0, 567 + mtk_i2sout4_ch4_mix, 568 + ARRAY_SIZE(mtk_i2sout4_ch4_mix)), 569 + SND_SOC_DAPM_MIXER("I2SOUT4_CH5", SND_SOC_NOPM, 0, 0, 570 + mtk_i2sout4_ch5_mix, 571 + ARRAY_SIZE(mtk_i2sout4_ch5_mix)), 572 + SND_SOC_DAPM_MIXER("I2SOUT4_CH6", SND_SOC_NOPM, 0, 0, 573 + mtk_i2sout4_ch6_mix, 574 + ARRAY_SIZE(mtk_i2sout4_ch6_mix)), 575 + SND_SOC_DAPM_MIXER("I2SOUT4_CH7", SND_SOC_NOPM, 0, 0, 576 + mtk_i2sout4_ch7_mix, 577 + ARRAY_SIZE(mtk_i2sout4_ch7_mix)), 578 + SND_SOC_DAPM_MIXER("I2SOUT4_CH8", SND_SOC_NOPM, 0, 0, 579 + mtk_i2sout4_ch8_mix, 580 + ARRAY_SIZE(mtk_i2sout4_ch8_mix)), 581 + 582 + /* i2s en*/ 583 + SND_SOC_DAPM_SUPPLY_S("I2SIN0_EN", SUPPLY_SEQ_I2S_EN, 584 + ETDM_IN0_CON0, REG_ETDM_IN_EN_SFT, 0, 585 + NULL, 0), 586 + SND_SOC_DAPM_SUPPLY_S("I2SIN1_EN", SUPPLY_SEQ_I2S_EN, 587 + ETDM_IN1_CON0, REG_ETDM_IN_EN_SFT, 0, 588 + NULL, 0), 589 + SND_SOC_DAPM_SUPPLY_S("I2SOUT0_EN", SUPPLY_SEQ_I2S_EN, 590 + ETDM_OUT0_CON0, OUT_REG_ETDM_OUT_EN_SFT, 0, 591 + NULL, 0), 592 + SND_SOC_DAPM_SUPPLY_S("I2SOUT1_EN", SUPPLY_SEQ_I2S_EN, 593 + ETDM_OUT1_CON0, OUT_REG_ETDM_OUT_EN_SFT, 0, 594 + NULL, 0), 595 + SND_SOC_DAPM_SUPPLY_S("I2SOUT4_EN", SUPPLY_SEQ_I2S_EN, 596 + ETDM_OUT4_CON0, OUT_REG_ETDM_OUT_EN_SFT, 0, 597 + NULL, 0), 598 + 599 + /* i2s mclk en */ 600 + SND_SOC_DAPM_SUPPLY_S(I2SIN0_MCLK_EN_W_NAME, SUPPLY_SEQ_I2S_MCLK_EN, 601 + SND_SOC_NOPM, 0, 0, 602 + mtk_mclk_en_event, 603 + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 604 + SND_SOC_DAPM_SUPPLY_S(I2SIN1_MCLK_EN_W_NAME, SUPPLY_SEQ_I2S_MCLK_EN, 605 + SND_SOC_NOPM, 0, 0, 606 + mtk_mclk_en_event, 607 + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 608 + SND_SOC_DAPM_SUPPLY_S(I2SOUT0_MCLK_EN_W_NAME, SUPPLY_SEQ_I2S_MCLK_EN, 609 + SND_SOC_NOPM, 0, 0, 610 + mtk_mclk_en_event, 611 + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 612 + SND_SOC_DAPM_SUPPLY_S(I2SOUT1_MCLK_EN_W_NAME, SUPPLY_SEQ_I2S_MCLK_EN, 613 + SND_SOC_NOPM, 0, 0, 614 + mtk_mclk_en_event, 615 + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 616 + SND_SOC_DAPM_SUPPLY_S(I2SOUT4_MCLK_EN_W_NAME, SUPPLY_SEQ_I2S_MCLK_EN, 617 + SND_SOC_NOPM, 0, 0, 618 + mtk_mclk_en_event, 619 + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 620 + 621 + /* cg */ 622 + SND_SOC_DAPM_SUPPLY_S("I2SOUT0_CG", SUPPLY_SEQ_I2S_CG_EN, 623 + AUDIO_TOP_CON2, PDN_ETDM_OUT0_SFT, 1, 624 + NULL, 0), 625 + SND_SOC_DAPM_SUPPLY_S("I2SOUT1_CG", SUPPLY_SEQ_I2S_CG_EN, 626 + AUDIO_TOP_CON2, PDN_ETDM_OUT1_SFT, 1, 627 + NULL, 0), 628 + SND_SOC_DAPM_SUPPLY_S("I2SOUT4_CG", SUPPLY_SEQ_I2S_CG_EN, 629 + AUDIO_TOP_CON2, PDN_ETDM_OUT4_SFT, 1, 630 + NULL, 0), 631 + SND_SOC_DAPM_SUPPLY_S("I2SIN0_CG", SUPPLY_SEQ_I2S_CG_EN, 632 + AUDIO_TOP_CON2, PDN_ETDM_IN0_SFT, 1, 633 + NULL, 0), 634 + SND_SOC_DAPM_SUPPLY_S("I2SIN1_CG", SUPPLY_SEQ_I2S_CG_EN, 635 + AUDIO_TOP_CON2, PDN_ETDM_IN1_SFT, 1, 636 + NULL, 0), 637 + 638 + /* apll */ 639 + SND_SOC_DAPM_SUPPLY_S(APLL1_W_NAME, SUPPLY_SEQ_APLL, 640 + SND_SOC_NOPM, 0, 0, 641 + mtk_apll_event, 642 + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 643 + SND_SOC_DAPM_SUPPLY_S(APLL2_W_NAME, SUPPLY_SEQ_APLL, 644 + SND_SOC_NOPM, 0, 0, 645 + mtk_apll_event, 646 + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 647 + 648 + /* allow i2s on without codec on */ 649 + SND_SOC_DAPM_OUTPUT("I2S_DUMMY_OUT"), 650 + SND_SOC_DAPM_MUX("I2S_OUT0_Mux", 651 + SND_SOC_NOPM, 0, 0, &i2s_out0_mux_control), 652 + SND_SOC_DAPM_MUX("I2S_OUT1_Mux", 653 + SND_SOC_NOPM, 0, 0, &i2s_out1_mux_control), 654 + SND_SOC_DAPM_MUX("I2S_OUT4_Mux", 655 + SND_SOC_NOPM, 0, 0, &i2s_out4_mux_control), 656 + 657 + SND_SOC_DAPM_INPUT("I2S_DUMMY_IN"), 658 + SND_SOC_DAPM_MUX("I2S_IN0_Mux", 659 + SND_SOC_NOPM, 0, 0, &i2s_in0_mux_control), 660 + SND_SOC_DAPM_MUX("I2S_IN1_Mux", 661 + SND_SOC_NOPM, 0, 0, &i2s_in1_mux_control), 662 + }; 663 + 664 + static int mtk_afe_i2s_share_connect(struct snd_soc_dapm_widget *source, 665 + struct snd_soc_dapm_widget *sink) 666 + { 667 + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(sink->dapm); 668 + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); 669 + struct mtk_afe_i2s_priv *i2s_priv; 670 + 671 + i2s_priv = get_i2s_priv_by_name(afe, sink->name); 672 + if (!i2s_priv) 673 + return 0; 674 + 675 + if (i2s_priv->share_i2s_id < 0) 676 + return 0; 677 + 678 + return i2s_priv->share_i2s_id == get_i2s_id_by_name(afe, source->name); 679 + } 680 + 681 + static int mtk_afe_i2s_apll_connect(struct snd_soc_dapm_widget *source, 682 + struct snd_soc_dapm_widget *sink) 683 + { 684 + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(sink->dapm); 685 + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); 686 + struct mtk_afe_i2s_priv *i2s_priv; 687 + int cur_apll; 688 + int needed_apll; 689 + 690 + i2s_priv = get_i2s_priv_by_name(afe, sink->name); 691 + if (!i2s_priv) 692 + return 0; 693 + 694 + /* which apll */ 695 + cur_apll = mt8189_get_apll_by_name(afe, source->name); 696 + 697 + /* choose APLL from i2s rate */ 698 + needed_apll = mt8189_get_apll_by_rate(afe, i2s_priv->rate); 699 + 700 + return needed_apll == cur_apll; 701 + } 702 + 703 + static int mtk_afe_i2s_mclk_connect(struct snd_soc_dapm_widget *source, 704 + struct snd_soc_dapm_widget *sink) 705 + { 706 + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(sink->dapm); 707 + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); 708 + struct mtk_afe_i2s_priv *i2s_priv; 709 + int i2s_num; 710 + 711 + i2s_priv = get_i2s_priv_by_name(afe, sink->name); 712 + if (!i2s_priv) 713 + return 0; 714 + 715 + i2s_num = get_i2s_id_by_name(afe, source->name); 716 + if (get_i2s_id_by_name(afe, sink->name) == i2s_num) 717 + return i2s_priv->mclk_rate > 0; 718 + 719 + /* check if share i2s need mclk */ 720 + if (i2s_priv->share_i2s_id < 0) 721 + return 0; 722 + 723 + if (i2s_priv->share_i2s_id == i2s_num) 724 + return i2s_priv->mclk_rate > 0; 725 + 726 + return 0; 727 + } 728 + 729 + static int mtk_afe_mclk_apll_connect(struct snd_soc_dapm_widget *source, 730 + struct snd_soc_dapm_widget *sink) 731 + { 732 + struct snd_soc_dapm_widget *w = sink; 733 + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); 734 + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); 735 + struct mtk_afe_i2s_priv *i2s_priv; 736 + int cur_apll; 737 + 738 + i2s_priv = get_i2s_priv_by_name(afe, w->name); 739 + if (!i2s_priv) 740 + return 0; 741 + 742 + /* which apll */ 743 + cur_apll = mt8189_get_apll_by_name(afe, source->name); 744 + 745 + return i2s_priv->mclk_apll == cur_apll; 746 + } 747 + 748 + static const struct snd_soc_dapm_route mtk_dai_i2s_routes[] = { 749 + /* I2SIN0 */ 750 + {"I2SIN0", NULL, "I2SIN0_EN"}, 751 + {"I2SIN0", NULL, "I2SIN1_EN", mtk_afe_i2s_share_connect}, 752 + {"I2SIN0", NULL, "I2SOUT0_EN", mtk_afe_i2s_share_connect}, 753 + {"I2SIN0", NULL, "I2SOUT1_EN", mtk_afe_i2s_share_connect}, 754 + {"I2SIN0", NULL, "I2SOUT4_EN", mtk_afe_i2s_share_connect}, 755 + 756 + {"I2SIN0", NULL, I2SIN0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, 757 + {"I2SIN0", NULL, I2SIN1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, 758 + {"I2SIN0", NULL, I2SOUT0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, 759 + {"I2SIN0", NULL, I2SOUT1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, 760 + {"I2SIN0", NULL, I2SOUT4_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, 761 + {I2SIN0_MCLK_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect}, 762 + {I2SIN0_MCLK_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect}, 763 + {"I2SIN0", NULL, APLL1_W_NAME, mtk_afe_i2s_apll_connect}, 764 + {"I2SIN0", NULL, APLL2_W_NAME, mtk_afe_i2s_apll_connect}, 765 + {"I2SIN0", NULL, "I2SOUT0_CG"}, 766 + {"I2SIN0", NULL, "I2SIN0_CG"}, 767 + 768 + /* i2sin1 */ 769 + {"I2SIN1", NULL, "I2SIN0_EN", mtk_afe_i2s_share_connect}, 770 + {"I2SIN1", NULL, "I2SIN1_EN"}, 771 + {"I2SIN1", NULL, "I2SOUT0_EN", mtk_afe_i2s_share_connect}, 772 + {"I2SIN1", NULL, "I2SOUT1_EN", mtk_afe_i2s_share_connect}, 773 + {"I2SIN1", NULL, "I2SOUT4_EN", mtk_afe_i2s_share_connect}, 774 + 775 + {"I2SIN1", NULL, I2SIN0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, 776 + {"I2SIN1", NULL, I2SIN1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, 777 + {"I2SIN1", NULL, I2SOUT0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, 778 + {"I2SIN1", NULL, I2SOUT1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, 779 + {"I2SIN1", NULL, I2SOUT4_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, 780 + {I2SIN1_MCLK_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect}, 781 + {I2SIN1_MCLK_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect}, 782 + {"I2SIN1", NULL, APLL1_W_NAME, mtk_afe_i2s_apll_connect}, 783 + {"I2SIN1", NULL, APLL2_W_NAME, mtk_afe_i2s_apll_connect}, 784 + {"I2SIN1", NULL, "I2SIN1_CG"}, 785 + {"I2SIN1", NULL, "I2SOUT1_CG"}, 786 + 787 + /* i2sout0 */ 788 + {"I2SOUT0_CH1", "DL0_CH1", "DL0"}, 789 + {"I2SOUT0_CH2", "DL0_CH2", "DL0"}, 790 + {"I2SOUT0_CH1", "DL1_CH1", "DL1"}, 791 + {"I2SOUT0_CH2", "DL1_CH2", "DL1"}, 792 + {"I2SOUT0_CH1", "DL2_CH1", "DL2"}, 793 + {"I2SOUT0_CH2", "DL2_CH2", "DL2"}, 794 + {"I2SOUT0_CH1", "DL3_CH1", "DL3"}, 795 + {"I2SOUT0_CH2", "DL3_CH2", "DL3"}, 796 + {"I2SOUT0_CH1", "DL4_CH1", "DL4"}, 797 + {"I2SOUT0_CH2", "DL4_CH2", "DL4"}, 798 + {"I2SOUT0_CH1", "DL5_CH1", "DL5"}, 799 + {"I2SOUT0_CH2", "DL5_CH2", "DL5"}, 800 + {"I2SOUT0_CH1", "DL6_CH1", "DL6"}, 801 + {"I2SOUT0_CH2", "DL6_CH2", "DL6"}, 802 + {"I2SOUT0_CH1", "DL7_CH1", "DL7"}, 803 + {"I2SOUT0_CH2", "DL7_CH2", "DL7"}, 804 + {"I2SOUT0_CH1", "DL8_CH1", "DL8"}, 805 + {"I2SOUT0_CH2", "DL8_CH2", "DL8"}, 806 + {"I2SOUT0_CH1", "DL_24CH_CH1", "DL_24CH"}, 807 + {"I2SOUT0_CH2", "DL_24CH_CH2", "DL_24CH"}, 808 + 809 + {"I2SOUT0", NULL, "I2SOUT0_CH1"}, 810 + {"I2SOUT0", NULL, "I2SOUT0_CH2"}, 811 + 812 + {"I2SOUT0", NULL, "I2SIN0_EN", mtk_afe_i2s_share_connect}, 813 + {"I2SOUT0", NULL, "I2SIN1_EN", mtk_afe_i2s_share_connect}, 814 + {"I2SOUT0", NULL, "I2SOUT0_EN"}, 815 + {"I2SOUT0", NULL, "I2SOUT1_EN", mtk_afe_i2s_share_connect}, 816 + {"I2SOUT0", NULL, "I2SOUT4_EN", mtk_afe_i2s_share_connect}, 817 + 818 + {"I2SOUT0", NULL, I2SIN0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, 819 + {"I2SOUT0", NULL, I2SIN1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, 820 + {"I2SOUT0", NULL, I2SOUT0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, 821 + {"I2SOUT0", NULL, I2SOUT1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, 822 + {"I2SOUT0", NULL, I2SOUT4_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, 823 + {I2SOUT0_MCLK_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect}, 824 + {I2SOUT0_MCLK_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect}, 825 + {"I2SOUT0", NULL, APLL1_W_NAME, mtk_afe_i2s_apll_connect}, 826 + {"I2SOUT0", NULL, APLL2_W_NAME, mtk_afe_i2s_apll_connect}, 827 + {"I2SOUT0", NULL, "I2SOUT0_CG"}, 828 + {"I2SOUT0", NULL, "I2SIN0_CG"}, 829 + 830 + /* i2sout1 */ 831 + {"I2SOUT1_CH1", "DL0_CH1", "DL0"}, 832 + {"I2SOUT1_CH2", "DL0_CH2", "DL0"}, 833 + {"I2SOUT1_CH1", "DL1_CH1", "DL1"}, 834 + {"I2SOUT1_CH2", "DL1_CH2", "DL1"}, 835 + {"I2SOUT1_CH1", "DL2_CH1", "DL2"}, 836 + {"I2SOUT1_CH2", "DL2_CH2", "DL2"}, 837 + {"I2SOUT1_CH1", "DL3_CH1", "DL3"}, 838 + {"I2SOUT1_CH2", "DL3_CH2", "DL3"}, 839 + {"I2SOUT1_CH1", "DL4_CH1", "DL4"}, 840 + {"I2SOUT1_CH2", "DL4_CH2", "DL4"}, 841 + {"I2SOUT1_CH1", "DL5_CH1", "DL5"}, 842 + {"I2SOUT1_CH2", "DL5_CH2", "DL5"}, 843 + {"I2SOUT1_CH1", "DL6_CH1", "DL6"}, 844 + {"I2SOUT1_CH2", "DL6_CH2", "DL6"}, 845 + {"I2SOUT1_CH1", "DL7_CH1", "DL7"}, 846 + {"I2SOUT1_CH2", "DL7_CH2", "DL7"}, 847 + {"I2SOUT1_CH1", "DL8_CH1", "DL8"}, 848 + {"I2SOUT1_CH2", "DL8_CH2", "DL8"}, 849 + {"I2SOUT1_CH1", "DL_24CH_CH1", "DL_24CH"}, 850 + {"I2SOUT1_CH2", "DL_24CH_CH2", "DL_24CH"}, 851 + 852 + {"I2SOUT1", NULL, "I2SOUT1_CH1"}, 853 + {"I2SOUT1", NULL, "I2SOUT1_CH2"}, 854 + 855 + {"I2SOUT1", NULL, "I2SIN0_EN", mtk_afe_i2s_share_connect}, 856 + {"I2SOUT1", NULL, "I2SIN1_EN", mtk_afe_i2s_share_connect}, 857 + {"I2SOUT1", NULL, "I2SOUT0_EN", mtk_afe_i2s_share_connect}, 858 + {"I2SOUT1", NULL, "I2SOUT1_EN"}, 859 + {"I2SOUT1", NULL, "I2SOUT4_EN", mtk_afe_i2s_share_connect}, 860 + 861 + {"I2SOUT1", NULL, I2SIN0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, 862 + {"I2SOUT1", NULL, I2SIN1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, 863 + {"I2SOUT1", NULL, I2SOUT0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, 864 + {"I2SOUT1", NULL, I2SOUT1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, 865 + {"I2SOUT1", NULL, I2SOUT4_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, 866 + {I2SOUT1_MCLK_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect}, 867 + {I2SOUT1_MCLK_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect}, 868 + {"I2SOUT1", NULL, APLL1_W_NAME, mtk_afe_i2s_apll_connect}, 869 + {"I2SOUT1", NULL, APLL2_W_NAME, mtk_afe_i2s_apll_connect}, 870 + {"I2SOUT1", NULL, "I2SOUT1_CG"}, 871 + {"I2SOUT1", NULL, "I2SIN1_CG"}, 872 + 873 + /* i2sout4 */ 874 + {"I2SOUT4_CH1", "DL0_CH1", "DL0"}, 875 + {"I2SOUT4_CH2", "DL0_CH2", "DL0"}, 876 + {"I2SOUT4_CH1", "DL1_CH1", "DL1"}, 877 + {"I2SOUT4_CH2", "DL1_CH2", "DL1"}, 878 + {"I2SOUT4_CH1", "DL2_CH1", "DL2"}, 879 + {"I2SOUT4_CH2", "DL2_CH2", "DL2"}, 880 + {"I2SOUT4_CH1", "DL3_CH1", "DL3"}, 881 + {"I2SOUT4_CH2", "DL3_CH2", "DL3"}, 882 + {"I2SOUT4_CH1", "DL4_CH1", "DL4"}, 883 + {"I2SOUT4_CH2", "DL4_CH2", "DL4"}, 884 + {"I2SOUT4_CH1", "DL5_CH1", "DL5"}, 885 + {"I2SOUT4_CH2", "DL5_CH2", "DL5"}, 886 + {"I2SOUT4_CH1", "DL6_CH1", "DL6"}, 887 + {"I2SOUT4_CH2", "DL6_CH2", "DL6"}, 888 + {"I2SOUT4_CH1", "DL7_CH1", "DL7"}, 889 + {"I2SOUT4_CH2", "DL7_CH2", "DL7"}, 890 + {"I2SOUT4_CH1", "DL8_CH1", "DL8"}, 891 + {"I2SOUT4_CH2", "DL8_CH2", "DL8"}, 892 + {"I2SOUT4_CH1", "DL_24CH_CH1", "DL_24CH"}, 893 + {"I2SOUT4_CH2", "DL_24CH_CH2", "DL_24CH"}, 894 + {"I2SOUT4_CH3", "DL_24CH_CH3", "DL_24CH"}, 895 + {"I2SOUT4_CH4", "DL_24CH_CH4", "DL_24CH"}, 896 + {"I2SOUT4_CH5", "DL_24CH_CH5", "DL_24CH"}, 897 + {"I2SOUT4_CH6", "DL_24CH_CH6", "DL_24CH"}, 898 + {"I2SOUT4_CH7", "DL_24CH_CH7", "DL_24CH"}, 899 + {"I2SOUT4_CH8", "DL_24CH_CH8", "DL_24CH"}, 900 + {"I2SOUT4_CH1", "DL24_CH1", "DL24"}, 901 + {"I2SOUT4_CH2", "DL24_CH2", "DL24"}, 902 + 903 + {"I2SOUT4", NULL, "I2SOUT4_CH1"}, 904 + {"I2SOUT4", NULL, "I2SOUT4_CH2"}, 905 + {"I2SOUT4", NULL, "I2SOUT4_CH3"}, 906 + {"I2SOUT4", NULL, "I2SOUT4_CH4"}, 907 + {"I2SOUT4", NULL, "I2SOUT4_CH5"}, 908 + {"I2SOUT4", NULL, "I2SOUT4_CH6"}, 909 + {"I2SOUT4", NULL, "I2SOUT4_CH7"}, 910 + {"I2SOUT4", NULL, "I2SOUT4_CH8"}, 911 + 912 + {"I2SOUT4", NULL, "I2SIN0_EN", mtk_afe_i2s_share_connect}, 913 + {"I2SOUT4", NULL, "I2SIN1_EN", mtk_afe_i2s_share_connect}, 914 + {"I2SOUT4", NULL, "I2SOUT0_EN", mtk_afe_i2s_share_connect}, 915 + {"I2SOUT4", NULL, "I2SOUT1_EN", mtk_afe_i2s_share_connect}, 916 + {"I2SOUT4", NULL, "I2SOUT4_EN"}, 917 + 918 + {"I2SOUT4", NULL, I2SIN0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, 919 + {"I2SOUT4", NULL, I2SIN1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, 920 + {"I2SOUT4", NULL, I2SOUT0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, 921 + {"I2SOUT4", NULL, I2SOUT1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, 922 + {"I2SOUT4", NULL, I2SOUT4_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, 923 + {I2SOUT4_MCLK_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect}, 924 + {I2SOUT4_MCLK_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect}, 925 + {"I2SOUT4", NULL, APLL1_W_NAME, mtk_afe_i2s_apll_connect}, 926 + {"I2SOUT4", NULL, APLL2_W_NAME, mtk_afe_i2s_apll_connect}, 927 + /* CG */ 928 + {"I2SOUT4", NULL, "I2SOUT4_CG"}, 929 + 930 + /* allow i2s on without codec on */ 931 + {"I2SIN0", NULL, "I2S_IN0_Mux"}, 932 + {"I2S_IN0_Mux", "Dummy_Widget", "I2S_DUMMY_IN"}, 933 + 934 + {"I2SIN1", NULL, "I2S_IN1_Mux"}, 935 + {"I2S_IN1_Mux", "Dummy_Widget", "I2S_DUMMY_IN"}, 936 + 937 + {"I2S_OUT0_Mux", "Dummy_Widget", "I2SOUT0"}, 938 + {"I2S_DUMMY_OUT", NULL, "I2S_OUT0_Mux"}, 939 + 940 + {"I2S_OUT1_Mux", "Dummy_Widget", "I2SOUT1"}, 941 + {"I2S_DUMMY_OUT", NULL, "I2S_OUT1_Mux"}, 942 + 943 + {"I2S_OUT4_Mux", "Dummy_Widget", "I2SOUT4"}, 944 + {"I2S_DUMMY_OUT", NULL, "I2S_OUT4_Mux"}, 945 + }; 946 + 947 + /* i2s dai ops*/ 948 + static int mtk_dai_i2s_config(struct mtk_base_afe *afe, 949 + struct snd_pcm_hw_params *params, 950 + int i2s_id) 951 + { 952 + struct mt8189_afe_private *afe_priv = afe->platform_priv; 953 + struct mtk_afe_i2s_priv *i2s_priv; 954 + unsigned int rate = params_rate(params); 955 + snd_pcm_format_t format = params_format(params); 956 + int ret; 957 + 958 + if (i2s_id >= MT8189_DAI_NUM || i2s_id < 0) 959 + return -EINVAL; 960 + 961 + i2s_priv = afe_priv->dai_priv[i2s_id]; 962 + if (!i2s_priv) 963 + return -EINVAL; 964 + 965 + i2s_priv->rate = rate; 966 + 967 + dev_dbg(afe->dev, "%s(), id %d, rate %d, format %d\n", 968 + __func__, i2s_id, rate, format); 969 + 970 + switch (i2s_id) { 971 + case MT8189_DAI_I2S_IN0: 972 + /* ---etdm in --- */ 973 + regmap_update_bits(afe->regmap, ETDM_IN0_CON1, 974 + REG_INITIAL_COUNT_MASK_SFT, 975 + 0x5 << REG_INITIAL_COUNT_SFT); 976 + /* 3: pad top 5: no pad top */ 977 + regmap_update_bits(afe->regmap, ETDM_IN0_CON1, 978 + REG_INITIAL_POINT_MASK_SFT, 979 + 0x5 << REG_INITIAL_POINT_SFT); 980 + regmap_update_bits(afe->regmap, ETDM_IN0_CON1, 981 + REG_LRCK_RESET_MASK_SFT, 982 + 0x1 << REG_LRCK_RESET_SFT); 983 + regmap_update_bits(afe->regmap, ETDM_IN0_CON2, 984 + REG_CLOCK_SOURCE_SEL_MASK_SFT, 985 + ETDM_CLK_SOURCE_APLL << 986 + REG_CLOCK_SOURCE_SEL_SFT); 987 + /* 0: manual 1: auto */ 988 + regmap_update_bits(afe->regmap, ETDM_IN0_CON2, 989 + REG_CK_EN_SEL_AUTO_MASK_SFT, 990 + 0x1 << REG_CK_EN_SEL_AUTO_SFT); 991 + regmap_update_bits(afe->regmap, ETDM_IN0_CON3, 992 + REG_FS_TIMING_SEL_MASK_SFT, 993 + get_etdm_rate(rate) << 994 + REG_FS_TIMING_SEL_SFT); 995 + regmap_update_bits(afe->regmap, ETDM_IN0_CON4, 996 + REG_RELATCH_1X_EN_SEL_MASK_SFT, 997 + get_etdm_inconn_rate(rate) << 998 + REG_RELATCH_1X_EN_SEL_SFT); 999 + 1000 + regmap_update_bits(afe->regmap, ETDM_IN0_CON8, 1001 + REG_ETDM_USE_AFIFO_MASK_SFT, 1002 + 0x0 << REG_ETDM_USE_AFIFO_SFT); 1003 + regmap_update_bits(afe->regmap, ETDM_IN0_CON8, 1004 + REG_AFIFO_MODE_MASK_SFT, 1005 + 0x0 << REG_AFIFO_MODE_SFT); 1006 + regmap_update_bits(afe->regmap, ETDM_IN0_CON9, 1007 + REG_ALMOST_END_CH_COUNT_MASK_SFT, 1008 + 0x0 << REG_ALMOST_END_CH_COUNT_SFT); 1009 + regmap_update_bits(afe->regmap, ETDM_IN0_CON9, 1010 + REG_ALMOST_END_BIT_COUNT_MASK_SFT, 1011 + 0x0 << REG_ALMOST_END_BIT_COUNT_SFT); 1012 + regmap_update_bits(afe->regmap, ETDM_IN0_CON9, 1013 + REG_OUT2LATCH_TIME_MASK_SFT, 1014 + 0x6 << REG_OUT2LATCH_TIME_SFT); 1015 + 1016 + /* 5: TDM Mode */ 1017 + regmap_update_bits(afe->regmap, ETDM_IN0_CON0, 1018 + REG_FMT_MASK_SFT, 0x0 << REG_FMT_SFT); 1019 + 1020 + /* APLL */ 1021 + regmap_update_bits(afe->regmap, ETDM_IN0_CON0, 1022 + REG_RELATCH_1X_EN_DOMAIN_SEL_MASK_SFT, 1023 + ETDM_RELATCH_SEL_APLL 1024 + << REG_RELATCH_1X_EN_DOMAIN_SEL_SFT); 1025 + regmap_update_bits(afe->regmap, ETDM_IN0_CON0, 1026 + REG_BIT_LENGTH_MASK_SFT, 1027 + get_etdm_lrck_width(format) << 1028 + REG_BIT_LENGTH_SFT); 1029 + regmap_update_bits(afe->regmap, ETDM_IN0_CON0, 1030 + REG_WORD_LENGTH_MASK_SFT, 1031 + get_etdm_wlen(format) << 1032 + REG_WORD_LENGTH_SFT); 1033 + 1034 + /* ---etdm cowork --- */ 1035 + regmap_update_bits(afe->regmap, ETDM_0_3_COWORK_CON0, 1036 + ETDM_IN0_SLAVE_SEL_MASK_SFT, 1037 + ETDM_SLAVE_SEL_ETDMOUT0_MASTER 1038 + << ETDM_IN0_SLAVE_SEL_SFT); 1039 + break; 1040 + case MT8189_DAI_I2S_IN1: 1041 + /* ---etdm in --- */ 1042 + regmap_update_bits(afe->regmap, ETDM_IN1_CON1, 1043 + REG_INITIAL_COUNT_MASK_SFT, 1044 + 0x5 << REG_INITIAL_COUNT_SFT); 1045 + /* 3: pad top 5: no pad top */ 1046 + regmap_update_bits(afe->regmap, ETDM_IN1_CON1, 1047 + REG_INITIAL_POINT_MASK_SFT, 1048 + 0x5 << REG_INITIAL_POINT_SFT); 1049 + regmap_update_bits(afe->regmap, ETDM_IN1_CON1, 1050 + REG_LRCK_RESET_MASK_SFT, 1051 + 0x1 << REG_LRCK_RESET_SFT); 1052 + regmap_update_bits(afe->regmap, ETDM_IN1_CON2, 1053 + REG_CLOCK_SOURCE_SEL_MASK_SFT, 1054 + ETDM_CLK_SOURCE_APLL << 1055 + REG_CLOCK_SOURCE_SEL_SFT); 1056 + /* 0: manual 1: auto */ 1057 + regmap_update_bits(afe->regmap, ETDM_IN1_CON2, 1058 + REG_CK_EN_SEL_AUTO_MASK_SFT, 1059 + 0x1 << REG_CK_EN_SEL_AUTO_SFT); 1060 + regmap_update_bits(afe->regmap, ETDM_IN1_CON3, 1061 + REG_FS_TIMING_SEL_MASK_SFT, 1062 + get_etdm_rate(rate) << 1063 + REG_FS_TIMING_SEL_SFT); 1064 + regmap_update_bits(afe->regmap, ETDM_IN1_CON4, 1065 + REG_RELATCH_1X_EN_SEL_MASK_SFT, 1066 + get_etdm_inconn_rate(rate) << 1067 + REG_RELATCH_1X_EN_SEL_SFT); 1068 + 1069 + regmap_update_bits(afe->regmap, ETDM_IN1_CON8, 1070 + REG_ETDM_USE_AFIFO_MASK_SFT, 1071 + 0x0 << REG_ETDM_USE_AFIFO_SFT); 1072 + regmap_update_bits(afe->regmap, ETDM_IN1_CON8, 1073 + REG_AFIFO_MODE_MASK_SFT, 1074 + 0x0 << REG_AFIFO_MODE_SFT); 1075 + regmap_update_bits(afe->regmap, ETDM_IN1_CON9, 1076 + REG_ALMOST_END_CH_COUNT_MASK_SFT, 1077 + 0x0 << REG_ALMOST_END_CH_COUNT_SFT); 1078 + regmap_update_bits(afe->regmap, ETDM_IN1_CON9, 1079 + REG_ALMOST_END_BIT_COUNT_MASK_SFT, 1080 + 0x0 << REG_ALMOST_END_BIT_COUNT_SFT); 1081 + regmap_update_bits(afe->regmap, ETDM_IN1_CON9, 1082 + REG_OUT2LATCH_TIME_MASK_SFT, 1083 + 0x6 << REG_OUT2LATCH_TIME_SFT); 1084 + 1085 + /* 5: TDM Mode */ 1086 + regmap_update_bits(afe->regmap, ETDM_IN1_CON0, 1087 + REG_FMT_MASK_SFT, 0x0 << REG_FMT_SFT); 1088 + 1089 + /* APLL */ 1090 + regmap_update_bits(afe->regmap, ETDM_IN1_CON0, 1091 + REG_RELATCH_1X_EN_DOMAIN_SEL_MASK_SFT, 1092 + ETDM_RELATCH_SEL_APLL 1093 + << REG_RELATCH_1X_EN_DOMAIN_SEL_SFT); 1094 + regmap_update_bits(afe->regmap, ETDM_IN1_CON0, 1095 + REG_BIT_LENGTH_MASK_SFT, 1096 + get_etdm_lrck_width(format) << 1097 + REG_BIT_LENGTH_SFT); 1098 + regmap_update_bits(afe->regmap, ETDM_IN1_CON0, 1099 + REG_WORD_LENGTH_MASK_SFT, 1100 + get_etdm_wlen(format) << 1101 + REG_WORD_LENGTH_SFT); 1102 + 1103 + /* ---etdm cowork --- */ 1104 + regmap_update_bits(afe->regmap, ETDM_0_3_COWORK_CON1, 1105 + ETDM_IN1_SLAVE_SEL_MASK_SFT, 1106 + ETDM_SLAVE_SEL_ETDMOUT1_MASTER 1107 + << ETDM_IN1_SLAVE_SEL_SFT); 1108 + break; 1109 + case MT8189_DAI_I2S_OUT0: 1110 + /* ---etdm out --- */ 1111 + regmap_update_bits(afe->regmap, ETDM_OUT0_CON1, 1112 + OUT_REG_INITIAL_COUNT_MASK_SFT, 1113 + 0x5 << OUT_REG_INITIAL_COUNT_SFT); 1114 + regmap_update_bits(afe->regmap, ETDM_OUT0_CON1, 1115 + OUT_REG_INITIAL_POINT_MASK_SFT, 1116 + 0x6 << OUT_REG_INITIAL_POINT_SFT); 1117 + regmap_update_bits(afe->regmap, ETDM_OUT0_CON1, 1118 + OUT_REG_LRCK_RESET_MASK_SFT, 1119 + 0x1 << OUT_REG_LRCK_RESET_SFT); 1120 + regmap_update_bits(afe->regmap, ETDM_OUT0_CON4, 1121 + OUT_REG_FS_TIMING_SEL_MASK_SFT, 1122 + get_etdm_rate(rate) << 1123 + OUT_REG_FS_TIMING_SEL_SFT); 1124 + regmap_update_bits(afe->regmap, ETDM_OUT0_CON4, 1125 + OUT_REG_CLOCK_SOURCE_SEL_MASK_SFT, 1126 + ETDM_CLK_SOURCE_APLL << 1127 + OUT_REG_CLOCK_SOURCE_SEL_SFT); 1128 + regmap_update_bits(afe->regmap, ETDM_OUT0_CON4, 1129 + OUT_REG_RELATCH_EN_SEL_MASK_SFT, 1130 + get_etdm_inconn_rate(rate) << 1131 + OUT_REG_RELATCH_EN_SEL_SFT); 1132 + /* 5: TDM Mode */ 1133 + regmap_update_bits(afe->regmap, ETDM_OUT0_CON0, 1134 + OUT_REG_FMT_MASK_SFT, 1135 + 0x0 << OUT_REG_FMT_SFT); 1136 + 1137 + /* APLL */ 1138 + regmap_update_bits(afe->regmap, ETDM_OUT0_CON0, 1139 + OUT_REG_RELATCH_DOMAIN_SEL_MASK_SFT, 1140 + ETDM_RELATCH_SEL_APLL 1141 + << OUT_REG_RELATCH_DOMAIN_SEL_SFT); 1142 + regmap_update_bits(afe->regmap, ETDM_OUT0_CON0, 1143 + OUT_REG_BIT_LENGTH_MASK_SFT, 1144 + get_etdm_lrck_width(format) << 1145 + OUT_REG_BIT_LENGTH_SFT); 1146 + regmap_update_bits(afe->regmap, ETDM_OUT0_CON0, 1147 + OUT_REG_WORD_LENGTH_MASK_SFT, 1148 + get_etdm_wlen(format) << 1149 + OUT_REG_WORD_LENGTH_SFT); 1150 + 1151 + /* ---etdm cowork --- */ 1152 + regmap_update_bits(afe->regmap, ETDM_0_3_COWORK_CON0, 1153 + ETDM_OUT0_SLAVE_SEL_MASK_SFT, 1154 + ETDM_SLAVE_SEL_ETDMIN0_MASTER 1155 + << ETDM_OUT0_SLAVE_SEL_SFT); 1156 + break; 1157 + case MT8189_DAI_I2S_OUT1: 1158 + /* ---etdm out --- */ 1159 + regmap_update_bits(afe->regmap, ETDM_OUT1_CON1, 1160 + OUT_REG_INITIAL_COUNT_MASK_SFT, 1161 + 0x5 << OUT_REG_INITIAL_COUNT_SFT); 1162 + regmap_update_bits(afe->regmap, ETDM_OUT1_CON1, 1163 + OUT_REG_INITIAL_POINT_MASK_SFT, 1164 + 0x6 << OUT_REG_INITIAL_POINT_SFT); 1165 + regmap_update_bits(afe->regmap, ETDM_OUT1_CON1, 1166 + OUT_REG_LRCK_RESET_MASK_SFT, 1167 + 0x1 << OUT_REG_LRCK_RESET_SFT); 1168 + regmap_update_bits(afe->regmap, ETDM_OUT1_CON4, 1169 + OUT_REG_FS_TIMING_SEL_MASK_SFT, 1170 + get_etdm_rate(rate) << 1171 + OUT_REG_FS_TIMING_SEL_SFT); 1172 + regmap_update_bits(afe->regmap, ETDM_OUT1_CON4, 1173 + OUT_REG_CLOCK_SOURCE_SEL_MASK_SFT, 1174 + ETDM_CLK_SOURCE_APLL << 1175 + OUT_REG_CLOCK_SOURCE_SEL_SFT); 1176 + regmap_update_bits(afe->regmap, ETDM_OUT1_CON4, 1177 + OUT_REG_RELATCH_EN_SEL_MASK_SFT, 1178 + get_etdm_inconn_rate(rate) << 1179 + OUT_REG_RELATCH_EN_SEL_SFT); 1180 + /* 5: TDM Mode */ 1181 + regmap_update_bits(afe->regmap, ETDM_OUT1_CON0, 1182 + OUT_REG_FMT_MASK_SFT, 1183 + 0x0 << OUT_REG_FMT_SFT); 1184 + 1185 + /* APLL */ 1186 + regmap_update_bits(afe->regmap, ETDM_OUT1_CON0, 1187 + OUT_REG_RELATCH_DOMAIN_SEL_MASK_SFT, 1188 + ETDM_RELATCH_SEL_APLL 1189 + << OUT_REG_RELATCH_DOMAIN_SEL_SFT); 1190 + regmap_update_bits(afe->regmap, ETDM_OUT1_CON0, 1191 + OUT_REG_BIT_LENGTH_MASK_SFT, 1192 + get_etdm_lrck_width(format) << 1193 + OUT_REG_BIT_LENGTH_SFT); 1194 + regmap_update_bits(afe->regmap, ETDM_OUT1_CON0, 1195 + OUT_REG_WORD_LENGTH_MASK_SFT, 1196 + get_etdm_wlen(format) << 1197 + OUT_REG_WORD_LENGTH_SFT); 1198 + 1199 + /* ---etdm cowork --- */ 1200 + regmap_update_bits(afe->regmap, ETDM_0_3_COWORK_CON0, 1201 + ETDM_OUT1_SLAVE_SEL_MASK_SFT, 1202 + ETDM_SLAVE_SEL_ETDMIN1_MASTER 1203 + << ETDM_OUT1_SLAVE_SEL_SFT); 1204 + break; 1205 + case MT8189_DAI_I2S_OUT4: 1206 + /* ---etdm out --- */ 1207 + regmap_update_bits(afe->regmap, ETDM_OUT4_CON1, 1208 + OUT_REG_INITIAL_COUNT_MASK_SFT, 1209 + 0x5 << OUT_REG_INITIAL_COUNT_SFT); 1210 + regmap_update_bits(afe->regmap, ETDM_OUT4_CON1, 1211 + OUT_REG_INITIAL_POINT_MASK_SFT, 1212 + 0x6 << OUT_REG_INITIAL_POINT_SFT); 1213 + regmap_update_bits(afe->regmap, ETDM_OUT4_CON1, 1214 + OUT_REG_LRCK_RESET_MASK_SFT, 1215 + 0x1 << OUT_REG_LRCK_RESET_SFT); 1216 + regmap_update_bits(afe->regmap, ETDM_OUT4_CON4, 1217 + OUT_REG_FS_TIMING_SEL_MASK_SFT, 1218 + get_etdm_rate(rate) << 1219 + OUT_REG_FS_TIMING_SEL_SFT); 1220 + regmap_update_bits(afe->regmap, ETDM_OUT4_CON4, 1221 + OUT_REG_CLOCK_SOURCE_SEL_MASK_SFT, 1222 + ETDM_CLK_SOURCE_APLL << 1223 + OUT_REG_CLOCK_SOURCE_SEL_SFT); 1224 + regmap_update_bits(afe->regmap, ETDM_OUT4_CON4, 1225 + OUT_REG_RELATCH_EN_SEL_MASK_SFT, 1226 + get_etdm_inconn_rate(rate) << 1227 + OUT_REG_RELATCH_EN_SEL_SFT); 1228 + /* 5: TDM Mode */ 1229 + regmap_update_bits(afe->regmap, ETDM_OUT4_CON0, 1230 + OUT_REG_FMT_MASK_SFT, 1231 + 0x0 << OUT_REG_FMT_SFT); 1232 + 1233 + /* APLL */ 1234 + regmap_update_bits(afe->regmap, ETDM_OUT4_CON0, 1235 + OUT_REG_RELATCH_DOMAIN_SEL_MASK_SFT, 1236 + ETDM_RELATCH_SEL_APLL 1237 + << OUT_REG_RELATCH_DOMAIN_SEL_SFT); 1238 + regmap_update_bits(afe->regmap, ETDM_OUT4_CON0, 1239 + OUT_REG_BIT_LENGTH_MASK_SFT, 1240 + get_etdm_lrck_width(format) << 1241 + OUT_REG_BIT_LENGTH_SFT); 1242 + regmap_update_bits(afe->regmap, ETDM_OUT4_CON0, 1243 + OUT_REG_WORD_LENGTH_MASK_SFT, 1244 + get_etdm_wlen(format) << 1245 + OUT_REG_WORD_LENGTH_SFT); 1246 + break; 1247 + default: 1248 + dev_err(afe->dev, "%s(), id %d not support\n", 1249 + __func__, i2s_id); 1250 + return -EINVAL; 1251 + } 1252 + 1253 + /* set share i2s */ 1254 + if (i2s_priv->share_i2s_id >= 0) { 1255 + ret = mtk_dai_i2s_config(afe, params, i2s_priv->share_i2s_id); 1256 + if (ret) 1257 + return ret; 1258 + } 1259 + 1260 + return 0; 1261 + } 1262 + 1263 + static int mtk_dai_i2s_hw_params(struct snd_pcm_substream *substream, 1264 + struct snd_pcm_hw_params *params, 1265 + struct snd_soc_dai *dai) 1266 + { 1267 + struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); 1268 + 1269 + return mtk_dai_i2s_config(afe, params, dai->id); 1270 + } 1271 + 1272 + static int mtk_dai_i2s_set_sysclk(struct snd_soc_dai *dai, 1273 + int clk_id, unsigned int freq, int dir) 1274 + { 1275 + struct mtk_base_afe *afe = dev_get_drvdata(dai->dev); 1276 + struct mt8189_afe_private *afe_priv = afe->platform_priv; 1277 + struct mtk_afe_i2s_priv *i2s_priv; 1278 + int apll; 1279 + int apll_rate; 1280 + 1281 + if (dai->id >= MT8189_DAI_NUM || dai->id < 0 || 1282 + dir != SND_SOC_CLOCK_OUT) 1283 + return -EINVAL; 1284 + 1285 + i2s_priv = afe_priv->dai_priv[dai->id]; 1286 + if (!i2s_priv) 1287 + return -EINVAL; 1288 + 1289 + dev_dbg(afe->dev, "%s(), freq %d\n", __func__, freq); 1290 + 1291 + apll = mt8189_get_apll_by_rate(afe, freq); 1292 + apll_rate = mt8189_get_apll_rate(afe, apll); 1293 + 1294 + if (freq > apll_rate || apll_rate % freq) { 1295 + dev_err(afe->dev, "%s(), freq %d, apll_rate %d\n", 1296 + __func__, freq, apll_rate); 1297 + return -EINVAL; 1298 + } 1299 + 1300 + i2s_priv->mclk_rate = freq; 1301 + i2s_priv->mclk_apll = apll; 1302 + 1303 + if (i2s_priv->share_i2s_id > 0) { 1304 + struct mtk_afe_i2s_priv *share_i2s_priv; 1305 + 1306 + share_i2s_priv = afe_priv->dai_priv[i2s_priv->share_i2s_id]; 1307 + if (!share_i2s_priv) 1308 + return -EINVAL; 1309 + 1310 + share_i2s_priv->mclk_rate = i2s_priv->mclk_rate; 1311 + share_i2s_priv->mclk_apll = i2s_priv->mclk_apll; 1312 + } 1313 + 1314 + return 0; 1315 + } 1316 + 1317 + static const struct snd_soc_dai_ops mtk_dai_i2s_ops = { 1318 + .hw_params = mtk_dai_i2s_hw_params, 1319 + .set_sysclk = mtk_dai_i2s_set_sysclk, 1320 + }; 1321 + 1322 + /* dai driver */ 1323 + #define MTK_ETDM_RATES (SNDRV_PCM_RATE_8000_192000) 1324 + #define MTK_ETDM_FORMATS (SNDRV_PCM_FMTBIT_S8 |\ 1325 + SNDRV_PCM_FMTBIT_S16_LE |\ 1326 + SNDRV_PCM_FMTBIT_S24_LE |\ 1327 + SNDRV_PCM_FMTBIT_S32_LE) 1328 + 1329 + #define MT8189_I2S_DAI(_name, _id, max_ch, dir) \ 1330 + { \ 1331 + .name = #_name, \ 1332 + .id = _id, \ 1333 + .dir = { \ 1334 + .stream_name = #_name, \ 1335 + .channels_min = 1, \ 1336 + .channels_max = max_ch, \ 1337 + .rates = MTK_ETDM_RATES, \ 1338 + .formats = MTK_ETDM_FORMATS, \ 1339 + }, \ 1340 + .ops = &mtk_dai_i2s_ops, \ 1341 + } 1342 + 1343 + static struct snd_soc_dai_driver mtk_dai_i2s_driver[] = { 1344 + /* capture */ 1345 + MT8189_I2S_DAI(I2SIN0, MT8189_DAI_I2S_IN0, 2, capture), 1346 + MT8189_I2S_DAI(I2SIN1, MT8189_DAI_I2S_IN1, 2, capture), 1347 + /* playback */ 1348 + MT8189_I2S_DAI(I2SOUT0, MT8189_DAI_I2S_OUT0, 2, playback), 1349 + MT8189_I2S_DAI(I2SOUT1, MT8189_DAI_I2S_OUT1, 2, playback), 1350 + MT8189_I2S_DAI(I2SOUT4, MT8189_DAI_I2S_OUT4, 8, playback), 1351 + }; 1352 + 1353 + static const struct mtk_afe_i2s_priv mt8189_i2s_priv[DAI_I2S_NUM] = { 1354 + [DAI_I2SIN0] = { 1355 + .id = MT8189_DAI_I2S_IN0, 1356 + .mclk_id = MT8189_I2SIN0_MCK, 1357 + .share_property_name = "i2sin0-share", 1358 + .share_i2s_id = MT8189_DAI_I2S_OUT0, 1359 + }, 1360 + [DAI_I2SIN1] = { 1361 + .id = MT8189_DAI_I2S_IN1, 1362 + .mclk_id = MT8189_I2SIN1_MCK, 1363 + .share_property_name = "i2sin1-share", 1364 + .share_i2s_id = MT8189_DAI_I2S_OUT1, 1365 + }, 1366 + [DAI_I2SOUT0] = { 1367 + .id = MT8189_DAI_I2S_OUT0, 1368 + .mclk_id = MT8189_I2SOUT0_MCK, 1369 + .share_property_name = "i2sout0-share", 1370 + .share_i2s_id = -1, 1371 + }, 1372 + [DAI_I2SOUT1] = { 1373 + .id = MT8189_DAI_I2S_OUT1, 1374 + .mclk_id = MT8189_I2SOUT1_MCK, 1375 + .share_property_name = "i2sout1-share", 1376 + .share_i2s_id = -1, 1377 + }, 1378 + [DAI_I2SOUT4] = { 1379 + .id = MT8189_DAI_I2S_OUT4, 1380 + .mclk_id = MT8189_I2SIN1_MCK, 1381 + .share_property_name = "i2sout4-share", 1382 + .share_i2s_id = -1, 1383 + }, 1384 + }; 1385 + 1386 + static int mt8189_dai_i2s_get_share(struct mtk_base_afe *afe) 1387 + { 1388 + struct mt8189_afe_private *afe_priv = afe->platform_priv; 1389 + const struct device_node *of_node = afe->dev->of_node; 1390 + 1391 + for (int i = 0; i < DAI_I2S_NUM; i++) { 1392 + const char *of_str; 1393 + struct mtk_afe_i2s_priv *i2s_priv = 1394 + afe_priv->dai_priv[mt8189_i2s_priv[i].id]; 1395 + const char *property_name = 1396 + mt8189_i2s_priv[i].share_property_name; 1397 + 1398 + if (of_property_read_string(of_node, property_name, &of_str)) 1399 + continue; 1400 + 1401 + i2s_priv->share_i2s_id = get_i2s_id_by_name(afe, of_str); 1402 + } 1403 + 1404 + return 0; 1405 + } 1406 + 1407 + static int init_i2s_priv_data(struct mtk_base_afe *afe) 1408 + { 1409 + struct mt8189_afe_private *afe_priv = afe->platform_priv; 1410 + struct mtk_afe_i2s_priv *i2s_priv; 1411 + 1412 + for (int i = 0; i < DAI_I2S_NUM; i++) { 1413 + int id = mt8189_i2s_priv[i].id; 1414 + size_t size = sizeof(struct mtk_afe_i2s_priv); 1415 + 1416 + if (id >= MT8189_DAI_NUM || id < 0) 1417 + return -EINVAL; 1418 + 1419 + i2s_priv = devm_kzalloc(afe->dev, size, GFP_KERNEL); 1420 + if (!i2s_priv) 1421 + return -ENOMEM; 1422 + 1423 + memcpy(i2s_priv, &mt8189_i2s_priv[i], size); 1424 + 1425 + afe_priv->dai_priv[id] = i2s_priv; 1426 + } 1427 + 1428 + return 0; 1429 + } 1430 + 1431 + int mt8189_dai_i2s_register(struct mtk_base_afe *afe) 1432 + { 1433 + struct mtk_base_afe_dai *dai; 1434 + int ret; 1435 + 1436 + dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL); 1437 + if (!dai) 1438 + return -ENOMEM; 1439 + 1440 + dai->dai_drivers = mtk_dai_i2s_driver; 1441 + dai->num_dai_drivers = ARRAY_SIZE(mtk_dai_i2s_driver); 1442 + 1443 + dai->controls = mtk_dai_i2s_controls; 1444 + dai->num_controls = ARRAY_SIZE(mtk_dai_i2s_controls); 1445 + dai->dapm_widgets = mtk_dai_i2s_widgets; 1446 + dai->num_dapm_widgets = ARRAY_SIZE(mtk_dai_i2s_widgets); 1447 + dai->dapm_routes = mtk_dai_i2s_routes; 1448 + dai->num_dapm_routes = ARRAY_SIZE(mtk_dai_i2s_routes); 1449 + 1450 + /* set all dai i2s private data */ 1451 + ret = init_i2s_priv_data(afe); 1452 + if (ret) 1453 + return ret; 1454 + 1455 + /* parse share i2s */ 1456 + ret = mt8189_dai_i2s_get_share(afe); 1457 + if (ret) 1458 + return ret; 1459 + 1460 + list_add(&dai->list, &afe->sub_dais); 1461 + 1462 + return 0; 1463 + }