1 // SPDX-License-Identifier: GPL-2.0 2 // 3 // MediaTek ALSA SoC Audio DAI SRC Control 4 // 5 // Copyright (c) 2022 MediaTek Inc. 6 // Author: Jiaxin Yu <jiaxin.yu@mediatek.com> 7 8 #include <linux/regmap.h> 9 #include "mt8186-afe-common.h" 10 #include "mt8186-interconnection.h" 11 12 struct mtk_afe_src_priv { 13 int dl_rate; 14 int ul_rate; 15 }; 16 17 static const unsigned int src_iir_coeff_32_to_16[] = { 18 0x0dbae6, 0xff9b0a, 0x0dbae6, 0x05e488, 0xe072b9, 0x000002, 19 0x0dbae6, 0x000f3b, 0x0dbae6, 0x06a537, 0xe17d79, 0x000002, 20 0x0dbae6, 0x01246a, 0x0dbae6, 0x087261, 0xe306be, 0x000002, 21 0x0dbae6, 0x03437d, 0x0dbae6, 0x0bc16f, 0xe57c87, 0x000002, 22 0x0dbae6, 0x072981, 0x0dbae6, 0x111dd3, 0xe94f2a, 0x000002, 23 0x0dbae6, 0x0dc4a6, 0x0dbae6, 0x188611, 0xee85a0, 0x000002, 24 0x0dbae6, 0x168b9a, 0x0dbae6, 0x200e8f, 0xf3ccf1, 0x000002, 25 0x000000, 0x1b75cb, 0x1b75cb, 0x2374a2, 0x000000, 0x000001 26 }; 27 28 static const unsigned int src_iir_coeff_44_to_16[] = { 29 0x09ae28, 0xf7d97d, 0x09ae28, 0x212a3d, 0xe0ac3a, 0x000002, 30 0x09ae28, 0xf8525a, 0x09ae28, 0x216d72, 0xe234be, 0x000002, 31 0x09ae28, 0xf980f5, 0x09ae28, 0x22a057, 0xe45a81, 0x000002, 32 0x09ae28, 0xfc0a08, 0x09ae28, 0x24d3bd, 0xe7752d, 0x000002, 33 0x09ae28, 0x016162, 0x09ae28, 0x27da01, 0xeb6ea8, 0x000002, 34 0x09ae28, 0x0b67df, 0x09ae28, 0x2aca4a, 0xef34c4, 0x000002, 35 0x000000, 0x135c50, 0x135c50, 0x2c1079, 0x000000, 0x000001 36 }; 37 38 static const unsigned int src_iir_coeff_44_to_32[] = { 39 0x096966, 0x0c4d35, 0x096966, 0xedee81, 0xf05070, 0x000003, 40 0x12d2cc, 0x193910, 0x12d2cc, 0xddbf4f, 0xe21e1d, 0x000002, 41 0x12d2cc, 0x1a9e60, 0x12d2cc, 0xe18916, 0xe470fd, 0x000002, 42 0x12d2cc, 0x1d06e0, 0x12d2cc, 0xe8a4a6, 0xe87b24, 0x000002, 43 0x12d2cc, 0x207578, 0x12d2cc, 0xf4fe62, 0xef5917, 0x000002, 44 0x12d2cc, 0x24055f, 0x12d2cc, 0x05ee2b, 0xf8b502, 0x000002, 45 0x000000, 0x25a599, 0x25a599, 0x0fabe2, 0x000000, 0x000001 46 }; 47 48 static const unsigned int src_iir_coeff_48_to_16[] = { 49 0x0296a4, 0xfd69dd, 0x0296a4, 0x209439, 0xe01ff9, 0x000002, 50 0x0f4ff3, 0xf0d6d4, 0x0f4ff3, 0x209bc9, 0xe076c3, 0x000002, 51 0x0e8490, 0xf1fe63, 0x0e8490, 0x20cfd6, 0xe12124, 0x000002, 52 0x14852f, 0xed794a, 0x14852f, 0x21503d, 0xe28b32, 0x000002, 53 0x136222, 0xf17677, 0x136222, 0x225be1, 0xe56964, 0x000002, 54 0x0a8d85, 0xfc4a97, 0x0a8d85, 0x24310c, 0xea6952, 0x000002, 55 0x05eff5, 0x043455, 0x05eff5, 0x4ced8f, 0xe134d6, 0x000001, 56 0x000000, 0x3aebe6, 0x3aebe6, 0x04f3b0, 0x000000, 0x000004 57 }; 58 59 static const unsigned int src_iir_coeff_48_to_32[] = { 60 0x10c1b8, 0x10a7df, 0x10c1b8, 0xe7514e, 0xe0b41f, 0x000002, 61 0x10c1b8, 0x116257, 0x10c1b8, 0xe9402f, 0xe25aaa, 0x000002, 62 0x10c1b8, 0x130c89, 0x10c1b8, 0xed3cc3, 0xe4dddb, 0x000002, 63 0x10c1b8, 0x1600dd, 0x10c1b8, 0xf48000, 0xe90c55, 0x000002, 64 0x10c1b8, 0x1a672e, 0x10c1b8, 0x00494c, 0xefa807, 0x000002, 65 0x10c1b8, 0x1f38e6, 0x10c1b8, 0x0ee076, 0xf7c5f3, 0x000002, 66 0x000000, 0x218370, 0x218370, 0x168b40, 0x000000, 0x000001 67 }; 68 69 static const unsigned int src_iir_coeff_48_to_44[] = { 70 0x0bf71c, 0x170f3f, 0x0bf71c, 0xe3a4c8, 0xf096cb, 0x000003, 71 0x0bf71c, 0x17395e, 0x0bf71c, 0xe58085, 0xf210c8, 0x000003, 72 0x0bf71c, 0x1782bd, 0x0bf71c, 0xe95ef6, 0xf4c899, 0x000003, 73 0x0bf71c, 0x17cd97, 0x0bf71c, 0xf1608a, 0xfa3b18, 0x000003, 74 0x000000, 0x2fdc6f, 0x2fdc6f, 0xf15663, 0x000000, 0x000001 75 }; 76 77 static const unsigned int src_iir_coeff_96_to_16[] = { 78 0x0805a1, 0xf21ae3, 0x0805a1, 0x3840bb, 0xe02a2e, 0x000002, 79 0x0d5dd8, 0xe8f259, 0x0d5dd8, 0x1c0af6, 0xf04700, 0x000003, 80 0x0bb422, 0xec08d9, 0x0bb422, 0x1bfccc, 0xf09216, 0x000003, 81 0x08fde6, 0xf108be, 0x08fde6, 0x1bf096, 0xf10ae0, 0x000003, 82 0x0ae311, 0xeeeda3, 0x0ae311, 0x37c646, 0xe385f5, 0x000002, 83 0x044089, 0xfa7242, 0x044089, 0x37a785, 0xe56526, 0x000002, 84 0x00c75c, 0xffb947, 0x00c75c, 0x378ba3, 0xe72c5f, 0x000002, 85 0x000000, 0x0ef76e, 0x0ef76e, 0x377fda, 0x000000, 0x000001, 86 }; 87 88 static const unsigned int src_iir_coeff_96_to_44[] = { 89 0x08b543, 0xfd80f4, 0x08b543, 0x0e2332, 0xe06ed0, 0x000002, 90 0x1b6038, 0xf90e7e, 0x1b6038, 0x0ec1ac, 0xe16f66, 0x000002, 91 0x188478, 0xfbb921, 0x188478, 0x105859, 0xe2e596, 0x000002, 92 0x13eff3, 0xffa707, 0x13eff3, 0x13455c, 0xe533b7, 0x000002, 93 0x0dc239, 0x03d458, 0x0dc239, 0x17f120, 0xe8b617, 0x000002, 94 0x0745f1, 0x05d790, 0x0745f1, 0x1e3d75, 0xed5f18, 0x000002, 95 0x05641f, 0x085e2b, 0x05641f, 0x48efd0, 0xe3e9c8, 0x000001, 96 0x000000, 0x28f632, 0x28f632, 0x273905, 0x000000, 0x000001, 97 }; 98 99 static unsigned int mtk_get_src_freq_mode(struct mtk_base_afe *afe, int rate) 100 { 101 switch (rate) { 102 case 8000: 103 return 0x50000; 104 case 11025: 105 return 0x6e400; 106 case 12000: 107 return 0x78000; 108 case 16000: 109 return 0xa0000; 110 case 22050: 111 return 0xdc800; 112 case 24000: 113 return 0xf0000; 114 case 32000: 115 return 0x140000; 116 case 44100: 117 return 0x1b9000; 118 case 48000: 119 return 0x1e0000; 120 case 88200: 121 return 0x372000; 122 case 96000: 123 return 0x3c0000; 124 case 176400: 125 return 0x6e4000; 126 case 192000: 127 return 0x780000; 128 default: 129 dev_err(afe->dev, "%s(), rate %d invalid!!!\n", 130 __func__, rate); 131 return 0; 132 } 133 } 134 135 static const unsigned int *get_iir_coeff(unsigned int rate_in, 136 unsigned int rate_out, 137 unsigned int *param_num) 138 { 139 if (rate_in == 32000 && rate_out == 16000) { 140 *param_num = ARRAY_SIZE(src_iir_coeff_32_to_16); 141 return src_iir_coeff_32_to_16; 142 } else if (rate_in == 44100 && rate_out == 16000) { 143 *param_num = ARRAY_SIZE(src_iir_coeff_44_to_16); 144 return src_iir_coeff_44_to_16; 145 } else if (rate_in == 44100 && rate_out == 32000) { 146 *param_num = ARRAY_SIZE(src_iir_coeff_44_to_32); 147 return src_iir_coeff_44_to_32; 148 } else if ((rate_in == 48000 && rate_out == 16000) || 149 (rate_in == 96000 && rate_out == 32000)) { 150 *param_num = ARRAY_SIZE(src_iir_coeff_48_to_16); 151 return src_iir_coeff_48_to_16; 152 } else if (rate_in == 48000 && rate_out == 32000) { 153 *param_num = ARRAY_SIZE(src_iir_coeff_48_to_32); 154 return src_iir_coeff_48_to_32; 155 } else if (rate_in == 48000 && rate_out == 44100) { 156 *param_num = ARRAY_SIZE(src_iir_coeff_48_to_44); 157 return src_iir_coeff_48_to_44; 158 } else if (rate_in == 96000 && rate_out == 16000) { 159 *param_num = ARRAY_SIZE(src_iir_coeff_96_to_16); 160 return src_iir_coeff_96_to_16; 161 } else if ((rate_in == 96000 && rate_out == 44100) || 162 (rate_in == 48000 && rate_out == 22050)) { 163 *param_num = ARRAY_SIZE(src_iir_coeff_96_to_44); 164 return src_iir_coeff_96_to_44; 165 } 166 167 *param_num = 0; 168 return NULL; 169 } 170 171 static int mtk_set_src_1_param(struct mtk_base_afe *afe, int id) 172 { 173 struct mt8186_afe_private *afe_priv = afe->platform_priv; 174 struct mtk_afe_src_priv *src_priv = afe_priv->dai_priv[id]; 175 unsigned int iir_coeff_num; 176 unsigned int iir_stage; 177 int rate_in = src_priv->dl_rate; 178 int rate_out = src_priv->ul_rate; 179 unsigned int out_freq_mode = mtk_get_src_freq_mode(afe, rate_out); 180 unsigned int in_freq_mode = mtk_get_src_freq_mode(afe, rate_in); 181 182 /* set out freq mode */ 183 regmap_update_bits(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON3, 184 G_SRC_ASM_FREQ_4_MASK_SFT, 185 out_freq_mode << G_SRC_ASM_FREQ_4_SFT); 186 187 /* set in freq mode */ 188 regmap_update_bits(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON4, 189 G_SRC_ASM_FREQ_5_MASK_SFT, 190 in_freq_mode << G_SRC_ASM_FREQ_5_SFT); 191 192 regmap_write(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON5, 0x3f5986); 193 regmap_write(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON5, 0x3f5987); 194 regmap_write(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON6, 0x1fbd); 195 regmap_write(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON2, 0); 196 197 /* set iir if in_rate > out_rate */ 198 if (rate_in > rate_out) { 199 int i; 200 const unsigned int *iir_coeff = get_iir_coeff(rate_in, rate_out, 201 &iir_coeff_num); 202 203 if (iir_coeff_num == 0 || !iir_coeff) { 204 dev_err(afe->dev, "%s(), iir coeff error, num %d, coeff %p\n", 205 __func__, iir_coeff_num, iir_coeff); 206 return -EINVAL; 207 } 208 209 /* COEFF_SRAM_CTRL */ 210 regmap_update_bits(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON0, 211 G_SRC_COEFF_SRAM_CTRL_MASK_SFT, 212 BIT(G_SRC_COEFF_SRAM_CTRL_SFT)); 213 /* Clear coeff history to r/w coeff from the first position */ 214 regmap_update_bits(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON13, 215 G_SRC_COEFF_SRAM_ADR_MASK_SFT, 0); 216 /* Write SRC coeff, should not read the reg during write */ 217 for (i = 0; i < iir_coeff_num; i++) 218 regmap_write(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON12, 219 iir_coeff[i]); 220 /* disable sram access */ 221 regmap_update_bits(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON0, 222 G_SRC_COEFF_SRAM_CTRL_MASK_SFT, 0); 223 /* CHSET_IIR_STAGE */ 224 iir_stage = (iir_coeff_num / 6) - 1; 225 regmap_update_bits(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON2, 226 G_SRC_CHSET_IIR_STAGE_MASK_SFT, 227 iir_stage << G_SRC_CHSET_IIR_STAGE_SFT); 228 /* CHSET_IIR_EN */ 229 regmap_update_bits(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON2, 230 G_SRC_CHSET_IIR_EN_MASK_SFT, 231 BIT(G_SRC_CHSET_IIR_EN_SFT)); 232 } else { 233 /* CHSET_IIR_EN off */ 234 regmap_update_bits(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON2, 235 G_SRC_CHSET_IIR_EN_MASK_SFT, 0); 236 } 237 238 return 0; 239 } 240 241 static int mtk_set_src_2_param(struct mtk_base_afe *afe, int id) 242 { 243 struct mt8186_afe_private *afe_priv = afe->platform_priv; 244 struct mtk_afe_src_priv *src_priv = afe_priv->dai_priv[id]; 245 unsigned int iir_coeff_num; 246 unsigned int iir_stage; 247 int rate_in = src_priv->dl_rate; 248 int rate_out = src_priv->ul_rate; 249 unsigned int out_freq_mode = mtk_get_src_freq_mode(afe, rate_out); 250 unsigned int in_freq_mode = mtk_get_src_freq_mode(afe, rate_in); 251 252 /* set out freq mode */ 253 regmap_update_bits(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON3, 254 G_SRC_ASM_FREQ_4_MASK_SFT, 255 out_freq_mode << G_SRC_ASM_FREQ_4_SFT); 256 257 /* set in freq mode */ 258 regmap_update_bits(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON4, 259 G_SRC_ASM_FREQ_5_MASK_SFT, 260 in_freq_mode << G_SRC_ASM_FREQ_5_SFT); 261 262 regmap_write(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON5, 0x3f5986); 263 regmap_write(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON5, 0x3f5987); 264 regmap_write(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON6, 0x1fbd); 265 regmap_write(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON2, 0); 266 267 /* set iir if in_rate > out_rate */ 268 if (rate_in > rate_out) { 269 int i; 270 const unsigned int *iir_coeff = get_iir_coeff(rate_in, rate_out, 271 &iir_coeff_num); 272 273 if (iir_coeff_num == 0 || !iir_coeff) { 274 dev_err(afe->dev, "%s(), iir coeff error, num %d, coeff %p\n", 275 __func__, iir_coeff_num, iir_coeff); 276 return -EINVAL; 277 } 278 279 /* COEFF_SRAM_CTRL */ 280 regmap_update_bits(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON0, 281 G_SRC_COEFF_SRAM_CTRL_MASK_SFT, 282 BIT(G_SRC_COEFF_SRAM_CTRL_SFT)); 283 /* Clear coeff history to r/w coeff from the first position */ 284 regmap_update_bits(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON13, 285 G_SRC_COEFF_SRAM_ADR_MASK_SFT, 0); 286 /* Write SRC coeff, should not read the reg during write */ 287 for (i = 0; i < iir_coeff_num; i++) 288 regmap_write(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON12, 289 iir_coeff[i]); 290 /* disable sram access */ 291 regmap_update_bits(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON0, 292 G_SRC_COEFF_SRAM_CTRL_MASK_SFT, 0); 293 /* CHSET_IIR_STAGE */ 294 iir_stage = (iir_coeff_num / 6) - 1; 295 regmap_update_bits(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON2, 296 G_SRC_CHSET_IIR_STAGE_MASK_SFT, 297 iir_stage << G_SRC_CHSET_IIR_STAGE_SFT); 298 /* CHSET_IIR_EN */ 299 regmap_update_bits(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON2, 300 G_SRC_CHSET_IIR_EN_MASK_SFT, 301 BIT(G_SRC_CHSET_IIR_EN_SFT)); 302 } else { 303 /* CHSET_IIR_EN off */ 304 regmap_update_bits(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON2, 305 G_SRC_CHSET_IIR_EN_MASK_SFT, 0); 306 } 307 308 return 0; 309 } 310 311 #define HW_SRC_1_EN_W_NAME "HW_SRC_1_Enable" 312 #define HW_SRC_2_EN_W_NAME "HW_SRC_2_Enable" 313 314 static int mtk_hw_src_event(struct snd_soc_dapm_widget *w, 315 struct snd_kcontrol *kcontrol, 316 int event) 317 { 318 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); 319 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); 320 struct mt8186_afe_private *afe_priv = afe->platform_priv; 321 int id; 322 struct mtk_afe_src_priv *src_priv; 323 unsigned int reg; 324 325 if (snd_soc_dapm_widget_name_cmp(w, HW_SRC_1_EN_W_NAME) == 0) 326 id = MT8186_DAI_SRC_1; 327 else 328 id = MT8186_DAI_SRC_2; 329 330 src_priv = afe_priv->dai_priv[id]; 331 332 dev_dbg(afe->dev, 333 "%s(), name %s, event 0x%x, id %d, src_priv %p, dl_rate %d, ul_rate %d\n", 334 __func__, w->name, event, id, src_priv, 335 src_priv->dl_rate, src_priv->ul_rate); 336 337 switch (event) { 338 case SND_SOC_DAPM_PRE_PMU: 339 if (id == MT8186_DAI_SRC_1) 340 mtk_set_src_1_param(afe, id); 341 else 342 mtk_set_src_2_param(afe, id); 343 break; 344 case SND_SOC_DAPM_POST_PMU: 345 reg = (id == MT8186_DAI_SRC_1) ? 346 AFE_GENERAL1_ASRC_2CH_CON0 : AFE_GENERAL2_ASRC_2CH_CON0; 347 /* ASM_ON */ 348 regmap_update_bits(afe->regmap, reg, 349 G_SRC_ASM_ON_MASK_SFT, 350 BIT(G_SRC_ASM_ON_SFT)); 351 /* CHSET_ON */ 352 regmap_update_bits(afe->regmap, reg, 353 G_SRC_CHSET_ON_MASK_SFT, 354 BIT(G_SRC_CHSET_ON_SFT)); 355 /* CHSET_STR_CLR */ 356 regmap_update_bits(afe->regmap, reg, 357 G_SRC_CHSET_STR_CLR_MASK_SFT, 358 BIT(G_SRC_CHSET_STR_CLR_SFT)); 359 break; 360 case SND_SOC_DAPM_PRE_PMD: 361 reg = (id == MT8186_DAI_SRC_1) ? 362 AFE_GENERAL1_ASRC_2CH_CON0 : AFE_GENERAL2_ASRC_2CH_CON0; 363 /* ASM_OFF */ 364 regmap_update_bits(afe->regmap, reg, G_SRC_ASM_ON_MASK_SFT, 0); 365 /* CHSET_OFF */ 366 regmap_update_bits(afe->regmap, reg, G_SRC_CHSET_ON_MASK_SFT, 0); 367 /* CHSET_STR_CLR */ 368 regmap_update_bits(afe->regmap, reg, G_SRC_CHSET_STR_CLR_MASK_SFT, 0); 369 break; 370 default: 371 break; 372 } 373 374 return 0; 375 } 376 377 /* dai component */ 378 static const struct snd_kcontrol_new mtk_hw_src_1_in_ch1_mix[] = { 379 SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1 Switch", AFE_CONN40, 380 I_DL1_CH1, 1, 0), 381 SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1 Switch", AFE_CONN40, 382 I_DL2_CH1, 1, 0), 383 SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1 Switch", AFE_CONN40, 384 I_DL3_CH1, 1, 0), 385 SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH1 Switch", AFE_CONN40_1, 386 I_DL4_CH1, 1, 0), 387 SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH1 Switch", AFE_CONN40_1, 388 I_DL6_CH1, 1, 0), 389 SOC_DAPM_SINGLE_AUTODISABLE("I2S0_CH1 Switch", AFE_CONN40, 390 I_I2S0_CH1, 1, 0), 391 SOC_DAPM_SINGLE_AUTODISABLE("DL5_CH1 Switch", AFE_CONN40_1, 392 I_DL5_CH1, 1, 0), 393 }; 394 395 static const struct snd_kcontrol_new mtk_hw_src_1_in_ch2_mix[] = { 396 SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH2 Switch", AFE_CONN41, 397 I_DL1_CH2, 1, 0), 398 SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH2 Switch", AFE_CONN41, 399 I_DL2_CH2, 1, 0), 400 SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH2 Switch", AFE_CONN41, 401 I_DL3_CH2, 1, 0), 402 SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH2 Switch", AFE_CONN41_1, 403 I_DL4_CH2, 1, 0), 404 SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH2 Switch", AFE_CONN41_1, 405 I_DL6_CH2, 1, 0), 406 SOC_DAPM_SINGLE_AUTODISABLE("I2S0_CH2 Switch", AFE_CONN41, 407 I_I2S0_CH2, 1, 0), 408 SOC_DAPM_SINGLE_AUTODISABLE("DL5_CH2 Switch", AFE_CONN41_1, 409 I_DL5_CH2, 1, 0), 410 }; 411 412 static const struct snd_kcontrol_new mtk_hw_src_2_in_ch1_mix[] = { 413 SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1 Switch", AFE_CONN42, 414 I_DL1_CH1, 1, 0), 415 SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1 Switch", AFE_CONN42, 416 I_DL2_CH1, 1, 0), 417 SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1 Switch", AFE_CONN42, 418 I_DL3_CH1, 1, 0), 419 SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH1 Switch", AFE_CONN42, 420 I_DL4_CH1, 1, 0), 421 SOC_DAPM_SINGLE_AUTODISABLE("DL5_CH1 Switch", AFE_CONN42_1, 422 I_DL5_CH1, 1, 0), 423 SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH1 Switch", AFE_CONN42_1, 424 I_DL6_CH1, 1, 0), 425 SOC_DAPM_SINGLE_AUTODISABLE("HW_GAIN2_OUT_CH1 Switch", AFE_CONN42, 426 I_GAIN2_OUT_CH1, 1, 0), 427 }; 428 429 static const struct snd_kcontrol_new mtk_hw_src_2_in_ch2_mix[] = { 430 SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH2 Switch", AFE_CONN43, 431 I_DL1_CH2, 1, 0), 432 SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH2 Switch", AFE_CONN43, 433 I_DL2_CH2, 1, 0), 434 SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH2 Switch", AFE_CONN43, 435 I_DL3_CH2, 1, 0), 436 SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH2 Switch", AFE_CONN43, 437 I_DL4_CH2, 1, 0), 438 SOC_DAPM_SINGLE_AUTODISABLE("DL5_CH2 Switch", AFE_CONN43_1, 439 I_DL5_CH2, 1, 0), 440 SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH2 Switch", AFE_CONN43_1, 441 I_DL6_CH2, 1, 0), 442 SOC_DAPM_SINGLE_AUTODISABLE("HW_GAIN2_OUT_CH2 Switch", AFE_CONN43, 443 I_GAIN2_OUT_CH2, 1, 0), 444 }; 445 446 static const struct snd_soc_dapm_widget mtk_dai_src_widgets[] = { 447 /* inter-connections */ 448 SND_SOC_DAPM_MIXER("HW_SRC_1_IN_CH1", SND_SOC_NOPM, 0, 0, 449 mtk_hw_src_1_in_ch1_mix, 450 ARRAY_SIZE(mtk_hw_src_1_in_ch1_mix)), 451 SND_SOC_DAPM_MIXER("HW_SRC_1_IN_CH2", SND_SOC_NOPM, 0, 0, 452 mtk_hw_src_1_in_ch2_mix, 453 ARRAY_SIZE(mtk_hw_src_1_in_ch2_mix)), 454 SND_SOC_DAPM_MIXER("HW_SRC_2_IN_CH1", SND_SOC_NOPM, 0, 0, 455 mtk_hw_src_2_in_ch1_mix, 456 ARRAY_SIZE(mtk_hw_src_2_in_ch1_mix)), 457 SND_SOC_DAPM_MIXER("HW_SRC_2_IN_CH2", SND_SOC_NOPM, 0, 0, 458 mtk_hw_src_2_in_ch2_mix, 459 ARRAY_SIZE(mtk_hw_src_2_in_ch2_mix)), 460 461 SND_SOC_DAPM_SUPPLY(HW_SRC_1_EN_W_NAME, 462 GENERAL_ASRC_EN_ON, GENERAL1_ASRC_EN_ON_SFT, 0, 463 mtk_hw_src_event, 464 SND_SOC_DAPM_PRE_PMU | 465 SND_SOC_DAPM_POST_PMU | 466 SND_SOC_DAPM_PRE_PMD), 467 468 SND_SOC_DAPM_SUPPLY(HW_SRC_2_EN_W_NAME, 469 GENERAL_ASRC_EN_ON, GENERAL2_ASRC_EN_ON_SFT, 0, 470 mtk_hw_src_event, 471 SND_SOC_DAPM_PRE_PMU | 472 SND_SOC_DAPM_POST_PMU | 473 SND_SOC_DAPM_PRE_PMD), 474 475 SND_SOC_DAPM_INPUT("HW SRC 1 Out Endpoint"), 476 SND_SOC_DAPM_INPUT("HW SRC 2 Out Endpoint"), 477 SND_SOC_DAPM_OUTPUT("HW SRC 1 In Endpoint"), 478 SND_SOC_DAPM_OUTPUT("HW SRC 2 In Endpoint"), 479 }; 480 481 static int mtk_afe_src_en_connect(struct snd_soc_dapm_widget *source, 482 struct snd_soc_dapm_widget *sink) 483 { 484 struct snd_soc_dapm_widget *w = source; 485 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); 486 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); 487 struct mt8186_afe_private *afe_priv = afe->platform_priv; 488 struct mtk_afe_src_priv *src_priv; 489 490 if (snd_soc_dapm_widget_name_cmp(w, HW_SRC_1_EN_W_NAME) == 0) 491 src_priv = afe_priv->dai_priv[MT8186_DAI_SRC_1]; 492 else 493 src_priv = afe_priv->dai_priv[MT8186_DAI_SRC_2]; 494 495 dev_dbg(afe->dev, 496 "%s(), source %s, sink %s, dl_rate %d, ul_rate %d\n", 497 __func__, source->name, sink->name, 498 src_priv->dl_rate, src_priv->ul_rate); 499 500 return (src_priv->dl_rate > 0 && src_priv->ul_rate > 0) ? 1 : 0; 501 } 502 503 static const struct snd_soc_dapm_route mtk_dai_src_routes[] = { 504 {"HW_SRC_1_IN_CH1", "DL1_CH1 Switch", "DL1"}, 505 {"HW_SRC_1_IN_CH2", "DL1_CH2 Switch", "DL1"}, 506 {"HW_SRC_2_IN_CH1", "DL1_CH1 Switch", "DL1"}, 507 {"HW_SRC_2_IN_CH2", "DL1_CH2 Switch", "DL1"}, 508 {"HW_SRC_1_IN_CH1", "DL2_CH1 Switch", "DL2"}, 509 {"HW_SRC_1_IN_CH2", "DL2_CH2 Switch", "DL2"}, 510 {"HW_SRC_2_IN_CH1", "DL2_CH1 Switch", "DL2"}, 511 {"HW_SRC_2_IN_CH2", "DL2_CH2 Switch", "DL2"}, 512 {"HW_SRC_1_IN_CH1", "DL3_CH1 Switch", "DL3"}, 513 {"HW_SRC_1_IN_CH2", "DL3_CH2 Switch", "DL3"}, 514 {"HW_SRC_2_IN_CH1", "DL3_CH1 Switch", "DL3"}, 515 {"HW_SRC_2_IN_CH2", "DL3_CH2 Switch", "DL3"}, 516 {"HW_SRC_1_IN_CH1", "DL6_CH1 Switch", "DL6"}, 517 {"HW_SRC_1_IN_CH2", "DL6_CH2 Switch", "DL6"}, 518 {"HW_SRC_2_IN_CH1", "DL6_CH1 Switch", "DL6"}, 519 {"HW_SRC_2_IN_CH2", "DL6_CH2 Switch", "DL6"}, 520 {"HW_SRC_1_IN_CH1", "DL5_CH1 Switch", "DL5"}, 521 {"HW_SRC_1_IN_CH2", "DL5_CH2 Switch", "DL5"}, 522 {"HW_SRC_2_IN_CH1", "DL5_CH1 Switch", "DL5"}, 523 {"HW_SRC_2_IN_CH2", "DL5_CH2 Switch", "DL5"}, 524 {"HW_SRC_1_IN_CH1", "DL4_CH1 Switch", "DL4"}, 525 {"HW_SRC_1_IN_CH2", "DL4_CH2 Switch", "DL4"}, 526 {"HW_SRC_2_IN_CH1", "DL4_CH1 Switch", "DL4"}, 527 {"HW_SRC_2_IN_CH2", "DL4_CH2 Switch", "DL4"}, 528 529 {"HW_SRC_1_In", NULL, "HW_SRC_1_IN_CH1"}, 530 {"HW_SRC_1_In", NULL, "HW_SRC_1_IN_CH2"}, 531 532 {"HW_SRC_2_In", NULL, "HW_SRC_2_IN_CH1"}, 533 {"HW_SRC_2_In", NULL, "HW_SRC_2_IN_CH2"}, 534 535 {"HW_SRC_1_In", NULL, HW_SRC_1_EN_W_NAME, mtk_afe_src_en_connect}, 536 {"HW_SRC_1_Out", NULL, HW_SRC_1_EN_W_NAME, mtk_afe_src_en_connect}, 537 {"HW_SRC_2_In", NULL, HW_SRC_2_EN_W_NAME, mtk_afe_src_en_connect}, 538 {"HW_SRC_2_Out", NULL, HW_SRC_2_EN_W_NAME, mtk_afe_src_en_connect}, 539 540 {"HW SRC 1 In Endpoint", NULL, "HW_SRC_1_In"}, 541 {"HW SRC 2 In Endpoint", NULL, "HW_SRC_2_In"}, 542 {"HW_SRC_1_Out", NULL, "HW SRC 1 Out Endpoint"}, 543 {"HW_SRC_2_Out", NULL, "HW SRC 2 Out Endpoint"}, 544 }; 545 546 /* dai ops */ 547 static int mtk_dai_src_hw_params(struct snd_pcm_substream *substream, 548 struct snd_pcm_hw_params *params, 549 struct snd_soc_dai *dai) 550 { 551 struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); 552 struct mt8186_afe_private *afe_priv = afe->platform_priv; 553 int id = dai->id; 554 struct mtk_afe_src_priv *src_priv = afe_priv->dai_priv[id]; 555 unsigned int sft, mask; 556 unsigned int rate = params_rate(params); 557 unsigned int rate_reg = mt8186_rate_transform(afe->dev, rate, id); 558 559 dev_dbg(afe->dev, "%s(), id %d, stream %d, rate %d\n", 560 __func__, id, substream->stream, rate); 561 562 /* rate */ 563 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 564 src_priv->dl_rate = rate; 565 if (id == MT8186_DAI_SRC_1) { 566 sft = GENERAL1_ASRCIN_MODE_SFT; 567 mask = GENERAL1_ASRCIN_MODE_MASK; 568 } else { 569 sft = GENERAL2_ASRCIN_MODE_SFT; 570 mask = GENERAL2_ASRCIN_MODE_MASK; 571 } 572 } else { 573 src_priv->ul_rate = rate; 574 if (id == MT8186_DAI_SRC_1) { 575 sft = GENERAL1_ASRCOUT_MODE_SFT; 576 mask = GENERAL1_ASRCOUT_MODE_MASK; 577 } else { 578 sft = GENERAL2_ASRCOUT_MODE_SFT; 579 mask = GENERAL2_ASRCOUT_MODE_MASK; 580 } 581 } 582 583 regmap_update_bits(afe->regmap, GENERAL_ASRC_MODE, mask << sft, rate_reg << sft); 584 585 return 0; 586 } 587 588 static int mtk_dai_src_hw_free(struct snd_pcm_substream *substream, 589 struct snd_soc_dai *dai) 590 { 591 struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); 592 struct mt8186_afe_private *afe_priv = afe->platform_priv; 593 int id = dai->id; 594 struct mtk_afe_src_priv *src_priv = afe_priv->dai_priv[id]; 595 596 dev_dbg(afe->dev, "%s(), id %d, stream %d\n", 597 __func__, id, substream->stream); 598 599 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 600 src_priv->dl_rate = 0; 601 else 602 src_priv->ul_rate = 0; 603 604 return 0; 605 } 606 607 static const struct snd_soc_dai_ops mtk_dai_src_ops = { 608 .hw_params = mtk_dai_src_hw_params, 609 .hw_free = mtk_dai_src_hw_free, 610 }; 611 612 /* dai driver */ 613 #define MTK_SRC_RATES (SNDRV_PCM_RATE_8000_48000 |\ 614 SNDRV_PCM_RATE_88200 |\ 615 SNDRV_PCM_RATE_96000 |\ 616 SNDRV_PCM_RATE_176400 |\ 617 SNDRV_PCM_RATE_192000) 618 619 #define MTK_SRC_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ 620 SNDRV_PCM_FMTBIT_S24_LE |\ 621 SNDRV_PCM_FMTBIT_S32_LE) 622 623 static struct snd_soc_dai_driver mtk_dai_src_driver[] = { 624 { 625 .name = "HW_SRC_1", 626 .id = MT8186_DAI_SRC_1, 627 .playback = { 628 .stream_name = "HW_SRC_1_In", 629 .channels_min = 1, 630 .channels_max = 2, 631 .rates = MTK_SRC_RATES, 632 .formats = MTK_SRC_FORMATS, 633 }, 634 .capture = { 635 .stream_name = "HW_SRC_1_Out", 636 .channels_min = 1, 637 .channels_max = 2, 638 .rates = MTK_SRC_RATES, 639 .formats = MTK_SRC_FORMATS, 640 }, 641 .ops = &mtk_dai_src_ops, 642 }, 643 { 644 .name = "HW_SRC_2", 645 .id = MT8186_DAI_SRC_2, 646 .playback = { 647 .stream_name = "HW_SRC_2_In", 648 .channels_min = 1, 649 .channels_max = 2, 650 .rates = MTK_SRC_RATES, 651 .formats = MTK_SRC_FORMATS, 652 }, 653 .capture = { 654 .stream_name = "HW_SRC_2_Out", 655 .channels_min = 1, 656 .channels_max = 2, 657 .rates = MTK_SRC_RATES, 658 .formats = MTK_SRC_FORMATS, 659 }, 660 .ops = &mtk_dai_src_ops, 661 }, 662 }; 663 664 int mt8186_dai_src_register(struct mtk_base_afe *afe) 665 { 666 struct mtk_base_afe_dai *dai; 667 int ret; 668 669 dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL); 670 if (!dai) 671 return -ENOMEM; 672 673 list_add(&dai->list, &afe->sub_dais); 674 675 dai->dai_drivers = mtk_dai_src_driver; 676 dai->num_dai_drivers = ARRAY_SIZE(mtk_dai_src_driver); 677 678 dai->dapm_widgets = mtk_dai_src_widgets; 679 dai->num_dapm_widgets = ARRAY_SIZE(mtk_dai_src_widgets); 680 dai->dapm_routes = mtk_dai_src_routes; 681 dai->num_dapm_routes = ARRAY_SIZE(mtk_dai_src_routes); 682 683 /* set dai priv */ 684 ret = mt8186_dai_set_priv(afe, MT8186_DAI_SRC_1, 685 sizeof(struct mtk_afe_src_priv), NULL); 686 if (ret) 687 return ret; 688 689 ret = mt8186_dai_set_priv(afe, MT8186_DAI_SRC_2, 690 sizeof(struct mtk_afe_src_priv), NULL); 691 if (ret) 692 return ret; 693 694 return 0; 695 } 696
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.