xref: /openbmc/linux/sound/soc/codecs/rt5670.c (revision 11cce87f)
1d2912cb1SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
25e8351deSBard Liao /*
35e8351deSBard Liao  * rt5670.c  --  RT5670 ALSA SoC audio codec driver
45e8351deSBard Liao  *
55e8351deSBard Liao  * Copyright 2014 Realtek Semiconductor Corp.
65e8351deSBard Liao  * Author: Bard Liao <bardliao@realtek.com>
75e8351deSBard Liao  */
85e8351deSBard Liao 
95e8351deSBard Liao #include <linux/module.h>
105e8351deSBard Liao #include <linux/moduleparam.h>
115e8351deSBard Liao #include <linux/init.h>
125e8351deSBard Liao #include <linux/delay.h>
135e8351deSBard Liao #include <linux/pm.h>
1464e89e5fSBard Liao #include <linux/pm_runtime.h>
155e8351deSBard Liao #include <linux/i2c.h>
165e8351deSBard Liao #include <linux/platform_device.h>
170605815eSMengdong Lin #include <linux/acpi.h>
185e8351deSBard Liao #include <linux/spi/spi.h>
19223c055aSBard Liao #include <linux/dmi.h>
205e8351deSBard Liao #include <sound/core.h>
215e8351deSBard Liao #include <sound/pcm.h>
225e8351deSBard Liao #include <sound/pcm_params.h>
235e8351deSBard Liao #include <sound/jack.h>
245e8351deSBard Liao #include <sound/soc.h>
255e8351deSBard Liao #include <sound/soc-dapm.h>
265e8351deSBard Liao #include <sound/initval.h>
275e8351deSBard Liao #include <sound/tlv.h>
285e8351deSBard Liao 
295e8351deSBard Liao #include "rl6231.h"
305e8351deSBard Liao #include "rt5670.h"
315e8351deSBard Liao #include "rt5670-dsp.h"
325e8351deSBard Liao 
33883330c1SHans de Goede #define RT5670_GPIO1_IS_IRQ			BIT(0)
348e1b1785SPierre-Louis Bossart #define RT5670_IN2_DIFF			BIT(1)
358e1b1785SPierre-Louis Bossart #define RT5670_DMIC_EN			BIT(2)
368e1b1785SPierre-Louis Bossart #define RT5670_DMIC1_IN2P		BIT(3)
378e1b1785SPierre-Louis Bossart #define RT5670_DMIC1_GPIO6		BIT(4)
388e1b1785SPierre-Louis Bossart #define RT5670_DMIC1_GPIO7		BIT(5)
398e1b1785SPierre-Louis Bossart #define RT5670_DMIC2_INR		BIT(6)
408e1b1785SPierre-Louis Bossart #define RT5670_DMIC2_GPIO8		BIT(7)
418e1b1785SPierre-Louis Bossart #define RT5670_DMIC3_GPIO5		BIT(8)
428e1b1785SPierre-Louis Bossart #define RT5670_JD_MODE1			BIT(9)
438e1b1785SPierre-Louis Bossart #define RT5670_JD_MODE2			BIT(10)
448e1b1785SPierre-Louis Bossart #define RT5670_JD_MODE3			BIT(11)
4585ca6b17SHans de Goede #define RT5670_GPIO1_IS_EXT_SPK_EN	BIT(12)
468e1b1785SPierre-Louis Bossart 
478e1b1785SPierre-Louis Bossart static unsigned long rt5670_quirk;
488e1b1785SPierre-Louis Bossart static unsigned int quirk_override;
498e1b1785SPierre-Louis Bossart module_param_named(quirk, quirk_override, uint, 0444);
508e1b1785SPierre-Louis Bossart MODULE_PARM_DESC(quirk, "Board-specific quirk override");
518e1b1785SPierre-Louis Bossart 
525e8351deSBard Liao #define RT5670_DEVICE_ID 0x6271
535e8351deSBard Liao 
545e8351deSBard Liao #define RT5670_PR_RANGE_BASE (0xff + 1)
555e8351deSBard Liao #define RT5670_PR_SPACING 0x100
565e8351deSBard Liao 
575e8351deSBard Liao #define RT5670_PR_BASE (RT5670_PR_RANGE_BASE + (0 * RT5670_PR_SPACING))
585e8351deSBard Liao 
595e8351deSBard Liao static const struct regmap_range_cfg rt5670_ranges[] = {
605e8351deSBard Liao 	{ .name = "PR", .range_min = RT5670_PR_BASE,
615e8351deSBard Liao 	  .range_max = RT5670_PR_BASE + 0xf8,
625e8351deSBard Liao 	  .selector_reg = RT5670_PRIV_INDEX,
635e8351deSBard Liao 	  .selector_mask = 0xff,
645e8351deSBard Liao 	  .selector_shift = 0x0,
655e8351deSBard Liao 	  .window_start = RT5670_PRIV_DATA,
665e8351deSBard Liao 	  .window_len = 0x1, },
675e8351deSBard Liao };
685e8351deSBard Liao 
698019ff6cSNariman Poushin static const struct reg_sequence init_list[] = {
705e8351deSBard Liao 	{ RT5670_PR_BASE + 0x14, 0x9a8a },
7181dd1c5dSBard Liao 	{ RT5670_PR_BASE + 0x38, 0x1fe1 },
725e8351deSBard Liao 	{ RT5670_PR_BASE + 0x3d, 0x3640 },
73874352a7SBard Liao 	{ 0x8a, 0x0123 },
745e8351deSBard Liao };
755e8351deSBard Liao 
765e8351deSBard Liao static const struct reg_default rt5670_reg[] = {
775e8351deSBard Liao 	{ 0x00, 0x0000 },
785e8351deSBard Liao 	{ 0x02, 0x8888 },
795e8351deSBard Liao 	{ 0x03, 0x8888 },
805e8351deSBard Liao 	{ 0x0a, 0x0001 },
815e8351deSBard Liao 	{ 0x0b, 0x0827 },
825e8351deSBard Liao 	{ 0x0c, 0x0000 },
835e8351deSBard Liao 	{ 0x0d, 0x0008 },
845e8351deSBard Liao 	{ 0x0e, 0x0000 },
855e8351deSBard Liao 	{ 0x0f, 0x0808 },
865e8351deSBard Liao 	{ 0x19, 0xafaf },
875e8351deSBard Liao 	{ 0x1a, 0xafaf },
885e8351deSBard Liao 	{ 0x1b, 0x0011 },
895e8351deSBard Liao 	{ 0x1c, 0x2f2f },
905e8351deSBard Liao 	{ 0x1d, 0x2f2f },
915e8351deSBard Liao 	{ 0x1e, 0x0000 },
925e8351deSBard Liao 	{ 0x1f, 0x2f2f },
935e8351deSBard Liao 	{ 0x20, 0x0000 },
945e8351deSBard Liao 	{ 0x26, 0x7860 },
955e8351deSBard Liao 	{ 0x27, 0x7860 },
965e8351deSBard Liao 	{ 0x28, 0x7871 },
975e8351deSBard Liao 	{ 0x29, 0x8080 },
985e8351deSBard Liao 	{ 0x2a, 0x5656 },
995e8351deSBard Liao 	{ 0x2b, 0x5454 },
1005e8351deSBard Liao 	{ 0x2c, 0xaaa0 },
1015e8351deSBard Liao 	{ 0x2d, 0x0000 },
1025e8351deSBard Liao 	{ 0x2e, 0x2f2f },
1035e8351deSBard Liao 	{ 0x2f, 0x1002 },
1045e8351deSBard Liao 	{ 0x30, 0x0000 },
1055e8351deSBard Liao 	{ 0x31, 0x5f00 },
1065e8351deSBard Liao 	{ 0x32, 0x0000 },
1075e8351deSBard Liao 	{ 0x33, 0x0000 },
1085e8351deSBard Liao 	{ 0x34, 0x0000 },
1095e8351deSBard Liao 	{ 0x35, 0x0000 },
1105e8351deSBard Liao 	{ 0x36, 0x0000 },
1115e8351deSBard Liao 	{ 0x37, 0x0000 },
1125e8351deSBard Liao 	{ 0x38, 0x0000 },
1135e8351deSBard Liao 	{ 0x3b, 0x0000 },
1145e8351deSBard Liao 	{ 0x3c, 0x007f },
1155e8351deSBard Liao 	{ 0x3d, 0x0000 },
1165e8351deSBard Liao 	{ 0x3e, 0x007f },
1175e8351deSBard Liao 	{ 0x45, 0xe00f },
1185e8351deSBard Liao 	{ 0x4c, 0x5380 },
1195e8351deSBard Liao 	{ 0x4f, 0x0073 },
1205e8351deSBard Liao 	{ 0x52, 0x00d3 },
121ac87f221SBard Liao 	{ 0x53, 0xf000 },
1225e8351deSBard Liao 	{ 0x61, 0x0000 },
1235e8351deSBard Liao 	{ 0x62, 0x0001 },
1245e8351deSBard Liao 	{ 0x63, 0x00c3 },
1255e8351deSBard Liao 	{ 0x64, 0x0000 },
126ac87f221SBard Liao 	{ 0x65, 0x0001 },
1275e8351deSBard Liao 	{ 0x66, 0x0000 },
1285e8351deSBard Liao 	{ 0x6f, 0x8000 },
1295e8351deSBard Liao 	{ 0x70, 0x8000 },
1305e8351deSBard Liao 	{ 0x71, 0x8000 },
1315e8351deSBard Liao 	{ 0x72, 0x8000 },
132ac87f221SBard Liao 	{ 0x73, 0x7770 },
1335e8351deSBard Liao 	{ 0x74, 0x0e00 },
1345e8351deSBard Liao 	{ 0x75, 0x1505 },
1355e8351deSBard Liao 	{ 0x76, 0x0015 },
1365e8351deSBard Liao 	{ 0x77, 0x0c00 },
1375e8351deSBard Liao 	{ 0x78, 0x4000 },
1385e8351deSBard Liao 	{ 0x79, 0x0123 },
1395e8351deSBard Liao 	{ 0x7f, 0x1100 },
1405e8351deSBard Liao 	{ 0x80, 0x0000 },
1415e8351deSBard Liao 	{ 0x81, 0x0000 },
1425e8351deSBard Liao 	{ 0x82, 0x0000 },
1435e8351deSBard Liao 	{ 0x83, 0x0000 },
1445e8351deSBard Liao 	{ 0x84, 0x0000 },
1455e8351deSBard Liao 	{ 0x85, 0x0000 },
146ac87f221SBard Liao 	{ 0x86, 0x0004 },
1475e8351deSBard Liao 	{ 0x87, 0x0000 },
1485e8351deSBard Liao 	{ 0x88, 0x0000 },
1495e8351deSBard Liao 	{ 0x89, 0x0000 },
150874352a7SBard Liao 	{ 0x8a, 0x0123 },
1515e8351deSBard Liao 	{ 0x8b, 0x0000 },
152ac87f221SBard Liao 	{ 0x8c, 0x0003 },
1535e8351deSBard Liao 	{ 0x8d, 0x0000 },
1545e8351deSBard Liao 	{ 0x8e, 0x0004 },
1555e8351deSBard Liao 	{ 0x8f, 0x1100 },
1565e8351deSBard Liao 	{ 0x90, 0x0646 },
1575e8351deSBard Liao 	{ 0x91, 0x0c06 },
1585e8351deSBard Liao 	{ 0x93, 0x0000 },
159ac87f221SBard Liao 	{ 0x94, 0x1270 },
160ac87f221SBard Liao 	{ 0x95, 0x1000 },
1615e8351deSBard Liao 	{ 0x97, 0x0000 },
1625e8351deSBard Liao 	{ 0x98, 0x0000 },
1635e8351deSBard Liao 	{ 0x99, 0x0000 },
1645e8351deSBard Liao 	{ 0x9a, 0x2184 },
1655e8351deSBard Liao 	{ 0x9b, 0x010a },
1665e8351deSBard Liao 	{ 0x9c, 0x0aea },
1675e8351deSBard Liao 	{ 0x9d, 0x000c },
1685e8351deSBard Liao 	{ 0x9e, 0x0400 },
1695e8351deSBard Liao 	{ 0xae, 0x7000 },
1705e8351deSBard Liao 	{ 0xaf, 0x0000 },
171ac87f221SBard Liao 	{ 0xb0, 0x7000 },
1725e8351deSBard Liao 	{ 0xb1, 0x0000 },
1735e8351deSBard Liao 	{ 0xb2, 0x0000 },
1745e8351deSBard Liao 	{ 0xb3, 0x001f },
175ac87f221SBard Liao 	{ 0xb4, 0x220c },
1765e8351deSBard Liao 	{ 0xb5, 0x1f00 },
1775e8351deSBard Liao 	{ 0xb6, 0x0000 },
1785e8351deSBard Liao 	{ 0xb7, 0x0000 },
1795e8351deSBard Liao 	{ 0xbb, 0x0000 },
1805e8351deSBard Liao 	{ 0xbc, 0x0000 },
1815e8351deSBard Liao 	{ 0xbd, 0x0000 },
1825e8351deSBard Liao 	{ 0xbe, 0x0000 },
1835e8351deSBard Liao 	{ 0xbf, 0x0000 },
1845e8351deSBard Liao 	{ 0xc0, 0x0000 },
1855e8351deSBard Liao 	{ 0xc1, 0x0000 },
1865e8351deSBard Liao 	{ 0xc2, 0x0000 },
1875e8351deSBard Liao 	{ 0xcd, 0x0000 },
1885e8351deSBard Liao 	{ 0xce, 0x0000 },
1895e8351deSBard Liao 	{ 0xcf, 0x1813 },
1905e8351deSBard Liao 	{ 0xd0, 0x0690 },
1915e8351deSBard Liao 	{ 0xd1, 0x1c17 },
192ac87f221SBard Liao 	{ 0xd3, 0xa220 },
1935e8351deSBard Liao 	{ 0xd4, 0x0000 },
1945e8351deSBard Liao 	{ 0xd6, 0x0400 },
1955e8351deSBard Liao 	{ 0xd9, 0x0809 },
1965e8351deSBard Liao 	{ 0xda, 0x0000 },
1975e8351deSBard Liao 	{ 0xdb, 0x0001 },
1985e8351deSBard Liao 	{ 0xdc, 0x0049 },
199ac87f221SBard Liao 	{ 0xdd, 0x0024 },
2005e8351deSBard Liao 	{ 0xe6, 0x8000 },
2015e8351deSBard Liao 	{ 0xe7, 0x0000 },
202ac87f221SBard Liao 	{ 0xec, 0xa200 },
2035e8351deSBard Liao 	{ 0xed, 0x0000 },
204ac87f221SBard Liao 	{ 0xee, 0xa200 },
2055e8351deSBard Liao 	{ 0xef, 0x0000 },
2065e8351deSBard Liao 	{ 0xf8, 0x0000 },
2075e8351deSBard Liao 	{ 0xf9, 0x0000 },
2085e8351deSBard Liao 	{ 0xfa, 0x8010 },
2095e8351deSBard Liao 	{ 0xfb, 0x0033 },
210ac87f221SBard Liao 	{ 0xfc, 0x0100 },
2115e8351deSBard Liao };
2125e8351deSBard Liao 
rt5670_volatile_register(struct device * dev,unsigned int reg)2135e8351deSBard Liao static bool rt5670_volatile_register(struct device *dev, unsigned int reg)
2145e8351deSBard Liao {
2155e8351deSBard Liao 	int i;
2165e8351deSBard Liao 
2175e8351deSBard Liao 	for (i = 0; i < ARRAY_SIZE(rt5670_ranges); i++) {
2185e8351deSBard Liao 		if ((reg >= rt5670_ranges[i].window_start &&
2195e8351deSBard Liao 		     reg <= rt5670_ranges[i].window_start +
2205e8351deSBard Liao 		     rt5670_ranges[i].window_len) ||
2215e8351deSBard Liao 		    (reg >= rt5670_ranges[i].range_min &&
2225e8351deSBard Liao 		     reg <= rt5670_ranges[i].range_max)) {
2235e8351deSBard Liao 			return true;
2245e8351deSBard Liao 		}
2255e8351deSBard Liao 	}
2265e8351deSBard Liao 
2275e8351deSBard Liao 	switch (reg) {
2285e8351deSBard Liao 	case RT5670_RESET:
2295e8351deSBard Liao 	case RT5670_PDM_DATA_CTRL1:
2305e8351deSBard Liao 	case RT5670_PDM1_DATA_CTRL4:
2315e8351deSBard Liao 	case RT5670_PDM2_DATA_CTRL4:
2325e8351deSBard Liao 	case RT5670_PRIV_DATA:
2335e8351deSBard Liao 	case RT5670_ASRC_5:
2345e8351deSBard Liao 	case RT5670_CJ_CTRL1:
2355e8351deSBard Liao 	case RT5670_CJ_CTRL2:
2365e8351deSBard Liao 	case RT5670_CJ_CTRL3:
2375e8351deSBard Liao 	case RT5670_A_JD_CTRL1:
2385e8351deSBard Liao 	case RT5670_A_JD_CTRL2:
2395e8351deSBard Liao 	case RT5670_VAD_CTRL5:
2405e8351deSBard Liao 	case RT5670_ADC_EQ_CTRL1:
2415e8351deSBard Liao 	case RT5670_EQ_CTRL1:
2425e8351deSBard Liao 	case RT5670_ALC_CTRL_1:
2435e8351deSBard Liao 	case RT5670_IRQ_CTRL2:
2445e8351deSBard Liao 	case RT5670_INT_IRQ_ST:
2455e8351deSBard Liao 	case RT5670_IL_CMD:
2465e8351deSBard Liao 	case RT5670_DSP_CTRL1:
2475e8351deSBard Liao 	case RT5670_DSP_CTRL2:
2485e8351deSBard Liao 	case RT5670_DSP_CTRL3:
2495e8351deSBard Liao 	case RT5670_DSP_CTRL4:
2505e8351deSBard Liao 	case RT5670_DSP_CTRL5:
2515e8351deSBard Liao 	case RT5670_VENDOR_ID:
2525e8351deSBard Liao 	case RT5670_VENDOR_ID1:
2535e8351deSBard Liao 	case RT5670_VENDOR_ID2:
2545e8351deSBard Liao 		return true;
2555e8351deSBard Liao 	default:
2565e8351deSBard Liao 		return false;
2575e8351deSBard Liao 	}
2585e8351deSBard Liao }
2595e8351deSBard Liao 
rt5670_readable_register(struct device * dev,unsigned int reg)2605e8351deSBard Liao static bool rt5670_readable_register(struct device *dev, unsigned int reg)
2615e8351deSBard Liao {
2625e8351deSBard Liao 	int i;
2635e8351deSBard Liao 
2645e8351deSBard Liao 	for (i = 0; i < ARRAY_SIZE(rt5670_ranges); i++) {
2655e8351deSBard Liao 		if ((reg >= rt5670_ranges[i].window_start &&
2665e8351deSBard Liao 		     reg <= rt5670_ranges[i].window_start +
2675e8351deSBard Liao 		     rt5670_ranges[i].window_len) ||
2685e8351deSBard Liao 		    (reg >= rt5670_ranges[i].range_min &&
2695e8351deSBard Liao 		     reg <= rt5670_ranges[i].range_max)) {
2705e8351deSBard Liao 			return true;
2715e8351deSBard Liao 		}
2725e8351deSBard Liao 	}
2735e8351deSBard Liao 
2745e8351deSBard Liao 	switch (reg) {
2755e8351deSBard Liao 	case RT5670_RESET:
2765e8351deSBard Liao 	case RT5670_HP_VOL:
2775e8351deSBard Liao 	case RT5670_LOUT1:
2785e8351deSBard Liao 	case RT5670_CJ_CTRL1:
2795e8351deSBard Liao 	case RT5670_CJ_CTRL2:
2805e8351deSBard Liao 	case RT5670_CJ_CTRL3:
2815e8351deSBard Liao 	case RT5670_IN2:
2825e8351deSBard Liao 	case RT5670_INL1_INR1_VOL:
2835e8351deSBard Liao 	case RT5670_DAC1_DIG_VOL:
2845e8351deSBard Liao 	case RT5670_DAC2_DIG_VOL:
2855e8351deSBard Liao 	case RT5670_DAC_CTRL:
2865e8351deSBard Liao 	case RT5670_STO1_ADC_DIG_VOL:
2875e8351deSBard Liao 	case RT5670_MONO_ADC_DIG_VOL:
2885e8351deSBard Liao 	case RT5670_STO2_ADC_DIG_VOL:
2895e8351deSBard Liao 	case RT5670_ADC_BST_VOL1:
2905e8351deSBard Liao 	case RT5670_ADC_BST_VOL2:
2915e8351deSBard Liao 	case RT5670_STO2_ADC_MIXER:
2925e8351deSBard Liao 	case RT5670_STO1_ADC_MIXER:
2935e8351deSBard Liao 	case RT5670_MONO_ADC_MIXER:
2945e8351deSBard Liao 	case RT5670_AD_DA_MIXER:
2955e8351deSBard Liao 	case RT5670_STO_DAC_MIXER:
2965e8351deSBard Liao 	case RT5670_DD_MIXER:
2975e8351deSBard Liao 	case RT5670_DIG_MIXER:
2985e8351deSBard Liao 	case RT5670_DSP_PATH1:
2995e8351deSBard Liao 	case RT5670_DSP_PATH2:
3005e8351deSBard Liao 	case RT5670_DIG_INF1_DATA:
3015e8351deSBard Liao 	case RT5670_DIG_INF2_DATA:
3025e8351deSBard Liao 	case RT5670_PDM_OUT_CTRL:
3035e8351deSBard Liao 	case RT5670_PDM_DATA_CTRL1:
3045e8351deSBard Liao 	case RT5670_PDM1_DATA_CTRL2:
3055e8351deSBard Liao 	case RT5670_PDM1_DATA_CTRL3:
3065e8351deSBard Liao 	case RT5670_PDM1_DATA_CTRL4:
3075e8351deSBard Liao 	case RT5670_PDM2_DATA_CTRL2:
3085e8351deSBard Liao 	case RT5670_PDM2_DATA_CTRL3:
3095e8351deSBard Liao 	case RT5670_PDM2_DATA_CTRL4:
3105e8351deSBard Liao 	case RT5670_REC_L1_MIXER:
3115e8351deSBard Liao 	case RT5670_REC_L2_MIXER:
3125e8351deSBard Liao 	case RT5670_REC_R1_MIXER:
3135e8351deSBard Liao 	case RT5670_REC_R2_MIXER:
3145e8351deSBard Liao 	case RT5670_HPO_MIXER:
3155e8351deSBard Liao 	case RT5670_MONO_MIXER:
3165e8351deSBard Liao 	case RT5670_OUT_L1_MIXER:
3175e8351deSBard Liao 	case RT5670_OUT_R1_MIXER:
3185e8351deSBard Liao 	case RT5670_LOUT_MIXER:
3195e8351deSBard Liao 	case RT5670_PWR_DIG1:
3205e8351deSBard Liao 	case RT5670_PWR_DIG2:
3215e8351deSBard Liao 	case RT5670_PWR_ANLG1:
3225e8351deSBard Liao 	case RT5670_PWR_ANLG2:
3235e8351deSBard Liao 	case RT5670_PWR_MIXER:
3245e8351deSBard Liao 	case RT5670_PWR_VOL:
3255e8351deSBard Liao 	case RT5670_PRIV_INDEX:
3265e8351deSBard Liao 	case RT5670_PRIV_DATA:
3275e8351deSBard Liao 	case RT5670_I2S4_SDP:
3285e8351deSBard Liao 	case RT5670_I2S1_SDP:
3295e8351deSBard Liao 	case RT5670_I2S2_SDP:
3305e8351deSBard Liao 	case RT5670_I2S3_SDP:
3315e8351deSBard Liao 	case RT5670_ADDA_CLK1:
3325e8351deSBard Liao 	case RT5670_ADDA_CLK2:
3335e8351deSBard Liao 	case RT5670_DMIC_CTRL1:
3345e8351deSBard Liao 	case RT5670_DMIC_CTRL2:
3355e8351deSBard Liao 	case RT5670_TDM_CTRL_1:
3365e8351deSBard Liao 	case RT5670_TDM_CTRL_2:
3375e8351deSBard Liao 	case RT5670_TDM_CTRL_3:
3385e8351deSBard Liao 	case RT5670_DSP_CLK:
3395e8351deSBard Liao 	case RT5670_GLB_CLK:
3405e8351deSBard Liao 	case RT5670_PLL_CTRL1:
3415e8351deSBard Liao 	case RT5670_PLL_CTRL2:
3425e8351deSBard Liao 	case RT5670_ASRC_1:
3435e8351deSBard Liao 	case RT5670_ASRC_2:
3445e8351deSBard Liao 	case RT5670_ASRC_3:
3455e8351deSBard Liao 	case RT5670_ASRC_4:
3465e8351deSBard Liao 	case RT5670_ASRC_5:
3475e8351deSBard Liao 	case RT5670_ASRC_7:
3485e8351deSBard Liao 	case RT5670_ASRC_8:
3495e8351deSBard Liao 	case RT5670_ASRC_9:
3505e8351deSBard Liao 	case RT5670_ASRC_10:
3515e8351deSBard Liao 	case RT5670_ASRC_11:
3525e8351deSBard Liao 	case RT5670_ASRC_12:
3535e8351deSBard Liao 	case RT5670_ASRC_13:
3545e8351deSBard Liao 	case RT5670_ASRC_14:
3555e8351deSBard Liao 	case RT5670_DEPOP_M1:
3565e8351deSBard Liao 	case RT5670_DEPOP_M2:
3575e8351deSBard Liao 	case RT5670_DEPOP_M3:
3585e8351deSBard Liao 	case RT5670_CHARGE_PUMP:
3595e8351deSBard Liao 	case RT5670_MICBIAS:
3605e8351deSBard Liao 	case RT5670_A_JD_CTRL1:
3615e8351deSBard Liao 	case RT5670_A_JD_CTRL2:
3625e8351deSBard Liao 	case RT5670_VAD_CTRL1:
3635e8351deSBard Liao 	case RT5670_VAD_CTRL2:
3645e8351deSBard Liao 	case RT5670_VAD_CTRL3:
3655e8351deSBard Liao 	case RT5670_VAD_CTRL4:
3665e8351deSBard Liao 	case RT5670_VAD_CTRL5:
3675e8351deSBard Liao 	case RT5670_ADC_EQ_CTRL1:
3685e8351deSBard Liao 	case RT5670_ADC_EQ_CTRL2:
3695e8351deSBard Liao 	case RT5670_EQ_CTRL1:
3705e8351deSBard Liao 	case RT5670_EQ_CTRL2:
3715e8351deSBard Liao 	case RT5670_ALC_DRC_CTRL1:
3725e8351deSBard Liao 	case RT5670_ALC_DRC_CTRL2:
3735e8351deSBard Liao 	case RT5670_ALC_CTRL_1:
3745e8351deSBard Liao 	case RT5670_ALC_CTRL_2:
3755e8351deSBard Liao 	case RT5670_ALC_CTRL_3:
3765e8351deSBard Liao 	case RT5670_JD_CTRL:
3775e8351deSBard Liao 	case RT5670_IRQ_CTRL1:
3785e8351deSBard Liao 	case RT5670_IRQ_CTRL2:
3795e8351deSBard Liao 	case RT5670_INT_IRQ_ST:
3805e8351deSBard Liao 	case RT5670_GPIO_CTRL1:
3815e8351deSBard Liao 	case RT5670_GPIO_CTRL2:
3825e8351deSBard Liao 	case RT5670_GPIO_CTRL3:
3835e8351deSBard Liao 	case RT5670_SCRABBLE_FUN:
3845e8351deSBard Liao 	case RT5670_SCRABBLE_CTRL:
3855e8351deSBard Liao 	case RT5670_BASE_BACK:
3865e8351deSBard Liao 	case RT5670_MP3_PLUS1:
3875e8351deSBard Liao 	case RT5670_MP3_PLUS2:
3885e8351deSBard Liao 	case RT5670_ADJ_HPF1:
3895e8351deSBard Liao 	case RT5670_ADJ_HPF2:
3905e8351deSBard Liao 	case RT5670_HP_CALIB_AMP_DET:
3915e8351deSBard Liao 	case RT5670_SV_ZCD1:
3925e8351deSBard Liao 	case RT5670_SV_ZCD2:
3935e8351deSBard Liao 	case RT5670_IL_CMD:
3945e8351deSBard Liao 	case RT5670_IL_CMD2:
3955e8351deSBard Liao 	case RT5670_IL_CMD3:
3965e8351deSBard Liao 	case RT5670_DRC_HL_CTRL1:
3975e8351deSBard Liao 	case RT5670_DRC_HL_CTRL2:
3985e8351deSBard Liao 	case RT5670_ADC_MONO_HP_CTRL1:
3995e8351deSBard Liao 	case RT5670_ADC_MONO_HP_CTRL2:
4005e8351deSBard Liao 	case RT5670_ADC_STO2_HP_CTRL1:
4015e8351deSBard Liao 	case RT5670_ADC_STO2_HP_CTRL2:
4025e8351deSBard Liao 	case RT5670_JD_CTRL3:
4035e8351deSBard Liao 	case RT5670_JD_CTRL4:
4045e8351deSBard Liao 	case RT5670_DIG_MISC:
4055e8351deSBard Liao 	case RT5670_DSP_CTRL1:
4065e8351deSBard Liao 	case RT5670_DSP_CTRL2:
4075e8351deSBard Liao 	case RT5670_DSP_CTRL3:
4085e8351deSBard Liao 	case RT5670_DSP_CTRL4:
4095e8351deSBard Liao 	case RT5670_DSP_CTRL5:
4105e8351deSBard Liao 	case RT5670_GEN_CTRL2:
4115e8351deSBard Liao 	case RT5670_GEN_CTRL3:
4125e8351deSBard Liao 	case RT5670_VENDOR_ID:
4135e8351deSBard Liao 	case RT5670_VENDOR_ID1:
4145e8351deSBard Liao 	case RT5670_VENDOR_ID2:
4155e8351deSBard Liao 		return true;
4165e8351deSBard Liao 	default:
4175e8351deSBard Liao 		return false;
4185e8351deSBard Liao 	}
4195e8351deSBard Liao }
4205e8351deSBard Liao 
421d3ef7054SBard Liao /**
422d3ef7054SBard Liao  * rt5670_headset_detect - Detect headset.
4235ba04c66SKuninori Morimoto  * @component: SoC audio component device.
424d3ef7054SBard Liao  * @jack_insert: Jack insert or not.
425d3ef7054SBard Liao  *
426d3ef7054SBard Liao  * Detect whether is headset or not when jack inserted.
427d3ef7054SBard Liao  *
428d3ef7054SBard Liao  * Returns detect status.
429d3ef7054SBard Liao  */
430d3ef7054SBard Liao 
rt5670_headset_detect(struct snd_soc_component * component,int jack_insert)4315ba04c66SKuninori Morimoto static int rt5670_headset_detect(struct snd_soc_component *component, int jack_insert)
432d3ef7054SBard Liao {
433d3ef7054SBard Liao 	int val;
4345ba04c66SKuninori Morimoto 	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
4355ba04c66SKuninori Morimoto 	struct rt5670_priv *rt5670 = snd_soc_component_get_drvdata(component);
436d3ef7054SBard Liao 
437d3ef7054SBard Liao 	if (jack_insert) {
4386d8135ffSLars-Peter Clausen 		snd_soc_dapm_force_enable_pin(dapm, "Mic Det Power");
4396d8135ffSLars-Peter Clausen 		snd_soc_dapm_sync(dapm);
4405ba04c66SKuninori Morimoto 		snd_soc_component_update_bits(component, RT5670_GEN_CTRL3, 0x4, 0x0);
4415ba04c66SKuninori Morimoto 		snd_soc_component_update_bits(component, RT5670_CJ_CTRL2,
442d3ef7054SBard Liao 			RT5670_CBJ_DET_MODE | RT5670_CBJ_MN_JD,
443d3ef7054SBard Liao 			RT5670_CBJ_MN_JD);
4445ba04c66SKuninori Morimoto 		snd_soc_component_write(component, RT5670_GPIO_CTRL2, 0x0004);
4455ba04c66SKuninori Morimoto 		snd_soc_component_update_bits(component, RT5670_GPIO_CTRL1,
446d3ef7054SBard Liao 			RT5670_GP1_PIN_MASK, RT5670_GP1_PIN_IRQ);
4475ba04c66SKuninori Morimoto 		snd_soc_component_update_bits(component, RT5670_CJ_CTRL1,
448d3ef7054SBard Liao 			RT5670_CBJ_BST1_EN, RT5670_CBJ_BST1_EN);
4495ba04c66SKuninori Morimoto 		snd_soc_component_write(component, RT5670_JD_CTRL3, 0x00f0);
4505ba04c66SKuninori Morimoto 		snd_soc_component_update_bits(component, RT5670_CJ_CTRL2,
451d3ef7054SBard Liao 			RT5670_CBJ_MN_JD, RT5670_CBJ_MN_JD);
4525ba04c66SKuninori Morimoto 		snd_soc_component_update_bits(component, RT5670_CJ_CTRL2,
453d3ef7054SBard Liao 			RT5670_CBJ_MN_JD, 0);
454d3ef7054SBard Liao 		msleep(300);
455467a2553SKuninori Morimoto 		val = snd_soc_component_read(component, RT5670_CJ_CTRL3) & 0x7;
456d3ef7054SBard Liao 		if (val == 0x1 || val == 0x2) {
457d3ef7054SBard Liao 			rt5670->jack_type = SND_JACK_HEADSET;
458d3ef7054SBard Liao 			/* for push button */
4595ba04c66SKuninori Morimoto 			snd_soc_component_update_bits(component, RT5670_INT_IRQ_ST, 0x8, 0x8);
4605ba04c66SKuninori Morimoto 			snd_soc_component_update_bits(component, RT5670_IL_CMD, 0x40, 0x40);
461467a2553SKuninori Morimoto 			snd_soc_component_read(component, RT5670_IL_CMD);
462d3ef7054SBard Liao 		} else {
4635ba04c66SKuninori Morimoto 			snd_soc_component_update_bits(component, RT5670_GEN_CTRL3, 0x4, 0x4);
464d3ef7054SBard Liao 			rt5670->jack_type = SND_JACK_HEADPHONE;
4656d8135ffSLars-Peter Clausen 			snd_soc_dapm_disable_pin(dapm, "Mic Det Power");
4666d8135ffSLars-Peter Clausen 			snd_soc_dapm_sync(dapm);
467d3ef7054SBard Liao 		}
468d3ef7054SBard Liao 	} else {
4695ba04c66SKuninori Morimoto 		snd_soc_component_update_bits(component, RT5670_INT_IRQ_ST, 0x8, 0x0);
4705ba04c66SKuninori Morimoto 		snd_soc_component_update_bits(component, RT5670_GEN_CTRL3, 0x4, 0x4);
471d3ef7054SBard Liao 		rt5670->jack_type = 0;
4726d8135ffSLars-Peter Clausen 		snd_soc_dapm_disable_pin(dapm, "Mic Det Power");
4736d8135ffSLars-Peter Clausen 		snd_soc_dapm_sync(dapm);
474d3ef7054SBard Liao 	}
475d3ef7054SBard Liao 
476d3ef7054SBard Liao 	return rt5670->jack_type;
477d3ef7054SBard Liao }
478d3ef7054SBard Liao 
rt5670_jack_suspend(struct snd_soc_component * component)4795ba04c66SKuninori Morimoto void rt5670_jack_suspend(struct snd_soc_component *component)
480cc3c340dSBard Liao {
4815ba04c66SKuninori Morimoto 	struct rt5670_priv *rt5670 = snd_soc_component_get_drvdata(component);
482cc3c340dSBard Liao 
483cc3c340dSBard Liao 	rt5670->jack_type_saved = rt5670->jack_type;
4845ba04c66SKuninori Morimoto 	rt5670_headset_detect(component, 0);
485cc3c340dSBard Liao }
486cc3c340dSBard Liao EXPORT_SYMBOL_GPL(rt5670_jack_suspend);
487cc3c340dSBard Liao 
rt5670_jack_resume(struct snd_soc_component * component)4885ba04c66SKuninori Morimoto void rt5670_jack_resume(struct snd_soc_component *component)
489cc3c340dSBard Liao {
4905ba04c66SKuninori Morimoto 	struct rt5670_priv *rt5670 = snd_soc_component_get_drvdata(component);
491cc3c340dSBard Liao 
492cc3c340dSBard Liao 	if (rt5670->jack_type_saved)
4935ba04c66SKuninori Morimoto 		rt5670_headset_detect(component, 1);
494cc3c340dSBard Liao }
495cc3c340dSBard Liao EXPORT_SYMBOL_GPL(rt5670_jack_resume);
496cc3c340dSBard Liao 
rt5670_button_detect(struct snd_soc_component * component)4975ba04c66SKuninori Morimoto static int rt5670_button_detect(struct snd_soc_component *component)
498d3ef7054SBard Liao {
499d3ef7054SBard Liao 	int btn_type, val;
500d3ef7054SBard Liao 
501467a2553SKuninori Morimoto 	val = snd_soc_component_read(component, RT5670_IL_CMD);
502d3ef7054SBard Liao 	btn_type = val & 0xff80;
5035ba04c66SKuninori Morimoto 	snd_soc_component_write(component, RT5670_IL_CMD, val);
504d3ef7054SBard Liao 	if (btn_type != 0) {
505d3ef7054SBard Liao 		msleep(20);
506467a2553SKuninori Morimoto 		val = snd_soc_component_read(component, RT5670_IL_CMD);
5075ba04c66SKuninori Morimoto 		snd_soc_component_write(component, RT5670_IL_CMD, val);
508d3ef7054SBard Liao 	}
509d3ef7054SBard Liao 
510d3ef7054SBard Liao 	return btn_type;
511d3ef7054SBard Liao }
512d3ef7054SBard Liao 
rt5670_irq_detection(void * data)513d3ef7054SBard Liao static int rt5670_irq_detection(void *data)
514d3ef7054SBard Liao {
515d3ef7054SBard Liao 	struct rt5670_priv *rt5670 = (struct rt5670_priv *)data;
516d3ef7054SBard Liao 	struct snd_soc_jack_gpio *gpio = &rt5670->hp_gpio;
517d3ef7054SBard Liao 	struct snd_soc_jack *jack = rt5670->jack;
518d3ef7054SBard Liao 	int val, btn_type, report = jack->status;
519d3ef7054SBard Liao 
520c14f61a8SHans de Goede 	if (rt5670->jd_mode == 1) /* 2 port */
521467a2553SKuninori Morimoto 		val = snd_soc_component_read(rt5670->component, RT5670_A_JD_CTRL1) & 0x0070;
522d3ef7054SBard Liao 	else
523467a2553SKuninori Morimoto 		val = snd_soc_component_read(rt5670->component, RT5670_A_JD_CTRL1) & 0x0020;
524d3ef7054SBard Liao 
525d3ef7054SBard Liao 	switch (val) {
526d3ef7054SBard Liao 	/* jack in */
527d3ef7054SBard Liao 	case 0x30: /* 2 port */
528d3ef7054SBard Liao 	case 0x0: /* 1 port or 2 port */
529d3ef7054SBard Liao 		if (rt5670->jack_type == 0) {
5305ba04c66SKuninori Morimoto 			report = rt5670_headset_detect(rt5670->component, 1);
531d3ef7054SBard Liao 			/* for push button and jack out */
532d3ef7054SBard Liao 			gpio->debounce_time = 25;
533d3ef7054SBard Liao 			break;
534d3ef7054SBard Liao 		}
535d3ef7054SBard Liao 		btn_type = 0;
536467a2553SKuninori Morimoto 		if (snd_soc_component_read(rt5670->component, RT5670_INT_IRQ_ST) & 0x4) {
537d3ef7054SBard Liao 			/* button pressed */
538d3ef7054SBard Liao 			report = SND_JACK_HEADSET;
5395ba04c66SKuninori Morimoto 			btn_type = rt5670_button_detect(rt5670->component);
540d3ef7054SBard Liao 			switch (btn_type) {
541d3ef7054SBard Liao 			case 0x2000: /* up */
542d3ef7054SBard Liao 				report |= SND_JACK_BTN_1;
543d3ef7054SBard Liao 				break;
544d3ef7054SBard Liao 			case 0x0400: /* center */
545d3ef7054SBard Liao 				report |= SND_JACK_BTN_0;
546d3ef7054SBard Liao 				break;
547d3ef7054SBard Liao 			case 0x0080: /* down */
548d3ef7054SBard Liao 				report |= SND_JACK_BTN_2;
549d3ef7054SBard Liao 				break;
550d3ef7054SBard Liao 			default:
5515ba04c66SKuninori Morimoto 				dev_err(rt5670->component->dev,
552d3ef7054SBard Liao 					"Unexpected button code 0x%04x\n",
553d3ef7054SBard Liao 					btn_type);
554d3ef7054SBard Liao 				break;
555d3ef7054SBard Liao 			}
556d3ef7054SBard Liao 		}
557d3ef7054SBard Liao 		if (btn_type == 0)/* button release */
558d3ef7054SBard Liao 			report =  rt5670->jack_type;
559d3ef7054SBard Liao 
560d3ef7054SBard Liao 		break;
561d3ef7054SBard Liao 	/* jack out */
562d3ef7054SBard Liao 	case 0x70: /* 2 port */
563d3ef7054SBard Liao 	case 0x10: /* 2 port */
564d3ef7054SBard Liao 	case 0x20: /* 1 port */
565d3ef7054SBard Liao 		report = 0;
5665ba04c66SKuninori Morimoto 		snd_soc_component_update_bits(rt5670->component, RT5670_INT_IRQ_ST, 0x1, 0x0);
5675ba04c66SKuninori Morimoto 		rt5670_headset_detect(rt5670->component, 0);
568d3ef7054SBard Liao 		gpio->debounce_time = 150; /* for jack in */
569d3ef7054SBard Liao 		break;
570d3ef7054SBard Liao 	default:
571d3ef7054SBard Liao 		break;
572d3ef7054SBard Liao 	}
573d3ef7054SBard Liao 
574d3ef7054SBard Liao 	return report;
575d3ef7054SBard Liao }
576d3ef7054SBard Liao 
rt5670_set_jack_detect(struct snd_soc_component * component,struct snd_soc_jack * jack)5775ba04c66SKuninori Morimoto int rt5670_set_jack_detect(struct snd_soc_component *component,
578d3ef7054SBard Liao 	struct snd_soc_jack *jack)
579d3ef7054SBard Liao {
5805ba04c66SKuninori Morimoto 	struct rt5670_priv *rt5670 = snd_soc_component_get_drvdata(component);
581d3ef7054SBard Liao 	int ret;
582d3ef7054SBard Liao 
583d3ef7054SBard Liao 	rt5670->jack = jack;
5845ba04c66SKuninori Morimoto 	rt5670->hp_gpio.gpiod_dev = component->dev;
585804e73adSTakashi Iwai 	rt5670->hp_gpio.name = "headset";
586d3ef7054SBard Liao 	rt5670->hp_gpio.report = SND_JACK_HEADSET |
587d3ef7054SBard Liao 		SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_BTN_2;
588d3ef7054SBard Liao 	rt5670->hp_gpio.debounce_time = 150;
589d3ef7054SBard Liao 	rt5670->hp_gpio.wake = true;
590d3ef7054SBard Liao 	rt5670->hp_gpio.data = (struct rt5670_priv *)rt5670;
591d3ef7054SBard Liao 	rt5670->hp_gpio.jack_status_check = rt5670_irq_detection;
592d3ef7054SBard Liao 
593d3ef7054SBard Liao 	ret = snd_soc_jack_add_gpios(rt5670->jack, 1,
594d3ef7054SBard Liao 			&rt5670->hp_gpio);
595d3ef7054SBard Liao 	if (ret) {
5965ba04c66SKuninori Morimoto 		dev_err(component->dev, "Adding jack GPIO failed\n");
597d3ef7054SBard Liao 		return ret;
598d3ef7054SBard Liao 	}
599d3ef7054SBard Liao 
600d3ef7054SBard Liao 	return 0;
601d3ef7054SBard Liao }
602d3ef7054SBard Liao EXPORT_SYMBOL_GPL(rt5670_set_jack_detect);
603d3ef7054SBard Liao 
6045e8351deSBard Liao static const DECLARE_TLV_DB_SCALE(out_vol_tlv, -4650, 150, 0);
6053f31f7d9SHans de Goede static const DECLARE_TLV_DB_MINMAX(dac_vol_tlv, -6562, 0);
6065e8351deSBard Liao static const DECLARE_TLV_DB_SCALE(in_vol_tlv, -3450, 150, 0);
6073f31f7d9SHans de Goede static const DECLARE_TLV_DB_MINMAX(adc_vol_tlv, -1762, 3000);
6085e8351deSBard Liao static const DECLARE_TLV_DB_SCALE(adc_bst_tlv, 0, 1200, 0);
6095e8351deSBard Liao 
6105e8351deSBard Liao /* {0, +20, +24, +30, +35, +40, +44, +50, +52} dB */
611dea6d32eSLars-Peter Clausen static const DECLARE_TLV_DB_RANGE(bst_tlv,
6125e8351deSBard Liao 	0, 0, TLV_DB_SCALE_ITEM(0, 0, 0),
6135e8351deSBard Liao 	1, 1, TLV_DB_SCALE_ITEM(2000, 0, 0),
6145e8351deSBard Liao 	2, 2, TLV_DB_SCALE_ITEM(2400, 0, 0),
6155e8351deSBard Liao 	3, 5, TLV_DB_SCALE_ITEM(3000, 500, 0),
6165e8351deSBard Liao 	6, 6, TLV_DB_SCALE_ITEM(4400, 0, 0),
6175e8351deSBard Liao 	7, 7, TLV_DB_SCALE_ITEM(5000, 0, 0),
618dea6d32eSLars-Peter Clausen 	8, 8, TLV_DB_SCALE_ITEM(5200, 0, 0)
619dea6d32eSLars-Peter Clausen );
6205e8351deSBard Liao 
6215e8351deSBard Liao /* Interface data select */
6225e8351deSBard Liao static const char * const rt5670_data_select[] = {
6235e8351deSBard Liao 	"Normal", "Swap", "left copy to right", "right copy to left"
6245e8351deSBard Liao };
6255e8351deSBard Liao 
62601957572SMark Brown static SOC_ENUM_SINGLE_DECL(rt5670_if2_dac_enum, RT5670_DIG_INF1_DATA,
6275e8351deSBard Liao 				RT5670_IF2_DAC_SEL_SFT, rt5670_data_select);
6285e8351deSBard Liao 
62901957572SMark Brown static SOC_ENUM_SINGLE_DECL(rt5670_if2_adc_enum, RT5670_DIG_INF1_DATA,
6305e8351deSBard Liao 				RT5670_IF2_ADC_SEL_SFT, rt5670_data_select);
6315e8351deSBard Liao 
63242121c26SHans de Goede /*
63342121c26SHans de Goede  * For reliable output-mute LED control we need a "DAC1 Playback Switch" control.
63442121c26SHans de Goede  * We emulate this by only clearing the RT5670_M_DAC1_L/_R AD_DA_MIXER register
63542121c26SHans de Goede  * bits when both our emulated DAC1 Playback Switch control and the DAC1 MIXL/R
63642121c26SHans de Goede  * DAPM-mixer DAC1 input are enabled.
63742121c26SHans de Goede  */
rt5670_update_ad_da_mixer_dac1_m_bits(struct rt5670_priv * rt5670)63842121c26SHans de Goede static void rt5670_update_ad_da_mixer_dac1_m_bits(struct rt5670_priv *rt5670)
63942121c26SHans de Goede {
64042121c26SHans de Goede 	int val = RT5670_M_DAC1_L | RT5670_M_DAC1_R;
64142121c26SHans de Goede 
64242121c26SHans de Goede 	if (rt5670->dac1_mixl_dac1_switch && rt5670->dac1_playback_switch_l)
64342121c26SHans de Goede 		val &= ~RT5670_M_DAC1_L;
64442121c26SHans de Goede 
64542121c26SHans de Goede 	if (rt5670->dac1_mixr_dac1_switch && rt5670->dac1_playback_switch_r)
64642121c26SHans de Goede 		val &= ~RT5670_M_DAC1_R;
64742121c26SHans de Goede 
64842121c26SHans de Goede 	regmap_update_bits(rt5670->regmap, RT5670_AD_DA_MIXER,
64942121c26SHans de Goede 			   RT5670_M_DAC1_L | RT5670_M_DAC1_R, val);
65042121c26SHans de Goede }
65142121c26SHans de Goede 
rt5670_dac1_playback_switch_get(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)65242121c26SHans de Goede static int rt5670_dac1_playback_switch_get(struct snd_kcontrol *kcontrol,
65342121c26SHans de Goede 					   struct snd_ctl_elem_value *ucontrol)
65442121c26SHans de Goede {
65542121c26SHans de Goede 	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
65642121c26SHans de Goede 	struct rt5670_priv *rt5670 = snd_soc_component_get_drvdata(component);
65742121c26SHans de Goede 
65842121c26SHans de Goede 	ucontrol->value.integer.value[0] = rt5670->dac1_playback_switch_l;
65942121c26SHans de Goede 	ucontrol->value.integer.value[1] = rt5670->dac1_playback_switch_r;
66042121c26SHans de Goede 
66142121c26SHans de Goede 	return 0;
66242121c26SHans de Goede }
66342121c26SHans de Goede 
rt5670_dac1_playback_switch_put(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)66442121c26SHans de Goede static int rt5670_dac1_playback_switch_put(struct snd_kcontrol *kcontrol,
66542121c26SHans de Goede 					   struct snd_ctl_elem_value *ucontrol)
66642121c26SHans de Goede {
66742121c26SHans de Goede 	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
66842121c26SHans de Goede 	struct rt5670_priv *rt5670 = snd_soc_component_get_drvdata(component);
66942121c26SHans de Goede 
67042121c26SHans de Goede 	if (rt5670->dac1_playback_switch_l == ucontrol->value.integer.value[0] &&
67142121c26SHans de Goede 	    rt5670->dac1_playback_switch_r == ucontrol->value.integer.value[1])
67242121c26SHans de Goede 		return 0;
67342121c26SHans de Goede 
67442121c26SHans de Goede 	rt5670->dac1_playback_switch_l = ucontrol->value.integer.value[0];
67542121c26SHans de Goede 	rt5670->dac1_playback_switch_r = ucontrol->value.integer.value[1];
67642121c26SHans de Goede 
67742121c26SHans de Goede 	rt5670_update_ad_da_mixer_dac1_m_bits(rt5670);
67842121c26SHans de Goede 
67942121c26SHans de Goede 	return 1;
68042121c26SHans de Goede }
68142121c26SHans de Goede 
6825e8351deSBard Liao static const struct snd_kcontrol_new rt5670_snd_controls[] = {
6835e8351deSBard Liao 	/* Headphone Output Volume */
6845e8351deSBard Liao 	SOC_DOUBLE_TLV("HP Playback Volume", RT5670_HP_VOL,
6855e8351deSBard Liao 		RT5670_L_VOL_SFT, RT5670_R_VOL_SFT,
686e1f42a2fSBard Liao 		39, 1, out_vol_tlv),
6875e8351deSBard Liao 	/* OUTPUT Control */
6885e8351deSBard Liao 	SOC_DOUBLE_TLV("OUT Playback Volume", RT5670_LOUT1,
6895e8351deSBard Liao 		RT5670_L_VOL_SFT, RT5670_R_VOL_SFT, 39, 1, out_vol_tlv),
6905e8351deSBard Liao 	/* DAC Digital Volume */
6915e8351deSBard Liao 	SOC_DOUBLE("DAC2 Playback Switch", RT5670_DAC_CTRL,
6925e8351deSBard Liao 		RT5670_M_DAC_L2_VOL_SFT, RT5670_M_DAC_R2_VOL_SFT, 1, 1),
69342121c26SHans de Goede 	SOC_DOUBLE_EXT("DAC1 Playback Switch", SND_SOC_NOPM, 0, 1, 1, 0,
69442121c26SHans de Goede 			rt5670_dac1_playback_switch_get, rt5670_dac1_playback_switch_put),
6955e8351deSBard Liao 	SOC_DOUBLE_TLV("DAC1 Playback Volume", RT5670_DAC1_DIG_VOL,
6965e8351deSBard Liao 			RT5670_L_VOL_SFT, RT5670_R_VOL_SFT,
6975e8351deSBard Liao 			175, 0, dac_vol_tlv),
6985e8351deSBard Liao 	SOC_DOUBLE_TLV("Mono DAC Playback Volume", RT5670_DAC2_DIG_VOL,
6995e8351deSBard Liao 			RT5670_L_VOL_SFT, RT5670_R_VOL_SFT,
7005e8351deSBard Liao 			175, 0, dac_vol_tlv),
7015e8351deSBard Liao 	/* IN1/IN2 Control */
7025e8351deSBard Liao 	SOC_SINGLE_TLV("IN1 Boost Volume", RT5670_CJ_CTRL1,
7035e8351deSBard Liao 		RT5670_BST_SFT1, 8, 0, bst_tlv),
7045e8351deSBard Liao 	SOC_SINGLE_TLV("IN2 Boost Volume", RT5670_IN2,
7055e8351deSBard Liao 		RT5670_BST_SFT1, 8, 0, bst_tlv),
7065e8351deSBard Liao 	/* INL/INR Volume Control */
7075e8351deSBard Liao 	SOC_DOUBLE_TLV("IN Capture Volume", RT5670_INL1_INR1_VOL,
7085e8351deSBard Liao 			RT5670_INL_VOL_SFT, RT5670_INR_VOL_SFT,
7095e8351deSBard Liao 			31, 1, in_vol_tlv),
7105e8351deSBard Liao 	/* ADC Digital Volume Control */
7115e8351deSBard Liao 	SOC_DOUBLE("ADC Capture Switch", RT5670_STO1_ADC_DIG_VOL,
7125e8351deSBard Liao 		RT5670_L_MUTE_SFT, RT5670_R_MUTE_SFT, 1, 1),
7135e8351deSBard Liao 	SOC_DOUBLE_TLV("ADC Capture Volume", RT5670_STO1_ADC_DIG_VOL,
7145e8351deSBard Liao 			RT5670_L_VOL_SFT, RT5670_R_VOL_SFT,
7155e8351deSBard Liao 			127, 0, adc_vol_tlv),
7165e8351deSBard Liao 
7175e8351deSBard Liao 	SOC_DOUBLE_TLV("Mono ADC Capture Volume", RT5670_MONO_ADC_DIG_VOL,
7185e8351deSBard Liao 			RT5670_L_VOL_SFT, RT5670_R_VOL_SFT,
7195e8351deSBard Liao 			127, 0, adc_vol_tlv),
7205e8351deSBard Liao 
7215e8351deSBard Liao 	/* ADC Boost Volume Control */
7225e8351deSBard Liao 	SOC_DOUBLE_TLV("STO1 ADC Boost Gain Volume", RT5670_ADC_BST_VOL1,
7235e8351deSBard Liao 			RT5670_STO1_ADC_L_BST_SFT, RT5670_STO1_ADC_R_BST_SFT,
7245e8351deSBard Liao 			3, 0, adc_bst_tlv),
7255e8351deSBard Liao 
7265e8351deSBard Liao 	SOC_DOUBLE_TLV("STO2 ADC Boost Gain Volume", RT5670_ADC_BST_VOL1,
7275e8351deSBard Liao 			RT5670_STO2_ADC_L_BST_SFT, RT5670_STO2_ADC_R_BST_SFT,
7285e8351deSBard Liao 			3, 0, adc_bst_tlv),
7295e8351deSBard Liao 
7305e8351deSBard Liao 	SOC_ENUM("ADC IF2 Data Switch", rt5670_if2_adc_enum),
7315e8351deSBard Liao 	SOC_ENUM("DAC IF2 Data Switch", rt5670_if2_dac_enum),
7325e8351deSBard Liao };
7335e8351deSBard Liao 
7345e8351deSBard Liao /**
7355e8351deSBard Liao  * set_dmic_clk - Set parameter of dmic.
7365e8351deSBard Liao  *
7375e8351deSBard Liao  * @w: DAPM widget.
7385e8351deSBard Liao  * @kcontrol: The kcontrol of this widget.
7395e8351deSBard Liao  * @event: Event id.
7405e8351deSBard Liao  *
7415e8351deSBard Liao  * Choose dmic clock between 1MHz and 3MHz.
7425e8351deSBard Liao  * It is better for clock to approximate 3MHz.
7435e8351deSBard Liao  */
set_dmic_clk(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)7445e8351deSBard Liao static int set_dmic_clk(struct snd_soc_dapm_widget *w,
7455e8351deSBard Liao 	struct snd_kcontrol *kcontrol, int event)
7465e8351deSBard Liao {
7475ba04c66SKuninori Morimoto 	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
7485ba04c66SKuninori Morimoto 	struct rt5670_priv *rt5670 = snd_soc_component_get_drvdata(component);
74900a6d6e5SOder Chiou 	int idx, rate;
7505e8351deSBard Liao 
75100a6d6e5SOder Chiou 	rate = rt5670->sysclk / rl6231_get_pre_div(rt5670->regmap,
75200a6d6e5SOder Chiou 		RT5670_ADDA_CLK1, RT5670_I2S_PD1_SFT);
75300a6d6e5SOder Chiou 	idx = rl6231_calc_dmic_clk(rate);
7545e8351deSBard Liao 	if (idx < 0)
7555ba04c66SKuninori Morimoto 		dev_err(component->dev, "Failed to set DMIC clock\n");
7565e8351deSBard Liao 	else
7575ba04c66SKuninori Morimoto 		snd_soc_component_update_bits(component, RT5670_DMIC_CTRL1,
7585e8351deSBard Liao 			RT5670_DMIC_CLK_MASK, idx << RT5670_DMIC_CLK_SFT);
7595e8351deSBard Liao 	return idx;
7605e8351deSBard Liao }
7615e8351deSBard Liao 
is_sys_clk_from_pll(struct snd_soc_dapm_widget * source,struct snd_soc_dapm_widget * sink)7625e8351deSBard Liao static int is_sys_clk_from_pll(struct snd_soc_dapm_widget *source,
7635e8351deSBard Liao 			 struct snd_soc_dapm_widget *sink)
7645e8351deSBard Liao {
7655ba04c66SKuninori Morimoto 	struct snd_soc_component *component = snd_soc_dapm_to_component(source->dapm);
7665ba04c66SKuninori Morimoto 	struct rt5670_priv *rt5670 = snd_soc_component_get_drvdata(component);
7675e8351deSBard Liao 
768485372dcSBard Liao 	if (rt5670->sysclk_src == RT5670_SCLK_S_PLL1)
7695e8351deSBard Liao 		return 1;
7705e8351deSBard Liao 	else
7715e8351deSBard Liao 		return 0;
7725e8351deSBard Liao }
7735e8351deSBard Liao 
is_using_asrc(struct snd_soc_dapm_widget * source,struct snd_soc_dapm_widget * sink)7745e8351deSBard Liao static int is_using_asrc(struct snd_soc_dapm_widget *source,
7755e8351deSBard Liao 			 struct snd_soc_dapm_widget *sink)
7765e8351deSBard Liao {
7775ba04c66SKuninori Morimoto 	struct snd_soc_component *component = snd_soc_dapm_to_component(source->dapm);
7785e8351deSBard Liao 	unsigned int reg, shift, val;
7795e8351deSBard Liao 
7805e8351deSBard Liao 	switch (source->shift) {
7815e8351deSBard Liao 	case 0:
7825e8351deSBard Liao 		reg = RT5670_ASRC_3;
7835e8351deSBard Liao 		shift = 0;
7845e8351deSBard Liao 		break;
7855e8351deSBard Liao 	case 1:
7865e8351deSBard Liao 		reg = RT5670_ASRC_3;
7875e8351deSBard Liao 		shift = 4;
7885e8351deSBard Liao 		break;
7895e8351deSBard Liao 	case 2:
7905e8351deSBard Liao 		reg = RT5670_ASRC_5;
7915e8351deSBard Liao 		shift = 12;
7925e8351deSBard Liao 		break;
7935e8351deSBard Liao 	case 3:
7945e8351deSBard Liao 		reg = RT5670_ASRC_2;
7955e8351deSBard Liao 		shift = 0;
7965e8351deSBard Liao 		break;
7975e8351deSBard Liao 	case 8:
7985e8351deSBard Liao 		reg = RT5670_ASRC_2;
7995e8351deSBard Liao 		shift = 4;
8005e8351deSBard Liao 		break;
8015e8351deSBard Liao 	case 9:
8025e8351deSBard Liao 		reg = RT5670_ASRC_2;
8035e8351deSBard Liao 		shift = 8;
8045e8351deSBard Liao 		break;
8055e8351deSBard Liao 	case 10:
8065e8351deSBard Liao 		reg = RT5670_ASRC_2;
8075e8351deSBard Liao 		shift = 12;
8085e8351deSBard Liao 		break;
8095e8351deSBard Liao 	default:
8105e8351deSBard Liao 		return 0;
8115e8351deSBard Liao 	}
8125e8351deSBard Liao 
813467a2553SKuninori Morimoto 	val = (snd_soc_component_read(component, reg) >> shift) & 0xf;
8145e8351deSBard Liao 	switch (val) {
8155e8351deSBard Liao 	case 1:
8165e8351deSBard Liao 	case 2:
8175e8351deSBard Liao 	case 3:
8185e8351deSBard Liao 	case 4:
8195e8351deSBard Liao 		return 1;
8205e8351deSBard Liao 	default:
8215e8351deSBard Liao 		return 0;
8225e8351deSBard Liao 	}
8235e8351deSBard Liao 
8245e8351deSBard Liao }
8255e8351deSBard Liao 
can_use_asrc(struct snd_soc_dapm_widget * source,struct snd_soc_dapm_widget * sink)826e50334d4SBard Liao static int can_use_asrc(struct snd_soc_dapm_widget *source,
827e50334d4SBard Liao 			 struct snd_soc_dapm_widget *sink)
828e50334d4SBard Liao {
8295ba04c66SKuninori Morimoto 	struct snd_soc_component *component = snd_soc_dapm_to_component(source->dapm);
8305ba04c66SKuninori Morimoto 	struct rt5670_priv *rt5670 = snd_soc_component_get_drvdata(component);
831e50334d4SBard Liao 
832e50334d4SBard Liao 	if (rt5670->sysclk > rt5670->lrck[RT5670_AIF1] * 384)
833e50334d4SBard Liao 		return 1;
834e50334d4SBard Liao 
835e50334d4SBard Liao 	return 0;
836e50334d4SBard Liao }
837e50334d4SBard Liao 
838ea232b3fSMengdong Lin 
839ea232b3fSMengdong Lin /**
840ea232b3fSMengdong Lin  * rt5670_sel_asrc_clk_src - select ASRC clock source for a set of filters
8415ba04c66SKuninori Morimoto  * @component: SoC audio component device.
842ea232b3fSMengdong Lin  * @filter_mask: mask of filters.
843ea232b3fSMengdong Lin  * @clk_src: clock source
844ea232b3fSMengdong Lin  *
845ea232b3fSMengdong Lin  * The ASRC function is for asynchronous MCLK and LRCK. Also, since RT5670 can
846ea232b3fSMengdong Lin  * only support standard 32fs or 64fs i2s format, ASRC should be enabled to
847ea232b3fSMengdong Lin  * support special i2s clock format such as Intel's 100fs(100 * sampling rate).
848ea232b3fSMengdong Lin  * ASRC function will track i2s clock and generate a corresponding system clock
849ea232b3fSMengdong Lin  * for codec. This function provides an API to select the clock source for a
850ea232b3fSMengdong Lin  * set of filters specified by the mask. And the codec driver will turn on ASRC
851ea232b3fSMengdong Lin  * for these filters if ASRC is selected as their clock source.
852ea232b3fSMengdong Lin  */
rt5670_sel_asrc_clk_src(struct snd_soc_component * component,unsigned int filter_mask,unsigned int clk_src)8535ba04c66SKuninori Morimoto int rt5670_sel_asrc_clk_src(struct snd_soc_component *component,
854ea232b3fSMengdong Lin 			    unsigned int filter_mask, unsigned int clk_src)
855ea232b3fSMengdong Lin {
856ea232b3fSMengdong Lin 	unsigned int asrc2_mask = 0, asrc2_value = 0;
857ea232b3fSMengdong Lin 	unsigned int asrc3_mask = 0, asrc3_value = 0;
858ea232b3fSMengdong Lin 
859ea232b3fSMengdong Lin 	if (clk_src > RT5670_CLK_SEL_SYS3)
860ea232b3fSMengdong Lin 		return -EINVAL;
861ea232b3fSMengdong Lin 
862ea232b3fSMengdong Lin 	if (filter_mask & RT5670_DA_STEREO_FILTER) {
863ea232b3fSMengdong Lin 		asrc2_mask |= RT5670_DA_STO_CLK_SEL_MASK;
864ea232b3fSMengdong Lin 		asrc2_value = (asrc2_value & ~RT5670_DA_STO_CLK_SEL_MASK)
865ea232b3fSMengdong Lin 				| (clk_src <<  RT5670_DA_STO_CLK_SEL_SFT);
866ea232b3fSMengdong Lin 	}
867ea232b3fSMengdong Lin 
868ea232b3fSMengdong Lin 	if (filter_mask & RT5670_DA_MONO_L_FILTER) {
869ea232b3fSMengdong Lin 		asrc2_mask |= RT5670_DA_MONOL_CLK_SEL_MASK;
870ea232b3fSMengdong Lin 		asrc2_value = (asrc2_value & ~RT5670_DA_MONOL_CLK_SEL_MASK)
871ea232b3fSMengdong Lin 				| (clk_src <<  RT5670_DA_MONOL_CLK_SEL_SFT);
872ea232b3fSMengdong Lin 	}
873ea232b3fSMengdong Lin 
874ea232b3fSMengdong Lin 	if (filter_mask & RT5670_DA_MONO_R_FILTER) {
875ea232b3fSMengdong Lin 		asrc2_mask |= RT5670_DA_MONOR_CLK_SEL_MASK;
876ea232b3fSMengdong Lin 		asrc2_value = (asrc2_value & ~RT5670_DA_MONOR_CLK_SEL_MASK)
877ea232b3fSMengdong Lin 				| (clk_src <<  RT5670_DA_MONOR_CLK_SEL_SFT);
878ea232b3fSMengdong Lin 	}
879ea232b3fSMengdong Lin 
880ea232b3fSMengdong Lin 	if (filter_mask & RT5670_AD_STEREO_FILTER) {
881ea232b3fSMengdong Lin 		asrc2_mask |= RT5670_AD_STO1_CLK_SEL_MASK;
882ea232b3fSMengdong Lin 		asrc2_value = (asrc2_value & ~RT5670_AD_STO1_CLK_SEL_MASK)
883ea232b3fSMengdong Lin 				| (clk_src <<  RT5670_AD_STO1_CLK_SEL_SFT);
884ea232b3fSMengdong Lin 	}
885ea232b3fSMengdong Lin 
886ea232b3fSMengdong Lin 	if (filter_mask & RT5670_AD_MONO_L_FILTER) {
887ea232b3fSMengdong Lin 		asrc3_mask |= RT5670_AD_MONOL_CLK_SEL_MASK;
888ea232b3fSMengdong Lin 		asrc3_value = (asrc3_value & ~RT5670_AD_MONOL_CLK_SEL_MASK)
889ea232b3fSMengdong Lin 				| (clk_src <<  RT5670_AD_MONOL_CLK_SEL_SFT);
890ea232b3fSMengdong Lin 	}
891ea232b3fSMengdong Lin 
892ea232b3fSMengdong Lin 	if (filter_mask & RT5670_AD_MONO_R_FILTER)  {
893ea232b3fSMengdong Lin 		asrc3_mask |= RT5670_AD_MONOR_CLK_SEL_MASK;
894ea232b3fSMengdong Lin 		asrc3_value = (asrc3_value & ~RT5670_AD_MONOR_CLK_SEL_MASK)
895ea232b3fSMengdong Lin 				| (clk_src <<  RT5670_AD_MONOR_CLK_SEL_SFT);
896ea232b3fSMengdong Lin 	}
897ea232b3fSMengdong Lin 
898ea232b3fSMengdong Lin 	if (filter_mask & RT5670_UP_RATE_FILTER) {
899ea232b3fSMengdong Lin 		asrc3_mask |= RT5670_UP_CLK_SEL_MASK;
900ea232b3fSMengdong Lin 		asrc3_value = (asrc3_value & ~RT5670_UP_CLK_SEL_MASK)
901ea232b3fSMengdong Lin 				| (clk_src <<  RT5670_UP_CLK_SEL_SFT);
902ea232b3fSMengdong Lin 	}
903ea232b3fSMengdong Lin 
904ea232b3fSMengdong Lin 	if (filter_mask & RT5670_DOWN_RATE_FILTER) {
905ea232b3fSMengdong Lin 		asrc3_mask |= RT5670_DOWN_CLK_SEL_MASK;
906ea232b3fSMengdong Lin 		asrc3_value = (asrc3_value & ~RT5670_DOWN_CLK_SEL_MASK)
907ea232b3fSMengdong Lin 				| (clk_src <<  RT5670_DOWN_CLK_SEL_SFT);
908ea232b3fSMengdong Lin 	}
909ea232b3fSMengdong Lin 
910ea232b3fSMengdong Lin 	if (asrc2_mask)
9115ba04c66SKuninori Morimoto 		snd_soc_component_update_bits(component, RT5670_ASRC_2,
912ea232b3fSMengdong Lin 				    asrc2_mask, asrc2_value);
913ea232b3fSMengdong Lin 
914ea232b3fSMengdong Lin 	if (asrc3_mask)
9155ba04c66SKuninori Morimoto 		snd_soc_component_update_bits(component, RT5670_ASRC_3,
916ea232b3fSMengdong Lin 				    asrc3_mask, asrc3_value);
917ea232b3fSMengdong Lin 	return 0;
918ea232b3fSMengdong Lin }
919ea232b3fSMengdong Lin EXPORT_SYMBOL_GPL(rt5670_sel_asrc_clk_src);
920ea232b3fSMengdong Lin 
9215e8351deSBard Liao /* Digital Mixer */
9225e8351deSBard Liao static const struct snd_kcontrol_new rt5670_sto1_adc_l_mix[] = {
9235e8351deSBard Liao 	SOC_DAPM_SINGLE("ADC1 Switch", RT5670_STO1_ADC_MIXER,
9245e8351deSBard Liao 			RT5670_M_ADC_L1_SFT, 1, 1),
9255e8351deSBard Liao 	SOC_DAPM_SINGLE("ADC2 Switch", RT5670_STO1_ADC_MIXER,
9265e8351deSBard Liao 			RT5670_M_ADC_L2_SFT, 1, 1),
9275e8351deSBard Liao };
9285e8351deSBard Liao 
9295e8351deSBard Liao static const struct snd_kcontrol_new rt5670_sto1_adc_r_mix[] = {
9305e8351deSBard Liao 	SOC_DAPM_SINGLE("ADC1 Switch", RT5670_STO1_ADC_MIXER,
9315e8351deSBard Liao 			RT5670_M_ADC_R1_SFT, 1, 1),
9325e8351deSBard Liao 	SOC_DAPM_SINGLE("ADC2 Switch", RT5670_STO1_ADC_MIXER,
9335e8351deSBard Liao 			RT5670_M_ADC_R2_SFT, 1, 1),
9345e8351deSBard Liao };
9355e8351deSBard Liao 
9365e8351deSBard Liao static const struct snd_kcontrol_new rt5670_sto2_adc_l_mix[] = {
9375e8351deSBard Liao 	SOC_DAPM_SINGLE("ADC1 Switch", RT5670_STO2_ADC_MIXER,
9385e8351deSBard Liao 			RT5670_M_ADC_L1_SFT, 1, 1),
9395e8351deSBard Liao 	SOC_DAPM_SINGLE("ADC2 Switch", RT5670_STO2_ADC_MIXER,
9405e8351deSBard Liao 			RT5670_M_ADC_L2_SFT, 1, 1),
9415e8351deSBard Liao };
9425e8351deSBard Liao 
9435e8351deSBard Liao static const struct snd_kcontrol_new rt5670_sto2_adc_r_mix[] = {
9445e8351deSBard Liao 	SOC_DAPM_SINGLE("ADC1 Switch", RT5670_STO2_ADC_MIXER,
9455e8351deSBard Liao 			RT5670_M_ADC_R1_SFT, 1, 1),
9465e8351deSBard Liao 	SOC_DAPM_SINGLE("ADC2 Switch", RT5670_STO2_ADC_MIXER,
9475e8351deSBard Liao 			RT5670_M_ADC_R2_SFT, 1, 1),
9485e8351deSBard Liao };
9495e8351deSBard Liao 
9505e8351deSBard Liao static const struct snd_kcontrol_new rt5670_mono_adc_l_mix[] = {
9515e8351deSBard Liao 	SOC_DAPM_SINGLE("ADC1 Switch", RT5670_MONO_ADC_MIXER,
9525e8351deSBard Liao 			RT5670_M_MONO_ADC_L1_SFT, 1, 1),
9535e8351deSBard Liao 	SOC_DAPM_SINGLE("ADC2 Switch", RT5670_MONO_ADC_MIXER,
9545e8351deSBard Liao 			RT5670_M_MONO_ADC_L2_SFT, 1, 1),
9555e8351deSBard Liao };
9565e8351deSBard Liao 
9575e8351deSBard Liao static const struct snd_kcontrol_new rt5670_mono_adc_r_mix[] = {
9585e8351deSBard Liao 	SOC_DAPM_SINGLE("ADC1 Switch", RT5670_MONO_ADC_MIXER,
9595e8351deSBard Liao 			RT5670_M_MONO_ADC_R1_SFT, 1, 1),
9605e8351deSBard Liao 	SOC_DAPM_SINGLE("ADC2 Switch", RT5670_MONO_ADC_MIXER,
9615e8351deSBard Liao 			RT5670_M_MONO_ADC_R2_SFT, 1, 1),
9625e8351deSBard Liao };
9635e8351deSBard Liao 
96442121c26SHans de Goede /* See comment above rt5670_update_ad_da_mixer_dac1_m_bits() */
rt5670_put_dac1_mix_dac1_switch(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)96542121c26SHans de Goede static int rt5670_put_dac1_mix_dac1_switch(struct snd_kcontrol *kcontrol,
96642121c26SHans de Goede 					   struct snd_ctl_elem_value *ucontrol)
96742121c26SHans de Goede {
96842121c26SHans de Goede 	struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value;
96942121c26SHans de Goede 	struct snd_soc_component *component = snd_soc_dapm_kcontrol_component(kcontrol);
97042121c26SHans de Goede 	struct rt5670_priv *rt5670 = snd_soc_component_get_drvdata(component);
97142121c26SHans de Goede 	int ret;
97242121c26SHans de Goede 
97342121c26SHans de Goede 	if (mc->shift == 0)
97442121c26SHans de Goede 		rt5670->dac1_mixl_dac1_switch = ucontrol->value.integer.value[0];
97542121c26SHans de Goede 	else
97642121c26SHans de Goede 		rt5670->dac1_mixr_dac1_switch = ucontrol->value.integer.value[0];
97742121c26SHans de Goede 
97842121c26SHans de Goede 	/* Apply the update (if any) */
97942121c26SHans de Goede 	ret = snd_soc_dapm_put_volsw(kcontrol, ucontrol);
98042121c26SHans de Goede 	if (ret == 0)
98142121c26SHans de Goede 		return 0;
98242121c26SHans de Goede 
98342121c26SHans de Goede 	rt5670_update_ad_da_mixer_dac1_m_bits(rt5670);
98442121c26SHans de Goede 
98542121c26SHans de Goede 	return 1;
98642121c26SHans de Goede }
98742121c26SHans de Goede 
98842121c26SHans de Goede #define SOC_DAPM_SINGLE_RT5670_DAC1_SW(name, shift) \
98942121c26SHans de Goede 	SOC_SINGLE_EXT(name, SND_SOC_NOPM, shift, 1, 0, \
99042121c26SHans de Goede 		       snd_soc_dapm_get_volsw, rt5670_put_dac1_mix_dac1_switch)
99142121c26SHans de Goede 
9925e8351deSBard Liao static const struct snd_kcontrol_new rt5670_dac_l_mix[] = {
9935e8351deSBard Liao 	SOC_DAPM_SINGLE("Stereo ADC Switch", RT5670_AD_DA_MIXER,
9945e8351deSBard Liao 			RT5670_M_ADCMIX_L_SFT, 1, 1),
99542121c26SHans de Goede 	SOC_DAPM_SINGLE_RT5670_DAC1_SW("DAC1 Switch", 0),
9965e8351deSBard Liao };
9975e8351deSBard Liao 
9985e8351deSBard Liao static const struct snd_kcontrol_new rt5670_dac_r_mix[] = {
9995e8351deSBard Liao 	SOC_DAPM_SINGLE("Stereo ADC Switch", RT5670_AD_DA_MIXER,
10005e8351deSBard Liao 			RT5670_M_ADCMIX_R_SFT, 1, 1),
100142121c26SHans de Goede 	SOC_DAPM_SINGLE_RT5670_DAC1_SW("DAC1 Switch", 1),
10025e8351deSBard Liao };
10035e8351deSBard Liao 
10045e8351deSBard Liao static const struct snd_kcontrol_new rt5670_sto_dac_l_mix[] = {
10055e8351deSBard Liao 	SOC_DAPM_SINGLE("DAC L1 Switch", RT5670_STO_DAC_MIXER,
10065e8351deSBard Liao 			RT5670_M_DAC_L1_SFT, 1, 1),
10075e8351deSBard Liao 	SOC_DAPM_SINGLE("DAC L2 Switch", RT5670_STO_DAC_MIXER,
10085e8351deSBard Liao 			RT5670_M_DAC_L2_SFT, 1, 1),
10095e8351deSBard Liao 	SOC_DAPM_SINGLE("DAC R1 Switch", RT5670_STO_DAC_MIXER,
10105e8351deSBard Liao 			RT5670_M_DAC_R1_STO_L_SFT, 1, 1),
10115e8351deSBard Liao };
10125e8351deSBard Liao 
10135e8351deSBard Liao static const struct snd_kcontrol_new rt5670_sto_dac_r_mix[] = {
10145e8351deSBard Liao 	SOC_DAPM_SINGLE("DAC R1 Switch", RT5670_STO_DAC_MIXER,
10155e8351deSBard Liao 			RT5670_M_DAC_R1_SFT, 1, 1),
10165e8351deSBard Liao 	SOC_DAPM_SINGLE("DAC R2 Switch", RT5670_STO_DAC_MIXER,
10175e8351deSBard Liao 			RT5670_M_DAC_R2_SFT, 1, 1),
10185e8351deSBard Liao 	SOC_DAPM_SINGLE("DAC L1 Switch", RT5670_STO_DAC_MIXER,
10195e8351deSBard Liao 			RT5670_M_DAC_L1_STO_R_SFT, 1, 1),
10205e8351deSBard Liao };
10215e8351deSBard Liao 
10225e8351deSBard Liao static const struct snd_kcontrol_new rt5670_mono_dac_l_mix[] = {
10235e8351deSBard Liao 	SOC_DAPM_SINGLE("DAC L1 Switch", RT5670_DD_MIXER,
10245e8351deSBard Liao 			RT5670_M_DAC_L1_MONO_L_SFT, 1, 1),
10255e8351deSBard Liao 	SOC_DAPM_SINGLE("DAC L2 Switch", RT5670_DD_MIXER,
10265e8351deSBard Liao 			RT5670_M_DAC_L2_MONO_L_SFT, 1, 1),
10275e8351deSBard Liao 	SOC_DAPM_SINGLE("DAC R2 Switch", RT5670_DD_MIXER,
10285e8351deSBard Liao 			RT5670_M_DAC_R2_MONO_L_SFT, 1, 1),
10295e8351deSBard Liao };
10305e8351deSBard Liao 
10315e8351deSBard Liao static const struct snd_kcontrol_new rt5670_mono_dac_r_mix[] = {
10325e8351deSBard Liao 	SOC_DAPM_SINGLE("DAC R1 Switch", RT5670_DD_MIXER,
10335e8351deSBard Liao 			RT5670_M_DAC_R1_MONO_R_SFT, 1, 1),
10345e8351deSBard Liao 	SOC_DAPM_SINGLE("DAC R2 Switch", RT5670_DD_MIXER,
10355e8351deSBard Liao 			RT5670_M_DAC_R2_MONO_R_SFT, 1, 1),
10365e8351deSBard Liao 	SOC_DAPM_SINGLE("DAC L2 Switch", RT5670_DD_MIXER,
10375e8351deSBard Liao 			RT5670_M_DAC_L2_MONO_R_SFT, 1, 1),
10385e8351deSBard Liao };
10395e8351deSBard Liao 
10405e8351deSBard Liao static const struct snd_kcontrol_new rt5670_dig_l_mix[] = {
10415e8351deSBard Liao 	SOC_DAPM_SINGLE("Sto DAC Mix L Switch", RT5670_DIG_MIXER,
10425e8351deSBard Liao 			RT5670_M_STO_L_DAC_L_SFT, 1, 1),
10435e8351deSBard Liao 	SOC_DAPM_SINGLE("DAC L2 Switch", RT5670_DIG_MIXER,
10445e8351deSBard Liao 			RT5670_M_DAC_L2_DAC_L_SFT, 1, 1),
10455e8351deSBard Liao 	SOC_DAPM_SINGLE("DAC R2 Switch", RT5670_DIG_MIXER,
10465e8351deSBard Liao 			RT5670_M_DAC_R2_DAC_L_SFT, 1, 1),
10475e8351deSBard Liao };
10485e8351deSBard Liao 
10495e8351deSBard Liao static const struct snd_kcontrol_new rt5670_dig_r_mix[] = {
10505e8351deSBard Liao 	SOC_DAPM_SINGLE("Sto DAC Mix R Switch", RT5670_DIG_MIXER,
10515e8351deSBard Liao 			RT5670_M_STO_R_DAC_R_SFT, 1, 1),
10525e8351deSBard Liao 	SOC_DAPM_SINGLE("DAC R2 Switch", RT5670_DIG_MIXER,
10535e8351deSBard Liao 			RT5670_M_DAC_R2_DAC_R_SFT, 1, 1),
10545e8351deSBard Liao 	SOC_DAPM_SINGLE("DAC L2 Switch", RT5670_DIG_MIXER,
10555e8351deSBard Liao 			RT5670_M_DAC_L2_DAC_R_SFT, 1, 1),
10565e8351deSBard Liao };
10575e8351deSBard Liao 
10585e8351deSBard Liao /* Analog Input Mixer */
10595e8351deSBard Liao static const struct snd_kcontrol_new rt5670_rec_l_mix[] = {
10605e8351deSBard Liao 	SOC_DAPM_SINGLE("INL Switch", RT5670_REC_L2_MIXER,
10615e8351deSBard Liao 			RT5670_M_IN_L_RM_L_SFT, 1, 1),
10625e8351deSBard Liao 	SOC_DAPM_SINGLE("BST2 Switch", RT5670_REC_L2_MIXER,
10635e8351deSBard Liao 			RT5670_M_BST2_RM_L_SFT, 1, 1),
10645e8351deSBard Liao 	SOC_DAPM_SINGLE("BST1 Switch", RT5670_REC_L2_MIXER,
10655e8351deSBard Liao 			RT5670_M_BST1_RM_L_SFT, 1, 1),
10665e8351deSBard Liao };
10675e8351deSBard Liao 
10685e8351deSBard Liao static const struct snd_kcontrol_new rt5670_rec_r_mix[] = {
10695e8351deSBard Liao 	SOC_DAPM_SINGLE("INR Switch", RT5670_REC_R2_MIXER,
10705e8351deSBard Liao 			RT5670_M_IN_R_RM_R_SFT, 1, 1),
10715e8351deSBard Liao 	SOC_DAPM_SINGLE("BST2 Switch", RT5670_REC_R2_MIXER,
10725e8351deSBard Liao 			RT5670_M_BST2_RM_R_SFT, 1, 1),
10735e8351deSBard Liao 	SOC_DAPM_SINGLE("BST1 Switch", RT5670_REC_R2_MIXER,
10745e8351deSBard Liao 			RT5670_M_BST1_RM_R_SFT, 1, 1),
10755e8351deSBard Liao };
10765e8351deSBard Liao 
10775e8351deSBard Liao static const struct snd_kcontrol_new rt5670_out_l_mix[] = {
10785e8351deSBard Liao 	SOC_DAPM_SINGLE("BST1 Switch", RT5670_OUT_L1_MIXER,
10795e8351deSBard Liao 			RT5670_M_BST1_OM_L_SFT, 1, 1),
10805e8351deSBard Liao 	SOC_DAPM_SINGLE("INL Switch", RT5670_OUT_L1_MIXER,
10815e8351deSBard Liao 			RT5670_M_IN_L_OM_L_SFT, 1, 1),
10825e8351deSBard Liao 	SOC_DAPM_SINGLE("DAC L2 Switch", RT5670_OUT_L1_MIXER,
10835e8351deSBard Liao 			RT5670_M_DAC_L2_OM_L_SFT, 1, 1),
10845e8351deSBard Liao 	SOC_DAPM_SINGLE("DAC L1 Switch", RT5670_OUT_L1_MIXER,
10855e8351deSBard Liao 			RT5670_M_DAC_L1_OM_L_SFT, 1, 1),
10865e8351deSBard Liao };
10875e8351deSBard Liao 
10885e8351deSBard Liao static const struct snd_kcontrol_new rt5670_out_r_mix[] = {
10895e8351deSBard Liao 	SOC_DAPM_SINGLE("BST2 Switch", RT5670_OUT_R1_MIXER,
10905e8351deSBard Liao 			RT5670_M_BST2_OM_R_SFT, 1, 1),
10915e8351deSBard Liao 	SOC_DAPM_SINGLE("INR Switch", RT5670_OUT_R1_MIXER,
10925e8351deSBard Liao 			RT5670_M_IN_R_OM_R_SFT, 1, 1),
10935e8351deSBard Liao 	SOC_DAPM_SINGLE("DAC R2 Switch", RT5670_OUT_R1_MIXER,
10945e8351deSBard Liao 			RT5670_M_DAC_R2_OM_R_SFT, 1, 1),
10955e8351deSBard Liao 	SOC_DAPM_SINGLE("DAC R1 Switch", RT5670_OUT_R1_MIXER,
10965e8351deSBard Liao 			RT5670_M_DAC_R1_OM_R_SFT, 1, 1),
10975e8351deSBard Liao };
10985e8351deSBard Liao 
10995e8351deSBard Liao static const struct snd_kcontrol_new rt5670_hpo_mix[] = {
11005e8351deSBard Liao 	SOC_DAPM_SINGLE("DAC1 Switch", RT5670_HPO_MIXER,
11015e8351deSBard Liao 			RT5670_M_DAC1_HM_SFT, 1, 1),
11025e8351deSBard Liao 	SOC_DAPM_SINGLE("HPVOL Switch", RT5670_HPO_MIXER,
11035e8351deSBard Liao 			RT5670_M_HPVOL_HM_SFT, 1, 1),
11045e8351deSBard Liao };
11055e8351deSBard Liao 
11065e8351deSBard Liao static const struct snd_kcontrol_new rt5670_hpvoll_mix[] = {
11075e8351deSBard Liao 	SOC_DAPM_SINGLE("DAC1 Switch", RT5670_HPO_MIXER,
11085e8351deSBard Liao 			RT5670_M_DACL1_HML_SFT, 1, 1),
11095e8351deSBard Liao 	SOC_DAPM_SINGLE("INL Switch", RT5670_HPO_MIXER,
11105e8351deSBard Liao 			RT5670_M_INL1_HML_SFT, 1, 1),
11115e8351deSBard Liao };
11125e8351deSBard Liao 
11135e8351deSBard Liao static const struct snd_kcontrol_new rt5670_hpvolr_mix[] = {
11145e8351deSBard Liao 	SOC_DAPM_SINGLE("DAC1 Switch", RT5670_HPO_MIXER,
11155e8351deSBard Liao 			RT5670_M_DACR1_HMR_SFT, 1, 1),
11165e8351deSBard Liao 	SOC_DAPM_SINGLE("INR Switch", RT5670_HPO_MIXER,
11175e8351deSBard Liao 			RT5670_M_INR1_HMR_SFT, 1, 1),
11185e8351deSBard Liao };
11195e8351deSBard Liao 
11205e8351deSBard Liao static const struct snd_kcontrol_new rt5670_lout_mix[] = {
11215e8351deSBard Liao 	SOC_DAPM_SINGLE("DAC L1 Switch", RT5670_LOUT_MIXER,
11225e8351deSBard Liao 			RT5670_M_DAC_L1_LM_SFT, 1, 1),
11235e8351deSBard Liao 	SOC_DAPM_SINGLE("DAC R1 Switch", RT5670_LOUT_MIXER,
11245e8351deSBard Liao 			RT5670_M_DAC_R1_LM_SFT, 1, 1),
11255e8351deSBard Liao 	SOC_DAPM_SINGLE("OUTMIX L Switch", RT5670_LOUT_MIXER,
11265e8351deSBard Liao 			RT5670_M_OV_L_LM_SFT, 1, 1),
11275e8351deSBard Liao 	SOC_DAPM_SINGLE("OUTMIX R Switch", RT5670_LOUT_MIXER,
11285e8351deSBard Liao 			RT5670_M_OV_R_LM_SFT, 1, 1),
11295e8351deSBard Liao };
11305e8351deSBard Liao 
11315e8351deSBard Liao static const struct snd_kcontrol_new lout_l_enable_control =
11325e8351deSBard Liao 	SOC_DAPM_SINGLE_AUTODISABLE("Switch", RT5670_LOUT1,
11335e8351deSBard Liao 		RT5670_L_MUTE_SFT, 1, 1);
11345e8351deSBard Liao 
11355e8351deSBard Liao static const struct snd_kcontrol_new lout_r_enable_control =
11365e8351deSBard Liao 	SOC_DAPM_SINGLE_AUTODISABLE("Switch", RT5670_LOUT1,
11375e8351deSBard Liao 		RT5670_R_MUTE_SFT, 1, 1);
11385e8351deSBard Liao 
11395e8351deSBard Liao /* DAC1 L/R source */ /* MX-29 [9:8] [11:10] */
11405e8351deSBard Liao static const char * const rt5670_dac1_src[] = {
11415e8351deSBard Liao 	"IF1 DAC", "IF2 DAC"
11425e8351deSBard Liao };
11435e8351deSBard Liao 
114401957572SMark Brown static SOC_ENUM_SINGLE_DECL(rt5670_dac1l_enum, RT5670_AD_DA_MIXER,
11455e8351deSBard Liao 	RT5670_DAC1_L_SEL_SFT, rt5670_dac1_src);
11465e8351deSBard Liao 
11475e8351deSBard Liao static const struct snd_kcontrol_new rt5670_dac1l_mux =
11485e8351deSBard Liao 	SOC_DAPM_ENUM("DAC1 L source", rt5670_dac1l_enum);
11495e8351deSBard Liao 
115001957572SMark Brown static SOC_ENUM_SINGLE_DECL(rt5670_dac1r_enum, RT5670_AD_DA_MIXER,
11515e8351deSBard Liao 	RT5670_DAC1_R_SEL_SFT, rt5670_dac1_src);
11525e8351deSBard Liao 
11535e8351deSBard Liao static const struct snd_kcontrol_new rt5670_dac1r_mux =
11545e8351deSBard Liao 	SOC_DAPM_ENUM("DAC1 R source", rt5670_dac1r_enum);
11555e8351deSBard Liao 
11565e8351deSBard Liao /*DAC2 L/R source*/ /* MX-1B [6:4] [2:0] */
11575e8351deSBard Liao /* TODO Use SOC_VALUE_ENUM_SINGLE_DECL */
11585e8351deSBard Liao static const char * const rt5670_dac12_src[] = {
11595e8351deSBard Liao 	"IF1 DAC", "IF2 DAC", "IF3 DAC", "TxDC DAC",
11605e8351deSBard Liao 	"Bass", "VAD_ADC", "IF4 DAC"
11615e8351deSBard Liao };
11625e8351deSBard Liao 
116301957572SMark Brown static SOC_ENUM_SINGLE_DECL(rt5670_dac2l_enum, RT5670_DAC_CTRL,
11645e8351deSBard Liao 	RT5670_DAC2_L_SEL_SFT, rt5670_dac12_src);
11655e8351deSBard Liao 
11665e8351deSBard Liao static const struct snd_kcontrol_new rt5670_dac_l2_mux =
11675e8351deSBard Liao 	SOC_DAPM_ENUM("DAC2 L source", rt5670_dac2l_enum);
11685e8351deSBard Liao 
11695e8351deSBard Liao static const char * const rt5670_dacr2_src[] = {
11705e8351deSBard Liao 	"IF1 DAC", "IF2 DAC", "IF3 DAC", "TxDC DAC", "TxDP ADC", "IF4 DAC"
11715e8351deSBard Liao };
11725e8351deSBard Liao 
117301957572SMark Brown static SOC_ENUM_SINGLE_DECL(rt5670_dac2r_enum, RT5670_DAC_CTRL,
11745e8351deSBard Liao 	RT5670_DAC2_R_SEL_SFT, rt5670_dacr2_src);
11755e8351deSBard Liao 
11765e8351deSBard Liao static const struct snd_kcontrol_new rt5670_dac_r2_mux =
11775e8351deSBard Liao 	SOC_DAPM_ENUM("DAC2 R source", rt5670_dac2r_enum);
11785e8351deSBard Liao 
11795e8351deSBard Liao /*RxDP source*/ /* MX-2D [15:13] */
11805e8351deSBard Liao static const char * const rt5670_rxdp_src[] = {
11815e8351deSBard Liao 	"IF2 DAC", "IF1 DAC", "STO1 ADC Mixer", "STO2 ADC Mixer",
11825e8351deSBard Liao 	"Mono ADC Mixer L", "Mono ADC Mixer R", "DAC1"
11835e8351deSBard Liao };
11845e8351deSBard Liao 
118501957572SMark Brown static SOC_ENUM_SINGLE_DECL(rt5670_rxdp_enum, RT5670_DSP_PATH1,
11865e8351deSBard Liao 	RT5670_RXDP_SEL_SFT, rt5670_rxdp_src);
11875e8351deSBard Liao 
11885e8351deSBard Liao static const struct snd_kcontrol_new rt5670_rxdp_mux =
11895e8351deSBard Liao 	SOC_DAPM_ENUM("DAC2 L source", rt5670_rxdp_enum);
11905e8351deSBard Liao 
11915e8351deSBard Liao /* MX-2D [1] [0] */
11925e8351deSBard Liao static const char * const rt5670_dsp_bypass_src[] = {
11935e8351deSBard Liao 	"DSP", "Bypass"
11945e8351deSBard Liao };
11955e8351deSBard Liao 
119601957572SMark Brown static SOC_ENUM_SINGLE_DECL(rt5670_dsp_ul_enum, RT5670_DSP_PATH1,
11975e8351deSBard Liao 	RT5670_DSP_UL_SFT, rt5670_dsp_bypass_src);
11985e8351deSBard Liao 
11995e8351deSBard Liao static const struct snd_kcontrol_new rt5670_dsp_ul_mux =
12005e8351deSBard Liao 	SOC_DAPM_ENUM("DSP UL source", rt5670_dsp_ul_enum);
12015e8351deSBard Liao 
120201957572SMark Brown static SOC_ENUM_SINGLE_DECL(rt5670_dsp_dl_enum, RT5670_DSP_PATH1,
12035e8351deSBard Liao 	RT5670_DSP_DL_SFT, rt5670_dsp_bypass_src);
12045e8351deSBard Liao 
12055e8351deSBard Liao static const struct snd_kcontrol_new rt5670_dsp_dl_mux =
12065e8351deSBard Liao 	SOC_DAPM_ENUM("DSP DL source", rt5670_dsp_dl_enum);
12075e8351deSBard Liao 
12085e8351deSBard Liao /* Stereo2 ADC source */
12095e8351deSBard Liao /* MX-26 [15] */
12105e8351deSBard Liao static const char * const rt5670_stereo2_adc_lr_src[] = {
12115e8351deSBard Liao 	"L", "LR"
12125e8351deSBard Liao };
12135e8351deSBard Liao 
121401957572SMark Brown static SOC_ENUM_SINGLE_DECL(rt5670_stereo2_adc_lr_enum, RT5670_STO2_ADC_MIXER,
12155e8351deSBard Liao 	RT5670_STO2_ADC_SRC_SFT, rt5670_stereo2_adc_lr_src);
12165e8351deSBard Liao 
12175e8351deSBard Liao static const struct snd_kcontrol_new rt5670_sto2_adc_lr_mux =
12185e8351deSBard Liao 	SOC_DAPM_ENUM("Stereo2 ADC LR source", rt5670_stereo2_adc_lr_enum);
12195e8351deSBard Liao 
12205e8351deSBard Liao /* Stereo1 ADC source */
12215e8351deSBard Liao /* MX-27 MX-26 [12] */
12225e8351deSBard Liao static const char * const rt5670_stereo_adc1_src[] = {
12235e8351deSBard Liao 	"DAC MIX", "ADC"
12245e8351deSBard Liao };
12255e8351deSBard Liao 
122601957572SMark Brown static SOC_ENUM_SINGLE_DECL(rt5670_stereo1_adc1_enum, RT5670_STO1_ADC_MIXER,
12275e8351deSBard Liao 	RT5670_ADC_1_SRC_SFT, rt5670_stereo_adc1_src);
12285e8351deSBard Liao 
1229ea746a29SBard Liao static const struct snd_kcontrol_new rt5670_sto_adc_1_mux =
1230ea746a29SBard Liao 	SOC_DAPM_ENUM("Stereo1 ADC 1 Mux", rt5670_stereo1_adc1_enum);
12315e8351deSBard Liao 
123201957572SMark Brown static SOC_ENUM_SINGLE_DECL(rt5670_stereo2_adc1_enum, RT5670_STO2_ADC_MIXER,
12335e8351deSBard Liao 	RT5670_ADC_1_SRC_SFT, rt5670_stereo_adc1_src);
12345e8351deSBard Liao 
1235ea746a29SBard Liao static const struct snd_kcontrol_new rt5670_sto2_adc_1_mux =
1236ea746a29SBard Liao 	SOC_DAPM_ENUM("Stereo2 ADC 1 Mux", rt5670_stereo2_adc1_enum);
12375e8351deSBard Liao 
12385e8351deSBard Liao 
12395e8351deSBard Liao /* MX-27 MX-26 [11] */
12405e8351deSBard Liao static const char * const rt5670_stereo_adc2_src[] = {
12415e8351deSBard Liao 	"DAC MIX", "DMIC"
12425e8351deSBard Liao };
12435e8351deSBard Liao 
124401957572SMark Brown static SOC_ENUM_SINGLE_DECL(rt5670_stereo1_adc2_enum, RT5670_STO1_ADC_MIXER,
12455e8351deSBard Liao 	RT5670_ADC_2_SRC_SFT, rt5670_stereo_adc2_src);
12465e8351deSBard Liao 
1247ea746a29SBard Liao static const struct snd_kcontrol_new rt5670_sto_adc_2_mux =
1248ea746a29SBard Liao 	SOC_DAPM_ENUM("Stereo1 ADC 2 Mux", rt5670_stereo1_adc2_enum);
12495e8351deSBard Liao 
125001957572SMark Brown static SOC_ENUM_SINGLE_DECL(rt5670_stereo2_adc2_enum, RT5670_STO2_ADC_MIXER,
12515e8351deSBard Liao 	RT5670_ADC_2_SRC_SFT, rt5670_stereo_adc2_src);
12525e8351deSBard Liao 
1253ea746a29SBard Liao static const struct snd_kcontrol_new rt5670_sto2_adc_2_mux =
1254ea746a29SBard Liao 	SOC_DAPM_ENUM("Stereo2 ADC 2 Mux", rt5670_stereo2_adc2_enum);
12555e8351deSBard Liao 
12565e8351deSBard Liao /* MX-27 MX-26 [9:8] */
12575e8351deSBard Liao static const char * const rt5670_stereo_dmic_src[] = {
12585e8351deSBard Liao 	"DMIC1", "DMIC2", "DMIC3"
12595e8351deSBard Liao };
12605e8351deSBard Liao 
126101957572SMark Brown static SOC_ENUM_SINGLE_DECL(rt5670_stereo1_dmic_enum, RT5670_STO1_ADC_MIXER,
12625e8351deSBard Liao 	RT5670_DMIC_SRC_SFT, rt5670_stereo_dmic_src);
12635e8351deSBard Liao 
12645e8351deSBard Liao static const struct snd_kcontrol_new rt5670_sto1_dmic_mux =
12655e8351deSBard Liao 	SOC_DAPM_ENUM("Stereo1 DMIC source", rt5670_stereo1_dmic_enum);
12665e8351deSBard Liao 
126701957572SMark Brown static SOC_ENUM_SINGLE_DECL(rt5670_stereo2_dmic_enum, RT5670_STO2_ADC_MIXER,
12685e8351deSBard Liao 	RT5670_DMIC_SRC_SFT, rt5670_stereo_dmic_src);
12695e8351deSBard Liao 
12705e8351deSBard Liao static const struct snd_kcontrol_new rt5670_sto2_dmic_mux =
12715e8351deSBard Liao 	SOC_DAPM_ENUM("Stereo2 DMIC source", rt5670_stereo2_dmic_enum);
12725e8351deSBard Liao 
12735e8351deSBard Liao /* Mono ADC source */
12745e8351deSBard Liao /* MX-28 [12] */
12755e8351deSBard Liao static const char * const rt5670_mono_adc_l1_src[] = {
12765e8351deSBard Liao 	"Mono DAC MIXL", "ADC1"
12775e8351deSBard Liao };
12785e8351deSBard Liao 
127901957572SMark Brown static SOC_ENUM_SINGLE_DECL(rt5670_mono_adc_l1_enum, RT5670_MONO_ADC_MIXER,
12805e8351deSBard Liao 	RT5670_MONO_ADC_L1_SRC_SFT, rt5670_mono_adc_l1_src);
12815e8351deSBard Liao 
12825e8351deSBard Liao static const struct snd_kcontrol_new rt5670_mono_adc_l1_mux =
12835e8351deSBard Liao 	SOC_DAPM_ENUM("Mono ADC1 left source", rt5670_mono_adc_l1_enum);
12845e8351deSBard Liao /* MX-28 [11] */
12855e8351deSBard Liao static const char * const rt5670_mono_adc_l2_src[] = {
12865e8351deSBard Liao 	"Mono DAC MIXL", "DMIC"
12875e8351deSBard Liao };
12885e8351deSBard Liao 
128901957572SMark Brown static SOC_ENUM_SINGLE_DECL(rt5670_mono_adc_l2_enum, RT5670_MONO_ADC_MIXER,
12905e8351deSBard Liao 	RT5670_MONO_ADC_L2_SRC_SFT, rt5670_mono_adc_l2_src);
12915e8351deSBard Liao 
12925e8351deSBard Liao static const struct snd_kcontrol_new rt5670_mono_adc_l2_mux =
12935e8351deSBard Liao 	SOC_DAPM_ENUM("Mono ADC2 left source", rt5670_mono_adc_l2_enum);
12945e8351deSBard Liao 
12955e8351deSBard Liao /* MX-28 [9:8] */
12965e8351deSBard Liao static const char * const rt5670_mono_dmic_src[] = {
12975e8351deSBard Liao 	"DMIC1", "DMIC2", "DMIC3"
12985e8351deSBard Liao };
12995e8351deSBard Liao 
130001957572SMark Brown static SOC_ENUM_SINGLE_DECL(rt5670_mono_dmic_l_enum, RT5670_MONO_ADC_MIXER,
13015e8351deSBard Liao 	RT5670_MONO_DMIC_L_SRC_SFT, rt5670_mono_dmic_src);
13025e8351deSBard Liao 
13035e8351deSBard Liao static const struct snd_kcontrol_new rt5670_mono_dmic_l_mux =
13045e8351deSBard Liao 	SOC_DAPM_ENUM("Mono DMIC left source", rt5670_mono_dmic_l_enum);
13055e8351deSBard Liao /* MX-28 [1:0] */
130601957572SMark Brown static SOC_ENUM_SINGLE_DECL(rt5670_mono_dmic_r_enum, RT5670_MONO_ADC_MIXER,
13075e8351deSBard Liao 	RT5670_MONO_DMIC_R_SRC_SFT, rt5670_mono_dmic_src);
13085e8351deSBard Liao 
13095e8351deSBard Liao static const struct snd_kcontrol_new rt5670_mono_dmic_r_mux =
13105e8351deSBard Liao 	SOC_DAPM_ENUM("Mono DMIC Right source", rt5670_mono_dmic_r_enum);
13115e8351deSBard Liao /* MX-28 [4] */
13125e8351deSBard Liao static const char * const rt5670_mono_adc_r1_src[] = {
13135e8351deSBard Liao 	"Mono DAC MIXR", "ADC2"
13145e8351deSBard Liao };
13155e8351deSBard Liao 
131601957572SMark Brown static SOC_ENUM_SINGLE_DECL(rt5670_mono_adc_r1_enum, RT5670_MONO_ADC_MIXER,
13175e8351deSBard Liao 	RT5670_MONO_ADC_R1_SRC_SFT, rt5670_mono_adc_r1_src);
13185e8351deSBard Liao 
13195e8351deSBard Liao static const struct snd_kcontrol_new rt5670_mono_adc_r1_mux =
13205e8351deSBard Liao 	SOC_DAPM_ENUM("Mono ADC1 right source", rt5670_mono_adc_r1_enum);
13215e8351deSBard Liao /* MX-28 [3] */
13225e8351deSBard Liao static const char * const rt5670_mono_adc_r2_src[] = {
13235e8351deSBard Liao 	"Mono DAC MIXR", "DMIC"
13245e8351deSBard Liao };
13255e8351deSBard Liao 
132601957572SMark Brown static SOC_ENUM_SINGLE_DECL(rt5670_mono_adc_r2_enum, RT5670_MONO_ADC_MIXER,
13275e8351deSBard Liao 	RT5670_MONO_ADC_R2_SRC_SFT, rt5670_mono_adc_r2_src);
13285e8351deSBard Liao 
13295e8351deSBard Liao static const struct snd_kcontrol_new rt5670_mono_adc_r2_mux =
13305e8351deSBard Liao 	SOC_DAPM_ENUM("Mono ADC2 right source", rt5670_mono_adc_r2_enum);
13315e8351deSBard Liao 
13325e8351deSBard Liao /* MX-2D [3:2] */
13335e8351deSBard Liao static const char * const rt5670_txdp_slot_src[] = {
13345e8351deSBard Liao 	"Slot 0-1", "Slot 2-3", "Slot 4-5", "Slot 6-7"
13355e8351deSBard Liao };
13365e8351deSBard Liao 
133701957572SMark Brown static SOC_ENUM_SINGLE_DECL(rt5670_txdp_slot_enum, RT5670_DSP_PATH1,
13385e8351deSBard Liao 	RT5670_TXDP_SLOT_SEL_SFT, rt5670_txdp_slot_src);
13395e8351deSBard Liao 
13405e8351deSBard Liao static const struct snd_kcontrol_new rt5670_txdp_slot_mux =
13415e8351deSBard Liao 	SOC_DAPM_ENUM("TxDP Slot source", rt5670_txdp_slot_enum);
13425e8351deSBard Liao 
13435e8351deSBard Liao /* MX-2F [15] */
13445e8351deSBard Liao static const char * const rt5670_if1_adc2_in_src[] = {
13455e8351deSBard Liao 	"IF_ADC2", "VAD_ADC"
13465e8351deSBard Liao };
13475e8351deSBard Liao 
134801957572SMark Brown static SOC_ENUM_SINGLE_DECL(rt5670_if1_adc2_in_enum, RT5670_DIG_INF1_DATA,
13495e8351deSBard Liao 	RT5670_IF1_ADC2_IN_SFT, rt5670_if1_adc2_in_src);
13505e8351deSBard Liao 
13515e8351deSBard Liao static const struct snd_kcontrol_new rt5670_if1_adc2_in_mux =
13525e8351deSBard Liao 	SOC_DAPM_ENUM("IF1 ADC2 IN source", rt5670_if1_adc2_in_enum);
13535e8351deSBard Liao 
13545e8351deSBard Liao /* MX-2F [14:12] */
13555e8351deSBard Liao static const char * const rt5670_if2_adc_in_src[] = {
13565e8351deSBard Liao 	"IF_ADC1", "IF_ADC2", "IF_ADC3", "TxDC_DAC", "TxDP_ADC", "VAD_ADC"
13575e8351deSBard Liao };
13585e8351deSBard Liao 
135901957572SMark Brown static SOC_ENUM_SINGLE_DECL(rt5670_if2_adc_in_enum, RT5670_DIG_INF1_DATA,
13605e8351deSBard Liao 	RT5670_IF2_ADC_IN_SFT, rt5670_if2_adc_in_src);
13615e8351deSBard Liao 
13625e8351deSBard Liao static const struct snd_kcontrol_new rt5670_if2_adc_in_mux =
13635e8351deSBard Liao 	SOC_DAPM_ENUM("IF2 ADC IN source", rt5670_if2_adc_in_enum);
13645e8351deSBard Liao 
13655e8351deSBard Liao /* MX-31 [15] [13] [11] [9] */
13665e8351deSBard Liao static const char * const rt5670_pdm_src[] = {
13675e8351deSBard Liao 	"Mono DAC", "Stereo DAC"
13685e8351deSBard Liao };
13695e8351deSBard Liao 
137001957572SMark Brown static SOC_ENUM_SINGLE_DECL(rt5670_pdm1_l_enum, RT5670_PDM_OUT_CTRL,
13715e8351deSBard Liao 	RT5670_PDM1_L_SFT, rt5670_pdm_src);
13725e8351deSBard Liao 
13735e8351deSBard Liao static const struct snd_kcontrol_new rt5670_pdm1_l_mux =
13745e8351deSBard Liao 	SOC_DAPM_ENUM("PDM1 L source", rt5670_pdm1_l_enum);
13755e8351deSBard Liao 
137601957572SMark Brown static SOC_ENUM_SINGLE_DECL(rt5670_pdm1_r_enum, RT5670_PDM_OUT_CTRL,
13775e8351deSBard Liao 	RT5670_PDM1_R_SFT, rt5670_pdm_src);
13785e8351deSBard Liao 
13795e8351deSBard Liao static const struct snd_kcontrol_new rt5670_pdm1_r_mux =
13805e8351deSBard Liao 	SOC_DAPM_ENUM("PDM1 R source", rt5670_pdm1_r_enum);
13815e8351deSBard Liao 
138201957572SMark Brown static SOC_ENUM_SINGLE_DECL(rt5670_pdm2_l_enum, RT5670_PDM_OUT_CTRL,
13835e8351deSBard Liao 	RT5670_PDM2_L_SFT, rt5670_pdm_src);
13845e8351deSBard Liao 
13855e8351deSBard Liao static const struct snd_kcontrol_new rt5670_pdm2_l_mux =
13865e8351deSBard Liao 	SOC_DAPM_ENUM("PDM2 L source", rt5670_pdm2_l_enum);
13875e8351deSBard Liao 
138801957572SMark Brown static SOC_ENUM_SINGLE_DECL(rt5670_pdm2_r_enum, RT5670_PDM_OUT_CTRL,
13895e8351deSBard Liao 	RT5670_PDM2_R_SFT, rt5670_pdm_src);
13905e8351deSBard Liao 
13915e8351deSBard Liao static const struct snd_kcontrol_new rt5670_pdm2_r_mux =
13925e8351deSBard Liao 	SOC_DAPM_ENUM("PDM2 R source", rt5670_pdm2_r_enum);
13935e8351deSBard Liao 
13945e8351deSBard Liao /* MX-FA [12] */
13955e8351deSBard Liao static const char * const rt5670_if1_adc1_in1_src[] = {
13965e8351deSBard Liao 	"IF_ADC1", "IF1_ADC3"
13975e8351deSBard Liao };
13985e8351deSBard Liao 
139901957572SMark Brown static SOC_ENUM_SINGLE_DECL(rt5670_if1_adc1_in1_enum, RT5670_DIG_MISC,
14005e8351deSBard Liao 	RT5670_IF1_ADC1_IN1_SFT, rt5670_if1_adc1_in1_src);
14015e8351deSBard Liao 
14025e8351deSBard Liao static const struct snd_kcontrol_new rt5670_if1_adc1_in1_mux =
14035e8351deSBard Liao 	SOC_DAPM_ENUM("IF1 ADC1 IN1 source", rt5670_if1_adc1_in1_enum);
14045e8351deSBard Liao 
14055e8351deSBard Liao /* MX-FA [11] */
14065e8351deSBard Liao static const char * const rt5670_if1_adc1_in2_src[] = {
14075e8351deSBard Liao 	"IF1_ADC1_IN1", "IF1_ADC4"
14085e8351deSBard Liao };
14095e8351deSBard Liao 
141001957572SMark Brown static SOC_ENUM_SINGLE_DECL(rt5670_if1_adc1_in2_enum, RT5670_DIG_MISC,
14115e8351deSBard Liao 	RT5670_IF1_ADC1_IN2_SFT, rt5670_if1_adc1_in2_src);
14125e8351deSBard Liao 
14135e8351deSBard Liao static const struct snd_kcontrol_new rt5670_if1_adc1_in2_mux =
14145e8351deSBard Liao 	SOC_DAPM_ENUM("IF1 ADC1 IN2 source", rt5670_if1_adc1_in2_enum);
14155e8351deSBard Liao 
14165e8351deSBard Liao /* MX-FA [10] */
14175e8351deSBard Liao static const char * const rt5670_if1_adc2_in1_src[] = {
14185e8351deSBard Liao 	"IF1_ADC2_IN", "IF1_ADC4"
14195e8351deSBard Liao };
14205e8351deSBard Liao 
142101957572SMark Brown static SOC_ENUM_SINGLE_DECL(rt5670_if1_adc2_in1_enum, RT5670_DIG_MISC,
14225e8351deSBard Liao 	RT5670_IF1_ADC2_IN1_SFT, rt5670_if1_adc2_in1_src);
14235e8351deSBard Liao 
14245e8351deSBard Liao static const struct snd_kcontrol_new rt5670_if1_adc2_in1_mux =
14255e8351deSBard Liao 	SOC_DAPM_ENUM("IF1 ADC2 IN1 source", rt5670_if1_adc2_in1_enum);
14265e8351deSBard Liao 
14275e8351deSBard Liao /* MX-9D [9:8] */
14285e8351deSBard Liao static const char * const rt5670_vad_adc_src[] = {
14295e8351deSBard Liao 	"Sto1 ADC L", "Mono ADC L", "Mono ADC R", "Sto2 ADC L"
14305e8351deSBard Liao };
14315e8351deSBard Liao 
143201957572SMark Brown static SOC_ENUM_SINGLE_DECL(rt5670_vad_adc_enum, RT5670_VAD_CTRL4,
14335e8351deSBard Liao 	RT5670_VAD_SEL_SFT, rt5670_vad_adc_src);
14345e8351deSBard Liao 
14355e8351deSBard Liao static const struct snd_kcontrol_new rt5670_vad_adc_mux =
14365e8351deSBard Liao 	SOC_DAPM_ENUM("VAD ADC source", rt5670_vad_adc_enum);
14375e8351deSBard Liao 
rt5670_hp_power_event(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)14385e8351deSBard Liao static int rt5670_hp_power_event(struct snd_soc_dapm_widget *w,
14395e8351deSBard Liao 			   struct snd_kcontrol *kcontrol, int event)
14405e8351deSBard Liao {
14415ba04c66SKuninori Morimoto 	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
14425ba04c66SKuninori Morimoto 	struct rt5670_priv *rt5670 = snd_soc_component_get_drvdata(component);
14435e8351deSBard Liao 
14445e8351deSBard Liao 	switch (event) {
14455e8351deSBard Liao 	case SND_SOC_DAPM_POST_PMU:
14465e8351deSBard Liao 		regmap_update_bits(rt5670->regmap, RT5670_CHARGE_PUMP,
14475e8351deSBard Liao 			RT5670_PM_HP_MASK, RT5670_PM_HP_HV);
14485e8351deSBard Liao 		regmap_update_bits(rt5670->regmap, RT5670_GEN_CTRL2,
14495e8351deSBard Liao 			0x0400, 0x0400);
14505e8351deSBard Liao 		/* headphone amp power on */
14515e8351deSBard Liao 		regmap_update_bits(rt5670->regmap, RT5670_PWR_ANLG1,
14525e8351deSBard Liao 			RT5670_PWR_HA |	RT5670_PWR_FV1 |
14535e8351deSBard Liao 			RT5670_PWR_FV2,	RT5670_PWR_HA |
14545e8351deSBard Liao 			RT5670_PWR_FV1 | RT5670_PWR_FV2);
14555e8351deSBard Liao 		/* depop parameters */
14565e8351deSBard Liao 		regmap_write(rt5670->regmap, RT5670_DEPOP_M2, 0x3100);
14575e8351deSBard Liao 		regmap_write(rt5670->regmap, RT5670_DEPOP_M1, 0x8009);
14585e8351deSBard Liao 		regmap_write(rt5670->regmap, RT5670_PR_BASE +
14595e8351deSBard Liao 			RT5670_HP_DCC_INT1, 0x9f00);
14605e8351deSBard Liao 		mdelay(20);
14615e8351deSBard Liao 		regmap_write(rt5670->regmap, RT5670_DEPOP_M1, 0x8019);
14625e8351deSBard Liao 		break;
14635e8351deSBard Liao 	case SND_SOC_DAPM_PRE_PMD:
14645e8351deSBard Liao 		regmap_write(rt5670->regmap, RT5670_DEPOP_M1, 0x0004);
14655e8351deSBard Liao 		msleep(30);
14665e8351deSBard Liao 		break;
14675e8351deSBard Liao 	default:
14685e8351deSBard Liao 		return 0;
14695e8351deSBard Liao 	}
14705e8351deSBard Liao 
14715e8351deSBard Liao 	return 0;
14725e8351deSBard Liao }
14735e8351deSBard Liao 
rt5670_hp_event(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)14745e8351deSBard Liao static int rt5670_hp_event(struct snd_soc_dapm_widget *w,
14755e8351deSBard Liao 	struct snd_kcontrol *kcontrol, int event)
14765e8351deSBard Liao {
14775ba04c66SKuninori Morimoto 	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
14785ba04c66SKuninori Morimoto 	struct rt5670_priv *rt5670 = snd_soc_component_get_drvdata(component);
14795e8351deSBard Liao 
14805e8351deSBard Liao 	switch (event) {
14815e8351deSBard Liao 	case SND_SOC_DAPM_POST_PMU:
14825e8351deSBard Liao 		/* headphone unmute sequence */
14835e8351deSBard Liao 		regmap_write(rt5670->regmap, RT5670_PR_BASE +
14845e8351deSBard Liao 				RT5670_MAMP_INT_REG2, 0xb400);
14855e8351deSBard Liao 		regmap_write(rt5670->regmap, RT5670_DEPOP_M3, 0x0772);
14865e8351deSBard Liao 		regmap_write(rt5670->regmap, RT5670_DEPOP_M1, 0x805d);
14875e8351deSBard Liao 		regmap_write(rt5670->regmap, RT5670_DEPOP_M1, 0x831d);
14885e8351deSBard Liao 		regmap_update_bits(rt5670->regmap, RT5670_GEN_CTRL2,
14895e8351deSBard Liao 				0x0300, 0x0300);
14905e8351deSBard Liao 		regmap_update_bits(rt5670->regmap, RT5670_HP_VOL,
14915e8351deSBard Liao 			RT5670_L_MUTE | RT5670_R_MUTE, 0);
14925e8351deSBard Liao 		msleep(80);
14935e8351deSBard Liao 		regmap_write(rt5670->regmap, RT5670_DEPOP_M1, 0x8019);
14945e8351deSBard Liao 		break;
14955e8351deSBard Liao 
14965e8351deSBard Liao 	case SND_SOC_DAPM_PRE_PMD:
14975e8351deSBard Liao 		/* headphone mute sequence */
14985e8351deSBard Liao 		regmap_write(rt5670->regmap, RT5670_PR_BASE +
14995e8351deSBard Liao 				RT5670_MAMP_INT_REG2, 0xb400);
15005e8351deSBard Liao 		regmap_write(rt5670->regmap, RT5670_DEPOP_M3, 0x0772);
15015e8351deSBard Liao 		regmap_write(rt5670->regmap, RT5670_DEPOP_M1, 0x803d);
15025e8351deSBard Liao 		mdelay(10);
15035e8351deSBard Liao 		regmap_write(rt5670->regmap, RT5670_DEPOP_M1, 0x831d);
15045e8351deSBard Liao 		mdelay(10);
15055e8351deSBard Liao 		regmap_update_bits(rt5670->regmap, RT5670_HP_VOL,
15065e8351deSBard Liao 				   RT5670_L_MUTE | RT5670_R_MUTE,
15075e8351deSBard Liao 				   RT5670_L_MUTE | RT5670_R_MUTE);
15085e8351deSBard Liao 		msleep(20);
15095e8351deSBard Liao 		regmap_update_bits(rt5670->regmap,
15105e8351deSBard Liao 				   RT5670_GEN_CTRL2, 0x0300, 0x0);
15115e8351deSBard Liao 		regmap_write(rt5670->regmap, RT5670_DEPOP_M1, 0x8019);
15125e8351deSBard Liao 		regmap_write(rt5670->regmap, RT5670_DEPOP_M3, 0x0707);
15135e8351deSBard Liao 		regmap_write(rt5670->regmap, RT5670_PR_BASE +
15145e8351deSBard Liao 				RT5670_MAMP_INT_REG2, 0xfc00);
15155e8351deSBard Liao 		break;
15165e8351deSBard Liao 
15175e8351deSBard Liao 	default:
15185e8351deSBard Liao 		return 0;
15195e8351deSBard Liao 	}
15205e8351deSBard Liao 
15215e8351deSBard Liao 	return 0;
15225e8351deSBard Liao }
15235e8351deSBard Liao 
rt5670_spk_event(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)152485ca6b17SHans de Goede static int rt5670_spk_event(struct snd_soc_dapm_widget *w,
152585ca6b17SHans de Goede 	struct snd_kcontrol *kcontrol, int event)
152685ca6b17SHans de Goede {
152785ca6b17SHans de Goede 	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
152885ca6b17SHans de Goede 	struct rt5670_priv *rt5670 = snd_soc_component_get_drvdata(component);
152985ca6b17SHans de Goede 
1530c14f61a8SHans de Goede 	if (!rt5670->gpio1_is_ext_spk_en)
153185ca6b17SHans de Goede 		return 0;
153285ca6b17SHans de Goede 
153385ca6b17SHans de Goede 	switch (event) {
153485ca6b17SHans de Goede 	case SND_SOC_DAPM_POST_PMU:
153585ca6b17SHans de Goede 		regmap_update_bits(rt5670->regmap, RT5670_GPIO_CTRL2,
153685ca6b17SHans de Goede 				   RT5670_GP1_OUT_MASK, RT5670_GP1_OUT_HI);
153785ca6b17SHans de Goede 		break;
153885ca6b17SHans de Goede 
153985ca6b17SHans de Goede 	case SND_SOC_DAPM_PRE_PMD:
154085ca6b17SHans de Goede 		regmap_update_bits(rt5670->regmap, RT5670_GPIO_CTRL2,
154185ca6b17SHans de Goede 				   RT5670_GP1_OUT_MASK, RT5670_GP1_OUT_LO);
154285ca6b17SHans de Goede 		break;
154385ca6b17SHans de Goede 
154485ca6b17SHans de Goede 	default:
154585ca6b17SHans de Goede 		return 0;
154685ca6b17SHans de Goede 	}
154785ca6b17SHans de Goede 
154885ca6b17SHans de Goede 	return 0;
154985ca6b17SHans de Goede }
155085ca6b17SHans de Goede 
rt5670_bst1_event(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)15515e8351deSBard Liao static int rt5670_bst1_event(struct snd_soc_dapm_widget *w,
15525e8351deSBard Liao 	struct snd_kcontrol *kcontrol, int event)
15535e8351deSBard Liao {
15545ba04c66SKuninori Morimoto 	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
15555e8351deSBard Liao 
15565e8351deSBard Liao 	switch (event) {
15575e8351deSBard Liao 	case SND_SOC_DAPM_POST_PMU:
15585ba04c66SKuninori Morimoto 		snd_soc_component_update_bits(component, RT5670_PWR_ANLG2,
15595e8351deSBard Liao 				    RT5670_PWR_BST1_P, RT5670_PWR_BST1_P);
15605e8351deSBard Liao 		break;
15615e8351deSBard Liao 
15625e8351deSBard Liao 	case SND_SOC_DAPM_PRE_PMD:
15635ba04c66SKuninori Morimoto 		snd_soc_component_update_bits(component, RT5670_PWR_ANLG2,
15645e8351deSBard Liao 				    RT5670_PWR_BST1_P, 0);
15655e8351deSBard Liao 		break;
15665e8351deSBard Liao 
15675e8351deSBard Liao 	default:
15685e8351deSBard Liao 		return 0;
15695e8351deSBard Liao 	}
15705e8351deSBard Liao 
15715e8351deSBard Liao 	return 0;
15725e8351deSBard Liao }
15735e8351deSBard Liao 
rt5670_bst2_event(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)15745e8351deSBard Liao static int rt5670_bst2_event(struct snd_soc_dapm_widget *w,
15755e8351deSBard Liao 	struct snd_kcontrol *kcontrol, int event)
15765e8351deSBard Liao {
15775ba04c66SKuninori Morimoto 	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
15785e8351deSBard Liao 
15795e8351deSBard Liao 	switch (event) {
15805e8351deSBard Liao 	case SND_SOC_DAPM_POST_PMU:
15815ba04c66SKuninori Morimoto 		snd_soc_component_update_bits(component, RT5670_PWR_ANLG2,
15825e8351deSBard Liao 				    RT5670_PWR_BST2_P, RT5670_PWR_BST2_P);
15835e8351deSBard Liao 		break;
15845e8351deSBard Liao 
15855e8351deSBard Liao 	case SND_SOC_DAPM_PRE_PMD:
15865ba04c66SKuninori Morimoto 		snd_soc_component_update_bits(component, RT5670_PWR_ANLG2,
15875e8351deSBard Liao 				    RT5670_PWR_BST2_P, 0);
15885e8351deSBard Liao 		break;
15895e8351deSBard Liao 
15905e8351deSBard Liao 	default:
15915e8351deSBard Liao 		return 0;
15925e8351deSBard Liao 	}
15935e8351deSBard Liao 
15945e8351deSBard Liao 	return 0;
15955e8351deSBard Liao }
15965e8351deSBard Liao 
15975e8351deSBard Liao static const struct snd_soc_dapm_widget rt5670_dapm_widgets[] = {
15985e8351deSBard Liao 	SND_SOC_DAPM_SUPPLY("PLL1", RT5670_PWR_ANLG2,
15995e8351deSBard Liao 			    RT5670_PWR_PLL_BIT, 0, NULL, 0),
16005e8351deSBard Liao 	SND_SOC_DAPM_SUPPLY("I2S DSP", RT5670_PWR_DIG2,
16015e8351deSBard Liao 			    RT5670_PWR_I2S_DSP_BIT, 0, NULL, 0),
16025e8351deSBard Liao 	SND_SOC_DAPM_SUPPLY("Mic Det Power", RT5670_PWR_VOL,
16035e8351deSBard Liao 			    RT5670_PWR_MIC_DET_BIT, 0, NULL, 0),
16045e8351deSBard Liao 
16055e8351deSBard Liao 	/* ASRC */
16065e8351deSBard Liao 	SND_SOC_DAPM_SUPPLY_S("I2S1 ASRC", 1, RT5670_ASRC_1,
16075e8351deSBard Liao 			      11, 0, NULL, 0),
16085e8351deSBard Liao 	SND_SOC_DAPM_SUPPLY_S("I2S2 ASRC", 1, RT5670_ASRC_1,
16095e8351deSBard Liao 			      12, 0, NULL, 0),
16105e8351deSBard Liao 	SND_SOC_DAPM_SUPPLY_S("DAC STO ASRC", 1, RT5670_ASRC_1,
16115e8351deSBard Liao 			      10, 0, NULL, 0),
16125e8351deSBard Liao 	SND_SOC_DAPM_SUPPLY_S("DAC MONO L ASRC", 1, RT5670_ASRC_1,
16135e8351deSBard Liao 			      9, 0, NULL, 0),
16145e8351deSBard Liao 	SND_SOC_DAPM_SUPPLY_S("DAC MONO R ASRC", 1, RT5670_ASRC_1,
16155e8351deSBard Liao 			      8, 0, NULL, 0),
1616ff4541c3SBard Liao 	SND_SOC_DAPM_SUPPLY_S("DMIC STO1 ASRC", 1, RT5670_ASRC_1,
1617ff4541c3SBard Liao 			      7, 0, NULL, 0),
1618ff4541c3SBard Liao 	SND_SOC_DAPM_SUPPLY_S("DMIC STO2 ASRC", 1, RT5670_ASRC_1,
1619ff4541c3SBard Liao 			      6, 0, NULL, 0),
1620ff4541c3SBard Liao 	SND_SOC_DAPM_SUPPLY_S("DMIC MONO L ASRC", 1, RT5670_ASRC_1,
1621ff4541c3SBard Liao 			      5, 0, NULL, 0),
1622ff4541c3SBard Liao 	SND_SOC_DAPM_SUPPLY_S("DMIC MONO R ASRC", 1, RT5670_ASRC_1,
1623ff4541c3SBard Liao 			      4, 0, NULL, 0),
16245e8351deSBard Liao 	SND_SOC_DAPM_SUPPLY_S("ADC STO1 ASRC", 1, RT5670_ASRC_1,
16255e8351deSBard Liao 			      3, 0, NULL, 0),
16265e8351deSBard Liao 	SND_SOC_DAPM_SUPPLY_S("ADC STO2 ASRC", 1, RT5670_ASRC_1,
16275e8351deSBard Liao 			      2, 0, NULL, 0),
16285e8351deSBard Liao 	SND_SOC_DAPM_SUPPLY_S("ADC MONO L ASRC", 1, RT5670_ASRC_1,
16295e8351deSBard Liao 			      1, 0, NULL, 0),
16305e8351deSBard Liao 	SND_SOC_DAPM_SUPPLY_S("ADC MONO R ASRC", 1, RT5670_ASRC_1,
16315e8351deSBard Liao 			      0, 0, NULL, 0),
16325e8351deSBard Liao 
16335e8351deSBard Liao 	/* Input Side */
16345e8351deSBard Liao 	/* micbias */
16355e8351deSBard Liao 	SND_SOC_DAPM_SUPPLY("MICBIAS1", RT5670_PWR_ANLG2,
16365e8351deSBard Liao 			     RT5670_PWR_MB1_BIT, 0, NULL, 0),
16375e8351deSBard Liao 
16385e8351deSBard Liao 	/* Input Lines */
16395e8351deSBard Liao 	SND_SOC_DAPM_INPUT("DMIC L1"),
16405e8351deSBard Liao 	SND_SOC_DAPM_INPUT("DMIC R1"),
16415e8351deSBard Liao 	SND_SOC_DAPM_INPUT("DMIC L2"),
16425e8351deSBard Liao 	SND_SOC_DAPM_INPUT("DMIC R2"),
16435e8351deSBard Liao 	SND_SOC_DAPM_INPUT("DMIC L3"),
16445e8351deSBard Liao 	SND_SOC_DAPM_INPUT("DMIC R3"),
16455e8351deSBard Liao 
16465e8351deSBard Liao 	SND_SOC_DAPM_INPUT("IN1P"),
16475e8351deSBard Liao 	SND_SOC_DAPM_INPUT("IN1N"),
16485e8351deSBard Liao 	SND_SOC_DAPM_INPUT("IN2P"),
16495e8351deSBard Liao 	SND_SOC_DAPM_INPUT("IN2N"),
16505e8351deSBard Liao 
16515e8351deSBard Liao 	SND_SOC_DAPM_PGA("DMIC1", SND_SOC_NOPM, 0, 0, NULL, 0),
16525e8351deSBard Liao 	SND_SOC_DAPM_PGA("DMIC2", SND_SOC_NOPM, 0, 0, NULL, 0),
16535e8351deSBard Liao 	SND_SOC_DAPM_PGA("DMIC3", SND_SOC_NOPM, 0, 0, NULL, 0),
16545e8351deSBard Liao 
16555e8351deSBard Liao 	SND_SOC_DAPM_SUPPLY("DMIC CLK", SND_SOC_NOPM, 0, 0,
16565e8351deSBard Liao 			    set_dmic_clk, SND_SOC_DAPM_PRE_PMU),
16575e8351deSBard Liao 	SND_SOC_DAPM_SUPPLY("DMIC1 Power", RT5670_DMIC_CTRL1,
16585e8351deSBard Liao 			    RT5670_DMIC_1_EN_SFT, 0, NULL, 0),
16595e8351deSBard Liao 	SND_SOC_DAPM_SUPPLY("DMIC2 Power", RT5670_DMIC_CTRL1,
16605e8351deSBard Liao 			    RT5670_DMIC_2_EN_SFT, 0, NULL, 0),
16615e8351deSBard Liao 	SND_SOC_DAPM_SUPPLY("DMIC3 Power", RT5670_DMIC_CTRL1,
16625e8351deSBard Liao 			    RT5670_DMIC_3_EN_SFT, 0, NULL, 0),
16635e8351deSBard Liao 	/* Boost */
16645e8351deSBard Liao 	SND_SOC_DAPM_PGA_E("BST1", RT5670_PWR_ANLG2, RT5670_PWR_BST1_BIT,
16655e8351deSBard Liao 			   0, NULL, 0, rt5670_bst1_event,
16665e8351deSBard Liao 			   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
16675e8351deSBard Liao 	SND_SOC_DAPM_PGA_E("BST2", RT5670_PWR_ANLG2, RT5670_PWR_BST2_BIT,
16685e8351deSBard Liao 			   0, NULL, 0, rt5670_bst2_event,
16695e8351deSBard Liao 			   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
16705e8351deSBard Liao 	/* Input Volume */
16715e8351deSBard Liao 	SND_SOC_DAPM_PGA("INL VOL", RT5670_PWR_VOL,
16725e8351deSBard Liao 			 RT5670_PWR_IN_L_BIT, 0, NULL, 0),
16735e8351deSBard Liao 	SND_SOC_DAPM_PGA("INR VOL", RT5670_PWR_VOL,
16745e8351deSBard Liao 			 RT5670_PWR_IN_R_BIT, 0, NULL, 0),
16755e8351deSBard Liao 
16765e8351deSBard Liao 	/* REC Mixer */
16775e8351deSBard Liao 	SND_SOC_DAPM_MIXER("RECMIXL", RT5670_PWR_MIXER, RT5670_PWR_RM_L_BIT, 0,
16785e8351deSBard Liao 			   rt5670_rec_l_mix, ARRAY_SIZE(rt5670_rec_l_mix)),
16795e8351deSBard Liao 	SND_SOC_DAPM_MIXER("RECMIXR", RT5670_PWR_MIXER, RT5670_PWR_RM_R_BIT, 0,
16805e8351deSBard Liao 			   rt5670_rec_r_mix, ARRAY_SIZE(rt5670_rec_r_mix)),
16815e8351deSBard Liao 	/* ADCs */
16825e8351deSBard Liao 	SND_SOC_DAPM_ADC("ADC 1", NULL, SND_SOC_NOPM, 0, 0),
16835e8351deSBard Liao 	SND_SOC_DAPM_ADC("ADC 2", NULL, SND_SOC_NOPM, 0, 0),
16845e8351deSBard Liao 
16855e8351deSBard Liao 	SND_SOC_DAPM_PGA("ADC 1_2", SND_SOC_NOPM, 0, 0, NULL, 0),
16865e8351deSBard Liao 
16875e8351deSBard Liao 	SND_SOC_DAPM_SUPPLY("ADC 1 power", RT5670_PWR_DIG1,
16885e8351deSBard Liao 			    RT5670_PWR_ADC_L_BIT, 0, NULL, 0),
16895e8351deSBard Liao 	SND_SOC_DAPM_SUPPLY("ADC 2 power", RT5670_PWR_DIG1,
16905e8351deSBard Liao 			    RT5670_PWR_ADC_R_BIT, 0, NULL, 0),
16915e8351deSBard Liao 	SND_SOC_DAPM_SUPPLY("ADC clock", RT5670_PR_BASE +
16925e8351deSBard Liao 			    RT5670_CHOP_DAC_ADC, 12, 0, NULL, 0),
16935e8351deSBard Liao 	/* ADC Mux */
16945e8351deSBard Liao 	SND_SOC_DAPM_MUX("Stereo1 DMIC Mux", SND_SOC_NOPM, 0, 0,
16955e8351deSBard Liao 			 &rt5670_sto1_dmic_mux),
16965e8351deSBard Liao 	SND_SOC_DAPM_MUX("Stereo1 ADC L2 Mux", SND_SOC_NOPM, 0, 0,
1697ea746a29SBard Liao 			 &rt5670_sto_adc_2_mux),
16985e8351deSBard Liao 	SND_SOC_DAPM_MUX("Stereo1 ADC R2 Mux", SND_SOC_NOPM, 0, 0,
1699ea746a29SBard Liao 			 &rt5670_sto_adc_2_mux),
17005e8351deSBard Liao 	SND_SOC_DAPM_MUX("Stereo1 ADC L1 Mux", SND_SOC_NOPM, 0, 0,
1701ea746a29SBard Liao 			 &rt5670_sto_adc_1_mux),
17025e8351deSBard Liao 	SND_SOC_DAPM_MUX("Stereo1 ADC R1 Mux", SND_SOC_NOPM, 0, 0,
1703ea746a29SBard Liao 			 &rt5670_sto_adc_1_mux),
17045e8351deSBard Liao 	SND_SOC_DAPM_MUX("Stereo2 DMIC Mux", SND_SOC_NOPM, 0, 0,
17055e8351deSBard Liao 			 &rt5670_sto2_dmic_mux),
17065e8351deSBard Liao 	SND_SOC_DAPM_MUX("Stereo2 ADC L2 Mux", SND_SOC_NOPM, 0, 0,
1707ea746a29SBard Liao 			 &rt5670_sto2_adc_2_mux),
17085e8351deSBard Liao 	SND_SOC_DAPM_MUX("Stereo2 ADC R2 Mux", SND_SOC_NOPM, 0, 0,
1709ea746a29SBard Liao 			 &rt5670_sto2_adc_2_mux),
17105e8351deSBard Liao 	SND_SOC_DAPM_MUX("Stereo2 ADC L1 Mux", SND_SOC_NOPM, 0, 0,
1711ea746a29SBard Liao 			 &rt5670_sto2_adc_1_mux),
17125e8351deSBard Liao 	SND_SOC_DAPM_MUX("Stereo2 ADC R1 Mux", SND_SOC_NOPM, 0, 0,
1713ea746a29SBard Liao 			 &rt5670_sto2_adc_1_mux),
17145e8351deSBard Liao 	SND_SOC_DAPM_MUX("Stereo2 ADC LR Mux", SND_SOC_NOPM, 0, 0,
17155e8351deSBard Liao 			 &rt5670_sto2_adc_lr_mux),
17165e8351deSBard Liao 	SND_SOC_DAPM_MUX("Mono DMIC L Mux", SND_SOC_NOPM, 0, 0,
17175e8351deSBard Liao 			 &rt5670_mono_dmic_l_mux),
17185e8351deSBard Liao 	SND_SOC_DAPM_MUX("Mono DMIC R Mux", SND_SOC_NOPM, 0, 0,
17195e8351deSBard Liao 			 &rt5670_mono_dmic_r_mux),
17205e8351deSBard Liao 	SND_SOC_DAPM_MUX("Mono ADC L2 Mux", SND_SOC_NOPM, 0, 0,
17215e8351deSBard Liao 			 &rt5670_mono_adc_l2_mux),
17225e8351deSBard Liao 	SND_SOC_DAPM_MUX("Mono ADC L1 Mux", SND_SOC_NOPM, 0, 0,
17235e8351deSBard Liao 			 &rt5670_mono_adc_l1_mux),
17245e8351deSBard Liao 	SND_SOC_DAPM_MUX("Mono ADC R1 Mux", SND_SOC_NOPM, 0, 0,
17255e8351deSBard Liao 			 &rt5670_mono_adc_r1_mux),
17265e8351deSBard Liao 	SND_SOC_DAPM_MUX("Mono ADC R2 Mux", SND_SOC_NOPM, 0, 0,
17275e8351deSBard Liao 			 &rt5670_mono_adc_r2_mux),
17285e8351deSBard Liao 	/* ADC Mixer */
17295e8351deSBard Liao 	SND_SOC_DAPM_SUPPLY("ADC Stereo1 Filter", RT5670_PWR_DIG2,
17305e8351deSBard Liao 			    RT5670_PWR_ADC_S1F_BIT, 0, NULL, 0),
17315e8351deSBard Liao 	SND_SOC_DAPM_SUPPLY("ADC Stereo2 Filter", RT5670_PWR_DIG2,
17325e8351deSBard Liao 			    RT5670_PWR_ADC_S2F_BIT, 0, NULL, 0),
173302aa946eSHans de Goede 	SND_SOC_DAPM_MIXER("Sto1 ADC MIXL", SND_SOC_NOPM, 0, 0,
173402aa946eSHans de Goede 			   rt5670_sto1_adc_l_mix, ARRAY_SIZE(rt5670_sto1_adc_l_mix)),
173502aa946eSHans de Goede 	SND_SOC_DAPM_MIXER("Sto1 ADC MIXR", SND_SOC_NOPM, 0, 0,
173602aa946eSHans de Goede 			   rt5670_sto1_adc_r_mix, ARRAY_SIZE(rt5670_sto1_adc_r_mix)),
17375e8351deSBard Liao 	SND_SOC_DAPM_MIXER("Sto2 ADC MIXL", SND_SOC_NOPM, 0, 0,
17385e8351deSBard Liao 			   rt5670_sto2_adc_l_mix,
17395e8351deSBard Liao 			   ARRAY_SIZE(rt5670_sto2_adc_l_mix)),
17405e8351deSBard Liao 	SND_SOC_DAPM_MIXER("Sto2 ADC MIXR", SND_SOC_NOPM, 0, 0,
17415e8351deSBard Liao 			   rt5670_sto2_adc_r_mix,
17425e8351deSBard Liao 			   ARRAY_SIZE(rt5670_sto2_adc_r_mix)),
17435e8351deSBard Liao 	SND_SOC_DAPM_SUPPLY("ADC Mono Left Filter", RT5670_PWR_DIG2,
17445e8351deSBard Liao 			    RT5670_PWR_ADC_MF_L_BIT, 0, NULL, 0),
17455e8351deSBard Liao 	SND_SOC_DAPM_MIXER("Mono ADC MIXL", RT5670_MONO_ADC_DIG_VOL,
17465e8351deSBard Liao 			   RT5670_L_MUTE_SFT, 1, rt5670_mono_adc_l_mix,
17475e8351deSBard Liao 			   ARRAY_SIZE(rt5670_mono_adc_l_mix)),
17485e8351deSBard Liao 	SND_SOC_DAPM_SUPPLY("ADC Mono Right Filter", RT5670_PWR_DIG2,
17495e8351deSBard Liao 			    RT5670_PWR_ADC_MF_R_BIT, 0, NULL, 0),
17505e8351deSBard Liao 	SND_SOC_DAPM_MIXER("Mono ADC MIXR", RT5670_MONO_ADC_DIG_VOL,
17515e8351deSBard Liao 			   RT5670_R_MUTE_SFT, 1, rt5670_mono_adc_r_mix,
17525e8351deSBard Liao 			   ARRAY_SIZE(rt5670_mono_adc_r_mix)),
17535e8351deSBard Liao 
17545e8351deSBard Liao 	/* ADC PGA */
17555e8351deSBard Liao 	SND_SOC_DAPM_PGA("Stereo1 ADC MIXL", SND_SOC_NOPM, 0, 0, NULL, 0),
17565e8351deSBard Liao 	SND_SOC_DAPM_PGA("Stereo1 ADC MIXR", SND_SOC_NOPM, 0, 0, NULL, 0),
17575e8351deSBard Liao 	SND_SOC_DAPM_PGA("Stereo2 ADC MIXL", SND_SOC_NOPM, 0, 0, NULL, 0),
17585e8351deSBard Liao 	SND_SOC_DAPM_PGA("Stereo2 ADC MIXR", SND_SOC_NOPM, 0, 0, NULL, 0),
17595e8351deSBard Liao 	SND_SOC_DAPM_PGA("Sto2 ADC LR MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
17605e8351deSBard Liao 	SND_SOC_DAPM_PGA("Stereo1 ADC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
17615e8351deSBard Liao 	SND_SOC_DAPM_PGA("Stereo2 ADC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
17625e8351deSBard Liao 	SND_SOC_DAPM_PGA("Mono ADC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
17635e8351deSBard Liao 	SND_SOC_DAPM_PGA("VAD_ADC", SND_SOC_NOPM, 0, 0, NULL, 0),
17645e8351deSBard Liao 	SND_SOC_DAPM_PGA("IF_ADC1", SND_SOC_NOPM, 0, 0, NULL, 0),
17655e8351deSBard Liao 	SND_SOC_DAPM_PGA("IF_ADC2", SND_SOC_NOPM, 0, 0, NULL, 0),
17665e8351deSBard Liao 	SND_SOC_DAPM_PGA("IF_ADC3", SND_SOC_NOPM, 0, 0, NULL, 0),
17675e8351deSBard Liao 	SND_SOC_DAPM_PGA("IF1_ADC1", SND_SOC_NOPM, 0, 0, NULL, 0),
17685e8351deSBard Liao 	SND_SOC_DAPM_PGA("IF1_ADC2", SND_SOC_NOPM, 0, 0, NULL, 0),
17695e8351deSBard Liao 	SND_SOC_DAPM_PGA("IF1_ADC3", SND_SOC_NOPM, 0, 0, NULL, 0),
17705e8351deSBard Liao 
17715e8351deSBard Liao 	/* DSP */
17725e8351deSBard Liao 	SND_SOC_DAPM_PGA("TxDP_ADC", SND_SOC_NOPM, 0, 0, NULL, 0),
17735e8351deSBard Liao 	SND_SOC_DAPM_PGA("TxDP_ADC_L", SND_SOC_NOPM, 0, 0, NULL, 0),
17745e8351deSBard Liao 	SND_SOC_DAPM_PGA("TxDP_ADC_R", SND_SOC_NOPM, 0, 0, NULL, 0),
17755e8351deSBard Liao 	SND_SOC_DAPM_PGA("TxDC_DAC", SND_SOC_NOPM, 0, 0, NULL, 0),
17765e8351deSBard Liao 
17775e8351deSBard Liao 	SND_SOC_DAPM_MUX("TDM Data Mux", SND_SOC_NOPM, 0, 0,
17785e8351deSBard Liao 			 &rt5670_txdp_slot_mux),
17795e8351deSBard Liao 
17805e8351deSBard Liao 	SND_SOC_DAPM_MUX("DSP UL Mux", SND_SOC_NOPM, 0, 0,
17815e8351deSBard Liao 			 &rt5670_dsp_ul_mux),
17825e8351deSBard Liao 	SND_SOC_DAPM_MUX("DSP DL Mux", SND_SOC_NOPM, 0, 0,
17835e8351deSBard Liao 			 &rt5670_dsp_dl_mux),
17845e8351deSBard Liao 
17855e8351deSBard Liao 	SND_SOC_DAPM_MUX("RxDP Mux", SND_SOC_NOPM, 0, 0,
17865e8351deSBard Liao 			 &rt5670_rxdp_mux),
17875e8351deSBard Liao 
17885e8351deSBard Liao 	/* IF2 Mux */
17895e8351deSBard Liao 	SND_SOC_DAPM_MUX("IF2 ADC Mux", SND_SOC_NOPM, 0, 0,
17905e8351deSBard Liao 			 &rt5670_if2_adc_in_mux),
17915e8351deSBard Liao 
17925e8351deSBard Liao 	/* Digital Interface */
17935e8351deSBard Liao 	SND_SOC_DAPM_SUPPLY("I2S1", RT5670_PWR_DIG1,
17945e8351deSBard Liao 			    RT5670_PWR_I2S1_BIT, 0, NULL, 0),
17955e8351deSBard Liao 	SND_SOC_DAPM_PGA("IF1 DAC1", SND_SOC_NOPM, 0, 0, NULL, 0),
17965e8351deSBard Liao 	SND_SOC_DAPM_PGA("IF1 DAC2", SND_SOC_NOPM, 0, 0, NULL, 0),
17975e8351deSBard Liao 	SND_SOC_DAPM_PGA("IF1 DAC1 L", SND_SOC_NOPM, 0, 0, NULL, 0),
17985e8351deSBard Liao 	SND_SOC_DAPM_PGA("IF1 DAC1 R", SND_SOC_NOPM, 0, 0, NULL, 0),
17995e8351deSBard Liao 	SND_SOC_DAPM_PGA("IF1 DAC2 L", SND_SOC_NOPM, 0, 0, NULL, 0),
18005e8351deSBard Liao 	SND_SOC_DAPM_PGA("IF1 DAC2 R", SND_SOC_NOPM, 0, 0, NULL, 0),
18015e8351deSBard Liao 	SND_SOC_DAPM_PGA("IF1 ADC", SND_SOC_NOPM, 0, 0, NULL, 0),
18025e8351deSBard Liao 	SND_SOC_DAPM_PGA("IF1 ADC L", SND_SOC_NOPM, 0, 0, NULL, 0),
18035e8351deSBard Liao 	SND_SOC_DAPM_PGA("IF1 ADC R", SND_SOC_NOPM, 0, 0, NULL, 0),
18045e8351deSBard Liao 	SND_SOC_DAPM_SUPPLY("I2S2", RT5670_PWR_DIG1,
18055e8351deSBard Liao 			    RT5670_PWR_I2S2_BIT, 0, NULL, 0),
18065e8351deSBard Liao 	SND_SOC_DAPM_PGA("IF2 DAC", SND_SOC_NOPM, 0, 0, NULL, 0),
18075e8351deSBard Liao 	SND_SOC_DAPM_PGA("IF2 DAC L", SND_SOC_NOPM, 0, 0, NULL, 0),
18085e8351deSBard Liao 	SND_SOC_DAPM_PGA("IF2 DAC R", SND_SOC_NOPM, 0, 0, NULL, 0),
18095e8351deSBard Liao 	SND_SOC_DAPM_PGA("IF2 ADC", SND_SOC_NOPM, 0, 0, NULL, 0),
18105e8351deSBard Liao 	SND_SOC_DAPM_PGA("IF2 ADC L", SND_SOC_NOPM, 0, 0, NULL, 0),
18115e8351deSBard Liao 	SND_SOC_DAPM_PGA("IF2 ADC R", SND_SOC_NOPM, 0, 0, NULL, 0),
18125e8351deSBard Liao 
18135e8351deSBard Liao 	/* Digital Interface Select */
18145e8351deSBard Liao 	SND_SOC_DAPM_MUX("IF1 ADC1 IN1 Mux", SND_SOC_NOPM, 0, 0,
18155e8351deSBard Liao 			 &rt5670_if1_adc1_in1_mux),
18165e8351deSBard Liao 	SND_SOC_DAPM_MUX("IF1 ADC1 IN2 Mux", SND_SOC_NOPM, 0, 0,
18175e8351deSBard Liao 			 &rt5670_if1_adc1_in2_mux),
18185e8351deSBard Liao 	SND_SOC_DAPM_MUX("IF1 ADC2 IN Mux", SND_SOC_NOPM, 0, 0,
18195e8351deSBard Liao 			 &rt5670_if1_adc2_in_mux),
18205e8351deSBard Liao 	SND_SOC_DAPM_MUX("IF1 ADC2 IN1 Mux", SND_SOC_NOPM, 0, 0,
18215e8351deSBard Liao 			 &rt5670_if1_adc2_in1_mux),
18225e8351deSBard Liao 	SND_SOC_DAPM_MUX("VAD ADC Mux", SND_SOC_NOPM, 0, 0,
18235e8351deSBard Liao 			 &rt5670_vad_adc_mux),
18245e8351deSBard Liao 
18255e8351deSBard Liao 	/* Audio Interface */
18265e8351deSBard Liao 	SND_SOC_DAPM_AIF_IN("AIF1RX", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0),
18275e8351deSBard Liao 	SND_SOC_DAPM_AIF_OUT("AIF1TX", "AIF1 Capture", 0, SND_SOC_NOPM, 0, 0),
18285e8351deSBard Liao 	SND_SOC_DAPM_AIF_IN("AIF2RX", "AIF2 Playback", 0, SND_SOC_NOPM, 0, 0),
18295e8351deSBard Liao 	SND_SOC_DAPM_AIF_OUT("AIF2TX", "AIF2 Capture", 0,
18305e8351deSBard Liao 			     RT5670_GPIO_CTRL1, RT5670_I2S2_PIN_SFT, 1),
18315e8351deSBard Liao 
18325e8351deSBard Liao 	/* Audio DSP */
18335e8351deSBard Liao 	SND_SOC_DAPM_PGA("Audio DSP", SND_SOC_NOPM, 0, 0, NULL, 0),
18345e8351deSBard Liao 
18355e8351deSBard Liao 	/* Output Side */
18365e8351deSBard Liao 	/* DAC mixer before sound effect  */
18375e8351deSBard Liao 	SND_SOC_DAPM_MIXER("DAC1 MIXL", SND_SOC_NOPM, 0, 0,
18385e8351deSBard Liao 			   rt5670_dac_l_mix, ARRAY_SIZE(rt5670_dac_l_mix)),
18395e8351deSBard Liao 	SND_SOC_DAPM_MIXER("DAC1 MIXR", SND_SOC_NOPM, 0, 0,
18405e8351deSBard Liao 			   rt5670_dac_r_mix, ARRAY_SIZE(rt5670_dac_r_mix)),
18415e8351deSBard Liao 	SND_SOC_DAPM_PGA("DAC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
18425e8351deSBard Liao 
18435e8351deSBard Liao 	/* DAC2 channel Mux */
18445e8351deSBard Liao 	SND_SOC_DAPM_MUX("DAC L2 Mux", SND_SOC_NOPM, 0, 0,
18455e8351deSBard Liao 			 &rt5670_dac_l2_mux),
18465e8351deSBard Liao 	SND_SOC_DAPM_MUX("DAC R2 Mux", SND_SOC_NOPM, 0, 0,
18475e8351deSBard Liao 			 &rt5670_dac_r2_mux),
18485e8351deSBard Liao 	SND_SOC_DAPM_PGA("DAC L2 Volume", RT5670_PWR_DIG1,
18495e8351deSBard Liao 			 RT5670_PWR_DAC_L2_BIT, 0, NULL, 0),
18505e8351deSBard Liao 	SND_SOC_DAPM_PGA("DAC R2 Volume", RT5670_PWR_DIG1,
18515e8351deSBard Liao 			 RT5670_PWR_DAC_R2_BIT, 0, NULL, 0),
18525e8351deSBard Liao 
18535e8351deSBard Liao 	SND_SOC_DAPM_MUX("DAC1 L Mux", SND_SOC_NOPM, 0, 0, &rt5670_dac1l_mux),
18545e8351deSBard Liao 	SND_SOC_DAPM_MUX("DAC1 R Mux", SND_SOC_NOPM, 0, 0, &rt5670_dac1r_mux),
18555e8351deSBard Liao 
18565e8351deSBard Liao 	/* DAC Mixer */
18575e8351deSBard Liao 	SND_SOC_DAPM_SUPPLY("DAC Stereo1 Filter", RT5670_PWR_DIG2,
18585e8351deSBard Liao 			    RT5670_PWR_DAC_S1F_BIT, 0, NULL, 0),
18595e8351deSBard Liao 	SND_SOC_DAPM_SUPPLY("DAC Mono Left Filter", RT5670_PWR_DIG2,
18605e8351deSBard Liao 			    RT5670_PWR_DAC_MF_L_BIT, 0, NULL, 0),
18615e8351deSBard Liao 	SND_SOC_DAPM_SUPPLY("DAC Mono Right Filter", RT5670_PWR_DIG2,
18625e8351deSBard Liao 			    RT5670_PWR_DAC_MF_R_BIT, 0, NULL, 0),
18635e8351deSBard Liao 	SND_SOC_DAPM_MIXER("Stereo DAC MIXL", SND_SOC_NOPM, 0, 0,
18645e8351deSBard Liao 			   rt5670_sto_dac_l_mix,
18655e8351deSBard Liao 			   ARRAY_SIZE(rt5670_sto_dac_l_mix)),
18665e8351deSBard Liao 	SND_SOC_DAPM_MIXER("Stereo DAC MIXR", SND_SOC_NOPM, 0, 0,
18675e8351deSBard Liao 			   rt5670_sto_dac_r_mix,
18685e8351deSBard Liao 			   ARRAY_SIZE(rt5670_sto_dac_r_mix)),
18695e8351deSBard Liao 	SND_SOC_DAPM_MIXER("Mono DAC MIXL", SND_SOC_NOPM, 0, 0,
18705e8351deSBard Liao 			   rt5670_mono_dac_l_mix,
18715e8351deSBard Liao 			   ARRAY_SIZE(rt5670_mono_dac_l_mix)),
18725e8351deSBard Liao 	SND_SOC_DAPM_MIXER("Mono DAC MIXR", SND_SOC_NOPM, 0, 0,
18735e8351deSBard Liao 			   rt5670_mono_dac_r_mix,
18745e8351deSBard Liao 			   ARRAY_SIZE(rt5670_mono_dac_r_mix)),
18755e8351deSBard Liao 	SND_SOC_DAPM_MIXER("DAC MIXL", SND_SOC_NOPM, 0, 0,
18765e8351deSBard Liao 			   rt5670_dig_l_mix,
18775e8351deSBard Liao 			   ARRAY_SIZE(rt5670_dig_l_mix)),
18785e8351deSBard Liao 	SND_SOC_DAPM_MIXER("DAC MIXR", SND_SOC_NOPM, 0, 0,
18795e8351deSBard Liao 			   rt5670_dig_r_mix,
18805e8351deSBard Liao 			   ARRAY_SIZE(rt5670_dig_r_mix)),
18815e8351deSBard Liao 
18825e8351deSBard Liao 	/* DACs */
18835e8351deSBard Liao 	SND_SOC_DAPM_SUPPLY("DAC L1 Power", RT5670_PWR_DIG1,
18845e8351deSBard Liao 			    RT5670_PWR_DAC_L1_BIT, 0, NULL, 0),
18855e8351deSBard Liao 	SND_SOC_DAPM_SUPPLY("DAC R1 Power", RT5670_PWR_DIG1,
18865e8351deSBard Liao 			    RT5670_PWR_DAC_R1_BIT, 0, NULL, 0),
18875e8351deSBard Liao 	SND_SOC_DAPM_DAC("DAC L1", NULL, SND_SOC_NOPM, 0, 0),
18885e8351deSBard Liao 	SND_SOC_DAPM_DAC("DAC R1", NULL, SND_SOC_NOPM, 0, 0),
18895e8351deSBard Liao 	SND_SOC_DAPM_DAC("DAC L2", NULL, RT5670_PWR_DIG1,
18905e8351deSBard Liao 			 RT5670_PWR_DAC_L2_BIT, 0),
18915e8351deSBard Liao 
18925e8351deSBard Liao 	SND_SOC_DAPM_DAC("DAC R2", NULL, RT5670_PWR_DIG1,
18935e8351deSBard Liao 			 RT5670_PWR_DAC_R2_BIT, 0),
18945e8351deSBard Liao 	/* OUT Mixer */
18955e8351deSBard Liao 
18965e8351deSBard Liao 	SND_SOC_DAPM_MIXER("OUT MIXL", RT5670_PWR_MIXER, RT5670_PWR_OM_L_BIT,
18975e8351deSBard Liao 			   0, rt5670_out_l_mix, ARRAY_SIZE(rt5670_out_l_mix)),
18985e8351deSBard Liao 	SND_SOC_DAPM_MIXER("OUT MIXR", RT5670_PWR_MIXER, RT5670_PWR_OM_R_BIT,
18995e8351deSBard Liao 			   0, rt5670_out_r_mix, ARRAY_SIZE(rt5670_out_r_mix)),
19005e8351deSBard Liao 	/* Ouput Volume */
19015e8351deSBard Liao 	SND_SOC_DAPM_MIXER("HPOVOL MIXL", RT5670_PWR_VOL,
19025e8351deSBard Liao 			   RT5670_PWR_HV_L_BIT, 0,
19035e8351deSBard Liao 			   rt5670_hpvoll_mix, ARRAY_SIZE(rt5670_hpvoll_mix)),
19045e8351deSBard Liao 	SND_SOC_DAPM_MIXER("HPOVOL MIXR", RT5670_PWR_VOL,
19055e8351deSBard Liao 			   RT5670_PWR_HV_R_BIT, 0,
19065e8351deSBard Liao 			   rt5670_hpvolr_mix, ARRAY_SIZE(rt5670_hpvolr_mix)),
19075e8351deSBard Liao 	SND_SOC_DAPM_PGA("DAC 1", SND_SOC_NOPM, 0, 0, NULL, 0),
19085e8351deSBard Liao 	SND_SOC_DAPM_PGA("DAC 2", SND_SOC_NOPM,	0, 0, NULL, 0),
19095e8351deSBard Liao 	SND_SOC_DAPM_PGA("HPOVOL", SND_SOC_NOPM, 0, 0, NULL, 0),
19105e8351deSBard Liao 
19115e8351deSBard Liao 	/* HPO/LOUT/Mono Mixer */
19125e8351deSBard Liao 	SND_SOC_DAPM_MIXER("HPO MIX", SND_SOC_NOPM, 0, 0,
19135e8351deSBard Liao 			   rt5670_hpo_mix, ARRAY_SIZE(rt5670_hpo_mix)),
19145e8351deSBard Liao 	SND_SOC_DAPM_MIXER("LOUT MIX", RT5670_PWR_ANLG1, RT5670_PWR_LM_BIT,
19155e8351deSBard Liao 			   0, rt5670_lout_mix, ARRAY_SIZE(rt5670_lout_mix)),
19165e8351deSBard Liao 	SND_SOC_DAPM_SUPPLY_S("Improve HP Amp Drv", 1, SND_SOC_NOPM, 0, 0,
19175e8351deSBard Liao 			      rt5670_hp_power_event, SND_SOC_DAPM_POST_PMU |
19185e8351deSBard Liao 			      SND_SOC_DAPM_PRE_PMD),
19195e8351deSBard Liao 	SND_SOC_DAPM_SUPPLY("HP L Amp", RT5670_PWR_ANLG1,
19205e8351deSBard Liao 			    RT5670_PWR_HP_L_BIT, 0, NULL, 0),
19215e8351deSBard Liao 	SND_SOC_DAPM_SUPPLY("HP R Amp", RT5670_PWR_ANLG1,
19225e8351deSBard Liao 			    RT5670_PWR_HP_R_BIT, 0, NULL, 0),
19235e8351deSBard Liao 	SND_SOC_DAPM_PGA_S("HP Amp", 1, SND_SOC_NOPM, 0, 0,
19245e8351deSBard Liao 			   rt5670_hp_event, SND_SOC_DAPM_PRE_PMD |
19255e8351deSBard Liao 			   SND_SOC_DAPM_POST_PMU),
19265e8351deSBard Liao 	SND_SOC_DAPM_SWITCH("LOUT L Playback", SND_SOC_NOPM, 0, 0,
19275e8351deSBard Liao 			    &lout_l_enable_control),
19285e8351deSBard Liao 	SND_SOC_DAPM_SWITCH("LOUT R Playback", SND_SOC_NOPM, 0, 0,
19295e8351deSBard Liao 			    &lout_r_enable_control),
19305e8351deSBard Liao 	SND_SOC_DAPM_PGA("LOUT Amp", SND_SOC_NOPM, 0, 0, NULL, 0),
19315e8351deSBard Liao 
19325e8351deSBard Liao 	/* PDM */
19335e8351deSBard Liao 	SND_SOC_DAPM_SUPPLY("PDM1 Power", RT5670_PWR_DIG2,
19345e8351deSBard Liao 		RT5670_PWR_PDM1_BIT, 0, NULL, 0),
19355e8351deSBard Liao 
19365e8351deSBard Liao 	SND_SOC_DAPM_MUX("PDM1 L Mux", RT5670_PDM_OUT_CTRL,
19375e8351deSBard Liao 			 RT5670_M_PDM1_L_SFT, 1, &rt5670_pdm1_l_mux),
19385e8351deSBard Liao 	SND_SOC_DAPM_MUX("PDM1 R Mux", RT5670_PDM_OUT_CTRL,
19395e8351deSBard Liao 			 RT5670_M_PDM1_R_SFT, 1, &rt5670_pdm1_r_mux),
19405e8351deSBard Liao 
19415e8351deSBard Liao 	/* Output Lines */
19425e8351deSBard Liao 	SND_SOC_DAPM_OUTPUT("HPOL"),
19435e8351deSBard Liao 	SND_SOC_DAPM_OUTPUT("HPOR"),
19445e8351deSBard Liao 	SND_SOC_DAPM_OUTPUT("LOUTL"),
19455e8351deSBard Liao 	SND_SOC_DAPM_OUTPUT("LOUTR"),
19460cf18632SBard Liao };
19470cf18632SBard Liao 
19480cf18632SBard Liao static const struct snd_soc_dapm_widget rt5670_specific_dapm_widgets[] = {
19490cf18632SBard Liao 	SND_SOC_DAPM_SUPPLY("PDM2 Power", RT5670_PWR_DIG2,
19500cf18632SBard Liao 		RT5670_PWR_PDM2_BIT, 0, NULL, 0),
19510cf18632SBard Liao 	SND_SOC_DAPM_MUX("PDM2 L Mux", RT5670_PDM_OUT_CTRL,
19520cf18632SBard Liao 			 RT5670_M_PDM2_L_SFT, 1, &rt5670_pdm2_l_mux),
19530cf18632SBard Liao 	SND_SOC_DAPM_MUX("PDM2 R Mux", RT5670_PDM_OUT_CTRL,
19540cf18632SBard Liao 			 RT5670_M_PDM2_R_SFT, 1, &rt5670_pdm2_r_mux),
19555e8351deSBard Liao 	SND_SOC_DAPM_OUTPUT("PDM1L"),
19565e8351deSBard Liao 	SND_SOC_DAPM_OUTPUT("PDM1R"),
19575e8351deSBard Liao 	SND_SOC_DAPM_OUTPUT("PDM2L"),
19585e8351deSBard Liao 	SND_SOC_DAPM_OUTPUT("PDM2R"),
19595e8351deSBard Liao };
19605e8351deSBard Liao 
19610cf18632SBard Liao static const struct snd_soc_dapm_widget rt5672_specific_dapm_widgets[] = {
196285ca6b17SHans de Goede 	SND_SOC_DAPM_PGA_E("SPO Amp", SND_SOC_NOPM, 0, 0, NULL, 0,
196385ca6b17SHans de Goede 			   rt5670_spk_event, SND_SOC_DAPM_PRE_PMD |
196485ca6b17SHans de Goede 			   SND_SOC_DAPM_POST_PMU),
19650cf18632SBard Liao 	SND_SOC_DAPM_OUTPUT("SPOLP"),
19660cf18632SBard Liao 	SND_SOC_DAPM_OUTPUT("SPOLN"),
19670cf18632SBard Liao 	SND_SOC_DAPM_OUTPUT("SPORP"),
19680cf18632SBard Liao 	SND_SOC_DAPM_OUTPUT("SPORN"),
19690cf18632SBard Liao };
19700cf18632SBard Liao 
19715e8351deSBard Liao static const struct snd_soc_dapm_route rt5670_dapm_routes[] = {
19725e8351deSBard Liao 	{ "ADC Stereo1 Filter", NULL, "ADC STO1 ASRC", is_using_asrc },
19735e8351deSBard Liao 	{ "ADC Stereo2 Filter", NULL, "ADC STO2 ASRC", is_using_asrc },
19745e8351deSBard Liao 	{ "ADC Mono Left Filter", NULL, "ADC MONO L ASRC", is_using_asrc },
19755e8351deSBard Liao 	{ "ADC Mono Right Filter", NULL, "ADC MONO R ASRC", is_using_asrc },
19765e8351deSBard Liao 	{ "DAC Mono Left Filter", NULL, "DAC MONO L ASRC", is_using_asrc },
19775e8351deSBard Liao 	{ "DAC Mono Right Filter", NULL, "DAC MONO R ASRC", is_using_asrc },
19785e8351deSBard Liao 	{ "DAC Stereo1 Filter", NULL, "DAC STO ASRC", is_using_asrc },
1979ff4541c3SBard Liao 	{ "Stereo1 DMIC Mux", NULL, "DMIC STO1 ASRC", can_use_asrc },
1980ff4541c3SBard Liao 	{ "Stereo2 DMIC Mux", NULL, "DMIC STO2 ASRC", can_use_asrc },
1981ff4541c3SBard Liao 	{ "Mono DMIC L Mux", NULL, "DMIC MONO L ASRC", can_use_asrc },
1982ff4541c3SBard Liao 	{ "Mono DMIC R Mux", NULL, "DMIC MONO R ASRC", can_use_asrc },
19835e8351deSBard Liao 
1984e50334d4SBard Liao 	{ "I2S1", NULL, "I2S1 ASRC", can_use_asrc},
1985e50334d4SBard Liao 	{ "I2S2", NULL, "I2S2 ASRC", can_use_asrc},
19865e8351deSBard Liao 
19875e8351deSBard Liao 	{ "DMIC1", NULL, "DMIC L1" },
19885e8351deSBard Liao 	{ "DMIC1", NULL, "DMIC R1" },
19895e8351deSBard Liao 	{ "DMIC2", NULL, "DMIC L2" },
19905e8351deSBard Liao 	{ "DMIC2", NULL, "DMIC R2" },
19915e8351deSBard Liao 	{ "DMIC3", NULL, "DMIC L3" },
19925e8351deSBard Liao 	{ "DMIC3", NULL, "DMIC R3" },
19935e8351deSBard Liao 
19945e8351deSBard Liao 	{ "BST1", NULL, "IN1P" },
19955e8351deSBard Liao 	{ "BST1", NULL, "IN1N" },
19965e8351deSBard Liao 	{ "BST1", NULL, "Mic Det Power" },
19975e8351deSBard Liao 	{ "BST2", NULL, "IN2P" },
19985e8351deSBard Liao 	{ "BST2", NULL, "IN2N" },
19995e8351deSBard Liao 
20005e8351deSBard Liao 	{ "INL VOL", NULL, "IN2P" },
20015e8351deSBard Liao 	{ "INR VOL", NULL, "IN2N" },
20025e8351deSBard Liao 
20035e8351deSBard Liao 	{ "RECMIXL", "INL Switch", "INL VOL" },
20045e8351deSBard Liao 	{ "RECMIXL", "BST2 Switch", "BST2" },
20055e8351deSBard Liao 	{ "RECMIXL", "BST1 Switch", "BST1" },
20065e8351deSBard Liao 
20075e8351deSBard Liao 	{ "RECMIXR", "INR Switch", "INR VOL" },
20085e8351deSBard Liao 	{ "RECMIXR", "BST2 Switch", "BST2" },
20095e8351deSBard Liao 	{ "RECMIXR", "BST1 Switch", "BST1" },
20105e8351deSBard Liao 
20115e8351deSBard Liao 	{ "ADC 1", NULL, "RECMIXL" },
20125e8351deSBard Liao 	{ "ADC 1", NULL, "ADC 1 power" },
20135e8351deSBard Liao 	{ "ADC 1", NULL, "ADC clock" },
20145e8351deSBard Liao 	{ "ADC 2", NULL, "RECMIXR" },
20155e8351deSBard Liao 	{ "ADC 2", NULL, "ADC 2 power" },
20165e8351deSBard Liao 	{ "ADC 2", NULL, "ADC clock" },
20175e8351deSBard Liao 
20185e8351deSBard Liao 	{ "DMIC L1", NULL, "DMIC CLK" },
20195e8351deSBard Liao 	{ "DMIC L1", NULL, "DMIC1 Power" },
20205e8351deSBard Liao 	{ "DMIC R1", NULL, "DMIC CLK" },
20215e8351deSBard Liao 	{ "DMIC R1", NULL, "DMIC1 Power" },
20225e8351deSBard Liao 	{ "DMIC L2", NULL, "DMIC CLK" },
20235e8351deSBard Liao 	{ "DMIC L2", NULL, "DMIC2 Power" },
20245e8351deSBard Liao 	{ "DMIC R2", NULL, "DMIC CLK" },
20255e8351deSBard Liao 	{ "DMIC R2", NULL, "DMIC2 Power" },
20265e8351deSBard Liao 	{ "DMIC L3", NULL, "DMIC CLK" },
20275e8351deSBard Liao 	{ "DMIC L3", NULL, "DMIC3 Power" },
20285e8351deSBard Liao 	{ "DMIC R3", NULL, "DMIC CLK" },
20295e8351deSBard Liao 	{ "DMIC R3", NULL, "DMIC3 Power" },
20305e8351deSBard Liao 
20315e8351deSBard Liao 	{ "Stereo1 DMIC Mux", "DMIC1", "DMIC1" },
20325e8351deSBard Liao 	{ "Stereo1 DMIC Mux", "DMIC2", "DMIC2" },
20335e8351deSBard Liao 	{ "Stereo1 DMIC Mux", "DMIC3", "DMIC3" },
20345e8351deSBard Liao 
20355e8351deSBard Liao 	{ "Stereo2 DMIC Mux", "DMIC1", "DMIC1" },
20365e8351deSBard Liao 	{ "Stereo2 DMIC Mux", "DMIC2", "DMIC2" },
20375e8351deSBard Liao 	{ "Stereo2 DMIC Mux", "DMIC3", "DMIC3" },
20385e8351deSBard Liao 
20395e8351deSBard Liao 	{ "Mono DMIC L Mux", "DMIC1", "DMIC L1" },
20405e8351deSBard Liao 	{ "Mono DMIC L Mux", "DMIC2", "DMIC L2" },
20415e8351deSBard Liao 	{ "Mono DMIC L Mux", "DMIC3", "DMIC L3" },
20425e8351deSBard Liao 
20435e8351deSBard Liao 	{ "Mono DMIC R Mux", "DMIC1", "DMIC R1" },
20445e8351deSBard Liao 	{ "Mono DMIC R Mux", "DMIC2", "DMIC R2" },
20455e8351deSBard Liao 	{ "Mono DMIC R Mux", "DMIC3", "DMIC R3" },
20465e8351deSBard Liao 
20475e8351deSBard Liao 	{ "ADC 1_2", NULL, "ADC 1" },
20485e8351deSBard Liao 	{ "ADC 1_2", NULL, "ADC 2" },
20495e8351deSBard Liao 
20505e8351deSBard Liao 	{ "Stereo1 ADC L2 Mux", "DMIC", "Stereo1 DMIC Mux" },
20515e8351deSBard Liao 	{ "Stereo1 ADC L2 Mux", "DAC MIX", "DAC MIXL" },
20525e8351deSBard Liao 	{ "Stereo1 ADC L1 Mux", "ADC", "ADC 1_2" },
20535e8351deSBard Liao 	{ "Stereo1 ADC L1 Mux", "DAC MIX", "DAC MIXL" },
20545e8351deSBard Liao 
20555e8351deSBard Liao 	{ "Stereo1 ADC R1 Mux", "ADC", "ADC 1_2" },
20565e8351deSBard Liao 	{ "Stereo1 ADC R1 Mux", "DAC MIX", "DAC MIXR" },
20575e8351deSBard Liao 	{ "Stereo1 ADC R2 Mux", "DMIC", "Stereo1 DMIC Mux" },
20585e8351deSBard Liao 	{ "Stereo1 ADC R2 Mux", "DAC MIX", "DAC MIXR" },
20595e8351deSBard Liao 
20605e8351deSBard Liao 	{ "Mono ADC L2 Mux", "DMIC", "Mono DMIC L Mux" },
20615e8351deSBard Liao 	{ "Mono ADC L2 Mux", "Mono DAC MIXL", "Mono DAC MIXL" },
20625e8351deSBard Liao 	{ "Mono ADC L1 Mux", "Mono DAC MIXL", "Mono DAC MIXL" },
20635e8351deSBard Liao 	{ "Mono ADC L1 Mux", "ADC1",  "ADC 1" },
20645e8351deSBard Liao 
20655e8351deSBard Liao 	{ "Mono ADC R1 Mux", "Mono DAC MIXR", "Mono DAC MIXR" },
20665e8351deSBard Liao 	{ "Mono ADC R1 Mux", "ADC2", "ADC 2" },
20675e8351deSBard Liao 	{ "Mono ADC R2 Mux", "DMIC", "Mono DMIC R Mux" },
20685e8351deSBard Liao 	{ "Mono ADC R2 Mux", "Mono DAC MIXR", "Mono DAC MIXR" },
20695e8351deSBard Liao 
20705e8351deSBard Liao 	{ "Sto1 ADC MIXL", "ADC1 Switch", "Stereo1 ADC L1 Mux" },
20715e8351deSBard Liao 	{ "Sto1 ADC MIXL", "ADC2 Switch", "Stereo1 ADC L2 Mux" },
20725e8351deSBard Liao 	{ "Sto1 ADC MIXR", "ADC1 Switch", "Stereo1 ADC R1 Mux" },
20735e8351deSBard Liao 	{ "Sto1 ADC MIXR", "ADC2 Switch", "Stereo1 ADC R2 Mux" },
20745e8351deSBard Liao 
20755e8351deSBard Liao 	{ "Stereo1 ADC MIXL", NULL, "Sto1 ADC MIXL" },
20765e8351deSBard Liao 	{ "Stereo1 ADC MIXL", NULL, "ADC Stereo1 Filter" },
20775e8351deSBard Liao 
20785e8351deSBard Liao 	{ "Stereo1 ADC MIXR", NULL, "Sto1 ADC MIXR" },
20795e8351deSBard Liao 	{ "Stereo1 ADC MIXR", NULL, "ADC Stereo1 Filter" },
20805e8351deSBard Liao 	{ "ADC Stereo1 Filter", NULL, "PLL1", is_sys_clk_from_pll },
20815e8351deSBard Liao 
20825e8351deSBard Liao 	{ "Mono ADC MIXL", "ADC1 Switch", "Mono ADC L1 Mux" },
20835e8351deSBard Liao 	{ "Mono ADC MIXL", "ADC2 Switch", "Mono ADC L2 Mux" },
20845e8351deSBard Liao 	{ "Mono ADC MIXL", NULL, "ADC Mono Left Filter" },
20855e8351deSBard Liao 	{ "ADC Mono Left Filter", NULL, "PLL1", is_sys_clk_from_pll },
20865e8351deSBard Liao 
20875e8351deSBard Liao 	{ "Mono ADC MIXR", "ADC1 Switch", "Mono ADC R1 Mux" },
20885e8351deSBard Liao 	{ "Mono ADC MIXR", "ADC2 Switch", "Mono ADC R2 Mux" },
20895e8351deSBard Liao 	{ "Mono ADC MIXR", NULL, "ADC Mono Right Filter" },
20905e8351deSBard Liao 	{ "ADC Mono Right Filter", NULL, "PLL1", is_sys_clk_from_pll },
20915e8351deSBard Liao 
20925e8351deSBard Liao 	{ "Stereo2 ADC L2 Mux", "DMIC", "Stereo2 DMIC Mux" },
20935e8351deSBard Liao 	{ "Stereo2 ADC L2 Mux", "DAC MIX", "DAC MIXL" },
20945e8351deSBard Liao 	{ "Stereo2 ADC L1 Mux", "ADC", "ADC 1_2" },
20955e8351deSBard Liao 	{ "Stereo2 ADC L1 Mux", "DAC MIX", "DAC MIXL" },
20965e8351deSBard Liao 
20975e8351deSBard Liao 	{ "Stereo2 ADC R1 Mux", "ADC", "ADC 1_2" },
20985e8351deSBard Liao 	{ "Stereo2 ADC R1 Mux", "DAC MIX", "DAC MIXR" },
20995e8351deSBard Liao 	{ "Stereo2 ADC R2 Mux", "DMIC", "Stereo2 DMIC Mux" },
21005e8351deSBard Liao 	{ "Stereo2 ADC R2 Mux", "DAC MIX", "DAC MIXR" },
21015e8351deSBard Liao 
21025e8351deSBard Liao 	{ "Sto2 ADC MIXL", "ADC1 Switch", "Stereo2 ADC L1 Mux" },
21035e8351deSBard Liao 	{ "Sto2 ADC MIXL", "ADC2 Switch", "Stereo2 ADC L2 Mux" },
21045e8351deSBard Liao 	{ "Sto2 ADC MIXR", "ADC1 Switch", "Stereo2 ADC R1 Mux" },
21055e8351deSBard Liao 	{ "Sto2 ADC MIXR", "ADC2 Switch", "Stereo2 ADC R2 Mux" },
21065e8351deSBard Liao 
21075e8351deSBard Liao 	{ "Sto2 ADC LR MIX", NULL, "Sto2 ADC MIXL" },
21085e8351deSBard Liao 	{ "Sto2 ADC LR MIX", NULL, "Sto2 ADC MIXR" },
21095e8351deSBard Liao 
21105e8351deSBard Liao 	{ "Stereo2 ADC LR Mux", "L", "Sto2 ADC MIXL" },
21115e8351deSBard Liao 	{ "Stereo2 ADC LR Mux", "LR", "Sto2 ADC LR MIX" },
21125e8351deSBard Liao 
21135e8351deSBard Liao 	{ "Stereo2 ADC MIXL", NULL, "Stereo2 ADC LR Mux" },
21145e8351deSBard Liao 	{ "Stereo2 ADC MIXL", NULL, "ADC Stereo2 Filter" },
21155e8351deSBard Liao 
21165e8351deSBard Liao 	{ "Stereo2 ADC MIXR", NULL, "Sto2 ADC MIXR" },
21175e8351deSBard Liao 	{ "Stereo2 ADC MIXR", NULL, "ADC Stereo2 Filter" },
21185e8351deSBard Liao 	{ "ADC Stereo2 Filter", NULL, "PLL1", is_sys_clk_from_pll },
21195e8351deSBard Liao 
21205e8351deSBard Liao 	{ "VAD ADC Mux", "Sto1 ADC L", "Stereo1 ADC MIXL" },
21215e8351deSBard Liao 	{ "VAD ADC Mux", "Mono ADC L", "Mono ADC MIXL" },
21225e8351deSBard Liao 	{ "VAD ADC Mux", "Mono ADC R", "Mono ADC MIXR" },
21235e8351deSBard Liao 	{ "VAD ADC Mux", "Sto2 ADC L", "Sto2 ADC MIXL" },
21245e8351deSBard Liao 
21255e8351deSBard Liao 	{ "VAD_ADC", NULL, "VAD ADC Mux" },
21265e8351deSBard Liao 
21275e8351deSBard Liao 	{ "IF_ADC1", NULL, "Stereo1 ADC MIXL" },
21285e8351deSBard Liao 	{ "IF_ADC1", NULL, "Stereo1 ADC MIXR" },
21295e8351deSBard Liao 	{ "IF_ADC2", NULL, "Mono ADC MIXL" },
21305e8351deSBard Liao 	{ "IF_ADC2", NULL, "Mono ADC MIXR" },
21315e8351deSBard Liao 	{ "IF_ADC3", NULL, "Stereo2 ADC MIXL" },
21325e8351deSBard Liao 	{ "IF_ADC3", NULL, "Stereo2 ADC MIXR" },
21335e8351deSBard Liao 
21345e8351deSBard Liao 	{ "IF1 ADC1 IN1 Mux", "IF_ADC1", "IF_ADC1" },
21355e8351deSBard Liao 	{ "IF1 ADC1 IN1 Mux", "IF1_ADC3", "IF1_ADC3" },
21365e8351deSBard Liao 
21375e8351deSBard Liao 	{ "IF1 ADC1 IN2 Mux", "IF1_ADC1_IN1", "IF1 ADC1 IN1 Mux" },
21388e2d163bSBard Liao 	{ "IF1 ADC1 IN2 Mux", "IF1_ADC4", "TxDP_ADC" },
21395e8351deSBard Liao 
21405e8351deSBard Liao 	{ "IF1 ADC2 IN Mux", "IF_ADC2", "IF_ADC2" },
21415e8351deSBard Liao 	{ "IF1 ADC2 IN Mux", "VAD_ADC", "VAD_ADC" },
21425e8351deSBard Liao 
21435e8351deSBard Liao 	{ "IF1 ADC2 IN1 Mux", "IF1_ADC2_IN", "IF1 ADC2 IN Mux" },
21448e2d163bSBard Liao 	{ "IF1 ADC2 IN1 Mux", "IF1_ADC4", "TxDP_ADC" },
21455e8351deSBard Liao 
21465e8351deSBard Liao 	{ "IF1_ADC1" , NULL, "IF1 ADC1 IN2 Mux" },
21475e8351deSBard Liao 	{ "IF1_ADC2" , NULL, "IF1 ADC2 IN1 Mux" },
21485e8351deSBard Liao 
21495e8351deSBard Liao 	{ "Stereo1 ADC MIX", NULL, "Stereo1 ADC MIXL" },
21505e8351deSBard Liao 	{ "Stereo1 ADC MIX", NULL, "Stereo1 ADC MIXR" },
21515e8351deSBard Liao 	{ "Stereo2 ADC MIX", NULL, "Sto2 ADC MIXL" },
21525e8351deSBard Liao 	{ "Stereo2 ADC MIX", NULL, "Sto2 ADC MIXR" },
21535e8351deSBard Liao 	{ "Mono ADC MIX", NULL, "Mono ADC MIXL" },
21545e8351deSBard Liao 	{ "Mono ADC MIX", NULL, "Mono ADC MIXR" },
21555e8351deSBard Liao 
21565e8351deSBard Liao 	{ "RxDP Mux", "IF2 DAC", "IF2 DAC" },
21575e8351deSBard Liao 	{ "RxDP Mux", "IF1 DAC", "IF1 DAC2" },
21585e8351deSBard Liao 	{ "RxDP Mux", "STO1 ADC Mixer", "Stereo1 ADC MIX" },
21595e8351deSBard Liao 	{ "RxDP Mux", "STO2 ADC Mixer", "Stereo2 ADC MIX" },
21605e8351deSBard Liao 	{ "RxDP Mux", "Mono ADC Mixer L", "Mono ADC MIXL" },
21615e8351deSBard Liao 	{ "RxDP Mux", "Mono ADC Mixer R", "Mono ADC MIXR" },
21625e8351deSBard Liao 	{ "RxDP Mux", "DAC1", "DAC MIX" },
21635e8351deSBard Liao 
21645e8351deSBard Liao 	{ "TDM Data Mux", "Slot 0-1", "Stereo1 ADC MIX" },
21655e8351deSBard Liao 	{ "TDM Data Mux", "Slot 2-3", "Mono ADC MIX" },
21665e8351deSBard Liao 	{ "TDM Data Mux", "Slot 4-5", "Stereo2 ADC MIX" },
21675e8351deSBard Liao 	{ "TDM Data Mux", "Slot 6-7", "IF2 DAC" },
21685e8351deSBard Liao 
21695e8351deSBard Liao 	{ "DSP UL Mux", "Bypass", "TDM Data Mux" },
21705e8351deSBard Liao 	{ "DSP UL Mux", NULL, "I2S DSP" },
21715e8351deSBard Liao 	{ "DSP DL Mux", "Bypass", "RxDP Mux" },
21725e8351deSBard Liao 	{ "DSP DL Mux", NULL, "I2S DSP" },
21735e8351deSBard Liao 
21745e8351deSBard Liao 	{ "TxDP_ADC_L", NULL, "DSP UL Mux" },
21755e8351deSBard Liao 	{ "TxDP_ADC_R", NULL, "DSP UL Mux" },
21765e8351deSBard Liao 	{ "TxDC_DAC", NULL, "DSP DL Mux" },
21775e8351deSBard Liao 
21785e8351deSBard Liao 	{ "TxDP_ADC", NULL, "TxDP_ADC_L" },
21795e8351deSBard Liao 	{ "TxDP_ADC", NULL, "TxDP_ADC_R" },
21805e8351deSBard Liao 
21815e8351deSBard Liao 	{ "IF1 ADC", NULL, "I2S1" },
21825e8351deSBard Liao 	{ "IF1 ADC", NULL, "IF1_ADC1" },
21835e8351deSBard Liao 	{ "IF1 ADC", NULL, "IF1_ADC2" },
21845e8351deSBard Liao 	{ "IF1 ADC", NULL, "IF_ADC3" },
21855e8351deSBard Liao 	{ "IF1 ADC", NULL, "TxDP_ADC" },
21865e8351deSBard Liao 
21875e8351deSBard Liao 	{ "IF2 ADC Mux", "IF_ADC1", "IF_ADC1" },
21885e8351deSBard Liao 	{ "IF2 ADC Mux", "IF_ADC2", "IF_ADC2" },
21895e8351deSBard Liao 	{ "IF2 ADC Mux", "IF_ADC3", "IF_ADC3" },
21905e8351deSBard Liao 	{ "IF2 ADC Mux", "TxDC_DAC", "TxDC_DAC" },
21915e8351deSBard Liao 	{ "IF2 ADC Mux", "TxDP_ADC", "TxDP_ADC" },
21925e8351deSBard Liao 	{ "IF2 ADC Mux", "VAD_ADC", "VAD_ADC" },
21935e8351deSBard Liao 
21945e8351deSBard Liao 	{ "IF2 ADC L", NULL, "IF2 ADC Mux" },
21955e8351deSBard Liao 	{ "IF2 ADC R", NULL, "IF2 ADC Mux" },
21965e8351deSBard Liao 
21975e8351deSBard Liao 	{ "IF2 ADC", NULL, "I2S2" },
21985e8351deSBard Liao 	{ "IF2 ADC", NULL, "IF2 ADC L" },
21995e8351deSBard Liao 	{ "IF2 ADC", NULL, "IF2 ADC R" },
22005e8351deSBard Liao 
22015e8351deSBard Liao 	{ "AIF1TX", NULL, "IF1 ADC" },
22025e8351deSBard Liao 	{ "AIF2TX", NULL, "IF2 ADC" },
22035e8351deSBard Liao 
22045e8351deSBard Liao 	{ "IF1 DAC1", NULL, "AIF1RX" },
22055e8351deSBard Liao 	{ "IF1 DAC2", NULL, "AIF1RX" },
22065e8351deSBard Liao 	{ "IF2 DAC", NULL, "AIF2RX" },
22075e8351deSBard Liao 
22085e8351deSBard Liao 	{ "IF1 DAC1", NULL, "I2S1" },
22095e8351deSBard Liao 	{ "IF1 DAC2", NULL, "I2S1" },
22105e8351deSBard Liao 	{ "IF2 DAC", NULL, "I2S2" },
22115e8351deSBard Liao 
22125e8351deSBard Liao 	{ "IF1 DAC2 L", NULL, "IF1 DAC2" },
22135e8351deSBard Liao 	{ "IF1 DAC2 R", NULL, "IF1 DAC2" },
22145e8351deSBard Liao 	{ "IF1 DAC1 L", NULL, "IF1 DAC1" },
22155e8351deSBard Liao 	{ "IF1 DAC1 R", NULL, "IF1 DAC1" },
22165e8351deSBard Liao 	{ "IF2 DAC L", NULL, "IF2 DAC" },
22175e8351deSBard Liao 	{ "IF2 DAC R", NULL, "IF2 DAC" },
22185e8351deSBard Liao 
22195e8351deSBard Liao 	{ "DAC1 L Mux", "IF1 DAC", "IF1 DAC1 L" },
22205e8351deSBard Liao 	{ "DAC1 L Mux", "IF2 DAC", "IF2 DAC L" },
22215e8351deSBard Liao 
22225e8351deSBard Liao 	{ "DAC1 R Mux", "IF1 DAC", "IF1 DAC1 R" },
22235e8351deSBard Liao 	{ "DAC1 R Mux", "IF2 DAC", "IF2 DAC R" },
22245e8351deSBard Liao 
22255e8351deSBard Liao 	{ "DAC1 MIXL", "Stereo ADC Switch", "Stereo1 ADC MIXL" },
22265e8351deSBard Liao 	{ "DAC1 MIXL", "DAC1 Switch", "DAC1 L Mux" },
22275e8351deSBard Liao 	{ "DAC1 MIXL", NULL, "DAC Stereo1 Filter" },
22285e8351deSBard Liao 	{ "DAC1 MIXR", "Stereo ADC Switch", "Stereo1 ADC MIXR" },
22295e8351deSBard Liao 	{ "DAC1 MIXR", "DAC1 Switch", "DAC1 R Mux" },
22305e8351deSBard Liao 	{ "DAC1 MIXR", NULL, "DAC Stereo1 Filter" },
22315e8351deSBard Liao 
223296927ac9SBard Liao 	{ "DAC Stereo1 Filter", NULL, "PLL1", is_sys_clk_from_pll },
223396927ac9SBard Liao 	{ "DAC Mono Left Filter", NULL, "PLL1", is_sys_clk_from_pll },
223496927ac9SBard Liao 	{ "DAC Mono Right Filter", NULL, "PLL1", is_sys_clk_from_pll },
223596927ac9SBard Liao 
22365e8351deSBard Liao 	{ "DAC MIX", NULL, "DAC1 MIXL" },
22375e8351deSBard Liao 	{ "DAC MIX", NULL, "DAC1 MIXR" },
22385e8351deSBard Liao 
22395e8351deSBard Liao 	{ "Audio DSP", NULL, "DAC1 MIXL" },
22405e8351deSBard Liao 	{ "Audio DSP", NULL, "DAC1 MIXR" },
22415e8351deSBard Liao 
22425e8351deSBard Liao 	{ "DAC L2 Mux", "IF1 DAC", "IF1 DAC2 L" },
22435e8351deSBard Liao 	{ "DAC L2 Mux", "IF2 DAC", "IF2 DAC L" },
22445e8351deSBard Liao 	{ "DAC L2 Mux", "TxDC DAC", "TxDC_DAC" },
22455e8351deSBard Liao 	{ "DAC L2 Mux", "VAD_ADC", "VAD_ADC" },
22465e8351deSBard Liao 	{ "DAC L2 Volume", NULL, "DAC L2 Mux" },
22475e8351deSBard Liao 	{ "DAC L2 Volume", NULL, "DAC Mono Left Filter" },
22485e8351deSBard Liao 
22495e8351deSBard Liao 	{ "DAC R2 Mux", "IF1 DAC", "IF1 DAC2 R" },
22505e8351deSBard Liao 	{ "DAC R2 Mux", "IF2 DAC", "IF2 DAC R" },
22515e8351deSBard Liao 	{ "DAC R2 Mux", "TxDC DAC", "TxDC_DAC" },
22525e8351deSBard Liao 	{ "DAC R2 Mux", "TxDP ADC", "TxDP_ADC" },
22535e8351deSBard Liao 	{ "DAC R2 Volume", NULL, "DAC R2 Mux" },
22545e8351deSBard Liao 	{ "DAC R2 Volume", NULL, "DAC Mono Right Filter" },
22555e8351deSBard Liao 
22565e8351deSBard Liao 	{ "Stereo DAC MIXL", "DAC L1 Switch", "DAC1 MIXL" },
22575e8351deSBard Liao 	{ "Stereo DAC MIXL", "DAC R1 Switch", "DAC1 MIXR" },
22585e8351deSBard Liao 	{ "Stereo DAC MIXL", "DAC L2 Switch", "DAC L2 Volume" },
22595e8351deSBard Liao 	{ "Stereo DAC MIXL", NULL, "DAC Stereo1 Filter" },
22605e8351deSBard Liao 	{ "Stereo DAC MIXL", NULL, "DAC L1 Power" },
22615e8351deSBard Liao 	{ "Stereo DAC MIXR", "DAC R1 Switch", "DAC1 MIXR" },
22625e8351deSBard Liao 	{ "Stereo DAC MIXR", "DAC L1 Switch", "DAC1 MIXL" },
22635e8351deSBard Liao 	{ "Stereo DAC MIXR", "DAC R2 Switch", "DAC R2 Volume" },
22645e8351deSBard Liao 	{ "Stereo DAC MIXR", NULL, "DAC Stereo1 Filter" },
22655e8351deSBard Liao 	{ "Stereo DAC MIXR", NULL, "DAC R1 Power" },
22665e8351deSBard Liao 
22675e8351deSBard Liao 	{ "Mono DAC MIXL", "DAC L1 Switch", "DAC1 MIXL" },
22685e8351deSBard Liao 	{ "Mono DAC MIXL", "DAC L2 Switch", "DAC L2 Volume" },
22695e8351deSBard Liao 	{ "Mono DAC MIXL", "DAC R2 Switch", "DAC R2 Volume" },
22705e8351deSBard Liao 	{ "Mono DAC MIXL", NULL, "DAC Mono Left Filter" },
22715e8351deSBard Liao 	{ "Mono DAC MIXR", "DAC R1 Switch", "DAC1 MIXR" },
22725e8351deSBard Liao 	{ "Mono DAC MIXR", "DAC R2 Switch", "DAC R2 Volume" },
22735e8351deSBard Liao 	{ "Mono DAC MIXR", "DAC L2 Switch", "DAC L2 Volume" },
22745e8351deSBard Liao 	{ "Mono DAC MIXR", NULL, "DAC Mono Right Filter" },
22755e8351deSBard Liao 
22765e8351deSBard Liao 	{ "DAC MIXL", "Sto DAC Mix L Switch", "Stereo DAC MIXL" },
22775e8351deSBard Liao 	{ "DAC MIXL", "DAC L2 Switch", "DAC L2 Volume" },
22785e8351deSBard Liao 	{ "DAC MIXL", "DAC R2 Switch", "DAC R2 Volume" },
22795e8351deSBard Liao 	{ "DAC MIXR", "Sto DAC Mix R Switch", "Stereo DAC MIXR" },
22805e8351deSBard Liao 	{ "DAC MIXR", "DAC R2 Switch", "DAC R2 Volume" },
22815e8351deSBard Liao 	{ "DAC MIXR", "DAC L2 Switch", "DAC L2 Volume" },
22825e8351deSBard Liao 
22835e8351deSBard Liao 	{ "DAC L1", NULL, "DAC L1 Power" },
22845e8351deSBard Liao 	{ "DAC L1", NULL, "Stereo DAC MIXL" },
22855e8351deSBard Liao 	{ "DAC R1", NULL, "DAC R1 Power" },
22865e8351deSBard Liao 	{ "DAC R1", NULL, "Stereo DAC MIXR" },
22875e8351deSBard Liao 	{ "DAC L2", NULL, "Mono DAC MIXL" },
22885e8351deSBard Liao 	{ "DAC R2", NULL, "Mono DAC MIXR" },
22895e8351deSBard Liao 
22905e8351deSBard Liao 	{ "OUT MIXL", "BST1 Switch", "BST1" },
22915e8351deSBard Liao 	{ "OUT MIXL", "INL Switch", "INL VOL" },
22925e8351deSBard Liao 	{ "OUT MIXL", "DAC L2 Switch", "DAC L2" },
22935e8351deSBard Liao 	{ "OUT MIXL", "DAC L1 Switch", "DAC L1" },
22945e8351deSBard Liao 
22955e8351deSBard Liao 	{ "OUT MIXR", "BST2 Switch", "BST2" },
22965e8351deSBard Liao 	{ "OUT MIXR", "INR Switch", "INR VOL" },
22975e8351deSBard Liao 	{ "OUT MIXR", "DAC R2 Switch", "DAC R2" },
22985e8351deSBard Liao 	{ "OUT MIXR", "DAC R1 Switch", "DAC R1" },
22995e8351deSBard Liao 
23005e8351deSBard Liao 	{ "HPOVOL MIXL", "DAC1 Switch", "DAC L1" },
23015e8351deSBard Liao 	{ "HPOVOL MIXL", "INL Switch", "INL VOL" },
23025e8351deSBard Liao 	{ "HPOVOL MIXR", "DAC1 Switch", "DAC R1" },
23035e8351deSBard Liao 	{ "HPOVOL MIXR", "INR Switch", "INR VOL" },
23045e8351deSBard Liao 
23055e8351deSBard Liao 	{ "DAC 2", NULL, "DAC L2" },
23065e8351deSBard Liao 	{ "DAC 2", NULL, "DAC R2" },
23075e8351deSBard Liao 	{ "DAC 1", NULL, "DAC L1" },
23085e8351deSBard Liao 	{ "DAC 1", NULL, "DAC R1" },
23095e8351deSBard Liao 	{ "HPOVOL", NULL, "HPOVOL MIXL" },
23105e8351deSBard Liao 	{ "HPOVOL", NULL, "HPOVOL MIXR" },
23115e8351deSBard Liao 	{ "HPO MIX", "DAC1 Switch", "DAC 1" },
23125e8351deSBard Liao 	{ "HPO MIX", "HPVOL Switch", "HPOVOL" },
23135e8351deSBard Liao 
23145e8351deSBard Liao 	{ "LOUT MIX", "DAC L1 Switch", "DAC L1" },
23155e8351deSBard Liao 	{ "LOUT MIX", "DAC R1 Switch", "DAC R1" },
23165e8351deSBard Liao 	{ "LOUT MIX", "OUTMIX L Switch", "OUT MIXL" },
23175e8351deSBard Liao 	{ "LOUT MIX", "OUTMIX R Switch", "OUT MIXR" },
23185e8351deSBard Liao 
23195e8351deSBard Liao 	{ "PDM1 L Mux", "Stereo DAC", "Stereo DAC MIXL" },
23205e8351deSBard Liao 	{ "PDM1 L Mux", "Mono DAC", "Mono DAC MIXL" },
23215e8351deSBard Liao 	{ "PDM1 L Mux", NULL, "PDM1 Power" },
23225e8351deSBard Liao 	{ "PDM1 R Mux", "Stereo DAC", "Stereo DAC MIXR" },
23235e8351deSBard Liao 	{ "PDM1 R Mux", "Mono DAC", "Mono DAC MIXR" },
23245e8351deSBard Liao 	{ "PDM1 R Mux", NULL, "PDM1 Power" },
23255e8351deSBard Liao 
23265e8351deSBard Liao 	{ "HP Amp", NULL, "HPO MIX" },
23275e8351deSBard Liao 	{ "HP Amp", NULL, "Mic Det Power" },
23285e8351deSBard Liao 	{ "HPOL", NULL, "HP Amp" },
23295e8351deSBard Liao 	{ "HPOL", NULL, "HP L Amp" },
23305e8351deSBard Liao 	{ "HPOL", NULL, "Improve HP Amp Drv" },
23315e8351deSBard Liao 	{ "HPOR", NULL, "HP Amp" },
23325e8351deSBard Liao 	{ "HPOR", NULL, "HP R Amp" },
23335e8351deSBard Liao 	{ "HPOR", NULL, "Improve HP Amp Drv" },
23345e8351deSBard Liao 
23355e8351deSBard Liao 	{ "LOUT Amp", NULL, "LOUT MIX" },
23365e8351deSBard Liao 	{ "LOUT L Playback", "Switch", "LOUT Amp" },
23375e8351deSBard Liao 	{ "LOUT R Playback", "Switch", "LOUT Amp" },
23385e8351deSBard Liao 	{ "LOUTL", NULL, "LOUT L Playback" },
23395e8351deSBard Liao 	{ "LOUTR", NULL, "LOUT R Playback" },
23405e8351deSBard Liao 	{ "LOUTL", NULL, "Improve HP Amp Drv" },
23415e8351deSBard Liao 	{ "LOUTR", NULL, "Improve HP Amp Drv" },
23420cf18632SBard Liao };
23435e8351deSBard Liao 
23440cf18632SBard Liao static const struct snd_soc_dapm_route rt5670_specific_dapm_routes[] = {
23450cf18632SBard Liao 	{ "PDM2 L Mux", "Stereo DAC", "Stereo DAC MIXL" },
23460cf18632SBard Liao 	{ "PDM2 L Mux", "Mono DAC", "Mono DAC MIXL" },
23470cf18632SBard Liao 	{ "PDM2 L Mux", NULL, "PDM2 Power" },
23480cf18632SBard Liao 	{ "PDM2 R Mux", "Stereo DAC", "Stereo DAC MIXR" },
23490cf18632SBard Liao 	{ "PDM2 R Mux", "Mono DAC", "Mono DAC MIXR" },
23500cf18632SBard Liao 	{ "PDM2 R Mux", NULL, "PDM2 Power" },
23515e8351deSBard Liao 	{ "PDM1L", NULL, "PDM1 L Mux" },
23525e8351deSBard Liao 	{ "PDM1R", NULL, "PDM1 R Mux" },
23535e8351deSBard Liao 	{ "PDM2L", NULL, "PDM2 L Mux" },
23545e8351deSBard Liao 	{ "PDM2R", NULL, "PDM2 R Mux" },
23555e8351deSBard Liao };
23565e8351deSBard Liao 
23570cf18632SBard Liao static const struct snd_soc_dapm_route rt5672_specific_dapm_routes[] = {
23580cf18632SBard Liao 	{ "SPO Amp", NULL, "PDM1 L Mux" },
23590cf18632SBard Liao 	{ "SPO Amp", NULL, "PDM1 R Mux" },
23600cf18632SBard Liao 	{ "SPOLP", NULL, "SPO Amp" },
23610cf18632SBard Liao 	{ "SPOLN", NULL, "SPO Amp" },
23620cf18632SBard Liao 	{ "SPORP", NULL, "SPO Amp" },
23630cf18632SBard Liao 	{ "SPORN", NULL, "SPO Amp" },
23640cf18632SBard Liao };
23650cf18632SBard Liao 
rt5670_hw_params(struct snd_pcm_substream * substream,struct snd_pcm_hw_params * params,struct snd_soc_dai * dai)23665e8351deSBard Liao static int rt5670_hw_params(struct snd_pcm_substream *substream,
23675e8351deSBard Liao 	struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
23685e8351deSBard Liao {
23695ba04c66SKuninori Morimoto 	struct snd_soc_component *component = dai->component;
23705ba04c66SKuninori Morimoto 	struct rt5670_priv *rt5670 = snd_soc_component_get_drvdata(component);
23715e8351deSBard Liao 	unsigned int val_len = 0, val_clk, mask_clk;
23725e8351deSBard Liao 	int pre_div, bclk_ms, frame_size;
23735e8351deSBard Liao 
23745e8351deSBard Liao 	rt5670->lrck[dai->id] = params_rate(params);
23755e8351deSBard Liao 	pre_div = rl6231_get_clk_info(rt5670->sysclk, rt5670->lrck[dai->id]);
23765e8351deSBard Liao 	if (pre_div < 0) {
23775ba04c66SKuninori Morimoto 		dev_err(component->dev, "Unsupported clock setting %d for DAI %d\n",
23785e8351deSBard Liao 			rt5670->lrck[dai->id], dai->id);
23795e8351deSBard Liao 		return -EINVAL;
23805e8351deSBard Liao 	}
23815e8351deSBard Liao 	frame_size = snd_soc_params_to_frame_size(params);
23825e8351deSBard Liao 	if (frame_size < 0) {
23835ba04c66SKuninori Morimoto 		dev_err(component->dev, "Unsupported frame size: %d\n", frame_size);
23845e8351deSBard Liao 		return -EINVAL;
23855e8351deSBard Liao 	}
23865e8351deSBard Liao 	bclk_ms = frame_size > 32;
23875e8351deSBard Liao 	rt5670->bclk[dai->id] = rt5670->lrck[dai->id] * (32 << bclk_ms);
23885e8351deSBard Liao 
23895e8351deSBard Liao 	dev_dbg(dai->dev, "bclk is %dHz and lrck is %dHz\n",
23905e8351deSBard Liao 		rt5670->bclk[dai->id], rt5670->lrck[dai->id]);
23915e8351deSBard Liao 	dev_dbg(dai->dev, "bclk_ms is %d and pre_div is %d for iis %d\n",
23925e8351deSBard Liao 				bclk_ms, pre_div, dai->id);
23935e8351deSBard Liao 
23945e8351deSBard Liao 	switch (params_width(params)) {
23955e8351deSBard Liao 	case 16:
23965e8351deSBard Liao 		break;
23975e8351deSBard Liao 	case 20:
23985e8351deSBard Liao 		val_len |= RT5670_I2S_DL_20;
23995e8351deSBard Liao 		break;
24005e8351deSBard Liao 	case 24:
24015e8351deSBard Liao 		val_len |= RT5670_I2S_DL_24;
24025e8351deSBard Liao 		break;
24035e8351deSBard Liao 	case 8:
24045e8351deSBard Liao 		val_len |= RT5670_I2S_DL_8;
24055e8351deSBard Liao 		break;
24065e8351deSBard Liao 	default:
24075e8351deSBard Liao 		return -EINVAL;
24085e8351deSBard Liao 	}
24095e8351deSBard Liao 
24105e8351deSBard Liao 	switch (dai->id) {
24115e8351deSBard Liao 	case RT5670_AIF1:
24125e8351deSBard Liao 		mask_clk = RT5670_I2S_BCLK_MS1_MASK | RT5670_I2S_PD1_MASK;
24135e8351deSBard Liao 		val_clk = bclk_ms << RT5670_I2S_BCLK_MS1_SFT |
24145e8351deSBard Liao 			pre_div << RT5670_I2S_PD1_SFT;
24155ba04c66SKuninori Morimoto 		snd_soc_component_update_bits(component, RT5670_I2S1_SDP,
24165e8351deSBard Liao 			RT5670_I2S_DL_MASK, val_len);
24175ba04c66SKuninori Morimoto 		snd_soc_component_update_bits(component, RT5670_ADDA_CLK1, mask_clk, val_clk);
24185e8351deSBard Liao 		break;
24195e8351deSBard Liao 	case RT5670_AIF2:
24205e8351deSBard Liao 		mask_clk = RT5670_I2S_BCLK_MS2_MASK | RT5670_I2S_PD2_MASK;
24215e8351deSBard Liao 		val_clk = bclk_ms << RT5670_I2S_BCLK_MS2_SFT |
24225e8351deSBard Liao 			pre_div << RT5670_I2S_PD2_SFT;
24235ba04c66SKuninori Morimoto 		snd_soc_component_update_bits(component, RT5670_I2S2_SDP,
24245e8351deSBard Liao 			RT5670_I2S_DL_MASK, val_len);
24255ba04c66SKuninori Morimoto 		snd_soc_component_update_bits(component, RT5670_ADDA_CLK1, mask_clk, val_clk);
24265e8351deSBard Liao 		break;
24275e8351deSBard Liao 	default:
24285ba04c66SKuninori Morimoto 		dev_err(component->dev, "Invalid dai->id: %d\n", dai->id);
24295e8351deSBard Liao 		return -EINVAL;
24305e8351deSBard Liao 	}
24315e8351deSBard Liao 
24325e8351deSBard Liao 	return 0;
24335e8351deSBard Liao }
24345e8351deSBard Liao 
rt5670_set_dai_fmt(struct snd_soc_dai * dai,unsigned int fmt)24355e8351deSBard Liao static int rt5670_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
24365e8351deSBard Liao {
24375ba04c66SKuninori Morimoto 	struct snd_soc_component *component = dai->component;
24385ba04c66SKuninori Morimoto 	struct rt5670_priv *rt5670 = snd_soc_component_get_drvdata(component);
24395e8351deSBard Liao 	unsigned int reg_val = 0;
24405e8351deSBard Liao 
24415e8351deSBard Liao 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
24425e8351deSBard Liao 	case SND_SOC_DAIFMT_CBM_CFM:
24435e8351deSBard Liao 		rt5670->master[dai->id] = 1;
24445e8351deSBard Liao 		break;
24455e8351deSBard Liao 	case SND_SOC_DAIFMT_CBS_CFS:
24465e8351deSBard Liao 		reg_val |= RT5670_I2S_MS_S;
24475e8351deSBard Liao 		rt5670->master[dai->id] = 0;
24485e8351deSBard Liao 		break;
24495e8351deSBard Liao 	default:
24505e8351deSBard Liao 		return -EINVAL;
24515e8351deSBard Liao 	}
24525e8351deSBard Liao 
24535e8351deSBard Liao 	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
24545e8351deSBard Liao 	case SND_SOC_DAIFMT_NB_NF:
24555e8351deSBard Liao 		break;
24565e8351deSBard Liao 	case SND_SOC_DAIFMT_IB_NF:
24575e8351deSBard Liao 		reg_val |= RT5670_I2S_BP_INV;
24585e8351deSBard Liao 		break;
24595e8351deSBard Liao 	default:
24605e8351deSBard Liao 		return -EINVAL;
24615e8351deSBard Liao 	}
24625e8351deSBard Liao 
24635e8351deSBard Liao 	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
24645e8351deSBard Liao 	case SND_SOC_DAIFMT_I2S:
24655e8351deSBard Liao 		break;
24665e8351deSBard Liao 	case SND_SOC_DAIFMT_LEFT_J:
24675e8351deSBard Liao 		reg_val |= RT5670_I2S_DF_LEFT;
24685e8351deSBard Liao 		break;
24695e8351deSBard Liao 	case SND_SOC_DAIFMT_DSP_A:
24705e8351deSBard Liao 		reg_val |= RT5670_I2S_DF_PCM_A;
24715e8351deSBard Liao 		break;
24725e8351deSBard Liao 	case SND_SOC_DAIFMT_DSP_B:
24735e8351deSBard Liao 		reg_val |= RT5670_I2S_DF_PCM_B;
24745e8351deSBard Liao 		break;
24755e8351deSBard Liao 	default:
24765e8351deSBard Liao 		return -EINVAL;
24775e8351deSBard Liao 	}
24785e8351deSBard Liao 
24795e8351deSBard Liao 	switch (dai->id) {
24805e8351deSBard Liao 	case RT5670_AIF1:
24815ba04c66SKuninori Morimoto 		snd_soc_component_update_bits(component, RT5670_I2S1_SDP,
24825e8351deSBard Liao 			RT5670_I2S_MS_MASK | RT5670_I2S_BP_MASK |
24835e8351deSBard Liao 			RT5670_I2S_DF_MASK, reg_val);
24845e8351deSBard Liao 		break;
24855e8351deSBard Liao 	case RT5670_AIF2:
24865ba04c66SKuninori Morimoto 		snd_soc_component_update_bits(component, RT5670_I2S2_SDP,
24875e8351deSBard Liao 			RT5670_I2S_MS_MASK | RT5670_I2S_BP_MASK |
24885e8351deSBard Liao 			RT5670_I2S_DF_MASK, reg_val);
24895e8351deSBard Liao 		break;
24905e8351deSBard Liao 	default:
24915ba04c66SKuninori Morimoto 		dev_err(component->dev, "Invalid dai->id: %d\n", dai->id);
24925e8351deSBard Liao 		return -EINVAL;
24935e8351deSBard Liao 	}
24945e8351deSBard Liao 	return 0;
24955e8351deSBard Liao }
24965e8351deSBard Liao 
rt5670_set_codec_sysclk(struct snd_soc_component * component,int clk_id,int source,unsigned int freq,int dir)24975ba04c66SKuninori Morimoto static int rt5670_set_codec_sysclk(struct snd_soc_component *component, int clk_id,
24986c28ce3cSBard Liao 				   int source, unsigned int freq, int dir)
24995e8351deSBard Liao {
25005ba04c66SKuninori Morimoto 	struct rt5670_priv *rt5670 = snd_soc_component_get_drvdata(component);
25015e8351deSBard Liao 	unsigned int reg_val = 0;
25025e8351deSBard Liao 
25035e8351deSBard Liao 	switch (clk_id) {
25045e8351deSBard Liao 	case RT5670_SCLK_S_MCLK:
25055e8351deSBard Liao 		reg_val |= RT5670_SCLK_SRC_MCLK;
25065e8351deSBard Liao 		break;
25075e8351deSBard Liao 	case RT5670_SCLK_S_PLL1:
25085e8351deSBard Liao 		reg_val |= RT5670_SCLK_SRC_PLL1;
25095e8351deSBard Liao 		break;
25105e8351deSBard Liao 	case RT5670_SCLK_S_RCCLK:
25115e8351deSBard Liao 		reg_val |= RT5670_SCLK_SRC_RCCLK;
25125e8351deSBard Liao 		break;
25135e8351deSBard Liao 	default:
25145ba04c66SKuninori Morimoto 		dev_err(component->dev, "Invalid clock id (%d)\n", clk_id);
25155e8351deSBard Liao 		return -EINVAL;
25165e8351deSBard Liao 	}
25175ba04c66SKuninori Morimoto 	snd_soc_component_update_bits(component, RT5670_GLB_CLK,
25185e8351deSBard Liao 		RT5670_SCLK_SRC_MASK, reg_val);
25195e8351deSBard Liao 	rt5670->sysclk = freq;
2520485372dcSBard Liao 	if (clk_id != RT5670_SCLK_S_RCCLK)
25215e8351deSBard Liao 		rt5670->sysclk_src = clk_id;
25225e8351deSBard Liao 
25235ba04c66SKuninori Morimoto 	dev_dbg(component->dev, "Sysclk : %dHz clock id : %d\n", freq, clk_id);
25245e8351deSBard Liao 
25255e8351deSBard Liao 	return 0;
25265e8351deSBard Liao }
25275e8351deSBard Liao 
rt5670_set_dai_pll(struct snd_soc_dai * dai,int pll_id,int source,unsigned int freq_in,unsigned int freq_out)25285e8351deSBard Liao static int rt5670_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source,
25295e8351deSBard Liao 			unsigned int freq_in, unsigned int freq_out)
25305e8351deSBard Liao {
25315ba04c66SKuninori Morimoto 	struct snd_soc_component *component = dai->component;
25325ba04c66SKuninori Morimoto 	struct rt5670_priv *rt5670 = snd_soc_component_get_drvdata(component);
25335e8351deSBard Liao 	struct rl6231_pll_code pll_code;
25345e8351deSBard Liao 	int ret;
25355e8351deSBard Liao 
25365e8351deSBard Liao 	if (source == rt5670->pll_src && freq_in == rt5670->pll_in &&
25375e8351deSBard Liao 	    freq_out == rt5670->pll_out)
25385e8351deSBard Liao 		return 0;
25395e8351deSBard Liao 
25405e8351deSBard Liao 	if (!freq_in || !freq_out) {
25415ba04c66SKuninori Morimoto 		dev_dbg(component->dev, "PLL disabled\n");
25425e8351deSBard Liao 
25435e8351deSBard Liao 		rt5670->pll_in = 0;
25445e8351deSBard Liao 		rt5670->pll_out = 0;
25455ba04c66SKuninori Morimoto 		snd_soc_component_update_bits(component, RT5670_GLB_CLK,
25465e8351deSBard Liao 			RT5670_SCLK_SRC_MASK, RT5670_SCLK_SRC_MCLK);
25475e8351deSBard Liao 		return 0;
25485e8351deSBard Liao 	}
25495e8351deSBard Liao 
25505e8351deSBard Liao 	switch (source) {
25515e8351deSBard Liao 	case RT5670_PLL1_S_MCLK:
25525ba04c66SKuninori Morimoto 		snd_soc_component_update_bits(component, RT5670_GLB_CLK,
25535e8351deSBard Liao 			RT5670_PLL1_SRC_MASK, RT5670_PLL1_SRC_MCLK);
25545e8351deSBard Liao 		break;
25555e8351deSBard Liao 	case RT5670_PLL1_S_BCLK1:
25565e8351deSBard Liao 	case RT5670_PLL1_S_BCLK2:
25575e8351deSBard Liao 	case RT5670_PLL1_S_BCLK3:
25585e8351deSBard Liao 	case RT5670_PLL1_S_BCLK4:
25595e8351deSBard Liao 		switch (dai->id) {
25605e8351deSBard Liao 		case RT5670_AIF1:
25615ba04c66SKuninori Morimoto 			snd_soc_component_update_bits(component, RT5670_GLB_CLK,
25625e8351deSBard Liao 				RT5670_PLL1_SRC_MASK, RT5670_PLL1_SRC_BCLK1);
25635e8351deSBard Liao 			break;
25645e8351deSBard Liao 		case RT5670_AIF2:
25655ba04c66SKuninori Morimoto 			snd_soc_component_update_bits(component, RT5670_GLB_CLK,
25665e8351deSBard Liao 				RT5670_PLL1_SRC_MASK, RT5670_PLL1_SRC_BCLK2);
25675e8351deSBard Liao 			break;
25685e8351deSBard Liao 		default:
25695ba04c66SKuninori Morimoto 			dev_err(component->dev, "Invalid dai->id: %d\n", dai->id);
25705e8351deSBard Liao 			return -EINVAL;
25715e8351deSBard Liao 		}
25725e8351deSBard Liao 		break;
25735e8351deSBard Liao 	default:
25745ba04c66SKuninori Morimoto 		dev_err(component->dev, "Unknown PLL source %d\n", source);
25755e8351deSBard Liao 		return -EINVAL;
25765e8351deSBard Liao 	}
25775e8351deSBard Liao 
25785e8351deSBard Liao 	ret = rl6231_pll_calc(freq_in, freq_out, &pll_code);
25795e8351deSBard Liao 	if (ret < 0) {
2580a4db95b2SColin Ian King 		dev_err(component->dev, "Unsupported input clock %d\n", freq_in);
25815e8351deSBard Liao 		return ret;
25825e8351deSBard Liao 	}
25835e8351deSBard Liao 
25845ba04c66SKuninori Morimoto 	dev_dbg(component->dev, "bypass=%d m=%d n=%d k=%d\n",
25855e8351deSBard Liao 		pll_code.m_bp, (pll_code.m_bp ? 0 : pll_code.m_code),
25865e8351deSBard Liao 		pll_code.n_code, pll_code.k_code);
25875e8351deSBard Liao 
25885ba04c66SKuninori Morimoto 	snd_soc_component_write(component, RT5670_PLL_CTRL1,
25895e8351deSBard Liao 		pll_code.n_code << RT5670_PLL_N_SFT | pll_code.k_code);
25905ba04c66SKuninori Morimoto 	snd_soc_component_write(component, RT5670_PLL_CTRL2,
25917ad9b8d2SPierre-Louis Bossart 		((pll_code.m_bp ? 0 : pll_code.m_code) << RT5670_PLL_M_SFT) |
25927ad9b8d2SPierre-Louis Bossart 		(pll_code.m_bp << RT5670_PLL_M_BP_SFT));
25935e8351deSBard Liao 
25945e8351deSBard Liao 	rt5670->pll_in = freq_in;
25955e8351deSBard Liao 	rt5670->pll_out = freq_out;
25965e8351deSBard Liao 	rt5670->pll_src = source;
25975e8351deSBard Liao 
25985e8351deSBard Liao 	return 0;
25995e8351deSBard Liao }
26005e8351deSBard Liao 
rt5670_set_tdm_slot(struct snd_soc_dai * dai,unsigned int tx_mask,unsigned int rx_mask,int slots,int slot_width)26015e8351deSBard Liao static int rt5670_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
26025e8351deSBard Liao 			unsigned int rx_mask, int slots, int slot_width)
26035e8351deSBard Liao {
26045ba04c66SKuninori Morimoto 	struct snd_soc_component *component = dai->component;
26055e8351deSBard Liao 	unsigned int val = 0;
26065e8351deSBard Liao 
26075e8351deSBard Liao 	if (rx_mask || tx_mask)
26085e8351deSBard Liao 		val |= (1 << 14);
26095e8351deSBard Liao 
26105e8351deSBard Liao 	switch (slots) {
26115e8351deSBard Liao 	case 4:
26125e8351deSBard Liao 		val |= (1 << 12);
26135e8351deSBard Liao 		break;
26145e8351deSBard Liao 	case 6:
26155e8351deSBard Liao 		val |= (2 << 12);
26165e8351deSBard Liao 		break;
26175e8351deSBard Liao 	case 8:
26185e8351deSBard Liao 		val |= (3 << 12);
26195e8351deSBard Liao 		break;
26205e8351deSBard Liao 	case 2:
26215e8351deSBard Liao 		break;
26225e8351deSBard Liao 	default:
26235e8351deSBard Liao 		return -EINVAL;
26245e8351deSBard Liao 	}
26255e8351deSBard Liao 
26265e8351deSBard Liao 	switch (slot_width) {
26275e8351deSBard Liao 	case 20:
26285e8351deSBard Liao 		val |= (1 << 10);
26295e8351deSBard Liao 		break;
26305e8351deSBard Liao 	case 24:
26315e8351deSBard Liao 		val |= (2 << 10);
26325e8351deSBard Liao 		break;
26335e8351deSBard Liao 	case 32:
26345e8351deSBard Liao 		val |= (3 << 10);
26355e8351deSBard Liao 		break;
26365e8351deSBard Liao 	case 16:
26375e8351deSBard Liao 		break;
26385e8351deSBard Liao 	default:
26395e8351deSBard Liao 		return -EINVAL;
26405e8351deSBard Liao 	}
26415e8351deSBard Liao 
26425ba04c66SKuninori Morimoto 	snd_soc_component_update_bits(component, RT5670_TDM_CTRL_1, 0x7c00, val);
26435e8351deSBard Liao 
26445e8351deSBard Liao 	return 0;
26455e8351deSBard Liao }
26465e8351deSBard Liao 
rt5670_set_bclk_ratio(struct snd_soc_dai * dai,unsigned int ratio)2647d0817657SBard Liao static int rt5670_set_bclk_ratio(struct snd_soc_dai *dai, unsigned int ratio)
2648d0817657SBard Liao {
26495ba04c66SKuninori Morimoto 	struct snd_soc_component *component = dai->component;
2650d0817657SBard Liao 
26515ba04c66SKuninori Morimoto 	dev_dbg(component->dev, "%s ratio=%d\n", __func__, ratio);
2652d0817657SBard Liao 	if (dai->id != RT5670_AIF1)
2653d0817657SBard Liao 		return 0;
2654d0817657SBard Liao 
2655d0817657SBard Liao 	if ((ratio % 50) == 0)
26565ba04c66SKuninori Morimoto 		snd_soc_component_update_bits(component, RT5670_GEN_CTRL3,
2657d0817657SBard Liao 			RT5670_TDM_DATA_MODE_SEL, RT5670_TDM_DATA_MODE_50FS);
2658d0817657SBard Liao 	else
26595ba04c66SKuninori Morimoto 		snd_soc_component_update_bits(component, RT5670_GEN_CTRL3,
2660d0817657SBard Liao 			RT5670_TDM_DATA_MODE_SEL, RT5670_TDM_DATA_MODE_NOR);
2661d0817657SBard Liao 
2662d0817657SBard Liao 	return 0;
2663d0817657SBard Liao }
2664d0817657SBard Liao 
rt5670_set_bias_level(struct snd_soc_component * component,enum snd_soc_bias_level level)26655ba04c66SKuninori Morimoto static int rt5670_set_bias_level(struct snd_soc_component *component,
26665e8351deSBard Liao 			enum snd_soc_bias_level level)
26675e8351deSBard Liao {
26685ba04c66SKuninori Morimoto 	struct rt5670_priv *rt5670 = snd_soc_component_get_drvdata(component);
2669044b724aSBard Liao 
26705e8351deSBard Liao 	switch (level) {
26715e8351deSBard Liao 	case SND_SOC_BIAS_PREPARE:
26725ba04c66SKuninori Morimoto 		if (SND_SOC_BIAS_STANDBY == snd_soc_component_get_bias_level(component)) {
26735ba04c66SKuninori Morimoto 			snd_soc_component_update_bits(component, RT5670_PWR_ANLG1,
26745e8351deSBard Liao 				RT5670_PWR_VREF1 | RT5670_PWR_MB |
26755e8351deSBard Liao 				RT5670_PWR_BG | RT5670_PWR_VREF2,
26765e8351deSBard Liao 				RT5670_PWR_VREF1 | RT5670_PWR_MB |
26775e8351deSBard Liao 				RT5670_PWR_BG | RT5670_PWR_VREF2);
26785e8351deSBard Liao 			mdelay(10);
26795ba04c66SKuninori Morimoto 			snd_soc_component_update_bits(component, RT5670_PWR_ANLG1,
26805e8351deSBard Liao 				RT5670_PWR_FV1 | RT5670_PWR_FV2,
26815e8351deSBard Liao 				RT5670_PWR_FV1 | RT5670_PWR_FV2);
26825ba04c66SKuninori Morimoto 			snd_soc_component_update_bits(component, RT5670_CHARGE_PUMP,
26835e8351deSBard Liao 				RT5670_OSW_L_MASK | RT5670_OSW_R_MASK,
26845e8351deSBard Liao 				RT5670_OSW_L_DIS | RT5670_OSW_R_DIS);
26855ba04c66SKuninori Morimoto 			snd_soc_component_update_bits(component, RT5670_DIG_MISC, 0x1, 0x1);
26865ba04c66SKuninori Morimoto 			snd_soc_component_update_bits(component, RT5670_PWR_ANLG1,
2687c8c6f0d8SBard Liao 				RT5670_LDO_SEL_MASK, 0x5);
26885e8351deSBard Liao 		}
26895e8351deSBard Liao 		break;
26905e8351deSBard Liao 	case SND_SOC_BIAS_STANDBY:
26915ba04c66SKuninori Morimoto 		snd_soc_component_update_bits(component, RT5670_PWR_ANLG1,
2692044b724aSBard Liao 				RT5670_PWR_VREF1 | RT5670_PWR_VREF2 |
2693044b724aSBard Liao 				RT5670_PWR_FV1 | RT5670_PWR_FV2, 0);
26945ba04c66SKuninori Morimoto 		snd_soc_component_update_bits(component, RT5670_PWR_ANLG1,
2695c8c6f0d8SBard Liao 				RT5670_LDO_SEL_MASK, 0x3);
26965e8351deSBard Liao 		break;
2697044b724aSBard Liao 	case SND_SOC_BIAS_OFF:
2698c14f61a8SHans de Goede 		if (rt5670->jd_mode)
26995ba04c66SKuninori Morimoto 			snd_soc_component_update_bits(component, RT5670_PWR_ANLG1,
2700044b724aSBard Liao 				RT5670_PWR_VREF1 | RT5670_PWR_MB |
2701044b724aSBard Liao 				RT5670_PWR_BG | RT5670_PWR_VREF2 |
2702044b724aSBard Liao 				RT5670_PWR_FV1 | RT5670_PWR_FV2,
2703044b724aSBard Liao 				RT5670_PWR_MB | RT5670_PWR_BG);
2704044b724aSBard Liao 		else
27055ba04c66SKuninori Morimoto 			snd_soc_component_update_bits(component, RT5670_PWR_ANLG1,
2706044b724aSBard Liao 				RT5670_PWR_VREF1 | RT5670_PWR_MB |
2707044b724aSBard Liao 				RT5670_PWR_BG | RT5670_PWR_VREF2 |
2708044b724aSBard Liao 				RT5670_PWR_FV1 | RT5670_PWR_FV2, 0);
2709044b724aSBard Liao 
27105ba04c66SKuninori Morimoto 		snd_soc_component_update_bits(component, RT5670_DIG_MISC, 0x1, 0x0);
2711044b724aSBard Liao 		break;
27125e8351deSBard Liao 
27135e8351deSBard Liao 	default:
27145e8351deSBard Liao 		break;
27155e8351deSBard Liao 	}
27165e8351deSBard Liao 
27175e8351deSBard Liao 	return 0;
27185e8351deSBard Liao }
27195e8351deSBard Liao 
rt5670_probe(struct snd_soc_component * component)27205ba04c66SKuninori Morimoto static int rt5670_probe(struct snd_soc_component *component)
27215e8351deSBard Liao {
27225ba04c66SKuninori Morimoto 	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
27235ba04c66SKuninori Morimoto 	struct rt5670_priv *rt5670 = snd_soc_component_get_drvdata(component);
27245e8351deSBard Liao 
2725467a2553SKuninori Morimoto 	switch (snd_soc_component_read(component, RT5670_RESET) & RT5670_ID_MASK) {
27260cf18632SBard Liao 	case RT5670_ID_5670:
27270cf18632SBard Liao 	case RT5670_ID_5671:
27286d8135ffSLars-Peter Clausen 		snd_soc_dapm_new_controls(dapm,
27290cf18632SBard Liao 			rt5670_specific_dapm_widgets,
27300cf18632SBard Liao 			ARRAY_SIZE(rt5670_specific_dapm_widgets));
27316d8135ffSLars-Peter Clausen 		snd_soc_dapm_add_routes(dapm,
27320cf18632SBard Liao 			rt5670_specific_dapm_routes,
27330cf18632SBard Liao 			ARRAY_SIZE(rt5670_specific_dapm_routes));
27340cf18632SBard Liao 		break;
27350cf18632SBard Liao 	case RT5670_ID_5672:
27366d8135ffSLars-Peter Clausen 		snd_soc_dapm_new_controls(dapm,
27370cf18632SBard Liao 			rt5672_specific_dapm_widgets,
27380cf18632SBard Liao 			ARRAY_SIZE(rt5672_specific_dapm_widgets));
27396d8135ffSLars-Peter Clausen 		snd_soc_dapm_add_routes(dapm,
27400cf18632SBard Liao 			rt5672_specific_dapm_routes,
27410cf18632SBard Liao 			ARRAY_SIZE(rt5672_specific_dapm_routes));
27420cf18632SBard Liao 		break;
27430cf18632SBard Liao 	default:
27445ba04c66SKuninori Morimoto 		dev_err(component->dev,
27450cf18632SBard Liao 			"The driver is for RT5670 RT5671 or RT5672 only\n");
27460cf18632SBard Liao 		return -ENODEV;
27470cf18632SBard Liao 	}
27485ba04c66SKuninori Morimoto 	rt5670->component = component;
27495e8351deSBard Liao 
27505e8351deSBard Liao 	return 0;
27515e8351deSBard Liao }
27525e8351deSBard Liao 
rt5670_remove(struct snd_soc_component * component)27535ba04c66SKuninori Morimoto static void rt5670_remove(struct snd_soc_component *component)
27545e8351deSBard Liao {
27555ba04c66SKuninori Morimoto 	struct rt5670_priv *rt5670 = snd_soc_component_get_drvdata(component);
27565e8351deSBard Liao 
27575e8351deSBard Liao 	regmap_write(rt5670->regmap, RT5670_RESET, 0);
2758d3ef7054SBard Liao 	snd_soc_jack_free_gpios(rt5670->jack, 1, &rt5670->hp_gpio);
27595e8351deSBard Liao }
27605e8351deSBard Liao 
27615e8351deSBard Liao #ifdef CONFIG_PM
rt5670_suspend(struct snd_soc_component * component)27625ba04c66SKuninori Morimoto static int rt5670_suspend(struct snd_soc_component *component)
27635e8351deSBard Liao {
27645ba04c66SKuninori Morimoto 	struct rt5670_priv *rt5670 = snd_soc_component_get_drvdata(component);
27655e8351deSBard Liao 
27665e8351deSBard Liao 	regcache_cache_only(rt5670->regmap, true);
27675e8351deSBard Liao 	regcache_mark_dirty(rt5670->regmap);
27685e8351deSBard Liao 	return 0;
27695e8351deSBard Liao }
27705e8351deSBard Liao 
rt5670_resume(struct snd_soc_component * component)27715ba04c66SKuninori Morimoto static int rt5670_resume(struct snd_soc_component *component)
27725e8351deSBard Liao {
27735ba04c66SKuninori Morimoto 	struct rt5670_priv *rt5670 = snd_soc_component_get_drvdata(component);
27745e8351deSBard Liao 
27755e8351deSBard Liao 	regcache_cache_only(rt5670->regmap, false);
27765e8351deSBard Liao 	regcache_sync(rt5670->regmap);
27775e8351deSBard Liao 
27785e8351deSBard Liao 	return 0;
27795e8351deSBard Liao }
27805e8351deSBard Liao #else
27815e8351deSBard Liao #define rt5670_suspend NULL
27825e8351deSBard Liao #define rt5670_resume NULL
27835e8351deSBard Liao #endif
27845e8351deSBard Liao 
27855e8351deSBard Liao #define RT5670_STEREO_RATES SNDRV_PCM_RATE_8000_96000
27865e8351deSBard Liao #define RT5670_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
27875e8351deSBard Liao 			SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S8)
27885e8351deSBard Liao 
278964793047SAxel Lin static const struct snd_soc_dai_ops rt5670_aif_dai_ops = {
27905e8351deSBard Liao 	.hw_params = rt5670_hw_params,
27915e8351deSBard Liao 	.set_fmt = rt5670_set_dai_fmt,
27925e8351deSBard Liao 	.set_tdm_slot = rt5670_set_tdm_slot,
27935e8351deSBard Liao 	.set_pll = rt5670_set_dai_pll,
2794d0817657SBard Liao 	.set_bclk_ratio = rt5670_set_bclk_ratio,
27955e8351deSBard Liao };
27965e8351deSBard Liao 
2797ff62b958SMark Brown static struct snd_soc_dai_driver rt5670_dai[] = {
27985e8351deSBard Liao 	{
27995e8351deSBard Liao 		.name = "rt5670-aif1",
28005e8351deSBard Liao 		.id = RT5670_AIF1,
28015e8351deSBard Liao 		.playback = {
28025e8351deSBard Liao 			.stream_name = "AIF1 Playback",
28035e8351deSBard Liao 			.channels_min = 1,
28045e8351deSBard Liao 			.channels_max = 2,
28055e8351deSBard Liao 			.rates = RT5670_STEREO_RATES,
28065e8351deSBard Liao 			.formats = RT5670_FORMATS,
28075e8351deSBard Liao 		},
28085e8351deSBard Liao 		.capture = {
28095e8351deSBard Liao 			.stream_name = "AIF1 Capture",
28105e8351deSBard Liao 			.channels_min = 1,
28115e8351deSBard Liao 			.channels_max = 2,
28125e8351deSBard Liao 			.rates = RT5670_STEREO_RATES,
28135e8351deSBard Liao 			.formats = RT5670_FORMATS,
28145e8351deSBard Liao 		},
28155e8351deSBard Liao 		.ops = &rt5670_aif_dai_ops,
2816bc03b391SKuninori Morimoto 		.symmetric_rate = 1,
28175e8351deSBard Liao 	},
28185e8351deSBard Liao 	{
28195e8351deSBard Liao 		.name = "rt5670-aif2",
28205e8351deSBard Liao 		.id = RT5670_AIF2,
28215e8351deSBard Liao 		.playback = {
28225e8351deSBard Liao 			.stream_name = "AIF2 Playback",
28235e8351deSBard Liao 			.channels_min = 1,
28245e8351deSBard Liao 			.channels_max = 2,
28255e8351deSBard Liao 			.rates = RT5670_STEREO_RATES,
28265e8351deSBard Liao 			.formats = RT5670_FORMATS,
28275e8351deSBard Liao 		},
28285e8351deSBard Liao 		.capture = {
28295e8351deSBard Liao 			.stream_name = "AIF2 Capture",
28305e8351deSBard Liao 			.channels_min = 1,
28315e8351deSBard Liao 			.channels_max = 2,
28325e8351deSBard Liao 			.rates = RT5670_STEREO_RATES,
28335e8351deSBard Liao 			.formats = RT5670_FORMATS,
28345e8351deSBard Liao 		},
28355e8351deSBard Liao 		.ops = &rt5670_aif_dai_ops,
2836bc03b391SKuninori Morimoto 		.symmetric_rate = 1,
28375e8351deSBard Liao 	},
28385e8351deSBard Liao };
28395e8351deSBard Liao 
28405ba04c66SKuninori Morimoto static const struct snd_soc_component_driver soc_component_dev_rt5670 = {
28415e8351deSBard Liao 	.probe			= rt5670_probe,
28425e8351deSBard Liao 	.remove			= rt5670_remove,
28435e8351deSBard Liao 	.suspend		= rt5670_suspend,
28445e8351deSBard Liao 	.resume			= rt5670_resume,
28455e8351deSBard Liao 	.set_bias_level		= rt5670_set_bias_level,
28466c28ce3cSBard Liao 	.set_sysclk		= rt5670_set_codec_sysclk,
28475e8351deSBard Liao 	.controls		= rt5670_snd_controls,
28485e8351deSBard Liao 	.num_controls		= ARRAY_SIZE(rt5670_snd_controls),
28495e8351deSBard Liao 	.dapm_widgets		= rt5670_dapm_widgets,
28505e8351deSBard Liao 	.num_dapm_widgets	= ARRAY_SIZE(rt5670_dapm_widgets),
28515e8351deSBard Liao 	.dapm_routes		= rt5670_dapm_routes,
28525e8351deSBard Liao 	.num_dapm_routes	= ARRAY_SIZE(rt5670_dapm_routes),
28535ba04c66SKuninori Morimoto 	.use_pmdown_time	= 1,
28545ba04c66SKuninori Morimoto 	.endianness		= 1,
28555e8351deSBard Liao };
28565e8351deSBard Liao 
28575e8351deSBard Liao static const struct regmap_config rt5670_regmap = {
28585e8351deSBard Liao 	.reg_bits = 8,
28595e8351deSBard Liao 	.val_bits = 16,
28601c96a2f6SDavid Frey 	.use_single_read = true,
28611c96a2f6SDavid Frey 	.use_single_write = true,
28625e8351deSBard Liao 	.max_register = RT5670_VENDOR_ID2 + 1 + (ARRAY_SIZE(rt5670_ranges) *
28635e8351deSBard Liao 					       RT5670_PR_SPACING),
28645e8351deSBard Liao 	.volatile_reg = rt5670_volatile_register,
28655e8351deSBard Liao 	.readable_reg = rt5670_readable_register,
2866*11cce87fSMark Brown 	.cache_type = REGCACHE_MAPLE,
28675e8351deSBard Liao 	.reg_defaults = rt5670_reg,
28685e8351deSBard Liao 	.num_reg_defaults = ARRAY_SIZE(rt5670_reg),
28695e8351deSBard Liao 	.ranges = rt5670_ranges,
28705e8351deSBard Liao 	.num_ranges = ARRAY_SIZE(rt5670_ranges),
28715e8351deSBard Liao };
28725e8351deSBard Liao 
28735e8351deSBard Liao static const struct i2c_device_id rt5670_i2c_id[] = {
28745e8351deSBard Liao 	{ "rt5670", 0 },
28750cf18632SBard Liao 	{ "rt5671", 0 },
28760cf18632SBard Liao 	{ "rt5672", 0 },
28775e8351deSBard Liao 	{ }
28785e8351deSBard Liao };
28795e8351deSBard Liao MODULE_DEVICE_TABLE(i2c, rt5670_i2c_id);
28805e8351deSBard Liao 
28810605815eSMengdong Lin #ifdef CONFIG_ACPI
28824e0ce6a4SMathias Krause static const struct acpi_device_id rt5670_acpi_match[] = {
28830605815eSMengdong Lin 	{ "10EC5670", 0},
2884d2528006STakashi Iwai 	{ "10EC5672", 0},
288593ffeaa8SPierre-Louis Bossart 	{ "10EC5640", 0}, /* quirk */
28860605815eSMengdong Lin 	{ },
28870605815eSMengdong Lin };
28880605815eSMengdong Lin MODULE_DEVICE_TABLE(acpi, rt5670_acpi_match);
28890605815eSMengdong Lin #endif
28900605815eSMengdong Lin 
rt5670_quirk_cb(const struct dmi_system_id * id)28918e1b1785SPierre-Louis Bossart static int rt5670_quirk_cb(const struct dmi_system_id *id)
2892223c055aSBard Liao {
28938e1b1785SPierre-Louis Bossart 	rt5670_quirk = (unsigned long)id->driver_data;
28948e1b1785SPierre-Louis Bossart 	return 1;
28958e1b1785SPierre-Louis Bossart }
28968e1b1785SPierre-Louis Bossart 
28978e1b1785SPierre-Louis Bossart static const struct dmi_system_id dmi_platform_intel_quirks[] = {
28988e1b1785SPierre-Louis Bossart 	{
28998e1b1785SPierre-Louis Bossart 		.callback = rt5670_quirk_cb,
2900223c055aSBard Liao 		.ident = "Intel Braswell",
2901223c055aSBard Liao 		.matches = {
2902223c055aSBard Liao 			DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"),
2903223c055aSBard Liao 			DMI_MATCH(DMI_BOARD_NAME, "Braswell CRB"),
2904223c055aSBard Liao 		},
29058e1b1785SPierre-Louis Bossart 		.driver_data = (unsigned long *)(RT5670_DMIC_EN |
29068e1b1785SPierre-Louis Bossart 						 RT5670_DMIC1_IN2P |
2907883330c1SHans de Goede 						 RT5670_GPIO1_IS_IRQ |
29088e1b1785SPierre-Louis Bossart 						 RT5670_JD_MODE1),
2909223c055aSBard Liao 	},
2910b4ff47d2STakashi Iwai 	{
29118e1b1785SPierre-Louis Bossart 		.callback = rt5670_quirk_cb,
2912b4ff47d2STakashi Iwai 		.ident = "Dell Wyse 3040",
2913b4ff47d2STakashi Iwai 		.matches = {
2914b4ff47d2STakashi Iwai 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
2915b4ff47d2STakashi Iwai 			DMI_MATCH(DMI_PRODUCT_NAME, "Wyse 3040"),
2916b4ff47d2STakashi Iwai 		},
29178e1b1785SPierre-Louis Bossart 		.driver_data = (unsigned long *)(RT5670_DMIC_EN |
29188e1b1785SPierre-Louis Bossart 						 RT5670_DMIC1_IN2P |
2919883330c1SHans de Goede 						 RT5670_GPIO1_IS_IRQ |
29208e1b1785SPierre-Louis Bossart 						 RT5670_JD_MODE1),
2921b4ff47d2STakashi Iwai 	},
292267e03ff3SNicole Faerber 	{
29238e1b1785SPierre-Louis Bossart 		.callback = rt5670_quirk_cb,
2924818838e6SHans de Goede 		.ident = "Lenovo Thinkpad Tablet 8",
2925818838e6SHans de Goede 		.matches = {
2926818838e6SHans de Goede 			DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
2927818838e6SHans de Goede 			DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad 8"),
2928818838e6SHans de Goede 		},
2929818838e6SHans de Goede 		.driver_data = (unsigned long *)(RT5670_DMIC_EN |
2930818838e6SHans de Goede 						 RT5670_DMIC2_INR |
2931883330c1SHans de Goede 						 RT5670_GPIO1_IS_IRQ |
2932818838e6SHans de Goede 						 RT5670_JD_MODE1),
2933818838e6SHans de Goede 	},
2934818838e6SHans de Goede 	{
2935818838e6SHans de Goede 		.callback = rt5670_quirk_cb,
293667e03ff3SNicole Faerber 		.ident = "Lenovo Thinkpad Tablet 10",
293767e03ff3SNicole Faerber 		.matches = {
293867e03ff3SNicole Faerber 			DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
293967e03ff3SNicole Faerber 			DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad 10"),
294067e03ff3SNicole Faerber 		},
29418e1b1785SPierre-Louis Bossart 		.driver_data = (unsigned long *)(RT5670_DMIC_EN |
29428e1b1785SPierre-Louis Bossart 						 RT5670_DMIC1_IN2P |
2943883330c1SHans de Goede 						 RT5670_GPIO1_IS_IRQ |
29448e1b1785SPierre-Louis Bossart 						 RT5670_JD_MODE1),
294567e03ff3SNicole Faerber 	},
294667e03ff3SNicole Faerber 	{
29478e1b1785SPierre-Louis Bossart 		.callback = rt5670_quirk_cb,
294867e03ff3SNicole Faerber 		.ident = "Lenovo Thinkpad Tablet 10",
294967e03ff3SNicole Faerber 		.matches = {
295067e03ff3SNicole Faerber 			DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
295167e03ff3SNicole Faerber 			DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad Tablet B"),
295267e03ff3SNicole Faerber 		},
29538e1b1785SPierre-Louis Bossart 		.driver_data = (unsigned long *)(RT5670_DMIC_EN |
29548e1b1785SPierre-Louis Bossart 						 RT5670_DMIC1_IN2P |
2955883330c1SHans de Goede 						 RT5670_GPIO1_IS_IRQ |
29568e1b1785SPierre-Louis Bossart 						 RT5670_JD_MODE1),
295767e03ff3SNicole Faerber 	},
295867e03ff3SNicole Faerber 	{
29598e1b1785SPierre-Louis Bossart 		.callback = rt5670_quirk_cb,
296085ca6b17SHans de Goede 		.ident = "Lenovo Miix 2 10",
296167e03ff3SNicole Faerber 		.matches = {
296267e03ff3SNicole Faerber 			DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
296367e03ff3SNicole Faerber 			DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo Miix 2 10"),
296467e03ff3SNicole Faerber 		},
29658e1b1785SPierre-Louis Bossart 		.driver_data = (unsigned long *)(RT5670_DMIC_EN |
29668e1b1785SPierre-Louis Bossart 						 RT5670_DMIC1_IN2P |
296785ca6b17SHans de Goede 						 RT5670_GPIO1_IS_EXT_SPK_EN |
29688e1b1785SPierre-Louis Bossart 						 RT5670_JD_MODE2),
296967e03ff3SNicole Faerber 	},
2970c26d8389SPierre-Louis Bossart 	{
29718e1b1785SPierre-Louis Bossart 		.callback = rt5670_quirk_cb,
2972c26d8389SPierre-Louis Bossart 		.ident = "Dell Venue 8 Pro 5855",
2973c26d8389SPierre-Louis Bossart 		.matches = {
2974c26d8389SPierre-Louis Bossart 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
2975c26d8389SPierre-Louis Bossart 			DMI_MATCH(DMI_PRODUCT_NAME, "Venue 8 Pro 5855"),
2976c26d8389SPierre-Louis Bossart 		},
29778e1b1785SPierre-Louis Bossart 		.driver_data = (unsigned long *)(RT5670_DMIC_EN |
29788e1b1785SPierre-Louis Bossart 						 RT5670_DMIC2_INR |
2979883330c1SHans de Goede 						 RT5670_GPIO1_IS_IRQ |
29808e1b1785SPierre-Louis Bossart 						 RT5670_JD_MODE3),
2981c26d8389SPierre-Louis Bossart 	},
29823e951e79SKovács Tamás 	{
29833e951e79SKovács Tamás 		.callback = rt5670_quirk_cb,
298484cb0d55SHans de Goede 		.ident = "Dell Venue 10 Pro 5055",
298584cb0d55SHans de Goede 		.matches = {
298684cb0d55SHans de Goede 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
298784cb0d55SHans de Goede 			DMI_MATCH(DMI_PRODUCT_NAME, "Venue 10 Pro 5055"),
298884cb0d55SHans de Goede 		},
298984cb0d55SHans de Goede 		.driver_data = (unsigned long *)(RT5670_DMIC_EN |
299084cb0d55SHans de Goede 						 RT5670_DMIC2_INR |
299184cb0d55SHans de Goede 						 RT5670_GPIO1_IS_IRQ |
299284cb0d55SHans de Goede 						 RT5670_JD_MODE1),
299384cb0d55SHans de Goede 	},
299484cb0d55SHans de Goede 	{
299584cb0d55SHans de Goede 		.callback = rt5670_quirk_cb,
29963e951e79SKovács Tamás 		.ident = "Aegex 10 tablet (RU2)",
29973e951e79SKovács Tamás 		.matches = {
29983e951e79SKovács Tamás 			DMI_MATCH(DMI_SYS_VENDOR, "AEGEX"),
29993e951e79SKovács Tamás 			DMI_MATCH(DMI_PRODUCT_VERSION, "RU2"),
30003e951e79SKovács Tamás 		},
30013e951e79SKovács Tamás 		.driver_data = (unsigned long *)(RT5670_DMIC_EN |
30023e951e79SKovács Tamás 						 RT5670_DMIC2_INR |
3003883330c1SHans de Goede 						 RT5670_GPIO1_IS_IRQ |
30043e951e79SKovács Tamás 						 RT5670_JD_MODE3),
30053e951e79SKovács Tamás 	},
3006c26d8389SPierre-Louis Bossart 	{}
3007c26d8389SPierre-Louis Bossart };
3008c26d8389SPierre-Louis Bossart 
rt5670_components(void)30093d534537SHans de Goede const char *rt5670_components(void)
30103d534537SHans de Goede {
30113d534537SHans de Goede 	unsigned long quirk;
30123d534537SHans de Goede 	bool dmic1 = false;
30133d534537SHans de Goede 	bool dmic2 = false;
30143d534537SHans de Goede 	bool dmic3 = false;
30153d534537SHans de Goede 
30163d534537SHans de Goede 	if (quirk_override) {
30173d534537SHans de Goede 		quirk = quirk_override;
30183d534537SHans de Goede 	} else {
30193d534537SHans de Goede 		dmi_check_system(dmi_platform_intel_quirks);
30203d534537SHans de Goede 		quirk = rt5670_quirk;
30213d534537SHans de Goede 	}
30223d534537SHans de Goede 
30233d534537SHans de Goede 	if ((quirk & RT5670_DMIC1_IN2P) ||
30243d534537SHans de Goede 	    (quirk & RT5670_DMIC1_GPIO6) ||
30253d534537SHans de Goede 	    (quirk & RT5670_DMIC1_GPIO7))
30263d534537SHans de Goede 		dmic1 = true;
30273d534537SHans de Goede 
30283d534537SHans de Goede 	if ((quirk & RT5670_DMIC2_INR) ||
30293d534537SHans de Goede 	    (quirk & RT5670_DMIC2_GPIO8))
30303d534537SHans de Goede 		dmic2 = true;
30313d534537SHans de Goede 
30323d534537SHans de Goede 	if (quirk & RT5670_DMIC3_GPIO5)
30333d534537SHans de Goede 		dmic3 = true;
30343d534537SHans de Goede 
30353d534537SHans de Goede 	if (dmic1 && dmic2)
30363d534537SHans de Goede 		return "cfg-spk:2 cfg-mic:dmics12";
30373d534537SHans de Goede 	else if (dmic1)
30383d534537SHans de Goede 		return "cfg-spk:2 cfg-mic:dmic1";
30393d534537SHans de Goede 	else if (dmic2)
30403d534537SHans de Goede 		return "cfg-spk:2 cfg-mic:dmic2";
30413d534537SHans de Goede 	else if (dmic3)
30423d534537SHans de Goede 		return "cfg-spk:2 cfg-mic:dmic3";
30433d534537SHans de Goede 
30443d534537SHans de Goede 	return NULL;
30453d534537SHans de Goede }
30463d534537SHans de Goede EXPORT_SYMBOL_GPL(rt5670_components);
30473d534537SHans de Goede 
rt5670_i2c_probe(struct i2c_client * i2c)304835b88858SStephen Kitt static int rt5670_i2c_probe(struct i2c_client *i2c)
30495e8351deSBard Liao {
30505e8351deSBard Liao 	struct rt5670_priv *rt5670;
30515e8351deSBard Liao 	int ret;
30525e8351deSBard Liao 	unsigned int val;
30535e8351deSBard Liao 
30545e8351deSBard Liao 	rt5670 = devm_kzalloc(&i2c->dev,
30555e8351deSBard Liao 				sizeof(struct rt5670_priv),
30565e8351deSBard Liao 				GFP_KERNEL);
30575e8351deSBard Liao 	if (NULL == rt5670)
30585e8351deSBard Liao 		return -ENOMEM;
30595e8351deSBard Liao 
30605e8351deSBard Liao 	i2c_set_clientdata(i2c, rt5670);
30615e8351deSBard Liao 
30628e1b1785SPierre-Louis Bossart 	dmi_check_system(dmi_platform_intel_quirks);
30638e1b1785SPierre-Louis Bossart 	if (quirk_override) {
30648e1b1785SPierre-Louis Bossart 		dev_info(&i2c->dev, "Overriding quirk 0x%x => 0x%x\n",
30658e1b1785SPierre-Louis Bossart 			 (unsigned int)rt5670_quirk, quirk_override);
30668e1b1785SPierre-Louis Bossart 		rt5670_quirk = quirk_override;
30678e1b1785SPierre-Louis Bossart 	}
30688e1b1785SPierre-Louis Bossart 
3069883330c1SHans de Goede 	if (rt5670_quirk & RT5670_GPIO1_IS_IRQ) {
3070883330c1SHans de Goede 		rt5670->gpio1_is_irq = true;
3071883330c1SHans de Goede 		dev_info(&i2c->dev, "quirk GPIO1 is IRQ\n");
30728e1b1785SPierre-Louis Bossart 	}
307385ca6b17SHans de Goede 	if (rt5670_quirk & RT5670_GPIO1_IS_EXT_SPK_EN) {
3074c14f61a8SHans de Goede 		rt5670->gpio1_is_ext_spk_en = true;
307585ca6b17SHans de Goede 		dev_info(&i2c->dev, "quirk GPIO1 is external speaker enable\n");
307685ca6b17SHans de Goede 	}
30778e1b1785SPierre-Louis Bossart 	if (rt5670_quirk & RT5670_IN2_DIFF) {
3078c14f61a8SHans de Goede 		rt5670->in2_diff = true;
30798e1b1785SPierre-Louis Bossart 		dev_info(&i2c->dev, "quirk IN2_DIFF\n");
30808e1b1785SPierre-Louis Bossart 	}
30818e1b1785SPierre-Louis Bossart 	if (rt5670_quirk & RT5670_DMIC_EN) {
3082c14f61a8SHans de Goede 		rt5670->dmic_en = true;
30838e1b1785SPierre-Louis Bossart 		dev_info(&i2c->dev, "quirk DMIC enabled\n");
30848e1b1785SPierre-Louis Bossart 	}
30858e1b1785SPierre-Louis Bossart 	if (rt5670_quirk & RT5670_DMIC1_IN2P) {
3086c14f61a8SHans de Goede 		rt5670->dmic1_data_pin = RT5670_DMIC_DATA_IN2P;
30878e1b1785SPierre-Louis Bossart 		dev_info(&i2c->dev, "quirk DMIC1 on IN2P pin\n");
30888e1b1785SPierre-Louis Bossart 	}
30898e1b1785SPierre-Louis Bossart 	if (rt5670_quirk & RT5670_DMIC1_GPIO6) {
3090c14f61a8SHans de Goede 		rt5670->dmic1_data_pin = RT5670_DMIC_DATA_GPIO6;
30918e1b1785SPierre-Louis Bossart 		dev_info(&i2c->dev, "quirk DMIC1 on GPIO6 pin\n");
30928e1b1785SPierre-Louis Bossart 	}
30938e1b1785SPierre-Louis Bossart 	if (rt5670_quirk & RT5670_DMIC1_GPIO7) {
3094c14f61a8SHans de Goede 		rt5670->dmic1_data_pin = RT5670_DMIC_DATA_GPIO7;
30958e1b1785SPierre-Louis Bossart 		dev_info(&i2c->dev, "quirk DMIC1 on GPIO7 pin\n");
30968e1b1785SPierre-Louis Bossart 	}
30978e1b1785SPierre-Louis Bossart 	if (rt5670_quirk & RT5670_DMIC2_INR) {
3098c14f61a8SHans de Goede 		rt5670->dmic2_data_pin = RT5670_DMIC_DATA_IN3N;
30998e1b1785SPierre-Louis Bossart 		dev_info(&i2c->dev, "quirk DMIC2 on INR pin\n");
31008e1b1785SPierre-Louis Bossart 	}
31018e1b1785SPierre-Louis Bossart 	if (rt5670_quirk & RT5670_DMIC2_GPIO8) {
3102c14f61a8SHans de Goede 		rt5670->dmic2_data_pin = RT5670_DMIC_DATA_GPIO8;
31038e1b1785SPierre-Louis Bossart 		dev_info(&i2c->dev, "quirk DMIC2 on GPIO8 pin\n");
31048e1b1785SPierre-Louis Bossart 	}
31058e1b1785SPierre-Louis Bossart 	if (rt5670_quirk & RT5670_DMIC3_GPIO5) {
3106c14f61a8SHans de Goede 		rt5670->dmic3_data_pin = RT5670_DMIC_DATA_GPIO5;
31078e1b1785SPierre-Louis Bossart 		dev_info(&i2c->dev, "quirk DMIC3 on GPIO5 pin\n");
31088e1b1785SPierre-Louis Bossart 	}
31098e1b1785SPierre-Louis Bossart 
31108e1b1785SPierre-Louis Bossart 	if (rt5670_quirk & RT5670_JD_MODE1) {
3111c14f61a8SHans de Goede 		rt5670->jd_mode = 1;
31128e1b1785SPierre-Louis Bossart 		dev_info(&i2c->dev, "quirk JD mode 1\n");
31138e1b1785SPierre-Louis Bossart 	}
31148e1b1785SPierre-Louis Bossart 	if (rt5670_quirk & RT5670_JD_MODE2) {
3115c14f61a8SHans de Goede 		rt5670->jd_mode = 2;
31168e1b1785SPierre-Louis Bossart 		dev_info(&i2c->dev, "quirk JD mode 2\n");
31178e1b1785SPierre-Louis Bossart 	}
31188e1b1785SPierre-Louis Bossart 	if (rt5670_quirk & RT5670_JD_MODE3) {
3119c14f61a8SHans de Goede 		rt5670->jd_mode = 3;
31208e1b1785SPierre-Louis Bossart 		dev_info(&i2c->dev, "quirk JD mode 3\n");
3121223c055aSBard Liao 	}
3122223c055aSBard Liao 
312342121c26SHans de Goede 	/*
312442121c26SHans de Goede 	 * Enable the emulated "DAC1 Playback Switch" by default to avoid
312542121c26SHans de Goede 	 * muting the output with older UCM profiles.
312642121c26SHans de Goede 	 */
312742121c26SHans de Goede 	rt5670->dac1_playback_switch_l = true;
312842121c26SHans de Goede 	rt5670->dac1_playback_switch_r = true;
312942121c26SHans de Goede 	/* The Power-On-Reset values for the DAC1 mixer have the DAC1 input enabled. */
313042121c26SHans de Goede 	rt5670->dac1_mixl_dac1_switch = true;
313142121c26SHans de Goede 	rt5670->dac1_mixr_dac1_switch = true;
313242121c26SHans de Goede 
31335e8351deSBard Liao 	rt5670->regmap = devm_regmap_init_i2c(i2c, &rt5670_regmap);
31345e8351deSBard Liao 	if (IS_ERR(rt5670->regmap)) {
31355e8351deSBard Liao 		ret = PTR_ERR(rt5670->regmap);
31365e8351deSBard Liao 		dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
31375e8351deSBard Liao 			ret);
31385e8351deSBard Liao 		return ret;
31395e8351deSBard Liao 	}
31405e8351deSBard Liao 
31415e8351deSBard Liao 	regmap_read(rt5670->regmap, RT5670_VENDOR_ID2, &val);
31425e8351deSBard Liao 	if (val != RT5670_DEVICE_ID) {
31435e8351deSBard Liao 		dev_err(&i2c->dev,
3144387ad57fSJarkko Nikula 			"Device with ID register %#x is not rt5670/72\n", val);
31455e8351deSBard Liao 		return -ENODEV;
31465e8351deSBard Liao 	}
31475e8351deSBard Liao 
31485e8351deSBard Liao 	regmap_write(rt5670->regmap, RT5670_RESET, 0);
31495e8351deSBard Liao 	regmap_update_bits(rt5670->regmap, RT5670_PWR_ANLG1,
31505e8351deSBard Liao 		RT5670_PWR_HP_L | RT5670_PWR_HP_R |
31515e8351deSBard Liao 		RT5670_PWR_VREF2, RT5670_PWR_VREF2);
31525e8351deSBard Liao 	msleep(100);
31535e8351deSBard Liao 
31545e8351deSBard Liao 	regmap_write(rt5670->regmap, RT5670_RESET, 0);
31555e8351deSBard Liao 
31562bf9eba1SBard Liao 	regmap_read(rt5670->regmap, RT5670_VENDOR_ID, &val);
31572bf9eba1SBard Liao 	if (val >= 4)
31582bf9eba1SBard Liao 		regmap_write(rt5670->regmap, RT5670_GPIO_CTRL3, 0x0980);
31592bf9eba1SBard Liao 	else
31602bf9eba1SBard Liao 		regmap_write(rt5670->regmap, RT5670_GPIO_CTRL3, 0x0d00);
31612bf9eba1SBard Liao 
31625e8351deSBard Liao 	ret = regmap_register_patch(rt5670->regmap, init_list,
31635e8351deSBard Liao 				    ARRAY_SIZE(init_list));
31645e8351deSBard Liao 	if (ret != 0)
31655e8351deSBard Liao 		dev_warn(&i2c->dev, "Failed to apply regmap patch: %d\n", ret);
31665e8351deSBard Liao 
3167a5d93da1SBard Liao 	regmap_update_bits(rt5670->regmap, RT5670_DIG_MISC,
3168a5d93da1SBard Liao 				 RT5670_MCLK_DET, RT5670_MCLK_DET);
3169a5d93da1SBard Liao 
3170c14f61a8SHans de Goede 	if (rt5670->in2_diff)
31715e8351deSBard Liao 		regmap_update_bits(rt5670->regmap, RT5670_IN2,
31725e8351deSBard Liao 					RT5670_IN_DF2, RT5670_IN_DF2);
31735e8351deSBard Liao 
3174883330c1SHans de Goede 	if (rt5670->gpio1_is_irq) {
3175d3ef7054SBard Liao 		/* for push button */
3176d3ef7054SBard Liao 		regmap_write(rt5670->regmap, RT5670_IL_CMD, 0x0000);
3177d3ef7054SBard Liao 		regmap_write(rt5670->regmap, RT5670_IL_CMD2, 0x0010);
3178d3ef7054SBard Liao 		regmap_write(rt5670->regmap, RT5670_IL_CMD3, 0x0014);
3179d3ef7054SBard Liao 		/* for irq */
31805e8351deSBard Liao 		regmap_update_bits(rt5670->regmap, RT5670_GPIO_CTRL1,
31815e8351deSBard Liao 				   RT5670_GP1_PIN_MASK, RT5670_GP1_PIN_IRQ);
31825e8351deSBard Liao 		regmap_update_bits(rt5670->regmap, RT5670_GPIO_CTRL2,
31835e8351deSBard Liao 				   RT5670_GP1_PF_MASK, RT5670_GP1_PF_OUT);
31845e8351deSBard Liao 	}
31855e8351deSBard Liao 
3186c14f61a8SHans de Goede 	if (rt5670->gpio1_is_ext_spk_en) {
318785ca6b17SHans de Goede 		regmap_update_bits(rt5670->regmap, RT5670_GPIO_CTRL1,
318885ca6b17SHans de Goede 				   RT5670_GP1_PIN_MASK, RT5670_GP1_PIN_GPIO1);
318985ca6b17SHans de Goede 		regmap_update_bits(rt5670->regmap, RT5670_GPIO_CTRL2,
319085ca6b17SHans de Goede 				   RT5670_GP1_PF_MASK, RT5670_GP1_PF_OUT);
319185ca6b17SHans de Goede 	}
319285ca6b17SHans de Goede 
3193c14f61a8SHans de Goede 	if (rt5670->jd_mode) {
3194026e7368SBard Liao 		regmap_update_bits(rt5670->regmap, RT5670_GLB_CLK,
3195026e7368SBard Liao 				   RT5670_SCLK_SRC_MASK, RT5670_SCLK_SRC_RCCLK);
3196026e7368SBard Liao 		rt5670->sysclk = 0;
3197026e7368SBard Liao 		rt5670->sysclk_src = RT5670_SCLK_S_RCCLK;
31985e8351deSBard Liao 		regmap_update_bits(rt5670->regmap, RT5670_PWR_ANLG1,
31995e8351deSBard Liao 				   RT5670_PWR_MB, RT5670_PWR_MB);
32005e8351deSBard Liao 		regmap_update_bits(rt5670->regmap, RT5670_PWR_ANLG2,
32015e8351deSBard Liao 				   RT5670_PWR_JD1, RT5670_PWR_JD1);
32025e8351deSBard Liao 		regmap_update_bits(rt5670->regmap, RT5670_IRQ_CTRL1,
32035e8351deSBard Liao 				   RT5670_JD1_1_EN_MASK, RT5670_JD1_1_EN);
32045e8351deSBard Liao 		regmap_update_bits(rt5670->regmap, RT5670_JD_CTRL3,
32055e8351deSBard Liao 				   RT5670_JD_TRI_CBJ_SEL_MASK |
32065e8351deSBard Liao 				   RT5670_JD_TRI_HPO_SEL_MASK,
32075e8351deSBard Liao 				   RT5670_JD_CBJ_JD1_1 | RT5670_JD_HPO_JD1_1);
3208c14f61a8SHans de Goede 		switch (rt5670->jd_mode) {
32095e8351deSBard Liao 		case 1:
32105e8351deSBard Liao 			regmap_update_bits(rt5670->regmap, RT5670_A_JD_CTRL1,
32115e8351deSBard Liao 					   RT5670_JD1_MODE_MASK,
32125e8351deSBard Liao 					   RT5670_JD1_MODE_0);
32135e8351deSBard Liao 			break;
32145e8351deSBard Liao 		case 2:
32155e8351deSBard Liao 			regmap_update_bits(rt5670->regmap, RT5670_A_JD_CTRL1,
32165e8351deSBard Liao 					   RT5670_JD1_MODE_MASK,
32175e8351deSBard Liao 					   RT5670_JD1_MODE_1);
32185e8351deSBard Liao 			break;
32195e8351deSBard Liao 		case 3:
32205e8351deSBard Liao 			regmap_update_bits(rt5670->regmap, RT5670_A_JD_CTRL1,
32215e8351deSBard Liao 					   RT5670_JD1_MODE_MASK,
32225e8351deSBard Liao 					   RT5670_JD1_MODE_2);
32235e8351deSBard Liao 			break;
32245e8351deSBard Liao 		default:
32255e8351deSBard Liao 			break;
32265e8351deSBard Liao 		}
32275e8351deSBard Liao 	}
32285e8351deSBard Liao 
3229c14f61a8SHans de Goede 	if (rt5670->dmic_en) {
32305e8351deSBard Liao 		regmap_update_bits(rt5670->regmap, RT5670_GPIO_CTRL1,
32315e8351deSBard Liao 				   RT5670_GP2_PIN_MASK,
32325e8351deSBard Liao 				   RT5670_GP2_PIN_DMIC1_SCL);
32335e8351deSBard Liao 
3234c14f61a8SHans de Goede 		switch (rt5670->dmic1_data_pin) {
32355e8351deSBard Liao 		case RT5670_DMIC_DATA_IN2P:
32365e8351deSBard Liao 			regmap_update_bits(rt5670->regmap, RT5670_DMIC_CTRL1,
32375e8351deSBard Liao 					   RT5670_DMIC_1_DP_MASK,
32385e8351deSBard Liao 					   RT5670_DMIC_1_DP_IN2P);
32395e8351deSBard Liao 			break;
32405e8351deSBard Liao 
32415e8351deSBard Liao 		case RT5670_DMIC_DATA_GPIO6:
32425e8351deSBard Liao 			regmap_update_bits(rt5670->regmap, RT5670_DMIC_CTRL1,
32435e8351deSBard Liao 					   RT5670_DMIC_1_DP_MASK,
32445e8351deSBard Liao 					   RT5670_DMIC_1_DP_GPIO6);
32455e8351deSBard Liao 			regmap_update_bits(rt5670->regmap, RT5670_GPIO_CTRL1,
32465e8351deSBard Liao 					   RT5670_GP6_PIN_MASK,
32475e8351deSBard Liao 					   RT5670_GP6_PIN_DMIC1_SDA);
32485e8351deSBard Liao 			break;
32495e8351deSBard Liao 
32505e8351deSBard Liao 		case RT5670_DMIC_DATA_GPIO7:
32515e8351deSBard Liao 			regmap_update_bits(rt5670->regmap, RT5670_DMIC_CTRL1,
32525e8351deSBard Liao 					   RT5670_DMIC_1_DP_MASK,
32535e8351deSBard Liao 					   RT5670_DMIC_1_DP_GPIO7);
32545e8351deSBard Liao 			regmap_update_bits(rt5670->regmap, RT5670_GPIO_CTRL1,
32555e8351deSBard Liao 					   RT5670_GP7_PIN_MASK,
32565e8351deSBard Liao 					   RT5670_GP7_PIN_DMIC1_SDA);
32575e8351deSBard Liao 			break;
32585e8351deSBard Liao 
32595e8351deSBard Liao 		default:
32605e8351deSBard Liao 			break;
32615e8351deSBard Liao 		}
32625e8351deSBard Liao 
3263c14f61a8SHans de Goede 		switch (rt5670->dmic2_data_pin) {
32645e8351deSBard Liao 		case RT5670_DMIC_DATA_IN3N:
32655e8351deSBard Liao 			regmap_update_bits(rt5670->regmap, RT5670_DMIC_CTRL1,
32665e8351deSBard Liao 					   RT5670_DMIC_2_DP_MASK,
32675e8351deSBard Liao 					   RT5670_DMIC_2_DP_IN3N);
32685e8351deSBard Liao 			break;
32695e8351deSBard Liao 
32705e8351deSBard Liao 		case RT5670_DMIC_DATA_GPIO8:
32715e8351deSBard Liao 			regmap_update_bits(rt5670->regmap, RT5670_DMIC_CTRL1,
32725e8351deSBard Liao 					   RT5670_DMIC_2_DP_MASK,
32735e8351deSBard Liao 					   RT5670_DMIC_2_DP_GPIO8);
32745e8351deSBard Liao 			regmap_update_bits(rt5670->regmap, RT5670_GPIO_CTRL1,
32755e8351deSBard Liao 					   RT5670_GP8_PIN_MASK,
32765e8351deSBard Liao 					   RT5670_GP8_PIN_DMIC2_SDA);
32775e8351deSBard Liao 			break;
32785e8351deSBard Liao 
32795e8351deSBard Liao 		default:
32805e8351deSBard Liao 			break;
32815e8351deSBard Liao 		}
32825e8351deSBard Liao 
3283c14f61a8SHans de Goede 		switch (rt5670->dmic3_data_pin) {
32845e8351deSBard Liao 		case RT5670_DMIC_DATA_GPIO5:
32855e8351deSBard Liao 			regmap_update_bits(rt5670->regmap, RT5670_DMIC_CTRL2,
32865e8351deSBard Liao 					   RT5670_DMIC_3_DP_MASK,
32875e8351deSBard Liao 					   RT5670_DMIC_3_DP_GPIO5);
32885e8351deSBard Liao 			regmap_update_bits(rt5670->regmap, RT5670_GPIO_CTRL1,
32895e8351deSBard Liao 					   RT5670_GP5_PIN_MASK,
32905e8351deSBard Liao 					   RT5670_GP5_PIN_DMIC3_SDA);
32915e8351deSBard Liao 			break;
32925e8351deSBard Liao 
32935e8351deSBard Liao 		case RT5670_DMIC_DATA_GPIO9:
32945e8351deSBard Liao 		case RT5670_DMIC_DATA_GPIO10:
32955e8351deSBard Liao 			dev_err(&i2c->dev,
32965e8351deSBard Liao 				"Always use GPIO5 as DMIC3 data pin\n");
32975e8351deSBard Liao 			break;
32985e8351deSBard Liao 
32995e8351deSBard Liao 		default:
33005e8351deSBard Liao 			break;
33015e8351deSBard Liao 		}
33025e8351deSBard Liao 
33035e8351deSBard Liao 	}
33045e8351deSBard Liao 
330564e89e5fSBard Liao 	pm_runtime_enable(&i2c->dev);
330664e89e5fSBard Liao 	pm_request_idle(&i2c->dev);
330764e89e5fSBard Liao 
33085ba04c66SKuninori Morimoto 	ret = devm_snd_soc_register_component(&i2c->dev,
33095ba04c66SKuninori Morimoto 			&soc_component_dev_rt5670,
33105e8351deSBard Liao 			rt5670_dai, ARRAY_SIZE(rt5670_dai));
33115e8351deSBard Liao 	if (ret < 0)
33125e8351deSBard Liao 		goto err;
33135e8351deSBard Liao 
33145e8351deSBard Liao 	return 0;
33155e8351deSBard Liao err:
331664e89e5fSBard Liao 	pm_runtime_disable(&i2c->dev);
331764e89e5fSBard Liao 
33185e8351deSBard Liao 	return ret;
33195e8351deSBard Liao }
33205e8351deSBard Liao 
rt5670_i2c_remove(struct i2c_client * i2c)3321ed5c2f5fSUwe Kleine-König static void rt5670_i2c_remove(struct i2c_client *i2c)
33225e8351deSBard Liao {
332364e89e5fSBard Liao 	pm_runtime_disable(&i2c->dev);
33245e8351deSBard Liao }
33255e8351deSBard Liao 
3326ff62b958SMark Brown static struct i2c_driver rt5670_i2c_driver = {
33275e8351deSBard Liao 	.driver = {
33285e8351deSBard Liao 		.name = "rt5670",
33290605815eSMengdong Lin 		.acpi_match_table = ACPI_PTR(rt5670_acpi_match),
33305e8351deSBard Liao 	},
33319abcd240SUwe Kleine-König 	.probe    = rt5670_i2c_probe,
33325e8351deSBard Liao 	.remove   = rt5670_i2c_remove,
33335e8351deSBard Liao 	.id_table = rt5670_i2c_id,
33345e8351deSBard Liao };
33355e8351deSBard Liao 
33365e8351deSBard Liao module_i2c_driver(rt5670_i2c_driver);
33375e8351deSBard Liao 
33385e8351deSBard Liao MODULE_DESCRIPTION("ASoC RT5670 driver");
33395e8351deSBard Liao MODULE_AUTHOR("Bard Liao <bardliao@realtek.com>");
33405e8351deSBard Liao MODULE_LICENSE("GPL v2");
3341