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