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) 2022 MediaTek Inc.
662306a36Sopenharmony_ci * Author: Bicycle Tsai <bicycle.tsai@mediatek.com>
762306a36Sopenharmony_ci *         Trevor Wu <trevor.wu@mediatek.com>
862306a36Sopenharmony_ci *         Chun-Chia Chiu <chun-chia.chiu@mediatek.com>
962306a36Sopenharmony_ci */
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ci#include <linux/bitfield.h>
1262306a36Sopenharmony_ci#include <linux/delay.h>
1362306a36Sopenharmony_ci#include <linux/regmap.h>
1462306a36Sopenharmony_ci#include "mt8188-afe-clk.h"
1562306a36Sopenharmony_ci#include "mt8188-afe-common.h"
1662306a36Sopenharmony_ci#include "mt8188-reg.h"
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_ci#define ADDA_HIRES_THRES 48000
1962306a36Sopenharmony_ci
2062306a36Sopenharmony_cienum {
2162306a36Sopenharmony_ci	SUPPLY_SEQ_ADDA_DL_ON,
2262306a36Sopenharmony_ci	SUPPLY_SEQ_ADDA_MTKAIF_CFG,
2362306a36Sopenharmony_ci	SUPPLY_SEQ_ADDA_UL_ON,
2462306a36Sopenharmony_ci	SUPPLY_SEQ_ADDA_AFE_ON,
2562306a36Sopenharmony_ci};
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_cienum {
2862306a36Sopenharmony_ci	MTK_AFE_ADDA_DL_RATE_8K = 0,
2962306a36Sopenharmony_ci	MTK_AFE_ADDA_DL_RATE_11K = 1,
3062306a36Sopenharmony_ci	MTK_AFE_ADDA_DL_RATE_12K = 2,
3162306a36Sopenharmony_ci	MTK_AFE_ADDA_DL_RATE_16K = 3,
3262306a36Sopenharmony_ci	MTK_AFE_ADDA_DL_RATE_22K = 4,
3362306a36Sopenharmony_ci	MTK_AFE_ADDA_DL_RATE_24K = 5,
3462306a36Sopenharmony_ci	MTK_AFE_ADDA_DL_RATE_32K = 6,
3562306a36Sopenharmony_ci	MTK_AFE_ADDA_DL_RATE_44K = 7,
3662306a36Sopenharmony_ci	MTK_AFE_ADDA_DL_RATE_48K = 8,
3762306a36Sopenharmony_ci	MTK_AFE_ADDA_DL_RATE_96K = 9,
3862306a36Sopenharmony_ci	MTK_AFE_ADDA_DL_RATE_192K = 10,
3962306a36Sopenharmony_ci};
4062306a36Sopenharmony_ci
4162306a36Sopenharmony_cienum {
4262306a36Sopenharmony_ci	MTK_AFE_ADDA_UL_RATE_8K = 0,
4362306a36Sopenharmony_ci	MTK_AFE_ADDA_UL_RATE_16K = 1,
4462306a36Sopenharmony_ci	MTK_AFE_ADDA_UL_RATE_32K = 2,
4562306a36Sopenharmony_ci	MTK_AFE_ADDA_UL_RATE_48K = 3,
4662306a36Sopenharmony_ci	MTK_AFE_ADDA_UL_RATE_96K = 4,
4762306a36Sopenharmony_ci	MTK_AFE_ADDA_UL_RATE_192K = 5,
4862306a36Sopenharmony_ci};
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_cienum {
5162306a36Sopenharmony_ci	DELAY_DATA_MISO1 = 0,
5262306a36Sopenharmony_ci	DELAY_DATA_MISO0 = 1,
5362306a36Sopenharmony_ci};
5462306a36Sopenharmony_ci
5562306a36Sopenharmony_cistruct mtk_dai_adda_priv {
5662306a36Sopenharmony_ci	bool hires_required;
5762306a36Sopenharmony_ci};
5862306a36Sopenharmony_ci
5962306a36Sopenharmony_cistatic unsigned int afe_adda_dl_rate_transform(struct mtk_base_afe *afe,
6062306a36Sopenharmony_ci					       unsigned int rate)
6162306a36Sopenharmony_ci{
6262306a36Sopenharmony_ci	switch (rate) {
6362306a36Sopenharmony_ci	case 8000:
6462306a36Sopenharmony_ci		return MTK_AFE_ADDA_DL_RATE_8K;
6562306a36Sopenharmony_ci	case 11025:
6662306a36Sopenharmony_ci		return MTK_AFE_ADDA_DL_RATE_11K;
6762306a36Sopenharmony_ci	case 12000:
6862306a36Sopenharmony_ci		return MTK_AFE_ADDA_DL_RATE_12K;
6962306a36Sopenharmony_ci	case 16000:
7062306a36Sopenharmony_ci		return MTK_AFE_ADDA_DL_RATE_16K;
7162306a36Sopenharmony_ci	case 22050:
7262306a36Sopenharmony_ci		return MTK_AFE_ADDA_DL_RATE_22K;
7362306a36Sopenharmony_ci	case 24000:
7462306a36Sopenharmony_ci		return MTK_AFE_ADDA_DL_RATE_24K;
7562306a36Sopenharmony_ci	case 32000:
7662306a36Sopenharmony_ci		return MTK_AFE_ADDA_DL_RATE_32K;
7762306a36Sopenharmony_ci	case 44100:
7862306a36Sopenharmony_ci		return MTK_AFE_ADDA_DL_RATE_44K;
7962306a36Sopenharmony_ci	case 48000:
8062306a36Sopenharmony_ci		return MTK_AFE_ADDA_DL_RATE_48K;
8162306a36Sopenharmony_ci	case 96000:
8262306a36Sopenharmony_ci		return MTK_AFE_ADDA_DL_RATE_96K;
8362306a36Sopenharmony_ci	case 192000:
8462306a36Sopenharmony_ci		return MTK_AFE_ADDA_DL_RATE_192K;
8562306a36Sopenharmony_ci	default:
8662306a36Sopenharmony_ci		dev_info(afe->dev, "%s(), rate %u invalid, use 48kHz!!!\n",
8762306a36Sopenharmony_ci			 __func__, rate);
8862306a36Sopenharmony_ci		return MTK_AFE_ADDA_DL_RATE_48K;
8962306a36Sopenharmony_ci	}
9062306a36Sopenharmony_ci}
9162306a36Sopenharmony_ci
9262306a36Sopenharmony_cistatic unsigned int afe_adda_ul_rate_transform(struct mtk_base_afe *afe,
9362306a36Sopenharmony_ci					       unsigned int rate)
9462306a36Sopenharmony_ci{
9562306a36Sopenharmony_ci	switch (rate) {
9662306a36Sopenharmony_ci	case 8000:
9762306a36Sopenharmony_ci		return MTK_AFE_ADDA_UL_RATE_8K;
9862306a36Sopenharmony_ci	case 16000:
9962306a36Sopenharmony_ci		return MTK_AFE_ADDA_UL_RATE_16K;
10062306a36Sopenharmony_ci	case 32000:
10162306a36Sopenharmony_ci		return MTK_AFE_ADDA_UL_RATE_32K;
10262306a36Sopenharmony_ci	case 48000:
10362306a36Sopenharmony_ci		return MTK_AFE_ADDA_UL_RATE_48K;
10462306a36Sopenharmony_ci	case 96000:
10562306a36Sopenharmony_ci		return MTK_AFE_ADDA_UL_RATE_96K;
10662306a36Sopenharmony_ci	case 192000:
10762306a36Sopenharmony_ci		return MTK_AFE_ADDA_UL_RATE_192K;
10862306a36Sopenharmony_ci	default:
10962306a36Sopenharmony_ci		dev_info(afe->dev, "%s(), rate %u invalid, use 48kHz!!!\n",
11062306a36Sopenharmony_ci			 __func__, rate);
11162306a36Sopenharmony_ci		return MTK_AFE_ADDA_UL_RATE_48K;
11262306a36Sopenharmony_ci	}
11362306a36Sopenharmony_ci}
11462306a36Sopenharmony_ci
11562306a36Sopenharmony_cistatic int mt8188_adda_mtkaif_init(struct mtk_base_afe *afe)
11662306a36Sopenharmony_ci{
11762306a36Sopenharmony_ci	struct mt8188_afe_private *afe_priv = afe->platform_priv;
11862306a36Sopenharmony_ci	struct mtkaif_param *param = &afe_priv->mtkaif_params;
11962306a36Sopenharmony_ci	int delay_data;
12062306a36Sopenharmony_ci	int delay_cycle;
12162306a36Sopenharmony_ci	unsigned int mask = 0;
12262306a36Sopenharmony_ci	unsigned int val = 0;
12362306a36Sopenharmony_ci
12462306a36Sopenharmony_ci	/* set rx protocol 2 & mtkaif_rxif_clkinv_adc inverse */
12562306a36Sopenharmony_ci	regmap_set_bits(afe->regmap, AFE_ADDA_MTKAIF_CFG0,
12662306a36Sopenharmony_ci			MTKAIF_RXIF_CLKINV_ADC | MTKAIF_RXIF_PROTOCOL2);
12762306a36Sopenharmony_ci
12862306a36Sopenharmony_ci	regmap_set_bits(afe->regmap, AFE_AUD_PAD_TOP, RG_RX_PROTOCOL2);
12962306a36Sopenharmony_ci
13062306a36Sopenharmony_ci	if (!param->mtkaif_calibration_ok) {
13162306a36Sopenharmony_ci		dev_info(afe->dev, "%s(), calibration fail\n",  __func__);
13262306a36Sopenharmony_ci		return 0;
13362306a36Sopenharmony_ci	}
13462306a36Sopenharmony_ci
13562306a36Sopenharmony_ci	/* set delay for ch1, ch2 */
13662306a36Sopenharmony_ci	if (param->mtkaif_phase_cycle[MT8188_MTKAIF_MISO_0] >=
13762306a36Sopenharmony_ci	    param->mtkaif_phase_cycle[MT8188_MTKAIF_MISO_1]) {
13862306a36Sopenharmony_ci		delay_data = DELAY_DATA_MISO1;
13962306a36Sopenharmony_ci		delay_cycle =
14062306a36Sopenharmony_ci			param->mtkaif_phase_cycle[MT8188_MTKAIF_MISO_0] -
14162306a36Sopenharmony_ci			param->mtkaif_phase_cycle[MT8188_MTKAIF_MISO_1];
14262306a36Sopenharmony_ci	} else {
14362306a36Sopenharmony_ci		delay_data = DELAY_DATA_MISO0;
14462306a36Sopenharmony_ci		delay_cycle =
14562306a36Sopenharmony_ci			param->mtkaif_phase_cycle[MT8188_MTKAIF_MISO_1] -
14662306a36Sopenharmony_ci			param->mtkaif_phase_cycle[MT8188_MTKAIF_MISO_0];
14762306a36Sopenharmony_ci	}
14862306a36Sopenharmony_ci
14962306a36Sopenharmony_ci	val = 0;
15062306a36Sopenharmony_ci	mask = (MTKAIF_RXIF_DELAY_DATA | MTKAIF_RXIF_DELAY_CYCLE_MASK);
15162306a36Sopenharmony_ci	val |= FIELD_PREP(MTKAIF_RXIF_DELAY_CYCLE_MASK, delay_cycle);
15262306a36Sopenharmony_ci	val |= FIELD_PREP(MTKAIF_RXIF_DELAY_DATA, delay_data);
15362306a36Sopenharmony_ci	regmap_update_bits(afe->regmap, AFE_ADDA_MTKAIF_RX_CFG2, mask, val);
15462306a36Sopenharmony_ci
15562306a36Sopenharmony_ci	return 0;
15662306a36Sopenharmony_ci}
15762306a36Sopenharmony_ci
15862306a36Sopenharmony_cistatic int mtk_adda_mtkaif_cfg_event(struct snd_soc_dapm_widget *w,
15962306a36Sopenharmony_ci				     struct snd_kcontrol *kcontrol,
16062306a36Sopenharmony_ci				     int event)
16162306a36Sopenharmony_ci{
16262306a36Sopenharmony_ci	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
16362306a36Sopenharmony_ci	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
16462306a36Sopenharmony_ci
16562306a36Sopenharmony_ci	dev_dbg(afe->dev, "%s(), name %s, event 0x%x\n",
16662306a36Sopenharmony_ci		__func__, w->name, event);
16762306a36Sopenharmony_ci
16862306a36Sopenharmony_ci	switch (event) {
16962306a36Sopenharmony_ci	case SND_SOC_DAPM_PRE_PMU:
17062306a36Sopenharmony_ci		mt8188_adda_mtkaif_init(afe);
17162306a36Sopenharmony_ci		break;
17262306a36Sopenharmony_ci	default:
17362306a36Sopenharmony_ci		break;
17462306a36Sopenharmony_ci	}
17562306a36Sopenharmony_ci
17662306a36Sopenharmony_ci	return 0;
17762306a36Sopenharmony_ci}
17862306a36Sopenharmony_ci
17962306a36Sopenharmony_cistatic int mtk_adda_dl_event(struct snd_soc_dapm_widget *w,
18062306a36Sopenharmony_ci			     struct snd_kcontrol *kcontrol,
18162306a36Sopenharmony_ci			     int event)
18262306a36Sopenharmony_ci{
18362306a36Sopenharmony_ci	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
18462306a36Sopenharmony_ci	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
18562306a36Sopenharmony_ci
18662306a36Sopenharmony_ci	dev_dbg(afe->dev, "%s(), name %s, event 0x%x\n",
18762306a36Sopenharmony_ci		__func__, w->name, event);
18862306a36Sopenharmony_ci
18962306a36Sopenharmony_ci	switch (event) {
19062306a36Sopenharmony_ci	case SND_SOC_DAPM_POST_PMD:
19162306a36Sopenharmony_ci		/* should delayed 1/fs(smallest is 8k) = 125us before afe off */
19262306a36Sopenharmony_ci		usleep_range(125, 135);
19362306a36Sopenharmony_ci		break;
19462306a36Sopenharmony_ci	default:
19562306a36Sopenharmony_ci		break;
19662306a36Sopenharmony_ci	}
19762306a36Sopenharmony_ci
19862306a36Sopenharmony_ci	return 0;
19962306a36Sopenharmony_ci}
20062306a36Sopenharmony_ci
20162306a36Sopenharmony_cistatic void mtk_adda_ul_mictype(struct mtk_base_afe *afe, bool dmic)
20262306a36Sopenharmony_ci{
20362306a36Sopenharmony_ci	unsigned int reg = AFE_ADDA_UL_SRC_CON0;
20462306a36Sopenharmony_ci	unsigned int val;
20562306a36Sopenharmony_ci
20662306a36Sopenharmony_ci	val = (UL_SDM3_LEVEL_CTL | UL_MODE_3P25M_CH1_CTL |
20762306a36Sopenharmony_ci	       UL_MODE_3P25M_CH2_CTL);
20862306a36Sopenharmony_ci
20962306a36Sopenharmony_ci	/* turn on dmic, ch1, ch2 */
21062306a36Sopenharmony_ci	if (dmic)
21162306a36Sopenharmony_ci		regmap_set_bits(afe->regmap, reg, val);
21262306a36Sopenharmony_ci	else
21362306a36Sopenharmony_ci		regmap_clear_bits(afe->regmap, reg, val);
21462306a36Sopenharmony_ci}
21562306a36Sopenharmony_ci
21662306a36Sopenharmony_cistatic int mtk_adda_ul_event(struct snd_soc_dapm_widget *w,
21762306a36Sopenharmony_ci			     struct snd_kcontrol *kcontrol,
21862306a36Sopenharmony_ci			     int event)
21962306a36Sopenharmony_ci{
22062306a36Sopenharmony_ci	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
22162306a36Sopenharmony_ci	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
22262306a36Sopenharmony_ci	struct mt8188_afe_private *afe_priv = afe->platform_priv;
22362306a36Sopenharmony_ci	struct mtkaif_param *param = &afe_priv->mtkaif_params;
22462306a36Sopenharmony_ci
22562306a36Sopenharmony_ci	dev_dbg(afe->dev, "%s(), name %s, event 0x%x\n",
22662306a36Sopenharmony_ci		__func__, w->name, event);
22762306a36Sopenharmony_ci
22862306a36Sopenharmony_ci	switch (event) {
22962306a36Sopenharmony_ci	case SND_SOC_DAPM_PRE_PMU:
23062306a36Sopenharmony_ci		mtk_adda_ul_mictype(afe, param->mtkaif_dmic_on);
23162306a36Sopenharmony_ci		break;
23262306a36Sopenharmony_ci	case SND_SOC_DAPM_POST_PMD:
23362306a36Sopenharmony_ci		/* should delayed 1/fs(smallest is 8k) = 125us before afe off */
23462306a36Sopenharmony_ci		usleep_range(125, 135);
23562306a36Sopenharmony_ci		break;
23662306a36Sopenharmony_ci	default:
23762306a36Sopenharmony_ci		break;
23862306a36Sopenharmony_ci	}
23962306a36Sopenharmony_ci
24062306a36Sopenharmony_ci	return 0;
24162306a36Sopenharmony_ci}
24262306a36Sopenharmony_ci
24362306a36Sopenharmony_cistatic struct mtk_dai_adda_priv *get_adda_priv_by_name(struct mtk_base_afe *afe,
24462306a36Sopenharmony_ci						       const char *name)
24562306a36Sopenharmony_ci{
24662306a36Sopenharmony_ci	struct mt8188_afe_private *afe_priv = afe->platform_priv;
24762306a36Sopenharmony_ci
24862306a36Sopenharmony_ci	if (strstr(name, "aud_adc_hires"))
24962306a36Sopenharmony_ci		return afe_priv->dai_priv[MT8188_AFE_IO_UL_SRC];
25062306a36Sopenharmony_ci	else if (strstr(name, "aud_dac_hires"))
25162306a36Sopenharmony_ci		return afe_priv->dai_priv[MT8188_AFE_IO_DL_SRC];
25262306a36Sopenharmony_ci	else
25362306a36Sopenharmony_ci		return NULL;
25462306a36Sopenharmony_ci}
25562306a36Sopenharmony_ci
25662306a36Sopenharmony_cistatic int mtk_afe_adda_hires_connect(struct snd_soc_dapm_widget *source,
25762306a36Sopenharmony_ci				      struct snd_soc_dapm_widget *sink)
25862306a36Sopenharmony_ci{
25962306a36Sopenharmony_ci	struct snd_soc_dapm_widget *w = source;
26062306a36Sopenharmony_ci	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
26162306a36Sopenharmony_ci	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
26262306a36Sopenharmony_ci	struct mtk_dai_adda_priv *adda_priv;
26362306a36Sopenharmony_ci
26462306a36Sopenharmony_ci	adda_priv = get_adda_priv_by_name(afe, w->name);
26562306a36Sopenharmony_ci
26662306a36Sopenharmony_ci	if (!adda_priv) {
26762306a36Sopenharmony_ci		dev_dbg(afe->dev, "adda_priv == NULL");
26862306a36Sopenharmony_ci		return 0;
26962306a36Sopenharmony_ci	}
27062306a36Sopenharmony_ci
27162306a36Sopenharmony_ci	return (adda_priv->hires_required) ? 1 : 0;
27262306a36Sopenharmony_ci}
27362306a36Sopenharmony_ci
27462306a36Sopenharmony_cistatic const struct snd_kcontrol_new mtk_dai_adda_o176_mix[] = {
27562306a36Sopenharmony_ci	SOC_DAPM_SINGLE_AUTODISABLE("I000 Switch", AFE_CONN176, 0, 1, 0),
27662306a36Sopenharmony_ci	SOC_DAPM_SINGLE_AUTODISABLE("I002 Switch", AFE_CONN176, 2, 1, 0),
27762306a36Sopenharmony_ci	SOC_DAPM_SINGLE_AUTODISABLE("I020 Switch", AFE_CONN176, 20, 1, 0),
27862306a36Sopenharmony_ci	SOC_DAPM_SINGLE_AUTODISABLE("I022 Switch", AFE_CONN176, 22, 1, 0),
27962306a36Sopenharmony_ci	SOC_DAPM_SINGLE_AUTODISABLE("I070 Switch", AFE_CONN176_2, 6, 1, 0),
28062306a36Sopenharmony_ci};
28162306a36Sopenharmony_ci
28262306a36Sopenharmony_cistatic const struct snd_kcontrol_new mtk_dai_adda_o177_mix[] = {
28362306a36Sopenharmony_ci	SOC_DAPM_SINGLE_AUTODISABLE("I001 Switch", AFE_CONN177, 1, 1, 0),
28462306a36Sopenharmony_ci	SOC_DAPM_SINGLE_AUTODISABLE("I003 Switch", AFE_CONN177, 3, 1, 0),
28562306a36Sopenharmony_ci	SOC_DAPM_SINGLE_AUTODISABLE("I021 Switch", AFE_CONN177, 21, 1, 0),
28662306a36Sopenharmony_ci	SOC_DAPM_SINGLE_AUTODISABLE("I023 Switch", AFE_CONN177, 23, 1, 0),
28762306a36Sopenharmony_ci	SOC_DAPM_SINGLE_AUTODISABLE("I071 Switch", AFE_CONN177_2, 7, 1, 0),
28862306a36Sopenharmony_ci};
28962306a36Sopenharmony_ci
29062306a36Sopenharmony_cistatic const char * const adda_dlgain_mux_map[] = {
29162306a36Sopenharmony_ci	"Bypass", "Connect",
29262306a36Sopenharmony_ci};
29362306a36Sopenharmony_ci
29462306a36Sopenharmony_cistatic SOC_ENUM_SINGLE_DECL(adda_dlgain_mux_map_enum,
29562306a36Sopenharmony_ci			    SND_SOC_NOPM, 0,
29662306a36Sopenharmony_ci			    adda_dlgain_mux_map);
29762306a36Sopenharmony_ci
29862306a36Sopenharmony_cistatic const struct snd_kcontrol_new adda_dlgain_mux_control =
29962306a36Sopenharmony_ci	SOC_DAPM_ENUM("DL_GAIN_MUX", adda_dlgain_mux_map_enum);
30062306a36Sopenharmony_ci
30162306a36Sopenharmony_cistatic const struct snd_soc_dapm_widget mtk_dai_adda_widgets[] = {
30262306a36Sopenharmony_ci	SND_SOC_DAPM_MIXER("I168", SND_SOC_NOPM, 0, 0, NULL, 0),
30362306a36Sopenharmony_ci	SND_SOC_DAPM_MIXER("I169", SND_SOC_NOPM, 0, 0, NULL, 0),
30462306a36Sopenharmony_ci
30562306a36Sopenharmony_ci	SND_SOC_DAPM_MIXER("O176", SND_SOC_NOPM, 0, 0,
30662306a36Sopenharmony_ci			   mtk_dai_adda_o176_mix,
30762306a36Sopenharmony_ci			   ARRAY_SIZE(mtk_dai_adda_o176_mix)),
30862306a36Sopenharmony_ci	SND_SOC_DAPM_MIXER("O177", SND_SOC_NOPM, 0, 0,
30962306a36Sopenharmony_ci			   mtk_dai_adda_o177_mix,
31062306a36Sopenharmony_ci			   ARRAY_SIZE(mtk_dai_adda_o177_mix)),
31162306a36Sopenharmony_ci
31262306a36Sopenharmony_ci	SND_SOC_DAPM_SUPPLY_S("ADDA Enable", SUPPLY_SEQ_ADDA_AFE_ON,
31362306a36Sopenharmony_ci			      AFE_ADDA_UL_DL_CON0,
31462306a36Sopenharmony_ci			      ADDA_AFE_ON_SHIFT, 0,
31562306a36Sopenharmony_ci			      NULL,
31662306a36Sopenharmony_ci			      0),
31762306a36Sopenharmony_ci
31862306a36Sopenharmony_ci	SND_SOC_DAPM_SUPPLY_S("ADDA Playback Enable", SUPPLY_SEQ_ADDA_DL_ON,
31962306a36Sopenharmony_ci			      AFE_ADDA_DL_SRC2_CON0,
32062306a36Sopenharmony_ci			      DL_2_SRC_ON_TMP_CTRL_PRE_SHIFT, 0,
32162306a36Sopenharmony_ci			      mtk_adda_dl_event,
32262306a36Sopenharmony_ci			      SND_SOC_DAPM_POST_PMD),
32362306a36Sopenharmony_ci
32462306a36Sopenharmony_ci	SND_SOC_DAPM_SUPPLY_S("ADDA Capture Enable", SUPPLY_SEQ_ADDA_UL_ON,
32562306a36Sopenharmony_ci			      AFE_ADDA_UL_SRC_CON0,
32662306a36Sopenharmony_ci			      UL_SRC_ON_TMP_CTL_SHIFT, 0,
32762306a36Sopenharmony_ci			      mtk_adda_ul_event,
32862306a36Sopenharmony_ci			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
32962306a36Sopenharmony_ci
33062306a36Sopenharmony_ci	SND_SOC_DAPM_SUPPLY_S("ADDA_MTKAIF_CFG", SUPPLY_SEQ_ADDA_MTKAIF_CFG,
33162306a36Sopenharmony_ci			      SND_SOC_NOPM,
33262306a36Sopenharmony_ci			      0, 0,
33362306a36Sopenharmony_ci			      mtk_adda_mtkaif_cfg_event,
33462306a36Sopenharmony_ci			      SND_SOC_DAPM_PRE_PMU),
33562306a36Sopenharmony_ci
33662306a36Sopenharmony_ci	SND_SOC_DAPM_MUX("DL_GAIN_MUX", SND_SOC_NOPM, 0, 0,
33762306a36Sopenharmony_ci			 &adda_dlgain_mux_control),
33862306a36Sopenharmony_ci
33962306a36Sopenharmony_ci	SND_SOC_DAPM_PGA("DL_GAIN", AFE_ADDA_DL_SRC2_CON0,
34062306a36Sopenharmony_ci			 DL_2_GAIN_ON_CTL_PRE_SHIFT, 0, NULL, 0),
34162306a36Sopenharmony_ci
34262306a36Sopenharmony_ci	SND_SOC_DAPM_INPUT("ADDA_INPUT"),
34362306a36Sopenharmony_ci	SND_SOC_DAPM_OUTPUT("ADDA_OUTPUT"),
34462306a36Sopenharmony_ci
34562306a36Sopenharmony_ci	SND_SOC_DAPM_CLOCK_SUPPLY("aud_dac"),
34662306a36Sopenharmony_ci	SND_SOC_DAPM_CLOCK_SUPPLY("aud_adc"),
34762306a36Sopenharmony_ci	SND_SOC_DAPM_CLOCK_SUPPLY("aud_dac_hires"),
34862306a36Sopenharmony_ci	SND_SOC_DAPM_CLOCK_SUPPLY("aud_adc_hires"),
34962306a36Sopenharmony_ci};
35062306a36Sopenharmony_ci
35162306a36Sopenharmony_cistatic const struct snd_soc_dapm_route mtk_dai_adda_routes[] = {
35262306a36Sopenharmony_ci	{"ADDA Capture", NULL, "ADDA Enable"},
35362306a36Sopenharmony_ci	{"ADDA Capture", NULL, "ADDA Capture Enable"},
35462306a36Sopenharmony_ci	{"ADDA Capture", NULL, "ADDA_MTKAIF_CFG"},
35562306a36Sopenharmony_ci	{"ADDA Capture", NULL, "aud_adc"},
35662306a36Sopenharmony_ci	{"ADDA Capture", NULL, "aud_adc_hires", mtk_afe_adda_hires_connect},
35762306a36Sopenharmony_ci
35862306a36Sopenharmony_ci	{"I168", NULL, "ADDA Capture"},
35962306a36Sopenharmony_ci	{"I169", NULL, "ADDA Capture"},
36062306a36Sopenharmony_ci
36162306a36Sopenharmony_ci	{"ADDA Playback", NULL, "ADDA Enable"},
36262306a36Sopenharmony_ci	{"ADDA Playback", NULL, "ADDA Playback Enable"},
36362306a36Sopenharmony_ci	{"ADDA Playback", NULL, "aud_dac"},
36462306a36Sopenharmony_ci	{"ADDA Playback", NULL, "aud_dac_hires", mtk_afe_adda_hires_connect},
36562306a36Sopenharmony_ci
36662306a36Sopenharmony_ci	{"DL_GAIN", NULL, "O176"},
36762306a36Sopenharmony_ci	{"DL_GAIN", NULL, "O177"},
36862306a36Sopenharmony_ci
36962306a36Sopenharmony_ci	{"DL_GAIN_MUX", "Bypass", "O176"},
37062306a36Sopenharmony_ci	{"DL_GAIN_MUX", "Bypass", "O177"},
37162306a36Sopenharmony_ci	{"DL_GAIN_MUX", "Connect", "DL_GAIN"},
37262306a36Sopenharmony_ci
37362306a36Sopenharmony_ci	{"ADDA Playback", NULL, "DL_GAIN_MUX"},
37462306a36Sopenharmony_ci
37562306a36Sopenharmony_ci	{"O176", "I000 Switch", "I000"},
37662306a36Sopenharmony_ci	{"O177", "I001 Switch", "I001"},
37762306a36Sopenharmony_ci
37862306a36Sopenharmony_ci	{"O176", "I002 Switch", "I002"},
37962306a36Sopenharmony_ci	{"O177", "I003 Switch", "I003"},
38062306a36Sopenharmony_ci
38162306a36Sopenharmony_ci	{"O176", "I020 Switch", "I020"},
38262306a36Sopenharmony_ci	{"O177", "I021 Switch", "I021"},
38362306a36Sopenharmony_ci
38462306a36Sopenharmony_ci	{"O176", "I022 Switch", "I022"},
38562306a36Sopenharmony_ci	{"O177", "I023 Switch", "I023"},
38662306a36Sopenharmony_ci
38762306a36Sopenharmony_ci	{"O176", "I070 Switch", "I070"},
38862306a36Sopenharmony_ci	{"O177", "I071 Switch", "I071"},
38962306a36Sopenharmony_ci
39062306a36Sopenharmony_ci	{"ADDA Capture", NULL, "ADDA_INPUT"},
39162306a36Sopenharmony_ci	{"ADDA_OUTPUT", NULL, "ADDA Playback"},
39262306a36Sopenharmony_ci};
39362306a36Sopenharmony_ci
39462306a36Sopenharmony_cistatic int mt8188_adda_dmic_get(struct snd_kcontrol *kcontrol,
39562306a36Sopenharmony_ci				struct snd_ctl_elem_value *ucontrol)
39662306a36Sopenharmony_ci{
39762306a36Sopenharmony_ci	struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
39862306a36Sopenharmony_ci	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
39962306a36Sopenharmony_ci	struct mt8188_afe_private *afe_priv = afe->platform_priv;
40062306a36Sopenharmony_ci	struct mtkaif_param *param = &afe_priv->mtkaif_params;
40162306a36Sopenharmony_ci
40262306a36Sopenharmony_ci	ucontrol->value.integer.value[0] = param->mtkaif_dmic_on;
40362306a36Sopenharmony_ci	return 0;
40462306a36Sopenharmony_ci}
40562306a36Sopenharmony_ci
40662306a36Sopenharmony_cistatic int mt8188_adda_dmic_set(struct snd_kcontrol *kcontrol,
40762306a36Sopenharmony_ci				struct snd_ctl_elem_value *ucontrol)
40862306a36Sopenharmony_ci{
40962306a36Sopenharmony_ci	struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
41062306a36Sopenharmony_ci	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
41162306a36Sopenharmony_ci	struct mt8188_afe_private *afe_priv = afe->platform_priv;
41262306a36Sopenharmony_ci	struct mtkaif_param *param = &afe_priv->mtkaif_params;
41362306a36Sopenharmony_ci	int dmic_on;
41462306a36Sopenharmony_ci
41562306a36Sopenharmony_ci	dmic_on = !!ucontrol->value.integer.value[0];
41662306a36Sopenharmony_ci
41762306a36Sopenharmony_ci	dev_dbg(afe->dev, "%s(), kcontrol name %s, dmic_on %d\n",
41862306a36Sopenharmony_ci		__func__, kcontrol->id.name, dmic_on);
41962306a36Sopenharmony_ci
42062306a36Sopenharmony_ci	if (param->mtkaif_dmic_on == dmic_on)
42162306a36Sopenharmony_ci		return 0;
42262306a36Sopenharmony_ci
42362306a36Sopenharmony_ci	param->mtkaif_dmic_on = dmic_on;
42462306a36Sopenharmony_ci	return 1;
42562306a36Sopenharmony_ci}
42662306a36Sopenharmony_ci
42762306a36Sopenharmony_cistatic const struct snd_kcontrol_new mtk_dai_adda_controls[] = {
42862306a36Sopenharmony_ci	SOC_SINGLE("ADDA_DL_GAIN", AFE_ADDA_DL_SRC2_CON1,
42962306a36Sopenharmony_ci		   DL_2_GAIN_CTL_PRE_SHIFT, 65535, 0),
43062306a36Sopenharmony_ci	SOC_SINGLE_BOOL_EXT("MTKAIF_DMIC Switch", 0,
43162306a36Sopenharmony_ci			    mt8188_adda_dmic_get, mt8188_adda_dmic_set),
43262306a36Sopenharmony_ci};
43362306a36Sopenharmony_ci
43462306a36Sopenharmony_cistatic int mtk_dai_da_configure(struct mtk_base_afe *afe,
43562306a36Sopenharmony_ci				unsigned int rate, int id)
43662306a36Sopenharmony_ci{
43762306a36Sopenharmony_ci	unsigned int val = 0;
43862306a36Sopenharmony_ci	unsigned int mask = 0;
43962306a36Sopenharmony_ci
44062306a36Sopenharmony_ci	/* set sampling rate */
44162306a36Sopenharmony_ci	mask |= DL_2_INPUT_MODE_CTL_MASK;
44262306a36Sopenharmony_ci	val |= FIELD_PREP(DL_2_INPUT_MODE_CTL_MASK,
44362306a36Sopenharmony_ci			  afe_adda_dl_rate_transform(afe, rate));
44462306a36Sopenharmony_ci
44562306a36Sopenharmony_ci	/* turn off saturation */
44662306a36Sopenharmony_ci	mask |= DL_2_CH1_SATURATION_EN_CTL;
44762306a36Sopenharmony_ci	mask |= DL_2_CH2_SATURATION_EN_CTL;
44862306a36Sopenharmony_ci
44962306a36Sopenharmony_ci	/* turn off mute function */
45062306a36Sopenharmony_ci	mask |= DL_2_MUTE_CH1_OFF_CTL_PRE;
45162306a36Sopenharmony_ci	mask |= DL_2_MUTE_CH2_OFF_CTL_PRE;
45262306a36Sopenharmony_ci	val |= DL_2_MUTE_CH1_OFF_CTL_PRE;
45362306a36Sopenharmony_ci	val |= DL_2_MUTE_CH2_OFF_CTL_PRE;
45462306a36Sopenharmony_ci
45562306a36Sopenharmony_ci	/* set voice input data if input sample rate is 8k or 16k */
45662306a36Sopenharmony_ci	mask |= DL_2_VOICE_MODE_CTL_PRE;
45762306a36Sopenharmony_ci	if (rate == 8000 || rate == 16000)
45862306a36Sopenharmony_ci		val |= DL_2_VOICE_MODE_CTL_PRE;
45962306a36Sopenharmony_ci
46062306a36Sopenharmony_ci	regmap_update_bits(afe->regmap, AFE_ADDA_DL_SRC2_CON0, mask, val);
46162306a36Sopenharmony_ci
46262306a36Sopenharmony_ci	/* new 2nd sdm */
46362306a36Sopenharmony_ci	regmap_set_bits(afe->regmap, AFE_ADDA_DL_SDM_DCCOMP_CON,
46462306a36Sopenharmony_ci			DL_USE_NEW_2ND_SDM);
46562306a36Sopenharmony_ci
46662306a36Sopenharmony_ci	return 0;
46762306a36Sopenharmony_ci}
46862306a36Sopenharmony_ci
46962306a36Sopenharmony_cistatic int mtk_dai_ad_configure(struct mtk_base_afe *afe,
47062306a36Sopenharmony_ci				unsigned int rate, int id)
47162306a36Sopenharmony_ci{
47262306a36Sopenharmony_ci	unsigned int val;
47362306a36Sopenharmony_ci	unsigned int mask;
47462306a36Sopenharmony_ci
47562306a36Sopenharmony_ci	mask = UL_VOICE_MODE_CTL_MASK;
47662306a36Sopenharmony_ci	val = FIELD_PREP(UL_VOICE_MODE_CTL_MASK,
47762306a36Sopenharmony_ci			 afe_adda_ul_rate_transform(afe, rate));
47862306a36Sopenharmony_ci
47962306a36Sopenharmony_ci	regmap_update_bits(afe->regmap, AFE_ADDA_UL_SRC_CON0,
48062306a36Sopenharmony_ci			   mask, val);
48162306a36Sopenharmony_ci	return 0;
48262306a36Sopenharmony_ci}
48362306a36Sopenharmony_ci
48462306a36Sopenharmony_cistatic int mtk_dai_adda_hw_params(struct snd_pcm_substream *substream,
48562306a36Sopenharmony_ci				  struct snd_pcm_hw_params *params,
48662306a36Sopenharmony_ci				  struct snd_soc_dai *dai)
48762306a36Sopenharmony_ci{
48862306a36Sopenharmony_ci	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
48962306a36Sopenharmony_ci	struct mt8188_afe_private *afe_priv = afe->platform_priv;
49062306a36Sopenharmony_ci	struct mtk_dai_adda_priv *adda_priv = afe_priv->dai_priv[dai->id];
49162306a36Sopenharmony_ci	unsigned int rate = params_rate(params);
49262306a36Sopenharmony_ci	int id = dai->id;
49362306a36Sopenharmony_ci	int ret = 0;
49462306a36Sopenharmony_ci
49562306a36Sopenharmony_ci	dev_dbg(afe->dev, "%s(), id %d, stream %d, rate %u\n",
49662306a36Sopenharmony_ci		__func__, id, substream->stream, rate);
49762306a36Sopenharmony_ci
49862306a36Sopenharmony_ci	adda_priv->hires_required = (rate > ADDA_HIRES_THRES);
49962306a36Sopenharmony_ci
50062306a36Sopenharmony_ci	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
50162306a36Sopenharmony_ci		ret = mtk_dai_da_configure(afe, rate, id);
50262306a36Sopenharmony_ci	else
50362306a36Sopenharmony_ci		ret = mtk_dai_ad_configure(afe, rate, id);
50462306a36Sopenharmony_ci
50562306a36Sopenharmony_ci	return ret;
50662306a36Sopenharmony_ci}
50762306a36Sopenharmony_ci
50862306a36Sopenharmony_cistatic const struct snd_soc_dai_ops mtk_dai_adda_ops = {
50962306a36Sopenharmony_ci	.hw_params = mtk_dai_adda_hw_params,
51062306a36Sopenharmony_ci};
51162306a36Sopenharmony_ci
51262306a36Sopenharmony_ci/* dai driver */
51362306a36Sopenharmony_ci#define MTK_ADDA_PLAYBACK_RATES (SNDRV_PCM_RATE_8000_48000 |\
51462306a36Sopenharmony_ci				 SNDRV_PCM_RATE_96000 |\
51562306a36Sopenharmony_ci				 SNDRV_PCM_RATE_192000)
51662306a36Sopenharmony_ci
51762306a36Sopenharmony_ci#define MTK_ADDA_CAPTURE_RATES (SNDRV_PCM_RATE_8000 |\
51862306a36Sopenharmony_ci				SNDRV_PCM_RATE_16000 |\
51962306a36Sopenharmony_ci				SNDRV_PCM_RATE_32000 |\
52062306a36Sopenharmony_ci				SNDRV_PCM_RATE_48000 |\
52162306a36Sopenharmony_ci				SNDRV_PCM_RATE_96000 |\
52262306a36Sopenharmony_ci				SNDRV_PCM_RATE_192000)
52362306a36Sopenharmony_ci
52462306a36Sopenharmony_ci#define MTK_ADDA_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
52562306a36Sopenharmony_ci			  SNDRV_PCM_FMTBIT_S24_LE |\
52662306a36Sopenharmony_ci			  SNDRV_PCM_FMTBIT_S32_LE)
52762306a36Sopenharmony_ci
52862306a36Sopenharmony_cistatic struct snd_soc_dai_driver mtk_dai_adda_driver[] = {
52962306a36Sopenharmony_ci	{
53062306a36Sopenharmony_ci		.name = "DL_SRC",
53162306a36Sopenharmony_ci		.id = MT8188_AFE_IO_DL_SRC,
53262306a36Sopenharmony_ci		.playback = {
53362306a36Sopenharmony_ci			.stream_name = "ADDA Playback",
53462306a36Sopenharmony_ci			.channels_min = 1,
53562306a36Sopenharmony_ci			.channels_max = 2,
53662306a36Sopenharmony_ci			.rates = MTK_ADDA_PLAYBACK_RATES,
53762306a36Sopenharmony_ci			.formats = MTK_ADDA_FORMATS,
53862306a36Sopenharmony_ci		},
53962306a36Sopenharmony_ci		.ops = &mtk_dai_adda_ops,
54062306a36Sopenharmony_ci	},
54162306a36Sopenharmony_ci	{
54262306a36Sopenharmony_ci		.name = "UL_SRC",
54362306a36Sopenharmony_ci		.id = MT8188_AFE_IO_UL_SRC,
54462306a36Sopenharmony_ci		.capture = {
54562306a36Sopenharmony_ci			.stream_name = "ADDA Capture",
54662306a36Sopenharmony_ci			.channels_min = 1,
54762306a36Sopenharmony_ci			.channels_max = 2,
54862306a36Sopenharmony_ci			.rates = MTK_ADDA_CAPTURE_RATES,
54962306a36Sopenharmony_ci			.formats = MTK_ADDA_FORMATS,
55062306a36Sopenharmony_ci		},
55162306a36Sopenharmony_ci		.ops = &mtk_dai_adda_ops,
55262306a36Sopenharmony_ci	},
55362306a36Sopenharmony_ci};
55462306a36Sopenharmony_ci
55562306a36Sopenharmony_cistatic int init_adda_priv_data(struct mtk_base_afe *afe)
55662306a36Sopenharmony_ci{
55762306a36Sopenharmony_ci	struct mt8188_afe_private *afe_priv = afe->platform_priv;
55862306a36Sopenharmony_ci	struct mtk_dai_adda_priv *adda_priv;
55962306a36Sopenharmony_ci	int adda_dai_list[] = {MT8188_AFE_IO_DL_SRC, MT8188_AFE_IO_UL_SRC};
56062306a36Sopenharmony_ci	int i;
56162306a36Sopenharmony_ci
56262306a36Sopenharmony_ci	for (i = 0; i < ARRAY_SIZE(adda_dai_list); i++) {
56362306a36Sopenharmony_ci		adda_priv = devm_kzalloc(afe->dev,
56462306a36Sopenharmony_ci					 sizeof(struct mtk_dai_adda_priv),
56562306a36Sopenharmony_ci					 GFP_KERNEL);
56662306a36Sopenharmony_ci		if (!adda_priv)
56762306a36Sopenharmony_ci			return -ENOMEM;
56862306a36Sopenharmony_ci
56962306a36Sopenharmony_ci		afe_priv->dai_priv[adda_dai_list[i]] = adda_priv;
57062306a36Sopenharmony_ci	}
57162306a36Sopenharmony_ci
57262306a36Sopenharmony_ci	return 0;
57362306a36Sopenharmony_ci}
57462306a36Sopenharmony_ci
57562306a36Sopenharmony_ciint mt8188_dai_adda_register(struct mtk_base_afe *afe)
57662306a36Sopenharmony_ci{
57762306a36Sopenharmony_ci	struct mtk_base_afe_dai *dai;
57862306a36Sopenharmony_ci
57962306a36Sopenharmony_ci	dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL);
58062306a36Sopenharmony_ci	if (!dai)
58162306a36Sopenharmony_ci		return -ENOMEM;
58262306a36Sopenharmony_ci
58362306a36Sopenharmony_ci	list_add(&dai->list, &afe->sub_dais);
58462306a36Sopenharmony_ci
58562306a36Sopenharmony_ci	dai->dai_drivers = mtk_dai_adda_driver;
58662306a36Sopenharmony_ci	dai->num_dai_drivers = ARRAY_SIZE(mtk_dai_adda_driver);
58762306a36Sopenharmony_ci
58862306a36Sopenharmony_ci	dai->dapm_widgets = mtk_dai_adda_widgets;
58962306a36Sopenharmony_ci	dai->num_dapm_widgets = ARRAY_SIZE(mtk_dai_adda_widgets);
59062306a36Sopenharmony_ci	dai->dapm_routes = mtk_dai_adda_routes;
59162306a36Sopenharmony_ci	dai->num_dapm_routes = ARRAY_SIZE(mtk_dai_adda_routes);
59262306a36Sopenharmony_ci	dai->controls = mtk_dai_adda_controls;
59362306a36Sopenharmony_ci	dai->num_controls = ARRAY_SIZE(mtk_dai_adda_controls);
59462306a36Sopenharmony_ci
59562306a36Sopenharmony_ci	return init_adda_priv_data(afe);
59662306a36Sopenharmony_ci}
597