xref: /linux/sound/soc/mediatek/mt6797/mt6797-dai-adda.c (revision d6c01755805d346a1382d2d81c214b2ca557487a)
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"
13*d6c01755SAngeloGioacchino Del Regno #include "../common/mtk-dai-adda-common.h"
1442a589e8SKaiChieh Chuang 
1542a589e8SKaiChieh Chuang /* dai component */
1642a589e8SKaiChieh Chuang static const struct snd_kcontrol_new mtk_adda_dl_ch1_mix[] = {
1742a589e8SKaiChieh Chuang 	SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1", AFE_CONN3, I_DL1_CH1, 1, 0),
1842a589e8SKaiChieh Chuang 	SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1", AFE_CONN3, I_DL2_CH1, 1, 0),
1942a589e8SKaiChieh Chuang 	SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1", AFE_CONN3, I_DL3_CH1, 1, 0),
2042a589e8SKaiChieh Chuang 	SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN3,
2142a589e8SKaiChieh Chuang 				    I_ADDA_UL_CH2, 1, 0),
2242a589e8SKaiChieh Chuang 	SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN3,
2342a589e8SKaiChieh Chuang 				    I_ADDA_UL_CH1, 1, 0),
242c1a5c04SKai Chieh Chuang 	SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH1", AFE_CONN3,
252c1a5c04SKai Chieh Chuang 				    I_PCM_1_CAP_CH1, 1, 0),
262c1a5c04SKai Chieh Chuang 	SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH1", AFE_CONN3,
272c1a5c04SKai Chieh Chuang 				    I_PCM_2_CAP_CH1, 1, 0),
2842a589e8SKaiChieh Chuang };
2942a589e8SKaiChieh Chuang 
3042a589e8SKaiChieh Chuang static const struct snd_kcontrol_new mtk_adda_dl_ch2_mix[] = {
3142a589e8SKaiChieh Chuang 	SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1", AFE_CONN4, I_DL1_CH1, 1, 0),
3242a589e8SKaiChieh Chuang 	SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH2", AFE_CONN4, I_DL1_CH2, 1, 0),
3342a589e8SKaiChieh Chuang 	SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1", AFE_CONN4, I_DL2_CH1, 1, 0),
3442a589e8SKaiChieh Chuang 	SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH2", AFE_CONN4, I_DL2_CH2, 1, 0),
3542a589e8SKaiChieh Chuang 	SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1", AFE_CONN4, I_DL3_CH1, 1, 0),
3642a589e8SKaiChieh Chuang 	SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH2", AFE_CONN4, I_DL3_CH2, 1, 0),
3742a589e8SKaiChieh Chuang 	SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN4,
3842a589e8SKaiChieh Chuang 				    I_ADDA_UL_CH2, 1, 0),
3942a589e8SKaiChieh Chuang 	SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN4,
4042a589e8SKaiChieh Chuang 				    I_ADDA_UL_CH1, 1, 0),
412c1a5c04SKai Chieh Chuang 	SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH1", AFE_CONN4,
422c1a5c04SKai Chieh Chuang 				    I_PCM_1_CAP_CH1, 1, 0),
432c1a5c04SKai Chieh Chuang 	SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH1", AFE_CONN4,
442c1a5c04SKai Chieh Chuang 				    I_PCM_2_CAP_CH1, 1, 0),
452c1a5c04SKai Chieh Chuang 	SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH2", AFE_CONN4,
462c1a5c04SKai Chieh Chuang 				    I_PCM_1_CAP_CH2, 1, 0),
472c1a5c04SKai Chieh Chuang 	SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH2", AFE_CONN4,
482c1a5c04SKai Chieh Chuang 				    I_PCM_2_CAP_CH2, 1, 0),
4942a589e8SKaiChieh Chuang };
5042a589e8SKaiChieh Chuang 
5142a589e8SKaiChieh Chuang static int mtk_adda_ul_event(struct snd_soc_dapm_widget *w,
5242a589e8SKaiChieh Chuang 			     struct snd_kcontrol *kcontrol,
5342a589e8SKaiChieh Chuang 			     int event)
5442a589e8SKaiChieh Chuang {
5542a589e8SKaiChieh Chuang 	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
5642a589e8SKaiChieh Chuang 	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
5742a589e8SKaiChieh Chuang 
5842a589e8SKaiChieh Chuang 	dev_dbg(afe->dev, "%s(), name %s, event 0x%x\n",
5942a589e8SKaiChieh Chuang 		__func__, w->name, event);
6042a589e8SKaiChieh Chuang 
6142a589e8SKaiChieh Chuang 	switch (event) {
6242a589e8SKaiChieh Chuang 	case SND_SOC_DAPM_POST_PMD:
6342a589e8SKaiChieh Chuang 		/* should delayed 1/fs(smallest is 8k) = 125us before afe off */
6442a589e8SKaiChieh Chuang 		usleep_range(125, 135);
6542a589e8SKaiChieh Chuang 		break;
6642a589e8SKaiChieh Chuang 	default:
6742a589e8SKaiChieh Chuang 		break;
6842a589e8SKaiChieh Chuang 	}
6942a589e8SKaiChieh Chuang 
7042a589e8SKaiChieh Chuang 	return 0;
7142a589e8SKaiChieh Chuang }
7242a589e8SKaiChieh Chuang 
7342a589e8SKaiChieh Chuang enum {
7442a589e8SKaiChieh Chuang 	SUPPLY_SEQ_AUD_TOP_PDN,
7542a589e8SKaiChieh Chuang 	SUPPLY_SEQ_ADDA_AFE_ON,
7642a589e8SKaiChieh Chuang 	SUPPLY_SEQ_ADDA_DL_ON,
7742a589e8SKaiChieh Chuang 	SUPPLY_SEQ_ADDA_UL_ON,
7842a589e8SKaiChieh Chuang };
7942a589e8SKaiChieh Chuang 
8042a589e8SKaiChieh Chuang static const struct snd_soc_dapm_widget mtk_dai_adda_widgets[] = {
8142a589e8SKaiChieh Chuang 	/* adda */
8242a589e8SKaiChieh Chuang 	SND_SOC_DAPM_MIXER("ADDA_DL_CH1", SND_SOC_NOPM, 0, 0,
8342a589e8SKaiChieh Chuang 			   mtk_adda_dl_ch1_mix,
8442a589e8SKaiChieh Chuang 			   ARRAY_SIZE(mtk_adda_dl_ch1_mix)),
8542a589e8SKaiChieh Chuang 	SND_SOC_DAPM_MIXER("ADDA_DL_CH2", SND_SOC_NOPM, 0, 0,
8642a589e8SKaiChieh Chuang 			   mtk_adda_dl_ch2_mix,
8742a589e8SKaiChieh Chuang 			   ARRAY_SIZE(mtk_adda_dl_ch2_mix)),
8842a589e8SKaiChieh Chuang 
8942a589e8SKaiChieh Chuang 	SND_SOC_DAPM_SUPPLY_S("ADDA Enable", SUPPLY_SEQ_ADDA_AFE_ON,
9042a589e8SKaiChieh Chuang 			      AFE_ADDA_UL_DL_CON0, ADDA_AFE_ON_SFT, 0,
9142a589e8SKaiChieh Chuang 			      NULL, 0),
9242a589e8SKaiChieh Chuang 
9342a589e8SKaiChieh Chuang 	SND_SOC_DAPM_SUPPLY_S("ADDA Playback Enable", SUPPLY_SEQ_ADDA_DL_ON,
9442a589e8SKaiChieh Chuang 			      AFE_ADDA_DL_SRC2_CON0,
9542a589e8SKaiChieh Chuang 			      DL_2_SRC_ON_TMP_CTL_PRE_SFT, 0,
9642a589e8SKaiChieh Chuang 			      NULL, 0),
9742a589e8SKaiChieh Chuang 
9842a589e8SKaiChieh Chuang 	SND_SOC_DAPM_SUPPLY_S("ADDA Capture Enable", SUPPLY_SEQ_ADDA_UL_ON,
9942a589e8SKaiChieh Chuang 			      AFE_ADDA_UL_SRC_CON0,
10042a589e8SKaiChieh Chuang 			      UL_SRC_ON_TMP_CTL_SFT, 0,
10142a589e8SKaiChieh Chuang 			      mtk_adda_ul_event,
10242a589e8SKaiChieh Chuang 			      SND_SOC_DAPM_POST_PMD),
10342a589e8SKaiChieh Chuang 
10442a589e8SKaiChieh Chuang 	SND_SOC_DAPM_SUPPLY_S("aud_dac_clk", SUPPLY_SEQ_AUD_TOP_PDN,
10542a589e8SKaiChieh Chuang 			      AUDIO_TOP_CON0, PDN_DAC_SFT, 1,
10642a589e8SKaiChieh Chuang 			      NULL, 0),
10742a589e8SKaiChieh Chuang 	SND_SOC_DAPM_SUPPLY_S("aud_dac_predis_clk", SUPPLY_SEQ_AUD_TOP_PDN,
10842a589e8SKaiChieh Chuang 			      AUDIO_TOP_CON0, PDN_DAC_PREDIS_SFT, 1,
10942a589e8SKaiChieh Chuang 			      NULL, 0),
11042a589e8SKaiChieh Chuang 
11142a589e8SKaiChieh Chuang 	SND_SOC_DAPM_SUPPLY_S("aud_adc_clk", SUPPLY_SEQ_AUD_TOP_PDN,
11242a589e8SKaiChieh Chuang 			      AUDIO_TOP_CON0, PDN_ADC_SFT, 1,
11342a589e8SKaiChieh Chuang 			      NULL, 0),
11442a589e8SKaiChieh Chuang 
11542a589e8SKaiChieh Chuang 	SND_SOC_DAPM_CLOCK_SUPPLY("mtkaif_26m_clk"),
11642a589e8SKaiChieh Chuang };
11742a589e8SKaiChieh Chuang 
11842a589e8SKaiChieh Chuang static const struct snd_soc_dapm_route mtk_dai_adda_routes[] = {
11942a589e8SKaiChieh Chuang 	/* playback */
12042a589e8SKaiChieh Chuang 	{"ADDA_DL_CH1", "DL1_CH1", "DL1"},
12142a589e8SKaiChieh Chuang 	{"ADDA_DL_CH2", "DL1_CH1", "DL1"},
12242a589e8SKaiChieh Chuang 	{"ADDA_DL_CH2", "DL1_CH2", "DL1"},
12342a589e8SKaiChieh Chuang 
12442a589e8SKaiChieh Chuang 	{"ADDA_DL_CH1", "DL2_CH1", "DL2"},
12542a589e8SKaiChieh Chuang 	{"ADDA_DL_CH2", "DL2_CH1", "DL2"},
12642a589e8SKaiChieh Chuang 	{"ADDA_DL_CH2", "DL2_CH2", "DL2"},
12742a589e8SKaiChieh Chuang 
12842a589e8SKaiChieh Chuang 	{"ADDA_DL_CH1", "DL3_CH1", "DL3"},
12942a589e8SKaiChieh Chuang 	{"ADDA_DL_CH2", "DL3_CH1", "DL3"},
13042a589e8SKaiChieh Chuang 	{"ADDA_DL_CH2", "DL3_CH2", "DL3"},
13142a589e8SKaiChieh Chuang 
13242a589e8SKaiChieh Chuang 	{"ADDA Playback", NULL, "ADDA_DL_CH1"},
13342a589e8SKaiChieh Chuang 	{"ADDA Playback", NULL, "ADDA_DL_CH2"},
13442a589e8SKaiChieh Chuang 
13542a589e8SKaiChieh Chuang 	/* adda enable */
13642a589e8SKaiChieh Chuang 	{"ADDA Playback", NULL, "ADDA Enable"},
13742a589e8SKaiChieh Chuang 	{"ADDA Playback", NULL, "ADDA Playback Enable"},
13842a589e8SKaiChieh Chuang 	{"ADDA Capture", NULL, "ADDA Enable"},
13942a589e8SKaiChieh Chuang 	{"ADDA Capture", NULL, "ADDA Capture Enable"},
14042a589e8SKaiChieh Chuang 
14142a589e8SKaiChieh Chuang 	/* clk */
14242a589e8SKaiChieh Chuang 	{"ADDA Playback", NULL, "mtkaif_26m_clk"},
14342a589e8SKaiChieh Chuang 	{"ADDA Playback", NULL, "aud_dac_clk"},
14442a589e8SKaiChieh Chuang 	{"ADDA Playback", NULL, "aud_dac_predis_clk"},
14542a589e8SKaiChieh Chuang 
14642a589e8SKaiChieh Chuang 	{"ADDA Capture", NULL, "mtkaif_26m_clk"},
14742a589e8SKaiChieh Chuang 	{"ADDA Capture", NULL, "aud_adc_clk"},
14842a589e8SKaiChieh Chuang };
14942a589e8SKaiChieh Chuang 
15042a589e8SKaiChieh Chuang /* dai ops */
15142a589e8SKaiChieh Chuang static int mtk_dai_adda_hw_params(struct snd_pcm_substream *substream,
15242a589e8SKaiChieh Chuang 				  struct snd_pcm_hw_params *params,
15342a589e8SKaiChieh Chuang 				  struct snd_soc_dai *dai)
15442a589e8SKaiChieh Chuang {
15542a589e8SKaiChieh Chuang 	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
15642a589e8SKaiChieh Chuang 	unsigned int rate = params_rate(params);
15742a589e8SKaiChieh Chuang 
15842a589e8SKaiChieh Chuang 	dev_dbg(afe->dev, "%s(), id %d, stream %d, rate %d\n",
15942a589e8SKaiChieh Chuang 		__func__, dai->id, substream->stream, rate);
16042a589e8SKaiChieh Chuang 
16142a589e8SKaiChieh Chuang 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
16242a589e8SKaiChieh Chuang 		unsigned int dl_src2_con0 = 0;
16342a589e8SKaiChieh Chuang 		unsigned int dl_src2_con1 = 0;
16442a589e8SKaiChieh Chuang 
16542a589e8SKaiChieh Chuang 		/* clean predistortion */
16642a589e8SKaiChieh Chuang 		regmap_write(afe->regmap, AFE_ADDA_PREDIS_CON0, 0);
16742a589e8SKaiChieh Chuang 		regmap_write(afe->regmap, AFE_ADDA_PREDIS_CON1, 0);
16842a589e8SKaiChieh Chuang 
16942a589e8SKaiChieh Chuang 		/* set input sampling rate */
170*d6c01755SAngeloGioacchino Del Regno 		dl_src2_con0 = mtk_adda_dl_rate_transform(afe, rate) << 28;
17142a589e8SKaiChieh Chuang 
17242a589e8SKaiChieh Chuang 		/* set output mode */
17342a589e8SKaiChieh Chuang 		switch (rate) {
17442a589e8SKaiChieh Chuang 		case 192000:
17542a589e8SKaiChieh Chuang 			dl_src2_con0 |= (0x1 << 24); /* UP_SAMPLING_RATE_X2 */
17642a589e8SKaiChieh Chuang 			dl_src2_con0 |= 1 << 14;
17742a589e8SKaiChieh Chuang 			break;
17842a589e8SKaiChieh Chuang 		case 96000:
17942a589e8SKaiChieh Chuang 			dl_src2_con0 |= (0x2 << 24); /* UP_SAMPLING_RATE_X4 */
18042a589e8SKaiChieh Chuang 			dl_src2_con0 |= 1 << 14;
18142a589e8SKaiChieh Chuang 			break;
18242a589e8SKaiChieh Chuang 		default:
18342a589e8SKaiChieh Chuang 			dl_src2_con0 |= (0x3 << 24); /* UP_SAMPLING_RATE_X8 */
18442a589e8SKaiChieh Chuang 			break;
18542a589e8SKaiChieh Chuang 		}
18642a589e8SKaiChieh Chuang 
18742a589e8SKaiChieh Chuang 		/* turn off mute function */
18842a589e8SKaiChieh Chuang 		dl_src2_con0 |= (0x03 << 11);
18942a589e8SKaiChieh Chuang 
19042a589e8SKaiChieh Chuang 		/* set voice input data if input sample rate is 8k or 16k */
19142a589e8SKaiChieh Chuang 		if (rate == 8000 || rate == 16000)
19242a589e8SKaiChieh Chuang 			dl_src2_con0 |= 0x01 << 5;
19342a589e8SKaiChieh Chuang 
19442a589e8SKaiChieh Chuang 		if (rate < 96000) {
19542a589e8SKaiChieh Chuang 			/* SA suggest apply -0.3db to audio/speech path */
19642a589e8SKaiChieh Chuang 			dl_src2_con1 = 0xf74f0000;
19742a589e8SKaiChieh Chuang 		} else {
19842a589e8SKaiChieh Chuang 			/* SA suggest apply -0.3db to audio/speech path
19942a589e8SKaiChieh Chuang 			 * with DL gain set to half,
20042a589e8SKaiChieh Chuang 			 * 0xFFFF = 0dB -> 0x8000 = 0dB when 96k, 192k
20142a589e8SKaiChieh Chuang 			 */
20242a589e8SKaiChieh Chuang 			dl_src2_con1 = 0x7ba70000;
20342a589e8SKaiChieh Chuang 		}
20442a589e8SKaiChieh Chuang 
20542a589e8SKaiChieh Chuang 		/* turn on down-link gain */
20642a589e8SKaiChieh Chuang 		dl_src2_con0 = dl_src2_con0 | (0x01 << 1);
20742a589e8SKaiChieh Chuang 
20842a589e8SKaiChieh Chuang 		regmap_write(afe->regmap, AFE_ADDA_DL_SRC2_CON0, dl_src2_con0);
20942a589e8SKaiChieh Chuang 		regmap_write(afe->regmap, AFE_ADDA_DL_SRC2_CON1, dl_src2_con1);
21042a589e8SKaiChieh Chuang 	} else {
21142a589e8SKaiChieh Chuang 		unsigned int voice_mode = 0;
21242a589e8SKaiChieh Chuang 		unsigned int ul_src_con0 = 0;	/* default value */
21342a589e8SKaiChieh Chuang 
21442a589e8SKaiChieh Chuang 		/* Using Internal ADC */
21542a589e8SKaiChieh Chuang 		regmap_update_bits(afe->regmap,
21642a589e8SKaiChieh Chuang 				   AFE_ADDA_TOP_CON0,
21742a589e8SKaiChieh Chuang 				   0x1 << 0,
21842a589e8SKaiChieh Chuang 				   0x0 << 0);
21942a589e8SKaiChieh Chuang 
220*d6c01755SAngeloGioacchino Del Regno 		voice_mode = mtk_adda_ul_rate_transform(afe, rate);
22142a589e8SKaiChieh Chuang 
22242a589e8SKaiChieh Chuang 		ul_src_con0 |= (voice_mode << 17) & (0x7 << 17);
22342a589e8SKaiChieh Chuang 
22442a589e8SKaiChieh Chuang 		/* up8x txif sat on */
22542a589e8SKaiChieh Chuang 		regmap_write(afe->regmap, AFE_ADDA_NEWIF_CFG0, 0x03F87201);
22642a589e8SKaiChieh Chuang 
22742a589e8SKaiChieh Chuang 		if (rate >= 96000) {	/* hires */
22842a589e8SKaiChieh Chuang 			/* use hires format [1 0 23] */
22942a589e8SKaiChieh Chuang 			regmap_update_bits(afe->regmap,
23042a589e8SKaiChieh Chuang 					   AFE_ADDA_NEWIF_CFG0,
23142a589e8SKaiChieh Chuang 					   0x1 << 5,
23242a589e8SKaiChieh Chuang 					   0x1 << 5);
23342a589e8SKaiChieh Chuang 
23442a589e8SKaiChieh Chuang 			regmap_update_bits(afe->regmap,
23542a589e8SKaiChieh Chuang 					   AFE_ADDA_NEWIF_CFG2,
23642a589e8SKaiChieh Chuang 					   0xf << 28,
23742a589e8SKaiChieh Chuang 					   voice_mode << 28);
23842a589e8SKaiChieh Chuang 		} else {	/* normal 8~48k */
23942a589e8SKaiChieh Chuang 			/* use fixed 260k anc path */
24042a589e8SKaiChieh Chuang 			regmap_update_bits(afe->regmap,
24142a589e8SKaiChieh Chuang 					   AFE_ADDA_NEWIF_CFG2,
24242a589e8SKaiChieh Chuang 					   0xf << 28,
24342a589e8SKaiChieh Chuang 					   8 << 28);
24442a589e8SKaiChieh Chuang 
24542a589e8SKaiChieh Chuang 			/* ul_use_cic_out */
24642a589e8SKaiChieh Chuang 			ul_src_con0 |= 0x1 << 20;
24742a589e8SKaiChieh Chuang 		}
24842a589e8SKaiChieh Chuang 
24942a589e8SKaiChieh Chuang 		regmap_update_bits(afe->regmap,
25042a589e8SKaiChieh Chuang 				   AFE_ADDA_NEWIF_CFG2,
25142a589e8SKaiChieh Chuang 				   0xf << 28,
25242a589e8SKaiChieh Chuang 				   8 << 28);
25342a589e8SKaiChieh Chuang 
25442a589e8SKaiChieh Chuang 		regmap_update_bits(afe->regmap,
25542a589e8SKaiChieh Chuang 				   AFE_ADDA_UL_SRC_CON0,
25642a589e8SKaiChieh Chuang 				   0xfffffffe,
25742a589e8SKaiChieh Chuang 				   ul_src_con0);
25842a589e8SKaiChieh Chuang 	}
25942a589e8SKaiChieh Chuang 
26042a589e8SKaiChieh Chuang 	return 0;
26142a589e8SKaiChieh Chuang }
26242a589e8SKaiChieh Chuang 
26342a589e8SKaiChieh Chuang static const struct snd_soc_dai_ops mtk_dai_adda_ops = {
26442a589e8SKaiChieh Chuang 	.hw_params = mtk_dai_adda_hw_params,
26542a589e8SKaiChieh Chuang };
26642a589e8SKaiChieh Chuang 
26742a589e8SKaiChieh Chuang /* dai driver */
26842a589e8SKaiChieh Chuang #define MTK_ADDA_PLAYBACK_RATES (SNDRV_PCM_RATE_8000_48000 |\
26942a589e8SKaiChieh Chuang 				 SNDRV_PCM_RATE_96000 |\
27042a589e8SKaiChieh Chuang 				 SNDRV_PCM_RATE_192000)
27142a589e8SKaiChieh Chuang 
27242a589e8SKaiChieh Chuang #define MTK_ADDA_CAPTURE_RATES (SNDRV_PCM_RATE_8000 |\
27342a589e8SKaiChieh Chuang 				SNDRV_PCM_RATE_16000 |\
27442a589e8SKaiChieh Chuang 				SNDRV_PCM_RATE_32000 |\
27542a589e8SKaiChieh Chuang 				SNDRV_PCM_RATE_48000 |\
27642a589e8SKaiChieh Chuang 				SNDRV_PCM_RATE_96000 |\
27742a589e8SKaiChieh Chuang 				SNDRV_PCM_RATE_192000)
27842a589e8SKaiChieh Chuang 
27942a589e8SKaiChieh Chuang #define MTK_ADDA_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
28042a589e8SKaiChieh Chuang 			  SNDRV_PCM_FMTBIT_S24_LE |\
28142a589e8SKaiChieh Chuang 			  SNDRV_PCM_FMTBIT_S32_LE)
28242a589e8SKaiChieh Chuang 
28342a589e8SKaiChieh Chuang static struct snd_soc_dai_driver mtk_dai_adda_driver[] = {
28442a589e8SKaiChieh Chuang 	{
28542a589e8SKaiChieh Chuang 		.name = "ADDA",
28642a589e8SKaiChieh Chuang 		.id = MT6797_DAI_ADDA,
28742a589e8SKaiChieh Chuang 		.playback = {
28842a589e8SKaiChieh Chuang 			.stream_name = "ADDA Playback",
28942a589e8SKaiChieh Chuang 			.channels_min = 1,
29042a589e8SKaiChieh Chuang 			.channels_max = 2,
29142a589e8SKaiChieh Chuang 			.rates = MTK_ADDA_PLAYBACK_RATES,
29242a589e8SKaiChieh Chuang 			.formats = MTK_ADDA_FORMATS,
29342a589e8SKaiChieh Chuang 		},
29442a589e8SKaiChieh Chuang 		.capture = {
29542a589e8SKaiChieh Chuang 			.stream_name = "ADDA Capture",
29642a589e8SKaiChieh Chuang 			.channels_min = 1,
29742a589e8SKaiChieh Chuang 			.channels_max = 2,
29842a589e8SKaiChieh Chuang 			.rates = MTK_ADDA_CAPTURE_RATES,
29942a589e8SKaiChieh Chuang 			.formats = MTK_ADDA_FORMATS,
30042a589e8SKaiChieh Chuang 		},
30142a589e8SKaiChieh Chuang 		.ops = &mtk_dai_adda_ops,
30242a589e8SKaiChieh Chuang 	},
30342a589e8SKaiChieh Chuang };
30442a589e8SKaiChieh Chuang 
30542a589e8SKaiChieh Chuang int mt6797_dai_adda_register(struct mtk_base_afe *afe)
30642a589e8SKaiChieh Chuang {
307c1d9b419SKaiChieh Chuang 	struct mtk_base_afe_dai *dai;
30842a589e8SKaiChieh Chuang 
309c1d9b419SKaiChieh Chuang 	dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL);
310c1d9b419SKaiChieh Chuang 	if (!dai)
311c1d9b419SKaiChieh Chuang 		return -ENOMEM;
31242a589e8SKaiChieh Chuang 
313c1d9b419SKaiChieh Chuang 	list_add(&dai->list, &afe->sub_dais);
314c1d9b419SKaiChieh Chuang 
315c1d9b419SKaiChieh Chuang 	dai->dai_drivers = mtk_dai_adda_driver;
316c1d9b419SKaiChieh Chuang 	dai->num_dai_drivers = ARRAY_SIZE(mtk_dai_adda_driver);
317c1d9b419SKaiChieh Chuang 
318c1d9b419SKaiChieh Chuang 	dai->dapm_widgets = mtk_dai_adda_widgets;
319c1d9b419SKaiChieh Chuang 	dai->num_dapm_widgets = ARRAY_SIZE(mtk_dai_adda_widgets);
320c1d9b419SKaiChieh Chuang 	dai->dapm_routes = mtk_dai_adda_routes;
321c1d9b419SKaiChieh Chuang 	dai->num_dapm_routes = ARRAY_SIZE(mtk_dai_adda_routes);
32242a589e8SKaiChieh Chuang 	return 0;
32342a589e8SKaiChieh Chuang }
324