brintos

brintos / linux-shallow public Read only

0
0
Text · 25.3 KiB · 11b9a5b Raw
847 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * MediaTek 8365 ALSA SoC Audio DAI I2S Control4 *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 917#define IIR_INV_COEF 1018#define IIR_NO_NEED 1119 20struct 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 */41enum {42	DAI_I2S0 = 0,43	DAI_I2S3,44	DAI_I2S_NUM,45};46 47static 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 80static 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, 99190	};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_NEED197		},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_NEED202		},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_NEED207		},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_NEED212		},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_NEED217		},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_NEED222		},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_NEED227		},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_NEED232		},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_NEED236		},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_NEED241		},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_NEED246		},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_NEED251		},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_NEED256		},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 279static 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		else310			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 consys319	}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 329int 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 339static 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 451static 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	else458		regmap_update_bits(afe->regmap, AFE_ASRC_2CH_CON0,459				   ASM_ON, ~ASM_ON);460	return 0;461}462 463void 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 497static 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 516static 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 542static 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		else566			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 589static 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	else631		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 670static 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 685static 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 721static 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 727static 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 735static 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 783static const char * const fmi2sin_text[] = {784	"OPEN", "FM_2ND_I2S_IN"785};786 787static SOC_ENUM_SINGLE_VIRT_DECL(fmi2sin_enum, fmi2sin_text);788 789static const struct snd_kcontrol_new fmi2sin_mux =790	SOC_DAPM_ENUM("FM 2ND I2S Source", fmi2sin_enum);791 792static const struct snd_kcontrol_new i2s_o03_o04_enable_ctl =793	SOC_DAPM_SINGLE_VIRT("Switch", 1);794 795static 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 802static 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 812static 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 827int 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