xref: /linux/sound/soc/mediatek/mt6797/mt6797-dai-adda.c (revision 42a589e8339517f9dc4e4184f5345d6965331c9c)
1*42a589e8SKaiChieh Chuang // SPDX-License-Identifier: GPL-2.0
2*42a589e8SKaiChieh Chuang //
3*42a589e8SKaiChieh Chuang // MediaTek ALSA SoC Audio DAI ADDA Control
4*42a589e8SKaiChieh Chuang //
5*42a589e8SKaiChieh Chuang // Copyright (c) 2018 MediaTek Inc.
6*42a589e8SKaiChieh Chuang // Author: KaiChieh Chuang <kaichieh.chuang@mediatek.com>
7*42a589e8SKaiChieh Chuang 
8*42a589e8SKaiChieh Chuang #include <linux/regmap.h>
9*42a589e8SKaiChieh Chuang #include <linux/delay.h>
10*42a589e8SKaiChieh Chuang #include "mt6797-afe-common.h"
11*42a589e8SKaiChieh Chuang #include "mt6797-interconnection.h"
12*42a589e8SKaiChieh Chuang #include "mt6797-reg.h"
13*42a589e8SKaiChieh Chuang 
14*42a589e8SKaiChieh Chuang enum {
15*42a589e8SKaiChieh Chuang 	MTK_AFE_ADDA_DL_RATE_8K = 0,
16*42a589e8SKaiChieh Chuang 	MTK_AFE_ADDA_DL_RATE_11K = 1,
17*42a589e8SKaiChieh Chuang 	MTK_AFE_ADDA_DL_RATE_12K = 2,
18*42a589e8SKaiChieh Chuang 	MTK_AFE_ADDA_DL_RATE_16K = 3,
19*42a589e8SKaiChieh Chuang 	MTK_AFE_ADDA_DL_RATE_22K = 4,
20*42a589e8SKaiChieh Chuang 	MTK_AFE_ADDA_DL_RATE_24K = 5,
21*42a589e8SKaiChieh Chuang 	MTK_AFE_ADDA_DL_RATE_32K = 6,
22*42a589e8SKaiChieh Chuang 	MTK_AFE_ADDA_DL_RATE_44K = 7,
23*42a589e8SKaiChieh Chuang 	MTK_AFE_ADDA_DL_RATE_48K = 8,
24*42a589e8SKaiChieh Chuang 	MTK_AFE_ADDA_DL_RATE_96K = 9,
25*42a589e8SKaiChieh Chuang 	MTK_AFE_ADDA_DL_RATE_192K = 10,
26*42a589e8SKaiChieh Chuang };
27*42a589e8SKaiChieh Chuang 
28*42a589e8SKaiChieh Chuang enum {
29*42a589e8SKaiChieh Chuang 	MTK_AFE_ADDA_UL_RATE_8K = 0,
30*42a589e8SKaiChieh Chuang 	MTK_AFE_ADDA_UL_RATE_16K = 1,
31*42a589e8SKaiChieh Chuang 	MTK_AFE_ADDA_UL_RATE_32K = 2,
32*42a589e8SKaiChieh Chuang 	MTK_AFE_ADDA_UL_RATE_48K = 3,
33*42a589e8SKaiChieh Chuang 	MTK_AFE_ADDA_UL_RATE_96K = 4,
34*42a589e8SKaiChieh Chuang 	MTK_AFE_ADDA_UL_RATE_192K = 5,
35*42a589e8SKaiChieh Chuang 	MTK_AFE_ADDA_UL_RATE_48K_HD = 6,
36*42a589e8SKaiChieh Chuang };
37*42a589e8SKaiChieh Chuang 
38*42a589e8SKaiChieh Chuang static unsigned int adda_dl_rate_transform(struct mtk_base_afe *afe,
39*42a589e8SKaiChieh Chuang 					   unsigned int rate)
40*42a589e8SKaiChieh Chuang {
41*42a589e8SKaiChieh Chuang 	switch (rate) {
42*42a589e8SKaiChieh Chuang 	case 8000:
43*42a589e8SKaiChieh Chuang 		return MTK_AFE_ADDA_DL_RATE_8K;
44*42a589e8SKaiChieh Chuang 	case 11025:
45*42a589e8SKaiChieh Chuang 		return MTK_AFE_ADDA_DL_RATE_11K;
46*42a589e8SKaiChieh Chuang 	case 12000:
47*42a589e8SKaiChieh Chuang 		return MTK_AFE_ADDA_DL_RATE_12K;
48*42a589e8SKaiChieh Chuang 	case 16000:
49*42a589e8SKaiChieh Chuang 		return MTK_AFE_ADDA_DL_RATE_16K;
50*42a589e8SKaiChieh Chuang 	case 22050:
51*42a589e8SKaiChieh Chuang 		return MTK_AFE_ADDA_DL_RATE_22K;
52*42a589e8SKaiChieh Chuang 	case 24000:
53*42a589e8SKaiChieh Chuang 		return MTK_AFE_ADDA_DL_RATE_24K;
54*42a589e8SKaiChieh Chuang 	case 32000:
55*42a589e8SKaiChieh Chuang 		return MTK_AFE_ADDA_DL_RATE_32K;
56*42a589e8SKaiChieh Chuang 	case 44100:
57*42a589e8SKaiChieh Chuang 		return MTK_AFE_ADDA_DL_RATE_44K;
58*42a589e8SKaiChieh Chuang 	case 48000:
59*42a589e8SKaiChieh Chuang 		return MTK_AFE_ADDA_DL_RATE_48K;
60*42a589e8SKaiChieh Chuang 	case 96000:
61*42a589e8SKaiChieh Chuang 		return MTK_AFE_ADDA_DL_RATE_96K;
62*42a589e8SKaiChieh Chuang 	case 192000:
63*42a589e8SKaiChieh Chuang 		return MTK_AFE_ADDA_DL_RATE_192K;
64*42a589e8SKaiChieh Chuang 	default:
65*42a589e8SKaiChieh Chuang 		dev_warn(afe->dev, "%s(), rate %d invalid, use 48kHz!!!\n",
66*42a589e8SKaiChieh Chuang 			 __func__, rate);
67*42a589e8SKaiChieh Chuang 		return MTK_AFE_ADDA_DL_RATE_48K;
68*42a589e8SKaiChieh Chuang 	}
69*42a589e8SKaiChieh Chuang }
70*42a589e8SKaiChieh Chuang 
71*42a589e8SKaiChieh Chuang static unsigned int adda_ul_rate_transform(struct mtk_base_afe *afe,
72*42a589e8SKaiChieh Chuang 					   unsigned int rate)
73*42a589e8SKaiChieh Chuang {
74*42a589e8SKaiChieh Chuang 	switch (rate) {
75*42a589e8SKaiChieh Chuang 	case 8000:
76*42a589e8SKaiChieh Chuang 		return MTK_AFE_ADDA_UL_RATE_8K;
77*42a589e8SKaiChieh Chuang 	case 16000:
78*42a589e8SKaiChieh Chuang 		return MTK_AFE_ADDA_UL_RATE_16K;
79*42a589e8SKaiChieh Chuang 	case 32000:
80*42a589e8SKaiChieh Chuang 		return MTK_AFE_ADDA_UL_RATE_32K;
81*42a589e8SKaiChieh Chuang 	case 48000:
82*42a589e8SKaiChieh Chuang 		return MTK_AFE_ADDA_UL_RATE_48K;
83*42a589e8SKaiChieh Chuang 	case 96000:
84*42a589e8SKaiChieh Chuang 		return MTK_AFE_ADDA_UL_RATE_96K;
85*42a589e8SKaiChieh Chuang 	case 192000:
86*42a589e8SKaiChieh Chuang 		return MTK_AFE_ADDA_UL_RATE_192K;
87*42a589e8SKaiChieh Chuang 	default:
88*42a589e8SKaiChieh Chuang 		dev_warn(afe->dev, "%s(), rate %d invalid, use 48kHz!!!\n",
89*42a589e8SKaiChieh Chuang 			 __func__, rate);
90*42a589e8SKaiChieh Chuang 		return MTK_AFE_ADDA_UL_RATE_48K;
91*42a589e8SKaiChieh Chuang 	}
92*42a589e8SKaiChieh Chuang }
93*42a589e8SKaiChieh Chuang 
94*42a589e8SKaiChieh Chuang /* dai component */
95*42a589e8SKaiChieh Chuang static const struct snd_kcontrol_new mtk_adda_dl_ch1_mix[] = {
96*42a589e8SKaiChieh Chuang 	SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1", AFE_CONN3, I_DL1_CH1, 1, 0),
97*42a589e8SKaiChieh Chuang 	SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1", AFE_CONN3, I_DL2_CH1, 1, 0),
98*42a589e8SKaiChieh Chuang 	SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1", AFE_CONN3, I_DL3_CH1, 1, 0),
99*42a589e8SKaiChieh Chuang 	SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN3,
100*42a589e8SKaiChieh Chuang 				    I_ADDA_UL_CH2, 1, 0),
101*42a589e8SKaiChieh Chuang 	SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN3,
102*42a589e8SKaiChieh Chuang 				    I_ADDA_UL_CH1, 1, 0),
103*42a589e8SKaiChieh Chuang };
104*42a589e8SKaiChieh Chuang 
105*42a589e8SKaiChieh Chuang static const struct snd_kcontrol_new mtk_adda_dl_ch2_mix[] = {
106*42a589e8SKaiChieh Chuang 	SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1", AFE_CONN4, I_DL1_CH1, 1, 0),
107*42a589e8SKaiChieh Chuang 	SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH2", AFE_CONN4, I_DL1_CH2, 1, 0),
108*42a589e8SKaiChieh Chuang 	SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1", AFE_CONN4, I_DL2_CH1, 1, 0),
109*42a589e8SKaiChieh Chuang 	SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH2", AFE_CONN4, I_DL2_CH2, 1, 0),
110*42a589e8SKaiChieh Chuang 	SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1", AFE_CONN4, I_DL3_CH1, 1, 0),
111*42a589e8SKaiChieh Chuang 	SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH2", AFE_CONN4, I_DL3_CH2, 1, 0),
112*42a589e8SKaiChieh Chuang 	SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN4,
113*42a589e8SKaiChieh Chuang 				    I_ADDA_UL_CH2, 1, 0),
114*42a589e8SKaiChieh Chuang 	SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN4,
115*42a589e8SKaiChieh Chuang 				    I_ADDA_UL_CH1, 1, 0),
116*42a589e8SKaiChieh Chuang };
117*42a589e8SKaiChieh Chuang 
118*42a589e8SKaiChieh Chuang static int mtk_adda_ul_event(struct snd_soc_dapm_widget *w,
119*42a589e8SKaiChieh Chuang 			     struct snd_kcontrol *kcontrol,
120*42a589e8SKaiChieh Chuang 			     int event)
121*42a589e8SKaiChieh Chuang {
122*42a589e8SKaiChieh Chuang 	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
123*42a589e8SKaiChieh Chuang 	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
124*42a589e8SKaiChieh Chuang 
125*42a589e8SKaiChieh Chuang 	dev_dbg(afe->dev, "%s(), name %s, event 0x%x\n",
126*42a589e8SKaiChieh Chuang 		__func__, w->name, event);
127*42a589e8SKaiChieh Chuang 
128*42a589e8SKaiChieh Chuang 	switch (event) {
129*42a589e8SKaiChieh Chuang 	case SND_SOC_DAPM_POST_PMD:
130*42a589e8SKaiChieh Chuang 		/* should delayed 1/fs(smallest is 8k) = 125us before afe off */
131*42a589e8SKaiChieh Chuang 		usleep_range(125, 135);
132*42a589e8SKaiChieh Chuang 		break;
133*42a589e8SKaiChieh Chuang 	default:
134*42a589e8SKaiChieh Chuang 		break;
135*42a589e8SKaiChieh Chuang 	}
136*42a589e8SKaiChieh Chuang 
137*42a589e8SKaiChieh Chuang 	return 0;
138*42a589e8SKaiChieh Chuang }
139*42a589e8SKaiChieh Chuang 
140*42a589e8SKaiChieh Chuang enum {
141*42a589e8SKaiChieh Chuang 	SUPPLY_SEQ_AUD_TOP_PDN,
142*42a589e8SKaiChieh Chuang 	SUPPLY_SEQ_ADDA_AFE_ON,
143*42a589e8SKaiChieh Chuang 	SUPPLY_SEQ_ADDA_DL_ON,
144*42a589e8SKaiChieh Chuang 	SUPPLY_SEQ_ADDA_UL_ON,
145*42a589e8SKaiChieh Chuang };
146*42a589e8SKaiChieh Chuang 
147*42a589e8SKaiChieh Chuang static const struct snd_soc_dapm_widget mtk_dai_adda_widgets[] = {
148*42a589e8SKaiChieh Chuang 	/* adda */
149*42a589e8SKaiChieh Chuang 	SND_SOC_DAPM_MIXER("ADDA_DL_CH1", SND_SOC_NOPM, 0, 0,
150*42a589e8SKaiChieh Chuang 			   mtk_adda_dl_ch1_mix,
151*42a589e8SKaiChieh Chuang 			   ARRAY_SIZE(mtk_adda_dl_ch1_mix)),
152*42a589e8SKaiChieh Chuang 	SND_SOC_DAPM_MIXER("ADDA_DL_CH2", SND_SOC_NOPM, 0, 0,
153*42a589e8SKaiChieh Chuang 			   mtk_adda_dl_ch2_mix,
154*42a589e8SKaiChieh Chuang 			   ARRAY_SIZE(mtk_adda_dl_ch2_mix)),
155*42a589e8SKaiChieh Chuang 
156*42a589e8SKaiChieh Chuang 	SND_SOC_DAPM_SUPPLY_S("ADDA Enable", SUPPLY_SEQ_ADDA_AFE_ON,
157*42a589e8SKaiChieh Chuang 			      AFE_ADDA_UL_DL_CON0, ADDA_AFE_ON_SFT, 0,
158*42a589e8SKaiChieh Chuang 			      NULL, 0),
159*42a589e8SKaiChieh Chuang 
160*42a589e8SKaiChieh Chuang 	SND_SOC_DAPM_SUPPLY_S("ADDA Playback Enable", SUPPLY_SEQ_ADDA_DL_ON,
161*42a589e8SKaiChieh Chuang 			      AFE_ADDA_DL_SRC2_CON0,
162*42a589e8SKaiChieh Chuang 			      DL_2_SRC_ON_TMP_CTL_PRE_SFT, 0,
163*42a589e8SKaiChieh Chuang 			      NULL, 0),
164*42a589e8SKaiChieh Chuang 
165*42a589e8SKaiChieh Chuang 	SND_SOC_DAPM_SUPPLY_S("ADDA Capture Enable", SUPPLY_SEQ_ADDA_UL_ON,
166*42a589e8SKaiChieh Chuang 			      AFE_ADDA_UL_SRC_CON0,
167*42a589e8SKaiChieh Chuang 			      UL_SRC_ON_TMP_CTL_SFT, 0,
168*42a589e8SKaiChieh Chuang 			      mtk_adda_ul_event,
169*42a589e8SKaiChieh Chuang 			      SND_SOC_DAPM_POST_PMD),
170*42a589e8SKaiChieh Chuang 
171*42a589e8SKaiChieh Chuang 	SND_SOC_DAPM_SUPPLY_S("aud_dac_clk", SUPPLY_SEQ_AUD_TOP_PDN,
172*42a589e8SKaiChieh Chuang 			      AUDIO_TOP_CON0, PDN_DAC_SFT, 1,
173*42a589e8SKaiChieh Chuang 			      NULL, 0),
174*42a589e8SKaiChieh Chuang 	SND_SOC_DAPM_SUPPLY_S("aud_dac_predis_clk", SUPPLY_SEQ_AUD_TOP_PDN,
175*42a589e8SKaiChieh Chuang 			      AUDIO_TOP_CON0, PDN_DAC_PREDIS_SFT, 1,
176*42a589e8SKaiChieh Chuang 			      NULL, 0),
177*42a589e8SKaiChieh Chuang 
178*42a589e8SKaiChieh Chuang 	SND_SOC_DAPM_SUPPLY_S("aud_adc_clk", SUPPLY_SEQ_AUD_TOP_PDN,
179*42a589e8SKaiChieh Chuang 			      AUDIO_TOP_CON0, PDN_ADC_SFT, 1,
180*42a589e8SKaiChieh Chuang 			      NULL, 0),
181*42a589e8SKaiChieh Chuang 
182*42a589e8SKaiChieh Chuang 	SND_SOC_DAPM_CLOCK_SUPPLY("mtkaif_26m_clk"),
183*42a589e8SKaiChieh Chuang };
184*42a589e8SKaiChieh Chuang 
185*42a589e8SKaiChieh Chuang static const struct snd_soc_dapm_route mtk_dai_adda_routes[] = {
186*42a589e8SKaiChieh Chuang 	/* playback */
187*42a589e8SKaiChieh Chuang 	{"ADDA_DL_CH1", "DL1_CH1", "DL1"},
188*42a589e8SKaiChieh Chuang 	{"ADDA_DL_CH2", "DL1_CH1", "DL1"},
189*42a589e8SKaiChieh Chuang 	{"ADDA_DL_CH2", "DL1_CH2", "DL1"},
190*42a589e8SKaiChieh Chuang 
191*42a589e8SKaiChieh Chuang 	{"ADDA_DL_CH1", "DL2_CH1", "DL2"},
192*42a589e8SKaiChieh Chuang 	{"ADDA_DL_CH2", "DL2_CH1", "DL2"},
193*42a589e8SKaiChieh Chuang 	{"ADDA_DL_CH2", "DL2_CH2", "DL2"},
194*42a589e8SKaiChieh Chuang 
195*42a589e8SKaiChieh Chuang 	{"ADDA_DL_CH1", "DL3_CH1", "DL3"},
196*42a589e8SKaiChieh Chuang 	{"ADDA_DL_CH2", "DL3_CH1", "DL3"},
197*42a589e8SKaiChieh Chuang 	{"ADDA_DL_CH2", "DL3_CH2", "DL3"},
198*42a589e8SKaiChieh Chuang 
199*42a589e8SKaiChieh Chuang 	{"ADDA Playback", NULL, "ADDA_DL_CH1"},
200*42a589e8SKaiChieh Chuang 	{"ADDA Playback", NULL, "ADDA_DL_CH2"},
201*42a589e8SKaiChieh Chuang 
202*42a589e8SKaiChieh Chuang 	/* adda enable */
203*42a589e8SKaiChieh Chuang 	{"ADDA Playback", NULL, "ADDA Enable"},
204*42a589e8SKaiChieh Chuang 	{"ADDA Playback", NULL, "ADDA Playback Enable"},
205*42a589e8SKaiChieh Chuang 	{"ADDA Capture", NULL, "ADDA Enable"},
206*42a589e8SKaiChieh Chuang 	{"ADDA Capture", NULL, "ADDA Capture Enable"},
207*42a589e8SKaiChieh Chuang 
208*42a589e8SKaiChieh Chuang 	/* clk */
209*42a589e8SKaiChieh Chuang 	{"ADDA Playback", NULL, "mtkaif_26m_clk"},
210*42a589e8SKaiChieh Chuang 	{"ADDA Playback", NULL, "aud_dac_clk"},
211*42a589e8SKaiChieh Chuang 	{"ADDA Playback", NULL, "aud_dac_predis_clk"},
212*42a589e8SKaiChieh Chuang 
213*42a589e8SKaiChieh Chuang 	{"ADDA Capture", NULL, "mtkaif_26m_clk"},
214*42a589e8SKaiChieh Chuang 	{"ADDA Capture", NULL, "aud_adc_clk"},
215*42a589e8SKaiChieh Chuang };
216*42a589e8SKaiChieh Chuang 
217*42a589e8SKaiChieh Chuang /* dai ops */
218*42a589e8SKaiChieh Chuang static int mtk_dai_adda_hw_params(struct snd_pcm_substream *substream,
219*42a589e8SKaiChieh Chuang 				  struct snd_pcm_hw_params *params,
220*42a589e8SKaiChieh Chuang 				  struct snd_soc_dai *dai)
221*42a589e8SKaiChieh Chuang {
222*42a589e8SKaiChieh Chuang 	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
223*42a589e8SKaiChieh Chuang 	unsigned int rate = params_rate(params);
224*42a589e8SKaiChieh Chuang 
225*42a589e8SKaiChieh Chuang 	dev_dbg(afe->dev, "%s(), id %d, stream %d, rate %d\n",
226*42a589e8SKaiChieh Chuang 		__func__, dai->id, substream->stream, rate);
227*42a589e8SKaiChieh Chuang 
228*42a589e8SKaiChieh Chuang 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
229*42a589e8SKaiChieh Chuang 		unsigned int dl_src2_con0 = 0;
230*42a589e8SKaiChieh Chuang 		unsigned int dl_src2_con1 = 0;
231*42a589e8SKaiChieh Chuang 
232*42a589e8SKaiChieh Chuang 		/* clean predistortion */
233*42a589e8SKaiChieh Chuang 		regmap_write(afe->regmap, AFE_ADDA_PREDIS_CON0, 0);
234*42a589e8SKaiChieh Chuang 		regmap_write(afe->regmap, AFE_ADDA_PREDIS_CON1, 0);
235*42a589e8SKaiChieh Chuang 
236*42a589e8SKaiChieh Chuang 		/* set input sampling rate */
237*42a589e8SKaiChieh Chuang 		dl_src2_con0 = adda_dl_rate_transform(afe, rate) << 28;
238*42a589e8SKaiChieh Chuang 
239*42a589e8SKaiChieh Chuang 		/* set output mode */
240*42a589e8SKaiChieh Chuang 		switch (rate) {
241*42a589e8SKaiChieh Chuang 		case 192000:
242*42a589e8SKaiChieh Chuang 			dl_src2_con0 |= (0x1 << 24); /* UP_SAMPLING_RATE_X2 */
243*42a589e8SKaiChieh Chuang 			dl_src2_con0 |= 1 << 14;
244*42a589e8SKaiChieh Chuang 			break;
245*42a589e8SKaiChieh Chuang 		case 96000:
246*42a589e8SKaiChieh Chuang 			dl_src2_con0 |= (0x2 << 24); /* UP_SAMPLING_RATE_X4 */
247*42a589e8SKaiChieh Chuang 			dl_src2_con0 |= 1 << 14;
248*42a589e8SKaiChieh Chuang 			break;
249*42a589e8SKaiChieh Chuang 		default:
250*42a589e8SKaiChieh Chuang 			dl_src2_con0 |= (0x3 << 24); /* UP_SAMPLING_RATE_X8 */
251*42a589e8SKaiChieh Chuang 			break;
252*42a589e8SKaiChieh Chuang 		}
253*42a589e8SKaiChieh Chuang 
254*42a589e8SKaiChieh Chuang 		/* turn off mute function */
255*42a589e8SKaiChieh Chuang 		dl_src2_con0 |= (0x03 << 11);
256*42a589e8SKaiChieh Chuang 
257*42a589e8SKaiChieh Chuang 		/* set voice input data if input sample rate is 8k or 16k */
258*42a589e8SKaiChieh Chuang 		if (rate == 8000 || rate == 16000)
259*42a589e8SKaiChieh Chuang 			dl_src2_con0 |= 0x01 << 5;
260*42a589e8SKaiChieh Chuang 
261*42a589e8SKaiChieh Chuang 		if (rate < 96000) {
262*42a589e8SKaiChieh Chuang 			/* SA suggest apply -0.3db to audio/speech path */
263*42a589e8SKaiChieh Chuang 			dl_src2_con1 = 0xf74f0000;
264*42a589e8SKaiChieh Chuang 		} else {
265*42a589e8SKaiChieh Chuang 			/* SA suggest apply -0.3db to audio/speech path
266*42a589e8SKaiChieh Chuang 			 * with DL gain set to half,
267*42a589e8SKaiChieh Chuang 			 * 0xFFFF = 0dB -> 0x8000 = 0dB when 96k, 192k
268*42a589e8SKaiChieh Chuang 			 */
269*42a589e8SKaiChieh Chuang 			dl_src2_con1 = 0x7ba70000;
270*42a589e8SKaiChieh Chuang 		}
271*42a589e8SKaiChieh Chuang 
272*42a589e8SKaiChieh Chuang 		/* turn on down-link gain */
273*42a589e8SKaiChieh Chuang 		dl_src2_con0 = dl_src2_con0 | (0x01 << 1);
274*42a589e8SKaiChieh Chuang 
275*42a589e8SKaiChieh Chuang 		regmap_write(afe->regmap, AFE_ADDA_DL_SRC2_CON0, dl_src2_con0);
276*42a589e8SKaiChieh Chuang 		regmap_write(afe->regmap, AFE_ADDA_DL_SRC2_CON1, dl_src2_con1);
277*42a589e8SKaiChieh Chuang 	} else {
278*42a589e8SKaiChieh Chuang 		unsigned int voice_mode = 0;
279*42a589e8SKaiChieh Chuang 		unsigned int ul_src_con0 = 0;	/* default value */
280*42a589e8SKaiChieh Chuang 
281*42a589e8SKaiChieh Chuang 		/* Using Internal ADC */
282*42a589e8SKaiChieh Chuang 		regmap_update_bits(afe->regmap,
283*42a589e8SKaiChieh Chuang 				   AFE_ADDA_TOP_CON0,
284*42a589e8SKaiChieh Chuang 				   0x1 << 0,
285*42a589e8SKaiChieh Chuang 				   0x0 << 0);
286*42a589e8SKaiChieh Chuang 
287*42a589e8SKaiChieh Chuang 		voice_mode = adda_ul_rate_transform(afe, rate);
288*42a589e8SKaiChieh Chuang 
289*42a589e8SKaiChieh Chuang 		ul_src_con0 |= (voice_mode << 17) & (0x7 << 17);
290*42a589e8SKaiChieh Chuang 
291*42a589e8SKaiChieh Chuang 		/* up8x txif sat on */
292*42a589e8SKaiChieh Chuang 		regmap_write(afe->regmap, AFE_ADDA_NEWIF_CFG0, 0x03F87201);
293*42a589e8SKaiChieh Chuang 
294*42a589e8SKaiChieh Chuang 		if (rate >= 96000) {	/* hires */
295*42a589e8SKaiChieh Chuang 			/* use hires format [1 0 23] */
296*42a589e8SKaiChieh Chuang 			regmap_update_bits(afe->regmap,
297*42a589e8SKaiChieh Chuang 					   AFE_ADDA_NEWIF_CFG0,
298*42a589e8SKaiChieh Chuang 					   0x1 << 5,
299*42a589e8SKaiChieh Chuang 					   0x1 << 5);
300*42a589e8SKaiChieh Chuang 
301*42a589e8SKaiChieh Chuang 			regmap_update_bits(afe->regmap,
302*42a589e8SKaiChieh Chuang 					   AFE_ADDA_NEWIF_CFG2,
303*42a589e8SKaiChieh Chuang 					   0xf << 28,
304*42a589e8SKaiChieh Chuang 					   voice_mode << 28);
305*42a589e8SKaiChieh Chuang 		} else {	/* normal 8~48k */
306*42a589e8SKaiChieh Chuang 			/* use fixed 260k anc path */
307*42a589e8SKaiChieh Chuang 			regmap_update_bits(afe->regmap,
308*42a589e8SKaiChieh Chuang 					   AFE_ADDA_NEWIF_CFG2,
309*42a589e8SKaiChieh Chuang 					   0xf << 28,
310*42a589e8SKaiChieh Chuang 					   8 << 28);
311*42a589e8SKaiChieh Chuang 
312*42a589e8SKaiChieh Chuang 			/* ul_use_cic_out */
313*42a589e8SKaiChieh Chuang 			ul_src_con0 |= 0x1 << 20;
314*42a589e8SKaiChieh Chuang 		}
315*42a589e8SKaiChieh Chuang 
316*42a589e8SKaiChieh Chuang 		regmap_update_bits(afe->regmap,
317*42a589e8SKaiChieh Chuang 				   AFE_ADDA_NEWIF_CFG2,
318*42a589e8SKaiChieh Chuang 				   0xf << 28,
319*42a589e8SKaiChieh Chuang 				   8 << 28);
320*42a589e8SKaiChieh Chuang 
321*42a589e8SKaiChieh Chuang 		regmap_update_bits(afe->regmap,
322*42a589e8SKaiChieh Chuang 				   AFE_ADDA_UL_SRC_CON0,
323*42a589e8SKaiChieh Chuang 				   0xfffffffe,
324*42a589e8SKaiChieh Chuang 				   ul_src_con0);
325*42a589e8SKaiChieh Chuang 	}
326*42a589e8SKaiChieh Chuang 
327*42a589e8SKaiChieh Chuang 	return 0;
328*42a589e8SKaiChieh Chuang }
329*42a589e8SKaiChieh Chuang 
330*42a589e8SKaiChieh Chuang static const struct snd_soc_dai_ops mtk_dai_adda_ops = {
331*42a589e8SKaiChieh Chuang 	.hw_params = mtk_dai_adda_hw_params,
332*42a589e8SKaiChieh Chuang };
333*42a589e8SKaiChieh Chuang 
334*42a589e8SKaiChieh Chuang /* dai driver */
335*42a589e8SKaiChieh Chuang #define MTK_ADDA_PLAYBACK_RATES (SNDRV_PCM_RATE_8000_48000 |\
336*42a589e8SKaiChieh Chuang 				 SNDRV_PCM_RATE_96000 |\
337*42a589e8SKaiChieh Chuang 				 SNDRV_PCM_RATE_192000)
338*42a589e8SKaiChieh Chuang 
339*42a589e8SKaiChieh Chuang #define MTK_ADDA_CAPTURE_RATES (SNDRV_PCM_RATE_8000 |\
340*42a589e8SKaiChieh Chuang 				SNDRV_PCM_RATE_16000 |\
341*42a589e8SKaiChieh Chuang 				SNDRV_PCM_RATE_32000 |\
342*42a589e8SKaiChieh Chuang 				SNDRV_PCM_RATE_48000 |\
343*42a589e8SKaiChieh Chuang 				SNDRV_PCM_RATE_96000 |\
344*42a589e8SKaiChieh Chuang 				SNDRV_PCM_RATE_192000)
345*42a589e8SKaiChieh Chuang 
346*42a589e8SKaiChieh Chuang #define MTK_ADDA_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
347*42a589e8SKaiChieh Chuang 			  SNDRV_PCM_FMTBIT_S24_LE |\
348*42a589e8SKaiChieh Chuang 			  SNDRV_PCM_FMTBIT_S32_LE)
349*42a589e8SKaiChieh Chuang 
350*42a589e8SKaiChieh Chuang static struct snd_soc_dai_driver mtk_dai_adda_driver[] = {
351*42a589e8SKaiChieh Chuang 	{
352*42a589e8SKaiChieh Chuang 		.name = "ADDA",
353*42a589e8SKaiChieh Chuang 		.id = MT6797_DAI_ADDA,
354*42a589e8SKaiChieh Chuang 		.playback = {
355*42a589e8SKaiChieh Chuang 			.stream_name = "ADDA Playback",
356*42a589e8SKaiChieh Chuang 			.channels_min = 1,
357*42a589e8SKaiChieh Chuang 			.channels_max = 2,
358*42a589e8SKaiChieh Chuang 			.rates = MTK_ADDA_PLAYBACK_RATES,
359*42a589e8SKaiChieh Chuang 			.formats = MTK_ADDA_FORMATS,
360*42a589e8SKaiChieh Chuang 		},
361*42a589e8SKaiChieh Chuang 		.capture = {
362*42a589e8SKaiChieh Chuang 			.stream_name = "ADDA Capture",
363*42a589e8SKaiChieh Chuang 			.channels_min = 1,
364*42a589e8SKaiChieh Chuang 			.channels_max = 2,
365*42a589e8SKaiChieh Chuang 			.rates = MTK_ADDA_CAPTURE_RATES,
366*42a589e8SKaiChieh Chuang 			.formats = MTK_ADDA_FORMATS,
367*42a589e8SKaiChieh Chuang 		},
368*42a589e8SKaiChieh Chuang 		.ops = &mtk_dai_adda_ops,
369*42a589e8SKaiChieh Chuang 	},
370*42a589e8SKaiChieh Chuang };
371*42a589e8SKaiChieh Chuang 
372*42a589e8SKaiChieh Chuang int mt6797_dai_adda_register(struct mtk_base_afe *afe)
373*42a589e8SKaiChieh Chuang {
374*42a589e8SKaiChieh Chuang 	int id = MT6797_DAI_ADDA;
375*42a589e8SKaiChieh Chuang 
376*42a589e8SKaiChieh Chuang 	afe->sub_dais[id].dai_drivers = mtk_dai_adda_driver;
377*42a589e8SKaiChieh Chuang 	afe->sub_dais[id].num_dai_drivers = ARRAY_SIZE(mtk_dai_adda_driver);
378*42a589e8SKaiChieh Chuang 
379*42a589e8SKaiChieh Chuang 	afe->sub_dais[id].dapm_widgets = mtk_dai_adda_widgets;
380*42a589e8SKaiChieh Chuang 	afe->sub_dais[id].num_dapm_widgets = ARRAY_SIZE(mtk_dai_adda_widgets);
381*42a589e8SKaiChieh Chuang 	afe->sub_dais[id].dapm_routes = mtk_dai_adda_routes;
382*42a589e8SKaiChieh Chuang 	afe->sub_dais[id].num_dapm_routes = ARRAY_SIZE(mtk_dai_adda_routes);
383*42a589e8SKaiChieh Chuang 	return 0;
384*42a589e8SKaiChieh Chuang }
385