162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci//
362306a36Sopenharmony_ci// MediaTek ALSA SoC Audio DAI ADDA Control
462306a36Sopenharmony_ci//
562306a36Sopenharmony_ci// Copyright (c) 2018 MediaTek Inc.
662306a36Sopenharmony_ci// Author: KaiChieh Chuang <kaichieh.chuang@mediatek.com>
762306a36Sopenharmony_ci
862306a36Sopenharmony_ci#include <linux/regmap.h>
962306a36Sopenharmony_ci#include <linux/delay.h>
1062306a36Sopenharmony_ci#include "mt8183-afe-common.h"
1162306a36Sopenharmony_ci#include "mt8183-interconnection.h"
1262306a36Sopenharmony_ci#include "mt8183-reg.h"
1362306a36Sopenharmony_ci
1462306a36Sopenharmony_cienum {
1562306a36Sopenharmony_ci	AUDIO_SDM_LEVEL_MUTE = 0,
1662306a36Sopenharmony_ci	AUDIO_SDM_LEVEL_NORMAL = 0x1d,
1762306a36Sopenharmony_ci	/* if you change level normal */
1862306a36Sopenharmony_ci	/* you need to change formula of hp impedance and dc trim too */
1962306a36Sopenharmony_ci};
2062306a36Sopenharmony_ci
2162306a36Sopenharmony_cienum {
2262306a36Sopenharmony_ci	DELAY_DATA_MISO1 = 0,
2362306a36Sopenharmony_ci	DELAY_DATA_MISO2,
2462306a36Sopenharmony_ci};
2562306a36Sopenharmony_ci
2662306a36Sopenharmony_cienum {
2762306a36Sopenharmony_ci	MTK_AFE_ADDA_DL_RATE_8K = 0,
2862306a36Sopenharmony_ci	MTK_AFE_ADDA_DL_RATE_11K = 1,
2962306a36Sopenharmony_ci	MTK_AFE_ADDA_DL_RATE_12K = 2,
3062306a36Sopenharmony_ci	MTK_AFE_ADDA_DL_RATE_16K = 3,
3162306a36Sopenharmony_ci	MTK_AFE_ADDA_DL_RATE_22K = 4,
3262306a36Sopenharmony_ci	MTK_AFE_ADDA_DL_RATE_24K = 5,
3362306a36Sopenharmony_ci	MTK_AFE_ADDA_DL_RATE_32K = 6,
3462306a36Sopenharmony_ci	MTK_AFE_ADDA_DL_RATE_44K = 7,
3562306a36Sopenharmony_ci	MTK_AFE_ADDA_DL_RATE_48K = 8,
3662306a36Sopenharmony_ci	MTK_AFE_ADDA_DL_RATE_96K = 9,
3762306a36Sopenharmony_ci	MTK_AFE_ADDA_DL_RATE_192K = 10,
3862306a36Sopenharmony_ci};
3962306a36Sopenharmony_ci
4062306a36Sopenharmony_cienum {
4162306a36Sopenharmony_ci	MTK_AFE_ADDA_UL_RATE_8K = 0,
4262306a36Sopenharmony_ci	MTK_AFE_ADDA_UL_RATE_16K = 1,
4362306a36Sopenharmony_ci	MTK_AFE_ADDA_UL_RATE_32K = 2,
4462306a36Sopenharmony_ci	MTK_AFE_ADDA_UL_RATE_48K = 3,
4562306a36Sopenharmony_ci	MTK_AFE_ADDA_UL_RATE_96K = 4,
4662306a36Sopenharmony_ci	MTK_AFE_ADDA_UL_RATE_192K = 5,
4762306a36Sopenharmony_ci	MTK_AFE_ADDA_UL_RATE_48K_HD = 6,
4862306a36Sopenharmony_ci};
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_cistatic unsigned int adda_dl_rate_transform(struct mtk_base_afe *afe,
5162306a36Sopenharmony_ci					   unsigned int rate)
5262306a36Sopenharmony_ci{
5362306a36Sopenharmony_ci	switch (rate) {
5462306a36Sopenharmony_ci	case 8000:
5562306a36Sopenharmony_ci		return MTK_AFE_ADDA_DL_RATE_8K;
5662306a36Sopenharmony_ci	case 11025:
5762306a36Sopenharmony_ci		return MTK_AFE_ADDA_DL_RATE_11K;
5862306a36Sopenharmony_ci	case 12000:
5962306a36Sopenharmony_ci		return MTK_AFE_ADDA_DL_RATE_12K;
6062306a36Sopenharmony_ci	case 16000:
6162306a36Sopenharmony_ci		return MTK_AFE_ADDA_DL_RATE_16K;
6262306a36Sopenharmony_ci	case 22050:
6362306a36Sopenharmony_ci		return MTK_AFE_ADDA_DL_RATE_22K;
6462306a36Sopenharmony_ci	case 24000:
6562306a36Sopenharmony_ci		return MTK_AFE_ADDA_DL_RATE_24K;
6662306a36Sopenharmony_ci	case 32000:
6762306a36Sopenharmony_ci		return MTK_AFE_ADDA_DL_RATE_32K;
6862306a36Sopenharmony_ci	case 44100:
6962306a36Sopenharmony_ci		return MTK_AFE_ADDA_DL_RATE_44K;
7062306a36Sopenharmony_ci	case 48000:
7162306a36Sopenharmony_ci		return MTK_AFE_ADDA_DL_RATE_48K;
7262306a36Sopenharmony_ci	case 96000:
7362306a36Sopenharmony_ci		return MTK_AFE_ADDA_DL_RATE_96K;
7462306a36Sopenharmony_ci	case 192000:
7562306a36Sopenharmony_ci		return MTK_AFE_ADDA_DL_RATE_192K;
7662306a36Sopenharmony_ci	default:
7762306a36Sopenharmony_ci		dev_warn(afe->dev, "%s(), rate %d invalid, use 48kHz!!!\n",
7862306a36Sopenharmony_ci			 __func__, rate);
7962306a36Sopenharmony_ci		return MTK_AFE_ADDA_DL_RATE_48K;
8062306a36Sopenharmony_ci	}
8162306a36Sopenharmony_ci}
8262306a36Sopenharmony_ci
8362306a36Sopenharmony_cistatic unsigned int adda_ul_rate_transform(struct mtk_base_afe *afe,
8462306a36Sopenharmony_ci					   unsigned int rate)
8562306a36Sopenharmony_ci{
8662306a36Sopenharmony_ci	switch (rate) {
8762306a36Sopenharmony_ci	case 8000:
8862306a36Sopenharmony_ci		return MTK_AFE_ADDA_UL_RATE_8K;
8962306a36Sopenharmony_ci	case 16000:
9062306a36Sopenharmony_ci		return MTK_AFE_ADDA_UL_RATE_16K;
9162306a36Sopenharmony_ci	case 32000:
9262306a36Sopenharmony_ci		return MTK_AFE_ADDA_UL_RATE_32K;
9362306a36Sopenharmony_ci	case 48000:
9462306a36Sopenharmony_ci		return MTK_AFE_ADDA_UL_RATE_48K;
9562306a36Sopenharmony_ci	case 96000:
9662306a36Sopenharmony_ci		return MTK_AFE_ADDA_UL_RATE_96K;
9762306a36Sopenharmony_ci	case 192000:
9862306a36Sopenharmony_ci		return MTK_AFE_ADDA_UL_RATE_192K;
9962306a36Sopenharmony_ci	default:
10062306a36Sopenharmony_ci		dev_warn(afe->dev, "%s(), rate %d invalid, use 48kHz!!!\n",
10162306a36Sopenharmony_ci			 __func__, rate);
10262306a36Sopenharmony_ci		return MTK_AFE_ADDA_UL_RATE_48K;
10362306a36Sopenharmony_ci	}
10462306a36Sopenharmony_ci}
10562306a36Sopenharmony_ci
10662306a36Sopenharmony_ci/* dai component */
10762306a36Sopenharmony_cistatic const struct snd_kcontrol_new mtk_adda_dl_ch1_mix[] = {
10862306a36Sopenharmony_ci	SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1", AFE_CONN3, I_DL1_CH1, 1, 0),
10962306a36Sopenharmony_ci	SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1", AFE_CONN3, I_DL2_CH1, 1, 0),
11062306a36Sopenharmony_ci	SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1", AFE_CONN3, I_DL3_CH1, 1, 0),
11162306a36Sopenharmony_ci	SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN3,
11262306a36Sopenharmony_ci				    I_ADDA_UL_CH2, 1, 0),
11362306a36Sopenharmony_ci	SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN3,
11462306a36Sopenharmony_ci				    I_ADDA_UL_CH1, 1, 0),
11562306a36Sopenharmony_ci	SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH1", AFE_CONN3,
11662306a36Sopenharmony_ci				    I_PCM_1_CAP_CH1, 1, 0),
11762306a36Sopenharmony_ci	SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH1", AFE_CONN3,
11862306a36Sopenharmony_ci				    I_PCM_2_CAP_CH1, 1, 0),
11962306a36Sopenharmony_ci};
12062306a36Sopenharmony_ci
12162306a36Sopenharmony_cistatic const struct snd_kcontrol_new mtk_adda_dl_ch2_mix[] = {
12262306a36Sopenharmony_ci	SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1", AFE_CONN4, I_DL1_CH1, 1, 0),
12362306a36Sopenharmony_ci	SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH2", AFE_CONN4, I_DL1_CH2, 1, 0),
12462306a36Sopenharmony_ci	SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1", AFE_CONN4, I_DL2_CH1, 1, 0),
12562306a36Sopenharmony_ci	SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH2", AFE_CONN4, I_DL2_CH2, 1, 0),
12662306a36Sopenharmony_ci	SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1", AFE_CONN4, I_DL3_CH1, 1, 0),
12762306a36Sopenharmony_ci	SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH2", AFE_CONN4, I_DL3_CH2, 1, 0),
12862306a36Sopenharmony_ci	SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN4,
12962306a36Sopenharmony_ci				    I_ADDA_UL_CH2, 1, 0),
13062306a36Sopenharmony_ci	SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN4,
13162306a36Sopenharmony_ci				    I_ADDA_UL_CH1, 1, 0),
13262306a36Sopenharmony_ci	SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH1", AFE_CONN4,
13362306a36Sopenharmony_ci				    I_PCM_1_CAP_CH1, 1, 0),
13462306a36Sopenharmony_ci	SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH1", AFE_CONN4,
13562306a36Sopenharmony_ci				    I_PCM_2_CAP_CH1, 1, 0),
13662306a36Sopenharmony_ci	SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH2", AFE_CONN4,
13762306a36Sopenharmony_ci				    I_PCM_1_CAP_CH2, 1, 0),
13862306a36Sopenharmony_ci	SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH2", AFE_CONN4,
13962306a36Sopenharmony_ci				    I_PCM_2_CAP_CH2, 1, 0),
14062306a36Sopenharmony_ci};
14162306a36Sopenharmony_ci
14262306a36Sopenharmony_cistatic int mtk_adda_ul_event(struct snd_soc_dapm_widget *w,
14362306a36Sopenharmony_ci			     struct snd_kcontrol *kcontrol,
14462306a36Sopenharmony_ci			     int event)
14562306a36Sopenharmony_ci{
14662306a36Sopenharmony_ci	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
14762306a36Sopenharmony_ci	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
14862306a36Sopenharmony_ci	struct mt8183_afe_private *afe_priv = afe->platform_priv;
14962306a36Sopenharmony_ci
15062306a36Sopenharmony_ci	dev_dbg(afe->dev, "%s(), name %s, event 0x%x\n",
15162306a36Sopenharmony_ci		__func__, w->name, event);
15262306a36Sopenharmony_ci
15362306a36Sopenharmony_ci	switch (event) {
15462306a36Sopenharmony_ci	case SND_SOC_DAPM_PRE_PMU:
15562306a36Sopenharmony_ci		/* update setting to dmic */
15662306a36Sopenharmony_ci		if (afe_priv->mtkaif_dmic) {
15762306a36Sopenharmony_ci			/* mtkaif_rxif_data_mode = 1, dmic */
15862306a36Sopenharmony_ci			regmap_update_bits(afe->regmap, AFE_ADDA_MTKAIF_RX_CFG0,
15962306a36Sopenharmony_ci					   0x1, 0x1);
16062306a36Sopenharmony_ci
16162306a36Sopenharmony_ci			/* dmic mode, 3.25M*/
16262306a36Sopenharmony_ci			regmap_update_bits(afe->regmap, AFE_ADDA_MTKAIF_RX_CFG0,
16362306a36Sopenharmony_ci					   0x0, 0xf << 20);
16462306a36Sopenharmony_ci			regmap_update_bits(afe->regmap, AFE_ADDA_UL_SRC_CON0,
16562306a36Sopenharmony_ci					   0x0, 0x1 << 5);
16662306a36Sopenharmony_ci			regmap_update_bits(afe->regmap, AFE_ADDA_UL_SRC_CON0,
16762306a36Sopenharmony_ci					   0x0, 0x3 << 14);
16862306a36Sopenharmony_ci
16962306a36Sopenharmony_ci			/* turn on dmic, ch1, ch2 */
17062306a36Sopenharmony_ci			regmap_update_bits(afe->regmap, AFE_ADDA_UL_SRC_CON0,
17162306a36Sopenharmony_ci					   0x1 << 1, 0x1 << 1);
17262306a36Sopenharmony_ci			regmap_update_bits(afe->regmap, AFE_ADDA_UL_SRC_CON0,
17362306a36Sopenharmony_ci					   0x3 << 21, 0x3 << 21);
17462306a36Sopenharmony_ci		}
17562306a36Sopenharmony_ci		break;
17662306a36Sopenharmony_ci	case SND_SOC_DAPM_POST_PMD:
17762306a36Sopenharmony_ci		/* should delayed 1/fs(smallest is 8k) = 125us before afe off */
17862306a36Sopenharmony_ci		usleep_range(125, 135);
17962306a36Sopenharmony_ci		break;
18062306a36Sopenharmony_ci	default:
18162306a36Sopenharmony_ci		break;
18262306a36Sopenharmony_ci	}
18362306a36Sopenharmony_ci
18462306a36Sopenharmony_ci	return 0;
18562306a36Sopenharmony_ci}
18662306a36Sopenharmony_ci
18762306a36Sopenharmony_ci/* mtkaif dmic */
18862306a36Sopenharmony_cistatic const char * const mt8183_adda_off_on_str[] = {
18962306a36Sopenharmony_ci	"Off", "On"
19062306a36Sopenharmony_ci};
19162306a36Sopenharmony_ci
19262306a36Sopenharmony_cistatic const struct soc_enum mt8183_adda_enum[] = {
19362306a36Sopenharmony_ci	SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(mt8183_adda_off_on_str),
19462306a36Sopenharmony_ci			    mt8183_adda_off_on_str),
19562306a36Sopenharmony_ci};
19662306a36Sopenharmony_ci
19762306a36Sopenharmony_cistatic int mt8183_adda_dmic_get(struct snd_kcontrol *kcontrol,
19862306a36Sopenharmony_ci				struct snd_ctl_elem_value *ucontrol)
19962306a36Sopenharmony_ci{
20062306a36Sopenharmony_ci	struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
20162306a36Sopenharmony_ci	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
20262306a36Sopenharmony_ci	struct mt8183_afe_private *afe_priv = afe->platform_priv;
20362306a36Sopenharmony_ci
20462306a36Sopenharmony_ci	ucontrol->value.integer.value[0] = afe_priv->mtkaif_dmic;
20562306a36Sopenharmony_ci
20662306a36Sopenharmony_ci	return 0;
20762306a36Sopenharmony_ci}
20862306a36Sopenharmony_ci
20962306a36Sopenharmony_cistatic int mt8183_adda_dmic_set(struct snd_kcontrol *kcontrol,
21062306a36Sopenharmony_ci				struct snd_ctl_elem_value *ucontrol)
21162306a36Sopenharmony_ci{
21262306a36Sopenharmony_ci	struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
21362306a36Sopenharmony_ci	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
21462306a36Sopenharmony_ci	struct mt8183_afe_private *afe_priv = afe->platform_priv;
21562306a36Sopenharmony_ci	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
21662306a36Sopenharmony_ci
21762306a36Sopenharmony_ci	if (ucontrol->value.enumerated.item[0] >= e->items)
21862306a36Sopenharmony_ci		return -EINVAL;
21962306a36Sopenharmony_ci
22062306a36Sopenharmony_ci	afe_priv->mtkaif_dmic = ucontrol->value.integer.value[0];
22162306a36Sopenharmony_ci
22262306a36Sopenharmony_ci	dev_info(afe->dev, "%s(), kcontrol name %s, mtkaif_dmic %d\n",
22362306a36Sopenharmony_ci		 __func__, kcontrol->id.name, afe_priv->mtkaif_dmic);
22462306a36Sopenharmony_ci
22562306a36Sopenharmony_ci	return 0;
22662306a36Sopenharmony_ci}
22762306a36Sopenharmony_ci
22862306a36Sopenharmony_cistatic const struct snd_kcontrol_new mtk_adda_controls[] = {
22962306a36Sopenharmony_ci	SOC_ENUM_EXT("MTKAIF_DMIC", mt8183_adda_enum[0],
23062306a36Sopenharmony_ci		     mt8183_adda_dmic_get, mt8183_adda_dmic_set),
23162306a36Sopenharmony_ci};
23262306a36Sopenharmony_ci
23362306a36Sopenharmony_cienum {
23462306a36Sopenharmony_ci	SUPPLY_SEQ_ADDA_AFE_ON,
23562306a36Sopenharmony_ci	SUPPLY_SEQ_ADDA_DL_ON,
23662306a36Sopenharmony_ci	SUPPLY_SEQ_ADDA_UL_ON,
23762306a36Sopenharmony_ci};
23862306a36Sopenharmony_ci
23962306a36Sopenharmony_cistatic const struct snd_soc_dapm_widget mtk_dai_adda_widgets[] = {
24062306a36Sopenharmony_ci	/* adda */
24162306a36Sopenharmony_ci	SND_SOC_DAPM_MIXER("ADDA_DL_CH1", SND_SOC_NOPM, 0, 0,
24262306a36Sopenharmony_ci			   mtk_adda_dl_ch1_mix,
24362306a36Sopenharmony_ci			   ARRAY_SIZE(mtk_adda_dl_ch1_mix)),
24462306a36Sopenharmony_ci	SND_SOC_DAPM_MIXER("ADDA_DL_CH2", SND_SOC_NOPM, 0, 0,
24562306a36Sopenharmony_ci			   mtk_adda_dl_ch2_mix,
24662306a36Sopenharmony_ci			   ARRAY_SIZE(mtk_adda_dl_ch2_mix)),
24762306a36Sopenharmony_ci
24862306a36Sopenharmony_ci	SND_SOC_DAPM_SUPPLY_S("ADDA Enable", SUPPLY_SEQ_ADDA_AFE_ON,
24962306a36Sopenharmony_ci			      AFE_ADDA_UL_DL_CON0, ADDA_AFE_ON_SFT, 0,
25062306a36Sopenharmony_ci			      NULL, 0),
25162306a36Sopenharmony_ci
25262306a36Sopenharmony_ci	SND_SOC_DAPM_SUPPLY_S("ADDA Playback Enable", SUPPLY_SEQ_ADDA_DL_ON,
25362306a36Sopenharmony_ci			      AFE_ADDA_DL_SRC2_CON0,
25462306a36Sopenharmony_ci			      DL_2_SRC_ON_TMP_CTL_PRE_SFT, 0,
25562306a36Sopenharmony_ci			      NULL, 0),
25662306a36Sopenharmony_ci
25762306a36Sopenharmony_ci	SND_SOC_DAPM_SUPPLY_S("ADDA Capture Enable", SUPPLY_SEQ_ADDA_UL_ON,
25862306a36Sopenharmony_ci			      AFE_ADDA_UL_SRC_CON0,
25962306a36Sopenharmony_ci			      UL_SRC_ON_TMP_CTL_SFT, 0,
26062306a36Sopenharmony_ci			      mtk_adda_ul_event,
26162306a36Sopenharmony_ci			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
26262306a36Sopenharmony_ci
26362306a36Sopenharmony_ci	SND_SOC_DAPM_CLOCK_SUPPLY("aud_dac_clk"),
26462306a36Sopenharmony_ci	SND_SOC_DAPM_CLOCK_SUPPLY("aud_dac_predis_clk"),
26562306a36Sopenharmony_ci	SND_SOC_DAPM_CLOCK_SUPPLY("aud_adc_clk"),
26662306a36Sopenharmony_ci	SND_SOC_DAPM_CLOCK_SUPPLY("mtkaif_26m_clk"),
26762306a36Sopenharmony_ci};
26862306a36Sopenharmony_ci
26962306a36Sopenharmony_cistatic const struct snd_soc_dapm_route mtk_dai_adda_routes[] = {
27062306a36Sopenharmony_ci	/* playback */
27162306a36Sopenharmony_ci	{"ADDA_DL_CH1", "DL1_CH1", "DL1"},
27262306a36Sopenharmony_ci	{"ADDA_DL_CH2", "DL1_CH1", "DL1"},
27362306a36Sopenharmony_ci	{"ADDA_DL_CH2", "DL1_CH2", "DL1"},
27462306a36Sopenharmony_ci
27562306a36Sopenharmony_ci	{"ADDA_DL_CH1", "DL2_CH1", "DL2"},
27662306a36Sopenharmony_ci	{"ADDA_DL_CH2", "DL2_CH1", "DL2"},
27762306a36Sopenharmony_ci	{"ADDA_DL_CH2", "DL2_CH2", "DL2"},
27862306a36Sopenharmony_ci
27962306a36Sopenharmony_ci	{"ADDA_DL_CH1", "DL3_CH1", "DL3"},
28062306a36Sopenharmony_ci	{"ADDA_DL_CH2", "DL3_CH1", "DL3"},
28162306a36Sopenharmony_ci	{"ADDA_DL_CH2", "DL3_CH2", "DL3"},
28262306a36Sopenharmony_ci
28362306a36Sopenharmony_ci	{"ADDA Playback", NULL, "ADDA_DL_CH1"},
28462306a36Sopenharmony_ci	{"ADDA Playback", NULL, "ADDA_DL_CH2"},
28562306a36Sopenharmony_ci
28662306a36Sopenharmony_ci	/* adda enable */
28762306a36Sopenharmony_ci	{"ADDA Playback", NULL, "ADDA Enable"},
28862306a36Sopenharmony_ci	{"ADDA Playback", NULL, "ADDA Playback Enable"},
28962306a36Sopenharmony_ci	{"ADDA Capture", NULL, "ADDA Enable"},
29062306a36Sopenharmony_ci	{"ADDA Capture", NULL, "ADDA Capture Enable"},
29162306a36Sopenharmony_ci
29262306a36Sopenharmony_ci	/* clk */
29362306a36Sopenharmony_ci	{"ADDA Playback", NULL, "mtkaif_26m_clk"},
29462306a36Sopenharmony_ci	{"ADDA Playback", NULL, "aud_dac_clk"},
29562306a36Sopenharmony_ci	{"ADDA Playback", NULL, "aud_dac_predis_clk"},
29662306a36Sopenharmony_ci
29762306a36Sopenharmony_ci	{"ADDA Capture", NULL, "mtkaif_26m_clk"},
29862306a36Sopenharmony_ci	{"ADDA Capture", NULL, "aud_adc_clk"},
29962306a36Sopenharmony_ci};
30062306a36Sopenharmony_ci
30162306a36Sopenharmony_cistatic int set_mtkaif_rx(struct mtk_base_afe *afe)
30262306a36Sopenharmony_ci{
30362306a36Sopenharmony_ci	struct mt8183_afe_private *afe_priv = afe->platform_priv;
30462306a36Sopenharmony_ci	int delay_data;
30562306a36Sopenharmony_ci	int delay_cycle;
30662306a36Sopenharmony_ci
30762306a36Sopenharmony_ci	switch (afe_priv->mtkaif_protocol) {
30862306a36Sopenharmony_ci	case MT8183_MTKAIF_PROTOCOL_2_CLK_P2:
30962306a36Sopenharmony_ci		regmap_write(afe->regmap, AFE_AUD_PAD_TOP, 0x38);
31062306a36Sopenharmony_ci		regmap_write(afe->regmap, AFE_AUD_PAD_TOP, 0x39);
31162306a36Sopenharmony_ci		/* mtkaif_rxif_clkinv_adc inverse for calibration */
31262306a36Sopenharmony_ci		regmap_write(afe->regmap, AFE_ADDA_MTKAIF_CFG0,
31362306a36Sopenharmony_ci			     0x80010000);
31462306a36Sopenharmony_ci
31562306a36Sopenharmony_ci		if (afe_priv->mtkaif_phase_cycle[0] >=
31662306a36Sopenharmony_ci		    afe_priv->mtkaif_phase_cycle[1]) {
31762306a36Sopenharmony_ci			delay_data = DELAY_DATA_MISO1;
31862306a36Sopenharmony_ci			delay_cycle = afe_priv->mtkaif_phase_cycle[0] -
31962306a36Sopenharmony_ci				      afe_priv->mtkaif_phase_cycle[1];
32062306a36Sopenharmony_ci		} else {
32162306a36Sopenharmony_ci			delay_data = DELAY_DATA_MISO2;
32262306a36Sopenharmony_ci			delay_cycle = afe_priv->mtkaif_phase_cycle[1] -
32362306a36Sopenharmony_ci				      afe_priv->mtkaif_phase_cycle[0];
32462306a36Sopenharmony_ci		}
32562306a36Sopenharmony_ci
32662306a36Sopenharmony_ci		regmap_update_bits(afe->regmap,
32762306a36Sopenharmony_ci				   AFE_ADDA_MTKAIF_RX_CFG2,
32862306a36Sopenharmony_ci				   MTKAIF_RXIF_DELAY_DATA_MASK_SFT,
32962306a36Sopenharmony_ci				   delay_data << MTKAIF_RXIF_DELAY_DATA_SFT);
33062306a36Sopenharmony_ci
33162306a36Sopenharmony_ci		regmap_update_bits(afe->regmap,
33262306a36Sopenharmony_ci				   AFE_ADDA_MTKAIF_RX_CFG2,
33362306a36Sopenharmony_ci				   MTKAIF_RXIF_DELAY_CYCLE_MASK_SFT,
33462306a36Sopenharmony_ci				   delay_cycle << MTKAIF_RXIF_DELAY_CYCLE_SFT);
33562306a36Sopenharmony_ci		break;
33662306a36Sopenharmony_ci	case MT8183_MTKAIF_PROTOCOL_2:
33762306a36Sopenharmony_ci		regmap_write(afe->regmap, AFE_AUD_PAD_TOP, 0x31);
33862306a36Sopenharmony_ci		regmap_write(afe->regmap, AFE_ADDA_MTKAIF_CFG0,
33962306a36Sopenharmony_ci			     0x00010000);
34062306a36Sopenharmony_ci		break;
34162306a36Sopenharmony_ci	case MT8183_MTKAIF_PROTOCOL_1:
34262306a36Sopenharmony_ci		regmap_write(afe->regmap, AFE_AUD_PAD_TOP, 0x31);
34362306a36Sopenharmony_ci		regmap_write(afe->regmap, AFE_ADDA_MTKAIF_CFG0, 0x0);
34462306a36Sopenharmony_ci		break;
34562306a36Sopenharmony_ci	default:
34662306a36Sopenharmony_ci		break;
34762306a36Sopenharmony_ci	}
34862306a36Sopenharmony_ci
34962306a36Sopenharmony_ci	return 0;
35062306a36Sopenharmony_ci}
35162306a36Sopenharmony_ci
35262306a36Sopenharmony_ci/* dai ops */
35362306a36Sopenharmony_cistatic int mtk_dai_adda_hw_params(struct snd_pcm_substream *substream,
35462306a36Sopenharmony_ci				  struct snd_pcm_hw_params *params,
35562306a36Sopenharmony_ci				  struct snd_soc_dai *dai)
35662306a36Sopenharmony_ci{
35762306a36Sopenharmony_ci	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
35862306a36Sopenharmony_ci	unsigned int rate = params_rate(params);
35962306a36Sopenharmony_ci
36062306a36Sopenharmony_ci	dev_dbg(afe->dev, "%s(), id %d, stream %d, rate %d\n",
36162306a36Sopenharmony_ci		__func__, dai->id, substream->stream, rate);
36262306a36Sopenharmony_ci
36362306a36Sopenharmony_ci	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
36462306a36Sopenharmony_ci		unsigned int dl_src2_con0 = 0;
36562306a36Sopenharmony_ci		unsigned int dl_src2_con1 = 0;
36662306a36Sopenharmony_ci
36762306a36Sopenharmony_ci		/* clean predistortion */
36862306a36Sopenharmony_ci		regmap_write(afe->regmap, AFE_ADDA_PREDIS_CON0, 0);
36962306a36Sopenharmony_ci		regmap_write(afe->regmap, AFE_ADDA_PREDIS_CON1, 0);
37062306a36Sopenharmony_ci
37162306a36Sopenharmony_ci		/* set sampling rate */
37262306a36Sopenharmony_ci		dl_src2_con0 = adda_dl_rate_transform(afe, rate) << 28;
37362306a36Sopenharmony_ci
37462306a36Sopenharmony_ci		/* set output mode */
37562306a36Sopenharmony_ci		switch (rate) {
37662306a36Sopenharmony_ci		case 192000:
37762306a36Sopenharmony_ci			dl_src2_con0 |= (0x1 << 24); /* UP_SAMPLING_RATE_X2 */
37862306a36Sopenharmony_ci			dl_src2_con0 |= 1 << 14;
37962306a36Sopenharmony_ci			break;
38062306a36Sopenharmony_ci		case 96000:
38162306a36Sopenharmony_ci			dl_src2_con0 |= (0x2 << 24); /* UP_SAMPLING_RATE_X4 */
38262306a36Sopenharmony_ci			dl_src2_con0 |= 1 << 14;
38362306a36Sopenharmony_ci			break;
38462306a36Sopenharmony_ci		default:
38562306a36Sopenharmony_ci			dl_src2_con0 |= (0x3 << 24); /* UP_SAMPLING_RATE_X8 */
38662306a36Sopenharmony_ci			break;
38762306a36Sopenharmony_ci		}
38862306a36Sopenharmony_ci
38962306a36Sopenharmony_ci		/* turn off mute function */
39062306a36Sopenharmony_ci		dl_src2_con0 |= (0x03 << 11);
39162306a36Sopenharmony_ci
39262306a36Sopenharmony_ci		/* set voice input data if input sample rate is 8k or 16k */
39362306a36Sopenharmony_ci		if (rate == 8000 || rate == 16000)
39462306a36Sopenharmony_ci			dl_src2_con0 |= 0x01 << 5;
39562306a36Sopenharmony_ci
39662306a36Sopenharmony_ci		/* SA suggest apply -0.3db to audio/speech path */
39762306a36Sopenharmony_ci		dl_src2_con1 = 0xf74f0000;
39862306a36Sopenharmony_ci
39962306a36Sopenharmony_ci		/* turn on down-link gain */
40062306a36Sopenharmony_ci		dl_src2_con0 = dl_src2_con0 | (0x01 << 1);
40162306a36Sopenharmony_ci
40262306a36Sopenharmony_ci		regmap_write(afe->regmap, AFE_ADDA_DL_SRC2_CON0, dl_src2_con0);
40362306a36Sopenharmony_ci		regmap_write(afe->regmap, AFE_ADDA_DL_SRC2_CON1, dl_src2_con1);
40462306a36Sopenharmony_ci
40562306a36Sopenharmony_ci		/* set sdm gain */
40662306a36Sopenharmony_ci		regmap_update_bits(afe->regmap,
40762306a36Sopenharmony_ci				   AFE_ADDA_DL_SDM_DCCOMP_CON,
40862306a36Sopenharmony_ci				   ATTGAIN_CTL_MASK_SFT,
40962306a36Sopenharmony_ci				   AUDIO_SDM_LEVEL_NORMAL << ATTGAIN_CTL_SFT);
41062306a36Sopenharmony_ci	} else {
41162306a36Sopenharmony_ci		unsigned int voice_mode = 0;
41262306a36Sopenharmony_ci		unsigned int ul_src_con0 = 0;	/* default value */
41362306a36Sopenharmony_ci
41462306a36Sopenharmony_ci		/* set mtkaif protocol */
41562306a36Sopenharmony_ci		set_mtkaif_rx(afe);
41662306a36Sopenharmony_ci
41762306a36Sopenharmony_ci		/* Using Internal ADC */
41862306a36Sopenharmony_ci		regmap_update_bits(afe->regmap,
41962306a36Sopenharmony_ci				   AFE_ADDA_TOP_CON0,
42062306a36Sopenharmony_ci				   0x1 << 0,
42162306a36Sopenharmony_ci				   0x0 << 0);
42262306a36Sopenharmony_ci
42362306a36Sopenharmony_ci		voice_mode = adda_ul_rate_transform(afe, rate);
42462306a36Sopenharmony_ci
42562306a36Sopenharmony_ci		ul_src_con0 |= (voice_mode << 17) & (0x7 << 17);
42662306a36Sopenharmony_ci
42762306a36Sopenharmony_ci		/* enable iir */
42862306a36Sopenharmony_ci		ul_src_con0 |= (1 << UL_IIR_ON_TMP_CTL_SFT) &
42962306a36Sopenharmony_ci			       UL_IIR_ON_TMP_CTL_MASK_SFT;
43062306a36Sopenharmony_ci
43162306a36Sopenharmony_ci		/* 35Hz @ 48k */
43262306a36Sopenharmony_ci		regmap_write(afe->regmap, AFE_ADDA_IIR_COEF_02_01, 0x00000000);
43362306a36Sopenharmony_ci		regmap_write(afe->regmap, AFE_ADDA_IIR_COEF_04_03, 0x00003FB8);
43462306a36Sopenharmony_ci		regmap_write(afe->regmap, AFE_ADDA_IIR_COEF_06_05, 0x3FB80000);
43562306a36Sopenharmony_ci		regmap_write(afe->regmap, AFE_ADDA_IIR_COEF_08_07, 0x3FB80000);
43662306a36Sopenharmony_ci		regmap_write(afe->regmap, AFE_ADDA_IIR_COEF_10_09, 0x0000C048);
43762306a36Sopenharmony_ci
43862306a36Sopenharmony_ci		regmap_write(afe->regmap, AFE_ADDA_UL_SRC_CON0, ul_src_con0);
43962306a36Sopenharmony_ci
44062306a36Sopenharmony_ci		/* mtkaif_rxif_data_mode = 0, amic */
44162306a36Sopenharmony_ci		regmap_update_bits(afe->regmap,
44262306a36Sopenharmony_ci				   AFE_ADDA_MTKAIF_RX_CFG0,
44362306a36Sopenharmony_ci				   0x1 << 0,
44462306a36Sopenharmony_ci				   0x0 << 0);
44562306a36Sopenharmony_ci	}
44662306a36Sopenharmony_ci
44762306a36Sopenharmony_ci	return 0;
44862306a36Sopenharmony_ci}
44962306a36Sopenharmony_ci
45062306a36Sopenharmony_cistatic const struct snd_soc_dai_ops mtk_dai_adda_ops = {
45162306a36Sopenharmony_ci	.hw_params = mtk_dai_adda_hw_params,
45262306a36Sopenharmony_ci};
45362306a36Sopenharmony_ci
45462306a36Sopenharmony_ci/* dai driver */
45562306a36Sopenharmony_ci#define MTK_ADDA_PLAYBACK_RATES (SNDRV_PCM_RATE_8000_48000 |\
45662306a36Sopenharmony_ci				 SNDRV_PCM_RATE_96000 |\
45762306a36Sopenharmony_ci				 SNDRV_PCM_RATE_192000)
45862306a36Sopenharmony_ci
45962306a36Sopenharmony_ci#define MTK_ADDA_CAPTURE_RATES (SNDRV_PCM_RATE_8000 |\
46062306a36Sopenharmony_ci				SNDRV_PCM_RATE_16000 |\
46162306a36Sopenharmony_ci				SNDRV_PCM_RATE_32000 |\
46262306a36Sopenharmony_ci				SNDRV_PCM_RATE_48000)
46362306a36Sopenharmony_ci
46462306a36Sopenharmony_ci#define MTK_ADDA_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
46562306a36Sopenharmony_ci			  SNDRV_PCM_FMTBIT_S24_LE |\
46662306a36Sopenharmony_ci			  SNDRV_PCM_FMTBIT_S32_LE)
46762306a36Sopenharmony_ci
46862306a36Sopenharmony_cistatic struct snd_soc_dai_driver mtk_dai_adda_driver[] = {
46962306a36Sopenharmony_ci	{
47062306a36Sopenharmony_ci		.name = "ADDA",
47162306a36Sopenharmony_ci		.id = MT8183_DAI_ADDA,
47262306a36Sopenharmony_ci		.playback = {
47362306a36Sopenharmony_ci			.stream_name = "ADDA Playback",
47462306a36Sopenharmony_ci			.channels_min = 1,
47562306a36Sopenharmony_ci			.channels_max = 2,
47662306a36Sopenharmony_ci			.rates = MTK_ADDA_PLAYBACK_RATES,
47762306a36Sopenharmony_ci			.formats = MTK_ADDA_FORMATS,
47862306a36Sopenharmony_ci		},
47962306a36Sopenharmony_ci		.capture = {
48062306a36Sopenharmony_ci			.stream_name = "ADDA Capture",
48162306a36Sopenharmony_ci			.channels_min = 1,
48262306a36Sopenharmony_ci			.channels_max = 2,
48362306a36Sopenharmony_ci			.rates = MTK_ADDA_CAPTURE_RATES,
48462306a36Sopenharmony_ci			.formats = MTK_ADDA_FORMATS,
48562306a36Sopenharmony_ci		},
48662306a36Sopenharmony_ci		.ops = &mtk_dai_adda_ops,
48762306a36Sopenharmony_ci	},
48862306a36Sopenharmony_ci};
48962306a36Sopenharmony_ci
49062306a36Sopenharmony_ciint mt8183_dai_adda_register(struct mtk_base_afe *afe)
49162306a36Sopenharmony_ci{
49262306a36Sopenharmony_ci	struct mtk_base_afe_dai *dai;
49362306a36Sopenharmony_ci
49462306a36Sopenharmony_ci	dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL);
49562306a36Sopenharmony_ci	if (!dai)
49662306a36Sopenharmony_ci		return -ENOMEM;
49762306a36Sopenharmony_ci
49862306a36Sopenharmony_ci	list_add(&dai->list, &afe->sub_dais);
49962306a36Sopenharmony_ci
50062306a36Sopenharmony_ci	dai->dai_drivers = mtk_dai_adda_driver;
50162306a36Sopenharmony_ci	dai->num_dai_drivers = ARRAY_SIZE(mtk_dai_adda_driver);
50262306a36Sopenharmony_ci
50362306a36Sopenharmony_ci	dai->controls = mtk_adda_controls;
50462306a36Sopenharmony_ci	dai->num_controls = ARRAY_SIZE(mtk_adda_controls);
50562306a36Sopenharmony_ci	dai->dapm_widgets = mtk_dai_adda_widgets;
50662306a36Sopenharmony_ci	dai->num_dapm_widgets = ARRAY_SIZE(mtk_dai_adda_widgets);
50762306a36Sopenharmony_ci	dai->dapm_routes = mtk_dai_adda_routes;
50862306a36Sopenharmony_ci	dai->num_dapm_routes = ARRAY_SIZE(mtk_dai_adda_routes);
50962306a36Sopenharmony_ci	return 0;
51062306a36Sopenharmony_ci}
511