brintos

brintos / linux-shallow public Read only

0
0
Text · 36.9 KiB · 7c40212 Raw
1232 lines · c
1// SPDX-License-Identifier: GPL-2.02//3// MediaTek ALSA SoC Audio DAI I2S Control4//5// Copyright (c) 2022 MediaTek Inc.6// Author: Jiaxin Yu <jiaxin.yu@mediatek.com>7 8#include <linux/bitops.h>9#include <linux/regmap.h>10#include <sound/pcm_params.h>11#include "mt8186-afe-clk.h"12#include "mt8186-afe-common.h"13#include "mt8186-afe-gpio.h"14#include "mt8186-interconnection.h"15 16enum {17	I2S_FMT_EIAJ = 0,18	I2S_FMT_I2S = 1,19};20 21enum {22	I2S_WLEN_16_BIT = 0,23	I2S_WLEN_32_BIT = 1,24};25 26enum {27	I2S_HD_NORMAL = 0,28	I2S_HD_LOW_JITTER = 1,29};30 31enum {32	I2S1_SEL_O28_O29 = 0,33	I2S1_SEL_O03_O04 = 1,34};35 36enum {37	I2S_IN_PAD_CONNSYS = 0,38	I2S_IN_PAD_IO_MUX = 1,39};40 41struct mtk_afe_i2s_priv {42	int id;43	int rate; /* for determine which apll to use */44	int low_jitter_en;45	int master; /* only i2s0 has slave mode*/46 47	int share_i2s_id;48 49	int mclk_id;50	int mclk_rate;51	int mclk_apll;52};53 54static unsigned int get_i2s_wlen(snd_pcm_format_t format)55{56	return snd_pcm_format_physical_width(format) <= 16 ?57	       I2S_WLEN_16_BIT : I2S_WLEN_32_BIT;58}59 60#define MTK_AFE_I2S0_KCONTROL_NAME "I2S0_HD_Mux"61#define MTK_AFE_I2S1_KCONTROL_NAME "I2S1_HD_Mux"62#define MTK_AFE_I2S2_KCONTROL_NAME "I2S2_HD_Mux"63#define MTK_AFE_I2S3_KCONTROL_NAME "I2S3_HD_Mux"64#define MTK_AFE_I2S0_SRC_KCONTROL_NAME "I2S0_SRC_Mux"65 66#define I2S0_HD_EN_W_NAME "I2S0_HD_EN"67#define I2S1_HD_EN_W_NAME "I2S1_HD_EN"68#define I2S2_HD_EN_W_NAME "I2S2_HD_EN"69#define I2S3_HD_EN_W_NAME "I2S3_HD_EN"70 71#define I2S0_MCLK_EN_W_NAME "I2S0_MCLK_EN"72#define I2S1_MCLK_EN_W_NAME "I2S1_MCLK_EN"73#define I2S2_MCLK_EN_W_NAME "I2S2_MCLK_EN"74#define I2S3_MCLK_EN_W_NAME "I2S3_MCLK_EN"75 76static int get_i2s_id_by_name(struct mtk_base_afe *afe,77			      const char *name)78{79	if (strncmp(name, "I2S0", 4) == 0)80		return MT8186_DAI_I2S_0;81	else if (strncmp(name, "I2S1", 4) == 0)82		return MT8186_DAI_I2S_1;83	else if (strncmp(name, "I2S2", 4) == 0)84		return MT8186_DAI_I2S_2;85	else if (strncmp(name, "I2S3", 4) == 0)86		return MT8186_DAI_I2S_3;87 88	return -EINVAL;89}90 91static struct mtk_afe_i2s_priv *get_i2s_priv_by_name(struct mtk_base_afe *afe,92						     const char *name)93{94	struct mt8186_afe_private *afe_priv = afe->platform_priv;95	int dai_id = get_i2s_id_by_name(afe, name);96 97	if (dai_id < 0)98		return NULL;99 100	return afe_priv->dai_priv[dai_id];101}102 103/* low jitter control */104static const char * const mt8186_i2s_hd_str[] = {105	"Normal", "Low_Jitter"106};107 108static const struct soc_enum mt8186_i2s_enum[] = {109	SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(mt8186_i2s_hd_str),110			    mt8186_i2s_hd_str),111};112 113static int mt8186_i2s_hd_get(struct snd_kcontrol *kcontrol,114			     struct snd_ctl_elem_value *ucontrol)115{116	struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);117	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);118	struct mtk_afe_i2s_priv *i2s_priv;119 120	i2s_priv = get_i2s_priv_by_name(afe, kcontrol->id.name);121	ucontrol->value.integer.value[0] = i2s_priv->low_jitter_en;122 123	return 0;124}125 126static int mt8186_i2s_hd_set(struct snd_kcontrol *kcontrol,127			     struct snd_ctl_elem_value *ucontrol)128{129	struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);130	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);131	struct mtk_afe_i2s_priv *i2s_priv;132	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;133	int hd_en;134 135	if (ucontrol->value.enumerated.item[0] >= e->items)136		return -EINVAL;137 138	hd_en = ucontrol->value.integer.value[0];139 140	dev_dbg(afe->dev, "%s(), kcontrol name %s, hd_en %d\n",141		__func__, kcontrol->id.name, hd_en);142 143	i2s_priv = get_i2s_priv_by_name(afe, kcontrol->id.name);144	if (i2s_priv->low_jitter_en == hd_en)145		return 0;146 147	i2s_priv->low_jitter_en = hd_en;148 149	return 1;150}151 152static const struct snd_kcontrol_new mtk_dai_i2s_controls[] = {153	SOC_ENUM_EXT(MTK_AFE_I2S0_KCONTROL_NAME, mt8186_i2s_enum[0],154		     mt8186_i2s_hd_get, mt8186_i2s_hd_set),155	SOC_ENUM_EXT(MTK_AFE_I2S1_KCONTROL_NAME, mt8186_i2s_enum[0],156		     mt8186_i2s_hd_get, mt8186_i2s_hd_set),157	SOC_ENUM_EXT(MTK_AFE_I2S2_KCONTROL_NAME, mt8186_i2s_enum[0],158		     mt8186_i2s_hd_get, mt8186_i2s_hd_set),159	SOC_ENUM_EXT(MTK_AFE_I2S3_KCONTROL_NAME, mt8186_i2s_enum[0],160		     mt8186_i2s_hd_get, mt8186_i2s_hd_set),161};162 163/* dai component */164/* i2s virtual mux to output widget */165static const char * const i2s_mux_map[] = {166	"Normal", "Dummy_Widget",167};168 169static int i2s_mux_map_value[] = {170	0, 1,171};172 173static SOC_VALUE_ENUM_SINGLE_AUTODISABLE_DECL(i2s_mux_map_enum,174					      SND_SOC_NOPM,175					      0,176					      1,177					      i2s_mux_map,178					      i2s_mux_map_value);179 180static const struct snd_kcontrol_new i2s0_in_mux_control =181	SOC_DAPM_ENUM("I2S0 In Select", i2s_mux_map_enum);182 183static const struct snd_kcontrol_new i2s1_out_mux_control =184	SOC_DAPM_ENUM("I2S1 Out Select", i2s_mux_map_enum);185 186static const struct snd_kcontrol_new i2s2_in_mux_control =187	SOC_DAPM_ENUM("I2S2 In Select", i2s_mux_map_enum);188 189static const struct snd_kcontrol_new i2s3_out_mux_control =190	SOC_DAPM_ENUM("I2S3 Out Select", i2s_mux_map_enum);191 192/* i2s in lpbk */193static const char * const i2s_lpbk_mux_map[] = {194	"Normal", "Lpbk",195};196 197static int i2s_lpbk_mux_map_value[] = {198	0, 1,199};200 201static SOC_VALUE_ENUM_SINGLE_AUTODISABLE_DECL(i2s0_lpbk_mux_map_enum,202					      AFE_I2S_CON,203					      I2S_LOOPBACK_SFT,204					      1,205					      i2s_lpbk_mux_map,206					      i2s_lpbk_mux_map_value);207 208static const struct snd_kcontrol_new i2s0_lpbk_mux_control =209	SOC_DAPM_ENUM("I2S Lpbk Select", i2s0_lpbk_mux_map_enum);210 211static SOC_VALUE_ENUM_SINGLE_AUTODISABLE_DECL(i2s2_lpbk_mux_map_enum,212					      AFE_I2S_CON2,213					      I2S3_LOOPBACK_SFT,214					      1,215					      i2s_lpbk_mux_map,216					      i2s_lpbk_mux_map_value);217 218static const struct snd_kcontrol_new i2s2_lpbk_mux_control =219	SOC_DAPM_ENUM("I2S Lpbk Select", i2s2_lpbk_mux_map_enum);220 221/* interconnection */222static const struct snd_kcontrol_new mtk_i2s3_ch1_mix[] = {223	SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1 Switch", AFE_CONN0,224				    I_DL1_CH1, 1, 0),225	SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1 Switch", AFE_CONN0,226				    I_DL2_CH1, 1, 0),227	SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1 Switch", AFE_CONN0,228				    I_DL3_CH1, 1, 0),229	SOC_DAPM_SINGLE_AUTODISABLE("DL12_CH1 Switch", AFE_CONN0,230				    I_DL12_CH1, 1, 0),231	SOC_DAPM_SINGLE_AUTODISABLE("DL12_CH3 Switch", AFE_CONN0,232				    I_DL12_CH3, 1, 0),233	SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH1 Switch", AFE_CONN0_1,234				    I_DL6_CH1, 1, 0),235	SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH1 Switch", AFE_CONN0_1,236				    I_DL4_CH1, 1, 0),237	SOC_DAPM_SINGLE_AUTODISABLE("DL5_CH1 Switch", AFE_CONN0_1,238				    I_DL5_CH1, 1, 0),239	SOC_DAPM_SINGLE_AUTODISABLE("DL8_CH1 Switch", AFE_CONN0_1,240				    I_DL8_CH1, 1, 0),241	SOC_DAPM_SINGLE_AUTODISABLE("GAIN1_OUT_CH1 Switch", AFE_CONN0,242				    I_GAIN1_OUT_CH1, 1, 0),243	SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1 Switch", AFE_CONN0,244				    I_ADDA_UL_CH1, 1, 0),245	SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2 Switch", AFE_CONN0,246				    I_ADDA_UL_CH2, 1, 0),247	SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3 Switch", AFE_CONN0,248				    I_ADDA_UL_CH3, 1, 0),249	SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH1 Switch", AFE_CONN0,250				    I_PCM_1_CAP_CH1, 1, 0),251	SOC_DAPM_SINGLE_AUTODISABLE("SRC_1_OUT_CH1 Switch", AFE_CONN0_1,252				    I_SRC_1_OUT_CH1, 1, 0),253};254 255static const struct snd_kcontrol_new mtk_i2s3_ch2_mix[] = {256	SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH2 Switch", AFE_CONN1,257				    I_DL1_CH2, 1, 0),258	SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH2 Switch", AFE_CONN1,259				    I_DL2_CH2, 1, 0),260	SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH2 Switch", AFE_CONN1,261				    I_DL3_CH2, 1, 0),262	SOC_DAPM_SINGLE_AUTODISABLE("DL12_CH2 Switch", AFE_CONN1,263				    I_DL12_CH2, 1, 0),264	SOC_DAPM_SINGLE_AUTODISABLE("DL12_CH4 Switch", AFE_CONN1,265				    I_DL12_CH4, 1, 0),266	SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH2 Switch", AFE_CONN1_1,267				    I_DL6_CH2, 1, 0),268	SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH2 Switch", AFE_CONN1_1,269				    I_DL4_CH2, 1, 0),270	SOC_DAPM_SINGLE_AUTODISABLE("DL5_CH2 Switch", AFE_CONN1_1,271				    I_DL5_CH2, 1, 0),272	SOC_DAPM_SINGLE_AUTODISABLE("DL8_CH2 Switch", AFE_CONN1_1,273				    I_DL8_CH2, 1, 0),274	SOC_DAPM_SINGLE_AUTODISABLE("GAIN1_OUT_CH2 Switch", AFE_CONN1,275				    I_GAIN1_OUT_CH2, 1, 0),276	SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1 Switch", AFE_CONN1,277				    I_ADDA_UL_CH1, 1, 0),278	SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2 Switch", AFE_CONN1,279				    I_ADDA_UL_CH2, 1, 0),280	SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3 Switch", AFE_CONN1,281				    I_ADDA_UL_CH3, 1, 0),282	SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH2 Switch", AFE_CONN1,283				    I_PCM_1_CAP_CH2, 1, 0),284	SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH2 Switch", AFE_CONN1,285				    I_PCM_2_CAP_CH2, 1, 0),286	SOC_DAPM_SINGLE_AUTODISABLE("SRC_1_OUT_CH2 Switch", AFE_CONN1_1,287				    I_SRC_1_OUT_CH2, 1, 0),288};289 290static const struct snd_kcontrol_new mtk_i2s1_ch1_mix[] = {291	SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1 Switch", AFE_CONN28,292				    I_DL1_CH1, 1, 0),293	SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1 Switch", AFE_CONN28,294				    I_DL2_CH1, 1, 0),295	SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1 Switch", AFE_CONN28,296				    I_DL3_CH1, 1, 0),297	SOC_DAPM_SINGLE_AUTODISABLE("DL12_CH1 Switch", AFE_CONN28,298				    I_DL12_CH1, 1, 0),299	SOC_DAPM_SINGLE_AUTODISABLE("DL12_CH3 Switch", AFE_CONN28,300				    I_DL12_CH3, 1, 0),301	SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH1 Switch", AFE_CONN28_1,302				    I_DL6_CH1, 1, 0),303	SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH1 Switch", AFE_CONN28_1,304				    I_DL4_CH1, 1, 0),305	SOC_DAPM_SINGLE_AUTODISABLE("DL5_CH1 Switch", AFE_CONN28_1,306				    I_DL5_CH1, 1, 0),307	SOC_DAPM_SINGLE_AUTODISABLE("DL8_CH1 Switch", AFE_CONN28_1,308				    I_DL8_CH1, 1, 0),309	SOC_DAPM_SINGLE_AUTODISABLE("GAIN1_OUT_CH1 Switch", AFE_CONN28,310				    I_GAIN1_OUT_CH1, 1, 0),311	SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1 Switch", AFE_CONN28,312				    I_ADDA_UL_CH1, 1, 0),313	SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH1 Switch", AFE_CONN28,314				    I_PCM_1_CAP_CH1, 1, 0),315	SOC_DAPM_SINGLE_AUTODISABLE("SRC_1_OUT_CH1 Switch", AFE_CONN28_1,316				    I_SRC_1_OUT_CH1, 1, 0),317};318 319static const struct snd_kcontrol_new mtk_i2s1_ch2_mix[] = {320	SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH2 Switch", AFE_CONN29,321				    I_DL1_CH2, 1, 0),322	SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH2 Switch", AFE_CONN29,323				    I_DL2_CH2, 1, 0),324	SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH2 Switch", AFE_CONN29,325				    I_DL3_CH2, 1, 0),326	SOC_DAPM_SINGLE_AUTODISABLE("DL12_CH2 Switch", AFE_CONN29,327				    I_DL12_CH2, 1, 0),328	SOC_DAPM_SINGLE_AUTODISABLE("DL12_CH4 Switch", AFE_CONN29,329				    I_DL12_CH4, 1, 0),330	SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH2 Switch", AFE_CONN29_1,331				    I_DL6_CH2, 1, 0),332	SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH2 Switch", AFE_CONN29_1,333				    I_DL4_CH2, 1, 0),334	SOC_DAPM_SINGLE_AUTODISABLE("DL5_CH2 Switch", AFE_CONN29_1,335				    I_DL5_CH2, 1, 0),336	SOC_DAPM_SINGLE_AUTODISABLE("DL8_CH2 Switch", AFE_CONN29_1,337				    I_DL8_CH2, 1, 0),338	SOC_DAPM_SINGLE_AUTODISABLE("GAIN1_OUT_CH2 Switch", AFE_CONN29,339				    I_GAIN1_OUT_CH2, 1, 0),340	SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2 Switch", AFE_CONN29,341				    I_ADDA_UL_CH2, 1, 0),342	SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH2 Switch", AFE_CONN29,343				    I_PCM_1_CAP_CH2, 1, 0),344	SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH2 Switch", AFE_CONN29,345				    I_PCM_2_CAP_CH2, 1, 0),346	SOC_DAPM_SINGLE_AUTODISABLE("SRC_1_OUT_CH2 Switch", AFE_CONN29_1,347				    I_SRC_1_OUT_CH2, 1, 0),348};349 350enum {351	SUPPLY_SEQ_APLL,352	SUPPLY_SEQ_I2S_MCLK_EN,353	SUPPLY_SEQ_I2S_HD_EN,354	SUPPLY_SEQ_I2S_EN,355};356 357static int mtk_i2s_en_event(struct snd_soc_dapm_widget *w,358			    struct snd_kcontrol *kcontrol,359			    int event)360{361	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);362	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);363	struct mtk_afe_i2s_priv *i2s_priv;364 365	i2s_priv = get_i2s_priv_by_name(afe, w->name);366 367	dev_dbg(cmpnt->dev, "%s(), name %s, event 0x%x\n",368		__func__, w->name, event);369 370	switch (event) {371	case SND_SOC_DAPM_PRE_PMU:372		mt8186_afe_gpio_request(afe->dev, true, i2s_priv->id, 0);373		break;374	case SND_SOC_DAPM_POST_PMD:375		mt8186_afe_gpio_request(afe->dev, false, i2s_priv->id, 0);376		break;377	default:378		break;379	}380 381	return 0;382}383 384static int mtk_apll_event(struct snd_soc_dapm_widget *w,385			  struct snd_kcontrol *kcontrol,386			  int event)387{388	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);389	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);390 391	dev_dbg(cmpnt->dev, "%s(), name %s, event 0x%x\n",392		__func__, w->name, event);393 394	switch (event) {395	case SND_SOC_DAPM_PRE_PMU:396		if (snd_soc_dapm_widget_name_cmp(w, APLL1_W_NAME) == 0)397			mt8186_apll1_enable(afe);398		else399			mt8186_apll2_enable(afe);400		break;401	case SND_SOC_DAPM_POST_PMD:402		if (snd_soc_dapm_widget_name_cmp(w, APLL1_W_NAME) == 0)403			mt8186_apll1_disable(afe);404		else405			mt8186_apll2_disable(afe);406		break;407	default:408		break;409	}410 411	return 0;412}413 414static int mtk_mclk_en_event(struct snd_soc_dapm_widget *w,415			     struct snd_kcontrol *kcontrol,416			     int event)417{418	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);419	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);420	struct mtk_afe_i2s_priv *i2s_priv;421 422	dev_dbg(cmpnt->dev, "%s(), name %s, event 0x%x\n",423		__func__, w->name, event);424 425	i2s_priv = get_i2s_priv_by_name(afe, w->name);426 427	switch (event) {428	case SND_SOC_DAPM_PRE_PMU:429		mt8186_mck_enable(afe, i2s_priv->mclk_id, i2s_priv->mclk_rate);430		break;431	case SND_SOC_DAPM_POST_PMD:432		i2s_priv->mclk_rate = 0;433		mt8186_mck_disable(afe, i2s_priv->mclk_id);434		break;435	default:436		break;437	}438 439	return 0;440}441 442static const struct snd_soc_dapm_widget mtk_dai_i2s_widgets[] = {443	SND_SOC_DAPM_INPUT("CONNSYS"),444 445	SND_SOC_DAPM_MIXER("I2S1_CH1", SND_SOC_NOPM, 0, 0,446			   mtk_i2s1_ch1_mix,447			   ARRAY_SIZE(mtk_i2s1_ch1_mix)),448	SND_SOC_DAPM_MIXER("I2S1_CH2", SND_SOC_NOPM, 0, 0,449			   mtk_i2s1_ch2_mix,450			   ARRAY_SIZE(mtk_i2s1_ch2_mix)),451 452	SND_SOC_DAPM_MIXER("I2S3_CH1", SND_SOC_NOPM, 0, 0,453			   mtk_i2s3_ch1_mix,454			   ARRAY_SIZE(mtk_i2s3_ch1_mix)),455	SND_SOC_DAPM_MIXER("I2S3_CH2", SND_SOC_NOPM, 0, 0,456			   mtk_i2s3_ch2_mix,457			   ARRAY_SIZE(mtk_i2s3_ch2_mix)),458 459	/* i2s en*/460	SND_SOC_DAPM_SUPPLY_S("I2S0_EN", SUPPLY_SEQ_I2S_EN,461			      AFE_I2S_CON, I2S_EN_SFT, 0,462			      mtk_i2s_en_event,463			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),464	SND_SOC_DAPM_SUPPLY_S("I2S1_EN", SUPPLY_SEQ_I2S_EN,465			      AFE_I2S_CON1, I2S_EN_SFT, 0,466			      mtk_i2s_en_event,467			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),468	SND_SOC_DAPM_SUPPLY_S("I2S2_EN", SUPPLY_SEQ_I2S_EN,469			      AFE_I2S_CON2, I2S_EN_SFT, 0,470			      mtk_i2s_en_event,471			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),472	SND_SOC_DAPM_SUPPLY_S("I2S3_EN", SUPPLY_SEQ_I2S_EN,473			      AFE_I2S_CON3, I2S_EN_SFT, 0,474			      mtk_i2s_en_event,475			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),476	/* i2s hd en */477	SND_SOC_DAPM_SUPPLY_S(I2S0_HD_EN_W_NAME, SUPPLY_SEQ_I2S_HD_EN,478			      AFE_I2S_CON, I2S1_HD_EN_SFT, 0, NULL,479			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),480	SND_SOC_DAPM_SUPPLY_S(I2S1_HD_EN_W_NAME, SUPPLY_SEQ_I2S_HD_EN,481			      AFE_I2S_CON1, I2S2_HD_EN_SFT, 0, NULL,482			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),483	SND_SOC_DAPM_SUPPLY_S(I2S2_HD_EN_W_NAME, SUPPLY_SEQ_I2S_HD_EN,484			      AFE_I2S_CON2, I2S3_HD_EN_SFT, 0, NULL,485			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),486	SND_SOC_DAPM_SUPPLY_S(I2S3_HD_EN_W_NAME, SUPPLY_SEQ_I2S_HD_EN,487			      AFE_I2S_CON3, I2S4_HD_EN_SFT, 0, NULL,488			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),489 490	/* i2s mclk en */491	SND_SOC_DAPM_SUPPLY_S(I2S0_MCLK_EN_W_NAME, SUPPLY_SEQ_I2S_MCLK_EN,492			      SND_SOC_NOPM, 0, 0,493			      mtk_mclk_en_event,494			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),495	SND_SOC_DAPM_SUPPLY_S(I2S1_MCLK_EN_W_NAME, SUPPLY_SEQ_I2S_MCLK_EN,496			      SND_SOC_NOPM, 0, 0,497			      mtk_mclk_en_event,498			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),499	SND_SOC_DAPM_SUPPLY_S(I2S2_MCLK_EN_W_NAME, SUPPLY_SEQ_I2S_MCLK_EN,500			      SND_SOC_NOPM, 0, 0,501			      mtk_mclk_en_event,502			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),503	SND_SOC_DAPM_SUPPLY_S(I2S3_MCLK_EN_W_NAME, SUPPLY_SEQ_I2S_MCLK_EN,504			      SND_SOC_NOPM, 0, 0,505			      mtk_mclk_en_event,506			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),507 508	/* apll */509	SND_SOC_DAPM_SUPPLY_S(APLL1_W_NAME, SUPPLY_SEQ_APLL,510			      SND_SOC_NOPM, 0, 0,511			      mtk_apll_event,512			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),513	SND_SOC_DAPM_SUPPLY_S(APLL2_W_NAME, SUPPLY_SEQ_APLL,514			      SND_SOC_NOPM, 0, 0,515			      mtk_apll_event,516			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),517 518	/* allow i2s on without codec on */519	SND_SOC_DAPM_OUTPUT("I2S_DUMMY_OUT"),520	SND_SOC_DAPM_MUX("I2S1_Out_Mux",521			 SND_SOC_NOPM, 0, 0, &i2s1_out_mux_control),522	SND_SOC_DAPM_MUX("I2S3_Out_Mux",523			 SND_SOC_NOPM, 0, 0, &i2s3_out_mux_control),524	SND_SOC_DAPM_INPUT("I2S_DUMMY_IN"),525	SND_SOC_DAPM_MUX("I2S0_In_Mux",526			 SND_SOC_NOPM, 0, 0, &i2s0_in_mux_control),527	SND_SOC_DAPM_MUX("I2S2_In_Mux",528			 SND_SOC_NOPM, 0, 0, &i2s2_in_mux_control),529 530	/* i2s in lpbk */531	SND_SOC_DAPM_MUX("I2S0_Lpbk_Mux",532			 SND_SOC_NOPM, 0, 0, &i2s0_lpbk_mux_control),533	SND_SOC_DAPM_MUX("I2S2_Lpbk_Mux",534			 SND_SOC_NOPM, 0, 0, &i2s2_lpbk_mux_control),535};536 537static int mtk_afe_i2s_share_connect(struct snd_soc_dapm_widget *source,538				     struct snd_soc_dapm_widget *sink)539{540	struct snd_soc_dapm_widget *w = sink;541	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);542	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);543	struct mtk_afe_i2s_priv *i2s_priv;544 545	i2s_priv = get_i2s_priv_by_name(afe, sink->name);546	if (i2s_priv->share_i2s_id < 0)547		return 0;548 549	return i2s_priv->share_i2s_id == get_i2s_id_by_name(afe, source->name);550}551 552static int mtk_afe_i2s_hd_connect(struct snd_soc_dapm_widget *source,553				  struct snd_soc_dapm_widget *sink)554{555	struct snd_soc_dapm_widget *w = sink;556	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);557	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);558	struct mtk_afe_i2s_priv *i2s_priv;559 560	i2s_priv = get_i2s_priv_by_name(afe, sink->name);561	if (get_i2s_id_by_name(afe, sink->name) ==562	    get_i2s_id_by_name(afe, source->name))563		return i2s_priv->low_jitter_en;564 565	/* check if share i2s need hd en */566	if (i2s_priv->share_i2s_id < 0)567		return 0;568 569	if (i2s_priv->share_i2s_id == get_i2s_id_by_name(afe, source->name))570		return i2s_priv->low_jitter_en;571 572	return 0;573}574 575static int mtk_afe_i2s_apll_connect(struct snd_soc_dapm_widget *source,576				    struct snd_soc_dapm_widget *sink)577{578	struct snd_soc_dapm_widget *w = sink;579	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);580	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);581	struct mtk_afe_i2s_priv *i2s_priv;582	int cur_apll;583	int i2s_need_apll;584 585	i2s_priv = get_i2s_priv_by_name(afe, w->name);586	/* which apll */587	cur_apll = mt8186_get_apll_by_name(afe, source->name);588	/* choose APLL from i2s rate */589	i2s_need_apll = mt8186_get_apll_by_rate(afe, i2s_priv->rate);590 591	return (i2s_need_apll == cur_apll) ? 1 : 0;592}593 594static int mtk_afe_i2s_mclk_connect(struct snd_soc_dapm_widget *source,595				    struct snd_soc_dapm_widget *sink)596{597	struct snd_soc_dapm_widget *w = sink;598	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);599	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);600	struct mtk_afe_i2s_priv *i2s_priv;601 602	i2s_priv = get_i2s_priv_by_name(afe, sink->name);603	if (get_i2s_id_by_name(afe, sink->name) ==604	    get_i2s_id_by_name(afe, source->name))605		return (i2s_priv->mclk_rate > 0) ? 1 : 0;606 607	/* check if share i2s need mclk */608	if (i2s_priv->share_i2s_id < 0)609		return 0;610 611	if (i2s_priv->share_i2s_id == get_i2s_id_by_name(afe, source->name))612		return (i2s_priv->mclk_rate > 0) ? 1 : 0;613 614	return 0;615}616 617static int mtk_afe_mclk_apll_connect(struct snd_soc_dapm_widget *source,618				     struct snd_soc_dapm_widget *sink)619{620	struct snd_soc_dapm_widget *w = sink;621	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);622	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);623	struct mtk_afe_i2s_priv *i2s_priv;624	int cur_apll;625 626	i2s_priv = get_i2s_priv_by_name(afe, w->name);627	/* which apll */628	cur_apll = mt8186_get_apll_by_name(afe, source->name);629 630	return (i2s_priv->mclk_apll == cur_apll) ? 1 : 0;631}632 633static const struct snd_soc_dapm_route mtk_dai_i2s_routes[] = {634	{"Connsys I2S", NULL, "CONNSYS"},635 636	/* i2s0 */637	{"I2S0", NULL, "I2S0_EN"},638	{"I2S0", NULL, "I2S1_EN", mtk_afe_i2s_share_connect},639	{"I2S0", NULL, "I2S2_EN", mtk_afe_i2s_share_connect},640	{"I2S0", NULL, "I2S3_EN", mtk_afe_i2s_share_connect},641 642	{"I2S0", NULL, I2S0_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},643	{"I2S0", NULL, I2S1_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},644	{"I2S0", NULL, I2S2_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},645	{"I2S0", NULL, I2S3_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},646	{I2S0_HD_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_i2s_apll_connect},647	{I2S0_HD_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_i2s_apll_connect},648 649	{"I2S0", NULL, I2S0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},650	{"I2S0", NULL, I2S1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},651	{"I2S0", NULL, I2S2_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},652	{"I2S0", NULL, I2S3_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},653	{I2S0_MCLK_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect},654	{I2S0_MCLK_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect},655 656	/* i2s1 */657	{"I2S1_CH1", "DL1_CH1 Switch", "DL1"},658	{"I2S1_CH2", "DL1_CH2 Switch", "DL1"},659 660	{"I2S1_CH1", "DL1_CH1 Switch", "DSP_DL1_VIRT"},661	{"I2S1_CH2", "DL1_CH2 Switch", "DSP_DL1_VIRT"},662 663	{"I2S1_CH1", "DL2_CH1 Switch", "DL2"},664	{"I2S1_CH2", "DL2_CH2 Switch", "DL2"},665 666	{"I2S1_CH1", "DL2_CH1 Switch", "DSP_DL2_VIRT"},667	{"I2S1_CH2", "DL2_CH2 Switch", "DSP_DL2_VIRT"},668 669	{"I2S1_CH1", "DL3_CH1 Switch", "DL3"},670	{"I2S1_CH2", "DL3_CH2 Switch", "DL3"},671 672	{"I2S1_CH1", "DL12_CH1 Switch", "DL12"},673	{"I2S1_CH2", "DL12_CH2 Switch", "DL12"},674 675	{"I2S1_CH1", "DL12_CH3 Switch", "DL12"},676	{"I2S1_CH2", "DL12_CH4 Switch", "DL12"},677 678	{"I2S1_CH1", "DL6_CH1 Switch", "DL6"},679	{"I2S1_CH2", "DL6_CH2 Switch", "DL6"},680 681	{"I2S1_CH1", "DL4_CH1 Switch", "DL4"},682	{"I2S1_CH2", "DL4_CH2 Switch", "DL4"},683 684	{"I2S1_CH1", "DL5_CH1 Switch", "DL5"},685	{"I2S1_CH2", "DL5_CH2 Switch", "DL5"},686 687	{"I2S1_CH1", "DL8_CH1 Switch", "DL8"},688	{"I2S1_CH2", "DL8_CH2 Switch", "DL8"},689 690	{"I2S1", NULL, "I2S1_CH1"},691	{"I2S1", NULL, "I2S1_CH2"},692 693	{"I2S1", NULL, "I2S0_EN", mtk_afe_i2s_share_connect},694	{"I2S1", NULL, "I2S1_EN"},695	{"I2S1", NULL, "I2S2_EN", mtk_afe_i2s_share_connect},696	{"I2S1", NULL, "I2S3_EN", mtk_afe_i2s_share_connect},697 698	{"I2S1", NULL, I2S0_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},699	{"I2S1", NULL, I2S1_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},700	{"I2S1", NULL, I2S2_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},701	{"I2S1", NULL, I2S3_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},702	{I2S1_HD_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_i2s_apll_connect},703	{I2S1_HD_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_i2s_apll_connect},704 705	{"I2S1", NULL, I2S0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},706	{"I2S1", NULL, I2S1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},707	{"I2S1", NULL, I2S2_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},708	{"I2S1", NULL, I2S3_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},709	{I2S1_MCLK_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect},710	{I2S1_MCLK_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect},711 712	/* i2s2 */713	{"I2S2", NULL, "I2S0_EN", mtk_afe_i2s_share_connect},714	{"I2S2", NULL, "I2S1_EN", mtk_afe_i2s_share_connect},715	{"I2S2", NULL, "I2S2_EN"},716	{"I2S2", NULL, "I2S3_EN", mtk_afe_i2s_share_connect},717 718	{"I2S2", NULL, I2S0_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},719	{"I2S2", NULL, I2S1_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},720	{"I2S2", NULL, I2S2_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},721	{"I2S2", NULL, I2S3_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},722	{I2S2_HD_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_i2s_apll_connect},723	{I2S2_HD_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_i2s_apll_connect},724 725	{"I2S2", NULL, I2S0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},726	{"I2S2", NULL, I2S1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},727	{"I2S2", NULL, I2S2_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},728	{"I2S2", NULL, I2S3_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},729	{I2S2_MCLK_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect},730	{I2S2_MCLK_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect},731 732	/* i2s3 */733	{"I2S3_CH1", "DL1_CH1 Switch", "DL1"},734	{"I2S3_CH2", "DL1_CH2 Switch", "DL1"},735 736	{"I2S3_CH1", "DL1_CH1 Switch", "DSP_DL1_VIRT"},737	{"I2S3_CH2", "DL1_CH2 Switch", "DSP_DL1_VIRT"},738 739	{"I2S3_CH1", "DL2_CH1 Switch", "DL2"},740	{"I2S3_CH2", "DL2_CH2 Switch", "DL2"},741 742	{"I2S3_CH1", "DL2_CH1 Switch", "DSP_DL2_VIRT"},743	{"I2S3_CH2", "DL2_CH2 Switch", "DSP_DL2_VIRT"},744 745	{"I2S3_CH1", "DL3_CH1 Switch", "DL3"},746	{"I2S3_CH2", "DL3_CH2 Switch", "DL3"},747 748	{"I2S3_CH1", "DL12_CH1 Switch", "DL12"},749	{"I2S3_CH2", "DL12_CH2 Switch", "DL12"},750 751	{"I2S3_CH1", "DL12_CH3 Switch", "DL12"},752	{"I2S3_CH2", "DL12_CH4 Switch", "DL12"},753 754	{"I2S3_CH1", "DL6_CH1 Switch", "DL6"},755	{"I2S3_CH2", "DL6_CH2 Switch", "DL6"},756 757	{"I2S3_CH1", "DL4_CH1 Switch", "DL4"},758	{"I2S3_CH2", "DL4_CH2 Switch", "DL4"},759 760	{"I2S3_CH1", "DL5_CH1 Switch", "DL5"},761	{"I2S3_CH2", "DL5_CH2 Switch", "DL5"},762 763	{"I2S3_CH1", "DL8_CH1 Switch", "DL8"},764	{"I2S3_CH2", "DL8_CH2 Switch", "DL8"},765 766	{"I2S3", NULL, "I2S3_CH1"},767	{"I2S3", NULL, "I2S3_CH2"},768 769	{"I2S3", NULL, "I2S0_EN", mtk_afe_i2s_share_connect},770	{"I2S3", NULL, "I2S1_EN", mtk_afe_i2s_share_connect},771	{"I2S3", NULL, "I2S2_EN", mtk_afe_i2s_share_connect},772	{"I2S3", NULL, "I2S3_EN"},773 774	{"I2S3", NULL, I2S0_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},775	{"I2S3", NULL, I2S1_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},776	{"I2S3", NULL, I2S2_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},777	{"I2S3", NULL, I2S3_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},778	{I2S3_HD_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_i2s_apll_connect},779	{I2S3_HD_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_i2s_apll_connect},780 781	{"I2S3", NULL, I2S0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},782	{"I2S3", NULL, I2S1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},783	{"I2S3", NULL, I2S2_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},784	{"I2S3", NULL, I2S3_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},785	{I2S3_MCLK_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect},786	{I2S3_MCLK_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect},787 788	/* allow i2s on without codec on */789	{"I2S0", NULL, "I2S0_In_Mux"},790	{"I2S0_In_Mux", "Dummy_Widget", "I2S_DUMMY_IN"},791 792	{"I2S1_Out_Mux", "Dummy_Widget", "I2S1"},793	{"I2S_DUMMY_OUT", NULL, "I2S1_Out_Mux"},794 795	{"I2S2", NULL, "I2S2_In_Mux"},796	{"I2S2_In_Mux", "Dummy_Widget", "I2S_DUMMY_IN"},797 798	{"I2S3_Out_Mux", "Dummy_Widget", "I2S3"},799	{"I2S_DUMMY_OUT", NULL, "I2S3_Out_Mux"},800 801	/* i2s in lpbk */802	{"I2S0_Lpbk_Mux", "Lpbk", "I2S3"},803	{"I2S2_Lpbk_Mux", "Lpbk", "I2S1"},804	{"I2S0", NULL, "I2S0_Lpbk_Mux"},805	{"I2S2", NULL, "I2S2_Lpbk_Mux"},806};807 808/* dai ops */809static int mtk_dai_connsys_i2s_hw_params(struct snd_pcm_substream *substream,810					 struct snd_pcm_hw_params *params,811					 struct snd_soc_dai *dai)812{813	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);814	unsigned int rate = params_rate(params);815	unsigned int rate_reg = mt8186_rate_transform(afe->dev,816						      rate, dai->id);817	unsigned int i2s_con = 0;818 819	dev_dbg(afe->dev, "%s(), id %d, stream %d, rate %d\n",820		__func__, dai->id, substream->stream, rate);821 822	/* non-inverse, i2s mode, slave, 16bits, from connsys */823	i2s_con |= 0 << INV_PAD_CTRL_SFT;824	i2s_con |= I2S_FMT_I2S << I2S_FMT_SFT;825	i2s_con |= 1 << I2S_SRC_SFT;826	i2s_con |= get_i2s_wlen(SNDRV_PCM_FORMAT_S16_LE) << I2S_WLEN_SFT;827	i2s_con |= 0 << I2SIN_PAD_SEL_SFT;828	regmap_write(afe->regmap, AFE_CONNSYS_I2S_CON, i2s_con);829 830	/* use asrc */831	regmap_update_bits(afe->regmap, AFE_CONNSYS_I2S_CON,832			   I2S_BYPSRC_MASK_SFT, 0);833 834	/* slave mode, set i2s for asrc */835	regmap_update_bits(afe->regmap, AFE_CONNSYS_I2S_CON,836			   I2S_MODE_MASK_SFT, rate_reg << I2S_MODE_SFT);837 838	if (rate == 44100)839		regmap_write(afe->regmap, AFE_ASRC_2CH_CON3, 0x1b9000);840	else if (rate == 32000)841		regmap_write(afe->regmap, AFE_ASRC_2CH_CON3, 0x140000);842	else843		regmap_write(afe->regmap, AFE_ASRC_2CH_CON3, 0x1e0000);844 845	/* Calibration setting */846	regmap_write(afe->regmap, AFE_ASRC_2CH_CON4, 0x140000);847	regmap_write(afe->regmap, AFE_ASRC_2CH_CON9, 0x36000);848	regmap_write(afe->regmap, AFE_ASRC_2CH_CON10, 0x2fc00);849	regmap_write(afe->regmap, AFE_ASRC_2CH_CON6, 0x7ef4);850	regmap_write(afe->regmap, AFE_ASRC_2CH_CON5, 0xff5986);851 852	/* 0:Stereo 1:Mono */853	regmap_update_bits(afe->regmap, AFE_ASRC_2CH_CON2,854			   CHSET_IS_MONO_MASK_SFT, 0);855 856	return 0;857}858 859static int mtk_dai_connsys_i2s_trigger(struct snd_pcm_substream *substream,860				       int cmd, struct snd_soc_dai *dai)861{862	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);863	struct mt8186_afe_private *afe_priv = afe->platform_priv;864 865	dev_dbg(afe->dev, "%s(), cmd %d, stream %d\n",866		__func__, cmd, substream->stream);867 868	switch (cmd) {869	case SNDRV_PCM_TRIGGER_START:870	case SNDRV_PCM_TRIGGER_RESUME:871		/* i2s enable */872		regmap_update_bits(afe->regmap,873				   AFE_CONNSYS_I2S_CON,874				   I2S_EN_MASK_SFT,875				   BIT(I2S_EN_SFT));876 877		/* calibrator enable */878		regmap_update_bits(afe->regmap,879				   AFE_ASRC_2CH_CON5,880				   CALI_EN_MASK_SFT,881				   BIT(CALI_EN_SFT));882 883		/* asrc enable */884		regmap_update_bits(afe->regmap,885				   AFE_ASRC_2CH_CON0,886				   CON0_CHSET_STR_CLR_MASK_SFT,887				   BIT(CON0_CHSET_STR_CLR_SFT));888		regmap_update_bits(afe->regmap,889				   AFE_ASRC_2CH_CON0,890				   CON0_ASM_ON_MASK_SFT,891				   BIT(CON0_ASM_ON_SFT));892 893		afe_priv->dai_on[dai->id] = true;894		return 0;895	case SNDRV_PCM_TRIGGER_STOP:896	case SNDRV_PCM_TRIGGER_SUSPEND:897		regmap_update_bits(afe->regmap, AFE_ASRC_2CH_CON0,898				   CON0_ASM_ON_MASK_SFT, 0);899		regmap_update_bits(afe->regmap, AFE_ASRC_2CH_CON5,900				   CALI_EN_MASK_SFT, 0);901 902		/* i2s disable */903		regmap_update_bits(afe->regmap, AFE_CONNSYS_I2S_CON,904				   I2S_EN_MASK_SFT, 0);905 906		/* bypass asrc */907		regmap_update_bits(afe->regmap, AFE_CONNSYS_I2S_CON,908				   I2S_BYPSRC_MASK_SFT, BIT(I2S_BYPSRC_SFT));909 910		afe_priv->dai_on[dai->id] = false;911		return 0;912	default:913		return -EINVAL;914	}915	return 0;916}917 918static const struct snd_soc_dai_ops mtk_dai_connsys_i2s_ops = {919	.hw_params = mtk_dai_connsys_i2s_hw_params,920	.trigger = mtk_dai_connsys_i2s_trigger,921};922 923/* i2s */924static int mtk_dai_i2s_config(struct mtk_base_afe *afe,925			      struct snd_pcm_hw_params *params,926			      int i2s_id)927{928	struct mt8186_afe_private *afe_priv = afe->platform_priv;929	struct mtk_afe_i2s_priv *i2s_priv = afe_priv->dai_priv[i2s_id];930 931	unsigned int rate = params_rate(params);932	unsigned int rate_reg = mt8186_rate_transform(afe->dev,933						      rate, i2s_id);934	snd_pcm_format_t format = params_format(params);935	unsigned int i2s_con = 0;936	int ret;937 938	dev_dbg(afe->dev, "%s(), id %d, rate %d, format %d\n",939		__func__, i2s_id, rate, format);940 941	i2s_priv->rate = rate;942 943	switch (i2s_id) {944	case MT8186_DAI_I2S_0:945		i2s_con = I2S_IN_PAD_IO_MUX << I2SIN_PAD_SEL_SFT;946		i2s_con |= rate_reg << I2S_OUT_MODE_SFT;947		i2s_con |= I2S_FMT_I2S << I2S_FMT_SFT;948		i2s_con |= get_i2s_wlen(format) << I2S_WLEN_SFT;949		regmap_update_bits(afe->regmap, AFE_I2S_CON,950				   0xffffeffa, i2s_con);951		break;952	case MT8186_DAI_I2S_1:953		i2s_con = I2S1_SEL_O28_O29 << I2S2_SEL_O03_O04_SFT;954		i2s_con |= rate_reg << I2S2_OUT_MODE_SFT;955		i2s_con |= I2S_FMT_I2S << I2S2_FMT_SFT;956		i2s_con |= get_i2s_wlen(format) << I2S2_WLEN_SFT;957		regmap_update_bits(afe->regmap, AFE_I2S_CON1,958				   0xffffeffa, i2s_con);959		break;960	case MT8186_DAI_I2S_2:961		i2s_con = 8 << I2S3_UPDATE_WORD_SFT;962		i2s_con |= rate_reg << I2S3_OUT_MODE_SFT;963		i2s_con |= I2S_FMT_I2S << I2S3_FMT_SFT;964		i2s_con |= get_i2s_wlen(format) << I2S3_WLEN_SFT;965		regmap_update_bits(afe->regmap, AFE_I2S_CON2,966				   0xffffeffa, i2s_con);967		break;968	case MT8186_DAI_I2S_3:969		i2s_con = rate_reg << I2S4_OUT_MODE_SFT;970		i2s_con |= I2S_FMT_I2S << I2S4_FMT_SFT;971		i2s_con |= get_i2s_wlen(format) << I2S4_WLEN_SFT;972		regmap_update_bits(afe->regmap, AFE_I2S_CON3,973				   0xffffeffa, i2s_con);974		break;975	default:976		dev_err(afe->dev, "%s(), id %d not support\n",977			__func__, i2s_id);978		return -EINVAL;979	}980 981	/* set share i2s */982	if (i2s_priv->share_i2s_id >= 0) {983		ret = mtk_dai_i2s_config(afe, params, i2s_priv->share_i2s_id);984		if (ret)985			return ret;986	}987 988	return 0;989}990 991static int mtk_dai_i2s_hw_params(struct snd_pcm_substream *substream,992				 struct snd_pcm_hw_params *params,993				 struct snd_soc_dai *dai)994{995	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);996 997	return mtk_dai_i2s_config(afe, params, dai->id);998}999 1000static int mtk_dai_i2s_set_sysclk(struct snd_soc_dai *dai,1001				  int clk_id, unsigned int freq, int dir)1002{1003	struct mtk_base_afe *afe = dev_get_drvdata(dai->dev);1004	struct mt8186_afe_private *afe_priv = afe->platform_priv;1005	struct mtk_afe_i2s_priv *i2s_priv = afe_priv->dai_priv[dai->id];1006	int apll;1007	int apll_rate;1008 1009	if (dir != SND_SOC_CLOCK_OUT) {1010		dev_err(afe->dev, "%s(), dir != SND_SOC_CLOCK_OUT", __func__);1011		return -EINVAL;1012	}1013 1014	dev_dbg(afe->dev, "%s(), freq %d\n", __func__, freq);1015 1016	apll = mt8186_get_apll_by_rate(afe, freq);1017	apll_rate = mt8186_get_apll_rate(afe, apll);1018 1019	if (freq > apll_rate) {1020		dev_err(afe->dev, "%s(), freq > apll rate", __func__);1021		return -EINVAL;1022	}1023 1024	if (apll_rate % freq != 0) {1025		dev_err(afe->dev, "%s(), APLL cannot generate freq Hz", __func__);1026		return -EINVAL;1027	}1028 1029	i2s_priv->mclk_rate = freq;1030	i2s_priv->mclk_apll = apll;1031 1032	if (i2s_priv->share_i2s_id > 0) {1033		struct mtk_afe_i2s_priv *share_i2s_priv;1034 1035		share_i2s_priv = afe_priv->dai_priv[i2s_priv->share_i2s_id];1036		if (!share_i2s_priv) {1037			dev_err(afe->dev, "%s(), share_i2s_priv == NULL", __func__);1038			return -EINVAL;1039		}1040 1041		share_i2s_priv->mclk_rate = i2s_priv->mclk_rate;1042		share_i2s_priv->mclk_apll = i2s_priv->mclk_apll;1043	}1044 1045	return 0;1046}1047 1048static const struct snd_soc_dai_ops mtk_dai_i2s_ops = {1049	.hw_params = mtk_dai_i2s_hw_params,1050	.set_sysclk = mtk_dai_i2s_set_sysclk,1051};1052 1053/* dai driver */1054#define MTK_CONNSYS_I2S_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000)1055 1056#define MTK_I2S_RATES (SNDRV_PCM_RATE_8000_48000 |\1057		       SNDRV_PCM_RATE_88200 |\1058		       SNDRV_PCM_RATE_96000 |\1059		       SNDRV_PCM_RATE_176400 |\1060		       SNDRV_PCM_RATE_192000)1061 1062#define MTK_I2S_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\1063			 SNDRV_PCM_FMTBIT_S24_LE |\1064			 SNDRV_PCM_FMTBIT_S32_LE)1065 1066static struct snd_soc_dai_driver mtk_dai_i2s_driver[] = {1067	{1068		.name = "CONNSYS_I2S",1069		.id = MT8186_DAI_CONNSYS_I2S,1070		.capture = {1071			.stream_name = "Connsys I2S",1072			.channels_min = 1,1073			.channels_max = 2,1074			.rates = MTK_CONNSYS_I2S_RATES,1075			.formats = MTK_I2S_FORMATS,1076		},1077		.ops = &mtk_dai_connsys_i2s_ops,1078	},1079	{1080		.name = "I2S0",1081		.id = MT8186_DAI_I2S_0,1082		.capture = {1083			.stream_name = "I2S0",1084			.channels_min = 1,1085			.channels_max = 2,1086			.rates = MTK_I2S_RATES,1087			.formats = MTK_I2S_FORMATS,1088		},1089		.ops = &mtk_dai_i2s_ops,1090	},1091	{1092		.name = "I2S1",1093		.id = MT8186_DAI_I2S_1,1094		.playback = {1095			.stream_name = "I2S1",1096			.channels_min = 1,1097			.channels_max = 2,1098			.rates = MTK_I2S_RATES,1099			.formats = MTK_I2S_FORMATS,1100		},1101		.ops = &mtk_dai_i2s_ops,1102	},1103	{1104		.name = "I2S2",1105		.id = MT8186_DAI_I2S_2,1106		.capture = {1107			.stream_name = "I2S2",1108			.channels_min = 1,1109			.channels_max = 2,1110			.rates = MTK_I2S_RATES,1111			.formats = MTK_I2S_FORMATS,1112		},1113		.ops = &mtk_dai_i2s_ops,1114	},1115	{1116		.name = "I2S3",1117		.id = MT8186_DAI_I2S_3,1118		.playback = {1119			.stream_name = "I2S3",1120			.channels_min = 1,1121			.channels_max = 2,1122			.rates = MTK_I2S_RATES,1123			.formats = MTK_I2S_FORMATS,1124		},1125		.ops = &mtk_dai_i2s_ops,1126	}1127};1128 1129/* this enum is merely for mtk_afe_i2s_priv declare */1130enum {1131	DAI_I2S0 = 0,1132	DAI_I2S1,1133	DAI_I2S2,1134	DAI_I2S3,1135	DAI_I2S_NUM,1136};1137 1138static const struct mtk_afe_i2s_priv mt8186_i2s_priv[DAI_I2S_NUM] = {1139	[DAI_I2S0] = {1140		.id = MT8186_DAI_I2S_0,1141		.mclk_id = MT8186_I2S0_MCK,1142		.share_i2s_id = -1,1143	},1144	[DAI_I2S1] = {1145		.id = MT8186_DAI_I2S_1,1146		.mclk_id = MT8186_I2S1_MCK,1147		.share_i2s_id = -1,1148	},1149	[DAI_I2S2] = {1150		.id = MT8186_DAI_I2S_2,1151		.mclk_id = MT8186_I2S2_MCK,1152		.share_i2s_id = -1,1153	},1154	[DAI_I2S3] = {1155		.id = MT8186_DAI_I2S_3,1156		/*  clock gate naming is hf_faud_i2s4_m_ck*/1157		.mclk_id = MT8186_I2S4_MCK,1158		.share_i2s_id = -1,1159	}1160};1161 1162/**1163 * mt8186_dai_i2s_set_share() - Set up I2S ports to share a single clock.1164 * @afe: Pointer to &struct mtk_base_afe1165 * @main_i2s_name: The name of the I2S port that will provide the clock1166 * @secondary_i2s_name: The name of the I2S port that will use this clock1167 */1168int mt8186_dai_i2s_set_share(struct mtk_base_afe *afe, const char *main_i2s_name,1169			     const char *secondary_i2s_name)1170{1171	struct mtk_afe_i2s_priv *secondary_i2s_priv;1172	int main_i2s_id;1173 1174	secondary_i2s_priv = get_i2s_priv_by_name(afe, secondary_i2s_name);1175	if (!secondary_i2s_priv)1176		return -EINVAL;1177 1178	main_i2s_id = get_i2s_id_by_name(afe, main_i2s_name);1179	if (main_i2s_id < 0)1180		return main_i2s_id;1181 1182	secondary_i2s_priv->share_i2s_id = main_i2s_id;1183 1184	return 0;1185}1186EXPORT_SYMBOL_GPL(mt8186_dai_i2s_set_share);1187 1188static int mt8186_dai_i2s_set_priv(struct mtk_base_afe *afe)1189{1190	int i;1191	int ret;1192 1193	for (i = 0; i < DAI_I2S_NUM; i++) {1194		ret = mt8186_dai_set_priv(afe, mt8186_i2s_priv[i].id,1195					  sizeof(struct mtk_afe_i2s_priv),1196					  &mt8186_i2s_priv[i]);1197		if (ret)1198			return ret;1199	}1200 1201	return 0;1202}1203 1204int mt8186_dai_i2s_register(struct mtk_base_afe *afe)1205{1206	struct mtk_base_afe_dai *dai;1207	int ret;1208 1209	dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL);1210	if (!dai)1211		return -ENOMEM;1212 1213	list_add(&dai->list, &afe->sub_dais);1214 1215	dai->dai_drivers = mtk_dai_i2s_driver;1216	dai->num_dai_drivers = ARRAY_SIZE(mtk_dai_i2s_driver);1217 1218	dai->controls = mtk_dai_i2s_controls;1219	dai->num_controls = ARRAY_SIZE(mtk_dai_i2s_controls);1220	dai->dapm_widgets = mtk_dai_i2s_widgets;1221	dai->num_dapm_widgets = ARRAY_SIZE(mtk_dai_i2s_widgets);1222	dai->dapm_routes = mtk_dai_i2s_routes;1223	dai->num_dapm_routes = ARRAY_SIZE(mtk_dai_i2s_routes);1224 1225	/* set all dai i2s private data */1226	ret = mt8186_dai_i2s_set_priv(afe);1227	if (ret)1228		return ret;1229 1230	return 0;1231}1232