15d1c8e88STrevor Wu // SPDX-License-Identifier: GPL-2.0
25d1c8e88STrevor Wu /*
35d1c8e88STrevor Wu * MediaTek ALSA SoC Audio DAI ADDA Control
45d1c8e88STrevor Wu *
55d1c8e88STrevor Wu * Copyright (c) 2022 MediaTek Inc.
65d1c8e88STrevor Wu * Author: Bicycle Tsai <bicycle.tsai@mediatek.com>
75d1c8e88STrevor Wu * Trevor Wu <trevor.wu@mediatek.com>
85d1c8e88STrevor Wu * Chun-Chia Chiu <chun-chia.chiu@mediatek.com>
95d1c8e88STrevor Wu */
105d1c8e88STrevor Wu
115d1c8e88STrevor Wu #include <linux/bitfield.h>
125d1c8e88STrevor Wu #include <linux/delay.h>
135d1c8e88STrevor Wu #include <linux/regmap.h>
145d1c8e88STrevor Wu #include "mt8188-afe-clk.h"
155d1c8e88STrevor Wu #include "mt8188-afe-common.h"
165d1c8e88STrevor Wu #include "mt8188-reg.h"
175d1c8e88STrevor Wu
185d1c8e88STrevor Wu #define ADDA_HIRES_THRES 48000
195d1c8e88STrevor Wu
205d1c8e88STrevor Wu enum {
215d1c8e88STrevor Wu SUPPLY_SEQ_ADDA_DL_ON,
225d1c8e88STrevor Wu SUPPLY_SEQ_ADDA_MTKAIF_CFG,
235d1c8e88STrevor Wu SUPPLY_SEQ_ADDA_UL_ON,
245d1c8e88STrevor Wu SUPPLY_SEQ_ADDA_AFE_ON,
255d1c8e88STrevor Wu };
265d1c8e88STrevor Wu
275d1c8e88STrevor Wu enum {
285d1c8e88STrevor Wu MTK_AFE_ADDA_DL_RATE_8K = 0,
295d1c8e88STrevor Wu MTK_AFE_ADDA_DL_RATE_11K = 1,
305d1c8e88STrevor Wu MTK_AFE_ADDA_DL_RATE_12K = 2,
315d1c8e88STrevor Wu MTK_AFE_ADDA_DL_RATE_16K = 3,
325d1c8e88STrevor Wu MTK_AFE_ADDA_DL_RATE_22K = 4,
335d1c8e88STrevor Wu MTK_AFE_ADDA_DL_RATE_24K = 5,
345d1c8e88STrevor Wu MTK_AFE_ADDA_DL_RATE_32K = 6,
355d1c8e88STrevor Wu MTK_AFE_ADDA_DL_RATE_44K = 7,
365d1c8e88STrevor Wu MTK_AFE_ADDA_DL_RATE_48K = 8,
375d1c8e88STrevor Wu MTK_AFE_ADDA_DL_RATE_96K = 9,
385d1c8e88STrevor Wu MTK_AFE_ADDA_DL_RATE_192K = 10,
395d1c8e88STrevor Wu };
405d1c8e88STrevor Wu
415d1c8e88STrevor Wu enum {
425d1c8e88STrevor Wu MTK_AFE_ADDA_UL_RATE_8K = 0,
435d1c8e88STrevor Wu MTK_AFE_ADDA_UL_RATE_16K = 1,
445d1c8e88STrevor Wu MTK_AFE_ADDA_UL_RATE_32K = 2,
455d1c8e88STrevor Wu MTK_AFE_ADDA_UL_RATE_48K = 3,
465d1c8e88STrevor Wu MTK_AFE_ADDA_UL_RATE_96K = 4,
475d1c8e88STrevor Wu MTK_AFE_ADDA_UL_RATE_192K = 5,
485d1c8e88STrevor Wu };
495d1c8e88STrevor Wu
505d1c8e88STrevor Wu enum {
515d1c8e88STrevor Wu DELAY_DATA_MISO1 = 0,
525d1c8e88STrevor Wu DELAY_DATA_MISO0 = 1,
535d1c8e88STrevor Wu };
545d1c8e88STrevor Wu
555d1c8e88STrevor Wu struct mtk_dai_adda_priv {
56*2a7a1ae9STrevor Wu bool hires_required;
575d1c8e88STrevor Wu };
585d1c8e88STrevor Wu
afe_adda_dl_rate_transform(struct mtk_base_afe * afe,unsigned int rate)595d1c8e88STrevor Wu static unsigned int afe_adda_dl_rate_transform(struct mtk_base_afe *afe,
605d1c8e88STrevor Wu unsigned int rate)
615d1c8e88STrevor Wu {
625d1c8e88STrevor Wu switch (rate) {
635d1c8e88STrevor Wu case 8000:
645d1c8e88STrevor Wu return MTK_AFE_ADDA_DL_RATE_8K;
655d1c8e88STrevor Wu case 11025:
665d1c8e88STrevor Wu return MTK_AFE_ADDA_DL_RATE_11K;
675d1c8e88STrevor Wu case 12000:
685d1c8e88STrevor Wu return MTK_AFE_ADDA_DL_RATE_12K;
695d1c8e88STrevor Wu case 16000:
705d1c8e88STrevor Wu return MTK_AFE_ADDA_DL_RATE_16K;
715d1c8e88STrevor Wu case 22050:
725d1c8e88STrevor Wu return MTK_AFE_ADDA_DL_RATE_22K;
735d1c8e88STrevor Wu case 24000:
745d1c8e88STrevor Wu return MTK_AFE_ADDA_DL_RATE_24K;
755d1c8e88STrevor Wu case 32000:
765d1c8e88STrevor Wu return MTK_AFE_ADDA_DL_RATE_32K;
775d1c8e88STrevor Wu case 44100:
785d1c8e88STrevor Wu return MTK_AFE_ADDA_DL_RATE_44K;
795d1c8e88STrevor Wu case 48000:
805d1c8e88STrevor Wu return MTK_AFE_ADDA_DL_RATE_48K;
815d1c8e88STrevor Wu case 96000:
825d1c8e88STrevor Wu return MTK_AFE_ADDA_DL_RATE_96K;
835d1c8e88STrevor Wu case 192000:
845d1c8e88STrevor Wu return MTK_AFE_ADDA_DL_RATE_192K;
855d1c8e88STrevor Wu default:
865d1c8e88STrevor Wu dev_info(afe->dev, "%s(), rate %u invalid, use 48kHz!!!\n",
875d1c8e88STrevor Wu __func__, rate);
885d1c8e88STrevor Wu return MTK_AFE_ADDA_DL_RATE_48K;
895d1c8e88STrevor Wu }
905d1c8e88STrevor Wu }
915d1c8e88STrevor Wu
afe_adda_ul_rate_transform(struct mtk_base_afe * afe,unsigned int rate)925d1c8e88STrevor Wu static unsigned int afe_adda_ul_rate_transform(struct mtk_base_afe *afe,
935d1c8e88STrevor Wu unsigned int rate)
945d1c8e88STrevor Wu {
955d1c8e88STrevor Wu switch (rate) {
965d1c8e88STrevor Wu case 8000:
975d1c8e88STrevor Wu return MTK_AFE_ADDA_UL_RATE_8K;
985d1c8e88STrevor Wu case 16000:
995d1c8e88STrevor Wu return MTK_AFE_ADDA_UL_RATE_16K;
1005d1c8e88STrevor Wu case 32000:
1015d1c8e88STrevor Wu return MTK_AFE_ADDA_UL_RATE_32K;
1025d1c8e88STrevor Wu case 48000:
1035d1c8e88STrevor Wu return MTK_AFE_ADDA_UL_RATE_48K;
1045d1c8e88STrevor Wu case 96000:
1055d1c8e88STrevor Wu return MTK_AFE_ADDA_UL_RATE_96K;
1065d1c8e88STrevor Wu case 192000:
1075d1c8e88STrevor Wu return MTK_AFE_ADDA_UL_RATE_192K;
1085d1c8e88STrevor Wu default:
1095d1c8e88STrevor Wu dev_info(afe->dev, "%s(), rate %u invalid, use 48kHz!!!\n",
1105d1c8e88STrevor Wu __func__, rate);
1115d1c8e88STrevor Wu return MTK_AFE_ADDA_UL_RATE_48K;
1125d1c8e88STrevor Wu }
1135d1c8e88STrevor Wu }
1145d1c8e88STrevor Wu
mt8188_adda_mtkaif_init(struct mtk_base_afe * afe)1155d1c8e88STrevor Wu static int mt8188_adda_mtkaif_init(struct mtk_base_afe *afe)
1165d1c8e88STrevor Wu {
1175d1c8e88STrevor Wu struct mt8188_afe_private *afe_priv = afe->platform_priv;
1185d1c8e88STrevor Wu struct mtkaif_param *param = &afe_priv->mtkaif_params;
1195d1c8e88STrevor Wu int delay_data;
1205d1c8e88STrevor Wu int delay_cycle;
1215d1c8e88STrevor Wu unsigned int mask = 0;
1225d1c8e88STrevor Wu unsigned int val = 0;
1235d1c8e88STrevor Wu
1245d1c8e88STrevor Wu /* set rx protocol 2 & mtkaif_rxif_clkinv_adc inverse */
1255d1c8e88STrevor Wu regmap_set_bits(afe->regmap, AFE_ADDA_MTKAIF_CFG0,
1265d1c8e88STrevor Wu MTKAIF_RXIF_CLKINV_ADC | MTKAIF_RXIF_PROTOCOL2);
1275d1c8e88STrevor Wu
1285d1c8e88STrevor Wu regmap_set_bits(afe->regmap, AFE_AUD_PAD_TOP, RG_RX_PROTOCOL2);
1295d1c8e88STrevor Wu
1305d1c8e88STrevor Wu if (!param->mtkaif_calibration_ok) {
1315d1c8e88STrevor Wu dev_info(afe->dev, "%s(), calibration fail\n", __func__);
1325d1c8e88STrevor Wu return 0;
1335d1c8e88STrevor Wu }
1345d1c8e88STrevor Wu
1355d1c8e88STrevor Wu /* set delay for ch1, ch2 */
1365d1c8e88STrevor Wu if (param->mtkaif_phase_cycle[MT8188_MTKAIF_MISO_0] >=
1375d1c8e88STrevor Wu param->mtkaif_phase_cycle[MT8188_MTKAIF_MISO_1]) {
1385d1c8e88STrevor Wu delay_data = DELAY_DATA_MISO1;
1395d1c8e88STrevor Wu delay_cycle =
1405d1c8e88STrevor Wu param->mtkaif_phase_cycle[MT8188_MTKAIF_MISO_0] -
1415d1c8e88STrevor Wu param->mtkaif_phase_cycle[MT8188_MTKAIF_MISO_1];
1425d1c8e88STrevor Wu } else {
1435d1c8e88STrevor Wu delay_data = DELAY_DATA_MISO0;
1445d1c8e88STrevor Wu delay_cycle =
1455d1c8e88STrevor Wu param->mtkaif_phase_cycle[MT8188_MTKAIF_MISO_1] -
1465d1c8e88STrevor Wu param->mtkaif_phase_cycle[MT8188_MTKAIF_MISO_0];
1475d1c8e88STrevor Wu }
1485d1c8e88STrevor Wu
1495d1c8e88STrevor Wu val = 0;
1505d1c8e88STrevor Wu mask = (MTKAIF_RXIF_DELAY_DATA | MTKAIF_RXIF_DELAY_CYCLE_MASK);
1515d1c8e88STrevor Wu val |= FIELD_PREP(MTKAIF_RXIF_DELAY_CYCLE_MASK, delay_cycle);
1525d1c8e88STrevor Wu val |= FIELD_PREP(MTKAIF_RXIF_DELAY_DATA, delay_data);
1535d1c8e88STrevor Wu regmap_update_bits(afe->regmap, AFE_ADDA_MTKAIF_RX_CFG2, mask, val);
1545d1c8e88STrevor Wu
1555d1c8e88STrevor Wu return 0;
1565d1c8e88STrevor Wu }
1575d1c8e88STrevor Wu
mtk_adda_mtkaif_cfg_event(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)1585d1c8e88STrevor Wu static int mtk_adda_mtkaif_cfg_event(struct snd_soc_dapm_widget *w,
1595d1c8e88STrevor Wu struct snd_kcontrol *kcontrol,
1605d1c8e88STrevor Wu int event)
1615d1c8e88STrevor Wu {
1625d1c8e88STrevor Wu struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
1635d1c8e88STrevor Wu struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
1645d1c8e88STrevor Wu
1655d1c8e88STrevor Wu dev_dbg(afe->dev, "%s(), name %s, event 0x%x\n",
1665d1c8e88STrevor Wu __func__, w->name, event);
1675d1c8e88STrevor Wu
1685d1c8e88STrevor Wu switch (event) {
1695d1c8e88STrevor Wu case SND_SOC_DAPM_PRE_PMU:
1705d1c8e88STrevor Wu mt8188_adda_mtkaif_init(afe);
1715d1c8e88STrevor Wu break;
1725d1c8e88STrevor Wu default:
1735d1c8e88STrevor Wu break;
1745d1c8e88STrevor Wu }
1755d1c8e88STrevor Wu
1765d1c8e88STrevor Wu return 0;
1775d1c8e88STrevor Wu }
1785d1c8e88STrevor Wu
mtk_adda_dl_event(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)1795d1c8e88STrevor Wu static int mtk_adda_dl_event(struct snd_soc_dapm_widget *w,
1805d1c8e88STrevor Wu struct snd_kcontrol *kcontrol,
1815d1c8e88STrevor Wu int event)
1825d1c8e88STrevor Wu {
1835d1c8e88STrevor Wu struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
1845d1c8e88STrevor Wu struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
1855d1c8e88STrevor Wu
1865d1c8e88STrevor Wu dev_dbg(afe->dev, "%s(), name %s, event 0x%x\n",
1875d1c8e88STrevor Wu __func__, w->name, event);
1885d1c8e88STrevor Wu
1895d1c8e88STrevor Wu switch (event) {
1905d1c8e88STrevor Wu case SND_SOC_DAPM_POST_PMD:
1915d1c8e88STrevor Wu /* should delayed 1/fs(smallest is 8k) = 125us before afe off */
1925d1c8e88STrevor Wu usleep_range(125, 135);
1935d1c8e88STrevor Wu break;
1945d1c8e88STrevor Wu default:
1955d1c8e88STrevor Wu break;
1965d1c8e88STrevor Wu }
1975d1c8e88STrevor Wu
1985d1c8e88STrevor Wu return 0;
1995d1c8e88STrevor Wu }
2005d1c8e88STrevor Wu
mtk_adda_ul_mictype(struct mtk_base_afe * afe,bool dmic)2015d1c8e88STrevor Wu static void mtk_adda_ul_mictype(struct mtk_base_afe *afe, bool dmic)
2025d1c8e88STrevor Wu {
2035d1c8e88STrevor Wu unsigned int reg = AFE_ADDA_UL_SRC_CON0;
2045d1c8e88STrevor Wu unsigned int val;
2055d1c8e88STrevor Wu
2065d1c8e88STrevor Wu val = (UL_SDM3_LEVEL_CTL | UL_MODE_3P25M_CH1_CTL |
2075d1c8e88STrevor Wu UL_MODE_3P25M_CH2_CTL);
2085d1c8e88STrevor Wu
2095d1c8e88STrevor Wu /* turn on dmic, ch1, ch2 */
2105d1c8e88STrevor Wu if (dmic)
2115d1c8e88STrevor Wu regmap_set_bits(afe->regmap, reg, val);
2125d1c8e88STrevor Wu else
2135d1c8e88STrevor Wu regmap_clear_bits(afe->regmap, reg, val);
2145d1c8e88STrevor Wu }
2155d1c8e88STrevor Wu
mtk_adda_ul_event(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)2165d1c8e88STrevor Wu static int mtk_adda_ul_event(struct snd_soc_dapm_widget *w,
2175d1c8e88STrevor Wu struct snd_kcontrol *kcontrol,
2185d1c8e88STrevor Wu int event)
2195d1c8e88STrevor Wu {
2205d1c8e88STrevor Wu struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
2215d1c8e88STrevor Wu struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
2225d1c8e88STrevor Wu struct mt8188_afe_private *afe_priv = afe->platform_priv;
2235d1c8e88STrevor Wu struct mtkaif_param *param = &afe_priv->mtkaif_params;
2245d1c8e88STrevor Wu
2255d1c8e88STrevor Wu dev_dbg(afe->dev, "%s(), name %s, event 0x%x\n",
2265d1c8e88STrevor Wu __func__, w->name, event);
2275d1c8e88STrevor Wu
2285d1c8e88STrevor Wu switch (event) {
2295d1c8e88STrevor Wu case SND_SOC_DAPM_PRE_PMU:
2305d1c8e88STrevor Wu mtk_adda_ul_mictype(afe, param->mtkaif_dmic_on);
2315d1c8e88STrevor Wu break;
2325d1c8e88STrevor Wu case SND_SOC_DAPM_POST_PMD:
2335d1c8e88STrevor Wu /* should delayed 1/fs(smallest is 8k) = 125us before afe off */
2345d1c8e88STrevor Wu usleep_range(125, 135);
2355d1c8e88STrevor Wu break;
2365d1c8e88STrevor Wu default:
2375d1c8e88STrevor Wu break;
2385d1c8e88STrevor Wu }
2395d1c8e88STrevor Wu
2405d1c8e88STrevor Wu return 0;
2415d1c8e88STrevor Wu }
2425d1c8e88STrevor Wu
get_adda_priv_by_name(struct mtk_base_afe * afe,const char * name)243*2a7a1ae9STrevor Wu static struct mtk_dai_adda_priv *get_adda_priv_by_name(struct mtk_base_afe *afe,
244*2a7a1ae9STrevor Wu const char *name)
245*2a7a1ae9STrevor Wu {
246*2a7a1ae9STrevor Wu struct mt8188_afe_private *afe_priv = afe->platform_priv;
247*2a7a1ae9STrevor Wu
248*2a7a1ae9STrevor Wu if (strstr(name, "aud_adc_hires"))
249*2a7a1ae9STrevor Wu return afe_priv->dai_priv[MT8188_AFE_IO_UL_SRC];
250*2a7a1ae9STrevor Wu else if (strstr(name, "aud_dac_hires"))
251*2a7a1ae9STrevor Wu return afe_priv->dai_priv[MT8188_AFE_IO_DL_SRC];
252*2a7a1ae9STrevor Wu else
253*2a7a1ae9STrevor Wu return NULL;
254*2a7a1ae9STrevor Wu }
255*2a7a1ae9STrevor Wu
mtk_afe_adda_hires_connect(struct snd_soc_dapm_widget * source,struct snd_soc_dapm_widget * sink)256*2a7a1ae9STrevor Wu static int mtk_afe_adda_hires_connect(struct snd_soc_dapm_widget *source,
2575d1c8e88STrevor Wu struct snd_soc_dapm_widget *sink)
2585d1c8e88STrevor Wu {
2595d1c8e88STrevor Wu struct snd_soc_dapm_widget *w = source;
2605d1c8e88STrevor Wu struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
2615d1c8e88STrevor Wu struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
2625d1c8e88STrevor Wu struct mtk_dai_adda_priv *adda_priv;
2635d1c8e88STrevor Wu
264*2a7a1ae9STrevor Wu adda_priv = get_adda_priv_by_name(afe, w->name);
2655d1c8e88STrevor Wu
2665d1c8e88STrevor Wu if (!adda_priv) {
267*2a7a1ae9STrevor Wu dev_dbg(afe->dev, "adda_priv == NULL");
2685d1c8e88STrevor Wu return 0;
2695d1c8e88STrevor Wu }
2705d1c8e88STrevor Wu
271*2a7a1ae9STrevor Wu return (adda_priv->hires_required) ? 1 : 0;
2725d1c8e88STrevor Wu }
2735d1c8e88STrevor Wu
2745d1c8e88STrevor Wu static const struct snd_kcontrol_new mtk_dai_adda_o176_mix[] = {
2755d1c8e88STrevor Wu SOC_DAPM_SINGLE_AUTODISABLE("I000 Switch", AFE_CONN176, 0, 1, 0),
2765d1c8e88STrevor Wu SOC_DAPM_SINGLE_AUTODISABLE("I002 Switch", AFE_CONN176, 2, 1, 0),
2775d1c8e88STrevor Wu SOC_DAPM_SINGLE_AUTODISABLE("I020 Switch", AFE_CONN176, 20, 1, 0),
2785d1c8e88STrevor Wu SOC_DAPM_SINGLE_AUTODISABLE("I022 Switch", AFE_CONN176, 22, 1, 0),
2795d1c8e88STrevor Wu SOC_DAPM_SINGLE_AUTODISABLE("I070 Switch", AFE_CONN176_2, 6, 1, 0),
2805d1c8e88STrevor Wu };
2815d1c8e88STrevor Wu
2825d1c8e88STrevor Wu static const struct snd_kcontrol_new mtk_dai_adda_o177_mix[] = {
2835d1c8e88STrevor Wu SOC_DAPM_SINGLE_AUTODISABLE("I001 Switch", AFE_CONN177, 1, 1, 0),
2845d1c8e88STrevor Wu SOC_DAPM_SINGLE_AUTODISABLE("I003 Switch", AFE_CONN177, 3, 1, 0),
2855d1c8e88STrevor Wu SOC_DAPM_SINGLE_AUTODISABLE("I021 Switch", AFE_CONN177, 21, 1, 0),
2865d1c8e88STrevor Wu SOC_DAPM_SINGLE_AUTODISABLE("I023 Switch", AFE_CONN177, 23, 1, 0),
2875d1c8e88STrevor Wu SOC_DAPM_SINGLE_AUTODISABLE("I071 Switch", AFE_CONN177_2, 7, 1, 0),
2885d1c8e88STrevor Wu };
2895d1c8e88STrevor Wu
2905d1c8e88STrevor Wu static const char * const adda_dlgain_mux_map[] = {
2915d1c8e88STrevor Wu "Bypass", "Connect",
2925d1c8e88STrevor Wu };
2935d1c8e88STrevor Wu
2945d1c8e88STrevor Wu static SOC_ENUM_SINGLE_DECL(adda_dlgain_mux_map_enum,
2955d1c8e88STrevor Wu SND_SOC_NOPM, 0,
2965d1c8e88STrevor Wu adda_dlgain_mux_map);
2975d1c8e88STrevor Wu
2985d1c8e88STrevor Wu static const struct snd_kcontrol_new adda_dlgain_mux_control =
2995d1c8e88STrevor Wu SOC_DAPM_ENUM("DL_GAIN_MUX", adda_dlgain_mux_map_enum);
3005d1c8e88STrevor Wu
3015d1c8e88STrevor Wu static const struct snd_soc_dapm_widget mtk_dai_adda_widgets[] = {
3025d1c8e88STrevor Wu SND_SOC_DAPM_MIXER("I168", SND_SOC_NOPM, 0, 0, NULL, 0),
3035d1c8e88STrevor Wu SND_SOC_DAPM_MIXER("I169", SND_SOC_NOPM, 0, 0, NULL, 0),
3045d1c8e88STrevor Wu
3055d1c8e88STrevor Wu SND_SOC_DAPM_MIXER("O176", SND_SOC_NOPM, 0, 0,
3065d1c8e88STrevor Wu mtk_dai_adda_o176_mix,
3075d1c8e88STrevor Wu ARRAY_SIZE(mtk_dai_adda_o176_mix)),
3085d1c8e88STrevor Wu SND_SOC_DAPM_MIXER("O177", SND_SOC_NOPM, 0, 0,
3095d1c8e88STrevor Wu mtk_dai_adda_o177_mix,
3105d1c8e88STrevor Wu ARRAY_SIZE(mtk_dai_adda_o177_mix)),
3115d1c8e88STrevor Wu
3125d1c8e88STrevor Wu SND_SOC_DAPM_SUPPLY_S("ADDA Enable", SUPPLY_SEQ_ADDA_AFE_ON,
3135d1c8e88STrevor Wu AFE_ADDA_UL_DL_CON0,
3145d1c8e88STrevor Wu ADDA_AFE_ON_SHIFT, 0,
3155d1c8e88STrevor Wu NULL,
3165d1c8e88STrevor Wu 0),
3175d1c8e88STrevor Wu
3185d1c8e88STrevor Wu SND_SOC_DAPM_SUPPLY_S("ADDA Playback Enable", SUPPLY_SEQ_ADDA_DL_ON,
3195d1c8e88STrevor Wu AFE_ADDA_DL_SRC2_CON0,
3205d1c8e88STrevor Wu DL_2_SRC_ON_TMP_CTRL_PRE_SHIFT, 0,
3215d1c8e88STrevor Wu mtk_adda_dl_event,
3225d1c8e88STrevor Wu SND_SOC_DAPM_POST_PMD),
3235d1c8e88STrevor Wu
3245d1c8e88STrevor Wu SND_SOC_DAPM_SUPPLY_S("ADDA Capture Enable", SUPPLY_SEQ_ADDA_UL_ON,
3255d1c8e88STrevor Wu AFE_ADDA_UL_SRC_CON0,
3265d1c8e88STrevor Wu UL_SRC_ON_TMP_CTL_SHIFT, 0,
3275d1c8e88STrevor Wu mtk_adda_ul_event,
3285d1c8e88STrevor Wu SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
3295d1c8e88STrevor Wu
3305d1c8e88STrevor Wu SND_SOC_DAPM_SUPPLY_S("ADDA_MTKAIF_CFG", SUPPLY_SEQ_ADDA_MTKAIF_CFG,
3315d1c8e88STrevor Wu SND_SOC_NOPM,
3325d1c8e88STrevor Wu 0, 0,
3335d1c8e88STrevor Wu mtk_adda_mtkaif_cfg_event,
3345d1c8e88STrevor Wu SND_SOC_DAPM_PRE_PMU),
3355d1c8e88STrevor Wu
3365d1c8e88STrevor Wu SND_SOC_DAPM_MUX("DL_GAIN_MUX", SND_SOC_NOPM, 0, 0,
3375d1c8e88STrevor Wu &adda_dlgain_mux_control),
3385d1c8e88STrevor Wu
3395d1c8e88STrevor Wu SND_SOC_DAPM_PGA("DL_GAIN", AFE_ADDA_DL_SRC2_CON0,
3405d1c8e88STrevor Wu DL_2_GAIN_ON_CTL_PRE_SHIFT, 0, NULL, 0),
3415d1c8e88STrevor Wu
3425d1c8e88STrevor Wu SND_SOC_DAPM_INPUT("ADDA_INPUT"),
3435d1c8e88STrevor Wu SND_SOC_DAPM_OUTPUT("ADDA_OUTPUT"),
3445d1c8e88STrevor Wu
3455d1c8e88STrevor Wu SND_SOC_DAPM_CLOCK_SUPPLY("aud_dac"),
3465d1c8e88STrevor Wu SND_SOC_DAPM_CLOCK_SUPPLY("aud_adc"),
3475d1c8e88STrevor Wu SND_SOC_DAPM_CLOCK_SUPPLY("aud_dac_hires"),
3485d1c8e88STrevor Wu SND_SOC_DAPM_CLOCK_SUPPLY("aud_adc_hires"),
3495d1c8e88STrevor Wu };
3505d1c8e88STrevor Wu
3515d1c8e88STrevor Wu static const struct snd_soc_dapm_route mtk_dai_adda_routes[] = {
3525d1c8e88STrevor Wu {"ADDA Capture", NULL, "ADDA Enable"},
3535d1c8e88STrevor Wu {"ADDA Capture", NULL, "ADDA Capture Enable"},
3545d1c8e88STrevor Wu {"ADDA Capture", NULL, "ADDA_MTKAIF_CFG"},
3555d1c8e88STrevor Wu {"ADDA Capture", NULL, "aud_adc"},
356*2a7a1ae9STrevor Wu {"ADDA Capture", NULL, "aud_adc_hires", mtk_afe_adda_hires_connect},
3575d1c8e88STrevor Wu
3585d1c8e88STrevor Wu {"I168", NULL, "ADDA Capture"},
3595d1c8e88STrevor Wu {"I169", NULL, "ADDA Capture"},
3605d1c8e88STrevor Wu
3615d1c8e88STrevor Wu {"ADDA Playback", NULL, "ADDA Enable"},
3625d1c8e88STrevor Wu {"ADDA Playback", NULL, "ADDA Playback Enable"},
3635d1c8e88STrevor Wu {"ADDA Playback", NULL, "aud_dac"},
364*2a7a1ae9STrevor Wu {"ADDA Playback", NULL, "aud_dac_hires", mtk_afe_adda_hires_connect},
3655d1c8e88STrevor Wu
3665d1c8e88STrevor Wu {"DL_GAIN", NULL, "O176"},
3675d1c8e88STrevor Wu {"DL_GAIN", NULL, "O177"},
3685d1c8e88STrevor Wu
3695d1c8e88STrevor Wu {"DL_GAIN_MUX", "Bypass", "O176"},
3705d1c8e88STrevor Wu {"DL_GAIN_MUX", "Bypass", "O177"},
3715d1c8e88STrevor Wu {"DL_GAIN_MUX", "Connect", "DL_GAIN"},
3725d1c8e88STrevor Wu
3735d1c8e88STrevor Wu {"ADDA Playback", NULL, "DL_GAIN_MUX"},
3745d1c8e88STrevor Wu
3755d1c8e88STrevor Wu {"O176", "I000 Switch", "I000"},
3765d1c8e88STrevor Wu {"O177", "I001 Switch", "I001"},
3775d1c8e88STrevor Wu
3785d1c8e88STrevor Wu {"O176", "I002 Switch", "I002"},
3795d1c8e88STrevor Wu {"O177", "I003 Switch", "I003"},
3805d1c8e88STrevor Wu
3815d1c8e88STrevor Wu {"O176", "I020 Switch", "I020"},
3825d1c8e88STrevor Wu {"O177", "I021 Switch", "I021"},
3835d1c8e88STrevor Wu
3845d1c8e88STrevor Wu {"O176", "I022 Switch", "I022"},
3855d1c8e88STrevor Wu {"O177", "I023 Switch", "I023"},
3865d1c8e88STrevor Wu
3875d1c8e88STrevor Wu {"O176", "I070 Switch", "I070"},
3885d1c8e88STrevor Wu {"O177", "I071 Switch", "I071"},
3895d1c8e88STrevor Wu
3905d1c8e88STrevor Wu {"ADDA Capture", NULL, "ADDA_INPUT"},
3915d1c8e88STrevor Wu {"ADDA_OUTPUT", NULL, "ADDA Playback"},
3925d1c8e88STrevor Wu };
3935d1c8e88STrevor Wu
mt8188_adda_dmic_get(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)3945d1c8e88STrevor Wu static int mt8188_adda_dmic_get(struct snd_kcontrol *kcontrol,
3955d1c8e88STrevor Wu struct snd_ctl_elem_value *ucontrol)
3965d1c8e88STrevor Wu {
3975d1c8e88STrevor Wu struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
3985d1c8e88STrevor Wu struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
3995d1c8e88STrevor Wu struct mt8188_afe_private *afe_priv = afe->platform_priv;
4005d1c8e88STrevor Wu struct mtkaif_param *param = &afe_priv->mtkaif_params;
4015d1c8e88STrevor Wu
4025d1c8e88STrevor Wu ucontrol->value.integer.value[0] = param->mtkaif_dmic_on;
4035d1c8e88STrevor Wu return 0;
4045d1c8e88STrevor Wu }
4055d1c8e88STrevor Wu
mt8188_adda_dmic_set(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)4065d1c8e88STrevor Wu static int mt8188_adda_dmic_set(struct snd_kcontrol *kcontrol,
4075d1c8e88STrevor Wu struct snd_ctl_elem_value *ucontrol)
4085d1c8e88STrevor Wu {
4095d1c8e88STrevor Wu struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
4105d1c8e88STrevor Wu struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
4115d1c8e88STrevor Wu struct mt8188_afe_private *afe_priv = afe->platform_priv;
4125d1c8e88STrevor Wu struct mtkaif_param *param = &afe_priv->mtkaif_params;
4135d1c8e88STrevor Wu int dmic_on;
4145d1c8e88STrevor Wu
4155d1c8e88STrevor Wu dmic_on = !!ucontrol->value.integer.value[0];
4165d1c8e88STrevor Wu
4175d1c8e88STrevor Wu dev_dbg(afe->dev, "%s(), kcontrol name %s, dmic_on %d\n",
4185d1c8e88STrevor Wu __func__, kcontrol->id.name, dmic_on);
4195d1c8e88STrevor Wu
4205d1c8e88STrevor Wu if (param->mtkaif_dmic_on == dmic_on)
4215d1c8e88STrevor Wu return 0;
4225d1c8e88STrevor Wu
4235d1c8e88STrevor Wu param->mtkaif_dmic_on = dmic_on;
4245d1c8e88STrevor Wu return 1;
4255d1c8e88STrevor Wu }
4265d1c8e88STrevor Wu
4275d1c8e88STrevor Wu static const struct snd_kcontrol_new mtk_dai_adda_controls[] = {
4285d1c8e88STrevor Wu SOC_SINGLE("ADDA_DL_GAIN", AFE_ADDA_DL_SRC2_CON1,
4295d1c8e88STrevor Wu DL_2_GAIN_CTL_PRE_SHIFT, 65535, 0),
4305d1c8e88STrevor Wu SOC_SINGLE_BOOL_EXT("MTKAIF_DMIC Switch", 0,
4315d1c8e88STrevor Wu mt8188_adda_dmic_get, mt8188_adda_dmic_set),
4325d1c8e88STrevor Wu };
4335d1c8e88STrevor Wu
mtk_dai_da_configure(struct mtk_base_afe * afe,unsigned int rate,int id)4345d1c8e88STrevor Wu static int mtk_dai_da_configure(struct mtk_base_afe *afe,
4355d1c8e88STrevor Wu unsigned int rate, int id)
4365d1c8e88STrevor Wu {
4375d1c8e88STrevor Wu unsigned int val = 0;
4385d1c8e88STrevor Wu unsigned int mask = 0;
4395d1c8e88STrevor Wu
4405d1c8e88STrevor Wu /* set sampling rate */
4415d1c8e88STrevor Wu mask |= DL_2_INPUT_MODE_CTL_MASK;
4425d1c8e88STrevor Wu val |= FIELD_PREP(DL_2_INPUT_MODE_CTL_MASK,
4435d1c8e88STrevor Wu afe_adda_dl_rate_transform(afe, rate));
4445d1c8e88STrevor Wu
4455d1c8e88STrevor Wu /* turn off saturation */
4465d1c8e88STrevor Wu mask |= DL_2_CH1_SATURATION_EN_CTL;
4475d1c8e88STrevor Wu mask |= DL_2_CH2_SATURATION_EN_CTL;
4485d1c8e88STrevor Wu
4495d1c8e88STrevor Wu /* turn off mute function */
4505d1c8e88STrevor Wu mask |= DL_2_MUTE_CH1_OFF_CTL_PRE;
4515d1c8e88STrevor Wu mask |= DL_2_MUTE_CH2_OFF_CTL_PRE;
4525d1c8e88STrevor Wu val |= DL_2_MUTE_CH1_OFF_CTL_PRE;
4535d1c8e88STrevor Wu val |= DL_2_MUTE_CH2_OFF_CTL_PRE;
4545d1c8e88STrevor Wu
4555d1c8e88STrevor Wu /* set voice input data if input sample rate is 8k or 16k */
4565d1c8e88STrevor Wu mask |= DL_2_VOICE_MODE_CTL_PRE;
4575d1c8e88STrevor Wu if (rate == 8000 || rate == 16000)
4585d1c8e88STrevor Wu val |= DL_2_VOICE_MODE_CTL_PRE;
4595d1c8e88STrevor Wu
4605d1c8e88STrevor Wu regmap_update_bits(afe->regmap, AFE_ADDA_DL_SRC2_CON0, mask, val);
4615d1c8e88STrevor Wu
4625d1c8e88STrevor Wu /* new 2nd sdm */
4635d1c8e88STrevor Wu regmap_set_bits(afe->regmap, AFE_ADDA_DL_SDM_DCCOMP_CON,
4645d1c8e88STrevor Wu DL_USE_NEW_2ND_SDM);
4655d1c8e88STrevor Wu
4665d1c8e88STrevor Wu return 0;
4675d1c8e88STrevor Wu }
4685d1c8e88STrevor Wu
mtk_dai_ad_configure(struct mtk_base_afe * afe,unsigned int rate,int id)4695d1c8e88STrevor Wu static int mtk_dai_ad_configure(struct mtk_base_afe *afe,
4705d1c8e88STrevor Wu unsigned int rate, int id)
4715d1c8e88STrevor Wu {
4725d1c8e88STrevor Wu unsigned int val;
4735d1c8e88STrevor Wu unsigned int mask;
4745d1c8e88STrevor Wu
4755d1c8e88STrevor Wu mask = UL_VOICE_MODE_CTL_MASK;
4765d1c8e88STrevor Wu val = FIELD_PREP(UL_VOICE_MODE_CTL_MASK,
4775d1c8e88STrevor Wu afe_adda_ul_rate_transform(afe, rate));
4785d1c8e88STrevor Wu
4795d1c8e88STrevor Wu regmap_update_bits(afe->regmap, AFE_ADDA_UL_SRC_CON0,
4805d1c8e88STrevor Wu mask, val);
4815d1c8e88STrevor Wu return 0;
4825d1c8e88STrevor Wu }
4835d1c8e88STrevor Wu
mtk_dai_adda_hw_params(struct snd_pcm_substream * substream,struct snd_pcm_hw_params * params,struct snd_soc_dai * dai)4845d1c8e88STrevor Wu static int mtk_dai_adda_hw_params(struct snd_pcm_substream *substream,
4855d1c8e88STrevor Wu struct snd_pcm_hw_params *params,
4865d1c8e88STrevor Wu struct snd_soc_dai *dai)
4875d1c8e88STrevor Wu {
4885d1c8e88STrevor Wu struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
4895d1c8e88STrevor Wu struct mt8188_afe_private *afe_priv = afe->platform_priv;
4905d1c8e88STrevor Wu struct mtk_dai_adda_priv *adda_priv = afe_priv->dai_priv[dai->id];
4915d1c8e88STrevor Wu unsigned int rate = params_rate(params);
4925d1c8e88STrevor Wu int id = dai->id;
4935d1c8e88STrevor Wu int ret = 0;
4945d1c8e88STrevor Wu
4955d1c8e88STrevor Wu dev_dbg(afe->dev, "%s(), id %d, stream %d, rate %u\n",
4965d1c8e88STrevor Wu __func__, id, substream->stream, rate);
4975d1c8e88STrevor Wu
498*2a7a1ae9STrevor Wu adda_priv->hires_required = (rate > ADDA_HIRES_THRES);
499*2a7a1ae9STrevor Wu
500*2a7a1ae9STrevor Wu if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
5015d1c8e88STrevor Wu ret = mtk_dai_da_configure(afe, rate, id);
502*2a7a1ae9STrevor Wu else
5035d1c8e88STrevor Wu ret = mtk_dai_ad_configure(afe, rate, id);
5045d1c8e88STrevor Wu
5055d1c8e88STrevor Wu return ret;
5065d1c8e88STrevor Wu }
5075d1c8e88STrevor Wu
5085d1c8e88STrevor Wu static const struct snd_soc_dai_ops mtk_dai_adda_ops = {
5095d1c8e88STrevor Wu .hw_params = mtk_dai_adda_hw_params,
5105d1c8e88STrevor Wu };
5115d1c8e88STrevor Wu
5125d1c8e88STrevor Wu /* dai driver */
5135d1c8e88STrevor Wu #define MTK_ADDA_PLAYBACK_RATES (SNDRV_PCM_RATE_8000_48000 |\
5145d1c8e88STrevor Wu SNDRV_PCM_RATE_96000 |\
5155d1c8e88STrevor Wu SNDRV_PCM_RATE_192000)
5165d1c8e88STrevor Wu
5175d1c8e88STrevor Wu #define MTK_ADDA_CAPTURE_RATES (SNDRV_PCM_RATE_8000 |\
5185d1c8e88STrevor Wu SNDRV_PCM_RATE_16000 |\
5195d1c8e88STrevor Wu SNDRV_PCM_RATE_32000 |\
5205d1c8e88STrevor Wu SNDRV_PCM_RATE_48000 |\
5215d1c8e88STrevor Wu SNDRV_PCM_RATE_96000 |\
5225d1c8e88STrevor Wu SNDRV_PCM_RATE_192000)
5235d1c8e88STrevor Wu
5245d1c8e88STrevor Wu #define MTK_ADDA_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
5255d1c8e88STrevor Wu SNDRV_PCM_FMTBIT_S24_LE |\
5265d1c8e88STrevor Wu SNDRV_PCM_FMTBIT_S32_LE)
5275d1c8e88STrevor Wu
5285d1c8e88STrevor Wu static struct snd_soc_dai_driver mtk_dai_adda_driver[] = {
5295d1c8e88STrevor Wu {
530*2a7a1ae9STrevor Wu .name = "DL_SRC",
531*2a7a1ae9STrevor Wu .id = MT8188_AFE_IO_DL_SRC,
5325d1c8e88STrevor Wu .playback = {
5335d1c8e88STrevor Wu .stream_name = "ADDA Playback",
5345d1c8e88STrevor Wu .channels_min = 1,
5355d1c8e88STrevor Wu .channels_max = 2,
5365d1c8e88STrevor Wu .rates = MTK_ADDA_PLAYBACK_RATES,
5375d1c8e88STrevor Wu .formats = MTK_ADDA_FORMATS,
5385d1c8e88STrevor Wu },
539*2a7a1ae9STrevor Wu .ops = &mtk_dai_adda_ops,
540*2a7a1ae9STrevor Wu },
541*2a7a1ae9STrevor Wu {
542*2a7a1ae9STrevor Wu .name = "UL_SRC",
543*2a7a1ae9STrevor Wu .id = MT8188_AFE_IO_UL_SRC,
5445d1c8e88STrevor Wu .capture = {
5455d1c8e88STrevor Wu .stream_name = "ADDA Capture",
5465d1c8e88STrevor Wu .channels_min = 1,
5475d1c8e88STrevor Wu .channels_max = 2,
5485d1c8e88STrevor Wu .rates = MTK_ADDA_CAPTURE_RATES,
5495d1c8e88STrevor Wu .formats = MTK_ADDA_FORMATS,
5505d1c8e88STrevor Wu },
5515d1c8e88STrevor Wu .ops = &mtk_dai_adda_ops,
5525d1c8e88STrevor Wu },
5535d1c8e88STrevor Wu };
5545d1c8e88STrevor Wu
init_adda_priv_data(struct mtk_base_afe * afe)5555d1c8e88STrevor Wu static int init_adda_priv_data(struct mtk_base_afe *afe)
5565d1c8e88STrevor Wu {
5575d1c8e88STrevor Wu struct mt8188_afe_private *afe_priv = afe->platform_priv;
5585d1c8e88STrevor Wu struct mtk_dai_adda_priv *adda_priv;
559*2a7a1ae9STrevor Wu int adda_dai_list[] = {MT8188_AFE_IO_DL_SRC, MT8188_AFE_IO_UL_SRC};
560*2a7a1ae9STrevor Wu int i;
5615d1c8e88STrevor Wu
562*2a7a1ae9STrevor Wu for (i = 0; i < ARRAY_SIZE(adda_dai_list); i++) {
563*2a7a1ae9STrevor Wu adda_priv = devm_kzalloc(afe->dev,
564*2a7a1ae9STrevor Wu sizeof(struct mtk_dai_adda_priv),
5655d1c8e88STrevor Wu GFP_KERNEL);
5665d1c8e88STrevor Wu if (!adda_priv)
5675d1c8e88STrevor Wu return -ENOMEM;
5685d1c8e88STrevor Wu
569*2a7a1ae9STrevor Wu afe_priv->dai_priv[adda_dai_list[i]] = adda_priv;
570*2a7a1ae9STrevor Wu }
5715d1c8e88STrevor Wu
5725d1c8e88STrevor Wu return 0;
5735d1c8e88STrevor Wu }
5745d1c8e88STrevor Wu
mt8188_dai_adda_register(struct mtk_base_afe * afe)5755d1c8e88STrevor Wu int mt8188_dai_adda_register(struct mtk_base_afe *afe)
5765d1c8e88STrevor Wu {
5775d1c8e88STrevor Wu struct mtk_base_afe_dai *dai;
5785d1c8e88STrevor Wu
5795d1c8e88STrevor Wu dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL);
5805d1c8e88STrevor Wu if (!dai)
5815d1c8e88STrevor Wu return -ENOMEM;
5825d1c8e88STrevor Wu
5835d1c8e88STrevor Wu list_add(&dai->list, &afe->sub_dais);
5845d1c8e88STrevor Wu
5855d1c8e88STrevor Wu dai->dai_drivers = mtk_dai_adda_driver;
5865d1c8e88STrevor Wu dai->num_dai_drivers = ARRAY_SIZE(mtk_dai_adda_driver);
5875d1c8e88STrevor Wu
5885d1c8e88STrevor Wu dai->dapm_widgets = mtk_dai_adda_widgets;
5895d1c8e88STrevor Wu dai->num_dapm_widgets = ARRAY_SIZE(mtk_dai_adda_widgets);
5905d1c8e88STrevor Wu dai->dapm_routes = mtk_dai_adda_routes;
5915d1c8e88STrevor Wu dai->num_dapm_routes = ARRAY_SIZE(mtk_dai_adda_routes);
5925d1c8e88STrevor Wu dai->controls = mtk_dai_adda_controls;
5935d1c8e88STrevor Wu dai->num_controls = ARRAY_SIZE(mtk_dai_adda_controls);
5945d1c8e88STrevor Wu
5955d1c8e88STrevor Wu return init_adda_priv_data(afe);
5965d1c8e88STrevor Wu }
597