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 {/**/ 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_CBM_CFM) { 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 unsigned long flags; 467 struct mt8365_afe_private *afe_priv = afe->platform_priv; 468 struct mtk_afe_i2s_priv *i2s_data = NULL; 469 470 for (i = 0; i < DAI_I2S_NUM; i++) { 471 if (mt8365_i2s_priv[i].adda_link) 472 i2s_data = afe_priv->dai_priv[mt8365_i2s_priv[i].id]; 473 } 474 475 if (!i2s_data) 476 return; 477 478 spin_lock_irqsave(&afe_priv->afe_ctrl_lock, flags); 479 480 if (enable) { 481 i2s_data->i2s_out_on_ref_cnt++; 482 if (i2s_data->i2s_out_on_ref_cnt == 1) 483 regmap_update_bits(afe->regmap, AFE_I2S_CON1, 484 0x1, enable); 485 } else { 486 i2s_data->i2s_out_on_ref_cnt--; 487 if (i2s_data->i2s_out_on_ref_cnt == 0) 488 regmap_update_bits(afe->regmap, AFE_I2S_CON1, 489 0x1, enable); 490 else if (i2s_data->i2s_out_on_ref_cnt < 0) 491 i2s_data->i2s_out_on_ref_cnt = 0; 492 } 493 494 spin_unlock_irqrestore(&afe_priv->afe_ctrl_lock, flags); 495 } 496 497 static void mt8365_dai_set_enable(struct mtk_base_afe *afe, 498 struct mtk_afe_i2s_priv *i2s_data, 499 bool is_input, bool enable) 500 { 501 unsigned int reg_off; 502 503 if (is_input) { 504 reg_off = i2s_data->reg_off_in; 505 } else { 506 if (i2s_data->adda_link) { 507 mt8365_afe_set_i2s_out_enable(afe, enable); 508 return; 509 } 510 reg_off = i2s_data->reg_off_out; 511 } 512 regmap_update_bits(afe->regmap, reg_off, 513 0x1, enable); 514 } 515 516 static int mt8365_dai_i2s_startup(struct snd_pcm_substream *substream, 517 struct snd_soc_dai *dai) 518 { 519 struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); 520 struct mt8365_afe_private *afe_priv = afe->platform_priv; 521 struct mtk_afe_i2s_priv *i2s_data = afe_priv->dai_priv[dai->id]; 522 struct mt8365_be_dai_data *be = &afe_priv->be_data[dai->id - MT8365_AFE_BACKEND_BASE]; 523 bool i2s_in_slave = 524 (substream->stream == SNDRV_PCM_STREAM_CAPTURE) && 525 ((be->fmt_mode & SND_SOC_DAIFMT_MASTER_MASK) == 526 SND_SOC_DAIFMT_CBM_CFM); 527 528 mt8365_afe_enable_main_clk(afe); 529 530 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 531 clk_prepare_enable(afe_priv->clocks[i2s_data->clk_id_out]); 532 533 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE && !i2s_in_slave) 534 clk_prepare_enable(afe_priv->clocks[i2s_data->clk_id_in]); 535 536 if (i2s_in_slave) 537 mt8365_afe_enable_top_cg(afe, MT8365_TOP_CG_I2S_IN); 538 539 return 0; 540 } 541 542 static void mt8365_dai_i2s_shutdown(struct snd_pcm_substream *substream, 543 struct snd_soc_dai *dai) 544 { 545 struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); 546 struct mt8365_afe_private *afe_priv = afe->platform_priv; 547 struct mtk_afe_i2s_priv *i2s_data = afe_priv->dai_priv[dai->id]; 548 struct mt8365_be_dai_data *be = &afe_priv->be_data[dai->id - MT8365_AFE_BACKEND_BASE]; 549 bool reset_i2s_out_change = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK); 550 bool reset_i2s_in_change = (substream->stream == SNDRV_PCM_STREAM_CAPTURE); 551 bool i2s_in_slave = 552 (substream->stream == SNDRV_PCM_STREAM_CAPTURE) && 553 ((be->fmt_mode & SND_SOC_DAIFMT_MASTER_MASK) == 554 SND_SOC_DAIFMT_CBM_CFM); 555 556 if (be->prepared[substream->stream]) { 557 if (reset_i2s_out_change) 558 mt8365_dai_set_enable(afe, i2s_data, false, false); 559 560 if (reset_i2s_in_change) 561 mt8365_dai_set_enable(afe, i2s_data, true, false); 562 563 if (substream->runtime->rate % 8000) 564 mt8365_afe_disable_apll_associated_cfg(afe, MT8365_AFE_APLL1); 565 else 566 mt8365_afe_disable_apll_associated_cfg(afe, MT8365_AFE_APLL2); 567 568 if (reset_i2s_out_change) 569 be->prepared[SNDRV_PCM_STREAM_PLAYBACK] = false; 570 571 if (reset_i2s_in_change) 572 be->prepared[SNDRV_PCM_STREAM_CAPTURE] = false; 573 } 574 575 if (reset_i2s_out_change) 576 mt8365_afe_disable_clk(afe, 577 afe_priv->clocks[i2s_data->clk_id_out]); 578 579 if (reset_i2s_in_change && !i2s_in_slave) 580 mt8365_afe_disable_clk(afe, 581 afe_priv->clocks[i2s_data->clk_id_in]); 582 583 if (i2s_in_slave) 584 mt8365_afe_disable_top_cg(afe, MT8365_TOP_CG_I2S_IN); 585 586 mt8365_afe_disable_main_clk(afe); 587 } 588 589 static int mt8365_dai_i2s_prepare(struct snd_pcm_substream *substream, 590 struct snd_soc_dai *dai) 591 { 592 struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); 593 struct mt8365_afe_private *afe_priv = afe->platform_priv; 594 struct mtk_afe_i2s_priv *i2s_data = afe_priv->dai_priv[dai->id]; 595 struct mt8365_be_dai_data *be = &afe_priv->be_data[dai->id - MT8365_AFE_BACKEND_BASE]; 596 bool apply_i2s_out_change = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK); 597 bool apply_i2s_in_change = (substream->stream == SNDRV_PCM_STREAM_CAPTURE); 598 unsigned int rate = substream->runtime->rate; 599 int bit_width = snd_pcm_format_width(substream->runtime->format); 600 int ret; 601 602 if (be->prepared[substream->stream]) { 603 dev_info(afe->dev, "%s '%s' prepared already\n", 604 __func__, snd_pcm_stream_str(substream)); 605 return 0; 606 } 607 608 if (apply_i2s_out_change) { 609 ret = mt8365_dai_set_config(afe, i2s_data, false, rate, bit_width); 610 if (ret) 611 return ret; 612 } 613 614 if (apply_i2s_in_change) { 615 if ((be->fmt_mode & SND_SOC_DAIFMT_MASTER_MASK) 616 == SND_SOC_DAIFMT_CBM_CFM) { 617 ret = mt8365_afe_set_2nd_i2s_asrc(afe, 32000, rate, 618 (unsigned int)bit_width, 619 0, 0, 1); 620 if (ret < 0) 621 return ret; 622 } 623 ret = mt8365_dai_set_config(afe, i2s_data, true, rate, bit_width); 624 if (ret) 625 return ret; 626 } 627 628 if (rate % 8000) 629 mt8365_afe_enable_apll_associated_cfg(afe, MT8365_AFE_APLL1); 630 else 631 mt8365_afe_enable_apll_associated_cfg(afe, MT8365_AFE_APLL2); 632 633 if (apply_i2s_out_change) { 634 mt8365_afe_set_clk_parent(afe, 635 afe_priv->clocks[i2s_data->clk_id_out_m_sel], 636 ((rate % 8000) ? 637 afe_priv->clocks[MT8365_CLK_AUD1] : 638 afe_priv->clocks[MT8365_CLK_AUD2])); 639 640 mt8365_afe_set_clk_rate(afe, 641 afe_priv->clocks[i2s_data->clk_id_out], 642 rate * i2s_data->clk_out_mult); 643 644 mt8365_dai_set_enable(afe, i2s_data, false, true); 645 be->prepared[SNDRV_PCM_STREAM_PLAYBACK] = true; 646 } 647 648 if (apply_i2s_in_change) { 649 mt8365_afe_set_clk_parent(afe, 650 afe_priv->clocks[i2s_data->clk_id_in_m_sel], 651 ((rate % 8000) ? 652 afe_priv->clocks[MT8365_CLK_AUD1] : 653 afe_priv->clocks[MT8365_CLK_AUD2])); 654 655 mt8365_afe_set_clk_rate(afe, 656 afe_priv->clocks[i2s_data->clk_id_in], 657 rate * i2s_data->clk_in_mult); 658 659 mt8365_dai_set_enable(afe, i2s_data, true, true); 660 661 if ((be->fmt_mode & SND_SOC_DAIFMT_MASTER_MASK) 662 == SND_SOC_DAIFMT_CBM_CFM) 663 mt8365_afe_set_2nd_i2s_asrc_enable(afe, true); 664 665 be->prepared[SNDRV_PCM_STREAM_CAPTURE] = true; 666 } 667 return 0; 668 } 669 670 static int mt8365_afe_2nd_i2s_hw_params(struct snd_pcm_substream *substream, 671 struct snd_pcm_hw_params *params, 672 struct snd_soc_dai *dai) 673 { 674 struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); 675 unsigned int width_val = params_width(params) > 16 ? 676 (AFE_CONN_24BIT_O00 | AFE_CONN_24BIT_O01) : 0; 677 678 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 679 regmap_update_bits(afe->regmap, AFE_CONN_24BIT, 680 AFE_CONN_24BIT_O00 | AFE_CONN_24BIT_O01, width_val); 681 682 return 0; 683 } 684 685 static int mt8365_afe_2nd_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) 686 { 687 struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); 688 struct mt8365_afe_private *afe_priv = afe->platform_priv; 689 struct mt8365_be_dai_data *be = &afe_priv->be_data[dai->id - MT8365_AFE_BACKEND_BASE]; 690 691 be->fmt_mode = 0; 692 693 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 694 case SND_SOC_DAIFMT_I2S: 695 be->fmt_mode |= SND_SOC_DAIFMT_I2S; 696 break; 697 case SND_SOC_DAIFMT_LEFT_J: 698 be->fmt_mode |= SND_SOC_DAIFMT_LEFT_J; 699 break; 700 default: 701 dev_err(afe->dev, "invalid audio format for 2nd i2s!\n"); 702 return -EINVAL; 703 } 704 705 if (((fmt & SND_SOC_DAIFMT_INV_MASK) != SND_SOC_DAIFMT_NB_NF) && 706 ((fmt & SND_SOC_DAIFMT_INV_MASK) != SND_SOC_DAIFMT_NB_IF) && 707 ((fmt & SND_SOC_DAIFMT_INV_MASK) != SND_SOC_DAIFMT_IB_NF) && 708 ((fmt & SND_SOC_DAIFMT_INV_MASK) != SND_SOC_DAIFMT_IB_IF)) { 709 dev_err(afe->dev, "invalid audio format for 2nd i2s!\n"); 710 return -EINVAL; 711 } 712 713 be->fmt_mode |= (fmt & SND_SOC_DAIFMT_INV_MASK); 714 715 if (((fmt & SND_SOC_DAIFMT_MASTER_MASK) == SND_SOC_DAIFMT_CBM_CFM)) 716 be->fmt_mode |= (fmt & SND_SOC_DAIFMT_MASTER_MASK); 717 718 return 0; 719 } 720 721 static const struct snd_soc_dai_ops mt8365_afe_i2s_ops = { 722 .startup = mt8365_dai_i2s_startup, 723 .shutdown = mt8365_dai_i2s_shutdown, 724 .prepare = mt8365_dai_i2s_prepare, 725 }; 726 727 static const struct snd_soc_dai_ops mt8365_afe_2nd_i2s_ops = { 728 .startup = mt8365_dai_i2s_startup, 729 .shutdown = mt8365_dai_i2s_shutdown, 730 .hw_params = mt8365_afe_2nd_i2s_hw_params, 731 .prepare = mt8365_dai_i2s_prepare, 732 .set_fmt = mt8365_afe_2nd_i2s_set_fmt, 733 }; 734 735 static struct snd_soc_dai_driver mtk_dai_i2s_driver[] = { 736 { 737 .name = "I2S", 738 .id = MT8365_AFE_IO_I2S, 739 .playback = { 740 .stream_name = "I2S Playback", 741 .channels_min = 1, 742 .channels_max = 2, 743 .rates = SNDRV_PCM_RATE_8000_192000, 744 .formats = SNDRV_PCM_FMTBIT_S16_LE | 745 SNDRV_PCM_FMTBIT_S24_LE | 746 SNDRV_PCM_FMTBIT_S32_LE, 747 }, 748 .capture = { 749 .stream_name = "I2S Capture", 750 .channels_min = 1, 751 .channels_max = 2, 752 .rates = SNDRV_PCM_RATE_8000_192000, 753 .formats = SNDRV_PCM_FMTBIT_S16_LE | 754 SNDRV_PCM_FMTBIT_S24_LE | 755 SNDRV_PCM_FMTBIT_S32_LE, 756 }, 757 .ops = &mt8365_afe_i2s_ops, 758 }, { 759 .name = "2ND I2S", 760 .id = MT8365_AFE_IO_2ND_I2S, 761 .playback = { 762 .stream_name = "2ND I2S Playback", 763 .channels_min = 1, 764 .channels_max = 2, 765 .rates = SNDRV_PCM_RATE_8000_192000, 766 .formats = SNDRV_PCM_FMTBIT_S16_LE | 767 SNDRV_PCM_FMTBIT_S24_LE | 768 SNDRV_PCM_FMTBIT_S32_LE, 769 }, 770 .capture = { 771 .stream_name = "2ND I2S Capture", 772 .channels_min = 1, 773 .channels_max = 2, 774 .rates = SNDRV_PCM_RATE_8000_192000, 775 .formats = SNDRV_PCM_FMTBIT_S16_LE | 776 SNDRV_PCM_FMTBIT_S24_LE | 777 SNDRV_PCM_FMTBIT_S32_LE, 778 }, 779 .ops = &mt8365_afe_2nd_i2s_ops, 780 } 781 }; 782 783 static const char * const fmi2sin_text[] = { 784 "OPEN", "FM_2ND_I2S_IN" 785 }; 786 787 static SOC_ENUM_SINGLE_VIRT_DECL(fmi2sin_enum, fmi2sin_text); 788 789 static const struct snd_kcontrol_new fmi2sin_mux = 790 SOC_DAPM_ENUM("FM 2ND I2S Source", fmi2sin_enum); 791 792 static const struct snd_kcontrol_new i2s_o03_o04_enable_ctl = 793 SOC_DAPM_SINGLE_VIRT("Switch", 1); 794 795 static const struct snd_soc_dapm_widget mtk_dai_i2s_widgets[] = { 796 SND_SOC_DAPM_SWITCH("I2S O03_O04", SND_SOC_NOPM, 0, 0, 797 &i2s_o03_o04_enable_ctl), 798 SND_SOC_DAPM_MUX("FM 2ND I2S Mux", SND_SOC_NOPM, 0, 0, &fmi2sin_mux), 799 SND_SOC_DAPM_INPUT("2ND I2S In"), 800 }; 801 802 static const struct snd_soc_dapm_route mtk_dai_i2s_routes[] = { 803 {"I2S O03_O04", "Switch", "O03"}, 804 {"I2S O03_O04", "Switch", "O04"}, 805 {"I2S Playback", NULL, "I2S O03_O04"}, 806 {"2ND I2S Playback", NULL, "O00"}, 807 {"2ND I2S Playback", NULL, "O01"}, 808 {"2ND I2S Capture", NULL, "2ND I2S In"}, 809 {"FM 2ND I2S Mux", "FM_2ND_I2S_IN", "2ND I2S Capture"}, 810 }; 811 812 static int mt8365_dai_i2s_set_priv(struct mtk_base_afe *afe) 813 { 814 int i, ret; 815 struct mt8365_afe_private *afe_priv = afe->platform_priv; 816 817 for (i = 0; i < DAI_I2S_NUM; i++) { 818 ret = mt8365_dai_set_priv(afe, mt8365_i2s_priv[i].id, 819 sizeof(*afe_priv), 820 &mt8365_i2s_priv[i]); 821 if (ret) 822 return ret; 823 } 824 return 0; 825 } 826 827 int mt8365_dai_i2s_register(struct mtk_base_afe *afe) 828 { 829 struct mtk_base_afe_dai *dai; 830 831 dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL); 832 if (!dai) 833 return -ENOMEM; 834 835 list_add(&dai->list, &afe->sub_dais); 836 837 dai->dai_drivers = mtk_dai_i2s_driver; 838 dai->num_dai_drivers = ARRAY_SIZE(mtk_dai_i2s_driver); 839 dai->dapm_widgets = mtk_dai_i2s_widgets; 840 dai->num_dapm_widgets = ARRAY_SIZE(mtk_dai_i2s_widgets); 841 dai->dapm_routes = mtk_dai_i2s_routes; 842 dai->num_dapm_routes = ARRAY_SIZE(mtk_dai_i2s_routes); 843 844 /* set all dai i2s private data */ 845 return mt8365_dai_i2s_set_priv(afe); 846 } 847
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.