xref: /openbmc/linux/sound/soc/codecs/mt6358.c (revision 1ac731c529cd4d6adbce134754b51ff7d822b145)
16a8d4198SShunli Wang // SPDX-License-Identifier: GPL-2.0
26a8d4198SShunli Wang //
36a8d4198SShunli Wang // mt6358.c  --  mt6358 ALSA SoC audio codec driver
46a8d4198SShunli Wang //
56a8d4198SShunli Wang // Copyright (c) 2018 MediaTek Inc.
66a8d4198SShunli Wang // Author: KaiChieh Chuang <kaichieh.chuang@mediatek.com>
76a8d4198SShunli Wang 
86a8d4198SShunli Wang #include <linux/platform_device.h>
96a8d4198SShunli Wang #include <linux/module.h>
106a8d4198SShunli Wang #include <linux/of_device.h>
116a8d4198SShunli Wang #include <linux/delay.h>
126a8d4198SShunli Wang #include <linux/kthread.h>
136a8d4198SShunli Wang #include <linux/sched.h>
146a8d4198SShunli Wang #include <linux/mfd/mt6397/core.h>
156a8d4198SShunli Wang #include <linux/regulator/consumer.h>
166a8d4198SShunli Wang 
176a8d4198SShunli Wang #include <sound/soc.h>
186a8d4198SShunli Wang #include <sound/tlv.h>
196a8d4198SShunli Wang 
206a8d4198SShunli Wang #include "mt6358.h"
216a8d4198SShunli Wang 
226a8d4198SShunli Wang enum {
236a8d4198SShunli Wang 	AUDIO_ANALOG_VOLUME_HSOUTL,
246a8d4198SShunli Wang 	AUDIO_ANALOG_VOLUME_HSOUTR,
256a8d4198SShunli Wang 	AUDIO_ANALOG_VOLUME_HPOUTL,
266a8d4198SShunli Wang 	AUDIO_ANALOG_VOLUME_HPOUTR,
276a8d4198SShunli Wang 	AUDIO_ANALOG_VOLUME_LINEOUTL,
286a8d4198SShunli Wang 	AUDIO_ANALOG_VOLUME_LINEOUTR,
296a8d4198SShunli Wang 	AUDIO_ANALOG_VOLUME_MICAMP1,
306a8d4198SShunli Wang 	AUDIO_ANALOG_VOLUME_MICAMP2,
316a8d4198SShunli Wang 	AUDIO_ANALOG_VOLUME_TYPE_MAX
326a8d4198SShunli Wang };
336a8d4198SShunli Wang 
346a8d4198SShunli Wang enum {
356a8d4198SShunli Wang 	MUX_ADC_L,
366a8d4198SShunli Wang 	MUX_ADC_R,
376a8d4198SShunli Wang 	MUX_PGA_L,
386a8d4198SShunli Wang 	MUX_PGA_R,
396a8d4198SShunli Wang 	MUX_MIC_TYPE,
406a8d4198SShunli Wang 	MUX_HP_L,
416a8d4198SShunli Wang 	MUX_HP_R,
426a8d4198SShunli Wang 	MUX_NUM,
436a8d4198SShunli Wang };
446a8d4198SShunli Wang 
456a8d4198SShunli Wang enum {
466a8d4198SShunli Wang 	DEVICE_HP,
476a8d4198SShunli Wang 	DEVICE_LO,
486a8d4198SShunli Wang 	DEVICE_RCV,
496a8d4198SShunli Wang 	DEVICE_MIC1,
506a8d4198SShunli Wang 	DEVICE_MIC2,
516a8d4198SShunli Wang 	DEVICE_NUM
526a8d4198SShunli Wang };
536a8d4198SShunli Wang 
546a8d4198SShunli Wang /* Supply widget subseq */
556a8d4198SShunli Wang enum {
566a8d4198SShunli Wang 	/* common */
576a8d4198SShunli Wang 	SUPPLY_SEQ_CLK_BUF,
586a8d4198SShunli Wang 	SUPPLY_SEQ_AUD_GLB,
596a8d4198SShunli Wang 	SUPPLY_SEQ_CLKSQ,
606a8d4198SShunli Wang 	SUPPLY_SEQ_VOW_AUD_LPW,
616a8d4198SShunli Wang 	SUPPLY_SEQ_AUD_VOW,
626a8d4198SShunli Wang 	SUPPLY_SEQ_VOW_CLK,
636a8d4198SShunli Wang 	SUPPLY_SEQ_VOW_LDO,
646a8d4198SShunli Wang 	SUPPLY_SEQ_TOP_CK,
656a8d4198SShunli Wang 	SUPPLY_SEQ_TOP_CK_LAST,
666a8d4198SShunli Wang 	SUPPLY_SEQ_AUD_TOP,
676a8d4198SShunli Wang 	SUPPLY_SEQ_AUD_TOP_LAST,
686a8d4198SShunli Wang 	SUPPLY_SEQ_AFE,
696a8d4198SShunli Wang 	/* capture */
706a8d4198SShunli Wang 	SUPPLY_SEQ_ADC_SUPPLY,
716a8d4198SShunli Wang };
726a8d4198SShunli Wang 
736a8d4198SShunli Wang enum {
746a8d4198SShunli Wang 	CH_L = 0,
756a8d4198SShunli Wang 	CH_R,
766a8d4198SShunli Wang 	NUM_CH,
776a8d4198SShunli Wang };
786a8d4198SShunli Wang 
796a8d4198SShunli Wang #define REG_STRIDE 2
806a8d4198SShunli Wang 
816a8d4198SShunli Wang struct mt6358_priv {
826a8d4198SShunli Wang 	struct device *dev;
836a8d4198SShunli Wang 	struct regmap *regmap;
846a8d4198SShunli Wang 
856a8d4198SShunli Wang 	unsigned int dl_rate;
866a8d4198SShunli Wang 	unsigned int ul_rate;
876a8d4198SShunli Wang 
886a8d4198SShunli Wang 	int ana_gain[AUDIO_ANALOG_VOLUME_TYPE_MAX];
896a8d4198SShunli Wang 	unsigned int mux_select[MUX_NUM];
906a8d4198SShunli Wang 
916a8d4198SShunli Wang 	int dev_counter[DEVICE_NUM];
926a8d4198SShunli Wang 
936a8d4198SShunli Wang 	int mtkaif_protocol;
946a8d4198SShunli Wang 
956a8d4198SShunli Wang 	struct regulator *avdd_reg;
968e8c533bSTzung-Bi Shih 
978e8c533bSTzung-Bi Shih 	int wov_enabled;
98c46fc800SJiaxin Yu 
99c46fc800SJiaxin Yu 	unsigned int dmic_one_wire_mode;
1006a8d4198SShunli Wang };
1016a8d4198SShunli Wang 
mt6358_set_mtkaif_protocol(struct snd_soc_component * cmpnt,int mtkaif_protocol)1026a8d4198SShunli Wang int mt6358_set_mtkaif_protocol(struct snd_soc_component *cmpnt,
1036a8d4198SShunli Wang 			       int mtkaif_protocol)
1046a8d4198SShunli Wang {
1056a8d4198SShunli Wang 	struct mt6358_priv *priv = snd_soc_component_get_drvdata(cmpnt);
1066a8d4198SShunli Wang 
1076a8d4198SShunli Wang 	priv->mtkaif_protocol = mtkaif_protocol;
1086a8d4198SShunli Wang 	return 0;
1096a8d4198SShunli Wang }
110a7663c89SJiaxin Yu EXPORT_SYMBOL_GPL(mt6358_set_mtkaif_protocol);
1116a8d4198SShunli Wang 
playback_gpio_set(struct mt6358_priv * priv)1126a8d4198SShunli Wang static void playback_gpio_set(struct mt6358_priv *priv)
1136a8d4198SShunli Wang {
1146a8d4198SShunli Wang 	/* set gpio mosi mode */
1156a8d4198SShunli Wang 	regmap_update_bits(priv->regmap, MT6358_GPIO_MODE2_CLR,
1166a8d4198SShunli Wang 			   0x01f8, 0x01f8);
1176a8d4198SShunli Wang 	regmap_update_bits(priv->regmap, MT6358_GPIO_MODE2_SET,
1186a8d4198SShunli Wang 			   0xffff, 0x0249);
1196a8d4198SShunli Wang 	regmap_update_bits(priv->regmap, MT6358_GPIO_MODE2,
1206a8d4198SShunli Wang 			   0xffff, 0x0249);
1216a8d4198SShunli Wang }
1226a8d4198SShunli Wang 
playback_gpio_reset(struct mt6358_priv * priv)1236a8d4198SShunli Wang static void playback_gpio_reset(struct mt6358_priv *priv)
1246a8d4198SShunli Wang {
1256a8d4198SShunli Wang 	/* set pad_aud_*_mosi to GPIO mode and dir input
1266a8d4198SShunli Wang 	 * reason:
1276a8d4198SShunli Wang 	 * pad_aud_dat_mosi*, because the pin is used as boot strap
1286a8d4198SShunli Wang 	 * don't clean clk/sync, for mtkaif protocol 2
1296a8d4198SShunli Wang 	 */
1306a8d4198SShunli Wang 	regmap_update_bits(priv->regmap, MT6358_GPIO_MODE2_CLR,
1316a8d4198SShunli Wang 			   0x01f8, 0x01f8);
1326a8d4198SShunli Wang 	regmap_update_bits(priv->regmap, MT6358_GPIO_MODE2,
1336a8d4198SShunli Wang 			   0x01f8, 0x0000);
1346a8d4198SShunli Wang 	regmap_update_bits(priv->regmap, MT6358_GPIO_DIR0,
1356a8d4198SShunli Wang 			   0xf << 8, 0x0);
1366a8d4198SShunli Wang }
1376a8d4198SShunli Wang 
capture_gpio_set(struct mt6358_priv * priv)1386a8d4198SShunli Wang static void capture_gpio_set(struct mt6358_priv *priv)
1396a8d4198SShunli Wang {
1406a8d4198SShunli Wang 	/* set gpio miso mode */
1416a8d4198SShunli Wang 	regmap_update_bits(priv->regmap, MT6358_GPIO_MODE3_CLR,
1426a8d4198SShunli Wang 			   0xffff, 0xffff);
1436a8d4198SShunli Wang 	regmap_update_bits(priv->regmap, MT6358_GPIO_MODE3_SET,
1446a8d4198SShunli Wang 			   0xffff, 0x0249);
1456a8d4198SShunli Wang 	regmap_update_bits(priv->regmap, MT6358_GPIO_MODE3,
1466a8d4198SShunli Wang 			   0xffff, 0x0249);
1476a8d4198SShunli Wang }
1486a8d4198SShunli Wang 
capture_gpio_reset(struct mt6358_priv * priv)1496a8d4198SShunli Wang static void capture_gpio_reset(struct mt6358_priv *priv)
1506a8d4198SShunli Wang {
1516a8d4198SShunli Wang 	/* set pad_aud_*_miso to GPIO mode and dir input
1526a8d4198SShunli Wang 	 * reason:
1536a8d4198SShunli Wang 	 * pad_aud_clk_miso, because when playback only the miso_clk
1546a8d4198SShunli Wang 	 * will also have 26m, so will have power leak
1556a8d4198SShunli Wang 	 * pad_aud_dat_miso*, because the pin is used as boot strap
1566a8d4198SShunli Wang 	 */
1576a8d4198SShunli Wang 	regmap_update_bits(priv->regmap, MT6358_GPIO_MODE3_CLR,
1586a8d4198SShunli Wang 			   0xffff, 0xffff);
1596a8d4198SShunli Wang 	regmap_update_bits(priv->regmap, MT6358_GPIO_MODE3,
1606a8d4198SShunli Wang 			   0xffff, 0x0000);
1616a8d4198SShunli Wang 	regmap_update_bits(priv->regmap, MT6358_GPIO_DIR0,
1626a8d4198SShunli Wang 			   0xf << 12, 0x0);
1636a8d4198SShunli Wang }
1646a8d4198SShunli Wang 
1656a8d4198SShunli Wang /* use only when not govern by DAPM */
mt6358_set_dcxo(struct mt6358_priv * priv,bool enable)1666a8d4198SShunli Wang static int mt6358_set_dcxo(struct mt6358_priv *priv, bool enable)
1676a8d4198SShunli Wang {
1686a8d4198SShunli Wang 	regmap_update_bits(priv->regmap, MT6358_DCXO_CW14,
1696a8d4198SShunli Wang 			   0x1 << RG_XO_AUDIO_EN_M_SFT,
1706a8d4198SShunli Wang 			   (enable ? 1 : 0) << RG_XO_AUDIO_EN_M_SFT);
1716a8d4198SShunli Wang 	return 0;
1726a8d4198SShunli Wang }
1736a8d4198SShunli Wang 
1746a8d4198SShunli Wang /* use only when not govern by DAPM */
mt6358_set_clksq(struct mt6358_priv * priv,bool enable)1756a8d4198SShunli Wang static int mt6358_set_clksq(struct mt6358_priv *priv, bool enable)
1766a8d4198SShunli Wang {
1776a8d4198SShunli Wang 	/* audio clk source from internal dcxo */
1786a8d4198SShunli Wang 	regmap_update_bits(priv->regmap, MT6358_AUDENC_ANA_CON6,
1796a8d4198SShunli Wang 			   RG_CLKSQ_IN_SEL_TEST_MASK_SFT,
1806a8d4198SShunli Wang 			   0x0);
1816a8d4198SShunli Wang 
1826a8d4198SShunli Wang 	/* Enable/disable CLKSQ 26MHz */
1836a8d4198SShunli Wang 	regmap_update_bits(priv->regmap, MT6358_AUDENC_ANA_CON6,
1846a8d4198SShunli Wang 			   RG_CLKSQ_EN_MASK_SFT,
1856a8d4198SShunli Wang 			   (enable ? 1 : 0) << RG_CLKSQ_EN_SFT);
1866a8d4198SShunli Wang 	return 0;
1876a8d4198SShunli Wang }
1886a8d4198SShunli Wang 
1896a8d4198SShunli Wang /* use only when not govern by DAPM */
mt6358_set_aud_global_bias(struct mt6358_priv * priv,bool enable)1906a8d4198SShunli Wang static int mt6358_set_aud_global_bias(struct mt6358_priv *priv, bool enable)
1916a8d4198SShunli Wang {
1926a8d4198SShunli Wang 	regmap_update_bits(priv->regmap, MT6358_AUDDEC_ANA_CON13,
1936a8d4198SShunli Wang 			   RG_AUDGLB_PWRDN_VA28_MASK_SFT,
1946a8d4198SShunli Wang 			   (enable ? 0 : 1) << RG_AUDGLB_PWRDN_VA28_SFT);
1956a8d4198SShunli Wang 	return 0;
1966a8d4198SShunli Wang }
1976a8d4198SShunli Wang 
1986a8d4198SShunli Wang /* use only when not govern by DAPM */
mt6358_set_topck(struct mt6358_priv * priv,bool enable)1996a8d4198SShunli Wang static int mt6358_set_topck(struct mt6358_priv *priv, bool enable)
2006a8d4198SShunli Wang {
2016a8d4198SShunli Wang 	regmap_update_bits(priv->regmap, MT6358_AUD_TOP_CKPDN_CON0,
2026a8d4198SShunli Wang 			   0x0066, enable ? 0x0 : 0x66);
2036a8d4198SShunli Wang 	return 0;
2046a8d4198SShunli Wang }
2056a8d4198SShunli Wang 
mt6358_mtkaif_tx_enable(struct mt6358_priv * priv)2066a8d4198SShunli Wang static int mt6358_mtkaif_tx_enable(struct mt6358_priv *priv)
2076a8d4198SShunli Wang {
2086a8d4198SShunli Wang 	switch (priv->mtkaif_protocol) {
2096a8d4198SShunli Wang 	case MT6358_MTKAIF_PROTOCOL_2_CLK_P2:
2106a8d4198SShunli Wang 		/* MTKAIF TX format setting */
2116a8d4198SShunli Wang 		regmap_update_bits(priv->regmap,
2126a8d4198SShunli Wang 				   MT6358_AFE_ADDA_MTKAIF_CFG0,
2136a8d4198SShunli Wang 				   0xffff, 0x0010);
2146a8d4198SShunli Wang 		/* enable aud_pad TX fifos */
2156a8d4198SShunli Wang 		regmap_update_bits(priv->regmap,
2166a8d4198SShunli Wang 				   MT6358_AFE_AUD_PAD_TOP,
2176a8d4198SShunli Wang 				   0xff00, 0x3800);
2186a8d4198SShunli Wang 		regmap_update_bits(priv->regmap,
2196a8d4198SShunli Wang 				   MT6358_AFE_AUD_PAD_TOP,
2206a8d4198SShunli Wang 				   0xff00, 0x3900);
2216a8d4198SShunli Wang 		break;
2226a8d4198SShunli Wang 	case MT6358_MTKAIF_PROTOCOL_2:
2236a8d4198SShunli Wang 		/* MTKAIF TX format setting */
2246a8d4198SShunli Wang 		regmap_update_bits(priv->regmap,
2256a8d4198SShunli Wang 				   MT6358_AFE_ADDA_MTKAIF_CFG0,
2266a8d4198SShunli Wang 				   0xffff, 0x0010);
2276a8d4198SShunli Wang 		/* enable aud_pad TX fifos */
2286a8d4198SShunli Wang 		regmap_update_bits(priv->regmap,
2296a8d4198SShunli Wang 				   MT6358_AFE_AUD_PAD_TOP,
2306a8d4198SShunli Wang 				   0xff00, 0x3100);
2316a8d4198SShunli Wang 		break;
2326a8d4198SShunli Wang 	case MT6358_MTKAIF_PROTOCOL_1:
2336a8d4198SShunli Wang 	default:
2346a8d4198SShunli Wang 		/* MTKAIF TX format setting */
2356a8d4198SShunli Wang 		regmap_update_bits(priv->regmap,
2366a8d4198SShunli Wang 				   MT6358_AFE_ADDA_MTKAIF_CFG0,
2376a8d4198SShunli Wang 				   0xffff, 0x0000);
2386a8d4198SShunli Wang 		/* enable aud_pad TX fifos */
2396a8d4198SShunli Wang 		regmap_update_bits(priv->regmap,
2406a8d4198SShunli Wang 				   MT6358_AFE_AUD_PAD_TOP,
2416a8d4198SShunli Wang 				   0xff00, 0x3100);
2426a8d4198SShunli Wang 		break;
2436a8d4198SShunli Wang 	}
2446a8d4198SShunli Wang 	return 0;
2456a8d4198SShunli Wang }
2466a8d4198SShunli Wang 
mt6358_mtkaif_tx_disable(struct mt6358_priv * priv)2476a8d4198SShunli Wang static int mt6358_mtkaif_tx_disable(struct mt6358_priv *priv)
2486a8d4198SShunli Wang {
2496a8d4198SShunli Wang 	/* disable aud_pad TX fifos */
2506a8d4198SShunli Wang 	regmap_update_bits(priv->regmap, MT6358_AFE_AUD_PAD_TOP,
2516a8d4198SShunli Wang 			   0xff00, 0x3000);
2526a8d4198SShunli Wang 	return 0;
2536a8d4198SShunli Wang }
2546a8d4198SShunli Wang 
mt6358_mtkaif_calibration_enable(struct snd_soc_component * cmpnt)2556a8d4198SShunli Wang int mt6358_mtkaif_calibration_enable(struct snd_soc_component *cmpnt)
2566a8d4198SShunli Wang {
2576a8d4198SShunli Wang 	struct mt6358_priv *priv = snd_soc_component_get_drvdata(cmpnt);
2586a8d4198SShunli Wang 
2596a8d4198SShunli Wang 	playback_gpio_set(priv);
2606a8d4198SShunli Wang 	capture_gpio_set(priv);
2616a8d4198SShunli Wang 	mt6358_mtkaif_tx_enable(priv);
2626a8d4198SShunli Wang 
2636a8d4198SShunli Wang 	mt6358_set_dcxo(priv, true);
2646a8d4198SShunli Wang 	mt6358_set_aud_global_bias(priv, true);
2656a8d4198SShunli Wang 	mt6358_set_clksq(priv, true);
2666a8d4198SShunli Wang 	mt6358_set_topck(priv, true);
2676a8d4198SShunli Wang 
2686a8d4198SShunli Wang 	/* set dat_miso_loopback on */
2696a8d4198SShunli Wang 	regmap_update_bits(priv->regmap, MT6358_AUDIO_DIG_CFG,
2706a8d4198SShunli Wang 			   RG_AUD_PAD_TOP_DAT_MISO2_LOOPBACK_MASK_SFT,
2716a8d4198SShunli Wang 			   1 << RG_AUD_PAD_TOP_DAT_MISO2_LOOPBACK_SFT);
2726a8d4198SShunli Wang 	regmap_update_bits(priv->regmap, MT6358_AUDIO_DIG_CFG,
2736a8d4198SShunli Wang 			   RG_AUD_PAD_TOP_DAT_MISO_LOOPBACK_MASK_SFT,
2746a8d4198SShunli Wang 			   1 << RG_AUD_PAD_TOP_DAT_MISO_LOOPBACK_SFT);
2756a8d4198SShunli Wang 	return 0;
2766a8d4198SShunli Wang }
277a7663c89SJiaxin Yu EXPORT_SYMBOL_GPL(mt6358_mtkaif_calibration_enable);
2786a8d4198SShunli Wang 
mt6358_mtkaif_calibration_disable(struct snd_soc_component * cmpnt)2796a8d4198SShunli Wang int mt6358_mtkaif_calibration_disable(struct snd_soc_component *cmpnt)
2806a8d4198SShunli Wang {
2816a8d4198SShunli Wang 	struct mt6358_priv *priv = snd_soc_component_get_drvdata(cmpnt);
2826a8d4198SShunli Wang 
2836a8d4198SShunli Wang 	/* set dat_miso_loopback off */
2846a8d4198SShunli Wang 	regmap_update_bits(priv->regmap, MT6358_AUDIO_DIG_CFG,
2856a8d4198SShunli Wang 			   RG_AUD_PAD_TOP_DAT_MISO2_LOOPBACK_MASK_SFT,
2866a8d4198SShunli Wang 			   0 << RG_AUD_PAD_TOP_DAT_MISO2_LOOPBACK_SFT);
2876a8d4198SShunli Wang 	regmap_update_bits(priv->regmap, MT6358_AUDIO_DIG_CFG,
2886a8d4198SShunli Wang 			   RG_AUD_PAD_TOP_DAT_MISO_LOOPBACK_MASK_SFT,
2896a8d4198SShunli Wang 			   0 << RG_AUD_PAD_TOP_DAT_MISO_LOOPBACK_SFT);
2906a8d4198SShunli Wang 
2916a8d4198SShunli Wang 	mt6358_set_topck(priv, false);
2926a8d4198SShunli Wang 	mt6358_set_clksq(priv, false);
2936a8d4198SShunli Wang 	mt6358_set_aud_global_bias(priv, false);
2946a8d4198SShunli Wang 	mt6358_set_dcxo(priv, false);
2956a8d4198SShunli Wang 
2966a8d4198SShunli Wang 	mt6358_mtkaif_tx_disable(priv);
2976a8d4198SShunli Wang 	playback_gpio_reset(priv);
2986a8d4198SShunli Wang 	capture_gpio_reset(priv);
2996a8d4198SShunli Wang 	return 0;
3006a8d4198SShunli Wang }
301a7663c89SJiaxin Yu EXPORT_SYMBOL_GPL(mt6358_mtkaif_calibration_disable);
3026a8d4198SShunli Wang 
mt6358_set_mtkaif_calibration_phase(struct snd_soc_component * cmpnt,int phase_1,int phase_2)3036a8d4198SShunli Wang int mt6358_set_mtkaif_calibration_phase(struct snd_soc_component *cmpnt,
3046a8d4198SShunli Wang 					int phase_1, int phase_2)
3056a8d4198SShunli Wang {
3066a8d4198SShunli Wang 	struct mt6358_priv *priv = snd_soc_component_get_drvdata(cmpnt);
3076a8d4198SShunli Wang 
3086a8d4198SShunli Wang 	regmap_update_bits(priv->regmap, MT6358_AUDIO_DIG_CFG,
3096a8d4198SShunli Wang 			   RG_AUD_PAD_TOP_PHASE_MODE_MASK_SFT,
3106a8d4198SShunli Wang 			   phase_1 << RG_AUD_PAD_TOP_PHASE_MODE_SFT);
3116a8d4198SShunli Wang 	regmap_update_bits(priv->regmap, MT6358_AUDIO_DIG_CFG,
3126a8d4198SShunli Wang 			   RG_AUD_PAD_TOP_PHASE_MODE2_MASK_SFT,
3136a8d4198SShunli Wang 			   phase_2 << RG_AUD_PAD_TOP_PHASE_MODE2_SFT);
3146a8d4198SShunli Wang 	return 0;
3156a8d4198SShunli Wang }
316a7663c89SJiaxin Yu EXPORT_SYMBOL_GPL(mt6358_set_mtkaif_calibration_phase);
3176a8d4198SShunli Wang 
3186a8d4198SShunli Wang /* dl pga gain */
3196a8d4198SShunli Wang enum {
3206a8d4198SShunli Wang 	DL_GAIN_8DB = 0,
3216a8d4198SShunli Wang 	DL_GAIN_0DB = 8,
3226a8d4198SShunli Wang 	DL_GAIN_N_1DB = 9,
3236a8d4198SShunli Wang 	DL_GAIN_N_10DB = 18,
3246a8d4198SShunli Wang 	DL_GAIN_N_40DB = 0x1f,
3256a8d4198SShunli Wang };
3266a8d4198SShunli Wang 
3276a8d4198SShunli Wang #define DL_GAIN_N_10DB_REG (DL_GAIN_N_10DB << 7 | DL_GAIN_N_10DB)
3286a8d4198SShunli Wang #define DL_GAIN_N_40DB_REG (DL_GAIN_N_40DB << 7 | DL_GAIN_N_40DB)
3296a8d4198SShunli Wang #define DL_GAIN_REG_MASK 0x0f9f
3306a8d4198SShunli Wang 
hp_zcd_disable(struct mt6358_priv * priv)3316a8d4198SShunli Wang static void hp_zcd_disable(struct mt6358_priv *priv)
3326a8d4198SShunli Wang {
3336a8d4198SShunli Wang 	regmap_write(priv->regmap, MT6358_ZCD_CON0, 0x0000);
3346a8d4198SShunli Wang }
3356a8d4198SShunli Wang 
hp_main_output_ramp(struct mt6358_priv * priv,bool up)3366a8d4198SShunli Wang static void hp_main_output_ramp(struct mt6358_priv *priv, bool up)
3376a8d4198SShunli Wang {
3382b5e8cd5SPierre-Louis Bossart 	int i, stage;
3396a8d4198SShunli Wang 	int target = 7;
3406a8d4198SShunli Wang 
3416a8d4198SShunli Wang 	/* Enable/Reduce HPL/R main output stage step by step */
3426a8d4198SShunli Wang 	for (i = 0; i <= target; i++) {
3436a8d4198SShunli Wang 		stage = up ? i : target - i;
3446a8d4198SShunli Wang 		regmap_update_bits(priv->regmap, MT6358_AUDDEC_ANA_CON1,
3456a8d4198SShunli Wang 				   0x7 << 8, stage << 8);
3466a8d4198SShunli Wang 		regmap_update_bits(priv->regmap, MT6358_AUDDEC_ANA_CON1,
3476a8d4198SShunli Wang 				   0x7 << 11, stage << 11);
3486a8d4198SShunli Wang 		usleep_range(100, 150);
3496a8d4198SShunli Wang 	}
3506a8d4198SShunli Wang }
3516a8d4198SShunli Wang 
hp_aux_feedback_loop_gain_ramp(struct mt6358_priv * priv,bool up)3526a8d4198SShunli Wang static void hp_aux_feedback_loop_gain_ramp(struct mt6358_priv *priv, bool up)
3536a8d4198SShunli Wang {
3542b5e8cd5SPierre-Louis Bossart 	int i, stage;
3556a8d4198SShunli Wang 
3566a8d4198SShunli Wang 	/* Reduce HP aux feedback loop gain step by step */
3576a8d4198SShunli Wang 	for (i = 0; i <= 0xf; i++) {
3586a8d4198SShunli Wang 		stage = up ? i : 0xf - i;
3596a8d4198SShunli Wang 		regmap_update_bits(priv->regmap, MT6358_AUDDEC_ANA_CON9,
3606a8d4198SShunli Wang 				   0xf << 12, stage << 12);
3616a8d4198SShunli Wang 		usleep_range(100, 150);
3626a8d4198SShunli Wang 	}
3636a8d4198SShunli Wang }
3646a8d4198SShunli Wang 
hp_pull_down(struct mt6358_priv * priv,bool enable)3656a8d4198SShunli Wang static void hp_pull_down(struct mt6358_priv *priv, bool enable)
3666a8d4198SShunli Wang {
3676a8d4198SShunli Wang 	int i;
3686a8d4198SShunli Wang 
3696a8d4198SShunli Wang 	if (enable) {
3706a8d4198SShunli Wang 		for (i = 0x0; i <= 0x6; i++) {
3716a8d4198SShunli Wang 			regmap_update_bits(priv->regmap, MT6358_AUDDEC_ANA_CON4,
3726a8d4198SShunli Wang 					   0x7, i);
3736a8d4198SShunli Wang 			usleep_range(600, 700);
3746a8d4198SShunli Wang 		}
3756a8d4198SShunli Wang 	} else {
3766a8d4198SShunli Wang 		for (i = 0x6; i >= 0x1; i--) {
3776a8d4198SShunli Wang 			regmap_update_bits(priv->regmap, MT6358_AUDDEC_ANA_CON4,
3786a8d4198SShunli Wang 					   0x7, i);
3796a8d4198SShunli Wang 			usleep_range(600, 700);
3806a8d4198SShunli Wang 		}
3816a8d4198SShunli Wang 	}
3826a8d4198SShunli Wang }
3836a8d4198SShunli Wang 
is_valid_hp_pga_idx(int reg_idx)3846a8d4198SShunli Wang static bool is_valid_hp_pga_idx(int reg_idx)
3856a8d4198SShunli Wang {
3866a8d4198SShunli Wang 	return (reg_idx >= DL_GAIN_8DB && reg_idx <= DL_GAIN_N_10DB) ||
3876a8d4198SShunli Wang 	       reg_idx == DL_GAIN_N_40DB;
3886a8d4198SShunli Wang }
3896a8d4198SShunli Wang 
headset_volume_ramp(struct mt6358_priv * priv,int from,int to)390bdb8fa6bSTzung-Bi Shih static void headset_volume_ramp(struct mt6358_priv *priv, int from, int to)
3916a8d4198SShunli Wang {
392bdb8fa6bSTzung-Bi Shih 	int offset = 0, count = 0, reg_idx;
3936a8d4198SShunli Wang 
3946a8d4198SShunli Wang 	if (!is_valid_hp_pga_idx(from) || !is_valid_hp_pga_idx(to))
3956a8d4198SShunli Wang 		dev_warn(priv->dev, "%s(), volume index is not valid, from %d, to %d\n",
3966a8d4198SShunli Wang 			 __func__, from, to);
3976a8d4198SShunli Wang 
3986a8d4198SShunli Wang 	dev_info(priv->dev, "%s(), from %d, to %d\n",
3996a8d4198SShunli Wang 		 __func__, from, to);
4006a8d4198SShunli Wang 
4016a8d4198SShunli Wang 	if (to > from)
4026a8d4198SShunli Wang 		offset = to - from;
4036a8d4198SShunli Wang 	else
4046a8d4198SShunli Wang 		offset = from - to;
4056a8d4198SShunli Wang 
406bdb8fa6bSTzung-Bi Shih 	while (offset >= 0) {
4076a8d4198SShunli Wang 		if (to > from)
4086a8d4198SShunli Wang 			reg_idx = from + count;
4096a8d4198SShunli Wang 		else
4106a8d4198SShunli Wang 			reg_idx = from - count;
4116a8d4198SShunli Wang 
4126a8d4198SShunli Wang 		if (is_valid_hp_pga_idx(reg_idx)) {
4136a8d4198SShunli Wang 			regmap_update_bits(priv->regmap,
4146a8d4198SShunli Wang 					   MT6358_ZCD_CON2,
4156a8d4198SShunli Wang 					   DL_GAIN_REG_MASK,
4166a8d4198SShunli Wang 					   (reg_idx << 7) | reg_idx);
4176a8d4198SShunli Wang 			usleep_range(200, 300);
4186a8d4198SShunli Wang 		}
4196a8d4198SShunli Wang 		offset--;
4206a8d4198SShunli Wang 		count++;
4216a8d4198SShunli Wang 	}
4226a8d4198SShunli Wang }
4236a8d4198SShunli Wang 
mt6358_put_volsw(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)424bbb56537STzung-Bi Shih static int mt6358_put_volsw(struct snd_kcontrol *kcontrol,
425bbb56537STzung-Bi Shih 			    struct snd_ctl_elem_value *ucontrol)
426bbb56537STzung-Bi Shih {
427bbb56537STzung-Bi Shih 	struct snd_soc_component *component =
428bbb56537STzung-Bi Shih 			snd_soc_kcontrol_component(kcontrol);
429bbb56537STzung-Bi Shih 	struct mt6358_priv *priv = snd_soc_component_get_drvdata(component);
430bbb56537STzung-Bi Shih 	struct soc_mixer_control *mc =
431bbb56537STzung-Bi Shih 			(struct soc_mixer_control *)kcontrol->private_value;
432*9760e01bSTrevor Wu 	unsigned int reg = 0;
433bbb56537STzung-Bi Shih 	int ret;
434bbb56537STzung-Bi Shih 
435bbb56537STzung-Bi Shih 	ret = snd_soc_put_volsw(kcontrol, ucontrol);
436bbb56537STzung-Bi Shih 	if (ret < 0)
437bbb56537STzung-Bi Shih 		return ret;
438bbb56537STzung-Bi Shih 
439bbb56537STzung-Bi Shih 	switch (mc->reg) {
440bbb56537STzung-Bi Shih 	case MT6358_ZCD_CON2:
441bbb56537STzung-Bi Shih 		regmap_read(priv->regmap, MT6358_ZCD_CON2, &reg);
442bbb56537STzung-Bi Shih 		priv->ana_gain[AUDIO_ANALOG_VOLUME_HPOUTL] =
443bbb56537STzung-Bi Shih 			(reg >> RG_AUDHPLGAIN_SFT) & RG_AUDHPLGAIN_MASK;
444bbb56537STzung-Bi Shih 		priv->ana_gain[AUDIO_ANALOG_VOLUME_HPOUTR] =
445bbb56537STzung-Bi Shih 			(reg >> RG_AUDHPRGAIN_SFT) & RG_AUDHPRGAIN_MASK;
446bbb56537STzung-Bi Shih 		break;
447bbb56537STzung-Bi Shih 	case MT6358_ZCD_CON1:
448bbb56537STzung-Bi Shih 		regmap_read(priv->regmap, MT6358_ZCD_CON1, &reg);
449bbb56537STzung-Bi Shih 		priv->ana_gain[AUDIO_ANALOG_VOLUME_LINEOUTL] =
450bbb56537STzung-Bi Shih 			(reg >> RG_AUDLOLGAIN_SFT) & RG_AUDLOLGAIN_MASK;
451bbb56537STzung-Bi Shih 		priv->ana_gain[AUDIO_ANALOG_VOLUME_LINEOUTR] =
452bbb56537STzung-Bi Shih 			(reg >> RG_AUDLORGAIN_SFT) & RG_AUDLORGAIN_MASK;
453bbb56537STzung-Bi Shih 		break;
454bbb56537STzung-Bi Shih 	case MT6358_ZCD_CON3:
455bbb56537STzung-Bi Shih 		regmap_read(priv->regmap, MT6358_ZCD_CON3, &reg);
456bbb56537STzung-Bi Shih 		priv->ana_gain[AUDIO_ANALOG_VOLUME_HSOUTL] =
457bbb56537STzung-Bi Shih 			(reg >> RG_AUDHSGAIN_SFT) & RG_AUDHSGAIN_MASK;
458bbb56537STzung-Bi Shih 		priv->ana_gain[AUDIO_ANALOG_VOLUME_HSOUTR] =
459bbb56537STzung-Bi Shih 			(reg >> RG_AUDHSGAIN_SFT) & RG_AUDHSGAIN_MASK;
460bbb56537STzung-Bi Shih 		break;
461ec0574a6STzung-Bi Shih 	case MT6358_AUDENC_ANA_CON0:
462ec0574a6STzung-Bi Shih 	case MT6358_AUDENC_ANA_CON1:
463ec0574a6STzung-Bi Shih 		regmap_read(priv->regmap, MT6358_AUDENC_ANA_CON0, &reg);
464ec0574a6STzung-Bi Shih 		priv->ana_gain[AUDIO_ANALOG_VOLUME_MICAMP1] =
465ec0574a6STzung-Bi Shih 			(reg >> RG_AUDPREAMPLGAIN_SFT) & RG_AUDPREAMPLGAIN_MASK;
466ec0574a6STzung-Bi Shih 		regmap_read(priv->regmap, MT6358_AUDENC_ANA_CON1, &reg);
467ec0574a6STzung-Bi Shih 		priv->ana_gain[AUDIO_ANALOG_VOLUME_MICAMP2] =
468ec0574a6STzung-Bi Shih 			(reg >> RG_AUDPREAMPRGAIN_SFT) & RG_AUDPREAMPRGAIN_MASK;
469ec0574a6STzung-Bi Shih 		break;
470bbb56537STzung-Bi Shih 	}
471bbb56537STzung-Bi Shih 
472bbb56537STzung-Bi Shih 	return ret;
473bbb56537STzung-Bi Shih }
474bbb56537STzung-Bi Shih 
4758e8c533bSTzung-Bi Shih static void mt6358_restore_pga(struct mt6358_priv *priv);
4768e8c533bSTzung-Bi Shih 
mt6358_enable_wov_phase2(struct mt6358_priv * priv)4778e8c533bSTzung-Bi Shih static int mt6358_enable_wov_phase2(struct mt6358_priv *priv)
4788e8c533bSTzung-Bi Shih {
4798e8c533bSTzung-Bi Shih 	/* analog */
4808e8c533bSTzung-Bi Shih 	regmap_update_bits(priv->regmap, MT6358_AUDDEC_ANA_CON13,
4818e8c533bSTzung-Bi Shih 			   0xffff, 0x0000);
4828e8c533bSTzung-Bi Shih 	regmap_update_bits(priv->regmap, MT6358_DCXO_CW14, 0xffff, 0xa2b5);
4838e8c533bSTzung-Bi Shih 	regmap_update_bits(priv->regmap, MT6358_AUDENC_ANA_CON1,
4848e8c533bSTzung-Bi Shih 			   0xffff, 0x0800);
4858e8c533bSTzung-Bi Shih 	mt6358_restore_pga(priv);
4868e8c533bSTzung-Bi Shih 
4878e8c533bSTzung-Bi Shih 	regmap_update_bits(priv->regmap, MT6358_DCXO_CW13, 0xffff, 0x9929);
4888e8c533bSTzung-Bi Shih 	regmap_update_bits(priv->regmap, MT6358_AUDENC_ANA_CON9,
4898e8c533bSTzung-Bi Shih 			   0xffff, 0x0025);
4908e8c533bSTzung-Bi Shih 	regmap_update_bits(priv->regmap, MT6358_AUDENC_ANA_CON8,
4918e8c533bSTzung-Bi Shih 			   0xffff, 0x0005);
4928e8c533bSTzung-Bi Shih 
4938e8c533bSTzung-Bi Shih 	/* digital */
4948e8c533bSTzung-Bi Shih 	regmap_update_bits(priv->regmap, MT6358_AUD_TOP_CKPDN_CON0,
4958e8c533bSTzung-Bi Shih 			   0xffff, 0x0000);
4968e8c533bSTzung-Bi Shih 	regmap_update_bits(priv->regmap, MT6358_GPIO_MODE3, 0xffff, 0x0120);
4978e8c533bSTzung-Bi Shih 	regmap_update_bits(priv->regmap, MT6358_AFE_VOW_CFG0, 0xffff, 0xffff);
4988e8c533bSTzung-Bi Shih 	regmap_update_bits(priv->regmap, MT6358_AFE_VOW_CFG1, 0xffff, 0x0200);
4998e8c533bSTzung-Bi Shih 	regmap_update_bits(priv->regmap, MT6358_AFE_VOW_CFG2, 0xffff, 0x2424);
5008e8c533bSTzung-Bi Shih 	regmap_update_bits(priv->regmap, MT6358_AFE_VOW_CFG3, 0xffff, 0xdbac);
5018e8c533bSTzung-Bi Shih 	regmap_update_bits(priv->regmap, MT6358_AFE_VOW_CFG4, 0xffff, 0x029e);
5028e8c533bSTzung-Bi Shih 	regmap_update_bits(priv->regmap, MT6358_AFE_VOW_CFG5, 0xffff, 0x0000);
5038e8c533bSTzung-Bi Shih 	regmap_update_bits(priv->regmap, MT6358_AFE_VOW_POSDIV_CFG0,
5048e8c533bSTzung-Bi Shih 			   0xffff, 0x0000);
5058e8c533bSTzung-Bi Shih 	regmap_update_bits(priv->regmap, MT6358_AFE_VOW_HPF_CFG0,
5068e8c533bSTzung-Bi Shih 			   0xffff, 0x0451);
5078e8c533bSTzung-Bi Shih 	regmap_update_bits(priv->regmap, MT6358_AFE_VOW_TOP, 0xffff, 0x68d1);
5088e8c533bSTzung-Bi Shih 
5098e8c533bSTzung-Bi Shih 	return 0;
5108e8c533bSTzung-Bi Shih }
5118e8c533bSTzung-Bi Shih 
mt6358_disable_wov_phase2(struct mt6358_priv * priv)5128e8c533bSTzung-Bi Shih static int mt6358_disable_wov_phase2(struct mt6358_priv *priv)
5138e8c533bSTzung-Bi Shih {
5148e8c533bSTzung-Bi Shih 	/* digital */
5158e8c533bSTzung-Bi Shih 	regmap_update_bits(priv->regmap, MT6358_AFE_VOW_TOP, 0xffff, 0xc000);
5168e8c533bSTzung-Bi Shih 	regmap_update_bits(priv->regmap, MT6358_AFE_VOW_HPF_CFG0,
5178e8c533bSTzung-Bi Shih 			   0xffff, 0x0450);
5188e8c533bSTzung-Bi Shih 	regmap_update_bits(priv->regmap, MT6358_AFE_VOW_POSDIV_CFG0,
5198e8c533bSTzung-Bi Shih 			   0xffff, 0x0c00);
5208e8c533bSTzung-Bi Shih 	regmap_update_bits(priv->regmap, MT6358_AFE_VOW_CFG5, 0xffff, 0x0100);
5218e8c533bSTzung-Bi Shih 	regmap_update_bits(priv->regmap, MT6358_AFE_VOW_CFG4, 0xffff, 0x006c);
5228e8c533bSTzung-Bi Shih 	regmap_update_bits(priv->regmap, MT6358_AFE_VOW_CFG3, 0xffff, 0xa879);
5238e8c533bSTzung-Bi Shih 	regmap_update_bits(priv->regmap, MT6358_AFE_VOW_CFG2, 0xffff, 0x2323);
5248e8c533bSTzung-Bi Shih 	regmap_update_bits(priv->regmap, MT6358_AFE_VOW_CFG1, 0xffff, 0x0400);
5258e8c533bSTzung-Bi Shih 	regmap_update_bits(priv->regmap, MT6358_AFE_VOW_CFG0, 0xffff, 0x0000);
5268e8c533bSTzung-Bi Shih 	regmap_update_bits(priv->regmap, MT6358_GPIO_MODE3, 0xffff, 0x02d8);
5278e8c533bSTzung-Bi Shih 	regmap_update_bits(priv->regmap, MT6358_AUD_TOP_CKPDN_CON0,
5288e8c533bSTzung-Bi Shih 			   0xffff, 0x0000);
5298e8c533bSTzung-Bi Shih 
5308e8c533bSTzung-Bi Shih 	/* analog */
5318e8c533bSTzung-Bi Shih 	regmap_update_bits(priv->regmap, MT6358_AUDENC_ANA_CON8,
5328e8c533bSTzung-Bi Shih 			   0xffff, 0x0004);
5338e8c533bSTzung-Bi Shih 	regmap_update_bits(priv->regmap, MT6358_AUDENC_ANA_CON9,
5348e8c533bSTzung-Bi Shih 			   0xffff, 0x0000);
5358e8c533bSTzung-Bi Shih 	regmap_update_bits(priv->regmap, MT6358_DCXO_CW13, 0xffff, 0x9829);
5368e8c533bSTzung-Bi Shih 	regmap_update_bits(priv->regmap, MT6358_AUDENC_ANA_CON1,
5378e8c533bSTzung-Bi Shih 			   0xffff, 0x0000);
5388e8c533bSTzung-Bi Shih 	mt6358_restore_pga(priv);
5398e8c533bSTzung-Bi Shih 	regmap_update_bits(priv->regmap, MT6358_DCXO_CW14, 0xffff, 0xa2b5);
5408e8c533bSTzung-Bi Shih 	regmap_update_bits(priv->regmap, MT6358_AUDDEC_ANA_CON13,
5418e8c533bSTzung-Bi Shih 			   0xffff, 0x0010);
5428e8c533bSTzung-Bi Shih 
5438e8c533bSTzung-Bi Shih 	return 0;
5448e8c533bSTzung-Bi Shih }
5458e8c533bSTzung-Bi Shih 
mt6358_get_wov(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)5468e8c533bSTzung-Bi Shih static int mt6358_get_wov(struct snd_kcontrol *kcontrol,
5478e8c533bSTzung-Bi Shih 			  struct snd_ctl_elem_value *ucontrol)
5488e8c533bSTzung-Bi Shih {
5498e8c533bSTzung-Bi Shih 	struct snd_soc_component *c = snd_soc_kcontrol_component(kcontrol);
5508e8c533bSTzung-Bi Shih 	struct mt6358_priv *priv = snd_soc_component_get_drvdata(c);
5518e8c533bSTzung-Bi Shih 
5528e8c533bSTzung-Bi Shih 	ucontrol->value.integer.value[0] = priv->wov_enabled;
5538e8c533bSTzung-Bi Shih 	return 0;
5548e8c533bSTzung-Bi Shih }
5558e8c533bSTzung-Bi Shih 
mt6358_put_wov(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)5568e8c533bSTzung-Bi Shih static int mt6358_put_wov(struct snd_kcontrol *kcontrol,
5578e8c533bSTzung-Bi Shih 			  struct snd_ctl_elem_value *ucontrol)
5588e8c533bSTzung-Bi Shih {
5598e8c533bSTzung-Bi Shih 	struct snd_soc_component *c = snd_soc_kcontrol_component(kcontrol);
5608e8c533bSTzung-Bi Shih 	struct mt6358_priv *priv = snd_soc_component_get_drvdata(c);
5618e8c533bSTzung-Bi Shih 	int enabled = ucontrol->value.integer.value[0];
5628e8c533bSTzung-Bi Shih 
5638e847a43SMark Brown 	if (enabled < 0 || enabled > 1)
5648e847a43SMark Brown 		return -EINVAL;
5658e847a43SMark Brown 
5668e8c533bSTzung-Bi Shih 	if (priv->wov_enabled != enabled) {
5678e8c533bSTzung-Bi Shih 		if (enabled)
5688e8c533bSTzung-Bi Shih 			mt6358_enable_wov_phase2(priv);
5698e8c533bSTzung-Bi Shih 		else
5708e8c533bSTzung-Bi Shih 			mt6358_disable_wov_phase2(priv);
5718e8c533bSTzung-Bi Shih 
5728e8c533bSTzung-Bi Shih 		priv->wov_enabled = enabled;
5733425ddaeSMark Brown 
5743425ddaeSMark Brown 		return 1;
5758e8c533bSTzung-Bi Shih 	}
5768e8c533bSTzung-Bi Shih 
5778e8c533bSTzung-Bi Shih 	return 0;
5788e8c533bSTzung-Bi Shih }
5798e8c533bSTzung-Bi Shih 
5806a8d4198SShunli Wang static const DECLARE_TLV_DB_SCALE(playback_tlv, -1000, 100, 0);
5816a8d4198SShunli Wang static const DECLARE_TLV_DB_SCALE(pga_tlv, 0, 600, 0);
5826a8d4198SShunli Wang 
5836a8d4198SShunli Wang static const struct snd_kcontrol_new mt6358_snd_controls[] = {
5846a8d4198SShunli Wang 	/* dl pga gain */
585bbb56537STzung-Bi Shih 	SOC_DOUBLE_EXT_TLV("Headphone Volume",
5866a8d4198SShunli Wang 			   MT6358_ZCD_CON2, 0, 7, 0x12, 1,
587bbb56537STzung-Bi Shih 			   snd_soc_get_volsw, mt6358_put_volsw, playback_tlv),
588bbb56537STzung-Bi Shih 	SOC_DOUBLE_EXT_TLV("Lineout Volume",
5896a8d4198SShunli Wang 			   MT6358_ZCD_CON1, 0, 7, 0x12, 1,
590bbb56537STzung-Bi Shih 			   snd_soc_get_volsw, mt6358_put_volsw, playback_tlv),
591bbb56537STzung-Bi Shih 	SOC_SINGLE_EXT_TLV("Handset Volume",
5926a8d4198SShunli Wang 			   MT6358_ZCD_CON3, 0, 0x12, 1,
593bbb56537STzung-Bi Shih 			   snd_soc_get_volsw, mt6358_put_volsw, playback_tlv),
5946a8d4198SShunli Wang 	/* ul pga gain */
595ec0574a6STzung-Bi Shih 	SOC_DOUBLE_R_EXT_TLV("PGA Volume",
5966a8d4198SShunli Wang 			     MT6358_AUDENC_ANA_CON0, MT6358_AUDENC_ANA_CON1,
5976a8d4198SShunli Wang 			     8, 4, 0,
598ec0574a6STzung-Bi Shih 			     snd_soc_get_volsw, mt6358_put_volsw, pga_tlv),
5998e8c533bSTzung-Bi Shih 
6008e8c533bSTzung-Bi Shih 	SOC_SINGLE_BOOL_EXT("Wake-on-Voice Phase2 Switch", 0,
6018e8c533bSTzung-Bi Shih 			    mt6358_get_wov, mt6358_put_wov),
6026a8d4198SShunli Wang };
6036a8d4198SShunli Wang 
6046a8d4198SShunli Wang /* MUX */
6056a8d4198SShunli Wang /* LOL MUX */
6066a8d4198SShunli Wang static const char * const lo_in_mux_map[] = {
6076a8d4198SShunli Wang 	"Open", "Mute", "Playback", "Test Mode"
6086a8d4198SShunli Wang };
6096a8d4198SShunli Wang 
6106a8d4198SShunli Wang static int lo_in_mux_map_value[] = {
6116a8d4198SShunli Wang 	0x0, 0x1, 0x2, 0x3,
6126a8d4198SShunli Wang };
6136a8d4198SShunli Wang 
6146a8d4198SShunli Wang static SOC_VALUE_ENUM_SINGLE_DECL(lo_in_mux_map_enum,
6156a8d4198SShunli Wang 				  MT6358_AUDDEC_ANA_CON7,
6166a8d4198SShunli Wang 				  RG_AUDLOLMUXINPUTSEL_VAUDP15_SFT,
6176a8d4198SShunli Wang 				  RG_AUDLOLMUXINPUTSEL_VAUDP15_MASK,
6186a8d4198SShunli Wang 				  lo_in_mux_map,
6196a8d4198SShunli Wang 				  lo_in_mux_map_value);
6206a8d4198SShunli Wang 
6216a8d4198SShunli Wang static const struct snd_kcontrol_new lo_in_mux_control =
6226a8d4198SShunli Wang 	SOC_DAPM_ENUM("In Select", lo_in_mux_map_enum);
6236a8d4198SShunli Wang 
6246a8d4198SShunli Wang /*HP MUX */
6256a8d4198SShunli Wang enum {
6266a8d4198SShunli Wang 	HP_MUX_OPEN = 0,
6276a8d4198SShunli Wang 	HP_MUX_HPSPK,
6286a8d4198SShunli Wang 	HP_MUX_HP,
6296a8d4198SShunli Wang 	HP_MUX_TEST_MODE,
6306a8d4198SShunli Wang 	HP_MUX_HP_IMPEDANCE,
6316a8d4198SShunli Wang 	HP_MUX_MASK = 0x7,
6326a8d4198SShunli Wang };
6336a8d4198SShunli Wang 
6346a8d4198SShunli Wang static const char * const hp_in_mux_map[] = {
6356a8d4198SShunli Wang 	"Open",
6366a8d4198SShunli Wang 	"LoudSPK Playback",
6376a8d4198SShunli Wang 	"Audio Playback",
6386a8d4198SShunli Wang 	"Test Mode",
6396a8d4198SShunli Wang 	"HP Impedance",
6406a8d4198SShunli Wang };
6416a8d4198SShunli Wang 
6426a8d4198SShunli Wang static int hp_in_mux_map_value[] = {
6436a8d4198SShunli Wang 	HP_MUX_OPEN,
6446a8d4198SShunli Wang 	HP_MUX_HPSPK,
6456a8d4198SShunli Wang 	HP_MUX_HP,
6466a8d4198SShunli Wang 	HP_MUX_TEST_MODE,
6476a8d4198SShunli Wang 	HP_MUX_HP_IMPEDANCE,
6486a8d4198SShunli Wang };
6496a8d4198SShunli Wang 
6506a8d4198SShunli Wang static SOC_VALUE_ENUM_SINGLE_DECL(hpl_in_mux_map_enum,
6516a8d4198SShunli Wang 				  SND_SOC_NOPM,
6526a8d4198SShunli Wang 				  0,
6536a8d4198SShunli Wang 				  HP_MUX_MASK,
6546a8d4198SShunli Wang 				  hp_in_mux_map,
6556a8d4198SShunli Wang 				  hp_in_mux_map_value);
6566a8d4198SShunli Wang 
6576a8d4198SShunli Wang static const struct snd_kcontrol_new hpl_in_mux_control =
6586a8d4198SShunli Wang 	SOC_DAPM_ENUM("HPL Select", hpl_in_mux_map_enum);
6596a8d4198SShunli Wang 
6606a8d4198SShunli Wang static SOC_VALUE_ENUM_SINGLE_DECL(hpr_in_mux_map_enum,
6616a8d4198SShunli Wang 				  SND_SOC_NOPM,
6626a8d4198SShunli Wang 				  0,
6636a8d4198SShunli Wang 				  HP_MUX_MASK,
6646a8d4198SShunli Wang 				  hp_in_mux_map,
6656a8d4198SShunli Wang 				  hp_in_mux_map_value);
6666a8d4198SShunli Wang 
6676a8d4198SShunli Wang static const struct snd_kcontrol_new hpr_in_mux_control =
6686a8d4198SShunli Wang 	SOC_DAPM_ENUM("HPR Select", hpr_in_mux_map_enum);
6696a8d4198SShunli Wang 
6706a8d4198SShunli Wang /* RCV MUX */
6716a8d4198SShunli Wang enum {
6726a8d4198SShunli Wang 	RCV_MUX_OPEN = 0,
6736a8d4198SShunli Wang 	RCV_MUX_MUTE,
6746a8d4198SShunli Wang 	RCV_MUX_VOICE_PLAYBACK,
6756a8d4198SShunli Wang 	RCV_MUX_TEST_MODE,
6766a8d4198SShunli Wang 	RCV_MUX_MASK = 0x3,
6776a8d4198SShunli Wang };
6786a8d4198SShunli Wang 
6796a8d4198SShunli Wang static const char * const rcv_in_mux_map[] = {
6806a8d4198SShunli Wang 	"Open", "Mute", "Voice Playback", "Test Mode"
6816a8d4198SShunli Wang };
6826a8d4198SShunli Wang 
6836a8d4198SShunli Wang static int rcv_in_mux_map_value[] = {
6846a8d4198SShunli Wang 	RCV_MUX_OPEN,
6856a8d4198SShunli Wang 	RCV_MUX_MUTE,
6866a8d4198SShunli Wang 	RCV_MUX_VOICE_PLAYBACK,
6876a8d4198SShunli Wang 	RCV_MUX_TEST_MODE,
6886a8d4198SShunli Wang };
6896a8d4198SShunli Wang 
6906a8d4198SShunli Wang static SOC_VALUE_ENUM_SINGLE_DECL(rcv_in_mux_map_enum,
6916a8d4198SShunli Wang 				  SND_SOC_NOPM,
6926a8d4198SShunli Wang 				  0,
6936a8d4198SShunli Wang 				  RCV_MUX_MASK,
6946a8d4198SShunli Wang 				  rcv_in_mux_map,
6956a8d4198SShunli Wang 				  rcv_in_mux_map_value);
6966a8d4198SShunli Wang 
6976a8d4198SShunli Wang static const struct snd_kcontrol_new rcv_in_mux_control =
6986a8d4198SShunli Wang 	SOC_DAPM_ENUM("RCV Select", rcv_in_mux_map_enum);
6996a8d4198SShunli Wang 
7006a8d4198SShunli Wang /* DAC In MUX */
7016a8d4198SShunli Wang static const char * const dac_in_mux_map[] = {
7026a8d4198SShunli Wang 	"Normal Path", "Sgen"
7036a8d4198SShunli Wang };
7046a8d4198SShunli Wang 
7056a8d4198SShunli Wang static int dac_in_mux_map_value[] = {
7066a8d4198SShunli Wang 	0x0, 0x1,
7076a8d4198SShunli Wang };
7086a8d4198SShunli Wang 
7096a8d4198SShunli Wang static SOC_VALUE_ENUM_SINGLE_DECL(dac_in_mux_map_enum,
7106a8d4198SShunli Wang 				  MT6358_AFE_TOP_CON0,
7116a8d4198SShunli Wang 				  DL_SINE_ON_SFT,
7126a8d4198SShunli Wang 				  DL_SINE_ON_MASK,
7136a8d4198SShunli Wang 				  dac_in_mux_map,
7146a8d4198SShunli Wang 				  dac_in_mux_map_value);
7156a8d4198SShunli Wang 
7166a8d4198SShunli Wang static const struct snd_kcontrol_new dac_in_mux_control =
7176a8d4198SShunli Wang 	SOC_DAPM_ENUM("DAC Select", dac_in_mux_map_enum);
7186a8d4198SShunli Wang 
7196a8d4198SShunli Wang /* AIF Out MUX */
7206a8d4198SShunli Wang static SOC_VALUE_ENUM_SINGLE_DECL(aif_out_mux_map_enum,
7216a8d4198SShunli Wang 				  MT6358_AFE_TOP_CON0,
7226a8d4198SShunli Wang 				  UL_SINE_ON_SFT,
7236a8d4198SShunli Wang 				  UL_SINE_ON_MASK,
7246a8d4198SShunli Wang 				  dac_in_mux_map,
7256a8d4198SShunli Wang 				  dac_in_mux_map_value);
7266a8d4198SShunli Wang 
7276a8d4198SShunli Wang static const struct snd_kcontrol_new aif_out_mux_control =
7286a8d4198SShunli Wang 	SOC_DAPM_ENUM("AIF Out Select", aif_out_mux_map_enum);
7296a8d4198SShunli Wang 
7306a8d4198SShunli Wang /* Mic Type MUX */
7316a8d4198SShunli Wang enum {
7326a8d4198SShunli Wang 	MIC_TYPE_MUX_IDLE = 0,
7336a8d4198SShunli Wang 	MIC_TYPE_MUX_ACC,
7346a8d4198SShunli Wang 	MIC_TYPE_MUX_DMIC,
7356a8d4198SShunli Wang 	MIC_TYPE_MUX_DCC,
7366a8d4198SShunli Wang 	MIC_TYPE_MUX_DCC_ECM_DIFF,
7376a8d4198SShunli Wang 	MIC_TYPE_MUX_DCC_ECM_SINGLE,
7386a8d4198SShunli Wang 	MIC_TYPE_MUX_MASK = 0x7,
7396a8d4198SShunli Wang };
7406a8d4198SShunli Wang 
7416a8d4198SShunli Wang #define IS_DCC_BASE(type) ((type) == MIC_TYPE_MUX_DCC || \
7426a8d4198SShunli Wang 			(type) == MIC_TYPE_MUX_DCC_ECM_DIFF || \
7436a8d4198SShunli Wang 			(type) == MIC_TYPE_MUX_DCC_ECM_SINGLE)
7446a8d4198SShunli Wang 
7456a8d4198SShunli Wang static const char * const mic_type_mux_map[] = {
7466a8d4198SShunli Wang 	"Idle",
7476a8d4198SShunli Wang 	"ACC",
7486a8d4198SShunli Wang 	"DMIC",
7496a8d4198SShunli Wang 	"DCC",
7506a8d4198SShunli Wang 	"DCC_ECM_DIFF",
7516a8d4198SShunli Wang 	"DCC_ECM_SINGLE",
7526a8d4198SShunli Wang };
7536a8d4198SShunli Wang 
7546a8d4198SShunli Wang static int mic_type_mux_map_value[] = {
7556a8d4198SShunli Wang 	MIC_TYPE_MUX_IDLE,
7566a8d4198SShunli Wang 	MIC_TYPE_MUX_ACC,
7576a8d4198SShunli Wang 	MIC_TYPE_MUX_DMIC,
7586a8d4198SShunli Wang 	MIC_TYPE_MUX_DCC,
7596a8d4198SShunli Wang 	MIC_TYPE_MUX_DCC_ECM_DIFF,
7606a8d4198SShunli Wang 	MIC_TYPE_MUX_DCC_ECM_SINGLE,
7616a8d4198SShunli Wang };
7626a8d4198SShunli Wang 
7636a8d4198SShunli Wang static SOC_VALUE_ENUM_SINGLE_DECL(mic_type_mux_map_enum,
7646a8d4198SShunli Wang 				  SND_SOC_NOPM,
7656a8d4198SShunli Wang 				  0,
7666a8d4198SShunli Wang 				  MIC_TYPE_MUX_MASK,
7676a8d4198SShunli Wang 				  mic_type_mux_map,
7686a8d4198SShunli Wang 				  mic_type_mux_map_value);
7696a8d4198SShunli Wang 
7706a8d4198SShunli Wang static const struct snd_kcontrol_new mic_type_mux_control =
7716a8d4198SShunli Wang 	SOC_DAPM_ENUM("Mic Type Select", mic_type_mux_map_enum);
7726a8d4198SShunli Wang 
7736a8d4198SShunli Wang /* ADC L MUX */
7746a8d4198SShunli Wang enum {
7756a8d4198SShunli Wang 	ADC_MUX_IDLE = 0,
7766a8d4198SShunli Wang 	ADC_MUX_AIN0,
7776a8d4198SShunli Wang 	ADC_MUX_PREAMPLIFIER,
7786a8d4198SShunli Wang 	ADC_MUX_IDLE1,
7796a8d4198SShunli Wang 	ADC_MUX_MASK = 0x3,
7806a8d4198SShunli Wang };
7816a8d4198SShunli Wang 
7826a8d4198SShunli Wang static const char * const adc_left_mux_map[] = {
7836a8d4198SShunli Wang 	"Idle", "AIN0", "Left Preamplifier", "Idle_1"
7846a8d4198SShunli Wang };
7856a8d4198SShunli Wang 
7866a8d4198SShunli Wang static int adc_mux_map_value[] = {
7876a8d4198SShunli Wang 	ADC_MUX_IDLE,
7886a8d4198SShunli Wang 	ADC_MUX_AIN0,
7896a8d4198SShunli Wang 	ADC_MUX_PREAMPLIFIER,
7906a8d4198SShunli Wang 	ADC_MUX_IDLE1,
7916a8d4198SShunli Wang };
7926a8d4198SShunli Wang 
7936a8d4198SShunli Wang static SOC_VALUE_ENUM_SINGLE_DECL(adc_left_mux_map_enum,
7946a8d4198SShunli Wang 				  SND_SOC_NOPM,
7956a8d4198SShunli Wang 				  0,
7966a8d4198SShunli Wang 				  ADC_MUX_MASK,
7976a8d4198SShunli Wang 				  adc_left_mux_map,
7986a8d4198SShunli Wang 				  adc_mux_map_value);
7996a8d4198SShunli Wang 
8006a8d4198SShunli Wang static const struct snd_kcontrol_new adc_left_mux_control =
8016a8d4198SShunli Wang 	SOC_DAPM_ENUM("ADC L Select", adc_left_mux_map_enum);
8026a8d4198SShunli Wang 
8036a8d4198SShunli Wang /* ADC R MUX */
8046a8d4198SShunli Wang static const char * const adc_right_mux_map[] = {
8056a8d4198SShunli Wang 	"Idle", "AIN0", "Right Preamplifier", "Idle_1"
8066a8d4198SShunli Wang };
8076a8d4198SShunli Wang 
8086a8d4198SShunli Wang static SOC_VALUE_ENUM_SINGLE_DECL(adc_right_mux_map_enum,
8096a8d4198SShunli Wang 				  SND_SOC_NOPM,
8106a8d4198SShunli Wang 				  0,
8116a8d4198SShunli Wang 				  ADC_MUX_MASK,
8126a8d4198SShunli Wang 				  adc_right_mux_map,
8136a8d4198SShunli Wang 				  adc_mux_map_value);
8146a8d4198SShunli Wang 
8156a8d4198SShunli Wang static const struct snd_kcontrol_new adc_right_mux_control =
8166a8d4198SShunli Wang 	SOC_DAPM_ENUM("ADC R Select", adc_right_mux_map_enum);
8176a8d4198SShunli Wang 
8186a8d4198SShunli Wang /* PGA L MUX */
8196a8d4198SShunli Wang enum {
8206a8d4198SShunli Wang 	PGA_MUX_NONE = 0,
8216a8d4198SShunli Wang 	PGA_MUX_AIN0,
8226a8d4198SShunli Wang 	PGA_MUX_AIN1,
8236a8d4198SShunli Wang 	PGA_MUX_AIN2,
8246a8d4198SShunli Wang 	PGA_MUX_MASK = 0x3,
8256a8d4198SShunli Wang };
8266a8d4198SShunli Wang 
8276a8d4198SShunli Wang static const char * const pga_mux_map[] = {
8286a8d4198SShunli Wang 	"None", "AIN0", "AIN1", "AIN2"
8296a8d4198SShunli Wang };
8306a8d4198SShunli Wang 
8316a8d4198SShunli Wang static int pga_mux_map_value[] = {
8326a8d4198SShunli Wang 	PGA_MUX_NONE,
8336a8d4198SShunli Wang 	PGA_MUX_AIN0,
8346a8d4198SShunli Wang 	PGA_MUX_AIN1,
8356a8d4198SShunli Wang 	PGA_MUX_AIN2,
8366a8d4198SShunli Wang };
8376a8d4198SShunli Wang 
8386a8d4198SShunli Wang static SOC_VALUE_ENUM_SINGLE_DECL(pga_left_mux_map_enum,
8396a8d4198SShunli Wang 				  SND_SOC_NOPM,
8406a8d4198SShunli Wang 				  0,
8416a8d4198SShunli Wang 				  PGA_MUX_MASK,
8426a8d4198SShunli Wang 				  pga_mux_map,
8436a8d4198SShunli Wang 				  pga_mux_map_value);
8446a8d4198SShunli Wang 
8456a8d4198SShunli Wang static const struct snd_kcontrol_new pga_left_mux_control =
8466a8d4198SShunli Wang 	SOC_DAPM_ENUM("PGA L Select", pga_left_mux_map_enum);
8476a8d4198SShunli Wang 
8486a8d4198SShunli Wang /* PGA R MUX */
8496a8d4198SShunli Wang static SOC_VALUE_ENUM_SINGLE_DECL(pga_right_mux_map_enum,
8506a8d4198SShunli Wang 				  SND_SOC_NOPM,
8516a8d4198SShunli Wang 				  0,
8526a8d4198SShunli Wang 				  PGA_MUX_MASK,
8536a8d4198SShunli Wang 				  pga_mux_map,
8546a8d4198SShunli Wang 				  pga_mux_map_value);
8556a8d4198SShunli Wang 
8566a8d4198SShunli Wang static const struct snd_kcontrol_new pga_right_mux_control =
8576a8d4198SShunli Wang 	SOC_DAPM_ENUM("PGA R Select", pga_right_mux_map_enum);
8586a8d4198SShunli Wang 
mt_clksq_event(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)8596a8d4198SShunli Wang static int mt_clksq_event(struct snd_soc_dapm_widget *w,
8606a8d4198SShunli Wang 			  struct snd_kcontrol *kcontrol,
8616a8d4198SShunli Wang 			  int event)
8626a8d4198SShunli Wang {
8636a8d4198SShunli Wang 	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
8646a8d4198SShunli Wang 	struct mt6358_priv *priv = snd_soc_component_get_drvdata(cmpnt);
8656a8d4198SShunli Wang 
8666a8d4198SShunli Wang 	dev_dbg(priv->dev, "%s(), event = 0x%x\n", __func__, event);
8676a8d4198SShunli Wang 
8686a8d4198SShunli Wang 	switch (event) {
8696a8d4198SShunli Wang 	case SND_SOC_DAPM_PRE_PMU:
8706a8d4198SShunli Wang 		/* audio clk source from internal dcxo */
8716a8d4198SShunli Wang 		regmap_update_bits(priv->regmap, MT6358_AUDENC_ANA_CON6,
8726a8d4198SShunli Wang 				   RG_CLKSQ_IN_SEL_TEST_MASK_SFT,
8736a8d4198SShunli Wang 				   0x0);
8746a8d4198SShunli Wang 		break;
8756a8d4198SShunli Wang 	default:
8766a8d4198SShunli Wang 		break;
8776a8d4198SShunli Wang 	}
8786a8d4198SShunli Wang 
8796a8d4198SShunli Wang 	return 0;
8806a8d4198SShunli Wang }
8816a8d4198SShunli Wang 
mt_sgen_event(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)8826a8d4198SShunli Wang static int mt_sgen_event(struct snd_soc_dapm_widget *w,
8836a8d4198SShunli Wang 			 struct snd_kcontrol *kcontrol,
8846a8d4198SShunli Wang 			 int event)
8856a8d4198SShunli Wang {
8866a8d4198SShunli Wang 	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
8876a8d4198SShunli Wang 	struct mt6358_priv *priv = snd_soc_component_get_drvdata(cmpnt);
8886a8d4198SShunli Wang 
8896a8d4198SShunli Wang 	dev_dbg(priv->dev, "%s(), event = 0x%x\n", __func__, event);
8906a8d4198SShunli Wang 
8916a8d4198SShunli Wang 	switch (event) {
8926a8d4198SShunli Wang 	case SND_SOC_DAPM_PRE_PMU:
8936a8d4198SShunli Wang 		/* sdm audio fifo clock power on */
8946a8d4198SShunli Wang 		regmap_write(priv->regmap, MT6358_AFUNC_AUD_CON2, 0x0006);
8956a8d4198SShunli Wang 		/* scrambler clock on enable */
8966a8d4198SShunli Wang 		regmap_write(priv->regmap, MT6358_AFUNC_AUD_CON0, 0xCBA1);
8976a8d4198SShunli Wang 		/* sdm power on */
8986a8d4198SShunli Wang 		regmap_write(priv->regmap, MT6358_AFUNC_AUD_CON2, 0x0003);
8996a8d4198SShunli Wang 		/* sdm fifo enable */
9006a8d4198SShunli Wang 		regmap_write(priv->regmap, MT6358_AFUNC_AUD_CON2, 0x000B);
9016a8d4198SShunli Wang 
9026a8d4198SShunli Wang 		regmap_update_bits(priv->regmap, MT6358_AFE_SGEN_CFG0,
9036a8d4198SShunli Wang 				   0xff3f,
9046a8d4198SShunli Wang 				   0x0000);
9056a8d4198SShunli Wang 		regmap_update_bits(priv->regmap, MT6358_AFE_SGEN_CFG1,
9066a8d4198SShunli Wang 				   0xffff,
9076a8d4198SShunli Wang 				   0x0001);
9086a8d4198SShunli Wang 		break;
9096a8d4198SShunli Wang 	case SND_SOC_DAPM_POST_PMD:
9106a8d4198SShunli Wang 		/* DL scrambler disabling sequence */
9116a8d4198SShunli Wang 		regmap_write(priv->regmap, MT6358_AFUNC_AUD_CON2, 0x0000);
9126a8d4198SShunli Wang 		regmap_write(priv->regmap, MT6358_AFUNC_AUD_CON0, 0xcba0);
9136a8d4198SShunli Wang 		break;
9146a8d4198SShunli Wang 	default:
9156a8d4198SShunli Wang 		break;
9166a8d4198SShunli Wang 	}
9176a8d4198SShunli Wang 
9186a8d4198SShunli Wang 	return 0;
9196a8d4198SShunli Wang }
9206a8d4198SShunli Wang 
mt_aif_in_event(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)9216a8d4198SShunli Wang static int mt_aif_in_event(struct snd_soc_dapm_widget *w,
9226a8d4198SShunli Wang 			   struct snd_kcontrol *kcontrol,
9236a8d4198SShunli Wang 			   int event)
9246a8d4198SShunli Wang {
9256a8d4198SShunli Wang 	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
9266a8d4198SShunli Wang 	struct mt6358_priv *priv = snd_soc_component_get_drvdata(cmpnt);
9276a8d4198SShunli Wang 
9286a8d4198SShunli Wang 	dev_info(priv->dev, "%s(), event 0x%x, rate %d\n",
9296a8d4198SShunli Wang 		 __func__, event, priv->dl_rate);
9306a8d4198SShunli Wang 
9316a8d4198SShunli Wang 	switch (event) {
9326a8d4198SShunli Wang 	case SND_SOC_DAPM_PRE_PMU:
9336a8d4198SShunli Wang 		playback_gpio_set(priv);
9346a8d4198SShunli Wang 
9356a8d4198SShunli Wang 		/* sdm audio fifo clock power on */
9366a8d4198SShunli Wang 		regmap_write(priv->regmap, MT6358_AFUNC_AUD_CON2, 0x0006);
9376a8d4198SShunli Wang 		/* scrambler clock on enable */
9386a8d4198SShunli Wang 		regmap_write(priv->regmap, MT6358_AFUNC_AUD_CON0, 0xCBA1);
9396a8d4198SShunli Wang 		/* sdm power on */
9406a8d4198SShunli Wang 		regmap_write(priv->regmap, MT6358_AFUNC_AUD_CON2, 0x0003);
9416a8d4198SShunli Wang 		/* sdm fifo enable */
9426a8d4198SShunli Wang 		regmap_write(priv->regmap, MT6358_AFUNC_AUD_CON2, 0x000B);
9436a8d4198SShunli Wang 		break;
9446a8d4198SShunli Wang 	case SND_SOC_DAPM_POST_PMD:
9456a8d4198SShunli Wang 		/* DL scrambler disabling sequence */
9466a8d4198SShunli Wang 		regmap_write(priv->regmap, MT6358_AFUNC_AUD_CON2, 0x0000);
9476a8d4198SShunli Wang 		regmap_write(priv->regmap, MT6358_AFUNC_AUD_CON0, 0xcba0);
9486a8d4198SShunli Wang 
9496a8d4198SShunli Wang 		playback_gpio_reset(priv);
9506a8d4198SShunli Wang 		break;
9516a8d4198SShunli Wang 	default:
9526a8d4198SShunli Wang 		break;
9536a8d4198SShunli Wang 	}
9546a8d4198SShunli Wang 
9556a8d4198SShunli Wang 	return 0;
9566a8d4198SShunli Wang }
9576a8d4198SShunli Wang 
mtk_hp_enable(struct mt6358_priv * priv)9586a8d4198SShunli Wang static int mtk_hp_enable(struct mt6358_priv *priv)
9596a8d4198SShunli Wang {
9606a8d4198SShunli Wang 	/* Pull-down HPL/R to AVSS28_AUD */
9616a8d4198SShunli Wang 	hp_pull_down(priv, true);
9626a8d4198SShunli Wang 	/* release HP CMFB gate rstb */
9636a8d4198SShunli Wang 	regmap_update_bits(priv->regmap, MT6358_AUDDEC_ANA_CON4,
9646a8d4198SShunli Wang 			   0x1 << 6, 0x1 << 6);
9656a8d4198SShunli Wang 
9666a8d4198SShunli Wang 	/* Reduce ESD resistance of AU_REFN */
9676a8d4198SShunli Wang 	regmap_write(priv->regmap, MT6358_AUDDEC_ANA_CON2, 0x4000);
9686a8d4198SShunli Wang 
9696a8d4198SShunli Wang 	/* Set HPR/HPL gain as minimum (~ -40dB) */
9706a8d4198SShunli Wang 	regmap_write(priv->regmap, MT6358_ZCD_CON2, DL_GAIN_N_40DB_REG);
9716a8d4198SShunli Wang 
9726a8d4198SShunli Wang 	/* Turn on DA_600K_NCP_VA18 */
9736a8d4198SShunli Wang 	regmap_write(priv->regmap, MT6358_AUDNCP_CLKDIV_CON1, 0x0001);
9746a8d4198SShunli Wang 	/* Set NCP clock as 604kHz // 26MHz/43 = 604KHz */
9756a8d4198SShunli Wang 	regmap_write(priv->regmap, MT6358_AUDNCP_CLKDIV_CON2, 0x002c);
9766a8d4198SShunli Wang 	/* Toggle RG_DIVCKS_CHG */
9776a8d4198SShunli Wang 	regmap_write(priv->regmap, MT6358_AUDNCP_CLKDIV_CON0, 0x0001);
9786a8d4198SShunli Wang 	/* Set NCP soft start mode as default mode: 100us */
9796a8d4198SShunli Wang 	regmap_write(priv->regmap, MT6358_AUDNCP_CLKDIV_CON4, 0x0003);
9806a8d4198SShunli Wang 	/* Enable NCP */
9816a8d4198SShunli Wang 	regmap_write(priv->regmap, MT6358_AUDNCP_CLKDIV_CON3, 0x0000);
9826a8d4198SShunli Wang 	usleep_range(250, 270);
9836a8d4198SShunli Wang 
9846a8d4198SShunli Wang 	/* Enable cap-less LDOs (1.5V) */
9856a8d4198SShunli Wang 	regmap_update_bits(priv->regmap, MT6358_AUDDEC_ANA_CON14,
9866a8d4198SShunli Wang 			   0x1055, 0x1055);
9876a8d4198SShunli Wang 	/* Enable NV regulator (-1.2V) */
9886a8d4198SShunli Wang 	regmap_write(priv->regmap, MT6358_AUDDEC_ANA_CON15, 0x0001);
9896a8d4198SShunli Wang 	usleep_range(100, 120);
9906a8d4198SShunli Wang 
9916a8d4198SShunli Wang 	/* Disable AUD_ZCD */
9926a8d4198SShunli Wang 	hp_zcd_disable(priv);
9936a8d4198SShunli Wang 
9946a8d4198SShunli Wang 	/* Disable headphone short-circuit protection */
9956a8d4198SShunli Wang 	regmap_write(priv->regmap, MT6358_AUDDEC_ANA_CON0, 0x3000);
9966a8d4198SShunli Wang 
9976a8d4198SShunli Wang 	/* Enable IBIST */
9986a8d4198SShunli Wang 	regmap_write(priv->regmap, MT6358_AUDDEC_ANA_CON12, 0x0055);
9996a8d4198SShunli Wang 
10006a8d4198SShunli Wang 	/* Set HP DR bias current optimization, 010: 6uA */
10016a8d4198SShunli Wang 	regmap_write(priv->regmap, MT6358_AUDDEC_ANA_CON11, 0x4900);
10026a8d4198SShunli Wang 	/* Set HP & ZCD bias current optimization */
10036a8d4198SShunli Wang 	/* 01: ZCD: 4uA, HP/HS/LO: 5uA */
10046a8d4198SShunli Wang 	regmap_write(priv->regmap, MT6358_AUDDEC_ANA_CON12, 0x0055);
10056a8d4198SShunli Wang 	/* Set HPP/N STB enhance circuits */
10066a8d4198SShunli Wang 	regmap_write(priv->regmap, MT6358_AUDDEC_ANA_CON2, 0x4033);
10076a8d4198SShunli Wang 
10086a8d4198SShunli Wang 	/* Enable HP aux output stage */
10096a8d4198SShunli Wang 	regmap_write(priv->regmap, MT6358_AUDDEC_ANA_CON1, 0x000c);
10106a8d4198SShunli Wang 	/* Enable HP aux feedback loop */
10116a8d4198SShunli Wang 	regmap_write(priv->regmap, MT6358_AUDDEC_ANA_CON1, 0x003c);
10126a8d4198SShunli Wang 	/* Enable HP aux CMFB loop */
10136a8d4198SShunli Wang 	regmap_write(priv->regmap, MT6358_AUDDEC_ANA_CON9, 0x0c00);
10146a8d4198SShunli Wang 	/* Enable HP driver bias circuits */
10156a8d4198SShunli Wang 	regmap_write(priv->regmap, MT6358_AUDDEC_ANA_CON0, 0x30c0);
10166a8d4198SShunli Wang 	/* Enable HP driver core circuits */
10176a8d4198SShunli Wang 	regmap_write(priv->regmap, MT6358_AUDDEC_ANA_CON0, 0x30f0);
10186a8d4198SShunli Wang 	/* Short HP main output to HP aux output stage */
10196a8d4198SShunli Wang 	regmap_write(priv->regmap, MT6358_AUDDEC_ANA_CON1, 0x00fc);
10206a8d4198SShunli Wang 
10216a8d4198SShunli Wang 	/* Enable HP main CMFB loop */
10226a8d4198SShunli Wang 	regmap_write(priv->regmap, MT6358_AUDDEC_ANA_CON9, 0x0e00);
10236a8d4198SShunli Wang 	/* Disable HP aux CMFB loop */
10246a8d4198SShunli Wang 	regmap_write(priv->regmap, MT6358_AUDDEC_ANA_CON9, 0x0200);
10256a8d4198SShunli Wang 
10266a8d4198SShunli Wang 	/* Select CMFB resistor bulk to AC mode */
10276a8d4198SShunli Wang 	/* Selec HS/LO cap size (6.5pF default) */
10286a8d4198SShunli Wang 	regmap_write(priv->regmap, MT6358_AUDDEC_ANA_CON10, 0x0000);
10296a8d4198SShunli Wang 
10306a8d4198SShunli Wang 	/* Enable HP main output stage */
10316a8d4198SShunli Wang 	regmap_write(priv->regmap, MT6358_AUDDEC_ANA_CON1, 0x00ff);
10326a8d4198SShunli Wang 	/* Enable HPR/L main output stage step by step */
10336a8d4198SShunli Wang 	hp_main_output_ramp(priv, true);
10346a8d4198SShunli Wang 
10356a8d4198SShunli Wang 	/* Reduce HP aux feedback loop gain */
10366a8d4198SShunli Wang 	hp_aux_feedback_loop_gain_ramp(priv, true);
10376a8d4198SShunli Wang 	/* Disable HP aux feedback loop */
10386a8d4198SShunli Wang 	regmap_write(priv->regmap, MT6358_AUDDEC_ANA_CON1, 0x3fcf);
10396a8d4198SShunli Wang 
10406a8d4198SShunli Wang 	/* apply volume setting */
10416a8d4198SShunli Wang 	headset_volume_ramp(priv,
10426a8d4198SShunli Wang 			    DL_GAIN_N_10DB,
10436a8d4198SShunli Wang 			    priv->ana_gain[AUDIO_ANALOG_VOLUME_HPOUTL]);
10446a8d4198SShunli Wang 
10456a8d4198SShunli Wang 	/* Disable HP aux output stage */
10466a8d4198SShunli Wang 	regmap_write(priv->regmap, MT6358_AUDDEC_ANA_CON1, 0x3fc3);
10476a8d4198SShunli Wang 	/* Unshort HP main output to HP aux output stage */
10486a8d4198SShunli Wang 	regmap_write(priv->regmap, MT6358_AUDDEC_ANA_CON1, 0x3f03);
10496a8d4198SShunli Wang 	usleep_range(100, 120);
10506a8d4198SShunli Wang 
10516a8d4198SShunli Wang 	/* Enable AUD_CLK */
10526a8d4198SShunli Wang 	regmap_update_bits(priv->regmap, MT6358_AUDDEC_ANA_CON13, 0x1, 0x1);
10536a8d4198SShunli Wang 	/* Enable Audio DAC  */
10546a8d4198SShunli Wang 	regmap_write(priv->regmap, MT6358_AUDDEC_ANA_CON0, 0x30ff);
10556a8d4198SShunli Wang 	/* Enable low-noise mode of DAC */
10566a8d4198SShunli Wang 	regmap_write(priv->regmap, MT6358_AUDDEC_ANA_CON9, 0xf201);
10576a8d4198SShunli Wang 	usleep_range(100, 120);
10586a8d4198SShunli Wang 
10596a8d4198SShunli Wang 	/* Switch HPL MUX to audio DAC */
10606a8d4198SShunli Wang 	regmap_write(priv->regmap, MT6358_AUDDEC_ANA_CON0, 0x32ff);
10616a8d4198SShunli Wang 	/* Switch HPR MUX to audio DAC */
10626a8d4198SShunli Wang 	regmap_write(priv->regmap, MT6358_AUDDEC_ANA_CON0, 0x3aff);
10636a8d4198SShunli Wang 
10646a8d4198SShunli Wang 	/* Disable Pull-down HPL/R to AVSS28_AUD */
10656a8d4198SShunli Wang 	hp_pull_down(priv, false);
10666a8d4198SShunli Wang 
10676a8d4198SShunli Wang 	return 0;
10686a8d4198SShunli Wang }
10696a8d4198SShunli Wang 
mtk_hp_disable(struct mt6358_priv * priv)10706a8d4198SShunli Wang static int mtk_hp_disable(struct mt6358_priv *priv)
10716a8d4198SShunli Wang {
10726a8d4198SShunli Wang 	/* Pull-down HPL/R to AVSS28_AUD */
10736a8d4198SShunli Wang 	hp_pull_down(priv, true);
10746a8d4198SShunli Wang 
10756a8d4198SShunli Wang 	/* HPR/HPL mux to open */
10766a8d4198SShunli Wang 	regmap_update_bits(priv->regmap, MT6358_AUDDEC_ANA_CON0,
10776a8d4198SShunli Wang 			   0x0f00, 0x0000);
10786a8d4198SShunli Wang 
10796a8d4198SShunli Wang 	/* Disable low-noise mode of DAC */
10806a8d4198SShunli Wang 	regmap_update_bits(priv->regmap, MT6358_AUDDEC_ANA_CON9,
10816a8d4198SShunli Wang 			   0x0001, 0x0000);
10826a8d4198SShunli Wang 
10836a8d4198SShunli Wang 	/* Disable Audio DAC */
10846a8d4198SShunli Wang 	regmap_update_bits(priv->regmap, MT6358_AUDDEC_ANA_CON0,
10856a8d4198SShunli Wang 			   0x000f, 0x0000);
10866a8d4198SShunli Wang 
10876a8d4198SShunli Wang 	/* Disable AUD_CLK */
10886a8d4198SShunli Wang 	regmap_update_bits(priv->regmap, MT6358_AUDDEC_ANA_CON13, 0x1, 0x0);
10896a8d4198SShunli Wang 
10906a8d4198SShunli Wang 	/* Short HP main output to HP aux output stage */
10916a8d4198SShunli Wang 	regmap_write(priv->regmap, MT6358_AUDDEC_ANA_CON1, 0x3fc3);
10926a8d4198SShunli Wang 	/* Enable HP aux output stage */
10936a8d4198SShunli Wang 	regmap_write(priv->regmap, MT6358_AUDDEC_ANA_CON1, 0x3fcf);
10946a8d4198SShunli Wang 
10956a8d4198SShunli Wang 	/* decrease HPL/R gain to normal gain step by step */
10966a8d4198SShunli Wang 	headset_volume_ramp(priv,
10976a8d4198SShunli Wang 			    priv->ana_gain[AUDIO_ANALOG_VOLUME_HPOUTL],
10986a8d4198SShunli Wang 			    DL_GAIN_N_40DB);
10996a8d4198SShunli Wang 
11006a8d4198SShunli Wang 	/* Enable HP aux feedback loop */
11016a8d4198SShunli Wang 	regmap_write(priv->regmap, MT6358_AUDDEC_ANA_CON1, 0x3fff);
11026a8d4198SShunli Wang 
11036a8d4198SShunli Wang 	/* Reduce HP aux feedback loop gain */
11046a8d4198SShunli Wang 	hp_aux_feedback_loop_gain_ramp(priv, false);
11056a8d4198SShunli Wang 
11066a8d4198SShunli Wang 	/* decrease HPR/L main output stage step by step */
11076a8d4198SShunli Wang 	hp_main_output_ramp(priv, false);
11086a8d4198SShunli Wang 
11096a8d4198SShunli Wang 	/* Disable HP main output stage */
11106a8d4198SShunli Wang 	regmap_update_bits(priv->regmap, MT6358_AUDDEC_ANA_CON1, 0x3, 0x0);
11116a8d4198SShunli Wang 
11126a8d4198SShunli Wang 	/* Enable HP aux CMFB loop */
11136a8d4198SShunli Wang 	regmap_write(priv->regmap, MT6358_AUDDEC_ANA_CON9, 0x0e00);
11146a8d4198SShunli Wang 
11156a8d4198SShunli Wang 	/* Disable HP main CMFB loop */
11166a8d4198SShunli Wang 	regmap_write(priv->regmap, MT6358_AUDDEC_ANA_CON9, 0x0c00);
11176a8d4198SShunli Wang 
11186a8d4198SShunli Wang 	/* Unshort HP main output to HP aux output stage */
11196a8d4198SShunli Wang 	regmap_update_bits(priv->regmap, MT6358_AUDDEC_ANA_CON1,
11206a8d4198SShunli Wang 			   0x3 << 6, 0x0);
11216a8d4198SShunli Wang 
11226a8d4198SShunli Wang 	/* Disable HP driver core circuits */
11236a8d4198SShunli Wang 	regmap_update_bits(priv->regmap, MT6358_AUDDEC_ANA_CON0,
11246a8d4198SShunli Wang 			   0x3 << 4, 0x0);
11256a8d4198SShunli Wang 
11266a8d4198SShunli Wang 	/* Disable HP driver bias circuits */
11276a8d4198SShunli Wang 	regmap_update_bits(priv->regmap, MT6358_AUDDEC_ANA_CON0,
11286a8d4198SShunli Wang 			   0x3 << 6, 0x0);
11296a8d4198SShunli Wang 
11306a8d4198SShunli Wang 	/* Disable HP aux CMFB loop */
11316a8d4198SShunli Wang 	regmap_write(priv->regmap, MT6358_AUDDEC_ANA_CON9, 0x0000);
11326a8d4198SShunli Wang 
11336a8d4198SShunli Wang 	/* Disable HP aux feedback loop */
11346a8d4198SShunli Wang 	regmap_update_bits(priv->regmap, MT6358_AUDDEC_ANA_CON1,
11356a8d4198SShunli Wang 			   0x3 << 4, 0x0);
11366a8d4198SShunli Wang 
11376a8d4198SShunli Wang 	/* Disable HP aux output stage */
11386a8d4198SShunli Wang 	regmap_update_bits(priv->regmap, MT6358_AUDDEC_ANA_CON1,
11396a8d4198SShunli Wang 			   0x3 << 2, 0x0);
11406a8d4198SShunli Wang 
11416a8d4198SShunli Wang 	/* Disable IBIST */
11426a8d4198SShunli Wang 	regmap_update_bits(priv->regmap, MT6358_AUDDEC_ANA_CON12,
11436a8d4198SShunli Wang 			   0x1 << 8, 0x1 << 8);
11446a8d4198SShunli Wang 
11456a8d4198SShunli Wang 	/* Disable NV regulator (-1.2V) */
11466a8d4198SShunli Wang 	regmap_update_bits(priv->regmap, MT6358_AUDDEC_ANA_CON15, 0x1, 0x0);
11476a8d4198SShunli Wang 	/* Disable cap-less LDOs (1.5V) */
11486a8d4198SShunli Wang 	regmap_update_bits(priv->regmap, MT6358_AUDDEC_ANA_CON14,
11496a8d4198SShunli Wang 			   0x1055, 0x0);
11506a8d4198SShunli Wang 	/* Disable NCP */
11516a8d4198SShunli Wang 	regmap_update_bits(priv->regmap, MT6358_AUDNCP_CLKDIV_CON3,
11526a8d4198SShunli Wang 			   0x1, 0x1);
11536a8d4198SShunli Wang 
11546a8d4198SShunli Wang 	/* Increase ESD resistance of AU_REFN */
11556a8d4198SShunli Wang 	regmap_update_bits(priv->regmap, MT6358_AUDDEC_ANA_CON2,
11566a8d4198SShunli Wang 			   0x1 << 14, 0x0);
11576a8d4198SShunli Wang 
11586a8d4198SShunli Wang 	/* Set HP CMFB gate rstb */
11596a8d4198SShunli Wang 	regmap_update_bits(priv->regmap, MT6358_AUDDEC_ANA_CON4,
11606a8d4198SShunli Wang 			   0x1 << 6, 0x0);
11616a8d4198SShunli Wang 	/* disable Pull-down HPL/R to AVSS28_AUD */
11626a8d4198SShunli Wang 	hp_pull_down(priv, false);
11636a8d4198SShunli Wang 
11646a8d4198SShunli Wang 	return 0;
11656a8d4198SShunli Wang }
11666a8d4198SShunli Wang 
mtk_hp_spk_enable(struct mt6358_priv * priv)11676a8d4198SShunli Wang static int mtk_hp_spk_enable(struct mt6358_priv *priv)
11686a8d4198SShunli Wang {
11696a8d4198SShunli Wang 	/* Pull-down HPL/R to AVSS28_AUD */
11706a8d4198SShunli Wang 	hp_pull_down(priv, true);
11716a8d4198SShunli Wang 	/* release HP CMFB gate rstb */
11726a8d4198SShunli Wang 	regmap_update_bits(priv->regmap, MT6358_AUDDEC_ANA_CON4,
11736a8d4198SShunli Wang 			   0x1 << 6, 0x1 << 6);
11746a8d4198SShunli Wang 
11756a8d4198SShunli Wang 	/* Reduce ESD resistance of AU_REFN */
11766a8d4198SShunli Wang 	regmap_write(priv->regmap, MT6358_AUDDEC_ANA_CON2, 0x4000);
11776a8d4198SShunli Wang 
11786a8d4198SShunli Wang 	/* Set HPR/HPL gain to -10dB */
11796a8d4198SShunli Wang 	regmap_write(priv->regmap, MT6358_ZCD_CON2, DL_GAIN_N_10DB_REG);
11806a8d4198SShunli Wang 
11816a8d4198SShunli Wang 	/* Turn on DA_600K_NCP_VA18 */
11826a8d4198SShunli Wang 	regmap_write(priv->regmap, MT6358_AUDNCP_CLKDIV_CON1, 0x0001);
11836a8d4198SShunli Wang 	/* Set NCP clock as 604kHz // 26MHz/43 = 604KHz */
11846a8d4198SShunli Wang 	regmap_write(priv->regmap, MT6358_AUDNCP_CLKDIV_CON2, 0x002c);
11856a8d4198SShunli Wang 	/* Toggle RG_DIVCKS_CHG */
11866a8d4198SShunli Wang 	regmap_write(priv->regmap, MT6358_AUDNCP_CLKDIV_CON0, 0x0001);
11876a8d4198SShunli Wang 	/* Set NCP soft start mode as default mode: 100us */
11886a8d4198SShunli Wang 	regmap_write(priv->regmap, MT6358_AUDNCP_CLKDIV_CON4, 0x0003);
11896a8d4198SShunli Wang 	/* Enable NCP */
11906a8d4198SShunli Wang 	regmap_write(priv->regmap, MT6358_AUDNCP_CLKDIV_CON3, 0x0000);
11916a8d4198SShunli Wang 	usleep_range(250, 270);
11926a8d4198SShunli Wang 
11936a8d4198SShunli Wang 	/* Enable cap-less LDOs (1.5V) */
11946a8d4198SShunli Wang 	regmap_update_bits(priv->regmap, MT6358_AUDDEC_ANA_CON14,
11956a8d4198SShunli Wang 			   0x1055, 0x1055);
11966a8d4198SShunli Wang 	/* Enable NV regulator (-1.2V) */
11976a8d4198SShunli Wang 	regmap_write(priv->regmap, MT6358_AUDDEC_ANA_CON15, 0x0001);
11986a8d4198SShunli Wang 	usleep_range(100, 120);
11996a8d4198SShunli Wang 
12006a8d4198SShunli Wang 	/* Disable AUD_ZCD */
12016a8d4198SShunli Wang 	hp_zcd_disable(priv);
12026a8d4198SShunli Wang 
12036a8d4198SShunli Wang 	/* Disable headphone short-circuit protection */
12046a8d4198SShunli Wang 	regmap_write(priv->regmap, MT6358_AUDDEC_ANA_CON0, 0x3000);
12056a8d4198SShunli Wang 
12066a8d4198SShunli Wang 	/* Enable IBIST */
12076a8d4198SShunli Wang 	regmap_write(priv->regmap, MT6358_AUDDEC_ANA_CON12, 0x0055);
12086a8d4198SShunli Wang 
12096a8d4198SShunli Wang 	/* Set HP DR bias current optimization, 010: 6uA */
12106a8d4198SShunli Wang 	regmap_write(priv->regmap, MT6358_AUDDEC_ANA_CON11, 0x4900);
12116a8d4198SShunli Wang 	/* Set HP & ZCD bias current optimization */
12126a8d4198SShunli Wang 	/* 01: ZCD: 4uA, HP/HS/LO: 5uA */
12136a8d4198SShunli Wang 	regmap_write(priv->regmap, MT6358_AUDDEC_ANA_CON12, 0x0055);
12146a8d4198SShunli Wang 	/* Set HPP/N STB enhance circuits */
12156a8d4198SShunli Wang 	regmap_write(priv->regmap, MT6358_AUDDEC_ANA_CON2, 0x4033);
12166a8d4198SShunli Wang 
12176a8d4198SShunli Wang 	/* Disable Pull-down HPL/R to AVSS28_AUD */
12186a8d4198SShunli Wang 	hp_pull_down(priv, false);
12196a8d4198SShunli Wang 
12206a8d4198SShunli Wang 	/* Enable HP driver bias circuits */
12216a8d4198SShunli Wang 	regmap_write(priv->regmap, MT6358_AUDDEC_ANA_CON0, 0x30c0);
12226a8d4198SShunli Wang 	/* Enable HP driver core circuits */
12236a8d4198SShunli Wang 	regmap_write(priv->regmap, MT6358_AUDDEC_ANA_CON0, 0x30f0);
12246a8d4198SShunli Wang 	/* Enable HP main CMFB loop */
12256a8d4198SShunli Wang 	regmap_write(priv->regmap, MT6358_AUDDEC_ANA_CON9, 0x0200);
12266a8d4198SShunli Wang 
12276a8d4198SShunli Wang 	/* Select CMFB resistor bulk to AC mode */
12286a8d4198SShunli Wang 	/* Selec HS/LO cap size (6.5pF default) */
12296a8d4198SShunli Wang 	regmap_write(priv->regmap, MT6358_AUDDEC_ANA_CON10, 0x0000);
12306a8d4198SShunli Wang 
12316a8d4198SShunli Wang 	/* Enable HP main output stage */
12326a8d4198SShunli Wang 	regmap_write(priv->regmap, MT6358_AUDDEC_ANA_CON1, 0x0003);
12336a8d4198SShunli Wang 	/* Enable HPR/L main output stage step by step */
12346a8d4198SShunli Wang 	hp_main_output_ramp(priv, true);
12356a8d4198SShunli Wang 
12366a8d4198SShunli Wang 	/* Set LO gain as minimum (~ -40dB) */
12376a8d4198SShunli Wang 	regmap_write(priv->regmap, MT6358_ZCD_CON1, DL_GAIN_N_40DB_REG);
12386a8d4198SShunli Wang 	/* apply volume setting */
12396a8d4198SShunli Wang 	headset_volume_ramp(priv,
12406a8d4198SShunli Wang 			    DL_GAIN_N_10DB,
12416a8d4198SShunli Wang 			    priv->ana_gain[AUDIO_ANALOG_VOLUME_HPOUTL]);
12426a8d4198SShunli Wang 
12436a8d4198SShunli Wang 	/* Set LO STB enhance circuits */
12446a8d4198SShunli Wang 	regmap_write(priv->regmap, MT6358_AUDDEC_ANA_CON7, 0x0110);
12456a8d4198SShunli Wang 	/* Enable LO driver bias circuits */
12466a8d4198SShunli Wang 	regmap_write(priv->regmap, MT6358_AUDDEC_ANA_CON7, 0x0112);
12476a8d4198SShunli Wang 	/* Enable LO driver core circuits */
12486a8d4198SShunli Wang 	regmap_write(priv->regmap, MT6358_AUDDEC_ANA_CON7, 0x0113);
12496a8d4198SShunli Wang 
12506a8d4198SShunli Wang 	/* Set LOL gain to normal gain step by step */
12516a8d4198SShunli Wang 	regmap_update_bits(priv->regmap, MT6358_ZCD_CON1,
12526a8d4198SShunli Wang 			   RG_AUDLOLGAIN_MASK_SFT,
12536a8d4198SShunli Wang 			   priv->ana_gain[AUDIO_ANALOG_VOLUME_LINEOUTL] <<
12546a8d4198SShunli Wang 			   RG_AUDLOLGAIN_SFT);
12556a8d4198SShunli Wang 	regmap_update_bits(priv->regmap, MT6358_ZCD_CON1,
12566a8d4198SShunli Wang 			   RG_AUDLORGAIN_MASK_SFT,
12576a8d4198SShunli Wang 			   priv->ana_gain[AUDIO_ANALOG_VOLUME_LINEOUTR] <<
12586a8d4198SShunli Wang 			   RG_AUDLORGAIN_SFT);
12596a8d4198SShunli Wang 
12606a8d4198SShunli Wang 	/* Enable AUD_CLK */
12616a8d4198SShunli Wang 	regmap_update_bits(priv->regmap, MT6358_AUDDEC_ANA_CON13, 0x1, 0x1);
12626a8d4198SShunli Wang 	/* Enable Audio DAC  */
12636a8d4198SShunli Wang 	regmap_write(priv->regmap, MT6358_AUDDEC_ANA_CON0, 0x30f9);
12646a8d4198SShunli Wang 	/* Enable low-noise mode of DAC */
12656a8d4198SShunli Wang 	regmap_write(priv->regmap, MT6358_AUDDEC_ANA_CON9, 0x0201);
12666a8d4198SShunli Wang 	/* Switch LOL MUX to audio DAC */
12676a8d4198SShunli Wang 	regmap_write(priv->regmap, MT6358_AUDDEC_ANA_CON7, 0x011b);
12686a8d4198SShunli Wang 	/* Switch HPL/R MUX to Line-out */
12696a8d4198SShunli Wang 	regmap_write(priv->regmap, MT6358_AUDDEC_ANA_CON0, 0x35f9);
12706a8d4198SShunli Wang 
12716a8d4198SShunli Wang 	return 0;
12726a8d4198SShunli Wang }
12736a8d4198SShunli Wang 
mtk_hp_spk_disable(struct mt6358_priv * priv)12746a8d4198SShunli Wang static int mtk_hp_spk_disable(struct mt6358_priv *priv)
12756a8d4198SShunli Wang {
12766a8d4198SShunli Wang 	/* HPR/HPL mux to open */
12776a8d4198SShunli Wang 	regmap_update_bits(priv->regmap, MT6358_AUDDEC_ANA_CON0,
12786a8d4198SShunli Wang 			   0x0f00, 0x0000);
12796a8d4198SShunli Wang 	/* LOL mux to open */
12806a8d4198SShunli Wang 	regmap_update_bits(priv->regmap, MT6358_AUDDEC_ANA_CON7,
12816a8d4198SShunli Wang 			   0x3 << 2, 0x0000);
12826a8d4198SShunli Wang 
12836a8d4198SShunli Wang 	/* Disable Audio DAC */
12846a8d4198SShunli Wang 	regmap_update_bits(priv->regmap, MT6358_AUDDEC_ANA_CON0,
12856a8d4198SShunli Wang 			   0x000f, 0x0000);
12866a8d4198SShunli Wang 
12876a8d4198SShunli Wang 	/* Disable AUD_CLK */
12886a8d4198SShunli Wang 	regmap_update_bits(priv->regmap, MT6358_AUDDEC_ANA_CON13, 0x1, 0x0);
12896a8d4198SShunli Wang 
12906a8d4198SShunli Wang 	/* decrease HPL/R gain to normal gain step by step */
12916a8d4198SShunli Wang 	headset_volume_ramp(priv,
12926a8d4198SShunli Wang 			    priv->ana_gain[AUDIO_ANALOG_VOLUME_HPOUTL],
12936a8d4198SShunli Wang 			    DL_GAIN_N_40DB);
12946a8d4198SShunli Wang 
12956a8d4198SShunli Wang 	/* decrease LOL gain to minimum gain step by step */
12966a8d4198SShunli Wang 	regmap_update_bits(priv->regmap, MT6358_ZCD_CON1,
12976a8d4198SShunli Wang 			   DL_GAIN_REG_MASK, DL_GAIN_N_40DB_REG);
12986a8d4198SShunli Wang 
12996a8d4198SShunli Wang 	/* decrease HPR/L main output stage step by step */
13006a8d4198SShunli Wang 	hp_main_output_ramp(priv, false);
13016a8d4198SShunli Wang 
13026a8d4198SShunli Wang 	/* Disable HP main output stage */
13036a8d4198SShunli Wang 	regmap_update_bits(priv->regmap, MT6358_AUDDEC_ANA_CON1, 0x3, 0x0);
13046a8d4198SShunli Wang 
13056a8d4198SShunli Wang 	/* Short HP main output to HP aux output stage */
13066a8d4198SShunli Wang 	regmap_write(priv->regmap, MT6358_AUDDEC_ANA_CON1, 0x3fc3);
13076a8d4198SShunli Wang 	/* Enable HP aux output stage */
13086a8d4198SShunli Wang 	regmap_write(priv->regmap, MT6358_AUDDEC_ANA_CON1, 0x3fcf);
13096a8d4198SShunli Wang 
13106a8d4198SShunli Wang 	/* Enable HP aux feedback loop */
13116a8d4198SShunli Wang 	regmap_write(priv->regmap, MT6358_AUDDEC_ANA_CON1, 0x3fff);
13126a8d4198SShunli Wang 
13136a8d4198SShunli Wang 	/* Reduce HP aux feedback loop gain */
13146a8d4198SShunli Wang 	hp_aux_feedback_loop_gain_ramp(priv, false);
13156a8d4198SShunli Wang 
13166a8d4198SShunli Wang 	/* Disable HP driver core circuits */
13176a8d4198SShunli Wang 	regmap_update_bits(priv->regmap, MT6358_AUDDEC_ANA_CON0,
13186a8d4198SShunli Wang 			   0x3 << 4, 0x0);
13196a8d4198SShunli Wang 	/* Disable LO driver core circuits */
13206a8d4198SShunli Wang 	regmap_update_bits(priv->regmap, MT6358_AUDDEC_ANA_CON7,
13216a8d4198SShunli Wang 			   0x1, 0x0);
13226a8d4198SShunli Wang 
13236a8d4198SShunli Wang 	/* Disable HP driver bias circuits */
13246a8d4198SShunli Wang 	regmap_update_bits(priv->regmap, MT6358_AUDDEC_ANA_CON0,
13256a8d4198SShunli Wang 			   0x3 << 6, 0x0);
13266a8d4198SShunli Wang 	/* Disable LO driver bias circuits */
13276a8d4198SShunli Wang 	regmap_update_bits(priv->regmap, MT6358_AUDDEC_ANA_CON7,
13286a8d4198SShunli Wang 			   0x1 << 1, 0x0);
13296a8d4198SShunli Wang 
13306a8d4198SShunli Wang 	/* Disable HP aux CMFB loop */
13316a8d4198SShunli Wang 	regmap_update_bits(priv->regmap, MT6358_AUDDEC_ANA_CON9,
13326a8d4198SShunli Wang 			   0xff << 8, 0x0000);
13336a8d4198SShunli Wang 
13346a8d4198SShunli Wang 	/* Disable IBIST */
13356a8d4198SShunli Wang 	regmap_update_bits(priv->regmap, MT6358_AUDDEC_ANA_CON12,
13366a8d4198SShunli Wang 			   0x1 << 8, 0x1 << 8);
13376a8d4198SShunli Wang 	/* Disable NV regulator (-1.2V) */
13386a8d4198SShunli Wang 	regmap_update_bits(priv->regmap, MT6358_AUDDEC_ANA_CON15, 0x1, 0x0);
13396a8d4198SShunli Wang 	/* Disable cap-less LDOs (1.5V) */
13406a8d4198SShunli Wang 	regmap_update_bits(priv->regmap, MT6358_AUDDEC_ANA_CON14, 0x1055, 0x0);
13416a8d4198SShunli Wang 	/* Disable NCP */
13426a8d4198SShunli Wang 	regmap_update_bits(priv->regmap, MT6358_AUDNCP_CLKDIV_CON3, 0x1, 0x1);
13436a8d4198SShunli Wang 
13446a8d4198SShunli Wang 	/* Set HP CMFB gate rstb */
13456a8d4198SShunli Wang 	regmap_update_bits(priv->regmap, MT6358_AUDDEC_ANA_CON4,
13466a8d4198SShunli Wang 			   0x1 << 6, 0x0);
13476a8d4198SShunli Wang 	/* disable Pull-down HPL/R to AVSS28_AUD */
13486a8d4198SShunli Wang 	hp_pull_down(priv, false);
13496a8d4198SShunli Wang 
13506a8d4198SShunli Wang 	return 0;
13516a8d4198SShunli Wang }
13526a8d4198SShunli Wang 
mt_hp_event(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)13536a8d4198SShunli Wang static int mt_hp_event(struct snd_soc_dapm_widget *w,
13546a8d4198SShunli Wang 		       struct snd_kcontrol *kcontrol,
13556a8d4198SShunli Wang 		       int event)
13566a8d4198SShunli Wang {
13576a8d4198SShunli Wang 	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
13586a8d4198SShunli Wang 	struct mt6358_priv *priv = snd_soc_component_get_drvdata(cmpnt);
13596a8d4198SShunli Wang 	unsigned int mux = dapm_kcontrol_get_value(w->kcontrols[0]);
13606a8d4198SShunli Wang 	int device = DEVICE_HP;
13616a8d4198SShunli Wang 
13626a8d4198SShunli Wang 	dev_info(priv->dev, "%s(), event 0x%x, dev_counter[DEV_HP] %d, mux %u\n",
13636a8d4198SShunli Wang 		 __func__,
13646a8d4198SShunli Wang 		 event,
13656a8d4198SShunli Wang 		 priv->dev_counter[device],
13666a8d4198SShunli Wang 		 mux);
13676a8d4198SShunli Wang 
13686a8d4198SShunli Wang 	switch (event) {
13696a8d4198SShunli Wang 	case SND_SOC_DAPM_PRE_PMU:
13706a8d4198SShunli Wang 		priv->dev_counter[device]++;
13716a8d4198SShunli Wang 		if (priv->dev_counter[device] > 1)
13726a8d4198SShunli Wang 			break;	/* already enabled, do nothing */
13736a8d4198SShunli Wang 		else if (priv->dev_counter[device] <= 0)
13746a8d4198SShunli Wang 			dev_warn(priv->dev, "%s(), dev_counter[DEV_HP] %d <= 0\n",
13756a8d4198SShunli Wang 				 __func__,
13766a8d4198SShunli Wang 				 priv->dev_counter[device]);
13776a8d4198SShunli Wang 
13786a8d4198SShunli Wang 		priv->mux_select[MUX_HP_L] = mux;
13796a8d4198SShunli Wang 
13806a8d4198SShunli Wang 		if (mux == HP_MUX_HP)
13816a8d4198SShunli Wang 			mtk_hp_enable(priv);
13826a8d4198SShunli Wang 		else if (mux == HP_MUX_HPSPK)
13836a8d4198SShunli Wang 			mtk_hp_spk_enable(priv);
13846a8d4198SShunli Wang 		break;
13856a8d4198SShunli Wang 	case SND_SOC_DAPM_PRE_PMD:
13866a8d4198SShunli Wang 		priv->dev_counter[device]--;
13876a8d4198SShunli Wang 		if (priv->dev_counter[device] > 0) {
13886a8d4198SShunli Wang 			break;	/* still being used, don't close */
13896a8d4198SShunli Wang 		} else if (priv->dev_counter[device] < 0) {
13906a8d4198SShunli Wang 			dev_warn(priv->dev, "%s(), dev_counter[DEV_HP] %d < 0\n",
13916a8d4198SShunli Wang 				 __func__,
13926a8d4198SShunli Wang 				 priv->dev_counter[device]);
13936a8d4198SShunli Wang 			priv->dev_counter[device] = 0;
13946a8d4198SShunli Wang 			break;
13956a8d4198SShunli Wang 		}
13966a8d4198SShunli Wang 
13976a8d4198SShunli Wang 		if (priv->mux_select[MUX_HP_L] == HP_MUX_HP)
13986a8d4198SShunli Wang 			mtk_hp_disable(priv);
13996a8d4198SShunli Wang 		else if (priv->mux_select[MUX_HP_L] == HP_MUX_HPSPK)
14006a8d4198SShunli Wang 			mtk_hp_spk_disable(priv);
14016a8d4198SShunli Wang 
14026a8d4198SShunli Wang 		priv->mux_select[MUX_HP_L] = mux;
14036a8d4198SShunli Wang 		break;
14046a8d4198SShunli Wang 	default:
14056a8d4198SShunli Wang 		break;
14066a8d4198SShunli Wang 	}
14076a8d4198SShunli Wang 
14086a8d4198SShunli Wang 	return 0;
14096a8d4198SShunli Wang }
14106a8d4198SShunli Wang 
mt_rcv_event(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)14116a8d4198SShunli Wang static int mt_rcv_event(struct snd_soc_dapm_widget *w,
14126a8d4198SShunli Wang 			struct snd_kcontrol *kcontrol,
14136a8d4198SShunli Wang 			int event)
14146a8d4198SShunli Wang {
14156a8d4198SShunli Wang 	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
14166a8d4198SShunli Wang 	struct mt6358_priv *priv = snd_soc_component_get_drvdata(cmpnt);
14176a8d4198SShunli Wang 
14186a8d4198SShunli Wang 	dev_info(priv->dev, "%s(), event 0x%x, mux %u\n",
14196a8d4198SShunli Wang 		 __func__,
14206a8d4198SShunli Wang 		 event,
14216a8d4198SShunli Wang 		 dapm_kcontrol_get_value(w->kcontrols[0]));
14226a8d4198SShunli Wang 
14236a8d4198SShunli Wang 	switch (event) {
14246a8d4198SShunli Wang 	case SND_SOC_DAPM_PRE_PMU:
14256a8d4198SShunli Wang 		/* Reduce ESD resistance of AU_REFN */
14266a8d4198SShunli Wang 		regmap_write(priv->regmap, MT6358_AUDDEC_ANA_CON2, 0x4000);
14276a8d4198SShunli Wang 
14286a8d4198SShunli Wang 		/* Turn on DA_600K_NCP_VA18 */
14296a8d4198SShunli Wang 		regmap_write(priv->regmap, MT6358_AUDNCP_CLKDIV_CON1, 0x0001);
14306a8d4198SShunli Wang 		/* Set NCP clock as 604kHz // 26MHz/43 = 604KHz */
14316a8d4198SShunli Wang 		regmap_write(priv->regmap, MT6358_AUDNCP_CLKDIV_CON2, 0x002c);
14326a8d4198SShunli Wang 		/* Toggle RG_DIVCKS_CHG */
14336a8d4198SShunli Wang 		regmap_write(priv->regmap, MT6358_AUDNCP_CLKDIV_CON0, 0x0001);
14346a8d4198SShunli Wang 		/* Set NCP soft start mode as default mode: 100us */
14356a8d4198SShunli Wang 		regmap_write(priv->regmap, MT6358_AUDNCP_CLKDIV_CON4, 0x0003);
14366a8d4198SShunli Wang 		/* Enable NCP */
14376a8d4198SShunli Wang 		regmap_write(priv->regmap, MT6358_AUDNCP_CLKDIV_CON3, 0x0000);
14386a8d4198SShunli Wang 		usleep_range(250, 270);
14396a8d4198SShunli Wang 
14406a8d4198SShunli Wang 		/* Enable cap-less LDOs (1.5V) */
14416a8d4198SShunli Wang 		regmap_update_bits(priv->regmap, MT6358_AUDDEC_ANA_CON14,
14426a8d4198SShunli Wang 				   0x1055, 0x1055);
14436a8d4198SShunli Wang 		/* Enable NV regulator (-1.2V) */
14446a8d4198SShunli Wang 		regmap_write(priv->regmap, MT6358_AUDDEC_ANA_CON15, 0x0001);
14456a8d4198SShunli Wang 		usleep_range(100, 120);
14466a8d4198SShunli Wang 
14476a8d4198SShunli Wang 		/* Disable AUD_ZCD */
14486a8d4198SShunli Wang 		hp_zcd_disable(priv);
14496a8d4198SShunli Wang 
14506a8d4198SShunli Wang 		/* Disable handset short-circuit protection */
14516a8d4198SShunli Wang 		regmap_write(priv->regmap, MT6358_AUDDEC_ANA_CON6, 0x0010);
14526a8d4198SShunli Wang 
14536a8d4198SShunli Wang 		/* Enable IBIST */
14546a8d4198SShunli Wang 		regmap_write(priv->regmap, MT6358_AUDDEC_ANA_CON12, 0x0055);
14556a8d4198SShunli Wang 		/* Set HP DR bias current optimization, 010: 6uA */
14566a8d4198SShunli Wang 		regmap_write(priv->regmap, MT6358_AUDDEC_ANA_CON11, 0x4900);
14576a8d4198SShunli Wang 		/* Set HP & ZCD bias current optimization */
14586a8d4198SShunli Wang 		/* 01: ZCD: 4uA, HP/HS/LO: 5uA */
14596a8d4198SShunli Wang 		regmap_write(priv->regmap, MT6358_AUDDEC_ANA_CON12, 0x0055);
14606a8d4198SShunli Wang 		/* Set HS STB enhance circuits */
14616a8d4198SShunli Wang 		regmap_write(priv->regmap, MT6358_AUDDEC_ANA_CON6, 0x0090);
14626a8d4198SShunli Wang 
14636a8d4198SShunli Wang 		/* Disable HP main CMFB loop */
14646a8d4198SShunli Wang 		regmap_write(priv->regmap, MT6358_AUDDEC_ANA_CON9, 0x0000);
14656a8d4198SShunli Wang 		/* Select CMFB resistor bulk to AC mode */
14666a8d4198SShunli Wang 		/* Selec HS/LO cap size (6.5pF default) */
14676a8d4198SShunli Wang 		regmap_write(priv->regmap, MT6358_AUDDEC_ANA_CON10, 0x0000);
14686a8d4198SShunli Wang 
14696a8d4198SShunli Wang 		/* Enable HS driver bias circuits */
14706a8d4198SShunli Wang 		regmap_write(priv->regmap, MT6358_AUDDEC_ANA_CON6, 0x0092);
14716a8d4198SShunli Wang 		/* Enable HS driver core circuits */
14726a8d4198SShunli Wang 		regmap_write(priv->regmap, MT6358_AUDDEC_ANA_CON6, 0x0093);
14736a8d4198SShunli Wang 
14746a8d4198SShunli Wang 		/* Enable AUD_CLK */
14756a8d4198SShunli Wang 		regmap_update_bits(priv->regmap, MT6358_AUDDEC_ANA_CON13,
14766a8d4198SShunli Wang 				   0x1, 0x1);
14776a8d4198SShunli Wang 
14786a8d4198SShunli Wang 		/* Enable Audio DAC  */
14796a8d4198SShunli Wang 		regmap_write(priv->regmap, MT6358_AUDDEC_ANA_CON0, 0x0009);
14806a8d4198SShunli Wang 		/* Enable low-noise mode of DAC */
14816a8d4198SShunli Wang 		regmap_write(priv->regmap, MT6358_AUDDEC_ANA_CON9, 0x0001);
14826a8d4198SShunli Wang 		/* Switch HS MUX to audio DAC */
14836a8d4198SShunli Wang 		regmap_write(priv->regmap, MT6358_AUDDEC_ANA_CON6, 0x009b);
14846a8d4198SShunli Wang 		break;
14856a8d4198SShunli Wang 	case SND_SOC_DAPM_PRE_PMD:
14866a8d4198SShunli Wang 		/* HS mux to open */
14876a8d4198SShunli Wang 		regmap_update_bits(priv->regmap, MT6358_AUDDEC_ANA_CON6,
14886a8d4198SShunli Wang 				   RG_AUDHSMUXINPUTSEL_VAUDP15_MASK_SFT,
14896a8d4198SShunli Wang 				   RCV_MUX_OPEN);
14906a8d4198SShunli Wang 
14916a8d4198SShunli Wang 		/* Disable Audio DAC */
14926a8d4198SShunli Wang 		regmap_update_bits(priv->regmap, MT6358_AUDDEC_ANA_CON0,
14936a8d4198SShunli Wang 				   0x000f, 0x0000);
14946a8d4198SShunli Wang 
14956a8d4198SShunli Wang 		/* Disable AUD_CLK */
14966a8d4198SShunli Wang 		regmap_update_bits(priv->regmap, MT6358_AUDDEC_ANA_CON13,
14976a8d4198SShunli Wang 				   0x1, 0x0);
14986a8d4198SShunli Wang 
14996a8d4198SShunli Wang 		/* decrease HS gain to minimum gain step by step */
15006a8d4198SShunli Wang 		regmap_write(priv->regmap, MT6358_ZCD_CON3, DL_GAIN_N_40DB);
15016a8d4198SShunli Wang 
15026a8d4198SShunli Wang 		/* Disable HS driver core circuits */
15036a8d4198SShunli Wang 		regmap_update_bits(priv->regmap, MT6358_AUDDEC_ANA_CON6,
15046a8d4198SShunli Wang 				   0x1, 0x0);
15056a8d4198SShunli Wang 
15066a8d4198SShunli Wang 		/* Disable HS driver bias circuits */
15076a8d4198SShunli Wang 		regmap_update_bits(priv->regmap, MT6358_AUDDEC_ANA_CON6,
15086a8d4198SShunli Wang 				   0x1 << 1, 0x0000);
15096a8d4198SShunli Wang 
15106a8d4198SShunli Wang 		/* Disable HP aux CMFB loop */
15116a8d4198SShunli Wang 		regmap_update_bits(priv->regmap, MT6358_AUDDEC_ANA_CON9,
15126a8d4198SShunli Wang 				   0xff << 8, 0x0);
15136a8d4198SShunli Wang 
15146a8d4198SShunli Wang 		/* Enable HP main CMFB Switch */
15156a8d4198SShunli Wang 		regmap_update_bits(priv->regmap, MT6358_AUDDEC_ANA_CON9,
15166a8d4198SShunli Wang 				   0xff << 8, 0x2 << 8);
15176a8d4198SShunli Wang 
15186a8d4198SShunli Wang 		/* Disable IBIST */
15196a8d4198SShunli Wang 		regmap_update_bits(priv->regmap, MT6358_AUDDEC_ANA_CON12,
15206a8d4198SShunli Wang 				   0x1 << 8, 0x1 << 8);
15216a8d4198SShunli Wang 
15226a8d4198SShunli Wang 		/* Disable NV regulator (-1.2V) */
15236a8d4198SShunli Wang 		regmap_update_bits(priv->regmap, MT6358_AUDDEC_ANA_CON15,
15246a8d4198SShunli Wang 				   0x1, 0x0);
15256a8d4198SShunli Wang 		/* Disable cap-less LDOs (1.5V) */
15266a8d4198SShunli Wang 		regmap_update_bits(priv->regmap, MT6358_AUDDEC_ANA_CON14,
15276a8d4198SShunli Wang 				   0x1055, 0x0);
15286a8d4198SShunli Wang 		/* Disable NCP */
15296a8d4198SShunli Wang 		regmap_update_bits(priv->regmap, MT6358_AUDNCP_CLKDIV_CON3,
15306a8d4198SShunli Wang 				   0x1, 0x1);
15316a8d4198SShunli Wang 		break;
15326a8d4198SShunli Wang 	default:
15336a8d4198SShunli Wang 		break;
15346a8d4198SShunli Wang 	}
15356a8d4198SShunli Wang 
15366a8d4198SShunli Wang 	return 0;
15376a8d4198SShunli Wang }
15386a8d4198SShunli Wang 
mt_aif_out_event(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)15396a8d4198SShunli Wang static int mt_aif_out_event(struct snd_soc_dapm_widget *w,
15406a8d4198SShunli Wang 			    struct snd_kcontrol *kcontrol,
15416a8d4198SShunli Wang 			    int event)
15426a8d4198SShunli Wang {
15436a8d4198SShunli Wang 	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
15446a8d4198SShunli Wang 	struct mt6358_priv *priv = snd_soc_component_get_drvdata(cmpnt);
15456a8d4198SShunli Wang 
15466a8d4198SShunli Wang 	dev_dbg(priv->dev, "%s(), event 0x%x, rate %d\n",
15476a8d4198SShunli Wang 		__func__, event, priv->ul_rate);
15486a8d4198SShunli Wang 
15496a8d4198SShunli Wang 	switch (event) {
15506a8d4198SShunli Wang 	case SND_SOC_DAPM_PRE_PMU:
15516a8d4198SShunli Wang 		capture_gpio_set(priv);
15526a8d4198SShunli Wang 		break;
15536a8d4198SShunli Wang 	case SND_SOC_DAPM_POST_PMD:
15546a8d4198SShunli Wang 		capture_gpio_reset(priv);
15556a8d4198SShunli Wang 		break;
15566a8d4198SShunli Wang 	default:
15576a8d4198SShunli Wang 		break;
15586a8d4198SShunli Wang 	}
15596a8d4198SShunli Wang 
15606a8d4198SShunli Wang 	return 0;
15616a8d4198SShunli Wang }
15626a8d4198SShunli Wang 
mt_adc_supply_event(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)15636a8d4198SShunli Wang static int mt_adc_supply_event(struct snd_soc_dapm_widget *w,
15646a8d4198SShunli Wang 			       struct snd_kcontrol *kcontrol,
15656a8d4198SShunli Wang 			       int event)
15666a8d4198SShunli Wang {
15676a8d4198SShunli Wang 	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
15686a8d4198SShunli Wang 	struct mt6358_priv *priv = snd_soc_component_get_drvdata(cmpnt);
15696a8d4198SShunli Wang 
15706a8d4198SShunli Wang 	dev_dbg(priv->dev, "%s(), event 0x%x\n",
15716a8d4198SShunli Wang 		__func__, event);
15726a8d4198SShunli Wang 
15736a8d4198SShunli Wang 	switch (event) {
15746a8d4198SShunli Wang 	case SND_SOC_DAPM_PRE_PMU:
15756a8d4198SShunli Wang 		/* Enable audio ADC CLKGEN  */
15766a8d4198SShunli Wang 		regmap_update_bits(priv->regmap, MT6358_AUDDEC_ANA_CON13,
15776a8d4198SShunli Wang 				   0x1 << 5, 0x1 << 5);
15786a8d4198SShunli Wang 		/* ADC CLK from CLKGEN (13MHz) */
15796a8d4198SShunli Wang 		regmap_write(priv->regmap, MT6358_AUDENC_ANA_CON3,
15806a8d4198SShunli Wang 			     0x0000);
15816a8d4198SShunli Wang 		/* Enable  LCLDO_ENC 1P8V */
15826a8d4198SShunli Wang 		regmap_update_bits(priv->regmap, MT6358_AUDDEC_ANA_CON14,
15836a8d4198SShunli Wang 				   0x2500, 0x0100);
15846a8d4198SShunli Wang 		/* LCLDO_ENC remote sense */
15856a8d4198SShunli Wang 		regmap_update_bits(priv->regmap, MT6358_AUDDEC_ANA_CON14,
15866a8d4198SShunli Wang 				   0x2500, 0x2500);
15876a8d4198SShunli Wang 		break;
15886a8d4198SShunli Wang 	case SND_SOC_DAPM_POST_PMD:
15896a8d4198SShunli Wang 		/* LCLDO_ENC remote sense off */
15906a8d4198SShunli Wang 		regmap_update_bits(priv->regmap, MT6358_AUDDEC_ANA_CON14,
15916a8d4198SShunli Wang 				   0x2500, 0x0100);
15926a8d4198SShunli Wang 		/* disable LCLDO_ENC 1P8V */
15936a8d4198SShunli Wang 		regmap_update_bits(priv->regmap, MT6358_AUDDEC_ANA_CON14,
15946a8d4198SShunli Wang 				   0x2500, 0x0000);
15956a8d4198SShunli Wang 
15966a8d4198SShunli Wang 		/* ADC CLK from CLKGEN (13MHz) */
15976a8d4198SShunli Wang 		regmap_write(priv->regmap, MT6358_AUDENC_ANA_CON3, 0x0000);
15986a8d4198SShunli Wang 		/* disable audio ADC CLKGEN  */
15996a8d4198SShunli Wang 		regmap_update_bits(priv->regmap, MT6358_AUDDEC_ANA_CON13,
16006a8d4198SShunli Wang 				   0x1 << 5, 0x0 << 5);
16016a8d4198SShunli Wang 		break;
16026a8d4198SShunli Wang 	default:
16036a8d4198SShunli Wang 		break;
16046a8d4198SShunli Wang 	}
16056a8d4198SShunli Wang 
16066a8d4198SShunli Wang 	return 0;
16076a8d4198SShunli Wang }
16086a8d4198SShunli Wang 
mt6358_amic_enable(struct mt6358_priv * priv)16096a8d4198SShunli Wang static int mt6358_amic_enable(struct mt6358_priv *priv)
16106a8d4198SShunli Wang {
16116a8d4198SShunli Wang 	unsigned int mic_type = priv->mux_select[MUX_MIC_TYPE];
16126a8d4198SShunli Wang 	unsigned int mux_pga_l = priv->mux_select[MUX_PGA_L];
16136a8d4198SShunli Wang 	unsigned int mux_pga_r = priv->mux_select[MUX_PGA_R];
16146a8d4198SShunli Wang 
16156a8d4198SShunli Wang 	dev_info(priv->dev, "%s(), mux, mic %u, pga l %u, pga r %u\n",
16166a8d4198SShunli Wang 		 __func__, mic_type, mux_pga_l, mux_pga_r);
16176a8d4198SShunli Wang 
16186a8d4198SShunli Wang 	if (IS_DCC_BASE(mic_type)) {
16196a8d4198SShunli Wang 		/* DCC 50k CLK (from 26M) */
16206a8d4198SShunli Wang 		regmap_write(priv->regmap, MT6358_AFE_DCCLK_CFG0, 0x2062);
16216a8d4198SShunli Wang 		regmap_write(priv->regmap, MT6358_AFE_DCCLK_CFG0, 0x2062);
16226a8d4198SShunli Wang 		regmap_write(priv->regmap, MT6358_AFE_DCCLK_CFG0, 0x2060);
16236a8d4198SShunli Wang 		regmap_write(priv->regmap, MT6358_AFE_DCCLK_CFG0, 0x2061);
16246a8d4198SShunli Wang 		regmap_write(priv->regmap, MT6358_AFE_DCCLK_CFG1, 0x0100);
16256a8d4198SShunli Wang 	}
16266a8d4198SShunli Wang 
16276a8d4198SShunli Wang 	/* mic bias 0 */
16286a8d4198SShunli Wang 	if (mux_pga_l == PGA_MUX_AIN0 || mux_pga_l == PGA_MUX_AIN2 ||
16296a8d4198SShunli Wang 	    mux_pga_r == PGA_MUX_AIN0 || mux_pga_r == PGA_MUX_AIN2) {
16306a8d4198SShunli Wang 		switch (mic_type) {
16316a8d4198SShunli Wang 		case MIC_TYPE_MUX_DCC_ECM_DIFF:
16326a8d4198SShunli Wang 			regmap_update_bits(priv->regmap, MT6358_AUDENC_ANA_CON9,
16336a8d4198SShunli Wang 					   0xff00, 0x7700);
16346a8d4198SShunli Wang 			break;
16356a8d4198SShunli Wang 		case MIC_TYPE_MUX_DCC_ECM_SINGLE:
16366a8d4198SShunli Wang 			regmap_update_bits(priv->regmap, MT6358_AUDENC_ANA_CON9,
16376a8d4198SShunli Wang 					   0xff00, 0x1100);
16386a8d4198SShunli Wang 			break;
16396a8d4198SShunli Wang 		default:
16406a8d4198SShunli Wang 			regmap_update_bits(priv->regmap, MT6358_AUDENC_ANA_CON9,
16416a8d4198SShunli Wang 					   0xff00, 0x0000);
16426a8d4198SShunli Wang 			break;
16436a8d4198SShunli Wang 		}
16446a8d4198SShunli Wang 		/* Enable MICBIAS0, MISBIAS0 = 1P9V */
16456a8d4198SShunli Wang 		regmap_update_bits(priv->regmap, MT6358_AUDENC_ANA_CON9,
16466a8d4198SShunli Wang 				   0xff, 0x21);
16476a8d4198SShunli Wang 	}
16486a8d4198SShunli Wang 
16496a8d4198SShunli Wang 	/* mic bias 1 */
16506a8d4198SShunli Wang 	if (mux_pga_l == PGA_MUX_AIN1 || mux_pga_r == PGA_MUX_AIN1) {
16516a8d4198SShunli Wang 		/* Enable MICBIAS1, MISBIAS1 = 2P6V */
16526a8d4198SShunli Wang 		if (mic_type == MIC_TYPE_MUX_DCC_ECM_SINGLE)
16536a8d4198SShunli Wang 			regmap_write(priv->regmap,
16546a8d4198SShunli Wang 				     MT6358_AUDENC_ANA_CON10, 0x0161);
16556a8d4198SShunli Wang 		else
16566a8d4198SShunli Wang 			regmap_write(priv->regmap,
16576a8d4198SShunli Wang 				     MT6358_AUDENC_ANA_CON10, 0x0061);
16586a8d4198SShunli Wang 	}
16596a8d4198SShunli Wang 
16606a8d4198SShunli Wang 	if (IS_DCC_BASE(mic_type)) {
16616a8d4198SShunli Wang 		/* Audio L/R preamplifier DCC precharge */
16626a8d4198SShunli Wang 		regmap_update_bits(priv->regmap, MT6358_AUDENC_ANA_CON0,
16636a8d4198SShunli Wang 				   0xf8ff, 0x0004);
16646a8d4198SShunli Wang 		regmap_update_bits(priv->regmap, MT6358_AUDENC_ANA_CON1,
16656a8d4198SShunli Wang 				   0xf8ff, 0x0004);
16666a8d4198SShunli Wang 	} else {
16676a8d4198SShunli Wang 		/* reset reg */
16686a8d4198SShunli Wang 		regmap_update_bits(priv->regmap, MT6358_AUDENC_ANA_CON0,
16696a8d4198SShunli Wang 				   0xf8ff, 0x0000);
16706a8d4198SShunli Wang 		regmap_update_bits(priv->regmap, MT6358_AUDENC_ANA_CON1,
16716a8d4198SShunli Wang 				   0xf8ff, 0x0000);
16726a8d4198SShunli Wang 	}
16736a8d4198SShunli Wang 
16746a8d4198SShunli Wang 	if (mux_pga_l != PGA_MUX_NONE) {
16756a8d4198SShunli Wang 		/* L preamplifier input sel */
16766a8d4198SShunli Wang 		regmap_update_bits(priv->regmap, MT6358_AUDENC_ANA_CON0,
16776a8d4198SShunli Wang 				   RG_AUDPREAMPLINPUTSEL_MASK_SFT,
16786a8d4198SShunli Wang 				   mux_pga_l << RG_AUDPREAMPLINPUTSEL_SFT);
16796a8d4198SShunli Wang 
16806a8d4198SShunli Wang 		/* L preamplifier enable */
16816a8d4198SShunli Wang 		regmap_update_bits(priv->regmap, MT6358_AUDENC_ANA_CON0,
16826a8d4198SShunli Wang 				   RG_AUDPREAMPLON_MASK_SFT,
16836a8d4198SShunli Wang 				   0x1 << RG_AUDPREAMPLON_SFT);
16846a8d4198SShunli Wang 
16856a8d4198SShunli Wang 		if (IS_DCC_BASE(mic_type)) {
16866a8d4198SShunli Wang 			/* L preamplifier DCCEN */
16876a8d4198SShunli Wang 			regmap_update_bits(priv->regmap, MT6358_AUDENC_ANA_CON0,
16886a8d4198SShunli Wang 					   RG_AUDPREAMPLDCCEN_MASK_SFT,
16896a8d4198SShunli Wang 					   0x1 << RG_AUDPREAMPLDCCEN_SFT);
16906a8d4198SShunli Wang 		}
16916a8d4198SShunli Wang 
16926a8d4198SShunli Wang 		/* L ADC input sel : L PGA. Enable audio L ADC */
16936a8d4198SShunli Wang 		regmap_update_bits(priv->regmap, MT6358_AUDENC_ANA_CON0,
16946a8d4198SShunli Wang 				   RG_AUDADCLINPUTSEL_MASK_SFT,
16956a8d4198SShunli Wang 				   ADC_MUX_PREAMPLIFIER <<
16966a8d4198SShunli Wang 				   RG_AUDADCLINPUTSEL_SFT);
16976a8d4198SShunli Wang 		regmap_update_bits(priv->regmap, MT6358_AUDENC_ANA_CON0,
16986a8d4198SShunli Wang 				   RG_AUDADCLPWRUP_MASK_SFT,
16996a8d4198SShunli Wang 				   0x1 << RG_AUDADCLPWRUP_SFT);
17006a8d4198SShunli Wang 	}
17016a8d4198SShunli Wang 
17026a8d4198SShunli Wang 	if (mux_pga_r != PGA_MUX_NONE) {
17036a8d4198SShunli Wang 		/* R preamplifier input sel */
17046a8d4198SShunli Wang 		regmap_update_bits(priv->regmap, MT6358_AUDENC_ANA_CON1,
17056a8d4198SShunli Wang 				   RG_AUDPREAMPRINPUTSEL_MASK_SFT,
17066a8d4198SShunli Wang 				   mux_pga_r << RG_AUDPREAMPRINPUTSEL_SFT);
17076a8d4198SShunli Wang 
17086a8d4198SShunli Wang 		/* R preamplifier enable */
17096a8d4198SShunli Wang 		regmap_update_bits(priv->regmap, MT6358_AUDENC_ANA_CON1,
17106a8d4198SShunli Wang 				   RG_AUDPREAMPRON_MASK_SFT,
17116a8d4198SShunli Wang 				   0x1 << RG_AUDPREAMPRON_SFT);
17126a8d4198SShunli Wang 
17136a8d4198SShunli Wang 		if (IS_DCC_BASE(mic_type)) {
17146a8d4198SShunli Wang 			/* R preamplifier DCCEN */
17156a8d4198SShunli Wang 			regmap_update_bits(priv->regmap, MT6358_AUDENC_ANA_CON1,
17166a8d4198SShunli Wang 					   RG_AUDPREAMPRDCCEN_MASK_SFT,
17176a8d4198SShunli Wang 					   0x1 << RG_AUDPREAMPRDCCEN_SFT);
17186a8d4198SShunli Wang 		}
17196a8d4198SShunli Wang 
17206a8d4198SShunli Wang 		/* R ADC input sel : R PGA. Enable audio R ADC */
17216a8d4198SShunli Wang 		regmap_update_bits(priv->regmap, MT6358_AUDENC_ANA_CON1,
17226a8d4198SShunli Wang 				   RG_AUDADCRINPUTSEL_MASK_SFT,
17236a8d4198SShunli Wang 				   ADC_MUX_PREAMPLIFIER <<
17246a8d4198SShunli Wang 				   RG_AUDADCRINPUTSEL_SFT);
17256a8d4198SShunli Wang 		regmap_update_bits(priv->regmap, MT6358_AUDENC_ANA_CON1,
17266a8d4198SShunli Wang 				   RG_AUDADCRPWRUP_MASK_SFT,
17276a8d4198SShunli Wang 				   0x1 << RG_AUDADCRPWRUP_SFT);
17286a8d4198SShunli Wang 	}
17296a8d4198SShunli Wang 
17306a8d4198SShunli Wang 	if (IS_DCC_BASE(mic_type)) {
17316a8d4198SShunli Wang 		usleep_range(100, 150);
17326a8d4198SShunli Wang 		/* Audio L preamplifier DCC precharge off */
17336a8d4198SShunli Wang 		regmap_update_bits(priv->regmap, MT6358_AUDENC_ANA_CON0,
17346a8d4198SShunli Wang 				   RG_AUDPREAMPLDCPRECHARGE_MASK_SFT, 0x0);
17356a8d4198SShunli Wang 		/* Audio R preamplifier DCC precharge off */
17366a8d4198SShunli Wang 		regmap_update_bits(priv->regmap, MT6358_AUDENC_ANA_CON1,
17376a8d4198SShunli Wang 				   RG_AUDPREAMPRDCPRECHARGE_MASK_SFT, 0x0);
17386a8d4198SShunli Wang 
17396a8d4198SShunli Wang 		/* Short body to ground in PGA */
17406a8d4198SShunli Wang 		regmap_update_bits(priv->regmap, MT6358_AUDENC_ANA_CON3,
17416a8d4198SShunli Wang 				   0x1 << 12, 0x0);
17426a8d4198SShunli Wang 	}
17436a8d4198SShunli Wang 
17446a8d4198SShunli Wang 	/* here to set digital part */
17456a8d4198SShunli Wang 	mt6358_mtkaif_tx_enable(priv);
17466a8d4198SShunli Wang 
17476a8d4198SShunli Wang 	/* UL dmic setting off */
17486a8d4198SShunli Wang 	regmap_write(priv->regmap, MT6358_AFE_UL_SRC_CON0_H, 0x0000);
17496a8d4198SShunli Wang 
17506a8d4198SShunli Wang 	/* UL turn on */
17516a8d4198SShunli Wang 	regmap_write(priv->regmap, MT6358_AFE_UL_SRC_CON0_L, 0x0001);
17526a8d4198SShunli Wang 
17536a8d4198SShunli Wang 	return 0;
17546a8d4198SShunli Wang }
17556a8d4198SShunli Wang 
mt6358_amic_disable(struct mt6358_priv * priv)17566a8d4198SShunli Wang static void mt6358_amic_disable(struct mt6358_priv *priv)
17576a8d4198SShunli Wang {
17586a8d4198SShunli Wang 	unsigned int mic_type = priv->mux_select[MUX_MIC_TYPE];
17596a8d4198SShunli Wang 	unsigned int mux_pga_l = priv->mux_select[MUX_PGA_L];
17606a8d4198SShunli Wang 	unsigned int mux_pga_r = priv->mux_select[MUX_PGA_R];
17616a8d4198SShunli Wang 
17626a8d4198SShunli Wang 	dev_info(priv->dev, "%s(), mux, mic %u, pga l %u, pga r %u\n",
17636a8d4198SShunli Wang 		 __func__, mic_type, mux_pga_l, mux_pga_r);
17646a8d4198SShunli Wang 
17656a8d4198SShunli Wang 	/* UL turn off */
17666a8d4198SShunli Wang 	regmap_update_bits(priv->regmap, MT6358_AFE_UL_SRC_CON0_L,
17676a8d4198SShunli Wang 			   0x0001, 0x0000);
17686a8d4198SShunli Wang 
17696a8d4198SShunli Wang 	/* disable aud_pad TX fifos */
17706a8d4198SShunli Wang 	mt6358_mtkaif_tx_disable(priv);
17716a8d4198SShunli Wang 
17726a8d4198SShunli Wang 	/* L ADC input sel : off, disable L ADC */
17736a8d4198SShunli Wang 	regmap_update_bits(priv->regmap, MT6358_AUDENC_ANA_CON0,
17746a8d4198SShunli Wang 			   0xf000, 0x0000);
17756a8d4198SShunli Wang 	/* L preamplifier DCCEN */
17766a8d4198SShunli Wang 	regmap_update_bits(priv->regmap, MT6358_AUDENC_ANA_CON0,
17776a8d4198SShunli Wang 			   0x1 << 1, 0x0);
17786a8d4198SShunli Wang 	/* L preamplifier input sel : off, L PGA 0 dB gain */
17796a8d4198SShunli Wang 	regmap_update_bits(priv->regmap, MT6358_AUDENC_ANA_CON0,
17806a8d4198SShunli Wang 			   0xfffb, 0x0000);
17816a8d4198SShunli Wang 
17826a8d4198SShunli Wang 	/* disable L preamplifier DCC precharge */
17836a8d4198SShunli Wang 	regmap_update_bits(priv->regmap, MT6358_AUDENC_ANA_CON0,
17846a8d4198SShunli Wang 			   0x1 << 2, 0x0);
17856a8d4198SShunli Wang 
17866a8d4198SShunli Wang 	/* R ADC input sel : off, disable R ADC */
17876a8d4198SShunli Wang 	regmap_update_bits(priv->regmap, MT6358_AUDENC_ANA_CON1,
17886a8d4198SShunli Wang 			   0xf000, 0x0000);
17896a8d4198SShunli Wang 	/* R preamplifier DCCEN */
17906a8d4198SShunli Wang 	regmap_update_bits(priv->regmap, MT6358_AUDENC_ANA_CON1,
17916a8d4198SShunli Wang 			   0x1 << 1, 0x0);
17926a8d4198SShunli Wang 	/* R preamplifier input sel : off, R PGA 0 dB gain */
17936a8d4198SShunli Wang 	regmap_update_bits(priv->regmap, MT6358_AUDENC_ANA_CON1,
17946a8d4198SShunli Wang 			   0x0ffb, 0x0000);
17956a8d4198SShunli Wang 
17966a8d4198SShunli Wang 	/* disable R preamplifier DCC precharge */
17976a8d4198SShunli Wang 	regmap_update_bits(priv->regmap, MT6358_AUDENC_ANA_CON1,
17986a8d4198SShunli Wang 			   0x1 << 2, 0x0);
17996a8d4198SShunli Wang 
18006a8d4198SShunli Wang 	/* mic bias */
18016a8d4198SShunli Wang 	/* Disable MICBIAS0, MISBIAS0 = 1P7V */
18026a8d4198SShunli Wang 	regmap_write(priv->regmap, MT6358_AUDENC_ANA_CON9, 0x0000);
18036a8d4198SShunli Wang 
18046a8d4198SShunli Wang 	/* Disable MICBIAS1 */
18056a8d4198SShunli Wang 	regmap_update_bits(priv->regmap, MT6358_AUDENC_ANA_CON10,
18066a8d4198SShunli Wang 			   0x0001, 0x0000);
18076a8d4198SShunli Wang 
18086a8d4198SShunli Wang 	if (IS_DCC_BASE(mic_type)) {
18096a8d4198SShunli Wang 		/* dcclk_gen_on=1'b0 */
18106a8d4198SShunli Wang 		regmap_write(priv->regmap, MT6358_AFE_DCCLK_CFG0, 0x2060);
18116a8d4198SShunli Wang 		/* dcclk_pdn=1'b1 */
18126a8d4198SShunli Wang 		regmap_write(priv->regmap, MT6358_AFE_DCCLK_CFG0, 0x2062);
18136a8d4198SShunli Wang 		/* dcclk_ref_ck_sel=2'b00 */
18146a8d4198SShunli Wang 		regmap_write(priv->regmap, MT6358_AFE_DCCLK_CFG0, 0x2062);
18156a8d4198SShunli Wang 		/* dcclk_div=11'b00100000011 */
18166a8d4198SShunli Wang 		regmap_write(priv->regmap, MT6358_AFE_DCCLK_CFG0, 0x2062);
18176a8d4198SShunli Wang 	}
18186a8d4198SShunli Wang }
18196a8d4198SShunli Wang 
mt6358_dmic_enable(struct mt6358_priv * priv)18206a8d4198SShunli Wang static int mt6358_dmic_enable(struct mt6358_priv *priv)
18216a8d4198SShunli Wang {
18226a8d4198SShunli Wang 	dev_info(priv->dev, "%s()\n", __func__);
18236a8d4198SShunli Wang 
18246a8d4198SShunli Wang 	/* mic bias */
18256a8d4198SShunli Wang 	/* Enable MICBIAS0, MISBIAS0 = 1P9V */
18266a8d4198SShunli Wang 	regmap_write(priv->regmap, MT6358_AUDENC_ANA_CON9, 0x0021);
18276a8d4198SShunli Wang 
18286a8d4198SShunli Wang 	/* RG_BANDGAPGEN=1'b0 */
18296a8d4198SShunli Wang 	regmap_update_bits(priv->regmap, MT6358_AUDENC_ANA_CON10,
18306a8d4198SShunli Wang 			   0x1 << 12, 0x0);
18316a8d4198SShunli Wang 
18326a8d4198SShunli Wang 	/* DMIC enable */
18336a8d4198SShunli Wang 	regmap_write(priv->regmap, MT6358_AUDENC_ANA_CON8, 0x0005);
18346a8d4198SShunli Wang 
18356a8d4198SShunli Wang 	/* here to set digital part */
18366a8d4198SShunli Wang 	mt6358_mtkaif_tx_enable(priv);
18376a8d4198SShunli Wang 
18386a8d4198SShunli Wang 	/* UL dmic setting */
1839c46fc800SJiaxin Yu 	if (priv->dmic_one_wire_mode)
1840c46fc800SJiaxin Yu 		regmap_write(priv->regmap, MT6358_AFE_UL_SRC_CON0_H, 0x0400);
1841c46fc800SJiaxin Yu 	else
18426a8d4198SShunli Wang 		regmap_write(priv->regmap, MT6358_AFE_UL_SRC_CON0_H, 0x0080);
18436a8d4198SShunli Wang 
18446a8d4198SShunli Wang 	/* UL turn on */
18456a8d4198SShunli Wang 	regmap_write(priv->regmap, MT6358_AFE_UL_SRC_CON0_L, 0x0003);
1846ccb1fa21SJiaxin Yu 
1847ccb1fa21SJiaxin Yu 	/* Prevent pop noise form dmic hw */
1848ccb1fa21SJiaxin Yu 	msleep(100);
1849ccb1fa21SJiaxin Yu 
18506a8d4198SShunli Wang 	return 0;
18516a8d4198SShunli Wang }
18526a8d4198SShunli Wang 
mt6358_dmic_disable(struct mt6358_priv * priv)18536a8d4198SShunli Wang static void mt6358_dmic_disable(struct mt6358_priv *priv)
18546a8d4198SShunli Wang {
18556a8d4198SShunli Wang 	dev_info(priv->dev, "%s()\n", __func__);
18566a8d4198SShunli Wang 
18576a8d4198SShunli Wang 	/* UL turn off */
18586a8d4198SShunli Wang 	regmap_update_bits(priv->regmap, MT6358_AFE_UL_SRC_CON0_L,
18596a8d4198SShunli Wang 			   0x0003, 0x0000);
18606a8d4198SShunli Wang 
18616a8d4198SShunli Wang 	/* disable aud_pad TX fifos */
18626a8d4198SShunli Wang 	mt6358_mtkaif_tx_disable(priv);
18636a8d4198SShunli Wang 
18646a8d4198SShunli Wang 	/* DMIC disable */
18656a8d4198SShunli Wang 	regmap_write(priv->regmap, MT6358_AUDENC_ANA_CON8, 0x0000);
18666a8d4198SShunli Wang 
18676a8d4198SShunli Wang 	/* mic bias */
18686a8d4198SShunli Wang 	/* MISBIAS0 = 1P7V */
18696a8d4198SShunli Wang 	regmap_write(priv->regmap, MT6358_AUDENC_ANA_CON9, 0x0001);
18706a8d4198SShunli Wang 
18716a8d4198SShunli Wang 	/* RG_BANDGAPGEN=1'b0 */
18726a8d4198SShunli Wang 	regmap_update_bits(priv->regmap, MT6358_AUDENC_ANA_CON10,
18736a8d4198SShunli Wang 			   0x1 << 12, 0x0);
18746a8d4198SShunli Wang 
18756a8d4198SShunli Wang 	/* MICBIA0 disable */
18766a8d4198SShunli Wang 	regmap_write(priv->regmap, MT6358_AUDENC_ANA_CON9, 0x0000);
18776a8d4198SShunli Wang }
18786a8d4198SShunli Wang 
mt6358_restore_pga(struct mt6358_priv * priv)1879ec0574a6STzung-Bi Shih static void mt6358_restore_pga(struct mt6358_priv *priv)
1880ec0574a6STzung-Bi Shih {
1881ec0574a6STzung-Bi Shih 	unsigned int gain_l, gain_r;
1882ec0574a6STzung-Bi Shih 
1883ec0574a6STzung-Bi Shih 	gain_l = priv->ana_gain[AUDIO_ANALOG_VOLUME_MICAMP1];
1884ec0574a6STzung-Bi Shih 	gain_r = priv->ana_gain[AUDIO_ANALOG_VOLUME_MICAMP2];
1885ec0574a6STzung-Bi Shih 
1886ec0574a6STzung-Bi Shih 	regmap_update_bits(priv->regmap, MT6358_AUDENC_ANA_CON0,
1887ec0574a6STzung-Bi Shih 			   RG_AUDPREAMPLGAIN_MASK_SFT,
1888ec0574a6STzung-Bi Shih 			   gain_l << RG_AUDPREAMPLGAIN_SFT);
1889ec0574a6STzung-Bi Shih 	regmap_update_bits(priv->regmap, MT6358_AUDENC_ANA_CON1,
1890ec0574a6STzung-Bi Shih 			   RG_AUDPREAMPRGAIN_MASK_SFT,
1891ec0574a6STzung-Bi Shih 			   gain_r << RG_AUDPREAMPRGAIN_SFT);
1892ec0574a6STzung-Bi Shih }
1893ec0574a6STzung-Bi Shih 
mt_mic_type_event(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)18946a8d4198SShunli Wang static int mt_mic_type_event(struct snd_soc_dapm_widget *w,
18956a8d4198SShunli Wang 			     struct snd_kcontrol *kcontrol,
18966a8d4198SShunli Wang 			     int event)
18976a8d4198SShunli Wang {
18986a8d4198SShunli Wang 	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
18996a8d4198SShunli Wang 	struct mt6358_priv *priv = snd_soc_component_get_drvdata(cmpnt);
19006a8d4198SShunli Wang 	unsigned int mux = dapm_kcontrol_get_value(w->kcontrols[0]);
19016a8d4198SShunli Wang 
19026a8d4198SShunli Wang 	dev_dbg(priv->dev, "%s(), event 0x%x, mux %u\n",
19036a8d4198SShunli Wang 		__func__, event, mux);
19046a8d4198SShunli Wang 
19056a8d4198SShunli Wang 	switch (event) {
19066a8d4198SShunli Wang 	case SND_SOC_DAPM_WILL_PMU:
19076a8d4198SShunli Wang 		priv->mux_select[MUX_MIC_TYPE] = mux;
19086a8d4198SShunli Wang 		break;
19096a8d4198SShunli Wang 	case SND_SOC_DAPM_PRE_PMU:
19106a8d4198SShunli Wang 		switch (mux) {
19116a8d4198SShunli Wang 		case MIC_TYPE_MUX_DMIC:
19126a8d4198SShunli Wang 			mt6358_dmic_enable(priv);
19136a8d4198SShunli Wang 			break;
19146a8d4198SShunli Wang 		default:
19156a8d4198SShunli Wang 			mt6358_amic_enable(priv);
19166a8d4198SShunli Wang 			break;
19176a8d4198SShunli Wang 		}
1918ec0574a6STzung-Bi Shih 		mt6358_restore_pga(priv);
19196a8d4198SShunli Wang 
19206a8d4198SShunli Wang 		break;
19216a8d4198SShunli Wang 	case SND_SOC_DAPM_POST_PMD:
19226a8d4198SShunli Wang 		switch (priv->mux_select[MUX_MIC_TYPE]) {
19236a8d4198SShunli Wang 		case MIC_TYPE_MUX_DMIC:
19246a8d4198SShunli Wang 			mt6358_dmic_disable(priv);
19256a8d4198SShunli Wang 			break;
19266a8d4198SShunli Wang 		default:
19276a8d4198SShunli Wang 			mt6358_amic_disable(priv);
19286a8d4198SShunli Wang 			break;
19296a8d4198SShunli Wang 		}
19306a8d4198SShunli Wang 
19316a8d4198SShunli Wang 		priv->mux_select[MUX_MIC_TYPE] = mux;
19326a8d4198SShunli Wang 		break;
19336a8d4198SShunli Wang 	default:
19346a8d4198SShunli Wang 		break;
19356a8d4198SShunli Wang 	}
19366a8d4198SShunli Wang 
19376a8d4198SShunli Wang 	return 0;
19386a8d4198SShunli Wang }
19396a8d4198SShunli Wang 
mt_adc_l_event(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)19406a8d4198SShunli Wang static int mt_adc_l_event(struct snd_soc_dapm_widget *w,
19416a8d4198SShunli Wang 			  struct snd_kcontrol *kcontrol,
19426a8d4198SShunli Wang 			  int event)
19436a8d4198SShunli Wang {
19446a8d4198SShunli Wang 	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
19456a8d4198SShunli Wang 	struct mt6358_priv *priv = snd_soc_component_get_drvdata(cmpnt);
19466a8d4198SShunli Wang 	unsigned int mux = dapm_kcontrol_get_value(w->kcontrols[0]);
19476a8d4198SShunli Wang 
19486a8d4198SShunli Wang 	dev_dbg(priv->dev, "%s(), event = 0x%x, mux %u\n",
19496a8d4198SShunli Wang 		__func__, event, mux);
19506a8d4198SShunli Wang 
19516a8d4198SShunli Wang 	priv->mux_select[MUX_ADC_L] = mux;
19526a8d4198SShunli Wang 
19536a8d4198SShunli Wang 	return 0;
19546a8d4198SShunli Wang }
19556a8d4198SShunli Wang 
mt_adc_r_event(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)19566a8d4198SShunli Wang static int mt_adc_r_event(struct snd_soc_dapm_widget *w,
19576a8d4198SShunli Wang 			  struct snd_kcontrol *kcontrol,
19586a8d4198SShunli Wang 			  int event)
19596a8d4198SShunli Wang {
19606a8d4198SShunli Wang 	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
19616a8d4198SShunli Wang 	struct mt6358_priv *priv = snd_soc_component_get_drvdata(cmpnt);
19626a8d4198SShunli Wang 	unsigned int mux = dapm_kcontrol_get_value(w->kcontrols[0]);
19636a8d4198SShunli Wang 
19646a8d4198SShunli Wang 	dev_dbg(priv->dev, "%s(), event = 0x%x, mux %u\n",
19656a8d4198SShunli Wang 		__func__, event, mux);
19666a8d4198SShunli Wang 
19676a8d4198SShunli Wang 	priv->mux_select[MUX_ADC_R] = mux;
19686a8d4198SShunli Wang 
19696a8d4198SShunli Wang 	return 0;
19706a8d4198SShunli Wang }
19716a8d4198SShunli Wang 
mt_pga_left_event(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)19726a8d4198SShunli Wang static int mt_pga_left_event(struct snd_soc_dapm_widget *w,
19736a8d4198SShunli Wang 			     struct snd_kcontrol *kcontrol,
19746a8d4198SShunli Wang 			     int event)
19756a8d4198SShunli Wang {
19766a8d4198SShunli Wang 	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
19776a8d4198SShunli Wang 	struct mt6358_priv *priv = snd_soc_component_get_drvdata(cmpnt);
19786a8d4198SShunli Wang 	unsigned int mux = dapm_kcontrol_get_value(w->kcontrols[0]);
19796a8d4198SShunli Wang 
19806a8d4198SShunli Wang 	dev_dbg(priv->dev, "%s(), event = 0x%x, mux %u\n",
19816a8d4198SShunli Wang 		__func__, event, mux);
19826a8d4198SShunli Wang 
19836a8d4198SShunli Wang 	priv->mux_select[MUX_PGA_L] = mux;
19846a8d4198SShunli Wang 
19856a8d4198SShunli Wang 	return 0;
19866a8d4198SShunli Wang }
19876a8d4198SShunli Wang 
mt_pga_right_event(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)19886a8d4198SShunli Wang static int mt_pga_right_event(struct snd_soc_dapm_widget *w,
19896a8d4198SShunli Wang 			      struct snd_kcontrol *kcontrol,
19906a8d4198SShunli Wang 			      int event)
19916a8d4198SShunli Wang {
19926a8d4198SShunli Wang 	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
19936a8d4198SShunli Wang 	struct mt6358_priv *priv = snd_soc_component_get_drvdata(cmpnt);
19946a8d4198SShunli Wang 	unsigned int mux = dapm_kcontrol_get_value(w->kcontrols[0]);
19956a8d4198SShunli Wang 
19966a8d4198SShunli Wang 	dev_dbg(priv->dev, "%s(), event = 0x%x, mux %u\n",
19976a8d4198SShunli Wang 		__func__, event, mux);
19986a8d4198SShunli Wang 
19996a8d4198SShunli Wang 	priv->mux_select[MUX_PGA_R] = mux;
20006a8d4198SShunli Wang 
20016a8d4198SShunli Wang 	return 0;
20026a8d4198SShunli Wang }
20036a8d4198SShunli Wang 
mt_delay_250_event(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)20046a8d4198SShunli Wang static int mt_delay_250_event(struct snd_soc_dapm_widget *w,
20056a8d4198SShunli Wang 			      struct snd_kcontrol *kcontrol,
20066a8d4198SShunli Wang 			      int event)
20076a8d4198SShunli Wang {
20086a8d4198SShunli Wang 	switch (event) {
20096a8d4198SShunli Wang 	case SND_SOC_DAPM_POST_PMU:
20106a8d4198SShunli Wang 		usleep_range(250, 270);
20116a8d4198SShunli Wang 		break;
20126a8d4198SShunli Wang 	case SND_SOC_DAPM_PRE_PMD:
20136a8d4198SShunli Wang 		usleep_range(250, 270);
20146a8d4198SShunli Wang 		break;
20156a8d4198SShunli Wang 	default:
20166a8d4198SShunli Wang 		break;
20176a8d4198SShunli Wang 	}
20186a8d4198SShunli Wang 
20196a8d4198SShunli Wang 	return 0;
20206a8d4198SShunli Wang }
20216a8d4198SShunli Wang 
20226a8d4198SShunli Wang /* DAPM Widgets */
20236a8d4198SShunli Wang static const struct snd_soc_dapm_widget mt6358_dapm_widgets[] = {
20246a8d4198SShunli Wang 	/* Global Supply*/
20256a8d4198SShunli Wang 	SND_SOC_DAPM_SUPPLY_S("CLK_BUF", SUPPLY_SEQ_CLK_BUF,
20266a8d4198SShunli Wang 			      MT6358_DCXO_CW14,
20276a8d4198SShunli Wang 			      RG_XO_AUDIO_EN_M_SFT, 0, NULL, 0),
20286a8d4198SShunli Wang 	SND_SOC_DAPM_SUPPLY_S("AUDGLB", SUPPLY_SEQ_AUD_GLB,
20296a8d4198SShunli Wang 			      MT6358_AUDDEC_ANA_CON13,
20306a8d4198SShunli Wang 			      RG_AUDGLB_PWRDN_VA28_SFT, 1, NULL, 0),
20316a8d4198SShunli Wang 	SND_SOC_DAPM_SUPPLY_S("CLKSQ Audio", SUPPLY_SEQ_CLKSQ,
20326a8d4198SShunli Wang 			      MT6358_AUDENC_ANA_CON6,
20336a8d4198SShunli Wang 			      RG_CLKSQ_EN_SFT, 0,
20346a8d4198SShunli Wang 			      mt_clksq_event,
20356a8d4198SShunli Wang 			      SND_SOC_DAPM_PRE_PMU),
20366a8d4198SShunli Wang 	SND_SOC_DAPM_SUPPLY_S("AUDNCP_CK", SUPPLY_SEQ_TOP_CK,
20376a8d4198SShunli Wang 			      MT6358_AUD_TOP_CKPDN_CON0,
20386a8d4198SShunli Wang 			      RG_AUDNCP_CK_PDN_SFT, 1, NULL, 0),
20396a8d4198SShunli Wang 	SND_SOC_DAPM_SUPPLY_S("ZCD13M_CK", SUPPLY_SEQ_TOP_CK,
20406a8d4198SShunli Wang 			      MT6358_AUD_TOP_CKPDN_CON0,
20416a8d4198SShunli Wang 			      RG_ZCD13M_CK_PDN_SFT, 1, NULL, 0),
20426a8d4198SShunli Wang 	SND_SOC_DAPM_SUPPLY_S("AUD_CK", SUPPLY_SEQ_TOP_CK_LAST,
20436a8d4198SShunli Wang 			      MT6358_AUD_TOP_CKPDN_CON0,
20446a8d4198SShunli Wang 			      RG_AUD_CK_PDN_SFT, 1,
20456a8d4198SShunli Wang 			      mt_delay_250_event,
20466a8d4198SShunli Wang 			      SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
20476a8d4198SShunli Wang 	SND_SOC_DAPM_SUPPLY_S("AUDIF_CK", SUPPLY_SEQ_TOP_CK,
20486a8d4198SShunli Wang 			      MT6358_AUD_TOP_CKPDN_CON0,
20496a8d4198SShunli Wang 			      RG_AUDIF_CK_PDN_SFT, 1, NULL, 0),
20506a8d4198SShunli Wang 
20516a8d4198SShunli Wang 	/* Digital Clock */
20526a8d4198SShunli Wang 	SND_SOC_DAPM_SUPPLY_S("AUDIO_TOP_AFE_CTL", SUPPLY_SEQ_AUD_TOP_LAST,
20536a8d4198SShunli Wang 			      MT6358_AUDIO_TOP_CON0,
20546a8d4198SShunli Wang 			      PDN_AFE_CTL_SFT, 1,
20556a8d4198SShunli Wang 			      mt_delay_250_event,
20566a8d4198SShunli Wang 			      SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
20576a8d4198SShunli Wang 	SND_SOC_DAPM_SUPPLY_S("AUDIO_TOP_DAC_CTL", SUPPLY_SEQ_AUD_TOP,
20586a8d4198SShunli Wang 			      MT6358_AUDIO_TOP_CON0,
20596a8d4198SShunli Wang 			      PDN_DAC_CTL_SFT, 1, NULL, 0),
20606a8d4198SShunli Wang 	SND_SOC_DAPM_SUPPLY_S("AUDIO_TOP_ADC_CTL", SUPPLY_SEQ_AUD_TOP,
20616a8d4198SShunli Wang 			      MT6358_AUDIO_TOP_CON0,
20626a8d4198SShunli Wang 			      PDN_ADC_CTL_SFT, 1, NULL, 0),
20636a8d4198SShunli Wang 	SND_SOC_DAPM_SUPPLY_S("AUDIO_TOP_I2S_DL", SUPPLY_SEQ_AUD_TOP,
20646a8d4198SShunli Wang 			      MT6358_AUDIO_TOP_CON0,
20656a8d4198SShunli Wang 			      PDN_I2S_DL_CTL_SFT, 1, NULL, 0),
20666a8d4198SShunli Wang 	SND_SOC_DAPM_SUPPLY_S("AUDIO_TOP_PWR_CLK", SUPPLY_SEQ_AUD_TOP,
20676a8d4198SShunli Wang 			      MT6358_AUDIO_TOP_CON0,
20686a8d4198SShunli Wang 			      PWR_CLK_DIS_CTL_SFT, 1, NULL, 0),
20696a8d4198SShunli Wang 	SND_SOC_DAPM_SUPPLY_S("AUDIO_TOP_PDN_AFE_TESTMODEL", SUPPLY_SEQ_AUD_TOP,
20706a8d4198SShunli Wang 			      MT6358_AUDIO_TOP_CON0,
20716a8d4198SShunli Wang 			      PDN_AFE_TESTMODEL_CTL_SFT, 1, NULL, 0),
20726a8d4198SShunli Wang 	SND_SOC_DAPM_SUPPLY_S("AUDIO_TOP_PDN_RESERVED", SUPPLY_SEQ_AUD_TOP,
20736a8d4198SShunli Wang 			      MT6358_AUDIO_TOP_CON0,
20746a8d4198SShunli Wang 			      PDN_RESERVED_SFT, 1, NULL, 0),
20756a8d4198SShunli Wang 
20766a8d4198SShunli Wang 	SND_SOC_DAPM_SUPPLY("DL Digital Clock", SND_SOC_NOPM,
20776a8d4198SShunli Wang 			    0, 0, NULL, 0),
20786a8d4198SShunli Wang 
20796a8d4198SShunli Wang 	/* AFE ON */
20806a8d4198SShunli Wang 	SND_SOC_DAPM_SUPPLY_S("AFE_ON", SUPPLY_SEQ_AFE,
20816a8d4198SShunli Wang 			      MT6358_AFE_UL_DL_CON0, AFE_ON_SFT, 0,
20826a8d4198SShunli Wang 			      NULL, 0),
20836a8d4198SShunli Wang 
20846a8d4198SShunli Wang 	/* AIF Rx*/
20856a8d4198SShunli Wang 	SND_SOC_DAPM_AIF_IN_E("AIF_RX", "AIF1 Playback", 0,
20866a8d4198SShunli Wang 			      MT6358_AFE_DL_SRC2_CON0_L,
20876a8d4198SShunli Wang 			      DL_2_SRC_ON_TMP_CTL_PRE_SFT, 0,
20886a8d4198SShunli Wang 			      mt_aif_in_event,
20896a8d4198SShunli Wang 			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
20906a8d4198SShunli Wang 
20916a8d4198SShunli Wang 	/* DL Supply */
20926a8d4198SShunli Wang 	SND_SOC_DAPM_SUPPLY("DL Power Supply", SND_SOC_NOPM,
20936a8d4198SShunli Wang 			    0, 0, NULL, 0),
20946a8d4198SShunli Wang 
20956a8d4198SShunli Wang 	/* DAC */
20966a8d4198SShunli Wang 	SND_SOC_DAPM_MUX("DAC In Mux", SND_SOC_NOPM, 0, 0, &dac_in_mux_control),
20976a8d4198SShunli Wang 
20986a8d4198SShunli Wang 	SND_SOC_DAPM_DAC("DACL", NULL, SND_SOC_NOPM, 0, 0),
20996a8d4198SShunli Wang 
21006a8d4198SShunli Wang 	SND_SOC_DAPM_DAC("DACR", NULL, SND_SOC_NOPM, 0, 0),
21016a8d4198SShunli Wang 
21026a8d4198SShunli Wang 	/* LOL */
21036a8d4198SShunli Wang 	SND_SOC_DAPM_MUX("LOL Mux", SND_SOC_NOPM, 0, 0, &lo_in_mux_control),
21046a8d4198SShunli Wang 
21056a8d4198SShunli Wang 	SND_SOC_DAPM_SUPPLY("LO Stability Enh", MT6358_AUDDEC_ANA_CON7,
21066a8d4198SShunli Wang 			    RG_LOOUTPUTSTBENH_VAUDP15_SFT, 0, NULL, 0),
21076a8d4198SShunli Wang 
21086a8d4198SShunli Wang 	SND_SOC_DAPM_OUT_DRV("LOL Buffer", MT6358_AUDDEC_ANA_CON7,
21096a8d4198SShunli Wang 			     RG_AUDLOLPWRUP_VAUDP15_SFT, 0, NULL, 0),
21106a8d4198SShunli Wang 
21116a8d4198SShunli Wang 	/* Headphone */
21126a8d4198SShunli Wang 	SND_SOC_DAPM_MUX_E("HPL Mux", SND_SOC_NOPM, 0, 0,
21136a8d4198SShunli Wang 			   &hpl_in_mux_control,
21146a8d4198SShunli Wang 			   mt_hp_event,
21156a8d4198SShunli Wang 			   SND_SOC_DAPM_PRE_PMU |
21166a8d4198SShunli Wang 			   SND_SOC_DAPM_PRE_PMD),
21176a8d4198SShunli Wang 
21186a8d4198SShunli Wang 	SND_SOC_DAPM_MUX_E("HPR Mux", SND_SOC_NOPM, 0, 0,
21196a8d4198SShunli Wang 			   &hpr_in_mux_control,
21206a8d4198SShunli Wang 			   mt_hp_event,
21216a8d4198SShunli Wang 			   SND_SOC_DAPM_PRE_PMU |
21226a8d4198SShunli Wang 			   SND_SOC_DAPM_PRE_PMD),
21236a8d4198SShunli Wang 
21246a8d4198SShunli Wang 	/* Receiver */
21256a8d4198SShunli Wang 	SND_SOC_DAPM_MUX_E("RCV Mux", SND_SOC_NOPM, 0, 0,
21266a8d4198SShunli Wang 			   &rcv_in_mux_control,
21276a8d4198SShunli Wang 			   mt_rcv_event,
21286a8d4198SShunli Wang 			   SND_SOC_DAPM_PRE_PMU |
21296a8d4198SShunli Wang 			   SND_SOC_DAPM_PRE_PMD),
21306a8d4198SShunli Wang 
21316a8d4198SShunli Wang 	/* Outputs */
21326a8d4198SShunli Wang 	SND_SOC_DAPM_OUTPUT("Receiver"),
21336a8d4198SShunli Wang 	SND_SOC_DAPM_OUTPUT("Headphone L"),
21346a8d4198SShunli Wang 	SND_SOC_DAPM_OUTPUT("Headphone R"),
21356a8d4198SShunli Wang 	SND_SOC_DAPM_OUTPUT("Headphone L Ext Spk Amp"),
21366a8d4198SShunli Wang 	SND_SOC_DAPM_OUTPUT("Headphone R Ext Spk Amp"),
21376a8d4198SShunli Wang 	SND_SOC_DAPM_OUTPUT("LINEOUT L"),
21386a8d4198SShunli Wang 	SND_SOC_DAPM_OUTPUT("LINEOUT L HSSPK"),
21396a8d4198SShunli Wang 
21406a8d4198SShunli Wang 	/* SGEN */
21416a8d4198SShunli Wang 	SND_SOC_DAPM_SUPPLY("SGEN DL Enable", MT6358_AFE_SGEN_CFG0,
21426a8d4198SShunli Wang 			    SGEN_DAC_EN_CTL_SFT, 0, NULL, 0),
21436a8d4198SShunli Wang 	SND_SOC_DAPM_SUPPLY("SGEN MUTE", MT6358_AFE_SGEN_CFG0,
21446a8d4198SShunli Wang 			    SGEN_MUTE_SW_CTL_SFT, 1,
21456a8d4198SShunli Wang 			    mt_sgen_event,
21466a8d4198SShunli Wang 			    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
21476a8d4198SShunli Wang 	SND_SOC_DAPM_SUPPLY("SGEN DL SRC", MT6358_AFE_DL_SRC2_CON0_L,
21486a8d4198SShunli Wang 			    DL_2_SRC_ON_TMP_CTL_PRE_SFT, 0, NULL, 0),
21496a8d4198SShunli Wang 
21506a8d4198SShunli Wang 	SND_SOC_DAPM_INPUT("SGEN DL"),
21516a8d4198SShunli Wang 
21526a8d4198SShunli Wang 	/* Uplinks */
21536a8d4198SShunli Wang 	SND_SOC_DAPM_AIF_OUT_E("AIF1TX", "AIF1 Capture", 0,
21546a8d4198SShunli Wang 			       SND_SOC_NOPM, 0, 0,
21556a8d4198SShunli Wang 			       mt_aif_out_event,
21566a8d4198SShunli Wang 			       SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
21576a8d4198SShunli Wang 
21586a8d4198SShunli Wang 	SND_SOC_DAPM_SUPPLY_S("ADC Supply", SUPPLY_SEQ_ADC_SUPPLY,
21596a8d4198SShunli Wang 			      SND_SOC_NOPM, 0, 0,
21606a8d4198SShunli Wang 			      mt_adc_supply_event,
21616a8d4198SShunli Wang 			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
21626a8d4198SShunli Wang 
21636a8d4198SShunli Wang 	/* Uplinks MUX */
21646a8d4198SShunli Wang 	SND_SOC_DAPM_MUX("AIF Out Mux", SND_SOC_NOPM, 0, 0,
21656a8d4198SShunli Wang 			 &aif_out_mux_control),
21666a8d4198SShunli Wang 
21676a8d4198SShunli Wang 	SND_SOC_DAPM_MUX_E("Mic Type Mux", SND_SOC_NOPM, 0, 0,
21686a8d4198SShunli Wang 			   &mic_type_mux_control,
21696a8d4198SShunli Wang 			   mt_mic_type_event,
21706a8d4198SShunli Wang 			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD |
21716a8d4198SShunli Wang 			   SND_SOC_DAPM_WILL_PMU),
21726a8d4198SShunli Wang 
21736a8d4198SShunli Wang 	SND_SOC_DAPM_MUX_E("ADC L Mux", SND_SOC_NOPM, 0, 0,
21746a8d4198SShunli Wang 			   &adc_left_mux_control,
21756a8d4198SShunli Wang 			   mt_adc_l_event,
21766a8d4198SShunli Wang 			   SND_SOC_DAPM_WILL_PMU),
21776a8d4198SShunli Wang 	SND_SOC_DAPM_MUX_E("ADC R Mux", SND_SOC_NOPM, 0, 0,
21786a8d4198SShunli Wang 			   &adc_right_mux_control,
21796a8d4198SShunli Wang 			   mt_adc_r_event,
21806a8d4198SShunli Wang 			   SND_SOC_DAPM_WILL_PMU),
21816a8d4198SShunli Wang 
21826a8d4198SShunli Wang 	SND_SOC_DAPM_ADC("ADC L", NULL, SND_SOC_NOPM, 0, 0),
21836a8d4198SShunli Wang 	SND_SOC_DAPM_ADC("ADC R", NULL, SND_SOC_NOPM, 0, 0),
21846a8d4198SShunli Wang 
21856a8d4198SShunli Wang 	SND_SOC_DAPM_MUX_E("PGA L Mux", SND_SOC_NOPM, 0, 0,
21866a8d4198SShunli Wang 			   &pga_left_mux_control,
21876a8d4198SShunli Wang 			   mt_pga_left_event,
21886a8d4198SShunli Wang 			   SND_SOC_DAPM_WILL_PMU),
21896a8d4198SShunli Wang 	SND_SOC_DAPM_MUX_E("PGA R Mux", SND_SOC_NOPM, 0, 0,
21906a8d4198SShunli Wang 			   &pga_right_mux_control,
21916a8d4198SShunli Wang 			   mt_pga_right_event,
21926a8d4198SShunli Wang 			   SND_SOC_DAPM_WILL_PMU),
21936a8d4198SShunli Wang 
21946a8d4198SShunli Wang 	SND_SOC_DAPM_PGA("PGA L", SND_SOC_NOPM, 0, 0, NULL, 0),
21956a8d4198SShunli Wang 	SND_SOC_DAPM_PGA("PGA R", SND_SOC_NOPM, 0, 0, NULL, 0),
21966a8d4198SShunli Wang 
21976a8d4198SShunli Wang 	/* UL input */
21986a8d4198SShunli Wang 	SND_SOC_DAPM_INPUT("AIN0"),
21996a8d4198SShunli Wang 	SND_SOC_DAPM_INPUT("AIN1"),
22006a8d4198SShunli Wang 	SND_SOC_DAPM_INPUT("AIN2"),
22016a8d4198SShunli Wang };
22026a8d4198SShunli Wang 
22036a8d4198SShunli Wang static const struct snd_soc_dapm_route mt6358_dapm_routes[] = {
22046a8d4198SShunli Wang 	/* Capture */
22056a8d4198SShunli Wang 	{"AIF1TX", NULL, "AIF Out Mux"},
22066a8d4198SShunli Wang 	{"AIF1TX", NULL, "CLK_BUF"},
22076a8d4198SShunli Wang 	{"AIF1TX", NULL, "AUDGLB"},
22086a8d4198SShunli Wang 	{"AIF1TX", NULL, "CLKSQ Audio"},
22096a8d4198SShunli Wang 
22106a8d4198SShunli Wang 	{"AIF1TX", NULL, "AUD_CK"},
22116a8d4198SShunli Wang 	{"AIF1TX", NULL, "AUDIF_CK"},
22126a8d4198SShunli Wang 
22136a8d4198SShunli Wang 	{"AIF1TX", NULL, "AUDIO_TOP_AFE_CTL"},
22146a8d4198SShunli Wang 	{"AIF1TX", NULL, "AUDIO_TOP_ADC_CTL"},
22156a8d4198SShunli Wang 	{"AIF1TX", NULL, "AUDIO_TOP_PWR_CLK"},
22166a8d4198SShunli Wang 	{"AIF1TX", NULL, "AUDIO_TOP_PDN_RESERVED"},
22176a8d4198SShunli Wang 	{"AIF1TX", NULL, "AUDIO_TOP_I2S_DL"},
22186a8d4198SShunli Wang 
22196a8d4198SShunli Wang 	{"AIF1TX", NULL, "AFE_ON"},
22206a8d4198SShunli Wang 
22216a8d4198SShunli Wang 	{"AIF Out Mux", NULL, "Mic Type Mux"},
22226a8d4198SShunli Wang 
22236a8d4198SShunli Wang 	{"Mic Type Mux", "ACC", "ADC L"},
22246a8d4198SShunli Wang 	{"Mic Type Mux", "ACC", "ADC R"},
22256a8d4198SShunli Wang 	{"Mic Type Mux", "DCC", "ADC L"},
22266a8d4198SShunli Wang 	{"Mic Type Mux", "DCC", "ADC R"},
22276a8d4198SShunli Wang 	{"Mic Type Mux", "DCC_ECM_DIFF", "ADC L"},
22286a8d4198SShunli Wang 	{"Mic Type Mux", "DCC_ECM_DIFF", "ADC R"},
22296a8d4198SShunli Wang 	{"Mic Type Mux", "DCC_ECM_SINGLE", "ADC L"},
22306a8d4198SShunli Wang 	{"Mic Type Mux", "DCC_ECM_SINGLE", "ADC R"},
22316a8d4198SShunli Wang 	{"Mic Type Mux", "DMIC", "AIN0"},
22326a8d4198SShunli Wang 	{"Mic Type Mux", "DMIC", "AIN2"},
22336a8d4198SShunli Wang 
22346a8d4198SShunli Wang 	{"ADC L", NULL, "ADC L Mux"},
22356a8d4198SShunli Wang 	{"ADC L", NULL, "ADC Supply"},
22366a8d4198SShunli Wang 	{"ADC R", NULL, "ADC R Mux"},
22376a8d4198SShunli Wang 	{"ADC R", NULL, "ADC Supply"},
22386a8d4198SShunli Wang 
22396a8d4198SShunli Wang 	{"ADC L Mux", "Left Preamplifier", "PGA L"},
22406a8d4198SShunli Wang 
22416a8d4198SShunli Wang 	{"ADC R Mux", "Right Preamplifier", "PGA R"},
22426a8d4198SShunli Wang 
22436a8d4198SShunli Wang 	{"PGA L", NULL, "PGA L Mux"},
22446a8d4198SShunli Wang 	{"PGA R", NULL, "PGA R Mux"},
22456a8d4198SShunli Wang 
22466a8d4198SShunli Wang 	{"PGA L Mux", "AIN0", "AIN0"},
22476a8d4198SShunli Wang 	{"PGA L Mux", "AIN1", "AIN1"},
22486a8d4198SShunli Wang 	{"PGA L Mux", "AIN2", "AIN2"},
22496a8d4198SShunli Wang 
22506a8d4198SShunli Wang 	{"PGA R Mux", "AIN0", "AIN0"},
22516a8d4198SShunli Wang 	{"PGA R Mux", "AIN1", "AIN1"},
22526a8d4198SShunli Wang 	{"PGA R Mux", "AIN2", "AIN2"},
22536a8d4198SShunli Wang 
22546a8d4198SShunli Wang 	/* DL Supply */
22556a8d4198SShunli Wang 	{"DL Power Supply", NULL, "CLK_BUF"},
22566a8d4198SShunli Wang 	{"DL Power Supply", NULL, "AUDGLB"},
22576a8d4198SShunli Wang 	{"DL Power Supply", NULL, "CLKSQ Audio"},
22586a8d4198SShunli Wang 
22596a8d4198SShunli Wang 	{"DL Power Supply", NULL, "AUDNCP_CK"},
22606a8d4198SShunli Wang 	{"DL Power Supply", NULL, "ZCD13M_CK"},
22616a8d4198SShunli Wang 	{"DL Power Supply", NULL, "AUD_CK"},
22626a8d4198SShunli Wang 	{"DL Power Supply", NULL, "AUDIF_CK"},
22636a8d4198SShunli Wang 
22646a8d4198SShunli Wang 	/* DL Digital Supply */
22656a8d4198SShunli Wang 	{"DL Digital Clock", NULL, "AUDIO_TOP_AFE_CTL"},
22666a8d4198SShunli Wang 	{"DL Digital Clock", NULL, "AUDIO_TOP_DAC_CTL"},
22676a8d4198SShunli Wang 	{"DL Digital Clock", NULL, "AUDIO_TOP_PWR_CLK"},
22686a8d4198SShunli Wang 
22696a8d4198SShunli Wang 	{"DL Digital Clock", NULL, "AFE_ON"},
22706a8d4198SShunli Wang 
22716a8d4198SShunli Wang 	{"AIF_RX", NULL, "DL Digital Clock"},
22726a8d4198SShunli Wang 
22736a8d4198SShunli Wang 	/* DL Path */
22746a8d4198SShunli Wang 	{"DAC In Mux", "Normal Path", "AIF_RX"},
22756a8d4198SShunli Wang 
22766a8d4198SShunli Wang 	{"DAC In Mux", "Sgen", "SGEN DL"},
22776a8d4198SShunli Wang 	{"SGEN DL", NULL, "SGEN DL SRC"},
22786a8d4198SShunli Wang 	{"SGEN DL", NULL, "SGEN MUTE"},
22796a8d4198SShunli Wang 	{"SGEN DL", NULL, "SGEN DL Enable"},
22806a8d4198SShunli Wang 	{"SGEN DL", NULL, "DL Digital Clock"},
22816a8d4198SShunli Wang 	{"SGEN DL", NULL, "AUDIO_TOP_PDN_AFE_TESTMODEL"},
22826a8d4198SShunli Wang 
22836a8d4198SShunli Wang 	{"DACL", NULL, "DAC In Mux"},
22846a8d4198SShunli Wang 	{"DACL", NULL, "DL Power Supply"},
22856a8d4198SShunli Wang 
22866a8d4198SShunli Wang 	{"DACR", NULL, "DAC In Mux"},
22876a8d4198SShunli Wang 	{"DACR", NULL, "DL Power Supply"},
22886a8d4198SShunli Wang 
22896a8d4198SShunli Wang 	/* Lineout Path */
22906a8d4198SShunli Wang 	{"LOL Mux", "Playback", "DACL"},
22916a8d4198SShunli Wang 
22926a8d4198SShunli Wang 	{"LOL Buffer", NULL, "LOL Mux"},
22936a8d4198SShunli Wang 	{"LOL Buffer", NULL, "LO Stability Enh"},
22946a8d4198SShunli Wang 
22956a8d4198SShunli Wang 	{"LINEOUT L", NULL, "LOL Buffer"},
22966a8d4198SShunli Wang 
22976a8d4198SShunli Wang 	/* Headphone Path */
22986a8d4198SShunli Wang 	{"HPL Mux", "Audio Playback", "DACL"},
22996a8d4198SShunli Wang 	{"HPR Mux", "Audio Playback", "DACR"},
23006a8d4198SShunli Wang 	{"HPL Mux", "HP Impedance", "DACL"},
23016a8d4198SShunli Wang 	{"HPR Mux", "HP Impedance", "DACR"},
23026a8d4198SShunli Wang 	{"HPL Mux", "LoudSPK Playback", "DACL"},
23036a8d4198SShunli Wang 	{"HPR Mux", "LoudSPK Playback", "DACR"},
23046a8d4198SShunli Wang 
23056a8d4198SShunli Wang 	{"Headphone L", NULL, "HPL Mux"},
23066a8d4198SShunli Wang 	{"Headphone R", NULL, "HPR Mux"},
23076a8d4198SShunli Wang 	{"Headphone L Ext Spk Amp", NULL, "HPL Mux"},
23086a8d4198SShunli Wang 	{"Headphone R Ext Spk Amp", NULL, "HPR Mux"},
23096a8d4198SShunli Wang 	{"LINEOUT L HSSPK", NULL, "HPL Mux"},
23106a8d4198SShunli Wang 
23116a8d4198SShunli Wang 	/* Receiver Path */
23126a8d4198SShunli Wang 	{"RCV Mux", "Voice Playback", "DACL"},
23136a8d4198SShunli Wang 	{"Receiver", NULL, "RCV Mux"},
23146a8d4198SShunli Wang };
23156a8d4198SShunli Wang 
mt6358_codec_dai_hw_params(struct snd_pcm_substream * substream,struct snd_pcm_hw_params * params,struct snd_soc_dai * dai)23166a8d4198SShunli Wang static int mt6358_codec_dai_hw_params(struct snd_pcm_substream *substream,
23176a8d4198SShunli Wang 				      struct snd_pcm_hw_params *params,
23186a8d4198SShunli Wang 				      struct snd_soc_dai *dai)
23196a8d4198SShunli Wang {
23206a8d4198SShunli Wang 	struct snd_soc_component *cmpnt = dai->component;
23216a8d4198SShunli Wang 	struct mt6358_priv *priv = snd_soc_component_get_drvdata(cmpnt);
23226a8d4198SShunli Wang 	unsigned int rate = params_rate(params);
23236a8d4198SShunli Wang 
23246a8d4198SShunli Wang 	dev_info(priv->dev, "%s(), substream->stream %d, rate %d, number %d\n",
23256a8d4198SShunli Wang 		 __func__,
23266a8d4198SShunli Wang 		 substream->stream,
23276a8d4198SShunli Wang 		 rate,
23286a8d4198SShunli Wang 		 substream->number);
23296a8d4198SShunli Wang 
23306a8d4198SShunli Wang 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
23316a8d4198SShunli Wang 		priv->dl_rate = rate;
23326a8d4198SShunli Wang 	else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
23336a8d4198SShunli Wang 		priv->ul_rate = rate;
23346a8d4198SShunli Wang 
23356a8d4198SShunli Wang 	return 0;
23366a8d4198SShunli Wang }
23376a8d4198SShunli Wang 
23386a8d4198SShunli Wang static const struct snd_soc_dai_ops mt6358_codec_dai_ops = {
23396a8d4198SShunli Wang 	.hw_params = mt6358_codec_dai_hw_params,
23406a8d4198SShunli Wang };
23416a8d4198SShunli Wang 
2342a5f956e2SCharles Keepax #define MT6358_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_LE |\
2343a5f956e2SCharles Keepax 			SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_U24_LE |\
2344a5f956e2SCharles Keepax 			SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_U32_LE)
23456a8d4198SShunli Wang 
23466a8d4198SShunli Wang static struct snd_soc_dai_driver mt6358_dai_driver[] = {
23476a8d4198SShunli Wang 	{
23486a8d4198SShunli Wang 		.name = "mt6358-snd-codec-aif1",
23496a8d4198SShunli Wang 		.playback = {
23506a8d4198SShunli Wang 			.stream_name = "AIF1 Playback",
23516a8d4198SShunli Wang 			.channels_min = 1,
23526a8d4198SShunli Wang 			.channels_max = 2,
23536a8d4198SShunli Wang 			.rates = SNDRV_PCM_RATE_8000_48000 |
23546a8d4198SShunli Wang 				 SNDRV_PCM_RATE_96000 |
23556a8d4198SShunli Wang 				 SNDRV_PCM_RATE_192000,
23566a8d4198SShunli Wang 			.formats = MT6358_FORMATS,
23576a8d4198SShunli Wang 		},
23586a8d4198SShunli Wang 		.capture = {
23596a8d4198SShunli Wang 			.stream_name = "AIF1 Capture",
23606a8d4198SShunli Wang 			.channels_min = 1,
23616a8d4198SShunli Wang 			.channels_max = 2,
23626a8d4198SShunli Wang 			.rates = SNDRV_PCM_RATE_8000 |
23636a8d4198SShunli Wang 				 SNDRV_PCM_RATE_16000 |
23646a8d4198SShunli Wang 				 SNDRV_PCM_RATE_32000 |
23656a8d4198SShunli Wang 				 SNDRV_PCM_RATE_48000,
23666a8d4198SShunli Wang 			.formats = MT6358_FORMATS,
23676a8d4198SShunli Wang 		},
23686a8d4198SShunli Wang 		.ops = &mt6358_codec_dai_ops,
23696a8d4198SShunli Wang 	},
23706a8d4198SShunli Wang };
23716a8d4198SShunli Wang 
mt6358_codec_init_reg(struct mt6358_priv * priv)23721d3dd532SHariprasad Kelam static void mt6358_codec_init_reg(struct mt6358_priv *priv)
23736a8d4198SShunli Wang {
23746a8d4198SShunli Wang 	/* Disable HeadphoneL/HeadphoneR short circuit protection */
23756a8d4198SShunli Wang 	regmap_update_bits(priv->regmap, MT6358_AUDDEC_ANA_CON0,
23766a8d4198SShunli Wang 			   RG_AUDHPLSCDISABLE_VAUDP15_MASK_SFT,
23776a8d4198SShunli Wang 			   0x1 << RG_AUDHPLSCDISABLE_VAUDP15_SFT);
23786a8d4198SShunli Wang 	regmap_update_bits(priv->regmap, MT6358_AUDDEC_ANA_CON0,
23796a8d4198SShunli Wang 			   RG_AUDHPRSCDISABLE_VAUDP15_MASK_SFT,
23806a8d4198SShunli Wang 			   0x1 << RG_AUDHPRSCDISABLE_VAUDP15_SFT);
23816a8d4198SShunli Wang 	/* Disable voice short circuit protection */
23826a8d4198SShunli Wang 	regmap_update_bits(priv->regmap, MT6358_AUDDEC_ANA_CON6,
23836a8d4198SShunli Wang 			   RG_AUDHSSCDISABLE_VAUDP15_MASK_SFT,
23846a8d4198SShunli Wang 			   0x1 << RG_AUDHSSCDISABLE_VAUDP15_SFT);
23856a8d4198SShunli Wang 	/* disable LO buffer left short circuit protection */
23866a8d4198SShunli Wang 	regmap_update_bits(priv->regmap, MT6358_AUDDEC_ANA_CON7,
23876a8d4198SShunli Wang 			   RG_AUDLOLSCDISABLE_VAUDP15_MASK_SFT,
23886a8d4198SShunli Wang 			   0x1 << RG_AUDLOLSCDISABLE_VAUDP15_SFT);
23896a8d4198SShunli Wang 
23906a8d4198SShunli Wang 	/* accdet s/w enable */
23916a8d4198SShunli Wang 	regmap_update_bits(priv->regmap, MT6358_ACCDET_CON13,
23926a8d4198SShunli Wang 			   0xFFFF, 0x700E);
23936a8d4198SShunli Wang 
23946a8d4198SShunli Wang 	/* gpio miso driving set to 4mA */
23956a8d4198SShunli Wang 	regmap_write(priv->regmap, MT6358_DRV_CON3, 0x8888);
23966a8d4198SShunli Wang 
23976a8d4198SShunli Wang 	/* set gpio */
23986a8d4198SShunli Wang 	playback_gpio_reset(priv);
23996a8d4198SShunli Wang 	capture_gpio_reset(priv);
24006a8d4198SShunli Wang }
24016a8d4198SShunli Wang 
mt6358_codec_probe(struct snd_soc_component * cmpnt)24026a8d4198SShunli Wang static int mt6358_codec_probe(struct snd_soc_component *cmpnt)
24036a8d4198SShunli Wang {
24046a8d4198SShunli Wang 	struct mt6358_priv *priv = snd_soc_component_get_drvdata(cmpnt);
24056a8d4198SShunli Wang 	int ret;
24066a8d4198SShunli Wang 
24076a8d4198SShunli Wang 	snd_soc_component_init_regmap(cmpnt, priv->regmap);
24086a8d4198SShunli Wang 
24096a8d4198SShunli Wang 	mt6358_codec_init_reg(priv);
24106a8d4198SShunli Wang 
24116a8d4198SShunli Wang 	priv->avdd_reg = devm_regulator_get(priv->dev, "Avdd");
24126a8d4198SShunli Wang 	if (IS_ERR(priv->avdd_reg)) {
24136a8d4198SShunli Wang 		dev_err(priv->dev, "%s() have no Avdd supply", __func__);
24146a8d4198SShunli Wang 		return PTR_ERR(priv->avdd_reg);
24156a8d4198SShunli Wang 	}
24166a8d4198SShunli Wang 
24176a8d4198SShunli Wang 	ret = regulator_enable(priv->avdd_reg);
24186a8d4198SShunli Wang 	if (ret)
24196a8d4198SShunli Wang 		return  ret;
24206a8d4198SShunli Wang 
24216a8d4198SShunli Wang 	return 0;
24226a8d4198SShunli Wang }
24236a8d4198SShunli Wang 
24246a8d4198SShunli Wang static const struct snd_soc_component_driver mt6358_soc_component_driver = {
24256a8d4198SShunli Wang 	.probe = mt6358_codec_probe,
24266a8d4198SShunli Wang 	.controls = mt6358_snd_controls,
24276a8d4198SShunli Wang 	.num_controls = ARRAY_SIZE(mt6358_snd_controls),
24286a8d4198SShunli Wang 	.dapm_widgets = mt6358_dapm_widgets,
24296a8d4198SShunli Wang 	.num_dapm_widgets = ARRAY_SIZE(mt6358_dapm_widgets),
24306a8d4198SShunli Wang 	.dapm_routes = mt6358_dapm_routes,
24316a8d4198SShunli Wang 	.num_dapm_routes = ARRAY_SIZE(mt6358_dapm_routes),
2432a5f956e2SCharles Keepax 	.endianness = 1,
24336a8d4198SShunli Wang };
24346a8d4198SShunli Wang 
mt6358_parse_dt(struct mt6358_priv * priv)2435c46fc800SJiaxin Yu static void mt6358_parse_dt(struct mt6358_priv *priv)
2436c46fc800SJiaxin Yu {
2437c46fc800SJiaxin Yu 	int ret;
2438c46fc800SJiaxin Yu 	struct device *dev = priv->dev;
2439c46fc800SJiaxin Yu 
2440c46fc800SJiaxin Yu 	ret = of_property_read_u32(dev->of_node, "mediatek,dmic-mode",
2441c46fc800SJiaxin Yu 				   &priv->dmic_one_wire_mode);
2442c46fc800SJiaxin Yu 	if (ret) {
2443c46fc800SJiaxin Yu 		dev_warn(priv->dev, "%s() failed to read dmic-mode\n",
2444c46fc800SJiaxin Yu 			 __func__);
2445c46fc800SJiaxin Yu 		priv->dmic_one_wire_mode = 0;
2446c46fc800SJiaxin Yu 	}
2447c46fc800SJiaxin Yu }
2448c46fc800SJiaxin Yu 
mt6358_platform_driver_probe(struct platform_device * pdev)24496a8d4198SShunli Wang static int mt6358_platform_driver_probe(struct platform_device *pdev)
24506a8d4198SShunli Wang {
24516a8d4198SShunli Wang 	struct mt6358_priv *priv;
24526a8d4198SShunli Wang 	struct mt6397_chip *mt6397 = dev_get_drvdata(pdev->dev.parent);
24536a8d4198SShunli Wang 
24546a8d4198SShunli Wang 	priv = devm_kzalloc(&pdev->dev,
24556a8d4198SShunli Wang 			    sizeof(struct mt6358_priv),
24566a8d4198SShunli Wang 			    GFP_KERNEL);
24576a8d4198SShunli Wang 	if (!priv)
24586a8d4198SShunli Wang 		return -ENOMEM;
24596a8d4198SShunli Wang 
24606a8d4198SShunli Wang 	dev_set_drvdata(&pdev->dev, priv);
24616a8d4198SShunli Wang 
24626a8d4198SShunli Wang 	priv->dev = &pdev->dev;
24636a8d4198SShunli Wang 
24646a8d4198SShunli Wang 	priv->regmap = mt6397->regmap;
24656a8d4198SShunli Wang 	if (IS_ERR(priv->regmap))
24666a8d4198SShunli Wang 		return PTR_ERR(priv->regmap);
24676a8d4198SShunli Wang 
2468c46fc800SJiaxin Yu 	mt6358_parse_dt(priv);
2469c46fc800SJiaxin Yu 
24706a8d4198SShunli Wang 	dev_info(priv->dev, "%s(), dev name %s\n",
24716a8d4198SShunli Wang 		 __func__, dev_name(&pdev->dev));
24726a8d4198SShunli Wang 
24736a8d4198SShunli Wang 	return devm_snd_soc_register_component(&pdev->dev,
24746a8d4198SShunli Wang 				      &mt6358_soc_component_driver,
24756a8d4198SShunli Wang 				      mt6358_dai_driver,
24766a8d4198SShunli Wang 				      ARRAY_SIZE(mt6358_dai_driver));
24776a8d4198SShunli Wang }
24786a8d4198SShunli Wang 
24796a8d4198SShunli Wang static const struct of_device_id mt6358_of_match[] = {
24806a8d4198SShunli Wang 	{.compatible = "mediatek,mt6358-sound",},
2481612c4695SJiaxin Yu 	{.compatible = "mediatek,mt6366-sound",},
24826a8d4198SShunli Wang 	{}
24836a8d4198SShunli Wang };
24846a8d4198SShunli Wang MODULE_DEVICE_TABLE(of, mt6358_of_match);
24856a8d4198SShunli Wang 
24866a8d4198SShunli Wang static struct platform_driver mt6358_platform_driver = {
24876a8d4198SShunli Wang 	.driver = {
24886a8d4198SShunli Wang 		.name = "mt6358-sound",
24896a8d4198SShunli Wang 		.of_match_table = mt6358_of_match,
24906a8d4198SShunli Wang 	},
24916a8d4198SShunli Wang 	.probe = mt6358_platform_driver_probe,
24926a8d4198SShunli Wang };
24936a8d4198SShunli Wang 
24946a8d4198SShunli Wang module_platform_driver(mt6358_platform_driver)
24956a8d4198SShunli Wang 
24966a8d4198SShunli Wang /* Module information */
24976a8d4198SShunli Wang MODULE_DESCRIPTION("MT6358 ALSA SoC codec driver");
24986a8d4198SShunli Wang MODULE_AUTHOR("KaiChieh Chuang <kaichieh.chuang@mediatek.com>");
24996a8d4198SShunli Wang MODULE_LICENSE("GPL v2");
2500