1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * MediaTek 8365 ALSA SoC Audio DAI I2S Control 4 * 5 * Copyright (c) 2024 MediaTek Inc. 6 * Authors: Jia Zeng <jia.zeng@mediatek.com> 7 * Alexandre Mergnat <amergnat@baylibre.com> 8 */ 9 10 #include <linux/bitops.h> 11 #include <linux/regmap.h> 12 #include <sound/pcm_params.h> 13 #include "mt8365-afe-clk.h" 14 #include "mt8365-afe-common.h" 15 16 #define IIR_RATIOVER 9 17 #define IIR_INV_COEF 10 18 #define IIR_NO_NEED 11 19 20 struct mtk_afe_i2s_priv { 21 bool adda_link; 22 int i2s_out_on_ref_cnt; 23 int id; 24 int low_jitter_en; 25 int mclk_id; 26 int share_i2s_id; 27 unsigned int clk_id_in; 28 unsigned int clk_id_in_m_sel; 29 unsigned int clk_id_out; 30 unsigned int clk_id_out_m_sel; 31 unsigned int clk_in_mult; 32 unsigned int clk_out_mult; 33 unsigned int config_val_in; 34 unsigned int config_val_out; 35 unsigned int dynamic_bck; 36 unsigned int reg_off_in; 37 unsigned int reg_off_out; 38 }; 39 40 /* This enum is merely for mtk_afe_i2s_priv declare */ 41 enum { 42 DAI_I2S0 = 0, 43 DAI_I2S3, 44 DAI_I2S_NUM, 45 }; 46 47 static const struct mtk_afe_i2s_priv mt8365_i2s_priv[DAI_I2S_NUM] = { 48 [DAI_I2S0] = { 49 .id = MT8365_AFE_IO_I2S, 50 .mclk_id = MT8365_I2S0_MCK, 51 .share_i2s_id = -1, 52 .clk_id_in = MT8365_CLK_AUD_I2S2_M, 53 .clk_id_out = MT8365_CLK_AUD_I2S1_M, 54 .clk_id_in_m_sel = MT8365_CLK_I2S2_M_SEL, 55 .clk_id_out_m_sel = MT8365_CLK_I2S1_M_SEL, 56 .clk_in_mult = 256, 57 .clk_out_mult = 256, 58 .adda_link = true, 59 .config_val_out = AFE_I2S_CON1_I2S2_TO_PAD, 60 .reg_off_in = AFE_I2S_CON2, 61 .reg_off_out = AFE_I2S_CON1, 62 }, 63 [DAI_I2S3] = { 64 .id = MT8365_AFE_IO_2ND_I2S, 65 .mclk_id = MT8365_I2S3_MCK, 66 .share_i2s_id = -1, 67 .clk_id_in = MT8365_CLK_AUD_I2S0_M, 68 .clk_id_out = MT8365_CLK_AUD_I2S3_M, 69 .clk_id_in_m_sel = MT8365_CLK_I2S0_M_SEL, 70 .clk_id_out_m_sel = MT8365_CLK_I2S3_M_SEL, 71 .clk_in_mult = 256, 72 .clk_out_mult = 256, 73 .adda_link = false, 74 .config_val_in = AFE_I2S_CON_FROM_IO_MUX, 75 .reg_off_in = AFE_I2S_CON, 76 .reg_off_out = AFE_I2S_CON3, 77 }, 78 }; 79 80 static const u32 *get_iir_coef(unsigned int input_fs, 81 unsigned int output_fs, unsigned int *count) 82 { 83 static const u32 IIR_COEF_48_TO_44p1[30] = { 84 0x061fb0, 0x0bd256, 0x061fb0, 0xe3a3e6, 0xf0a300, 0x000003, 85 0x0e416d, 0x1bb577, 0x0e416d, 0xe59178, 0xf23637, 0x000003, 86 0x0c7d72, 0x189060, 0x0c7d72, 0xe96f09, 0xf505b2, 0x000003, 87 0x126054, 0x249143, 0x126054, 0xe1fc0c, 0xf4b20a, 0x000002, 88 0x000000, 0x323c85, 0x323c85, 0xf76d4e, 0x000000, 0x000002, 89 }; 90 91 static const u32 IIR_COEF_44p1_TO_32[42] = { 92 0x0a6074, 0x0d237a, 0x0a6074, 0xdd8d6c, 0xe0b3f6, 0x000002, 93 0x0e41f8, 0x128d48, 0x0e41f8, 0xefc14e, 0xf12d7a, 0x000003, 94 0x0cfa60, 0x11e89c, 0x0cfa60, 0xf1b09e, 0xf27205, 0x000003, 95 0x15b69c, 0x20e7e4, 0x15b69c, 0xea799a, 0xe9314a, 0x000002, 96 0x0f79e2, 0x1a7064, 0x0f79e2, 0xf65e4a, 0xf03d8e, 0x000002, 97 0x10c34f, 0x1ffe4b, 0x10c34f, 0x0bbecb, 0xf2bc4b, 0x000001, 98 0x000000, 0x23b063, 0x23b063, 0x07335f, 0x000000, 0x000002, 99 }; 100 101 static const u32 IIR_COEF_48_TO_32[42] = { 102 0x0a2a9b, 0x0a2f05, 0x0a2a9b, 0xe73873, 0xe0c525, 0x000002, 103 0x0dd4ad, 0x0e765a, 0x0dd4ad, 0xf49808, 0xf14844, 0x000003, 104 0x18a8cd, 0x1c40d0, 0x18a8cd, 0xed2aab, 0xe542ec, 0x000002, 105 0x13e044, 0x1a47c4, 0x13e044, 0xf44aed, 0xe9acc7, 0x000002, 106 0x1abd9c, 0x2a5429, 0x1abd9c, 0xff3441, 0xe0fc5f, 0x000001, 107 0x0d86db, 0x193e2e, 0x0d86db, 0x1a6f15, 0xf14507, 0x000001, 108 0x000000, 0x1f820c, 0x1f820c, 0x0a1b1f, 0x000000, 0x000002, 109 }; 110 111 static const u32 IIR_COEF_32_TO_16[48] = { 112 0x122893, 0xffadd4, 0x122893, 0x0bc205, 0xc0ee1c, 0x000001, 113 0x1bab8a, 0x00750d, 0x1bab8a, 0x06a983, 0xe18a5c, 0x000002, 114 0x18f68e, 0x02706f, 0x18f68e, 0x0886a9, 0xe31bcb, 0x000002, 115 0x149c05, 0x054487, 0x149c05, 0x0bec31, 0xe5973e, 0x000002, 116 0x0ea303, 0x07f24a, 0x0ea303, 0x115ff9, 0xe967b6, 0x000002, 117 0x0823fd, 0x085531, 0x0823fd, 0x18d5b4, 0xee8d21, 0x000002, 118 0x06888e, 0x0acbbb, 0x06888e, 0x40b55c, 0xe76dce, 0x000001, 119 0x000000, 0x2d31a9, 0x2d31a9, 0x23ba4f, 0x000000, 0x000001, 120 }; 121 122 static const u32 IIR_COEF_96_TO_44p1[48] = { 123 0x08b543, 0xfd80f4, 0x08b543, 0x0e2332, 0xe06ed0, 0x000002, 124 0x1b6038, 0xf90e7e, 0x1b6038, 0x0ec1ac, 0xe16f66, 0x000002, 125 0x188478, 0xfbb921, 0x188478, 0x105859, 0xe2e596, 0x000002, 126 0x13eff3, 0xffa707, 0x13eff3, 0x13455c, 0xe533b7, 0x000002, 127 0x0dc239, 0x03d458, 0x0dc239, 0x17f120, 0xe8b617, 0x000002, 128 0x0745f1, 0x05d790, 0x0745f1, 0x1e3d75, 0xed5f18, 0x000002, 129 0x05641f, 0x085e2b, 0x05641f, 0x48efd0, 0xe3e9c8, 0x000001, 130 0x000000, 0x28f632, 0x28f632, 0x273905, 0x000000, 0x000001, 131 }; 132 133 static const u32 IIR_COEF_44p1_TO_16[48] = { 134 0x0998fb, 0xf7f925, 0x0998fb, 0x1e54a0, 0xe06605, 0x000002, 135 0x0d828e, 0xf50f97, 0x0d828e, 0x0f41b5, 0xf0a999, 0x000003, 136 0x17ebeb, 0xee30d8, 0x17ebeb, 0x1f48ca, 0xe2ae88, 0x000002, 137 0x12fab5, 0xf46ddc, 0x12fab5, 0x20cc51, 0xe4d068, 0x000002, 138 0x0c7ac6, 0xfbd00e, 0x0c7ac6, 0x2337da, 0xe8028c, 0x000002, 139 0x060ddc, 0x015b3e, 0x060ddc, 0x266754, 0xec21b6, 0x000002, 140 0x0407b5, 0x04f827, 0x0407b5, 0x52e3d0, 0xe0149f, 0x000001, 141 0x000000, 0x1f9521, 0x1f9521, 0x2ac116, 0x000000, 0x000001, 142 }; 143 144 static const u32 IIR_COEF_48_TO_16[48] = { 145 0x0955ff, 0xf6544a, 0x0955ff, 0x2474e5, 0xe062e6, 0x000002, 146 0x0d4180, 0xf297f4, 0x0d4180, 0x12415b, 0xf0a3b0, 0x000003, 147 0x0ba079, 0xf4f0b0, 0x0ba079, 0x1285d3, 0xf1488b, 0x000003, 148 0x12247c, 0xf1033c, 0x12247c, 0x2625be, 0xe48e0d, 0x000002, 149 0x0b98e0, 0xf96d1a, 0x0b98e0, 0x27e79c, 0xe7798a, 0x000002, 150 0x055e3b, 0xffed09, 0x055e3b, 0x2a2e2d, 0xeb2854, 0x000002, 151 0x01a934, 0x01ca03, 0x01a934, 0x2c4fea, 0xee93ab, 0x000002, 152 0x000000, 0x1c46c5, 0x1c46c5, 0x2d37dc, 0x000000, 0x000001, 153 }; 154 155 static const u32 IIR_COEF_96_TO_16[48] = { 156 0x0805a1, 0xf21ae3, 0x0805a1, 0x3840bb, 0xe02a2e, 0x000002, 157 0x0d5dd8, 0xe8f259, 0x0d5dd8, 0x1c0af6, 0xf04700, 0x000003, 158 0x0bb422, 0xec08d9, 0x0bb422, 0x1bfccc, 0xf09216, 0x000003, 159 0x08fde6, 0xf108be, 0x08fde6, 0x1bf096, 0xf10ae0, 0x000003, 160 0x0ae311, 0xeeeda3, 0x0ae311, 0x37c646, 0xe385f5, 0x000002, 161 0x044089, 0xfa7242, 0x044089, 0x37a785, 0xe56526, 0x000002, 162 0x00c75c, 0xffb947, 0x00c75c, 0x378ba3, 0xe72c5f, 0x000002, 163 0x000000, 0x0ef76e, 0x0ef76e, 0x377fda, 0x000000, 0x000001, 164 }; 165 166 static const struct { 167 const u32 *coef; 168 unsigned int cnt; 169 } iir_coef_tbl_list[8] = { 170 /* 0: 0.9188 */ 171 { IIR_COEF_48_TO_44p1, ARRAY_SIZE(IIR_COEF_48_TO_44p1) }, 172 /* 1: 0.7256 */ 173 { IIR_COEF_44p1_TO_32, ARRAY_SIZE(IIR_COEF_44p1_TO_32) }, 174 /* 2: 0.6667 */ 175 { IIR_COEF_48_TO_32, ARRAY_SIZE(IIR_COEF_48_TO_32) }, 176 /* 3: 0.5 */ 177 { IIR_COEF_32_TO_16, ARRAY_SIZE(IIR_COEF_32_TO_16) }, 178 /* 4: 0.4594 */ 179 { IIR_COEF_96_TO_44p1, ARRAY_SIZE(IIR_COEF_96_TO_44p1) }, 180 /* 5: 0.3628 */ 181 { IIR_COEF_44p1_TO_16, ARRAY_SIZE(IIR_COEF_44p1_TO_16) }, 182 /* 6: 0.3333 */ 183 { IIR_COEF_48_TO_16, ARRAY_SIZE(IIR_COEF_48_TO_16) }, 184 /* 7: 0.1667 */ 185 { IIR_COEF_96_TO_16, ARRAY_SIZE(IIR_COEF_96_TO_16) }, 186 }; 187 188 static const u32 freq_new_index[16] = { 189 0, 1, 2, 99, 3, 4, 5, 99, 6, 7, 8, 9, 10, 11, 12, 99 190 }; 191 192 static const u32 iir_coef_tbl_matrix[13][13] = { 193 {/*0*/ 194 IIR_NO_NEED, IIR_NO_NEED, IIR_NO_NEED, IIR_NO_NEED, IIR_NO_NEED, 195 IIR_NO_NEED, IIR_NO_NEED, IIR_NO_NEED, IIR_NO_NEED, IIR_NO_NEED, 196 IIR_NO_NEED, IIR_NO_NEED, IIR_NO_NEED 197 }, 198 {/*1*/ 199 1, IIR_NO_NEED, IIR_NO_NEED, IIR_NO_NEED, IIR_NO_NEED, 200 IIR_NO_NEED, IIR_NO_NEED, IIR_NO_NEED, IIR_NO_NEED, 201 IIR_NO_NEED, IIR_NO_NEED, IIR_NO_NEED, IIR_NO_NEED 202 }, 203 {/*2*/ 204 2, 0, IIR_NO_NEED, IIR_NO_NEED, IIR_NO_NEED, IIR_NO_NEED, 205 IIR_NO_NEED, IIR_NO_NEED, IIR_NO_NEED, IIR_NO_NEED, 206 IIR_NO_NEED, IIR_NO_NEED, IIR_NO_NEED 207 }, 208 {/*3*/ 209 3, IIR_INV_COEF, IIR_INV_COEF, IIR_NO_NEED, IIR_NO_NEED, 210 IIR_NO_NEED, IIR_NO_NEED, IIR_NO_NEED, IIR_NO_NEED, 211 IIR_NO_NEED, IIR_NO_NEED, IIR_NO_NEED, IIR_NO_NEED 212 }, 213 {/*4*/ 214 5, 3, IIR_INV_COEF, 2, IIR_NO_NEED, IIR_NO_NEED, 215 IIR_NO_NEED, IIR_NO_NEED, IIR_NO_NEED, 216 IIR_NO_NEED, IIR_NO_NEED, IIR_NO_NEED, IIR_NO_NEED 217 }, 218 {/*5*/ 219 6, 4, 3, 2, 0, IIR_NO_NEED, IIR_NO_NEED, IIR_NO_NEED, 220 IIR_NO_NEED, IIR_NO_NEED, IIR_NO_NEED, 221 IIR_NO_NEED, IIR_NO_NEED 222 }, 223 {/*6*/ 224 IIR_INV_COEF, IIR_INV_COEF, IIR_INV_COEF, 3, IIR_INV_COEF, 225 IIR_INV_COEF, IIR_NO_NEED, IIR_NO_NEED, IIR_NO_NEED, 226 IIR_NO_NEED, IIR_NO_NEED, IIR_NO_NEED 227 }, 228 {/*7*/ 229 IIR_INV_COEF, IIR_INV_COEF, IIR_INV_COEF, 5, 3, 230 IIR_INV_COEF, 1, IIR_NO_NEED, IIR_NO_NEED, 231 IIR_NO_NEED, IIR_NO_NEED, IIR_NO_NEED, IIR_NO_NEED 232 }, 233 {/*8*/ 234 7, IIR_INV_COEF, IIR_INV_COEF, 6, 4, 3, 2, 0, IIR_NO_NEED, 235 IIR_NO_NEED, IIR_NO_NEED, IIR_NO_NEED, IIR_NO_NEED 236 }, 237 {/*9*/ 238 IIR_INV_COEF, IIR_INV_COEF, IIR_INV_COEF, IIR_INV_COEF, 239 IIR_INV_COEF, IIR_INV_COEF, 5, 3, IIR_INV_COEF, 240 IIR_NO_NEED, IIR_NO_NEED, IIR_NO_NEED, IIR_NO_NEED 241 }, 242 {/*10*/ 243 IIR_INV_COEF, IIR_INV_COEF, IIR_INV_COEF, 7, IIR_INV_COEF, 244 IIR_INV_COEF, 6, 4, 3, 0, 245 IIR_NO_NEED, IIR_NO_NEED, IIR_NO_NEED 246 }, 247 { /*11*/ 248 IIR_RATIOVER, IIR_INV_COEF, IIR_INV_COEF, IIR_INV_COEF, 249 IIR_INV_COEF, IIR_INV_COEF, IIR_INV_COEF, IIR_INV_COEF, 250 IIR_INV_COEF, 3, IIR_INV_COEF, IIR_NO_NEED, IIR_NO_NEED 251 }, 252 {/*12*/ 253 IIR_RATIOVER, IIR_RATIOVER, IIR_INV_COEF, IIR_INV_COEF, 254 IIR_INV_COEF, IIR_INV_COEF, 7, IIR_INV_COEF, 255 IIR_INV_COEF, 4, 3, 0, IIR_NO_NEED 256 }, 257 }; 258 259 const u32 *coef = NULL; 260 unsigned int cnt = 0; 261 u32 i = freq_new_index[input_fs]; 262 u32 j = freq_new_index[output_fs]; 263 264 if (i < 13 && j < 13) { 265 u32 k = iir_coef_tbl_matrix[i][j]; 266 267 if (k >= IIR_NO_NEED) { 268 } else if (k == IIR_RATIOVER) { 269 } else if (k == IIR_INV_COEF) { 270 } else { 271 coef = iir_coef_tbl_list[k].coef; 272 cnt = iir_coef_tbl_list[k].cnt; 273 } 274 } 275 *count = cnt; 276 return coef; 277 } 278 279 static int mt8365_dai_set_config(struct mtk_base_afe *afe, 280 struct mtk_afe_i2s_priv *i2s_data, 281 bool is_input, unsigned int rate, 282 int bit_width) 283 { 284 struct mt8365_afe_private *afe_priv = afe->platform_priv; 285 struct mt8365_be_dai_data *be = 286 &afe_priv->be_data[i2s_data->id - MT8365_AFE_BACKEND_BASE]; 287 unsigned int val, reg_off; 288 int fs = mt8365_afe_fs_timing(rate); 289 290 if (fs < 0) 291 return -EINVAL; 292 293 val = AFE_I2S_CON_LOW_JITTER_CLK | AFE_I2S_CON_FORMAT_I2S; 294 val |= FIELD_PREP(AFE_I2S_CON_RATE_MASK, fs); 295 296 if (is_input) { 297 reg_off = i2s_data->reg_off_in; 298 if (i2s_data->adda_link) 299 val |= i2s_data->config_val_in; 300 } else { 301 reg_off = i2s_data->reg_off_out; 302 val |= i2s_data->config_val_in; 303 } 304 305 /* 1:bck=32lrck(16bit) or bck=64lrck(32bit) 0:fix bck=64lrck */ 306 if (i2s_data->dynamic_bck) { 307 if (bit_width > 16) 308 val |= AFE_I2S_CON_WLEN_32BIT; 309 else 310 val &= ~(u32)AFE_I2S_CON_WLEN_32BIT; 311 } else { 312 val |= AFE_I2S_CON_WLEN_32BIT; 313 } 314 315 if ((be->fmt_mode & SND_SOC_DAIFMT_MASTER_MASK) == 316 SND_SOC_DAIFMT_CBP_CFP) { 317 val |= AFE_I2S_CON_SRC_SLAVE; 318 val &= ~(u32)AFE_I2S_CON_FROM_IO_MUX;//from consys 319 } 320 321 regmap_update_bits(afe->regmap, reg_off, ~(u32)AFE_I2S_CON_EN, val); 322 323 if (i2s_data->adda_link && is_input) 324 regmap_update_bits(afe->regmap, AFE_ADDA_TOP_CON0, 0x1, 0x1); 325 326 return 0; 327 } 328 329 int mt8365_afe_set_i2s_out(struct mtk_base_afe *afe, 330 unsigned int rate, int bit_width) 331 { 332 struct mt8365_afe_private *afe_priv = afe->platform_priv; 333 struct mtk_afe_i2s_priv *i2s_data = 334 afe_priv->dai_priv[MT8365_AFE_IO_I2S]; 335 336 return mt8365_dai_set_config(afe, i2s_data, false, rate, bit_width); 337 } 338 339 static int mt8365_afe_set_2nd_i2s_asrc(struct mtk_base_afe *afe, 340 unsigned int rate_in, 341 unsigned int rate_out, 342 unsigned int width, 343 unsigned int mono, 344 int o16bit, int tracking) 345 { 346 int ifs, ofs = 0; 347 unsigned int val = 0; 348 unsigned int mask = 0; 349 const u32 *coef; 350 u32 iir_stage; 351 unsigned int coef_count = 0; 352 353 ifs = mt8365_afe_fs_timing(rate_in); 354 355 if (ifs < 0) 356 return -EINVAL; 357 358 ofs = mt8365_afe_fs_timing(rate_out); 359 360 if (ofs < 0) 361 return -EINVAL; 362 363 val = FIELD_PREP(O16BIT, o16bit) | FIELD_PREP(IS_MONO, mono); 364 regmap_update_bits(afe->regmap, AFE_ASRC_2CH_CON2, 365 O16BIT | IS_MONO, val); 366 367 coef = get_iir_coef(ifs, ofs, &coef_count); 368 iir_stage = ((u32)coef_count / 6) - 1; 369 370 if (coef) { 371 unsigned int i; 372 373 /* CPU control IIR coeff SRAM */ 374 regmap_update_bits(afe->regmap, AFE_ASRC_2CH_CON0, 375 COEFF_SRAM_CTRL, COEFF_SRAM_CTRL); 376 377 /* set to 0, IIR coeff SRAM addr */ 378 regmap_update_bits(afe->regmap, AFE_ASRC_2CH_CON13, 379 0xffffffff, 0x0); 380 381 for (i = 0; i < coef_count; ++i) 382 regmap_update_bits(afe->regmap, AFE_ASRC_2CH_CON12, 383 0xffffffff, coef[i]); 384 385 /* disable IIR coeff SRAM access */ 386 regmap_update_bits(afe->regmap, AFE_ASRC_2CH_CON0, 387 COEFF_SRAM_CTRL, 388 ~COEFF_SRAM_CTRL); 389 regmap_update_bits(afe->regmap, AFE_ASRC_2CH_CON2, 390 CLR_IIR_HISTORY | IIR_EN | IIR_STAGE_MASK, 391 CLR_IIR_HISTORY | IIR_EN | 392 FIELD_PREP(IIR_STAGE_MASK, iir_stage)); 393 } else { 394 /* disable IIR */ 395 regmap_update_bits(afe->regmap, AFE_ASRC_2CH_CON2, 396 IIR_EN, ~IIR_EN); 397 } 398 399 /* CON3 setting (RX OFS) */ 400 regmap_update_bits(afe->regmap, AFE_ASRC_2CH_CON3, 401 0x00FFFFFF, rx_frequency_palette(ofs)); 402 /* CON4 setting (RX IFS) */ 403 regmap_update_bits(afe->regmap, AFE_ASRC_2CH_CON4, 404 0x00FFFFFF, rx_frequency_palette(ifs)); 405 406 /* CON5 setting */ 407 if (tracking) { 408 val = CALI_64_CYCLE | 409 CALI_AUTORST | 410 AUTO_TUNE_FREQ5 | 411 COMP_FREQ_RES | 412 CALI_BP_DGL | 413 CALI_AUTO_RESTART | 414 CALI_USE_FREQ_OUT | 415 CALI_SEL_01; 416 417 mask = CALI_CYCLE_MASK | 418 CALI_AUTORST | 419 AUTO_TUNE_FREQ5 | 420 COMP_FREQ_RES | 421 CALI_SEL_MASK | 422 CALI_BP_DGL | 423 AUTO_TUNE_FREQ4 | 424 CALI_AUTO_RESTART | 425 CALI_USE_FREQ_OUT | 426 CALI_ON; 427 428 regmap_update_bits(afe->regmap, AFE_ASRC_2CH_CON5, 429 mask, val); 430 regmap_update_bits(afe->regmap, AFE_ASRC_2CH_CON5, 431 CALI_ON, CALI_ON); 432 } else { 433 regmap_update_bits(afe->regmap, AFE_ASRC_2CH_CON5, 434 0xffffffff, 0x0); 435 } 436 /* CON6 setting fix 8125 */ 437 regmap_update_bits(afe->regmap, AFE_ASRC_2CH_CON6, 438 0x0000ffff, 0x1FBD); 439 /* CON9 setting (RX IFS) */ 440 regmap_update_bits(afe->regmap, AFE_ASRC_2CH_CON9, 441 0x000fffff, AutoRstThHi(ifs)); 442 /* CON10 setting (RX IFS) */ 443 regmap_update_bits(afe->regmap, AFE_ASRC_2CH_CON10, 444 0x000fffff, AutoRstThLo(ifs)); 445 regmap_update_bits(afe->regmap, AFE_ASRC_2CH_CON0, 446 CHSET_STR_CLR, CHSET_STR_CLR); 447 448 return 0; 449 } 450 451 static int mt8365_afe_set_2nd_i2s_asrc_enable(struct mtk_base_afe *afe, 452 bool enable) 453 { 454 if (enable) 455 regmap_update_bits(afe->regmap, AFE_ASRC_2CH_CON0, 456 ASM_ON, ASM_ON); 457 else 458 regmap_update_bits(afe->regmap, AFE_ASRC_2CH_CON0, 459 ASM_ON, ~ASM_ON); 460 return 0; 461 } 462 463 void mt8365_afe_set_i2s_out_enable(struct mtk_base_afe *afe, bool enable) 464 { 465 int i; 466 struct mt8365_afe_private *afe_priv = afe->platform_priv; 467 struct mtk_afe_i2s_priv *i2s_data = NULL; 468 469 for (i = 0; i < DAI_I2S_NUM; i++) { 470 if (mt8365_i2s_priv[i].adda_link) 471 i2s_data = afe_priv->dai_priv[mt8365_i2s_priv[i].id]; 472 } 473 474 if (!i2s_data) 475 return; 476 477 guard(spinlock_irqsave)(&afe_priv->afe_ctrl_lock); 478 479 if (enable) { 480 i2s_data->i2s_out_on_ref_cnt++; 481 if (i2s_data->i2s_out_on_ref_cnt == 1) 482 regmap_update_bits(afe->regmap, AFE_I2S_CON1, 483 0x1, enable); 484 } else { 485 i2s_data->i2s_out_on_ref_cnt--; 486 if (i2s_data->i2s_out_on_ref_cnt == 0) 487 regmap_update_bits(afe->regmap, AFE_I2S_CON1, 488 0x1, enable); 489 else if (i2s_data->i2s_out_on_ref_cnt < 0) 490 i2s_data->i2s_out_on_ref_cnt = 0; 491 } 492 } 493 494 static void mt8365_dai_set_enable(struct mtk_base_afe *afe, 495 struct mtk_afe_i2s_priv *i2s_data, 496 bool is_input, bool enable) 497 { 498 unsigned int reg_off; 499 500 if (is_input) { 501 reg_off = i2s_data->reg_off_in; 502 } else { 503 if (i2s_data->adda_link) { 504 mt8365_afe_set_i2s_out_enable(afe, enable); 505 return; 506 } 507 reg_off = i2s_data->reg_off_out; 508 } 509 regmap_update_bits(afe->regmap, reg_off, 510 0x1, enable); 511 } 512 513 static int mt8365_dai_i2s_startup(struct snd_pcm_substream *substream, 514 struct snd_soc_dai *dai) 515 { 516 struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); 517 struct mt8365_afe_private *afe_priv = afe->platform_priv; 518 struct mtk_afe_i2s_priv *i2s_data = afe_priv->dai_priv[dai->id]; 519 struct mt8365_be_dai_data *be = &afe_priv->be_data[dai->id - MT8365_AFE_BACKEND_BASE]; 520 bool i2s_in_slave = 521 (substream->stream == SNDRV_PCM_STREAM_CAPTURE) && 522 ((be->fmt_mode & SND_SOC_DAIFMT_MASTER_MASK) == 523 SND_SOC_DAIFMT_CBP_CFP); 524 525 mt8365_afe_enable_main_clk(afe); 526 527 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 528 clk_prepare_enable(afe_priv->clocks[i2s_data->clk_id_out]); 529 530 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE && !i2s_in_slave) 531 clk_prepare_enable(afe_priv->clocks[i2s_data->clk_id_in]); 532 533 if (i2s_in_slave) 534 mt8365_afe_enable_top_cg(afe, MT8365_TOP_CG_I2S_IN); 535 536 return 0; 537 } 538 539 static void mt8365_dai_i2s_shutdown(struct snd_pcm_substream *substream, 540 struct snd_soc_dai *dai) 541 { 542 struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); 543 struct mt8365_afe_private *afe_priv = afe->platform_priv; 544 struct mtk_afe_i2s_priv *i2s_data = afe_priv->dai_priv[dai->id]; 545 struct mt8365_be_dai_data *be = &afe_priv->be_data[dai->id - MT8365_AFE_BACKEND_BASE]; 546 bool reset_i2s_out_change = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK); 547 bool reset_i2s_in_change = (substream->stream == SNDRV_PCM_STREAM_CAPTURE); 548 bool i2s_in_slave = 549 (substream->stream == SNDRV_PCM_STREAM_CAPTURE) && 550 ((be->fmt_mode & SND_SOC_DAIFMT_MASTER_MASK) == 551 SND_SOC_DAIFMT_CBP_CFP); 552 553 if (be->prepared[substream->stream]) { 554 if (reset_i2s_out_change) 555 mt8365_dai_set_enable(afe, i2s_data, false, false); 556 557 if (reset_i2s_in_change) 558 mt8365_dai_set_enable(afe, i2s_data, true, false); 559 560 if (substream->runtime->rate % 8000) 561 mt8365_afe_disable_apll_associated_cfg(afe, MT8365_AFE_APLL1); 562 else 563 mt8365_afe_disable_apll_associated_cfg(afe, MT8365_AFE_APLL2); 564 565 if (reset_i2s_out_change) 566 be->prepared[SNDRV_PCM_STREAM_PLAYBACK] = false; 567 568 if (reset_i2s_in_change) 569 be->prepared[SNDRV_PCM_STREAM_CAPTURE] = false; 570 } 571 572 if (reset_i2s_out_change) 573 mt8365_afe_disable_clk(afe, 574 afe_priv->clocks[i2s_data->clk_id_out]); 575 576 if (reset_i2s_in_change && !i2s_in_slave) 577 mt8365_afe_disable_clk(afe, 578 afe_priv->clocks[i2s_data->clk_id_in]); 579 580 if (i2s_in_slave) 581 mt8365_afe_disable_top_cg(afe, MT8365_TOP_CG_I2S_IN); 582 583 mt8365_afe_disable_main_clk(afe); 584 } 585 586 static int mt8365_dai_i2s_prepare(struct snd_pcm_substream *substream, 587 struct snd_soc_dai *dai) 588 { 589 struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); 590 struct mt8365_afe_private *afe_priv = afe->platform_priv; 591 struct mtk_afe_i2s_priv *i2s_data = afe_priv->dai_priv[dai->id]; 592 struct mt8365_be_dai_data *be = &afe_priv->be_data[dai->id - MT8365_AFE_BACKEND_BASE]; 593 bool apply_i2s_out_change = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK); 594 bool apply_i2s_in_change = (substream->stream == SNDRV_PCM_STREAM_CAPTURE); 595 unsigned int rate = substream->runtime->rate; 596 int bit_width = snd_pcm_format_width(substream->runtime->format); 597 int ret; 598 599 if (be->prepared[substream->stream]) { 600 dev_info(afe->dev, "%s '%s' prepared already\n", 601 __func__, snd_pcm_stream_str(substream)); 602 return 0; 603 } 604 605 if (apply_i2s_out_change) { 606 ret = mt8365_dai_set_config(afe, i2s_data, false, rate, bit_width); 607 if (ret) 608 return ret; 609 } 610 611 if (apply_i2s_in_change) { 612 if ((be->fmt_mode & SND_SOC_DAIFMT_MASTER_MASK) 613 == SND_SOC_DAIFMT_CBP_CFP) { 614 ret = mt8365_afe_set_2nd_i2s_asrc(afe, 32000, rate, 615 (unsigned int)bit_width, 616 0, 0, 1); 617 if (ret < 0) 618 return ret; 619 } 620 ret = mt8365_dai_set_config(afe, i2s_data, true, rate, bit_width); 621 if (ret) 622 return ret; 623 } 624 625 if (rate % 8000) 626 mt8365_afe_enable_apll_associated_cfg(afe, MT8365_AFE_APLL1); 627 else 628 mt8365_afe_enable_apll_associated_cfg(afe, MT8365_AFE_APLL2); 629 630 if (apply_i2s_out_change) { 631 mt8365_afe_set_clk_parent(afe, 632 afe_priv->clocks[i2s_data->clk_id_out_m_sel], 633 ((rate % 8000) ? 634 afe_priv->clocks[MT8365_CLK_AUD1] : 635 afe_priv->clocks[MT8365_CLK_AUD2])); 636 637 mt8365_afe_set_clk_rate(afe, 638 afe_priv->clocks[i2s_data->clk_id_out], 639 rate * i2s_data->clk_out_mult); 640 641 mt8365_dai_set_enable(afe, i2s_data, false, true); 642 be->prepared[SNDRV_PCM_STREAM_PLAYBACK] = true; 643 } 644 645 if (apply_i2s_in_change) { 646 mt8365_afe_set_clk_parent(afe, 647 afe_priv->clocks[i2s_data->clk_id_in_m_sel], 648 ((rate % 8000) ? 649 afe_priv->clocks[MT8365_CLK_AUD1] : 650 afe_priv->clocks[MT8365_CLK_AUD2])); 651 652 mt8365_afe_set_clk_rate(afe, 653 afe_priv->clocks[i2s_data->clk_id_in], 654 rate * i2s_data->clk_in_mult); 655 656 mt8365_dai_set_enable(afe, i2s_data, true, true); 657 658 if ((be->fmt_mode & SND_SOC_DAIFMT_MASTER_MASK) 659 == SND_SOC_DAIFMT_CBP_CFP) 660 mt8365_afe_set_2nd_i2s_asrc_enable(afe, true); 661 662 be->prepared[SNDRV_PCM_STREAM_CAPTURE] = true; 663 } 664 return 0; 665 } 666 667 static int mt8365_afe_2nd_i2s_hw_params(struct snd_pcm_substream *substream, 668 struct snd_pcm_hw_params *params, 669 struct snd_soc_dai *dai) 670 { 671 struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); 672 unsigned int width_val = params_width(params) > 16 ? 673 (AFE_CONN_24BIT_O00 | AFE_CONN_24BIT_O01) : 0; 674 675 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 676 regmap_update_bits(afe->regmap, AFE_CONN_24BIT, 677 AFE_CONN_24BIT_O00 | AFE_CONN_24BIT_O01, width_val); 678 679 return 0; 680 } 681 682 static int mt8365_afe_2nd_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) 683 { 684 struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); 685 struct mt8365_afe_private *afe_priv = afe->platform_priv; 686 struct mt8365_be_dai_data *be = &afe_priv->be_data[dai->id - MT8365_AFE_BACKEND_BASE]; 687 688 be->fmt_mode = 0; 689 690 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 691 case SND_SOC_DAIFMT_I2S: 692 be->fmt_mode |= SND_SOC_DAIFMT_I2S; 693 break; 694 case SND_SOC_DAIFMT_LEFT_J: 695 be->fmt_mode |= SND_SOC_DAIFMT_LEFT_J; 696 break; 697 default: 698 dev_err(afe->dev, "invalid audio format for 2nd i2s!\n"); 699 return -EINVAL; 700 } 701 702 if (((fmt & SND_SOC_DAIFMT_INV_MASK) != SND_SOC_DAIFMT_NB_NF) && 703 ((fmt & SND_SOC_DAIFMT_INV_MASK) != SND_SOC_DAIFMT_NB_IF) && 704 ((fmt & SND_SOC_DAIFMT_INV_MASK) != SND_SOC_DAIFMT_IB_NF) && 705 ((fmt & SND_SOC_DAIFMT_INV_MASK) != SND_SOC_DAIFMT_IB_IF)) { 706 dev_err(afe->dev, "invalid audio format for 2nd i2s!\n"); 707 return -EINVAL; 708 } 709 710 be->fmt_mode |= (fmt & SND_SOC_DAIFMT_INV_MASK); 711 712 if (((fmt & SND_SOC_DAIFMT_MASTER_MASK) == SND_SOC_DAIFMT_CBP_CFP)) 713 be->fmt_mode |= (fmt & SND_SOC_DAIFMT_MASTER_MASK); 714 715 return 0; 716 } 717 718 static const struct snd_soc_dai_ops mt8365_afe_i2s_ops = { 719 .startup = mt8365_dai_i2s_startup, 720 .shutdown = mt8365_dai_i2s_shutdown, 721 .prepare = mt8365_dai_i2s_prepare, 722 }; 723 724 static const struct snd_soc_dai_ops mt8365_afe_2nd_i2s_ops = { 725 .startup = mt8365_dai_i2s_startup, 726 .shutdown = mt8365_dai_i2s_shutdown, 727 .hw_params = mt8365_afe_2nd_i2s_hw_params, 728 .prepare = mt8365_dai_i2s_prepare, 729 .set_fmt = mt8365_afe_2nd_i2s_set_fmt, 730 }; 731 732 static struct snd_soc_dai_driver mtk_dai_i2s_driver[] = { 733 { 734 .name = "I2S", 735 .id = MT8365_AFE_IO_I2S, 736 .playback = { 737 .stream_name = "I2S Playback", 738 .channels_min = 1, 739 .channels_max = 2, 740 .rates = SNDRV_PCM_RATE_8000_192000, 741 .formats = SNDRV_PCM_FMTBIT_S16_LE | 742 SNDRV_PCM_FMTBIT_S24_LE | 743 SNDRV_PCM_FMTBIT_S32_LE, 744 }, 745 .capture = { 746 .stream_name = "I2S Capture", 747 .channels_min = 1, 748 .channels_max = 2, 749 .rates = SNDRV_PCM_RATE_8000_192000, 750 .formats = SNDRV_PCM_FMTBIT_S16_LE | 751 SNDRV_PCM_FMTBIT_S24_LE | 752 SNDRV_PCM_FMTBIT_S32_LE, 753 }, 754 .ops = &mt8365_afe_i2s_ops, 755 }, { 756 .name = "2ND I2S", 757 .id = MT8365_AFE_IO_2ND_I2S, 758 .playback = { 759 .stream_name = "2ND I2S Playback", 760 .channels_min = 1, 761 .channels_max = 2, 762 .rates = SNDRV_PCM_RATE_8000_192000, 763 .formats = SNDRV_PCM_FMTBIT_S16_LE | 764 SNDRV_PCM_FMTBIT_S24_LE | 765 SNDRV_PCM_FMTBIT_S32_LE, 766 }, 767 .capture = { 768 .stream_name = "2ND I2S Capture", 769 .channels_min = 1, 770 .channels_max = 2, 771 .rates = SNDRV_PCM_RATE_8000_192000, 772 .formats = SNDRV_PCM_FMTBIT_S16_LE | 773 SNDRV_PCM_FMTBIT_S24_LE | 774 SNDRV_PCM_FMTBIT_S32_LE, 775 }, 776 .ops = &mt8365_afe_2nd_i2s_ops, 777 } 778 }; 779 780 static const char * const fmi2sin_text[] = { 781 "OPEN", "FM_2ND_I2S_IN" 782 }; 783 784 static SOC_ENUM_SINGLE_VIRT_DECL(fmi2sin_enum, fmi2sin_text); 785 786 static const struct snd_kcontrol_new fmi2sin_mux = 787 SOC_DAPM_ENUM("FM 2ND I2S Source", fmi2sin_enum); 788 789 static const struct snd_kcontrol_new i2s_o03_o04_enable_ctl = 790 SOC_DAPM_SINGLE_VIRT("Switch", 1); 791 792 static const struct snd_soc_dapm_widget mtk_dai_i2s_widgets[] = { 793 SND_SOC_DAPM_SWITCH("I2S O03_O04", SND_SOC_NOPM, 0, 0, 794 &i2s_o03_o04_enable_ctl), 795 SND_SOC_DAPM_MUX("FM 2ND I2S Mux", SND_SOC_NOPM, 0, 0, &fmi2sin_mux), 796 SND_SOC_DAPM_INPUT("2ND I2S In"), 797 }; 798 799 static const struct snd_soc_dapm_route mtk_dai_i2s_routes[] = { 800 {"I2S O03_O04", "Switch", "O03"}, 801 {"I2S O03_O04", "Switch", "O04"}, 802 {"I2S Playback", NULL, "I2S O03_O04"}, 803 {"2ND I2S Playback", NULL, "O00"}, 804 {"2ND I2S Playback", NULL, "O01"}, 805 {"2ND I2S Capture", NULL, "2ND I2S In"}, 806 {"FM 2ND I2S Mux", "FM_2ND_I2S_IN", "2ND I2S Capture"}, 807 }; 808 809 static int mt8365_dai_i2s_set_priv(struct mtk_base_afe *afe) 810 { 811 int i, ret; 812 813 for (i = 0; i < DAI_I2S_NUM; i++) { 814 ret = mt8365_dai_set_priv(afe, mt8365_i2s_priv[i].id, 815 sizeof(mt8365_i2s_priv[i]), 816 &mt8365_i2s_priv[i]); 817 if (ret) 818 return ret; 819 } 820 return 0; 821 } 822 823 int mt8365_dai_i2s_register(struct mtk_base_afe *afe) 824 { 825 struct mtk_base_afe_dai *dai; 826 827 dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL); 828 if (!dai) 829 return -ENOMEM; 830 831 list_add(&dai->list, &afe->sub_dais); 832 833 dai->dai_drivers = mtk_dai_i2s_driver; 834 dai->num_dai_drivers = ARRAY_SIZE(mtk_dai_i2s_driver); 835 dai->dapm_widgets = mtk_dai_i2s_widgets; 836 dai->num_dapm_widgets = ARRAY_SIZE(mtk_dai_i2s_widgets); 837 dai->dapm_routes = mtk_dai_i2s_routes; 838 dai->num_dapm_routes = ARRAY_SIZE(mtk_dai_i2s_routes); 839 840 /* set all dai i2s private data */ 841 return mt8365_dai_i2s_set_priv(afe); 842 } 843