xref: /linux/sound/soc/mediatek/mt6797/mt6797-dai-adda.c (revision 2c1a5c04417ec10189e4ae9e07543b67c2b48b90)
142a589e8SKaiChieh Chuang // SPDX-License-Identifier: GPL-2.0
242a589e8SKaiChieh Chuang //
342a589e8SKaiChieh Chuang // MediaTek ALSA SoC Audio DAI ADDA Control
442a589e8SKaiChieh Chuang //
542a589e8SKaiChieh Chuang // Copyright (c) 2018 MediaTek Inc.
642a589e8SKaiChieh Chuang // Author: KaiChieh Chuang <kaichieh.chuang@mediatek.com>
742a589e8SKaiChieh Chuang 
842a589e8SKaiChieh Chuang #include <linux/regmap.h>
942a589e8SKaiChieh Chuang #include <linux/delay.h>
1042a589e8SKaiChieh Chuang #include "mt6797-afe-common.h"
1142a589e8SKaiChieh Chuang #include "mt6797-interconnection.h"
1242a589e8SKaiChieh Chuang #include "mt6797-reg.h"
1342a589e8SKaiChieh Chuang 
1442a589e8SKaiChieh Chuang enum {
1542a589e8SKaiChieh Chuang 	MTK_AFE_ADDA_DL_RATE_8K = 0,
1642a589e8SKaiChieh Chuang 	MTK_AFE_ADDA_DL_RATE_11K = 1,
1742a589e8SKaiChieh Chuang 	MTK_AFE_ADDA_DL_RATE_12K = 2,
1842a589e8SKaiChieh Chuang 	MTK_AFE_ADDA_DL_RATE_16K = 3,
1942a589e8SKaiChieh Chuang 	MTK_AFE_ADDA_DL_RATE_22K = 4,
2042a589e8SKaiChieh Chuang 	MTK_AFE_ADDA_DL_RATE_24K = 5,
2142a589e8SKaiChieh Chuang 	MTK_AFE_ADDA_DL_RATE_32K = 6,
2242a589e8SKaiChieh Chuang 	MTK_AFE_ADDA_DL_RATE_44K = 7,
2342a589e8SKaiChieh Chuang 	MTK_AFE_ADDA_DL_RATE_48K = 8,
2442a589e8SKaiChieh Chuang 	MTK_AFE_ADDA_DL_RATE_96K = 9,
2542a589e8SKaiChieh Chuang 	MTK_AFE_ADDA_DL_RATE_192K = 10,
2642a589e8SKaiChieh Chuang };
2742a589e8SKaiChieh Chuang 
2842a589e8SKaiChieh Chuang enum {
2942a589e8SKaiChieh Chuang 	MTK_AFE_ADDA_UL_RATE_8K = 0,
3042a589e8SKaiChieh Chuang 	MTK_AFE_ADDA_UL_RATE_16K = 1,
3142a589e8SKaiChieh Chuang 	MTK_AFE_ADDA_UL_RATE_32K = 2,
3242a589e8SKaiChieh Chuang 	MTK_AFE_ADDA_UL_RATE_48K = 3,
3342a589e8SKaiChieh Chuang 	MTK_AFE_ADDA_UL_RATE_96K = 4,
3442a589e8SKaiChieh Chuang 	MTK_AFE_ADDA_UL_RATE_192K = 5,
3542a589e8SKaiChieh Chuang 	MTK_AFE_ADDA_UL_RATE_48K_HD = 6,
3642a589e8SKaiChieh Chuang };
3742a589e8SKaiChieh Chuang 
3842a589e8SKaiChieh Chuang static unsigned int adda_dl_rate_transform(struct mtk_base_afe *afe,
3942a589e8SKaiChieh Chuang 					   unsigned int rate)
4042a589e8SKaiChieh Chuang {
4142a589e8SKaiChieh Chuang 	switch (rate) {
4242a589e8SKaiChieh Chuang 	case 8000:
4342a589e8SKaiChieh Chuang 		return MTK_AFE_ADDA_DL_RATE_8K;
4442a589e8SKaiChieh Chuang 	case 11025:
4542a589e8SKaiChieh Chuang 		return MTK_AFE_ADDA_DL_RATE_11K;
4642a589e8SKaiChieh Chuang 	case 12000:
4742a589e8SKaiChieh Chuang 		return MTK_AFE_ADDA_DL_RATE_12K;
4842a589e8SKaiChieh Chuang 	case 16000:
4942a589e8SKaiChieh Chuang 		return MTK_AFE_ADDA_DL_RATE_16K;
5042a589e8SKaiChieh Chuang 	case 22050:
5142a589e8SKaiChieh Chuang 		return MTK_AFE_ADDA_DL_RATE_22K;
5242a589e8SKaiChieh Chuang 	case 24000:
5342a589e8SKaiChieh Chuang 		return MTK_AFE_ADDA_DL_RATE_24K;
5442a589e8SKaiChieh Chuang 	case 32000:
5542a589e8SKaiChieh Chuang 		return MTK_AFE_ADDA_DL_RATE_32K;
5642a589e8SKaiChieh Chuang 	case 44100:
5742a589e8SKaiChieh Chuang 		return MTK_AFE_ADDA_DL_RATE_44K;
5842a589e8SKaiChieh Chuang 	case 48000:
5942a589e8SKaiChieh Chuang 		return MTK_AFE_ADDA_DL_RATE_48K;
6042a589e8SKaiChieh Chuang 	case 96000:
6142a589e8SKaiChieh Chuang 		return MTK_AFE_ADDA_DL_RATE_96K;
6242a589e8SKaiChieh Chuang 	case 192000:
6342a589e8SKaiChieh Chuang 		return MTK_AFE_ADDA_DL_RATE_192K;
6442a589e8SKaiChieh Chuang 	default:
6542a589e8SKaiChieh Chuang 		dev_warn(afe->dev, "%s(), rate %d invalid, use 48kHz!!!\n",
6642a589e8SKaiChieh Chuang 			 __func__, rate);
6742a589e8SKaiChieh Chuang 		return MTK_AFE_ADDA_DL_RATE_48K;
6842a589e8SKaiChieh Chuang 	}
6942a589e8SKaiChieh Chuang }
7042a589e8SKaiChieh Chuang 
7142a589e8SKaiChieh Chuang static unsigned int adda_ul_rate_transform(struct mtk_base_afe *afe,
7242a589e8SKaiChieh Chuang 					   unsigned int rate)
7342a589e8SKaiChieh Chuang {
7442a589e8SKaiChieh Chuang 	switch (rate) {
7542a589e8SKaiChieh Chuang 	case 8000:
7642a589e8SKaiChieh Chuang 		return MTK_AFE_ADDA_UL_RATE_8K;
7742a589e8SKaiChieh Chuang 	case 16000:
7842a589e8SKaiChieh Chuang 		return MTK_AFE_ADDA_UL_RATE_16K;
7942a589e8SKaiChieh Chuang 	case 32000:
8042a589e8SKaiChieh Chuang 		return MTK_AFE_ADDA_UL_RATE_32K;
8142a589e8SKaiChieh Chuang 	case 48000:
8242a589e8SKaiChieh Chuang 		return MTK_AFE_ADDA_UL_RATE_48K;
8342a589e8SKaiChieh Chuang 	case 96000:
8442a589e8SKaiChieh Chuang 		return MTK_AFE_ADDA_UL_RATE_96K;
8542a589e8SKaiChieh Chuang 	case 192000:
8642a589e8SKaiChieh Chuang 		return MTK_AFE_ADDA_UL_RATE_192K;
8742a589e8SKaiChieh Chuang 	default:
8842a589e8SKaiChieh Chuang 		dev_warn(afe->dev, "%s(), rate %d invalid, use 48kHz!!!\n",
8942a589e8SKaiChieh Chuang 			 __func__, rate);
9042a589e8SKaiChieh Chuang 		return MTK_AFE_ADDA_UL_RATE_48K;
9142a589e8SKaiChieh Chuang 	}
9242a589e8SKaiChieh Chuang }
9342a589e8SKaiChieh Chuang 
9442a589e8SKaiChieh Chuang /* dai component */
9542a589e8SKaiChieh Chuang static const struct snd_kcontrol_new mtk_adda_dl_ch1_mix[] = {
9642a589e8SKaiChieh Chuang 	SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1", AFE_CONN3, I_DL1_CH1, 1, 0),
9742a589e8SKaiChieh Chuang 	SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1", AFE_CONN3, I_DL2_CH1, 1, 0),
9842a589e8SKaiChieh Chuang 	SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1", AFE_CONN3, I_DL3_CH1, 1, 0),
9942a589e8SKaiChieh Chuang 	SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN3,
10042a589e8SKaiChieh Chuang 				    I_ADDA_UL_CH2, 1, 0),
10142a589e8SKaiChieh Chuang 	SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN3,
10242a589e8SKaiChieh Chuang 				    I_ADDA_UL_CH1, 1, 0),
103*2c1a5c04SKai Chieh Chuang 	SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH1", AFE_CONN3,
104*2c1a5c04SKai Chieh Chuang 				    I_PCM_1_CAP_CH1, 1, 0),
105*2c1a5c04SKai Chieh Chuang 	SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH1", AFE_CONN3,
106*2c1a5c04SKai Chieh Chuang 				    I_PCM_2_CAP_CH1, 1, 0),
10742a589e8SKaiChieh Chuang };
10842a589e8SKaiChieh Chuang 
10942a589e8SKaiChieh Chuang static const struct snd_kcontrol_new mtk_adda_dl_ch2_mix[] = {
11042a589e8SKaiChieh Chuang 	SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1", AFE_CONN4, I_DL1_CH1, 1, 0),
11142a589e8SKaiChieh Chuang 	SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH2", AFE_CONN4, I_DL1_CH2, 1, 0),
11242a589e8SKaiChieh Chuang 	SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1", AFE_CONN4, I_DL2_CH1, 1, 0),
11342a589e8SKaiChieh Chuang 	SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH2", AFE_CONN4, I_DL2_CH2, 1, 0),
11442a589e8SKaiChieh Chuang 	SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1", AFE_CONN4, I_DL3_CH1, 1, 0),
11542a589e8SKaiChieh Chuang 	SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH2", AFE_CONN4, I_DL3_CH2, 1, 0),
11642a589e8SKaiChieh Chuang 	SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN4,
11742a589e8SKaiChieh Chuang 				    I_ADDA_UL_CH2, 1, 0),
11842a589e8SKaiChieh Chuang 	SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN4,
11942a589e8SKaiChieh Chuang 				    I_ADDA_UL_CH1, 1, 0),
120*2c1a5c04SKai Chieh Chuang 	SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH1", AFE_CONN4,
121*2c1a5c04SKai Chieh Chuang 				    I_PCM_1_CAP_CH1, 1, 0),
122*2c1a5c04SKai Chieh Chuang 	SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH1", AFE_CONN4,
123*2c1a5c04SKai Chieh Chuang 				    I_PCM_2_CAP_CH1, 1, 0),
124*2c1a5c04SKai Chieh Chuang 	SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH2", AFE_CONN4,
125*2c1a5c04SKai Chieh Chuang 				    I_PCM_1_CAP_CH2, 1, 0),
126*2c1a5c04SKai Chieh Chuang 	SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH2", AFE_CONN4,
127*2c1a5c04SKai Chieh Chuang 				    I_PCM_2_CAP_CH2, 1, 0),
12842a589e8SKaiChieh Chuang };
12942a589e8SKaiChieh Chuang 
13042a589e8SKaiChieh Chuang static int mtk_adda_ul_event(struct snd_soc_dapm_widget *w,
13142a589e8SKaiChieh Chuang 			     struct snd_kcontrol *kcontrol,
13242a589e8SKaiChieh Chuang 			     int event)
13342a589e8SKaiChieh Chuang {
13442a589e8SKaiChieh Chuang 	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
13542a589e8SKaiChieh Chuang 	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
13642a589e8SKaiChieh Chuang 
13742a589e8SKaiChieh Chuang 	dev_dbg(afe->dev, "%s(), name %s, event 0x%x\n",
13842a589e8SKaiChieh Chuang 		__func__, w->name, event);
13942a589e8SKaiChieh Chuang 
14042a589e8SKaiChieh Chuang 	switch (event) {
14142a589e8SKaiChieh Chuang 	case SND_SOC_DAPM_POST_PMD:
14242a589e8SKaiChieh Chuang 		/* should delayed 1/fs(smallest is 8k) = 125us before afe off */
14342a589e8SKaiChieh Chuang 		usleep_range(125, 135);
14442a589e8SKaiChieh Chuang 		break;
14542a589e8SKaiChieh Chuang 	default:
14642a589e8SKaiChieh Chuang 		break;
14742a589e8SKaiChieh Chuang 	}
14842a589e8SKaiChieh Chuang 
14942a589e8SKaiChieh Chuang 	return 0;
15042a589e8SKaiChieh Chuang }
15142a589e8SKaiChieh Chuang 
15242a589e8SKaiChieh Chuang enum {
15342a589e8SKaiChieh Chuang 	SUPPLY_SEQ_AUD_TOP_PDN,
15442a589e8SKaiChieh Chuang 	SUPPLY_SEQ_ADDA_AFE_ON,
15542a589e8SKaiChieh Chuang 	SUPPLY_SEQ_ADDA_DL_ON,
15642a589e8SKaiChieh Chuang 	SUPPLY_SEQ_ADDA_UL_ON,
15742a589e8SKaiChieh Chuang };
15842a589e8SKaiChieh Chuang 
15942a589e8SKaiChieh Chuang static const struct snd_soc_dapm_widget mtk_dai_adda_widgets[] = {
16042a589e8SKaiChieh Chuang 	/* adda */
16142a589e8SKaiChieh Chuang 	SND_SOC_DAPM_MIXER("ADDA_DL_CH1", SND_SOC_NOPM, 0, 0,
16242a589e8SKaiChieh Chuang 			   mtk_adda_dl_ch1_mix,
16342a589e8SKaiChieh Chuang 			   ARRAY_SIZE(mtk_adda_dl_ch1_mix)),
16442a589e8SKaiChieh Chuang 	SND_SOC_DAPM_MIXER("ADDA_DL_CH2", SND_SOC_NOPM, 0, 0,
16542a589e8SKaiChieh Chuang 			   mtk_adda_dl_ch2_mix,
16642a589e8SKaiChieh Chuang 			   ARRAY_SIZE(mtk_adda_dl_ch2_mix)),
16742a589e8SKaiChieh Chuang 
16842a589e8SKaiChieh Chuang 	SND_SOC_DAPM_SUPPLY_S("ADDA Enable", SUPPLY_SEQ_ADDA_AFE_ON,
16942a589e8SKaiChieh Chuang 			      AFE_ADDA_UL_DL_CON0, ADDA_AFE_ON_SFT, 0,
17042a589e8SKaiChieh Chuang 			      NULL, 0),
17142a589e8SKaiChieh Chuang 
17242a589e8SKaiChieh Chuang 	SND_SOC_DAPM_SUPPLY_S("ADDA Playback Enable", SUPPLY_SEQ_ADDA_DL_ON,
17342a589e8SKaiChieh Chuang 			      AFE_ADDA_DL_SRC2_CON0,
17442a589e8SKaiChieh Chuang 			      DL_2_SRC_ON_TMP_CTL_PRE_SFT, 0,
17542a589e8SKaiChieh Chuang 			      NULL, 0),
17642a589e8SKaiChieh Chuang 
17742a589e8SKaiChieh Chuang 	SND_SOC_DAPM_SUPPLY_S("ADDA Capture Enable", SUPPLY_SEQ_ADDA_UL_ON,
17842a589e8SKaiChieh Chuang 			      AFE_ADDA_UL_SRC_CON0,
17942a589e8SKaiChieh Chuang 			      UL_SRC_ON_TMP_CTL_SFT, 0,
18042a589e8SKaiChieh Chuang 			      mtk_adda_ul_event,
18142a589e8SKaiChieh Chuang 			      SND_SOC_DAPM_POST_PMD),
18242a589e8SKaiChieh Chuang 
18342a589e8SKaiChieh Chuang 	SND_SOC_DAPM_SUPPLY_S("aud_dac_clk", SUPPLY_SEQ_AUD_TOP_PDN,
18442a589e8SKaiChieh Chuang 			      AUDIO_TOP_CON0, PDN_DAC_SFT, 1,
18542a589e8SKaiChieh Chuang 			      NULL, 0),
18642a589e8SKaiChieh Chuang 	SND_SOC_DAPM_SUPPLY_S("aud_dac_predis_clk", SUPPLY_SEQ_AUD_TOP_PDN,
18742a589e8SKaiChieh Chuang 			      AUDIO_TOP_CON0, PDN_DAC_PREDIS_SFT, 1,
18842a589e8SKaiChieh Chuang 			      NULL, 0),
18942a589e8SKaiChieh Chuang 
19042a589e8SKaiChieh Chuang 	SND_SOC_DAPM_SUPPLY_S("aud_adc_clk", SUPPLY_SEQ_AUD_TOP_PDN,
19142a589e8SKaiChieh Chuang 			      AUDIO_TOP_CON0, PDN_ADC_SFT, 1,
19242a589e8SKaiChieh Chuang 			      NULL, 0),
19342a589e8SKaiChieh Chuang 
19442a589e8SKaiChieh Chuang 	SND_SOC_DAPM_CLOCK_SUPPLY("mtkaif_26m_clk"),
19542a589e8SKaiChieh Chuang };
19642a589e8SKaiChieh Chuang 
19742a589e8SKaiChieh Chuang static const struct snd_soc_dapm_route mtk_dai_adda_routes[] = {
19842a589e8SKaiChieh Chuang 	/* playback */
19942a589e8SKaiChieh Chuang 	{"ADDA_DL_CH1", "DL1_CH1", "DL1"},
20042a589e8SKaiChieh Chuang 	{"ADDA_DL_CH2", "DL1_CH1", "DL1"},
20142a589e8SKaiChieh Chuang 	{"ADDA_DL_CH2", "DL1_CH2", "DL1"},
20242a589e8SKaiChieh Chuang 
20342a589e8SKaiChieh Chuang 	{"ADDA_DL_CH1", "DL2_CH1", "DL2"},
20442a589e8SKaiChieh Chuang 	{"ADDA_DL_CH2", "DL2_CH1", "DL2"},
20542a589e8SKaiChieh Chuang 	{"ADDA_DL_CH2", "DL2_CH2", "DL2"},
20642a589e8SKaiChieh Chuang 
20742a589e8SKaiChieh Chuang 	{"ADDA_DL_CH1", "DL3_CH1", "DL3"},
20842a589e8SKaiChieh Chuang 	{"ADDA_DL_CH2", "DL3_CH1", "DL3"},
20942a589e8SKaiChieh Chuang 	{"ADDA_DL_CH2", "DL3_CH2", "DL3"},
21042a589e8SKaiChieh Chuang 
21142a589e8SKaiChieh Chuang 	{"ADDA Playback", NULL, "ADDA_DL_CH1"},
21242a589e8SKaiChieh Chuang 	{"ADDA Playback", NULL, "ADDA_DL_CH2"},
21342a589e8SKaiChieh Chuang 
21442a589e8SKaiChieh Chuang 	/* adda enable */
21542a589e8SKaiChieh Chuang 	{"ADDA Playback", NULL, "ADDA Enable"},
21642a589e8SKaiChieh Chuang 	{"ADDA Playback", NULL, "ADDA Playback Enable"},
21742a589e8SKaiChieh Chuang 	{"ADDA Capture", NULL, "ADDA Enable"},
21842a589e8SKaiChieh Chuang 	{"ADDA Capture", NULL, "ADDA Capture Enable"},
21942a589e8SKaiChieh Chuang 
22042a589e8SKaiChieh Chuang 	/* clk */
22142a589e8SKaiChieh Chuang 	{"ADDA Playback", NULL, "mtkaif_26m_clk"},
22242a589e8SKaiChieh Chuang 	{"ADDA Playback", NULL, "aud_dac_clk"},
22342a589e8SKaiChieh Chuang 	{"ADDA Playback", NULL, "aud_dac_predis_clk"},
22442a589e8SKaiChieh Chuang 
22542a589e8SKaiChieh Chuang 	{"ADDA Capture", NULL, "mtkaif_26m_clk"},
22642a589e8SKaiChieh Chuang 	{"ADDA Capture", NULL, "aud_adc_clk"},
22742a589e8SKaiChieh Chuang };
22842a589e8SKaiChieh Chuang 
22942a589e8SKaiChieh Chuang /* dai ops */
23042a589e8SKaiChieh Chuang static int mtk_dai_adda_hw_params(struct snd_pcm_substream *substream,
23142a589e8SKaiChieh Chuang 				  struct snd_pcm_hw_params *params,
23242a589e8SKaiChieh Chuang 				  struct snd_soc_dai *dai)
23342a589e8SKaiChieh Chuang {
23442a589e8SKaiChieh Chuang 	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
23542a589e8SKaiChieh Chuang 	unsigned int rate = params_rate(params);
23642a589e8SKaiChieh Chuang 
23742a589e8SKaiChieh Chuang 	dev_dbg(afe->dev, "%s(), id %d, stream %d, rate %d\n",
23842a589e8SKaiChieh Chuang 		__func__, dai->id, substream->stream, rate);
23942a589e8SKaiChieh Chuang 
24042a589e8SKaiChieh Chuang 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
24142a589e8SKaiChieh Chuang 		unsigned int dl_src2_con0 = 0;
24242a589e8SKaiChieh Chuang 		unsigned int dl_src2_con1 = 0;
24342a589e8SKaiChieh Chuang 
24442a589e8SKaiChieh Chuang 		/* clean predistortion */
24542a589e8SKaiChieh Chuang 		regmap_write(afe->regmap, AFE_ADDA_PREDIS_CON0, 0);
24642a589e8SKaiChieh Chuang 		regmap_write(afe->regmap, AFE_ADDA_PREDIS_CON1, 0);
24742a589e8SKaiChieh Chuang 
24842a589e8SKaiChieh Chuang 		/* set input sampling rate */
24942a589e8SKaiChieh Chuang 		dl_src2_con0 = adda_dl_rate_transform(afe, rate) << 28;
25042a589e8SKaiChieh Chuang 
25142a589e8SKaiChieh Chuang 		/* set output mode */
25242a589e8SKaiChieh Chuang 		switch (rate) {
25342a589e8SKaiChieh Chuang 		case 192000:
25442a589e8SKaiChieh Chuang 			dl_src2_con0 |= (0x1 << 24); /* UP_SAMPLING_RATE_X2 */
25542a589e8SKaiChieh Chuang 			dl_src2_con0 |= 1 << 14;
25642a589e8SKaiChieh Chuang 			break;
25742a589e8SKaiChieh Chuang 		case 96000:
25842a589e8SKaiChieh Chuang 			dl_src2_con0 |= (0x2 << 24); /* UP_SAMPLING_RATE_X4 */
25942a589e8SKaiChieh Chuang 			dl_src2_con0 |= 1 << 14;
26042a589e8SKaiChieh Chuang 			break;
26142a589e8SKaiChieh Chuang 		default:
26242a589e8SKaiChieh Chuang 			dl_src2_con0 |= (0x3 << 24); /* UP_SAMPLING_RATE_X8 */
26342a589e8SKaiChieh Chuang 			break;
26442a589e8SKaiChieh Chuang 		}
26542a589e8SKaiChieh Chuang 
26642a589e8SKaiChieh Chuang 		/* turn off mute function */
26742a589e8SKaiChieh Chuang 		dl_src2_con0 |= (0x03 << 11);
26842a589e8SKaiChieh Chuang 
26942a589e8SKaiChieh Chuang 		/* set voice input data if input sample rate is 8k or 16k */
27042a589e8SKaiChieh Chuang 		if (rate == 8000 || rate == 16000)
27142a589e8SKaiChieh Chuang 			dl_src2_con0 |= 0x01 << 5;
27242a589e8SKaiChieh Chuang 
27342a589e8SKaiChieh Chuang 		if (rate < 96000) {
27442a589e8SKaiChieh Chuang 			/* SA suggest apply -0.3db to audio/speech path */
27542a589e8SKaiChieh Chuang 			dl_src2_con1 = 0xf74f0000;
27642a589e8SKaiChieh Chuang 		} else {
27742a589e8SKaiChieh Chuang 			/* SA suggest apply -0.3db to audio/speech path
27842a589e8SKaiChieh Chuang 			 * with DL gain set to half,
27942a589e8SKaiChieh Chuang 			 * 0xFFFF = 0dB -> 0x8000 = 0dB when 96k, 192k
28042a589e8SKaiChieh Chuang 			 */
28142a589e8SKaiChieh Chuang 			dl_src2_con1 = 0x7ba70000;
28242a589e8SKaiChieh Chuang 		}
28342a589e8SKaiChieh Chuang 
28442a589e8SKaiChieh Chuang 		/* turn on down-link gain */
28542a589e8SKaiChieh Chuang 		dl_src2_con0 = dl_src2_con0 | (0x01 << 1);
28642a589e8SKaiChieh Chuang 
28742a589e8SKaiChieh Chuang 		regmap_write(afe->regmap, AFE_ADDA_DL_SRC2_CON0, dl_src2_con0);
28842a589e8SKaiChieh Chuang 		regmap_write(afe->regmap, AFE_ADDA_DL_SRC2_CON1, dl_src2_con1);
28942a589e8SKaiChieh Chuang 	} else {
29042a589e8SKaiChieh Chuang 		unsigned int voice_mode = 0;
29142a589e8SKaiChieh Chuang 		unsigned int ul_src_con0 = 0;	/* default value */
29242a589e8SKaiChieh Chuang 
29342a589e8SKaiChieh Chuang 		/* Using Internal ADC */
29442a589e8SKaiChieh Chuang 		regmap_update_bits(afe->regmap,
29542a589e8SKaiChieh Chuang 				   AFE_ADDA_TOP_CON0,
29642a589e8SKaiChieh Chuang 				   0x1 << 0,
29742a589e8SKaiChieh Chuang 				   0x0 << 0);
29842a589e8SKaiChieh Chuang 
29942a589e8SKaiChieh Chuang 		voice_mode = adda_ul_rate_transform(afe, rate);
30042a589e8SKaiChieh Chuang 
30142a589e8SKaiChieh Chuang 		ul_src_con0 |= (voice_mode << 17) & (0x7 << 17);
30242a589e8SKaiChieh Chuang 
30342a589e8SKaiChieh Chuang 		/* up8x txif sat on */
30442a589e8SKaiChieh Chuang 		regmap_write(afe->regmap, AFE_ADDA_NEWIF_CFG0, 0x03F87201);
30542a589e8SKaiChieh Chuang 
30642a589e8SKaiChieh Chuang 		if (rate >= 96000) {	/* hires */
30742a589e8SKaiChieh Chuang 			/* use hires format [1 0 23] */
30842a589e8SKaiChieh Chuang 			regmap_update_bits(afe->regmap,
30942a589e8SKaiChieh Chuang 					   AFE_ADDA_NEWIF_CFG0,
31042a589e8SKaiChieh Chuang 					   0x1 << 5,
31142a589e8SKaiChieh Chuang 					   0x1 << 5);
31242a589e8SKaiChieh Chuang 
31342a589e8SKaiChieh Chuang 			regmap_update_bits(afe->regmap,
31442a589e8SKaiChieh Chuang 					   AFE_ADDA_NEWIF_CFG2,
31542a589e8SKaiChieh Chuang 					   0xf << 28,
31642a589e8SKaiChieh Chuang 					   voice_mode << 28);
31742a589e8SKaiChieh Chuang 		} else {	/* normal 8~48k */
31842a589e8SKaiChieh Chuang 			/* use fixed 260k anc path */
31942a589e8SKaiChieh Chuang 			regmap_update_bits(afe->regmap,
32042a589e8SKaiChieh Chuang 					   AFE_ADDA_NEWIF_CFG2,
32142a589e8SKaiChieh Chuang 					   0xf << 28,
32242a589e8SKaiChieh Chuang 					   8 << 28);
32342a589e8SKaiChieh Chuang 
32442a589e8SKaiChieh Chuang 			/* ul_use_cic_out */
32542a589e8SKaiChieh Chuang 			ul_src_con0 |= 0x1 << 20;
32642a589e8SKaiChieh Chuang 		}
32742a589e8SKaiChieh Chuang 
32842a589e8SKaiChieh Chuang 		regmap_update_bits(afe->regmap,
32942a589e8SKaiChieh Chuang 				   AFE_ADDA_NEWIF_CFG2,
33042a589e8SKaiChieh Chuang 				   0xf << 28,
33142a589e8SKaiChieh Chuang 				   8 << 28);
33242a589e8SKaiChieh Chuang 
33342a589e8SKaiChieh Chuang 		regmap_update_bits(afe->regmap,
33442a589e8SKaiChieh Chuang 				   AFE_ADDA_UL_SRC_CON0,
33542a589e8SKaiChieh Chuang 				   0xfffffffe,
33642a589e8SKaiChieh Chuang 				   ul_src_con0);
33742a589e8SKaiChieh Chuang 	}
33842a589e8SKaiChieh Chuang 
33942a589e8SKaiChieh Chuang 	return 0;
34042a589e8SKaiChieh Chuang }
34142a589e8SKaiChieh Chuang 
34242a589e8SKaiChieh Chuang static const struct snd_soc_dai_ops mtk_dai_adda_ops = {
34342a589e8SKaiChieh Chuang 	.hw_params = mtk_dai_adda_hw_params,
34442a589e8SKaiChieh Chuang };
34542a589e8SKaiChieh Chuang 
34642a589e8SKaiChieh Chuang /* dai driver */
34742a589e8SKaiChieh Chuang #define MTK_ADDA_PLAYBACK_RATES (SNDRV_PCM_RATE_8000_48000 |\
34842a589e8SKaiChieh Chuang 				 SNDRV_PCM_RATE_96000 |\
34942a589e8SKaiChieh Chuang 				 SNDRV_PCM_RATE_192000)
35042a589e8SKaiChieh Chuang 
35142a589e8SKaiChieh Chuang #define MTK_ADDA_CAPTURE_RATES (SNDRV_PCM_RATE_8000 |\
35242a589e8SKaiChieh Chuang 				SNDRV_PCM_RATE_16000 |\
35342a589e8SKaiChieh Chuang 				SNDRV_PCM_RATE_32000 |\
35442a589e8SKaiChieh Chuang 				SNDRV_PCM_RATE_48000 |\
35542a589e8SKaiChieh Chuang 				SNDRV_PCM_RATE_96000 |\
35642a589e8SKaiChieh Chuang 				SNDRV_PCM_RATE_192000)
35742a589e8SKaiChieh Chuang 
35842a589e8SKaiChieh Chuang #define MTK_ADDA_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
35942a589e8SKaiChieh Chuang 			  SNDRV_PCM_FMTBIT_S24_LE |\
36042a589e8SKaiChieh Chuang 			  SNDRV_PCM_FMTBIT_S32_LE)
36142a589e8SKaiChieh Chuang 
36242a589e8SKaiChieh Chuang static struct snd_soc_dai_driver mtk_dai_adda_driver[] = {
36342a589e8SKaiChieh Chuang 	{
36442a589e8SKaiChieh Chuang 		.name = "ADDA",
36542a589e8SKaiChieh Chuang 		.id = MT6797_DAI_ADDA,
36642a589e8SKaiChieh Chuang 		.playback = {
36742a589e8SKaiChieh Chuang 			.stream_name = "ADDA Playback",
36842a589e8SKaiChieh Chuang 			.channels_min = 1,
36942a589e8SKaiChieh Chuang 			.channels_max = 2,
37042a589e8SKaiChieh Chuang 			.rates = MTK_ADDA_PLAYBACK_RATES,
37142a589e8SKaiChieh Chuang 			.formats = MTK_ADDA_FORMATS,
37242a589e8SKaiChieh Chuang 		},
37342a589e8SKaiChieh Chuang 		.capture = {
37442a589e8SKaiChieh Chuang 			.stream_name = "ADDA Capture",
37542a589e8SKaiChieh Chuang 			.channels_min = 1,
37642a589e8SKaiChieh Chuang 			.channels_max = 2,
37742a589e8SKaiChieh Chuang 			.rates = MTK_ADDA_CAPTURE_RATES,
37842a589e8SKaiChieh Chuang 			.formats = MTK_ADDA_FORMATS,
37942a589e8SKaiChieh Chuang 		},
38042a589e8SKaiChieh Chuang 		.ops = &mtk_dai_adda_ops,
38142a589e8SKaiChieh Chuang 	},
38242a589e8SKaiChieh Chuang };
38342a589e8SKaiChieh Chuang 
38442a589e8SKaiChieh Chuang int mt6797_dai_adda_register(struct mtk_base_afe *afe)
38542a589e8SKaiChieh Chuang {
38642a589e8SKaiChieh Chuang 	int id = MT6797_DAI_ADDA;
38742a589e8SKaiChieh Chuang 
38842a589e8SKaiChieh Chuang 	afe->sub_dais[id].dai_drivers = mtk_dai_adda_driver;
38942a589e8SKaiChieh Chuang 	afe->sub_dais[id].num_dai_drivers = ARRAY_SIZE(mtk_dai_adda_driver);
39042a589e8SKaiChieh Chuang 
39142a589e8SKaiChieh Chuang 	afe->sub_dais[id].dapm_widgets = mtk_dai_adda_widgets;
39242a589e8SKaiChieh Chuang 	afe->sub_dais[id].num_dapm_widgets = ARRAY_SIZE(mtk_dai_adda_widgets);
39342a589e8SKaiChieh Chuang 	afe->sub_dais[id].dapm_routes = mtk_dai_adda_routes;
39442a589e8SKaiChieh Chuang 	afe->sub_dais[id].num_dapm_routes = ARRAY_SIZE(mtk_dai_adda_routes);
39542a589e8SKaiChieh Chuang 	return 0;
39642a589e8SKaiChieh Chuang }
397