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
get_iir_coef(unsigned int input_fs,unsigned int output_fs,unsigned int * count)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
mt8365_dai_set_config(struct mtk_base_afe * afe,struct mtk_afe_i2s_priv * i2s_data,bool is_input,unsigned int rate,int bit_width)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
mt8365_afe_set_i2s_out(struct mtk_base_afe * afe,unsigned int rate,int bit_width)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
mt8365_afe_set_2nd_i2s_asrc(struct mtk_base_afe * afe,unsigned int rate_in,unsigned int rate_out,unsigned int width,unsigned int mono,int o16bit,int tracking)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
mt8365_afe_set_2nd_i2s_asrc_enable(struct mtk_base_afe * afe,bool enable)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
mt8365_afe_set_i2s_out_enable(struct mtk_base_afe * afe,bool enable)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
mt8365_dai_set_enable(struct mtk_base_afe * afe,struct mtk_afe_i2s_priv * i2s_data,bool is_input,bool enable)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
mt8365_dai_i2s_startup(struct snd_pcm_substream * substream,struct snd_soc_dai * dai)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
mt8365_dai_i2s_shutdown(struct snd_pcm_substream * substream,struct snd_soc_dai * dai)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
mt8365_dai_i2s_prepare(struct snd_pcm_substream * substream,struct snd_soc_dai * dai)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
mt8365_afe_2nd_i2s_hw_params(struct snd_pcm_substream * substream,struct snd_pcm_hw_params * params,struct snd_soc_dai * dai)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
mt8365_afe_2nd_i2s_set_fmt(struct snd_soc_dai * dai,unsigned int fmt)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
mt8365_dai_i2s_set_priv(struct mtk_base_afe * afe)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
mt8365_dai_i2s_register(struct mtk_base_afe * afe)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