xref: /linux/sound/soc/mediatek/mt8365/mt8365-dai-i2s.c (revision 62bde3771c3b83587a4549c92111d141954806c4)
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