xref: /linux/sound/soc/codecs/da732x.c (revision 48e278746070b5fc62ec3da2e65f7cd511f6bbf4)
1*48e27874SAdam Thomson /*
2*48e27874SAdam Thomson  * da732x.c --- Dialog DA732X ALSA SoC Audio Driver
3*48e27874SAdam Thomson  *
4*48e27874SAdam Thomson  * Copyright (C) 2012 Dialog Semiconductor GmbH
5*48e27874SAdam Thomson  *
6*48e27874SAdam Thomson  * Author: Michal Hajduk <Michal.Hajduk@diasemi.com>
7*48e27874SAdam Thomson  *
8*48e27874SAdam Thomson  * This program is free software; you can redistribute it and/or modify
9*48e27874SAdam Thomson  * it under the terms of the GNU General Public License version 2 as
10*48e27874SAdam Thomson  * published by the Free Software Foundation.
11*48e27874SAdam Thomson  */
12*48e27874SAdam Thomson 
13*48e27874SAdam Thomson #include <linux/module.h>
14*48e27874SAdam Thomson #include <linux/moduleparam.h>
15*48e27874SAdam Thomson #include <linux/init.h>
16*48e27874SAdam Thomson #include <linux/delay.h>
17*48e27874SAdam Thomson #include <linux/pm.h>
18*48e27874SAdam Thomson #include <linux/i2c.h>
19*48e27874SAdam Thomson #include <linux/regmap.h>
20*48e27874SAdam Thomson #include <linux/platform_device.h>
21*48e27874SAdam Thomson #include <linux/slab.h>
22*48e27874SAdam Thomson #include <linux/sysfs.h>
23*48e27874SAdam Thomson #include <sound/core.h>
24*48e27874SAdam Thomson #include <sound/pcm.h>
25*48e27874SAdam Thomson #include <sound/pcm_params.h>
26*48e27874SAdam Thomson #include <sound/soc.h>
27*48e27874SAdam Thomson #include <sound/soc-dapm.h>
28*48e27874SAdam Thomson #include <sound/initval.h>
29*48e27874SAdam Thomson #include <sound/tlv.h>
30*48e27874SAdam Thomson #include <asm/div64.h>
31*48e27874SAdam Thomson 
32*48e27874SAdam Thomson #include "da732x.h"
33*48e27874SAdam Thomson #include "da732x_reg.h"
34*48e27874SAdam Thomson 
35*48e27874SAdam Thomson 
36*48e27874SAdam Thomson struct da732x_priv {
37*48e27874SAdam Thomson 	struct regmap *regmap;
38*48e27874SAdam Thomson 	struct snd_soc_codec *codec;
39*48e27874SAdam Thomson 
40*48e27874SAdam Thomson 	unsigned int sysclk;
41*48e27874SAdam Thomson 	bool pll_en;
42*48e27874SAdam Thomson };
43*48e27874SAdam Thomson 
44*48e27874SAdam Thomson /*
45*48e27874SAdam Thomson  * da732x register cache - default settings
46*48e27874SAdam Thomson  */
47*48e27874SAdam Thomson static struct reg_default da732x_reg_cache[] = {
48*48e27874SAdam Thomson 	{ DA732X_REG_REF1		, 0x02 },
49*48e27874SAdam Thomson 	{ DA732X_REG_BIAS_EN		, 0x80 },
50*48e27874SAdam Thomson 	{ DA732X_REG_BIAS1		, 0x00 },
51*48e27874SAdam Thomson 	{ DA732X_REG_BIAS2		, 0x00 },
52*48e27874SAdam Thomson 	{ DA732X_REG_BIAS3		, 0x00 },
53*48e27874SAdam Thomson 	{ DA732X_REG_BIAS4		, 0x00 },
54*48e27874SAdam Thomson 	{ DA732X_REG_MICBIAS2		, 0x00 },
55*48e27874SAdam Thomson 	{ DA732X_REG_MICBIAS1		, 0x00 },
56*48e27874SAdam Thomson 	{ DA732X_REG_MICDET		, 0x00 },
57*48e27874SAdam Thomson 	{ DA732X_REG_MIC1_PRE		, 0x01 },
58*48e27874SAdam Thomson 	{ DA732X_REG_MIC1		, 0x40 },
59*48e27874SAdam Thomson 	{ DA732X_REG_MIC2_PRE		, 0x01 },
60*48e27874SAdam Thomson 	{ DA732X_REG_MIC2		, 0x40 },
61*48e27874SAdam Thomson 	{ DA732X_REG_AUX1L		, 0x75 },
62*48e27874SAdam Thomson 	{ DA732X_REG_AUX1R		, 0x75 },
63*48e27874SAdam Thomson 	{ DA732X_REG_MIC3_PRE		, 0x01 },
64*48e27874SAdam Thomson 	{ DA732X_REG_MIC3		, 0x40 },
65*48e27874SAdam Thomson 	{ DA732X_REG_INP_PINBIAS	, 0x00 },
66*48e27874SAdam Thomson 	{ DA732X_REG_INP_ZC_EN		, 0x00 },
67*48e27874SAdam Thomson 	{ DA732X_REG_INP_MUX		, 0x50 },
68*48e27874SAdam Thomson 	{ DA732X_REG_HP_DET		, 0x00 },
69*48e27874SAdam Thomson 	{ DA732X_REG_HPL_DAC_OFFSET	, 0x00 },
70*48e27874SAdam Thomson 	{ DA732X_REG_HPL_DAC_OFF_CNTL	, 0x00 },
71*48e27874SAdam Thomson 	{ DA732X_REG_HPL_OUT_OFFSET	, 0x00 },
72*48e27874SAdam Thomson 	{ DA732X_REG_HPL		, 0x40 },
73*48e27874SAdam Thomson 	{ DA732X_REG_HPL_VOL		, 0x0F },
74*48e27874SAdam Thomson 	{ DA732X_REG_HPR_DAC_OFFSET	, 0x00 },
75*48e27874SAdam Thomson 	{ DA732X_REG_HPR_DAC_OFF_CNTL	, 0x00 },
76*48e27874SAdam Thomson 	{ DA732X_REG_HPR_OUT_OFFSET	, 0x00 },
77*48e27874SAdam Thomson 	{ DA732X_REG_HPR		, 0x40 },
78*48e27874SAdam Thomson 	{ DA732X_REG_HPR_VOL		, 0x0F },
79*48e27874SAdam Thomson 	{ DA732X_REG_LIN2		, 0x4F },
80*48e27874SAdam Thomson 	{ DA732X_REG_LIN3		, 0x4F },
81*48e27874SAdam Thomson 	{ DA732X_REG_LIN4		, 0x4F },
82*48e27874SAdam Thomson 	{ DA732X_REG_OUT_ZC_EN		, 0x00 },
83*48e27874SAdam Thomson 	{ DA732X_REG_HP_LIN1_GNDSEL	, 0x00 },
84*48e27874SAdam Thomson 	{ DA732X_REG_CP_HP1		, 0x0C },
85*48e27874SAdam Thomson 	{ DA732X_REG_CP_HP2		, 0x03 },
86*48e27874SAdam Thomson 	{ DA732X_REG_CP_CTRL1		, 0x00 },
87*48e27874SAdam Thomson 	{ DA732X_REG_CP_CTRL2		, 0x99 },
88*48e27874SAdam Thomson 	{ DA732X_REG_CP_CTRL3		, 0x25 },
89*48e27874SAdam Thomson 	{ DA732X_REG_CP_LEVEL_MASK	, 0x3F },
90*48e27874SAdam Thomson 	{ DA732X_REG_CP_DET		, 0x00 },
91*48e27874SAdam Thomson 	{ DA732X_REG_CP_STATUS		, 0x00 },
92*48e27874SAdam Thomson 	{ DA732X_REG_CP_THRESH1		, 0x00 },
93*48e27874SAdam Thomson 	{ DA732X_REG_CP_THRESH2		, 0x00 },
94*48e27874SAdam Thomson 	{ DA732X_REG_CP_THRESH3		, 0x00 },
95*48e27874SAdam Thomson 	{ DA732X_REG_CP_THRESH4		, 0x00 },
96*48e27874SAdam Thomson 	{ DA732X_REG_CP_THRESH5		, 0x00 },
97*48e27874SAdam Thomson 	{ DA732X_REG_CP_THRESH6		, 0x00 },
98*48e27874SAdam Thomson 	{ DA732X_REG_CP_THRESH7		, 0x00 },
99*48e27874SAdam Thomson 	{ DA732X_REG_CP_THRESH8		, 0x00 },
100*48e27874SAdam Thomson 	{ DA732X_REG_PLL_DIV_LO		, 0x00 },
101*48e27874SAdam Thomson 	{ DA732X_REG_PLL_DIV_MID	, 0x00 },
102*48e27874SAdam Thomson 	{ DA732X_REG_PLL_DIV_HI		, 0x00 },
103*48e27874SAdam Thomson 	{ DA732X_REG_PLL_CTRL		, 0x02 },
104*48e27874SAdam Thomson 	{ DA732X_REG_CLK_CTRL		, 0xaa },
105*48e27874SAdam Thomson 	{ DA732X_REG_CLK_DSP		, 0x07 },
106*48e27874SAdam Thomson 	{ DA732X_REG_CLK_EN1		, 0x00 },
107*48e27874SAdam Thomson 	{ DA732X_REG_CLK_EN2		, 0x00 },
108*48e27874SAdam Thomson 	{ DA732X_REG_CLK_EN3		, 0x00 },
109*48e27874SAdam Thomson 	{ DA732X_REG_CLK_EN4		, 0x00 },
110*48e27874SAdam Thomson 	{ DA732X_REG_CLK_EN5		, 0x00 },
111*48e27874SAdam Thomson 	{ DA732X_REG_AIF_MCLK		, 0x00 },
112*48e27874SAdam Thomson 	{ DA732X_REG_AIFA1		, 0x02 },
113*48e27874SAdam Thomson 	{ DA732X_REG_AIFA2		, 0x00 },
114*48e27874SAdam Thomson 	{ DA732X_REG_AIFA3		, 0x08 },
115*48e27874SAdam Thomson 	{ DA732X_REG_AIFB1		, 0x02 },
116*48e27874SAdam Thomson 	{ DA732X_REG_AIFB2		, 0x00 },
117*48e27874SAdam Thomson 	{ DA732X_REG_AIFB3		, 0x08 },
118*48e27874SAdam Thomson 	{ DA732X_REG_PC_CTRL		, 0xC0 },
119*48e27874SAdam Thomson 	{ DA732X_REG_DATA_ROUTE		, 0x00 },
120*48e27874SAdam Thomson 	{ DA732X_REG_DSP_CTRL		, 0x00 },
121*48e27874SAdam Thomson 	{ DA732X_REG_CIF_CTRL2		, 0x00 },
122*48e27874SAdam Thomson 	{ DA732X_REG_HANDSHAKE		, 0x00 },
123*48e27874SAdam Thomson 	{ DA732X_REG_SPARE1_OUT		, 0x00 },
124*48e27874SAdam Thomson 	{ DA732X_REG_SPARE2_OUT		, 0x00 },
125*48e27874SAdam Thomson 	{ DA732X_REG_SPARE1_IN		, 0x00 },
126*48e27874SAdam Thomson 	{ DA732X_REG_ADC1_PD		, 0x00 },
127*48e27874SAdam Thomson 	{ DA732X_REG_ADC1_HPF		, 0x00 },
128*48e27874SAdam Thomson 	{ DA732X_REG_ADC1_SEL		, 0x00 },
129*48e27874SAdam Thomson 	{ DA732X_REG_ADC1_EQ12		, 0x00 },
130*48e27874SAdam Thomson 	{ DA732X_REG_ADC1_EQ34		, 0x00 },
131*48e27874SAdam Thomson 	{ DA732X_REG_ADC1_EQ5		, 0x00 },
132*48e27874SAdam Thomson 	{ DA732X_REG_ADC2_PD		, 0x00 },
133*48e27874SAdam Thomson 	{ DA732X_REG_ADC2_HPF		, 0x00 },
134*48e27874SAdam Thomson 	{ DA732X_REG_ADC2_SEL		, 0x00 },
135*48e27874SAdam Thomson 	{ DA732X_REG_ADC2_EQ12		, 0x00 },
136*48e27874SAdam Thomson 	{ DA732X_REG_ADC2_EQ34		, 0x00 },
137*48e27874SAdam Thomson 	{ DA732X_REG_ADC2_EQ5		, 0x00 },
138*48e27874SAdam Thomson 	{ DA732X_REG_DAC1_HPF		, 0x00 },
139*48e27874SAdam Thomson 	{ DA732X_REG_DAC1_L_VOL		, 0x00 },
140*48e27874SAdam Thomson 	{ DA732X_REG_DAC1_R_VOL		, 0x00 },
141*48e27874SAdam Thomson 	{ DA732X_REG_DAC1_SEL		, 0x00 },
142*48e27874SAdam Thomson 	{ DA732X_REG_DAC1_SOFTMUTE	, 0x00 },
143*48e27874SAdam Thomson 	{ DA732X_REG_DAC1_EQ12		, 0x00 },
144*48e27874SAdam Thomson 	{ DA732X_REG_DAC1_EQ34		, 0x00 },
145*48e27874SAdam Thomson 	{ DA732X_REG_DAC1_EQ5		, 0x00 },
146*48e27874SAdam Thomson 	{ DA732X_REG_DAC2_HPF		, 0x00 },
147*48e27874SAdam Thomson 	{ DA732X_REG_DAC2_L_VOL		, 0x00 },
148*48e27874SAdam Thomson 	{ DA732X_REG_DAC2_R_VOL		, 0x00 },
149*48e27874SAdam Thomson 	{ DA732X_REG_DAC2_SEL		, 0x00 },
150*48e27874SAdam Thomson 	{ DA732X_REG_DAC2_SOFTMUTE	, 0x00 },
151*48e27874SAdam Thomson 	{ DA732X_REG_DAC2_EQ12		, 0x00 },
152*48e27874SAdam Thomson 	{ DA732X_REG_DAC2_EQ34		, 0x00 },
153*48e27874SAdam Thomson 	{ DA732X_REG_DAC2_EQ5		, 0x00 },
154*48e27874SAdam Thomson 	{ DA732X_REG_DAC3_HPF		, 0x00 },
155*48e27874SAdam Thomson 	{ DA732X_REG_DAC3_VOL		, 0x00 },
156*48e27874SAdam Thomson 	{ DA732X_REG_DAC3_SEL		, 0x00 },
157*48e27874SAdam Thomson 	{ DA732X_REG_DAC3_SOFTMUTE	, 0x00 },
158*48e27874SAdam Thomson 	{ DA732X_REG_DAC3_EQ12		, 0x00 },
159*48e27874SAdam Thomson 	{ DA732X_REG_DAC3_EQ34		, 0x00 },
160*48e27874SAdam Thomson 	{ DA732X_REG_DAC3_EQ5		, 0x00 },
161*48e27874SAdam Thomson 	{ DA732X_REG_BIQ_BYP		, 0x00 },
162*48e27874SAdam Thomson 	{ DA732X_REG_DMA_CMD		, 0x00 },
163*48e27874SAdam Thomson 	{ DA732X_REG_DMA_ADDR0		, 0x00 },
164*48e27874SAdam Thomson 	{ DA732X_REG_DMA_ADDR1		, 0x00 },
165*48e27874SAdam Thomson 	{ DA732X_REG_DMA_DATA0		, 0x00 },
166*48e27874SAdam Thomson 	{ DA732X_REG_DMA_DATA1		, 0x00 },
167*48e27874SAdam Thomson 	{ DA732X_REG_DMA_DATA2		, 0x00 },
168*48e27874SAdam Thomson 	{ DA732X_REG_DMA_DATA3		, 0x00 },
169*48e27874SAdam Thomson 	{ DA732X_REG_UNLOCK		, 0x00 },
170*48e27874SAdam Thomson };
171*48e27874SAdam Thomson 
172*48e27874SAdam Thomson static inline int da732x_get_input_div(struct snd_soc_codec *codec, int sysclk)
173*48e27874SAdam Thomson {
174*48e27874SAdam Thomson 	int val;
175*48e27874SAdam Thomson 	int ret;
176*48e27874SAdam Thomson 
177*48e27874SAdam Thomson 	if (sysclk < DA732X_MCLK_10MHZ) {
178*48e27874SAdam Thomson 		val = DA732X_MCLK_RET_0_10MHZ;
179*48e27874SAdam Thomson 		ret = DA732X_MCLK_VAL_0_10MHZ;
180*48e27874SAdam Thomson 	} else if ((sysclk >= DA732X_MCLK_10MHZ) &&
181*48e27874SAdam Thomson 	    (sysclk < DA732X_MCLK_20MHZ)) {
182*48e27874SAdam Thomson 		val = DA732X_MCLK_RET_10_20MHZ;
183*48e27874SAdam Thomson 		ret = DA732X_MCLK_VAL_10_20MHZ;
184*48e27874SAdam Thomson 	} else if ((sysclk >= DA732X_MCLK_20MHZ) &&
185*48e27874SAdam Thomson 	    (sysclk < DA732X_MCLK_40MHZ)) {
186*48e27874SAdam Thomson 		val = DA732X_MCLK_RET_20_40MHZ;
187*48e27874SAdam Thomson 		ret = DA732X_MCLK_VAL_20_40MHZ;
188*48e27874SAdam Thomson 	} else if ((sysclk >= DA732X_MCLK_40MHZ) &&
189*48e27874SAdam Thomson 	    (sysclk <= DA732X_MCLK_54MHZ)) {
190*48e27874SAdam Thomson 		val = DA732X_MCLK_RET_40_54MHZ;
191*48e27874SAdam Thomson 		ret = DA732X_MCLK_VAL_40_54MHZ;
192*48e27874SAdam Thomson 	} else {
193*48e27874SAdam Thomson 		return -EINVAL;
194*48e27874SAdam Thomson 	}
195*48e27874SAdam Thomson 
196*48e27874SAdam Thomson 	snd_soc_write(codec, DA732X_REG_PLL_CTRL, val);
197*48e27874SAdam Thomson 
198*48e27874SAdam Thomson 	return ret;
199*48e27874SAdam Thomson }
200*48e27874SAdam Thomson 
201*48e27874SAdam Thomson static void da732x_set_charge_pump(struct snd_soc_codec *codec, int state)
202*48e27874SAdam Thomson {
203*48e27874SAdam Thomson 	switch (state) {
204*48e27874SAdam Thomson 	case DA732X_ENABLE_CP:
205*48e27874SAdam Thomson 		snd_soc_write(codec, DA732X_REG_CLK_EN2, DA732X_CP_CLK_EN);
206*48e27874SAdam Thomson 		snd_soc_write(codec, DA732X_REG_CP_HP2, DA732X_HP_CP_EN |
207*48e27874SAdam Thomson 			      DA732X_HP_CP_REG | DA732X_HP_CP_PULSESKIP);
208*48e27874SAdam Thomson 		snd_soc_write(codec, DA732X_REG_CP_CTRL1, DA732X_CP_EN |
209*48e27874SAdam Thomson 			      DA732X_CP_CTRL_CPVDD1);
210*48e27874SAdam Thomson 		snd_soc_write(codec, DA732X_REG_CP_CTRL2,
211*48e27874SAdam Thomson 			      DA732X_CP_MANAGE_MAGNITUDE | DA732X_CP_BOOST);
212*48e27874SAdam Thomson 		snd_soc_write(codec, DA732X_REG_CP_CTRL3, DA732X_CP_1MHZ);
213*48e27874SAdam Thomson 		break;
214*48e27874SAdam Thomson 	case DA732X_DISABLE_CP:
215*48e27874SAdam Thomson 		snd_soc_write(codec, DA732X_REG_CLK_EN2, DA732X_CP_CLK_DIS);
216*48e27874SAdam Thomson 		snd_soc_write(codec, DA732X_REG_CP_HP2, DA732X_HP_CP_DIS);
217*48e27874SAdam Thomson 		snd_soc_write(codec, DA732X_REG_CP_CTRL1, DA723X_CP_DIS);
218*48e27874SAdam Thomson 		break;
219*48e27874SAdam Thomson 	default:
220*48e27874SAdam Thomson 		pr_err(KERN_ERR "Wrong charge pump state\n");
221*48e27874SAdam Thomson 		break;
222*48e27874SAdam Thomson 	}
223*48e27874SAdam Thomson }
224*48e27874SAdam Thomson 
225*48e27874SAdam Thomson static const DECLARE_TLV_DB_SCALE(mic_boost_tlv, DA732X_MIC_PRE_VOL_DB_MIN,
226*48e27874SAdam Thomson 				  DA732X_MIC_PRE_VOL_DB_INC, 0);
227*48e27874SAdam Thomson 
228*48e27874SAdam Thomson static const DECLARE_TLV_DB_SCALE(mic_pga_tlv, DA732X_MIC_VOL_DB_MIN,
229*48e27874SAdam Thomson 				  DA732X_MIC_VOL_DB_INC, 0);
230*48e27874SAdam Thomson 
231*48e27874SAdam Thomson static const DECLARE_TLV_DB_SCALE(aux_pga_tlv, DA732X_AUX_VOL_DB_MIN,
232*48e27874SAdam Thomson 				  DA732X_AUX_VOL_DB_INC, 0);
233*48e27874SAdam Thomson 
234*48e27874SAdam Thomson static const DECLARE_TLV_DB_SCALE(hp_pga_tlv, DA732X_HP_VOL_DB_MIN,
235*48e27874SAdam Thomson 				  DA732X_AUX_VOL_DB_INC, 0);
236*48e27874SAdam Thomson 
237*48e27874SAdam Thomson static const DECLARE_TLV_DB_SCALE(lin2_pga_tlv, DA732X_LIN2_VOL_DB_MIN,
238*48e27874SAdam Thomson 				  DA732X_LIN2_VOL_DB_INC, 0);
239*48e27874SAdam Thomson 
240*48e27874SAdam Thomson static const DECLARE_TLV_DB_SCALE(lin3_pga_tlv, DA732X_LIN3_VOL_DB_MIN,
241*48e27874SAdam Thomson 				  DA732X_LIN3_VOL_DB_INC, 0);
242*48e27874SAdam Thomson 
243*48e27874SAdam Thomson static const DECLARE_TLV_DB_SCALE(lin4_pga_tlv, DA732X_LIN4_VOL_DB_MIN,
244*48e27874SAdam Thomson 				  DA732X_LIN4_VOL_DB_INC, 0);
245*48e27874SAdam Thomson 
246*48e27874SAdam Thomson static const DECLARE_TLV_DB_SCALE(adc_pga_tlv, DA732X_ADC_VOL_DB_MIN,
247*48e27874SAdam Thomson 				  DA732X_ADC_VOL_DB_INC, 0);
248*48e27874SAdam Thomson 
249*48e27874SAdam Thomson static const DECLARE_TLV_DB_SCALE(dac_pga_tlv, DA732X_DAC_VOL_DB_MIN,
250*48e27874SAdam Thomson 				  DA732X_DAC_VOL_DB_INC, 0);
251*48e27874SAdam Thomson 
252*48e27874SAdam Thomson static const DECLARE_TLV_DB_SCALE(eq_band_pga_tlv, DA732X_EQ_BAND_VOL_DB_MIN,
253*48e27874SAdam Thomson 				  DA732X_EQ_BAND_VOL_DB_INC, 0);
254*48e27874SAdam Thomson 
255*48e27874SAdam Thomson static const DECLARE_TLV_DB_SCALE(eq_overall_tlv, DA732X_EQ_OVERALL_VOL_DB_MIN,
256*48e27874SAdam Thomson 				  DA732X_EQ_OVERALL_VOL_DB_INC, 0);
257*48e27874SAdam Thomson 
258*48e27874SAdam Thomson /* High Pass Filter */
259*48e27874SAdam Thomson static const char *da732x_hpf_mode[] = {
260*48e27874SAdam Thomson 	"Disable", "Music", "Voice",
261*48e27874SAdam Thomson };
262*48e27874SAdam Thomson 
263*48e27874SAdam Thomson static const char *da732x_hpf_music[] = {
264*48e27874SAdam Thomson 	"1.8Hz", "3.75Hz", "7.5Hz", "15Hz",
265*48e27874SAdam Thomson };
266*48e27874SAdam Thomson 
267*48e27874SAdam Thomson static const char *da732x_hpf_voice[] = {
268*48e27874SAdam Thomson 	"2.5Hz", "25Hz", "50Hz", "100Hz",
269*48e27874SAdam Thomson 	"150Hz", "200Hz", "300Hz", "400Hz"
270*48e27874SAdam Thomson };
271*48e27874SAdam Thomson 
272*48e27874SAdam Thomson static const struct soc_enum da732x_dac1_hpf_mode_enum[] = {
273*48e27874SAdam Thomson 	SOC_ENUM_SINGLE(DA732X_REG_DAC1_HPF, DA732X_HPF_MODE_SHIFT,
274*48e27874SAdam Thomson 			DA732X_HPF_MODE_MAX, da732x_hpf_mode)
275*48e27874SAdam Thomson };
276*48e27874SAdam Thomson 
277*48e27874SAdam Thomson static const struct soc_enum da732x_dac2_hpf_mode_enum[] = {
278*48e27874SAdam Thomson 	SOC_ENUM_SINGLE(DA732X_REG_DAC2_HPF, DA732X_HPF_MODE_SHIFT,
279*48e27874SAdam Thomson 			DA732X_HPF_MODE_MAX, da732x_hpf_mode)
280*48e27874SAdam Thomson };
281*48e27874SAdam Thomson 
282*48e27874SAdam Thomson static const struct soc_enum da732x_dac3_hpf_mode_enum[] = {
283*48e27874SAdam Thomson 	SOC_ENUM_SINGLE(DA732X_REG_DAC3_HPF, DA732X_HPF_MODE_SHIFT,
284*48e27874SAdam Thomson 			DA732X_HPF_MODE_MAX, da732x_hpf_mode)
285*48e27874SAdam Thomson };
286*48e27874SAdam Thomson 
287*48e27874SAdam Thomson static const struct soc_enum da732x_adc1_hpf_mode_enum[] = {
288*48e27874SAdam Thomson 	SOC_ENUM_SINGLE(DA732X_REG_ADC1_HPF, DA732X_HPF_MODE_SHIFT,
289*48e27874SAdam Thomson 			DA732X_HPF_MODE_MAX, da732x_hpf_mode)
290*48e27874SAdam Thomson };
291*48e27874SAdam Thomson 
292*48e27874SAdam Thomson static const struct soc_enum da732x_adc2_hpf_mode_enum[] = {
293*48e27874SAdam Thomson 	SOC_ENUM_SINGLE(DA732X_REG_ADC2_HPF, DA732X_HPF_MODE_SHIFT,
294*48e27874SAdam Thomson 			DA732X_HPF_MODE_MAX, da732x_hpf_mode)
295*48e27874SAdam Thomson };
296*48e27874SAdam Thomson 
297*48e27874SAdam Thomson static const struct soc_enum da732x_dac1_hp_filter_enum[] = {
298*48e27874SAdam Thomson 	SOC_ENUM_SINGLE(DA732X_REG_DAC1_HPF, DA732X_HPF_MUSIC_SHIFT,
299*48e27874SAdam Thomson 			DA732X_HPF_MUSIC_MAX, da732x_hpf_music)
300*48e27874SAdam Thomson };
301*48e27874SAdam Thomson 
302*48e27874SAdam Thomson static const struct soc_enum da732x_dac2_hp_filter_enum[] = {
303*48e27874SAdam Thomson 	SOC_ENUM_SINGLE(DA732X_REG_DAC2_HPF, DA732X_HPF_MUSIC_SHIFT,
304*48e27874SAdam Thomson 			DA732X_HPF_MUSIC_MAX, da732x_hpf_music)
305*48e27874SAdam Thomson };
306*48e27874SAdam Thomson 
307*48e27874SAdam Thomson static const struct soc_enum da732x_dac3_hp_filter_enum[] = {
308*48e27874SAdam Thomson 	SOC_ENUM_SINGLE(DA732X_REG_DAC3_HPF, DA732X_HPF_MUSIC_SHIFT,
309*48e27874SAdam Thomson 			DA732X_HPF_MUSIC_MAX, da732x_hpf_music)
310*48e27874SAdam Thomson };
311*48e27874SAdam Thomson 
312*48e27874SAdam Thomson static const struct soc_enum da732x_adc1_hp_filter_enum[] = {
313*48e27874SAdam Thomson 	SOC_ENUM_SINGLE(DA732X_REG_ADC1_HPF, DA732X_HPF_MUSIC_SHIFT,
314*48e27874SAdam Thomson 			DA732X_HPF_MUSIC_MAX, da732x_hpf_music)
315*48e27874SAdam Thomson };
316*48e27874SAdam Thomson 
317*48e27874SAdam Thomson static const struct soc_enum da732x_adc2_hp_filter_enum[] = {
318*48e27874SAdam Thomson 	SOC_ENUM_SINGLE(DA732X_REG_ADC2_HPF, DA732X_HPF_MUSIC_SHIFT,
319*48e27874SAdam Thomson 			DA732X_HPF_MUSIC_MAX, da732x_hpf_music)
320*48e27874SAdam Thomson };
321*48e27874SAdam Thomson 
322*48e27874SAdam Thomson static const struct soc_enum da732x_dac1_voice_filter_enum[] = {
323*48e27874SAdam Thomson 	SOC_ENUM_SINGLE(DA732X_REG_DAC1_HPF, DA732X_HPF_VOICE_SHIFT,
324*48e27874SAdam Thomson 			DA732X_HPF_VOICE_MAX, da732x_hpf_voice)
325*48e27874SAdam Thomson };
326*48e27874SAdam Thomson 
327*48e27874SAdam Thomson static const struct soc_enum da732x_dac2_voice_filter_enum[] = {
328*48e27874SAdam Thomson 	SOC_ENUM_SINGLE(DA732X_REG_DAC2_HPF, DA732X_HPF_VOICE_SHIFT,
329*48e27874SAdam Thomson 			DA732X_HPF_VOICE_MAX, da732x_hpf_voice)
330*48e27874SAdam Thomson };
331*48e27874SAdam Thomson 
332*48e27874SAdam Thomson static const struct soc_enum da732x_dac3_voice_filter_enum[] = {
333*48e27874SAdam Thomson 	SOC_ENUM_SINGLE(DA732X_REG_DAC3_HPF, DA732X_HPF_VOICE_SHIFT,
334*48e27874SAdam Thomson 			DA732X_HPF_VOICE_MAX, da732x_hpf_voice)
335*48e27874SAdam Thomson };
336*48e27874SAdam Thomson 
337*48e27874SAdam Thomson static const struct soc_enum da732x_adc1_voice_filter_enum[] = {
338*48e27874SAdam Thomson 	SOC_ENUM_SINGLE(DA732X_REG_ADC1_HPF, DA732X_HPF_VOICE_SHIFT,
339*48e27874SAdam Thomson 			DA732X_HPF_VOICE_MAX, da732x_hpf_voice)
340*48e27874SAdam Thomson };
341*48e27874SAdam Thomson 
342*48e27874SAdam Thomson static const struct soc_enum da732x_adc2_voice_filter_enum[] = {
343*48e27874SAdam Thomson 	SOC_ENUM_SINGLE(DA732X_REG_ADC2_HPF, DA732X_HPF_VOICE_SHIFT,
344*48e27874SAdam Thomson 			DA732X_HPF_VOICE_MAX, da732x_hpf_voice)
345*48e27874SAdam Thomson };
346*48e27874SAdam Thomson 
347*48e27874SAdam Thomson 
348*48e27874SAdam Thomson static int da732x_hpf_set(struct snd_kcontrol *kcontrol,
349*48e27874SAdam Thomson 			  struct snd_ctl_elem_value *ucontrol)
350*48e27874SAdam Thomson {
351*48e27874SAdam Thomson 	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
352*48e27874SAdam Thomson 	struct soc_enum *enum_ctrl = (struct soc_enum *)kcontrol->private_value;
353*48e27874SAdam Thomson 	unsigned int reg = enum_ctrl->reg;
354*48e27874SAdam Thomson 	unsigned int sel = ucontrol->value.integer.value[0];
355*48e27874SAdam Thomson 	unsigned int bits;
356*48e27874SAdam Thomson 
357*48e27874SAdam Thomson 	switch (sel) {
358*48e27874SAdam Thomson 	case DA732X_HPF_DISABLED:
359*48e27874SAdam Thomson 		bits = DA732X_HPF_DIS;
360*48e27874SAdam Thomson 		break;
361*48e27874SAdam Thomson 	case DA732X_HPF_VOICE:
362*48e27874SAdam Thomson 		bits = DA732X_HPF_VOICE_EN;
363*48e27874SAdam Thomson 		break;
364*48e27874SAdam Thomson 	case DA732X_HPF_MUSIC:
365*48e27874SAdam Thomson 		bits = DA732X_HPF_MUSIC_EN;
366*48e27874SAdam Thomson 		break;
367*48e27874SAdam Thomson 	default:
368*48e27874SAdam Thomson 		return -EINVAL;
369*48e27874SAdam Thomson 	}
370*48e27874SAdam Thomson 
371*48e27874SAdam Thomson 	snd_soc_update_bits(codec, reg, DA732X_HPF_MASK, bits);
372*48e27874SAdam Thomson 
373*48e27874SAdam Thomson 	return 0;
374*48e27874SAdam Thomson }
375*48e27874SAdam Thomson 
376*48e27874SAdam Thomson static int da732x_hpf_get(struct snd_kcontrol *kcontrol,
377*48e27874SAdam Thomson 			  struct snd_ctl_elem_value *ucontrol)
378*48e27874SAdam Thomson {
379*48e27874SAdam Thomson 	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
380*48e27874SAdam Thomson 	struct soc_enum *enum_ctrl = (struct soc_enum *)kcontrol->private_value;
381*48e27874SAdam Thomson 	unsigned int reg = enum_ctrl->reg;
382*48e27874SAdam Thomson 	int val;
383*48e27874SAdam Thomson 
384*48e27874SAdam Thomson 	val = snd_soc_read(codec, reg) & DA732X_HPF_MASK;
385*48e27874SAdam Thomson 
386*48e27874SAdam Thomson 	switch (val) {
387*48e27874SAdam Thomson 	case DA732X_HPF_VOICE_EN:
388*48e27874SAdam Thomson 		ucontrol->value.integer.value[0] = DA732X_HPF_VOICE;
389*48e27874SAdam Thomson 		break;
390*48e27874SAdam Thomson 	case DA732X_HPF_MUSIC_EN:
391*48e27874SAdam Thomson 		ucontrol->value.integer.value[0] = DA732X_HPF_MUSIC;
392*48e27874SAdam Thomson 		break;
393*48e27874SAdam Thomson 	default:
394*48e27874SAdam Thomson 		ucontrol->value.integer.value[0] = DA732X_HPF_DISABLED;
395*48e27874SAdam Thomson 		break;
396*48e27874SAdam Thomson 	}
397*48e27874SAdam Thomson 
398*48e27874SAdam Thomson 	return 0;
399*48e27874SAdam Thomson }
400*48e27874SAdam Thomson 
401*48e27874SAdam Thomson static const struct snd_kcontrol_new da732x_snd_controls[] = {
402*48e27874SAdam Thomson 	/* Input PGAs */
403*48e27874SAdam Thomson 	SOC_SINGLE_RANGE_TLV("MIC1 Boost Volume", DA732X_REG_MIC1_PRE,
404*48e27874SAdam Thomson 			     DA732X_MICBOOST_SHIFT, DA732X_MICBOOST_MIN,
405*48e27874SAdam Thomson 			     DA732X_MICBOOST_MAX, 0, mic_boost_tlv),
406*48e27874SAdam Thomson 	SOC_SINGLE_RANGE_TLV("MIC2 Boost Volume", DA732X_REG_MIC2_PRE,
407*48e27874SAdam Thomson 			     DA732X_MICBOOST_SHIFT, DA732X_MICBOOST_MIN,
408*48e27874SAdam Thomson 			     DA732X_MICBOOST_MAX, 0, mic_boost_tlv),
409*48e27874SAdam Thomson 	SOC_SINGLE_RANGE_TLV("MIC3 Boost Volume", DA732X_REG_MIC3_PRE,
410*48e27874SAdam Thomson 			     DA732X_MICBOOST_SHIFT, DA732X_MICBOOST_MIN,
411*48e27874SAdam Thomson 			     DA732X_MICBOOST_MAX, 0, mic_boost_tlv),
412*48e27874SAdam Thomson 
413*48e27874SAdam Thomson 	/* MICs */
414*48e27874SAdam Thomson 	SOC_SINGLE("MIC1 Switch", DA732X_REG_MIC1, DA732X_MIC_MUTE_SHIFT,
415*48e27874SAdam Thomson 		   DA732X_SWITCH_MAX, DA732X_INVERT),
416*48e27874SAdam Thomson 	SOC_SINGLE_RANGE_TLV("MIC1 Volume", DA732X_REG_MIC1,
417*48e27874SAdam Thomson 			     DA732X_MIC_VOL_SHIFT, DA732X_MIC_VOL_VAL_MIN,
418*48e27874SAdam Thomson 			     DA732X_MIC_VOL_VAL_MAX, 0, mic_pga_tlv),
419*48e27874SAdam Thomson 	SOC_SINGLE("MIC2 Switch", DA732X_REG_MIC2, DA732X_MIC_MUTE_SHIFT,
420*48e27874SAdam Thomson 		   DA732X_SWITCH_MAX, DA732X_INVERT),
421*48e27874SAdam Thomson 	SOC_SINGLE_RANGE_TLV("MIC2 Volume", DA732X_REG_MIC2,
422*48e27874SAdam Thomson 			     DA732X_MIC_VOL_SHIFT, DA732X_MIC_VOL_VAL_MIN,
423*48e27874SAdam Thomson 			     DA732X_MIC_VOL_VAL_MAX, 0, mic_pga_tlv),
424*48e27874SAdam Thomson 	SOC_SINGLE("MIC3 Switch", DA732X_REG_MIC3, DA732X_MIC_MUTE_SHIFT,
425*48e27874SAdam Thomson 		   DA732X_SWITCH_MAX, DA732X_INVERT),
426*48e27874SAdam Thomson 	SOC_SINGLE_RANGE_TLV("MIC3 Volume", DA732X_REG_MIC3,
427*48e27874SAdam Thomson 			     DA732X_MIC_VOL_SHIFT, DA732X_MIC_VOL_VAL_MIN,
428*48e27874SAdam Thomson 			     DA732X_MIC_VOL_VAL_MAX, 0, mic_pga_tlv),
429*48e27874SAdam Thomson 
430*48e27874SAdam Thomson 	/* AUXs */
431*48e27874SAdam Thomson 	SOC_SINGLE("AUX1L Switch", DA732X_REG_AUX1L, DA732X_AUX_MUTE_SHIFT,
432*48e27874SAdam Thomson 		   DA732X_SWITCH_MAX, DA732X_INVERT),
433*48e27874SAdam Thomson 	SOC_SINGLE_TLV("AUX1L Volume", DA732X_REG_AUX1L,
434*48e27874SAdam Thomson 		       DA732X_AUX_VOL_SHIFT, DA732X_AUX_VOL_VAL_MAX,
435*48e27874SAdam Thomson 		       DA732X_NO_INVERT, aux_pga_tlv),
436*48e27874SAdam Thomson 	SOC_SINGLE("AUX1R Switch", DA732X_REG_AUX1R, DA732X_AUX_MUTE_SHIFT,
437*48e27874SAdam Thomson 		   DA732X_SWITCH_MAX, DA732X_INVERT),
438*48e27874SAdam Thomson 	SOC_SINGLE_TLV("AUX1R Volume", DA732X_REG_AUX1R,
439*48e27874SAdam Thomson 		       DA732X_AUX_VOL_SHIFT, DA732X_AUX_VOL_VAL_MAX,
440*48e27874SAdam Thomson 		       DA732X_NO_INVERT, aux_pga_tlv),
441*48e27874SAdam Thomson 
442*48e27874SAdam Thomson 	/* ADCs */
443*48e27874SAdam Thomson 	SOC_DOUBLE_TLV("ADC1 Volume", DA732X_REG_ADC1_SEL,
444*48e27874SAdam Thomson 		       DA732X_ADCL_VOL_SHIFT, DA732X_ADCR_VOL_SHIFT,
445*48e27874SAdam Thomson 		       DA732X_ADC_VOL_VAL_MAX, DA732X_INVERT, adc_pga_tlv),
446*48e27874SAdam Thomson 
447*48e27874SAdam Thomson 	SOC_DOUBLE_TLV("ADC2 Volume", DA732X_REG_ADC2_SEL,
448*48e27874SAdam Thomson 		       DA732X_ADCL_VOL_SHIFT, DA732X_ADCR_VOL_SHIFT,
449*48e27874SAdam Thomson 		       DA732X_ADC_VOL_VAL_MAX, DA732X_INVERT, adc_pga_tlv),
450*48e27874SAdam Thomson 
451*48e27874SAdam Thomson 	/* DACs */
452*48e27874SAdam Thomson 	SOC_DOUBLE("Digital Playback DAC12 Switch", DA732X_REG_DAC1_SEL,
453*48e27874SAdam Thomson 		   DA732X_DACL_MUTE_SHIFT, DA732X_DACR_MUTE_SHIFT,
454*48e27874SAdam Thomson 		   DA732X_SWITCH_MAX, DA732X_INVERT),
455*48e27874SAdam Thomson 	SOC_DOUBLE_R_TLV("Digital Playback DAC12 Volume", DA732X_REG_DAC1_L_VOL,
456*48e27874SAdam Thomson 			 DA732X_REG_DAC1_R_VOL, DA732X_DAC_VOL_SHIFT,
457*48e27874SAdam Thomson 			 DA732X_DAC_VOL_VAL_MAX, DA732X_INVERT, dac_pga_tlv),
458*48e27874SAdam Thomson 	SOC_SINGLE("Digital Playback DAC3 Switch", DA732X_REG_DAC2_SEL,
459*48e27874SAdam Thomson 		   DA732X_DACL_MUTE_SHIFT, DA732X_SWITCH_MAX, DA732X_INVERT),
460*48e27874SAdam Thomson 	SOC_SINGLE_TLV("Digital Playback DAC3 Volume", DA732X_REG_DAC2_L_VOL,
461*48e27874SAdam Thomson 			DA732X_DAC_VOL_SHIFT, DA732X_DAC_VOL_VAL_MAX,
462*48e27874SAdam Thomson 			DA732X_INVERT, dac_pga_tlv),
463*48e27874SAdam Thomson 	SOC_SINGLE("Digital Playback DAC4 Switch", DA732X_REG_DAC2_SEL,
464*48e27874SAdam Thomson 		   DA732X_DACR_MUTE_SHIFT, DA732X_SWITCH_MAX, DA732X_INVERT),
465*48e27874SAdam Thomson 	SOC_SINGLE_TLV("Digital Playback DAC4 Volume", DA732X_REG_DAC2_R_VOL,
466*48e27874SAdam Thomson 		       DA732X_DAC_VOL_SHIFT, DA732X_DAC_VOL_VAL_MAX,
467*48e27874SAdam Thomson 		       DA732X_INVERT, dac_pga_tlv),
468*48e27874SAdam Thomson 	SOC_SINGLE("Digital Playback DAC5 Switch", DA732X_REG_DAC3_SEL,
469*48e27874SAdam Thomson 		   DA732X_DACL_MUTE_SHIFT, DA732X_SWITCH_MAX, DA732X_INVERT),
470*48e27874SAdam Thomson 	SOC_SINGLE_TLV("Digital Playback DAC5 Volume", DA732X_REG_DAC3_VOL,
471*48e27874SAdam Thomson 		       DA732X_DAC_VOL_SHIFT, DA732X_DAC_VOL_VAL_MAX,
472*48e27874SAdam Thomson 		       DA732X_INVERT, dac_pga_tlv),
473*48e27874SAdam Thomson 
474*48e27874SAdam Thomson 	/* High Pass Filters */
475*48e27874SAdam Thomson 	SOC_ENUM_EXT("DAC1 High Pass Filter Mode",
476*48e27874SAdam Thomson 		     da732x_dac1_hpf_mode_enum, da732x_hpf_get, da732x_hpf_set),
477*48e27874SAdam Thomson 	SOC_ENUM("DAC1 High Pass Filter", da732x_dac1_hp_filter_enum),
478*48e27874SAdam Thomson 	SOC_ENUM("DAC1 Voice Filter", da732x_dac1_voice_filter_enum),
479*48e27874SAdam Thomson 
480*48e27874SAdam Thomson 	SOC_ENUM_EXT("DAC2 High Pass Filter Mode",
481*48e27874SAdam Thomson 		     da732x_dac2_hpf_mode_enum, da732x_hpf_get, da732x_hpf_set),
482*48e27874SAdam Thomson 	SOC_ENUM("DAC2 High Pass Filter", da732x_dac2_hp_filter_enum),
483*48e27874SAdam Thomson 	SOC_ENUM("DAC2 Voice Filter", da732x_dac2_voice_filter_enum),
484*48e27874SAdam Thomson 
485*48e27874SAdam Thomson 	SOC_ENUM_EXT("DAC3 High Pass Filter Mode",
486*48e27874SAdam Thomson 		     da732x_dac3_hpf_mode_enum, da732x_hpf_get, da732x_hpf_set),
487*48e27874SAdam Thomson 	SOC_ENUM("DAC3 High Pass Filter", da732x_dac3_hp_filter_enum),
488*48e27874SAdam Thomson 	SOC_ENUM("DAC3 Filter Mode", da732x_dac3_voice_filter_enum),
489*48e27874SAdam Thomson 
490*48e27874SAdam Thomson 	SOC_ENUM_EXT("ADC1 High Pass Filter Mode",
491*48e27874SAdam Thomson 		     da732x_adc1_hpf_mode_enum, da732x_hpf_get, da732x_hpf_set),
492*48e27874SAdam Thomson 	SOC_ENUM("ADC1 High Pass Filter", da732x_adc1_hp_filter_enum),
493*48e27874SAdam Thomson 	SOC_ENUM("ADC1 Voice Filter", da732x_adc1_voice_filter_enum),
494*48e27874SAdam Thomson 
495*48e27874SAdam Thomson 	SOC_ENUM_EXT("ADC2 High Pass Filter Mode",
496*48e27874SAdam Thomson 		     da732x_adc2_hpf_mode_enum, da732x_hpf_get, da732x_hpf_set),
497*48e27874SAdam Thomson 	SOC_ENUM("ADC2 High Pass Filter", da732x_adc2_hp_filter_enum),
498*48e27874SAdam Thomson 	SOC_ENUM("ADC2 Voice Filter", da732x_adc2_voice_filter_enum),
499*48e27874SAdam Thomson 
500*48e27874SAdam Thomson 	/* Equalizers */
501*48e27874SAdam Thomson 	SOC_SINGLE("ADC1 EQ Switch", DA732X_REG_ADC1_EQ5,
502*48e27874SAdam Thomson 		   DA732X_EQ_EN_SHIFT, DA732X_EQ_EN_MAX, DA732X_NO_INVERT),
503*48e27874SAdam Thomson 	SOC_SINGLE_TLV("ADC1 EQ Band 1 Volume", DA732X_REG_ADC1_EQ12,
504*48e27874SAdam Thomson 		       DA732X_EQ_BAND1_SHIFT, DA732X_EQ_VOL_VAL_MAX,
505*48e27874SAdam Thomson 		       DA732X_INVERT, eq_band_pga_tlv),
506*48e27874SAdam Thomson 	SOC_SINGLE_TLV("ADC1 EQ Band 2 Volume", DA732X_REG_ADC1_EQ12,
507*48e27874SAdam Thomson 		       DA732X_EQ_BAND2_SHIFT, DA732X_EQ_VOL_VAL_MAX,
508*48e27874SAdam Thomson 		       DA732X_INVERT, eq_band_pga_tlv),
509*48e27874SAdam Thomson 	SOC_SINGLE_TLV("ADC1 EQ Band 3 Volume", DA732X_REG_ADC1_EQ34,
510*48e27874SAdam Thomson 		       DA732X_EQ_BAND3_SHIFT, DA732X_EQ_VOL_VAL_MAX,
511*48e27874SAdam Thomson 		       DA732X_INVERT, eq_band_pga_tlv),
512*48e27874SAdam Thomson 	SOC_SINGLE_TLV("ADC1 EQ Band 4 Volume", DA732X_REG_ADC1_EQ34,
513*48e27874SAdam Thomson 		       DA732X_EQ_BAND4_SHIFT, DA732X_EQ_VOL_VAL_MAX,
514*48e27874SAdam Thomson 		       DA732X_INVERT, eq_band_pga_tlv),
515*48e27874SAdam Thomson 	SOC_SINGLE_TLV("ADC1 EQ Band 5 Volume", DA732X_REG_ADC1_EQ5,
516*48e27874SAdam Thomson 		       DA732X_EQ_BAND5_SHIFT, DA732X_EQ_VOL_VAL_MAX,
517*48e27874SAdam Thomson 		       DA732X_INVERT, eq_band_pga_tlv),
518*48e27874SAdam Thomson 	SOC_SINGLE_TLV("ADC1 EQ Overall Volume", DA732X_REG_ADC1_EQ5,
519*48e27874SAdam Thomson 		       DA732X_EQ_OVERALL_SHIFT, DA732X_EQ_OVERALL_VOL_VAL_MAX,
520*48e27874SAdam Thomson 		       DA732X_INVERT, eq_overall_tlv),
521*48e27874SAdam Thomson 
522*48e27874SAdam Thomson 	SOC_SINGLE("ADC2 EQ Switch", DA732X_REG_ADC2_EQ5,
523*48e27874SAdam Thomson 		   DA732X_EQ_EN_SHIFT, DA732X_EQ_EN_MAX, DA732X_NO_INVERT),
524*48e27874SAdam Thomson 	SOC_SINGLE_TLV("ADC2 EQ Band 1 Volume", DA732X_REG_ADC2_EQ12,
525*48e27874SAdam Thomson 		       DA732X_EQ_BAND1_SHIFT, DA732X_EQ_VOL_VAL_MAX,
526*48e27874SAdam Thomson 		       DA732X_INVERT, eq_band_pga_tlv),
527*48e27874SAdam Thomson 	SOC_SINGLE_TLV("ADC2 EQ Band 2 Volume", DA732X_REG_ADC2_EQ12,
528*48e27874SAdam Thomson 		       DA732X_EQ_BAND2_SHIFT, DA732X_EQ_VOL_VAL_MAX,
529*48e27874SAdam Thomson 		       DA732X_INVERT, eq_band_pga_tlv),
530*48e27874SAdam Thomson 	SOC_SINGLE_TLV("ADC2 EQ Band 3 Volume", DA732X_REG_ADC2_EQ34,
531*48e27874SAdam Thomson 		       DA732X_EQ_BAND3_SHIFT, DA732X_EQ_VOL_VAL_MAX,
532*48e27874SAdam Thomson 		       DA732X_INVERT, eq_band_pga_tlv),
533*48e27874SAdam Thomson 	SOC_SINGLE_TLV("ACD2 EQ Band 4 Volume", DA732X_REG_ADC2_EQ34,
534*48e27874SAdam Thomson 		       DA732X_EQ_BAND4_SHIFT, DA732X_EQ_VOL_VAL_MAX,
535*48e27874SAdam Thomson 		       DA732X_INVERT, eq_band_pga_tlv),
536*48e27874SAdam Thomson 	SOC_SINGLE_TLV("ACD2 EQ Band 5 Volume", DA732X_REG_ADC2_EQ5,
537*48e27874SAdam Thomson 		       DA732X_EQ_BAND5_SHIFT, DA732X_EQ_VOL_VAL_MAX,
538*48e27874SAdam Thomson 		       DA732X_INVERT, eq_band_pga_tlv),
539*48e27874SAdam Thomson 	SOC_SINGLE_TLV("ADC2 EQ Overall Volume", DA732X_REG_ADC1_EQ5,
540*48e27874SAdam Thomson 		       DA732X_EQ_OVERALL_SHIFT, DA732X_EQ_OVERALL_VOL_VAL_MAX,
541*48e27874SAdam Thomson 		       DA732X_INVERT, eq_overall_tlv),
542*48e27874SAdam Thomson 
543*48e27874SAdam Thomson 	SOC_SINGLE("DAC1 EQ Switch", DA732X_REG_DAC1_EQ5,
544*48e27874SAdam Thomson 		   DA732X_EQ_EN_SHIFT, DA732X_EQ_EN_MAX, DA732X_NO_INVERT),
545*48e27874SAdam Thomson 	SOC_SINGLE_TLV("DAC1 EQ Band 1 Volume", DA732X_REG_DAC1_EQ12,
546*48e27874SAdam Thomson 		       DA732X_EQ_BAND1_SHIFT, DA732X_EQ_VOL_VAL_MAX,
547*48e27874SAdam Thomson 		       DA732X_INVERT, eq_band_pga_tlv),
548*48e27874SAdam Thomson 	SOC_SINGLE_TLV("DAC1 EQ Band 2 Volume", DA732X_REG_DAC1_EQ12,
549*48e27874SAdam Thomson 		       DA732X_EQ_BAND2_SHIFT, DA732X_EQ_VOL_VAL_MAX,
550*48e27874SAdam Thomson 		       DA732X_INVERT, eq_band_pga_tlv),
551*48e27874SAdam Thomson 	SOC_SINGLE_TLV("DAC1 EQ Band 3 Volume", DA732X_REG_DAC1_EQ34,
552*48e27874SAdam Thomson 		       DA732X_EQ_BAND3_SHIFT, DA732X_EQ_VOL_VAL_MAX,
553*48e27874SAdam Thomson 		       DA732X_INVERT, eq_band_pga_tlv),
554*48e27874SAdam Thomson 	SOC_SINGLE_TLV("DAC1 EQ Band 4 Volume", DA732X_REG_DAC1_EQ34,
555*48e27874SAdam Thomson 		       DA732X_EQ_BAND4_SHIFT, DA732X_EQ_VOL_VAL_MAX,
556*48e27874SAdam Thomson 		       DA732X_INVERT, eq_band_pga_tlv),
557*48e27874SAdam Thomson 	SOC_SINGLE_TLV("DAC1 EQ Band 5 Volume", DA732X_REG_DAC1_EQ5,
558*48e27874SAdam Thomson 		       DA732X_EQ_BAND5_SHIFT, DA732X_EQ_VOL_VAL_MAX,
559*48e27874SAdam Thomson 		       DA732X_INVERT, eq_band_pga_tlv),
560*48e27874SAdam Thomson 
561*48e27874SAdam Thomson 	SOC_SINGLE("DAC2 EQ Switch", DA732X_REG_DAC2_EQ5,
562*48e27874SAdam Thomson 		   DA732X_EQ_EN_SHIFT, DA732X_EQ_EN_MAX, DA732X_NO_INVERT),
563*48e27874SAdam Thomson 	SOC_SINGLE_TLV("DAC2 EQ Band 1 Volume", DA732X_REG_DAC2_EQ12,
564*48e27874SAdam Thomson 		       DA732X_EQ_BAND1_SHIFT, DA732X_EQ_VOL_VAL_MAX,
565*48e27874SAdam Thomson 		       DA732X_INVERT, eq_band_pga_tlv),
566*48e27874SAdam Thomson 	SOC_SINGLE_TLV("DAC2 EQ Band 2 Volume", DA732X_REG_DAC2_EQ12,
567*48e27874SAdam Thomson 		       DA732X_EQ_BAND2_SHIFT, DA732X_EQ_VOL_VAL_MAX,
568*48e27874SAdam Thomson 		       DA732X_INVERT, eq_band_pga_tlv),
569*48e27874SAdam Thomson 	SOC_SINGLE_TLV("DAC2 EQ Band 3 Volume", DA732X_REG_DAC2_EQ34,
570*48e27874SAdam Thomson 		       DA732X_EQ_BAND3_SHIFT, DA732X_EQ_VOL_VAL_MAX,
571*48e27874SAdam Thomson 		       DA732X_INVERT, eq_band_pga_tlv),
572*48e27874SAdam Thomson 	SOC_SINGLE_TLV("DAC2 EQ Band 4 Volume", DA732X_REG_DAC2_EQ34,
573*48e27874SAdam Thomson 		       DA732X_EQ_BAND4_SHIFT, DA732X_EQ_VOL_VAL_MAX,
574*48e27874SAdam Thomson 		       DA732X_INVERT, eq_band_pga_tlv),
575*48e27874SAdam Thomson 	SOC_SINGLE_TLV("DAC2 EQ Band 5 Volume", DA732X_REG_DAC2_EQ5,
576*48e27874SAdam Thomson 		       DA732X_EQ_BAND5_SHIFT, DA732X_EQ_VOL_VAL_MAX,
577*48e27874SAdam Thomson 		       DA732X_INVERT, eq_band_pga_tlv),
578*48e27874SAdam Thomson 
579*48e27874SAdam Thomson 	SOC_SINGLE("DAC3 EQ Switch", DA732X_REG_DAC3_EQ5,
580*48e27874SAdam Thomson 		   DA732X_EQ_EN_SHIFT, DA732X_EQ_EN_MAX, DA732X_NO_INVERT),
581*48e27874SAdam Thomson 	SOC_SINGLE_TLV("DAC3 EQ Band 1 Volume", DA732X_REG_DAC3_EQ12,
582*48e27874SAdam Thomson 		       DA732X_EQ_BAND1_SHIFT, DA732X_EQ_VOL_VAL_MAX,
583*48e27874SAdam Thomson 		       DA732X_INVERT, eq_band_pga_tlv),
584*48e27874SAdam Thomson 	SOC_SINGLE_TLV("DAC3 EQ Band 2 Volume", DA732X_REG_DAC3_EQ12,
585*48e27874SAdam Thomson 		       DA732X_EQ_BAND2_SHIFT, DA732X_EQ_VOL_VAL_MAX,
586*48e27874SAdam Thomson 		       DA732X_INVERT, eq_band_pga_tlv),
587*48e27874SAdam Thomson 	SOC_SINGLE_TLV("DAC3 EQ Band 3 Volume", DA732X_REG_DAC3_EQ34,
588*48e27874SAdam Thomson 		       DA732X_EQ_BAND3_SHIFT, DA732X_EQ_VOL_VAL_MAX,
589*48e27874SAdam Thomson 		       DA732X_INVERT, eq_band_pga_tlv),
590*48e27874SAdam Thomson 	SOC_SINGLE_TLV("DAC3 EQ Band 4 Volume", DA732X_REG_DAC3_EQ34,
591*48e27874SAdam Thomson 		       DA732X_EQ_BAND4_SHIFT, DA732X_EQ_VOL_VAL_MAX,
592*48e27874SAdam Thomson 		       DA732X_INVERT, eq_band_pga_tlv),
593*48e27874SAdam Thomson 	SOC_SINGLE_TLV("DAC3 EQ Band 5 Volume", DA732X_REG_DAC3_EQ5,
594*48e27874SAdam Thomson 		       DA732X_EQ_BAND5_SHIFT, DA732X_EQ_VOL_VAL_MAX,
595*48e27874SAdam Thomson 		       DA732X_INVERT, eq_band_pga_tlv),
596*48e27874SAdam Thomson 
597*48e27874SAdam Thomson 	/* Lineout 2 Reciever*/
598*48e27874SAdam Thomson 	SOC_SINGLE("Lineout 2 Switch", DA732X_REG_LIN2, DA732X_LOUT_MUTE_SHIFT,
599*48e27874SAdam Thomson 		   DA732X_SWITCH_MAX, DA732X_INVERT),
600*48e27874SAdam Thomson 	SOC_SINGLE_TLV("Lineout 2 Volume", DA732X_REG_LIN2,
601*48e27874SAdam Thomson 		       DA732X_LOUT_VOL_SHIFT, DA732X_LOUT_VOL_VAL_MAX,
602*48e27874SAdam Thomson 		       DA732X_NO_INVERT, lin2_pga_tlv),
603*48e27874SAdam Thomson 
604*48e27874SAdam Thomson 	/* Lineout 3 SPEAKER*/
605*48e27874SAdam Thomson 	SOC_SINGLE("Lineout 3 Switch", DA732X_REG_LIN3, DA732X_LOUT_MUTE_SHIFT,
606*48e27874SAdam Thomson 		   DA732X_SWITCH_MAX, DA732X_INVERT),
607*48e27874SAdam Thomson 	SOC_SINGLE_TLV("Lineout 3 Volume", DA732X_REG_LIN3,
608*48e27874SAdam Thomson 		       DA732X_LOUT_VOL_SHIFT, DA732X_LOUT_VOL_VAL_MAX,
609*48e27874SAdam Thomson 		       DA732X_NO_INVERT, lin3_pga_tlv),
610*48e27874SAdam Thomson 
611*48e27874SAdam Thomson 	/* Lineout 4 */
612*48e27874SAdam Thomson 	SOC_SINGLE("Lineout 4 Switch", DA732X_REG_LIN4, DA732X_LOUT_MUTE_SHIFT,
613*48e27874SAdam Thomson 		   DA732X_SWITCH_MAX, DA732X_INVERT),
614*48e27874SAdam Thomson 	SOC_SINGLE_TLV("Lineout 4 Volume", DA732X_REG_LIN4,
615*48e27874SAdam Thomson 		       DA732X_LOUT_VOL_SHIFT, DA732X_LOUT_VOL_VAL_MAX,
616*48e27874SAdam Thomson 		       DA732X_NO_INVERT, lin4_pga_tlv),
617*48e27874SAdam Thomson 
618*48e27874SAdam Thomson 	/* Headphones */
619*48e27874SAdam Thomson 	SOC_DOUBLE_R("Headphone Switch", DA732X_REG_HPR, DA732X_REG_HPL,
620*48e27874SAdam Thomson 		     DA732X_HP_MUTE_SHIFT, DA732X_SWITCH_MAX, DA732X_INVERT),
621*48e27874SAdam Thomson 	SOC_DOUBLE_R_TLV("Headphone Volume", DA732X_REG_HPL_VOL,
622*48e27874SAdam Thomson 			 DA732X_REG_HPR_VOL, DA732X_HP_VOL_SHIFT,
623*48e27874SAdam Thomson 			 DA732X_HP_VOL_VAL_MAX, DA732X_NO_INVERT, hp_pga_tlv),
624*48e27874SAdam Thomson };
625*48e27874SAdam Thomson 
626*48e27874SAdam Thomson static int da732x_adc_event(struct snd_soc_dapm_widget *w,
627*48e27874SAdam Thomson 			    struct snd_kcontrol *kcontrol, int event)
628*48e27874SAdam Thomson {
629*48e27874SAdam Thomson 	struct snd_soc_codec *codec = w->codec;
630*48e27874SAdam Thomson 
631*48e27874SAdam Thomson 	switch (event) {
632*48e27874SAdam Thomson 	case SND_SOC_DAPM_POST_PMU:
633*48e27874SAdam Thomson 		switch (w->reg) {
634*48e27874SAdam Thomson 		case DA732X_REG_ADC1_PD:
635*48e27874SAdam Thomson 			snd_soc_update_bits(codec, DA732X_REG_CLK_EN3,
636*48e27874SAdam Thomson 					    DA732X_ADCA_BB_CLK_EN,
637*48e27874SAdam Thomson 					    DA732X_ADCA_BB_CLK_EN);
638*48e27874SAdam Thomson 			break;
639*48e27874SAdam Thomson 		case DA732X_REG_ADC2_PD:
640*48e27874SAdam Thomson 			snd_soc_update_bits(codec, DA732X_REG_CLK_EN3,
641*48e27874SAdam Thomson 					    DA732X_ADCC_BB_CLK_EN,
642*48e27874SAdam Thomson 					    DA732X_ADCC_BB_CLK_EN);
643*48e27874SAdam Thomson 			break;
644*48e27874SAdam Thomson 		default:
645*48e27874SAdam Thomson 			return -EINVAL;
646*48e27874SAdam Thomson 		}
647*48e27874SAdam Thomson 
648*48e27874SAdam Thomson 		snd_soc_update_bits(codec, w->reg, DA732X_ADC_RST_MASK,
649*48e27874SAdam Thomson 				    DA732X_ADC_SET_ACT);
650*48e27874SAdam Thomson 		snd_soc_update_bits(codec, w->reg, DA732X_ADC_PD_MASK,
651*48e27874SAdam Thomson 				    DA732X_ADC_ON);
652*48e27874SAdam Thomson 		break;
653*48e27874SAdam Thomson 	case SND_SOC_DAPM_POST_PMD:
654*48e27874SAdam Thomson 		snd_soc_update_bits(codec, w->reg, DA732X_ADC_PD_MASK,
655*48e27874SAdam Thomson 				    DA732X_ADC_OFF);
656*48e27874SAdam Thomson 		snd_soc_update_bits(codec, w->reg, DA732X_ADC_RST_MASK,
657*48e27874SAdam Thomson 				    DA732X_ADC_SET_RST);
658*48e27874SAdam Thomson 
659*48e27874SAdam Thomson 		switch (w->reg) {
660*48e27874SAdam Thomson 		case DA732X_REG_ADC1_PD:
661*48e27874SAdam Thomson 			snd_soc_update_bits(codec, DA732X_REG_CLK_EN3,
662*48e27874SAdam Thomson 					    DA732X_ADCA_BB_CLK_EN, 0);
663*48e27874SAdam Thomson 			break;
664*48e27874SAdam Thomson 		case DA732X_REG_ADC2_PD:
665*48e27874SAdam Thomson 			snd_soc_update_bits(codec, DA732X_REG_CLK_EN3,
666*48e27874SAdam Thomson 					    DA732X_ADCC_BB_CLK_EN, 0);
667*48e27874SAdam Thomson 			break;
668*48e27874SAdam Thomson 		default:
669*48e27874SAdam Thomson 			return -EINVAL;
670*48e27874SAdam Thomson 		}
671*48e27874SAdam Thomson 
672*48e27874SAdam Thomson 		break;
673*48e27874SAdam Thomson 	default:
674*48e27874SAdam Thomson 		return -EINVAL;
675*48e27874SAdam Thomson 	}
676*48e27874SAdam Thomson 
677*48e27874SAdam Thomson 	return 0;
678*48e27874SAdam Thomson }
679*48e27874SAdam Thomson 
680*48e27874SAdam Thomson static int da732x_out_pga_event(struct snd_soc_dapm_widget *w,
681*48e27874SAdam Thomson 				struct snd_kcontrol *kcontrol, int event)
682*48e27874SAdam Thomson {
683*48e27874SAdam Thomson 	struct snd_soc_codec *codec = w->codec;
684*48e27874SAdam Thomson 
685*48e27874SAdam Thomson 	switch (event) {
686*48e27874SAdam Thomson 	case SND_SOC_DAPM_POST_PMU:
687*48e27874SAdam Thomson 		snd_soc_update_bits(codec, w->reg,
688*48e27874SAdam Thomson 				    (1 << w->shift) | DA732X_OUT_HIZ_EN,
689*48e27874SAdam Thomson 				    (1 << w->shift) | DA732X_OUT_HIZ_EN);
690*48e27874SAdam Thomson 		break;
691*48e27874SAdam Thomson 	case SND_SOC_DAPM_POST_PMD:
692*48e27874SAdam Thomson 		snd_soc_update_bits(codec, w->reg,
693*48e27874SAdam Thomson 				    (1 << w->shift) | DA732X_OUT_HIZ_EN,
694*48e27874SAdam Thomson 				    (1 << w->shift) | DA732X_OUT_HIZ_DIS);
695*48e27874SAdam Thomson 		break;
696*48e27874SAdam Thomson 	default:
697*48e27874SAdam Thomson 		return -EINVAL;
698*48e27874SAdam Thomson 	}
699*48e27874SAdam Thomson 
700*48e27874SAdam Thomson 	return 0;
701*48e27874SAdam Thomson }
702*48e27874SAdam Thomson 
703*48e27874SAdam Thomson static const char *adcl_text[] = {
704*48e27874SAdam Thomson 	"AUX1L", "MIC1"
705*48e27874SAdam Thomson };
706*48e27874SAdam Thomson 
707*48e27874SAdam Thomson static const char *adcr_text[] = {
708*48e27874SAdam Thomson 	"AUX1R", "MIC2", "MIC3"
709*48e27874SAdam Thomson };
710*48e27874SAdam Thomson 
711*48e27874SAdam Thomson static const char *enable_text[] = {
712*48e27874SAdam Thomson 	"Disabled",
713*48e27874SAdam Thomson 	"Enabled"
714*48e27874SAdam Thomson };
715*48e27874SAdam Thomson 
716*48e27874SAdam Thomson /* ADC1LMUX */
717*48e27874SAdam Thomson static const struct soc_enum adc1l_enum =
718*48e27874SAdam Thomson 	SOC_ENUM_SINGLE(DA732X_REG_INP_MUX, DA732X_ADC1L_MUX_SEL_SHIFT,
719*48e27874SAdam Thomson 			DA732X_ADCL_MUX_MAX, adcl_text);
720*48e27874SAdam Thomson static const struct snd_kcontrol_new adc1l_mux =
721*48e27874SAdam Thomson 	SOC_DAPM_ENUM("ADC Route", adc1l_enum);
722*48e27874SAdam Thomson 
723*48e27874SAdam Thomson /* ADC1RMUX */
724*48e27874SAdam Thomson static const struct soc_enum adc1r_enum =
725*48e27874SAdam Thomson 	SOC_ENUM_SINGLE(DA732X_REG_INP_MUX, DA732X_ADC1R_MUX_SEL_SHIFT,
726*48e27874SAdam Thomson 			DA732X_ADCR_MUX_MAX, adcr_text);
727*48e27874SAdam Thomson static const struct snd_kcontrol_new adc1r_mux =
728*48e27874SAdam Thomson 	SOC_DAPM_ENUM("ADC Route", adc1r_enum);
729*48e27874SAdam Thomson 
730*48e27874SAdam Thomson /* ADC2LMUX */
731*48e27874SAdam Thomson static const struct soc_enum adc2l_enum =
732*48e27874SAdam Thomson 	SOC_ENUM_SINGLE(DA732X_REG_INP_MUX, DA732X_ADC2L_MUX_SEL_SHIFT,
733*48e27874SAdam Thomson 			DA732X_ADCL_MUX_MAX, adcl_text);
734*48e27874SAdam Thomson static const struct snd_kcontrol_new adc2l_mux =
735*48e27874SAdam Thomson 	SOC_DAPM_ENUM("ADC Route", adc2l_enum);
736*48e27874SAdam Thomson 
737*48e27874SAdam Thomson /* ADC2RMUX */
738*48e27874SAdam Thomson static const struct soc_enum adc2r_enum =
739*48e27874SAdam Thomson 	SOC_ENUM_SINGLE(DA732X_REG_INP_MUX, DA732X_ADC2R_MUX_SEL_SHIFT,
740*48e27874SAdam Thomson 			DA732X_ADCR_MUX_MAX, adcr_text);
741*48e27874SAdam Thomson 
742*48e27874SAdam Thomson static const struct snd_kcontrol_new adc2r_mux =
743*48e27874SAdam Thomson 	SOC_DAPM_ENUM("ADC Route", adc2r_enum);
744*48e27874SAdam Thomson 
745*48e27874SAdam Thomson static const struct soc_enum da732x_hp_left_output =
746*48e27874SAdam Thomson 	SOC_ENUM_SINGLE(DA732X_REG_HPL, DA732X_HP_OUT_DAC_EN_SHIFT,
747*48e27874SAdam Thomson 			DA732X_DAC_EN_MAX, enable_text);
748*48e27874SAdam Thomson 
749*48e27874SAdam Thomson static const struct snd_kcontrol_new hpl_mux =
750*48e27874SAdam Thomson 	SOC_DAPM_ENUM("HPL Switch", da732x_hp_left_output);
751*48e27874SAdam Thomson 
752*48e27874SAdam Thomson static const struct soc_enum da732x_hp_right_output =
753*48e27874SAdam Thomson 	SOC_ENUM_SINGLE(DA732X_REG_HPR, DA732X_HP_OUT_DAC_EN_SHIFT,
754*48e27874SAdam Thomson 			DA732X_DAC_EN_MAX, enable_text);
755*48e27874SAdam Thomson 
756*48e27874SAdam Thomson static const struct snd_kcontrol_new hpr_mux =
757*48e27874SAdam Thomson 	SOC_DAPM_ENUM("HPR Switch", da732x_hp_right_output);
758*48e27874SAdam Thomson 
759*48e27874SAdam Thomson static const struct soc_enum da732x_speaker_output =
760*48e27874SAdam Thomson 	SOC_ENUM_SINGLE(DA732X_REG_LIN3, DA732X_LOUT_DAC_EN_SHIFT,
761*48e27874SAdam Thomson 			DA732X_DAC_EN_MAX, enable_text);
762*48e27874SAdam Thomson 
763*48e27874SAdam Thomson static const struct snd_kcontrol_new spk_mux =
764*48e27874SAdam Thomson 	SOC_DAPM_ENUM("SPK Switch", da732x_speaker_output);
765*48e27874SAdam Thomson 
766*48e27874SAdam Thomson static const struct soc_enum da732x_lout4_output =
767*48e27874SAdam Thomson 	SOC_ENUM_SINGLE(DA732X_REG_LIN4, DA732X_LOUT_DAC_EN_SHIFT,
768*48e27874SAdam Thomson 			DA732X_DAC_EN_MAX, enable_text);
769*48e27874SAdam Thomson 
770*48e27874SAdam Thomson static const struct snd_kcontrol_new lout4_mux =
771*48e27874SAdam Thomson 	SOC_DAPM_ENUM("LOUT4 Switch", da732x_lout4_output);
772*48e27874SAdam Thomson 
773*48e27874SAdam Thomson static const struct soc_enum da732x_lout2_output =
774*48e27874SAdam Thomson 	SOC_ENUM_SINGLE(DA732X_REG_LIN2, DA732X_LOUT_DAC_EN_SHIFT,
775*48e27874SAdam Thomson 			DA732X_DAC_EN_MAX, enable_text);
776*48e27874SAdam Thomson 
777*48e27874SAdam Thomson static const struct snd_kcontrol_new lout2_mux =
778*48e27874SAdam Thomson 	SOC_DAPM_ENUM("LOUT2 Switch", da732x_lout2_output);
779*48e27874SAdam Thomson 
780*48e27874SAdam Thomson static const struct snd_soc_dapm_widget da732x_dapm_widgets[] = {
781*48e27874SAdam Thomson 	/* Supplies */
782*48e27874SAdam Thomson 	SND_SOC_DAPM_SUPPLY("ADC1 Supply", DA732X_REG_ADC1_PD, 0,
783*48e27874SAdam Thomson 			    DA732X_NO_INVERT, da732x_adc_event,
784*48e27874SAdam Thomson 			    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
785*48e27874SAdam Thomson 	SND_SOC_DAPM_SUPPLY("ADC2 Supply", DA732X_REG_ADC2_PD, 0,
786*48e27874SAdam Thomson 			    DA732X_NO_INVERT, da732x_adc_event,
787*48e27874SAdam Thomson 			    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
788*48e27874SAdam Thomson 	SND_SOC_DAPM_SUPPLY("DAC1 CLK", DA732X_REG_CLK_EN4,
789*48e27874SAdam Thomson 			    DA732X_DACA_BB_CLK_SHIFT, DA732X_NO_INVERT,
790*48e27874SAdam Thomson 			    NULL, 0),
791*48e27874SAdam Thomson 	SND_SOC_DAPM_SUPPLY("DAC2 CLK", DA732X_REG_CLK_EN4,
792*48e27874SAdam Thomson 			    DA732X_DACC_BB_CLK_SHIFT, DA732X_NO_INVERT,
793*48e27874SAdam Thomson 			    NULL, 0),
794*48e27874SAdam Thomson 	SND_SOC_DAPM_SUPPLY("DAC3 CLK", DA732X_REG_CLK_EN5,
795*48e27874SAdam Thomson 			    DA732X_DACE_BB_CLK_SHIFT, DA732X_NO_INVERT,
796*48e27874SAdam Thomson 			    NULL, 0),
797*48e27874SAdam Thomson 
798*48e27874SAdam Thomson 	/* Micbias */
799*48e27874SAdam Thomson 	SND_SOC_DAPM_SUPPLY("MICBIAS1", DA732X_REG_MICBIAS1,
800*48e27874SAdam Thomson 			    DA732X_MICBIAS_EN_SHIFT,
801*48e27874SAdam Thomson 			    DA732X_NO_INVERT, NULL, 0),
802*48e27874SAdam Thomson 	SND_SOC_DAPM_SUPPLY("MICBIAS2", DA732X_REG_MICBIAS2,
803*48e27874SAdam Thomson 			    DA732X_MICBIAS_EN_SHIFT,
804*48e27874SAdam Thomson 			    DA732X_NO_INVERT, NULL, 0),
805*48e27874SAdam Thomson 
806*48e27874SAdam Thomson 	/* Inputs */
807*48e27874SAdam Thomson 	SND_SOC_DAPM_INPUT("MIC1"),
808*48e27874SAdam Thomson 	SND_SOC_DAPM_INPUT("MIC2"),
809*48e27874SAdam Thomson 	SND_SOC_DAPM_INPUT("MIC3"),
810*48e27874SAdam Thomson 	SND_SOC_DAPM_INPUT("AUX1L"),
811*48e27874SAdam Thomson 	SND_SOC_DAPM_INPUT("AUX1R"),
812*48e27874SAdam Thomson 
813*48e27874SAdam Thomson 	/* Outputs */
814*48e27874SAdam Thomson 	SND_SOC_DAPM_OUTPUT("HPL"),
815*48e27874SAdam Thomson 	SND_SOC_DAPM_OUTPUT("HPR"),
816*48e27874SAdam Thomson 	SND_SOC_DAPM_OUTPUT("LOUTL"),
817*48e27874SAdam Thomson 	SND_SOC_DAPM_OUTPUT("LOUTR"),
818*48e27874SAdam Thomson 	SND_SOC_DAPM_OUTPUT("ClassD"),
819*48e27874SAdam Thomson 
820*48e27874SAdam Thomson 	/* ADCs */
821*48e27874SAdam Thomson 	SND_SOC_DAPM_ADC("ADC1L", NULL, DA732X_REG_ADC1_SEL,
822*48e27874SAdam Thomson 			 DA732X_ADCL_EN_SHIFT, DA732X_NO_INVERT),
823*48e27874SAdam Thomson 	SND_SOC_DAPM_ADC("ADC1R", NULL, DA732X_REG_ADC1_SEL,
824*48e27874SAdam Thomson 			 DA732X_ADCR_EN_SHIFT, DA732X_NO_INVERT),
825*48e27874SAdam Thomson 	SND_SOC_DAPM_ADC("ADC2L", NULL, DA732X_REG_ADC2_SEL,
826*48e27874SAdam Thomson 			 DA732X_ADCL_EN_SHIFT, DA732X_NO_INVERT),
827*48e27874SAdam Thomson 	SND_SOC_DAPM_ADC("ADC2R", NULL, DA732X_REG_ADC2_SEL,
828*48e27874SAdam Thomson 			 DA732X_ADCR_EN_SHIFT, DA732X_NO_INVERT),
829*48e27874SAdam Thomson 
830*48e27874SAdam Thomson 	/* DACs */
831*48e27874SAdam Thomson 	SND_SOC_DAPM_DAC("DAC1L", NULL, DA732X_REG_DAC1_SEL,
832*48e27874SAdam Thomson 			 DA732X_DACL_EN_SHIFT, DA732X_NO_INVERT),
833*48e27874SAdam Thomson 	SND_SOC_DAPM_DAC("DAC1R", NULL, DA732X_REG_DAC1_SEL,
834*48e27874SAdam Thomson 			 DA732X_DACR_EN_SHIFT, DA732X_NO_INVERT),
835*48e27874SAdam Thomson 	SND_SOC_DAPM_DAC("DAC2L", NULL, DA732X_REG_DAC2_SEL,
836*48e27874SAdam Thomson 			 DA732X_DACL_EN_SHIFT, DA732X_NO_INVERT),
837*48e27874SAdam Thomson 	SND_SOC_DAPM_DAC("DAC2R", NULL, DA732X_REG_DAC2_SEL,
838*48e27874SAdam Thomson 			 DA732X_DACR_EN_SHIFT, DA732X_NO_INVERT),
839*48e27874SAdam Thomson 	SND_SOC_DAPM_DAC("DAC3", NULL, DA732X_REG_DAC3_SEL,
840*48e27874SAdam Thomson 			 DA732X_DACL_EN_SHIFT, DA732X_NO_INVERT),
841*48e27874SAdam Thomson 
842*48e27874SAdam Thomson 	/* Input Pgas */
843*48e27874SAdam Thomson 	SND_SOC_DAPM_PGA("MIC1 PGA", DA732X_REG_MIC1, DA732X_MIC_EN_SHIFT,
844*48e27874SAdam Thomson 			 0, NULL, 0),
845*48e27874SAdam Thomson 	SND_SOC_DAPM_PGA("MIC2 PGA", DA732X_REG_MIC2, DA732X_MIC_EN_SHIFT,
846*48e27874SAdam Thomson 			 0, NULL, 0),
847*48e27874SAdam Thomson 	SND_SOC_DAPM_PGA("MIC3 PGA", DA732X_REG_MIC3, DA732X_MIC_EN_SHIFT,
848*48e27874SAdam Thomson 			 0, NULL, 0),
849*48e27874SAdam Thomson 	SND_SOC_DAPM_PGA("AUX1L PGA", DA732X_REG_AUX1L, DA732X_AUX_EN_SHIFT,
850*48e27874SAdam Thomson 			 0, NULL, 0),
851*48e27874SAdam Thomson 	SND_SOC_DAPM_PGA("AUX1R PGA", DA732X_REG_AUX1R, DA732X_AUX_EN_SHIFT,
852*48e27874SAdam Thomson 			 0, NULL, 0),
853*48e27874SAdam Thomson 
854*48e27874SAdam Thomson 	SND_SOC_DAPM_PGA_E("HP Left", DA732X_REG_HPL, DA732X_HP_OUT_EN_SHIFT,
855*48e27874SAdam Thomson 			   0, NULL, 0, da732x_out_pga_event,
856*48e27874SAdam Thomson 			   SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
857*48e27874SAdam Thomson 	SND_SOC_DAPM_PGA_E("HP Right", DA732X_REG_HPR, DA732X_HP_OUT_EN_SHIFT,
858*48e27874SAdam Thomson 			   0, NULL, 0, da732x_out_pga_event,
859*48e27874SAdam Thomson 			   SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
860*48e27874SAdam Thomson 	SND_SOC_DAPM_PGA_E("LIN2", DA732X_REG_LIN2, DA732X_LIN_OUT_EN_SHIFT,
861*48e27874SAdam Thomson 			   0, NULL, 0, da732x_out_pga_event,
862*48e27874SAdam Thomson 			   SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
863*48e27874SAdam Thomson 	SND_SOC_DAPM_PGA_E("LIN3", DA732X_REG_LIN3, DA732X_LIN_OUT_EN_SHIFT,
864*48e27874SAdam Thomson 			   0, NULL, 0, da732x_out_pga_event,
865*48e27874SAdam Thomson 			   SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
866*48e27874SAdam Thomson 	SND_SOC_DAPM_PGA_E("LIN4", DA732X_REG_LIN4, DA732X_LIN_OUT_EN_SHIFT,
867*48e27874SAdam Thomson 			   0, NULL, 0, da732x_out_pga_event,
868*48e27874SAdam Thomson 			   SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
869*48e27874SAdam Thomson 
870*48e27874SAdam Thomson 	/* MUXs */
871*48e27874SAdam Thomson 	SND_SOC_DAPM_MUX("ADC1 Left MUX", SND_SOC_NOPM, 0, 0, &adc1l_mux),
872*48e27874SAdam Thomson 	SND_SOC_DAPM_MUX("ADC1 Right MUX", SND_SOC_NOPM, 0, 0, &adc1r_mux),
873*48e27874SAdam Thomson 	SND_SOC_DAPM_MUX("ADC2 Left MUX", SND_SOC_NOPM, 0, 0, &adc2l_mux),
874*48e27874SAdam Thomson 	SND_SOC_DAPM_MUX("ADC2 Right MUX", SND_SOC_NOPM, 0, 0, &adc2r_mux),
875*48e27874SAdam Thomson 
876*48e27874SAdam Thomson 	SND_SOC_DAPM_MUX("HP Left MUX", SND_SOC_NOPM, 0, 0, &hpl_mux),
877*48e27874SAdam Thomson 	SND_SOC_DAPM_MUX("HP Right MUX", SND_SOC_NOPM, 0, 0, &hpr_mux),
878*48e27874SAdam Thomson 	SND_SOC_DAPM_MUX("Speaker MUX", SND_SOC_NOPM, 0, 0, &spk_mux),
879*48e27874SAdam Thomson 	SND_SOC_DAPM_MUX("LOUT2 MUX", SND_SOC_NOPM, 0, 0, &lout2_mux),
880*48e27874SAdam Thomson 	SND_SOC_DAPM_MUX("LOUT4 MUX", SND_SOC_NOPM, 0, 0, &lout4_mux),
881*48e27874SAdam Thomson 
882*48e27874SAdam Thomson 	/* AIF interfaces */
883*48e27874SAdam Thomson 	SND_SOC_DAPM_AIF_OUT("AIFA Output", "AIFA Capture", 0, DA732X_REG_AIFA3,
884*48e27874SAdam Thomson 			     DA732X_AIF_EN_SHIFT, 0),
885*48e27874SAdam Thomson 	SND_SOC_DAPM_AIF_IN("AIFA Input", "AIFA Playback", 0, DA732X_REG_AIFA3,
886*48e27874SAdam Thomson 			    DA732X_AIF_EN_SHIFT, 0),
887*48e27874SAdam Thomson 
888*48e27874SAdam Thomson 	SND_SOC_DAPM_AIF_OUT("AIFB Output", "AIFB Capture", 0, DA732X_REG_AIFB3,
889*48e27874SAdam Thomson 			     DA732X_AIF_EN_SHIFT, 0),
890*48e27874SAdam Thomson 	SND_SOC_DAPM_AIF_IN("AIFB Input", "AIFB Playback", 0, DA732X_REG_AIFB3,
891*48e27874SAdam Thomson 			    DA732X_AIF_EN_SHIFT, 0),
892*48e27874SAdam Thomson };
893*48e27874SAdam Thomson 
894*48e27874SAdam Thomson static const struct snd_soc_dapm_route da732x_dapm_routes[] = {
895*48e27874SAdam Thomson 	/* Inputs */
896*48e27874SAdam Thomson 	{"AUX1L PGA", "NULL", "AUX1L"},
897*48e27874SAdam Thomson 	{"AUX1R PGA", "NULL", "AUX1R"},
898*48e27874SAdam Thomson 	{"MIC1 PGA", NULL, "MIC1"},
899*48e27874SAdam Thomson 	{"MIC2 PGA", "NULL", "MIC2"},
900*48e27874SAdam Thomson 	{"MIC3 PGA", "NULL", "MIC3"},
901*48e27874SAdam Thomson 
902*48e27874SAdam Thomson 	/* Capture Path */
903*48e27874SAdam Thomson 	{"ADC1 Left MUX", "MIC1", "MIC1 PGA"},
904*48e27874SAdam Thomson 	{"ADC1 Left MUX", "AUX1L", "AUX1L PGA"},
905*48e27874SAdam Thomson 
906*48e27874SAdam Thomson 	{"ADC1 Right MUX", "AUX1R", "AUX1R PGA"},
907*48e27874SAdam Thomson 	{"ADC1 Right MUX", "MIC2", "MIC2 PGA"},
908*48e27874SAdam Thomson 	{"ADC1 Right MUX", "MIC3", "MIC3 PGA"},
909*48e27874SAdam Thomson 
910*48e27874SAdam Thomson 	{"ADC2 Left MUX", "AUX1L", "AUX1L PGA"},
911*48e27874SAdam Thomson 	{"ADC2 Left MUX", "MIC1", "MIC1 PGA"},
912*48e27874SAdam Thomson 
913*48e27874SAdam Thomson 	{"ADC2 Right MUX", "AUX1R", "AUX1R PGA"},
914*48e27874SAdam Thomson 	{"ADC2 Right MUX", "MIC2", "MIC2 PGA"},
915*48e27874SAdam Thomson 	{"ADC2 Right MUX", "MIC3", "MIC3 PGA"},
916*48e27874SAdam Thomson 
917*48e27874SAdam Thomson 	{"ADC1L", NULL, "ADC1 Supply"},
918*48e27874SAdam Thomson 	{"ADC1R", NULL, "ADC1 Supply"},
919*48e27874SAdam Thomson 	{"ADC2L", NULL, "ADC2 Supply"},
920*48e27874SAdam Thomson 	{"ADC2R", NULL, "ADC2 Supply"},
921*48e27874SAdam Thomson 
922*48e27874SAdam Thomson 	{"ADC1L", NULL, "ADC1 Left MUX"},
923*48e27874SAdam Thomson 	{"ADC1R", NULL, "ADC1 Right MUX"},
924*48e27874SAdam Thomson 	{"ADC2L", NULL, "ADC2 Left MUX"},
925*48e27874SAdam Thomson 	{"ADC2R", NULL, "ADC2 Right MUX"},
926*48e27874SAdam Thomson 
927*48e27874SAdam Thomson 	{"AIFA Output", NULL, "ADC1L"},
928*48e27874SAdam Thomson 	{"AIFA Output", NULL, "ADC1R"},
929*48e27874SAdam Thomson 	{"AIFB Output", NULL, "ADC2L"},
930*48e27874SAdam Thomson 	{"AIFB Output", NULL, "ADC2R"},
931*48e27874SAdam Thomson 
932*48e27874SAdam Thomson 	{"HP Left MUX", "Enabled", "AIFA Input"},
933*48e27874SAdam Thomson 	{"HP Right MUX", "Enabled", "AIFA Input"},
934*48e27874SAdam Thomson 	{"Speaker MUX", "Enabled", "AIFB Input"},
935*48e27874SAdam Thomson 	{"LOUT2 MUX", "Enabled", "AIFB Input"},
936*48e27874SAdam Thomson 	{"LOUT4 MUX", "Enabled", "AIFB Input"},
937*48e27874SAdam Thomson 
938*48e27874SAdam Thomson 	{"DAC1L", NULL, "DAC1 CLK"},
939*48e27874SAdam Thomson 	{"DAC1R", NULL, "DAC1 CLK"},
940*48e27874SAdam Thomson 	{"DAC2L", NULL, "DAC2 CLK"},
941*48e27874SAdam Thomson 	{"DAC2R", NULL, "DAC2 CLK"},
942*48e27874SAdam Thomson 	{"DAC3", NULL, "DAC3 CLK"},
943*48e27874SAdam Thomson 
944*48e27874SAdam Thomson 	{"DAC1L", NULL, "HP Left MUX"},
945*48e27874SAdam Thomson 	{"DAC1R", NULL, "HP Right MUX"},
946*48e27874SAdam Thomson 	{"DAC2L", NULL, "Speaker MUX"},
947*48e27874SAdam Thomson 	{"DAC2R", NULL, "LOUT4 MUX"},
948*48e27874SAdam Thomson 	{"DAC3", NULL, "LOUT2 MUX"},
949*48e27874SAdam Thomson 
950*48e27874SAdam Thomson 	/* Output Pgas */
951*48e27874SAdam Thomson 	{"HP Left", NULL, "DAC1L"},
952*48e27874SAdam Thomson 	{"HP Right", NULL, "DAC1R"},
953*48e27874SAdam Thomson 	{"LIN3", NULL, "DAC2L"},
954*48e27874SAdam Thomson 	{"LIN4", NULL, "DAC2R"},
955*48e27874SAdam Thomson 	{"LIN2", NULL, "DAC3"},
956*48e27874SAdam Thomson 
957*48e27874SAdam Thomson 	/* Outputs */
958*48e27874SAdam Thomson 	{"ClassD", NULL, "LIN3"},
959*48e27874SAdam Thomson 	{"LOUTL", NULL, "LIN2"},
960*48e27874SAdam Thomson 	{"LOUTR", NULL, "LIN4"},
961*48e27874SAdam Thomson 	{"HPL", NULL, "HP Left"},
962*48e27874SAdam Thomson 	{"HPR", NULL, "HP Right"},
963*48e27874SAdam Thomson };
964*48e27874SAdam Thomson 
965*48e27874SAdam Thomson static int da732x_hw_params(struct snd_pcm_substream *substream,
966*48e27874SAdam Thomson 			    struct snd_pcm_hw_params *params,
967*48e27874SAdam Thomson 			    struct snd_soc_dai *dai)
968*48e27874SAdam Thomson {
969*48e27874SAdam Thomson 	struct snd_soc_codec *codec = dai->codec;
970*48e27874SAdam Thomson 	u32 aif = 0;
971*48e27874SAdam Thomson 	u32 reg_aif;
972*48e27874SAdam Thomson 	u32 fs;
973*48e27874SAdam Thomson 
974*48e27874SAdam Thomson 	reg_aif = dai->driver->base;
975*48e27874SAdam Thomson 
976*48e27874SAdam Thomson 	switch (params_format(params)) {
977*48e27874SAdam Thomson 	case SNDRV_PCM_FORMAT_S16_LE:
978*48e27874SAdam Thomson 		aif |= DA732X_AIF_WORD_16;
979*48e27874SAdam Thomson 		break;
980*48e27874SAdam Thomson 	case SNDRV_PCM_FORMAT_S20_3LE:
981*48e27874SAdam Thomson 		aif |= DA732X_AIF_WORD_20;
982*48e27874SAdam Thomson 		break;
983*48e27874SAdam Thomson 	case SNDRV_PCM_FORMAT_S24_LE:
984*48e27874SAdam Thomson 		aif |= DA732X_AIF_WORD_24;
985*48e27874SAdam Thomson 		break;
986*48e27874SAdam Thomson 	case SNDRV_PCM_FORMAT_S32_LE:
987*48e27874SAdam Thomson 		aif |= DA732X_AIF_WORD_32;
988*48e27874SAdam Thomson 		break;
989*48e27874SAdam Thomson 	default:
990*48e27874SAdam Thomson 		return -EINVAL;
991*48e27874SAdam Thomson 	}
992*48e27874SAdam Thomson 
993*48e27874SAdam Thomson 	switch (params_rate(params)) {
994*48e27874SAdam Thomson 	case 8000:
995*48e27874SAdam Thomson 		fs = DA732X_SR_8KHZ;
996*48e27874SAdam Thomson 		break;
997*48e27874SAdam Thomson 	case 11025:
998*48e27874SAdam Thomson 		fs = DA732X_SR_11_025KHZ;
999*48e27874SAdam Thomson 		break;
1000*48e27874SAdam Thomson 	case 12000:
1001*48e27874SAdam Thomson 		fs = DA732X_SR_12KHZ;
1002*48e27874SAdam Thomson 		break;
1003*48e27874SAdam Thomson 	case 16000:
1004*48e27874SAdam Thomson 		fs = DA732X_SR_16KHZ;
1005*48e27874SAdam Thomson 		break;
1006*48e27874SAdam Thomson 	case 22050:
1007*48e27874SAdam Thomson 		fs = DA732X_SR_22_05KHZ;
1008*48e27874SAdam Thomson 		break;
1009*48e27874SAdam Thomson 	case 24000:
1010*48e27874SAdam Thomson 		fs = DA732X_SR_24KHZ;
1011*48e27874SAdam Thomson 		break;
1012*48e27874SAdam Thomson 	case 32000:
1013*48e27874SAdam Thomson 		fs = DA732X_SR_32KHZ;
1014*48e27874SAdam Thomson 		break;
1015*48e27874SAdam Thomson 	case 44100:
1016*48e27874SAdam Thomson 		fs = DA732X_SR_44_1KHZ;
1017*48e27874SAdam Thomson 		break;
1018*48e27874SAdam Thomson 	case 48000:
1019*48e27874SAdam Thomson 		fs = DA732X_SR_48KHZ;
1020*48e27874SAdam Thomson 		break;
1021*48e27874SAdam Thomson 	case 88100:
1022*48e27874SAdam Thomson 		fs = DA732X_SR_88_1KHZ;
1023*48e27874SAdam Thomson 		break;
1024*48e27874SAdam Thomson 	case 96000:
1025*48e27874SAdam Thomson 		fs = DA732X_SR_96KHZ;
1026*48e27874SAdam Thomson 		break;
1027*48e27874SAdam Thomson 	default:
1028*48e27874SAdam Thomson 		return -EINVAL;
1029*48e27874SAdam Thomson 	}
1030*48e27874SAdam Thomson 
1031*48e27874SAdam Thomson 	snd_soc_update_bits(codec, reg_aif, DA732X_AIF_WORD_MASK, aif);
1032*48e27874SAdam Thomson 	snd_soc_update_bits(codec, DA732X_REG_CLK_CTRL, DA732X_SR1_MASK, fs);
1033*48e27874SAdam Thomson 
1034*48e27874SAdam Thomson 	return 0;
1035*48e27874SAdam Thomson }
1036*48e27874SAdam Thomson 
1037*48e27874SAdam Thomson static int da732x_set_dai_fmt(struct snd_soc_dai *dai, u32 fmt)
1038*48e27874SAdam Thomson {
1039*48e27874SAdam Thomson 	struct snd_soc_codec *codec = dai->codec;
1040*48e27874SAdam Thomson 	u32 aif_mclk, pc_count;
1041*48e27874SAdam Thomson 	u32 reg_aif1, aif1;
1042*48e27874SAdam Thomson 	u32 reg_aif3, aif3;
1043*48e27874SAdam Thomson 
1044*48e27874SAdam Thomson 	switch (dai->id) {
1045*48e27874SAdam Thomson 	case DA732X_DAI_ID1:
1046*48e27874SAdam Thomson 		reg_aif1 = DA732X_REG_AIFA1;
1047*48e27874SAdam Thomson 		reg_aif3 = DA732X_REG_AIFA3;
1048*48e27874SAdam Thomson 		pc_count = DA732X_PC_PULSE_AIFA | DA732X_PC_RESYNC_NOT_AUT |
1049*48e27874SAdam Thomson 			   DA732X_PC_SAME;
1050*48e27874SAdam Thomson 		break;
1051*48e27874SAdam Thomson 	case DA732X_DAI_ID2:
1052*48e27874SAdam Thomson 		reg_aif1 = DA732X_REG_AIFB1;
1053*48e27874SAdam Thomson 		reg_aif3 = DA732X_REG_AIFB3;
1054*48e27874SAdam Thomson 		pc_count = DA732X_PC_PULSE_AIFB | DA732X_PC_RESYNC_NOT_AUT |
1055*48e27874SAdam Thomson 			   DA732X_PC_SAME;
1056*48e27874SAdam Thomson 		break;
1057*48e27874SAdam Thomson 	default:
1058*48e27874SAdam Thomson 		return -EINVAL;
1059*48e27874SAdam Thomson 	}
1060*48e27874SAdam Thomson 
1061*48e27874SAdam Thomson 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1062*48e27874SAdam Thomson 	case SND_SOC_DAIFMT_CBS_CFS:
1063*48e27874SAdam Thomson 		aif1 = DA732X_AIF_SLAVE;
1064*48e27874SAdam Thomson 		aif_mclk = DA732X_AIFM_FRAME_64 | DA732X_AIFM_SRC_SEL_AIFA;
1065*48e27874SAdam Thomson 		break;
1066*48e27874SAdam Thomson 	case SND_SOC_DAIFMT_CBM_CFM:
1067*48e27874SAdam Thomson 		aif1 = DA732X_AIF_CLK_FROM_SRC;
1068*48e27874SAdam Thomson 		aif_mclk = DA732X_CLK_GENERATION_AIF_A;
1069*48e27874SAdam Thomson 		break;
1070*48e27874SAdam Thomson 	default:
1071*48e27874SAdam Thomson 		return -EINVAL;
1072*48e27874SAdam Thomson 	}
1073*48e27874SAdam Thomson 
1074*48e27874SAdam Thomson 	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1075*48e27874SAdam Thomson 	case SND_SOC_DAIFMT_I2S:
1076*48e27874SAdam Thomson 		aif3 = DA732X_AIF_I2S_MODE;
1077*48e27874SAdam Thomson 		break;
1078*48e27874SAdam Thomson 	case SND_SOC_DAIFMT_RIGHT_J:
1079*48e27874SAdam Thomson 		aif3 = DA732X_AIF_RIGHT_J_MODE;
1080*48e27874SAdam Thomson 		break;
1081*48e27874SAdam Thomson 	case SND_SOC_DAIFMT_LEFT_J:
1082*48e27874SAdam Thomson 		aif3 = DA732X_AIF_LEFT_J_MODE;
1083*48e27874SAdam Thomson 		break;
1084*48e27874SAdam Thomson 	case SND_SOC_DAIFMT_DSP_B:
1085*48e27874SAdam Thomson 		aif3 = DA732X_AIF_DSP_MODE;
1086*48e27874SAdam Thomson 		break;
1087*48e27874SAdam Thomson 	default:
1088*48e27874SAdam Thomson 		return -EINVAL;
1089*48e27874SAdam Thomson 	}
1090*48e27874SAdam Thomson 
1091*48e27874SAdam Thomson 	/* Clock inversion */
1092*48e27874SAdam Thomson 	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1093*48e27874SAdam Thomson 	case SND_SOC_DAIFMT_DSP_B:
1094*48e27874SAdam Thomson 		switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1095*48e27874SAdam Thomson 		case SND_SOC_DAIFMT_NB_NF:
1096*48e27874SAdam Thomson 			break;
1097*48e27874SAdam Thomson 		case SND_SOC_DAIFMT_IB_NF:
1098*48e27874SAdam Thomson 			aif3 |= DA732X_AIF_BCLK_INV;
1099*48e27874SAdam Thomson 			break;
1100*48e27874SAdam Thomson 		default:
1101*48e27874SAdam Thomson 			return -EINVAL;
1102*48e27874SAdam Thomson 		}
1103*48e27874SAdam Thomson 		break;
1104*48e27874SAdam Thomson 	case SND_SOC_DAIFMT_I2S:
1105*48e27874SAdam Thomson 	case SND_SOC_DAIFMT_RIGHT_J:
1106*48e27874SAdam Thomson 	case SND_SOC_DAIFMT_LEFT_J:
1107*48e27874SAdam Thomson 		switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1108*48e27874SAdam Thomson 		case SND_SOC_DAIFMT_NB_NF:
1109*48e27874SAdam Thomson 			break;
1110*48e27874SAdam Thomson 		case SND_SOC_DAIFMT_IB_IF:
1111*48e27874SAdam Thomson 			aif3 |= DA732X_AIF_BCLK_INV | DA732X_AIF_WCLK_INV;
1112*48e27874SAdam Thomson 			break;
1113*48e27874SAdam Thomson 		case SND_SOC_DAIFMT_IB_NF:
1114*48e27874SAdam Thomson 			aif3 |= DA732X_AIF_BCLK_INV;
1115*48e27874SAdam Thomson 			break;
1116*48e27874SAdam Thomson 		case SND_SOC_DAIFMT_NB_IF:
1117*48e27874SAdam Thomson 			aif3 |= DA732X_AIF_WCLK_INV;
1118*48e27874SAdam Thomson 			break;
1119*48e27874SAdam Thomson 		default:
1120*48e27874SAdam Thomson 			return -EINVAL;
1121*48e27874SAdam Thomson 		}
1122*48e27874SAdam Thomson 		break;
1123*48e27874SAdam Thomson 	default:
1124*48e27874SAdam Thomson 		return -EINVAL;
1125*48e27874SAdam Thomson 	}
1126*48e27874SAdam Thomson 
1127*48e27874SAdam Thomson 	snd_soc_write(codec, DA732X_REG_AIF_MCLK, aif_mclk);
1128*48e27874SAdam Thomson 	snd_soc_update_bits(codec, reg_aif1, DA732X_AIF1_CLK_MASK, aif1);
1129*48e27874SAdam Thomson 	snd_soc_update_bits(codec, reg_aif3, DA732X_AIF_BCLK_INV |
1130*48e27874SAdam Thomson 			    DA732X_AIF_WCLK_INV | DA732X_AIF_MODE_MASK, aif3);
1131*48e27874SAdam Thomson 	snd_soc_write(codec, DA732X_REG_PC_CTRL, pc_count);
1132*48e27874SAdam Thomson 
1133*48e27874SAdam Thomson 	return 0;
1134*48e27874SAdam Thomson }
1135*48e27874SAdam Thomson 
1136*48e27874SAdam Thomson 
1137*48e27874SAdam Thomson 
1138*48e27874SAdam Thomson static int da732x_set_dai_pll(struct snd_soc_codec *codec, int pll_id,
1139*48e27874SAdam Thomson 			      int source, unsigned int freq_in,
1140*48e27874SAdam Thomson 			      unsigned int freq_out)
1141*48e27874SAdam Thomson {
1142*48e27874SAdam Thomson 	struct da732x_priv *da732x = snd_soc_codec_get_drvdata(codec);
1143*48e27874SAdam Thomson 	int fref, indiv;
1144*48e27874SAdam Thomson 	u8 div_lo, div_mid, div_hi;
1145*48e27874SAdam Thomson 	u64 frac_div;
1146*48e27874SAdam Thomson 
1147*48e27874SAdam Thomson 	/* Disable PLL */
1148*48e27874SAdam Thomson 	if (freq_out == 0) {
1149*48e27874SAdam Thomson 		snd_soc_update_bits(codec, DA732X_REG_PLL_CTRL,
1150*48e27874SAdam Thomson 				    DA732X_PLL_EN, 0);
1151*48e27874SAdam Thomson 		da732x->pll_en = false;
1152*48e27874SAdam Thomson 		return 0;
1153*48e27874SAdam Thomson 	}
1154*48e27874SAdam Thomson 
1155*48e27874SAdam Thomson 	if (da732x->pll_en)
1156*48e27874SAdam Thomson 		return -EBUSY;
1157*48e27874SAdam Thomson 
1158*48e27874SAdam Thomson 	if (source == DA732X_SRCCLK_MCLK) {
1159*48e27874SAdam Thomson 		/* Validate Sysclk rate */
1160*48e27874SAdam Thomson 		switch (da732x->sysclk) {
1161*48e27874SAdam Thomson 		case 11290000:
1162*48e27874SAdam Thomson 		case 12288000:
1163*48e27874SAdam Thomson 		case 22580000:
1164*48e27874SAdam Thomson 		case 24576000:
1165*48e27874SAdam Thomson 		case 45160000:
1166*48e27874SAdam Thomson 		case 49152000:
1167*48e27874SAdam Thomson 			snd_soc_write(codec, DA732X_REG_PLL_CTRL,
1168*48e27874SAdam Thomson 				      DA732X_PLL_BYPASS);
1169*48e27874SAdam Thomson 			return 0;
1170*48e27874SAdam Thomson 		default:
1171*48e27874SAdam Thomson 			dev_err(codec->dev,
1172*48e27874SAdam Thomson 				"Cannot use PLL Bypass, invalid SYSCLK rate\n");
1173*48e27874SAdam Thomson 			return -EINVAL;
1174*48e27874SAdam Thomson 		}
1175*48e27874SAdam Thomson 	}
1176*48e27874SAdam Thomson 
1177*48e27874SAdam Thomson 	indiv = da732x_get_input_div(codec, da732x->sysclk);
1178*48e27874SAdam Thomson 	if (indiv < 0)
1179*48e27874SAdam Thomson 		return indiv;
1180*48e27874SAdam Thomson 
1181*48e27874SAdam Thomson 	fref = (da732x->sysclk / indiv);
1182*48e27874SAdam Thomson 	div_hi = freq_out / fref;
1183*48e27874SAdam Thomson 	frac_div = (u64)(freq_out % fref) * 8192ULL;
1184*48e27874SAdam Thomson 	do_div(frac_div, fref);
1185*48e27874SAdam Thomson 	div_mid = (frac_div >> DA732X_1BYTE_SHIFT) & DA732X_U8_MASK;
1186*48e27874SAdam Thomson 	div_lo = (frac_div) & DA732X_U8_MASK;
1187*48e27874SAdam Thomson 
1188*48e27874SAdam Thomson 	snd_soc_write(codec, DA732X_REG_PLL_DIV_LO, div_lo);
1189*48e27874SAdam Thomson 	snd_soc_write(codec, DA732X_REG_PLL_DIV_MID, div_mid);
1190*48e27874SAdam Thomson 	snd_soc_write(codec, DA732X_REG_PLL_DIV_HI, div_hi);
1191*48e27874SAdam Thomson 
1192*48e27874SAdam Thomson 	snd_soc_update_bits(codec, DA732X_REG_PLL_CTRL, DA732X_PLL_EN,
1193*48e27874SAdam Thomson 			    DA732X_PLL_EN);
1194*48e27874SAdam Thomson 
1195*48e27874SAdam Thomson 	da732x->pll_en = true;
1196*48e27874SAdam Thomson 
1197*48e27874SAdam Thomson 	return 0;
1198*48e27874SAdam Thomson }
1199*48e27874SAdam Thomson 
1200*48e27874SAdam Thomson static int da732x_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
1201*48e27874SAdam Thomson 				 unsigned int freq, int dir)
1202*48e27874SAdam Thomson {
1203*48e27874SAdam Thomson 	struct snd_soc_codec *codec = dai->codec;
1204*48e27874SAdam Thomson 	struct da732x_priv *da732x = snd_soc_codec_get_drvdata(codec);
1205*48e27874SAdam Thomson 
1206*48e27874SAdam Thomson 	da732x->sysclk = freq;
1207*48e27874SAdam Thomson 
1208*48e27874SAdam Thomson 	return 0;
1209*48e27874SAdam Thomson }
1210*48e27874SAdam Thomson 
1211*48e27874SAdam Thomson #define DA732X_RATES	SNDRV_PCM_RATE_8000_96000
1212*48e27874SAdam Thomson 
1213*48e27874SAdam Thomson #define	DA732X_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
1214*48e27874SAdam Thomson 			SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
1215*48e27874SAdam Thomson 
1216*48e27874SAdam Thomson static struct snd_soc_dai_ops da732x_dai1_ops = {
1217*48e27874SAdam Thomson 	.hw_params	= da732x_hw_params,
1218*48e27874SAdam Thomson 	.set_fmt	= da732x_set_dai_fmt,
1219*48e27874SAdam Thomson 	.set_sysclk	= da732x_set_dai_sysclk,
1220*48e27874SAdam Thomson };
1221*48e27874SAdam Thomson 
1222*48e27874SAdam Thomson static struct snd_soc_dai_ops da732x_dai2_ops = {
1223*48e27874SAdam Thomson 	.hw_params	= da732x_hw_params,
1224*48e27874SAdam Thomson 	.set_fmt	= da732x_set_dai_fmt,
1225*48e27874SAdam Thomson 	.set_sysclk	= da732x_set_dai_sysclk,
1226*48e27874SAdam Thomson };
1227*48e27874SAdam Thomson 
1228*48e27874SAdam Thomson static struct snd_soc_dai_driver da732x_dai[] = {
1229*48e27874SAdam Thomson 	{
1230*48e27874SAdam Thomson 		.name	= "DA732X_AIFA",
1231*48e27874SAdam Thomson 		.id	= DA732X_DAI_ID1,
1232*48e27874SAdam Thomson 		.base	= DA732X_REG_AIFA1,
1233*48e27874SAdam Thomson 		.playback = {
1234*48e27874SAdam Thomson 			.stream_name = "AIFA Playback",
1235*48e27874SAdam Thomson 			.channels_min = 1,
1236*48e27874SAdam Thomson 			.channels_max = 2,
1237*48e27874SAdam Thomson 			.rates = DA732X_RATES,
1238*48e27874SAdam Thomson 			.formats = DA732X_FORMATS,
1239*48e27874SAdam Thomson 		},
1240*48e27874SAdam Thomson 		.capture = {
1241*48e27874SAdam Thomson 			.stream_name = "AIFA Capture",
1242*48e27874SAdam Thomson 			.channels_min = 1,
1243*48e27874SAdam Thomson 			.channels_max = 2,
1244*48e27874SAdam Thomson 			.rates = DA732X_RATES,
1245*48e27874SAdam Thomson 			.formats = DA732X_FORMATS,
1246*48e27874SAdam Thomson 		},
1247*48e27874SAdam Thomson 		.ops = &da732x_dai1_ops,
1248*48e27874SAdam Thomson 	},
1249*48e27874SAdam Thomson 	{
1250*48e27874SAdam Thomson 		.name	= "DA732X_AIFB",
1251*48e27874SAdam Thomson 		.id	= DA732X_DAI_ID2,
1252*48e27874SAdam Thomson 		.base	= DA732X_REG_AIFB1,
1253*48e27874SAdam Thomson 		.playback = {
1254*48e27874SAdam Thomson 			.stream_name = "AIFB Playback",
1255*48e27874SAdam Thomson 			.channels_min = 1,
1256*48e27874SAdam Thomson 			.channels_max = 2,
1257*48e27874SAdam Thomson 			.rates = DA732X_RATES,
1258*48e27874SAdam Thomson 			.formats = DA732X_FORMATS,
1259*48e27874SAdam Thomson 		},
1260*48e27874SAdam Thomson 		.capture = {
1261*48e27874SAdam Thomson 			.stream_name = "AIFB Capture",
1262*48e27874SAdam Thomson 			.channels_min = 1,
1263*48e27874SAdam Thomson 			.channels_max = 2,
1264*48e27874SAdam Thomson 			.rates = DA732X_RATES,
1265*48e27874SAdam Thomson 			.formats = DA732X_FORMATS,
1266*48e27874SAdam Thomson 		},
1267*48e27874SAdam Thomson 		.ops = &da732x_dai2_ops,
1268*48e27874SAdam Thomson 	},
1269*48e27874SAdam Thomson };
1270*48e27874SAdam Thomson 
1271*48e27874SAdam Thomson static const struct regmap_config da732x_regmap = {
1272*48e27874SAdam Thomson 	.reg_bits		= 8,
1273*48e27874SAdam Thomson 	.val_bits		= 8,
1274*48e27874SAdam Thomson 
1275*48e27874SAdam Thomson 	.max_register		= DA732X_MAX_REG,
1276*48e27874SAdam Thomson 	.reg_defaults		= da732x_reg_cache,
1277*48e27874SAdam Thomson 	.num_reg_defaults	= ARRAY_SIZE(da732x_reg_cache),
1278*48e27874SAdam Thomson 	.cache_type		= REGCACHE_RBTREE,
1279*48e27874SAdam Thomson };
1280*48e27874SAdam Thomson 
1281*48e27874SAdam Thomson 
1282*48e27874SAdam Thomson static void da732x_dac_offset_adjust(struct snd_soc_codec *codec)
1283*48e27874SAdam Thomson {
1284*48e27874SAdam Thomson 	u8 offset[DA732X_HP_DACS];
1285*48e27874SAdam Thomson 	u8 sign[DA732X_HP_DACS];
1286*48e27874SAdam Thomson 	u8 step = DA732X_DAC_OFFSET_STEP;
1287*48e27874SAdam Thomson 
1288*48e27874SAdam Thomson 	/* Initialize DAC offset calibration circuits and registers */
1289*48e27874SAdam Thomson 	snd_soc_write(codec, DA732X_REG_HPL_DAC_OFFSET,
1290*48e27874SAdam Thomson 		      DA732X_HP_DAC_OFFSET_TRIM_VAL);
1291*48e27874SAdam Thomson 	snd_soc_write(codec, DA732X_REG_HPR_DAC_OFFSET,
1292*48e27874SAdam Thomson 		      DA732X_HP_DAC_OFFSET_TRIM_VAL);
1293*48e27874SAdam Thomson 	snd_soc_write(codec, DA732X_REG_HPL_DAC_OFF_CNTL,
1294*48e27874SAdam Thomson 		      DA732X_HP_DAC_OFF_CALIBRATION |
1295*48e27874SAdam Thomson 		      DA732X_HP_DAC_OFF_SCALE_STEPS);
1296*48e27874SAdam Thomson 	snd_soc_write(codec, DA732X_REG_HPR_DAC_OFF_CNTL,
1297*48e27874SAdam Thomson 		      DA732X_HP_DAC_OFF_CALIBRATION |
1298*48e27874SAdam Thomson 		      DA732X_HP_DAC_OFF_SCALE_STEPS);
1299*48e27874SAdam Thomson 
1300*48e27874SAdam Thomson 	/* Wait for voltage stabilization */
1301*48e27874SAdam Thomson 	msleep(DA732X_WAIT_FOR_STABILIZATION);
1302*48e27874SAdam Thomson 
1303*48e27874SAdam Thomson 	/* Check DAC offset sign */
1304*48e27874SAdam Thomson 	sign[DA732X_HPL_DAC] = (codec->hw_read(codec, DA732X_REG_HPL_DAC_OFF_CNTL) &
1305*48e27874SAdam Thomson 				DA732X_HP_DAC_OFF_CNTL_COMPO);
1306*48e27874SAdam Thomson 	sign[DA732X_HPR_DAC] = (codec->hw_read(codec, DA732X_REG_HPR_DAC_OFF_CNTL) &
1307*48e27874SAdam Thomson 				DA732X_HP_DAC_OFF_CNTL_COMPO);
1308*48e27874SAdam Thomson 
1309*48e27874SAdam Thomson 	/* Binary search DAC offset values (both channels at once) */
1310*48e27874SAdam Thomson 	offset[DA732X_HPL_DAC] = sign[DA732X_HPL_DAC] << DA732X_HP_DAC_COMPO_SHIFT;
1311*48e27874SAdam Thomson 	offset[DA732X_HPR_DAC] = sign[DA732X_HPR_DAC] << DA732X_HP_DAC_COMPO_SHIFT;
1312*48e27874SAdam Thomson 
1313*48e27874SAdam Thomson 	do {
1314*48e27874SAdam Thomson 		offset[DA732X_HPL_DAC] |= step;
1315*48e27874SAdam Thomson 		offset[DA732X_HPR_DAC] |= step;
1316*48e27874SAdam Thomson 		snd_soc_write(codec, DA732X_REG_HPL_DAC_OFFSET,
1317*48e27874SAdam Thomson 			      ~offset[DA732X_HPL_DAC] & DA732X_HP_DAC_OFF_MASK);
1318*48e27874SAdam Thomson 		snd_soc_write(codec, DA732X_REG_HPR_DAC_OFFSET,
1319*48e27874SAdam Thomson 			      ~offset[DA732X_HPR_DAC] & DA732X_HP_DAC_OFF_MASK);
1320*48e27874SAdam Thomson 
1321*48e27874SAdam Thomson 		msleep(DA732X_WAIT_FOR_STABILIZATION);
1322*48e27874SAdam Thomson 
1323*48e27874SAdam Thomson 		if ((codec->hw_read(codec, DA732X_REG_HPL_DAC_OFF_CNTL) &
1324*48e27874SAdam Thomson 		     DA732X_HP_DAC_OFF_CNTL_COMPO) ^ sign[DA732X_HPL_DAC])
1325*48e27874SAdam Thomson 			offset[DA732X_HPL_DAC] &= ~step;
1326*48e27874SAdam Thomson 		if ((codec->hw_read(codec, DA732X_REG_HPR_DAC_OFF_CNTL) &
1327*48e27874SAdam Thomson 		     DA732X_HP_DAC_OFF_CNTL_COMPO) ^ sign[DA732X_HPR_DAC])
1328*48e27874SAdam Thomson 			offset[DA732X_HPR_DAC] &= ~step;
1329*48e27874SAdam Thomson 
1330*48e27874SAdam Thomson 		step >>= 1;
1331*48e27874SAdam Thomson 	} while (step);
1332*48e27874SAdam Thomson 
1333*48e27874SAdam Thomson 	/* Write final DAC offsets to registers */
1334*48e27874SAdam Thomson 	snd_soc_write(codec, DA732X_REG_HPL_DAC_OFFSET,
1335*48e27874SAdam Thomson 		      ~offset[DA732X_HPL_DAC] &	DA732X_HP_DAC_OFF_MASK);
1336*48e27874SAdam Thomson 	snd_soc_write(codec, DA732X_REG_HPR_DAC_OFFSET,
1337*48e27874SAdam Thomson 		      ~offset[DA732X_HPR_DAC] &	DA732X_HP_DAC_OFF_MASK);
1338*48e27874SAdam Thomson 
1339*48e27874SAdam Thomson 	/* End DAC calibration mode */
1340*48e27874SAdam Thomson 	snd_soc_write(codec, DA732X_REG_HPL_DAC_OFF_CNTL,
1341*48e27874SAdam Thomson 		DA732X_HP_DAC_OFF_SCALE_STEPS);
1342*48e27874SAdam Thomson 	snd_soc_write(codec, DA732X_REG_HPR_DAC_OFF_CNTL,
1343*48e27874SAdam Thomson 		DA732X_HP_DAC_OFF_SCALE_STEPS);
1344*48e27874SAdam Thomson }
1345*48e27874SAdam Thomson 
1346*48e27874SAdam Thomson static void da732x_output_offset_adjust(struct snd_soc_codec *codec)
1347*48e27874SAdam Thomson {
1348*48e27874SAdam Thomson 	u8 offset[DA732X_HP_AMPS];
1349*48e27874SAdam Thomson 	u8 sign[DA732X_HP_AMPS];
1350*48e27874SAdam Thomson 	u8 step = DA732X_OUTPUT_OFFSET_STEP;
1351*48e27874SAdam Thomson 
1352*48e27874SAdam Thomson 	offset[DA732X_HPL_AMP] = DA732X_HP_OUT_TRIM_VAL;
1353*48e27874SAdam Thomson 	offset[DA732X_HPR_AMP] = DA732X_HP_OUT_TRIM_VAL;
1354*48e27874SAdam Thomson 
1355*48e27874SAdam Thomson 	/* Initialize output offset calibration circuits and registers  */
1356*48e27874SAdam Thomson 	snd_soc_write(codec, DA732X_REG_HPL_OUT_OFFSET, DA732X_HP_OUT_TRIM_VAL);
1357*48e27874SAdam Thomson 	snd_soc_write(codec, DA732X_REG_HPR_OUT_OFFSET, DA732X_HP_OUT_TRIM_VAL);
1358*48e27874SAdam Thomson 	snd_soc_write(codec, DA732X_REG_HPL,
1359*48e27874SAdam Thomson 		      DA732X_HP_OUT_COMP | DA732X_HP_OUT_EN);
1360*48e27874SAdam Thomson 	snd_soc_write(codec, DA732X_REG_HPR,
1361*48e27874SAdam Thomson 		      DA732X_HP_OUT_COMP | DA732X_HP_OUT_EN);
1362*48e27874SAdam Thomson 
1363*48e27874SAdam Thomson 	/* Wait for voltage stabilization */
1364*48e27874SAdam Thomson 	msleep(DA732X_WAIT_FOR_STABILIZATION);
1365*48e27874SAdam Thomson 
1366*48e27874SAdam Thomson 	/* Check output offset sign */
1367*48e27874SAdam Thomson 	sign[DA732X_HPL_AMP] = codec->hw_read(codec, DA732X_REG_HPL) &
1368*48e27874SAdam Thomson 			       DA732X_HP_OUT_COMPO;
1369*48e27874SAdam Thomson 	sign[DA732X_HPR_AMP] = codec->hw_read(codec, DA732X_REG_HPR) &
1370*48e27874SAdam Thomson 			       DA732X_HP_OUT_COMPO;
1371*48e27874SAdam Thomson 
1372*48e27874SAdam Thomson 	snd_soc_write(codec, DA732X_REG_HPL, DA732X_HP_OUT_COMP |
1373*48e27874SAdam Thomson 		      (sign[DA732X_HPL_AMP] >> DA732X_HP_OUT_COMPO_SHIFT) |
1374*48e27874SAdam Thomson 		      DA732X_HP_OUT_EN);
1375*48e27874SAdam Thomson 	snd_soc_write(codec, DA732X_REG_HPR, DA732X_HP_OUT_COMP |
1376*48e27874SAdam Thomson 		      (sign[DA732X_HPR_AMP] >> DA732X_HP_OUT_COMPO_SHIFT) |
1377*48e27874SAdam Thomson 		      DA732X_HP_OUT_EN);
1378*48e27874SAdam Thomson 
1379*48e27874SAdam Thomson 	/* Binary search output offset values (both channels at once) */
1380*48e27874SAdam Thomson 	do {
1381*48e27874SAdam Thomson 		offset[DA732X_HPL_AMP] |= step;
1382*48e27874SAdam Thomson 		offset[DA732X_HPR_AMP] |= step;
1383*48e27874SAdam Thomson 		snd_soc_write(codec, DA732X_REG_HPL_OUT_OFFSET,
1384*48e27874SAdam Thomson 			      offset[DA732X_HPL_AMP]);
1385*48e27874SAdam Thomson 		snd_soc_write(codec, DA732X_REG_HPR_OUT_OFFSET,
1386*48e27874SAdam Thomson 			      offset[DA732X_HPR_AMP]);
1387*48e27874SAdam Thomson 
1388*48e27874SAdam Thomson 		msleep(DA732X_WAIT_FOR_STABILIZATION);
1389*48e27874SAdam Thomson 
1390*48e27874SAdam Thomson 		if ((codec->hw_read(codec, DA732X_REG_HPL) &
1391*48e27874SAdam Thomson 		     DA732X_HP_OUT_COMPO) ^ sign[DA732X_HPL_AMP])
1392*48e27874SAdam Thomson 			offset[DA732X_HPL_AMP] &= ~step;
1393*48e27874SAdam Thomson 		if ((codec->hw_read(codec, DA732X_REG_HPR) &
1394*48e27874SAdam Thomson 		     DA732X_HP_OUT_COMPO) ^ sign[DA732X_HPR_AMP])
1395*48e27874SAdam Thomson 			offset[DA732X_HPR_AMP] &= ~step;
1396*48e27874SAdam Thomson 
1397*48e27874SAdam Thomson 		step >>= 1;
1398*48e27874SAdam Thomson 	} while (step);
1399*48e27874SAdam Thomson 
1400*48e27874SAdam Thomson 	/* Write final DAC offsets to registers */
1401*48e27874SAdam Thomson 	snd_soc_write(codec, DA732X_REG_HPL_OUT_OFFSET, offset[DA732X_HPL_AMP]);
1402*48e27874SAdam Thomson 	snd_soc_write(codec, DA732X_REG_HPR_OUT_OFFSET, offset[DA732X_HPR_AMP]);
1403*48e27874SAdam Thomson }
1404*48e27874SAdam Thomson 
1405*48e27874SAdam Thomson static void da732x_hp_dc_offset_cancellation(struct snd_soc_codec *codec)
1406*48e27874SAdam Thomson {
1407*48e27874SAdam Thomson 	/* Make sure that we have Soft Mute enabled */
1408*48e27874SAdam Thomson 	snd_soc_write(codec, DA732X_REG_DAC1_SOFTMUTE, DA732X_SOFTMUTE_EN |
1409*48e27874SAdam Thomson 		      DA732X_GAIN_RAMPED | DA732X_16_SAMPLES);
1410*48e27874SAdam Thomson 	snd_soc_write(codec, DA732X_REG_DAC1_SEL, DA732X_DACL_EN |
1411*48e27874SAdam Thomson 		      DA732X_DACR_EN | DA732X_DACL_SDM | DA732X_DACR_SDM |
1412*48e27874SAdam Thomson 		      DA732X_DACL_MUTE | DA732X_DACR_MUTE);
1413*48e27874SAdam Thomson 	snd_soc_write(codec, DA732X_REG_HPL, DA732X_HP_OUT_DAC_EN |
1414*48e27874SAdam Thomson 		      DA732X_HP_OUT_MUTE | DA732X_HP_OUT_EN);
1415*48e27874SAdam Thomson 	snd_soc_write(codec, DA732X_REG_HPR, DA732X_HP_OUT_EN |
1416*48e27874SAdam Thomson 		      DA732X_HP_OUT_MUTE | DA732X_HP_OUT_DAC_EN);
1417*48e27874SAdam Thomson 
1418*48e27874SAdam Thomson 	da732x_dac_offset_adjust(codec);
1419*48e27874SAdam Thomson 	da732x_output_offset_adjust(codec);
1420*48e27874SAdam Thomson 
1421*48e27874SAdam Thomson 	snd_soc_write(codec, DA732X_REG_DAC1_SEL, DA732X_DACS_DIS);
1422*48e27874SAdam Thomson 	snd_soc_write(codec, DA732X_REG_HPL, DA732X_HP_DIS);
1423*48e27874SAdam Thomson 	snd_soc_write(codec, DA732X_REG_HPR, DA732X_HP_DIS);
1424*48e27874SAdam Thomson }
1425*48e27874SAdam Thomson 
1426*48e27874SAdam Thomson static int da732x_set_bias_level(struct snd_soc_codec *codec,
1427*48e27874SAdam Thomson 				 enum snd_soc_bias_level level)
1428*48e27874SAdam Thomson {
1429*48e27874SAdam Thomson 	struct da732x_priv *da732x = snd_soc_codec_get_drvdata(codec);
1430*48e27874SAdam Thomson 
1431*48e27874SAdam Thomson 	switch (level) {
1432*48e27874SAdam Thomson 	case SND_SOC_BIAS_ON:
1433*48e27874SAdam Thomson 		snd_soc_update_bits(codec, DA732X_REG_BIAS_EN,
1434*48e27874SAdam Thomson 				    DA732X_BIAS_BOOST_MASK,
1435*48e27874SAdam Thomson 				    DA732X_BIAS_BOOST_100PC);
1436*48e27874SAdam Thomson 		break;
1437*48e27874SAdam Thomson 	case SND_SOC_BIAS_PREPARE:
1438*48e27874SAdam Thomson 		break;
1439*48e27874SAdam Thomson 	case SND_SOC_BIAS_STANDBY:
1440*48e27874SAdam Thomson 		if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
1441*48e27874SAdam Thomson 			/* Init Codec */
1442*48e27874SAdam Thomson 			snd_soc_write(codec, DA732X_REG_REF1,
1443*48e27874SAdam Thomson 				      DA732X_VMID_FASTCHG);
1444*48e27874SAdam Thomson 			snd_soc_write(codec, DA732X_REG_BIAS_EN,
1445*48e27874SAdam Thomson 				      DA732X_BIAS_EN);
1446*48e27874SAdam Thomson 
1447*48e27874SAdam Thomson 			mdelay(DA732X_STARTUP_DELAY);
1448*48e27874SAdam Thomson 
1449*48e27874SAdam Thomson 			/* Disable Fast Charge and enable DAC ref voltage */
1450*48e27874SAdam Thomson 			snd_soc_write(codec, DA732X_REG_REF1,
1451*48e27874SAdam Thomson 				      DA732X_REFBUFX2_EN);
1452*48e27874SAdam Thomson 
1453*48e27874SAdam Thomson 			/* Enable bypass DSP routing */
1454*48e27874SAdam Thomson 			snd_soc_write(codec, DA732X_REG_DATA_ROUTE,
1455*48e27874SAdam Thomson 				      DA732X_BYPASS_DSP);
1456*48e27874SAdam Thomson 
1457*48e27874SAdam Thomson 			/* Enable Digital subsystem */
1458*48e27874SAdam Thomson 			snd_soc_write(codec, DA732X_REG_DSP_CTRL,
1459*48e27874SAdam Thomson 				      DA732X_DIGITAL_EN);
1460*48e27874SAdam Thomson 
1461*48e27874SAdam Thomson 			snd_soc_write(codec, DA732X_REG_SPARE1_OUT,
1462*48e27874SAdam Thomson 				      DA732X_HP_DRIVER_EN |
1463*48e27874SAdam Thomson 				      DA732X_HP_GATE_LOW |
1464*48e27874SAdam Thomson 				      DA732X_HP_LOOP_GAIN_CTRL);
1465*48e27874SAdam Thomson 			snd_soc_write(codec, DA732X_REG_HP_LIN1_GNDSEL,
1466*48e27874SAdam Thomson 				      DA732X_HP_OUT_GNDSEL);
1467*48e27874SAdam Thomson 
1468*48e27874SAdam Thomson 			da732x_set_charge_pump(codec, DA732X_ENABLE_CP);
1469*48e27874SAdam Thomson 
1470*48e27874SAdam Thomson 			snd_soc_write(codec, DA732X_REG_CLK_EN1,
1471*48e27874SAdam Thomson 			      DA732X_SYS3_CLK_EN | DA732X_PC_CLK_EN);
1472*48e27874SAdam Thomson 
1473*48e27874SAdam Thomson 			/* Enable Zero Crossing */
1474*48e27874SAdam Thomson 			snd_soc_write(codec, DA732X_REG_INP_ZC_EN,
1475*48e27874SAdam Thomson 				      DA732X_MIC1_PRE_ZC_EN |
1476*48e27874SAdam Thomson 				      DA732X_MIC1_ZC_EN |
1477*48e27874SAdam Thomson 				      DA732X_MIC2_PRE_ZC_EN |
1478*48e27874SAdam Thomson 				      DA732X_MIC2_ZC_EN |
1479*48e27874SAdam Thomson 				      DA732X_AUXL_ZC_EN |
1480*48e27874SAdam Thomson 				      DA732X_AUXR_ZC_EN |
1481*48e27874SAdam Thomson 				      DA732X_MIC3_PRE_ZC_EN |
1482*48e27874SAdam Thomson 				      DA732X_MIC3_ZC_EN);
1483*48e27874SAdam Thomson 			snd_soc_write(codec, DA732X_REG_OUT_ZC_EN,
1484*48e27874SAdam Thomson 				      DA732X_HPL_ZC_EN | DA732X_HPR_ZC_EN |
1485*48e27874SAdam Thomson 				      DA732X_LIN2_ZC_EN | DA732X_LIN3_ZC_EN |
1486*48e27874SAdam Thomson 				      DA732X_LIN4_ZC_EN);
1487*48e27874SAdam Thomson 
1488*48e27874SAdam Thomson 			da732x_hp_dc_offset_cancellation(codec);
1489*48e27874SAdam Thomson 
1490*48e27874SAdam Thomson 			regcache_cache_only(codec->control_data, false);
1491*48e27874SAdam Thomson 			regcache_sync(codec->control_data);
1492*48e27874SAdam Thomson 		} else {
1493*48e27874SAdam Thomson 			snd_soc_update_bits(codec, DA732X_REG_BIAS_EN,
1494*48e27874SAdam Thomson 					    DA732X_BIAS_BOOST_MASK,
1495*48e27874SAdam Thomson 					    DA732X_BIAS_BOOST_50PC);
1496*48e27874SAdam Thomson 			snd_soc_update_bits(codec, DA732X_REG_PLL_CTRL,
1497*48e27874SAdam Thomson 					    DA732X_PLL_EN, 0);
1498*48e27874SAdam Thomson 			da732x->pll_en = false;
1499*48e27874SAdam Thomson 		}
1500*48e27874SAdam Thomson 		break;
1501*48e27874SAdam Thomson 	case SND_SOC_BIAS_OFF:
1502*48e27874SAdam Thomson 		regcache_cache_only(codec->control_data, true);
1503*48e27874SAdam Thomson 		da732x_set_charge_pump(codec, DA732X_DISABLE_CP);
1504*48e27874SAdam Thomson 		snd_soc_update_bits(codec, DA732X_REG_BIAS_EN, DA732X_BIAS_EN,
1505*48e27874SAdam Thomson 				    DA732X_BIAS_DIS);
1506*48e27874SAdam Thomson 		da732x->pll_en = false;
1507*48e27874SAdam Thomson 		break;
1508*48e27874SAdam Thomson 	}
1509*48e27874SAdam Thomson 
1510*48e27874SAdam Thomson 	codec->dapm.bias_level = level;
1511*48e27874SAdam Thomson 
1512*48e27874SAdam Thomson 	return 0;
1513*48e27874SAdam Thomson }
1514*48e27874SAdam Thomson 
1515*48e27874SAdam Thomson static int da732x_probe(struct snd_soc_codec *codec)
1516*48e27874SAdam Thomson {
1517*48e27874SAdam Thomson 	struct da732x_priv *da732x = snd_soc_codec_get_drvdata(codec);
1518*48e27874SAdam Thomson 	struct snd_soc_dapm_context *dapm = &codec->dapm;
1519*48e27874SAdam Thomson 	int ret = 0;
1520*48e27874SAdam Thomson 
1521*48e27874SAdam Thomson 	da732x->codec = codec;
1522*48e27874SAdam Thomson 
1523*48e27874SAdam Thomson 	dapm->idle_bias_off = false;
1524*48e27874SAdam Thomson 
1525*48e27874SAdam Thomson 	codec->control_data = da732x->regmap;
1526*48e27874SAdam Thomson 
1527*48e27874SAdam Thomson 	ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
1528*48e27874SAdam Thomson 	if (ret != 0) {
1529*48e27874SAdam Thomson 		dev_err(codec->dev, "Failed to register codec.\n");
1530*48e27874SAdam Thomson 		goto err;
1531*48e27874SAdam Thomson 	}
1532*48e27874SAdam Thomson 
1533*48e27874SAdam Thomson 	da732x_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1534*48e27874SAdam Thomson err:
1535*48e27874SAdam Thomson 	return ret;
1536*48e27874SAdam Thomson }
1537*48e27874SAdam Thomson 
1538*48e27874SAdam Thomson static int da732x_remove(struct snd_soc_codec *codec)
1539*48e27874SAdam Thomson {
1540*48e27874SAdam Thomson 
1541*48e27874SAdam Thomson 	da732x_set_bias_level(codec, SND_SOC_BIAS_OFF);
1542*48e27874SAdam Thomson 
1543*48e27874SAdam Thomson 	return 0;
1544*48e27874SAdam Thomson }
1545*48e27874SAdam Thomson 
1546*48e27874SAdam Thomson struct snd_soc_codec_driver soc_codec_dev_da732x = {
1547*48e27874SAdam Thomson 	.probe			= da732x_probe,
1548*48e27874SAdam Thomson 	.remove			= da732x_remove,
1549*48e27874SAdam Thomson 	.set_bias_level		= da732x_set_bias_level,
1550*48e27874SAdam Thomson 	.controls		= da732x_snd_controls,
1551*48e27874SAdam Thomson 	.num_controls		= ARRAY_SIZE(da732x_snd_controls),
1552*48e27874SAdam Thomson 	.dapm_widgets		= da732x_dapm_widgets,
1553*48e27874SAdam Thomson 	.num_dapm_widgets	= ARRAY_SIZE(da732x_dapm_widgets),
1554*48e27874SAdam Thomson 	.dapm_routes		= da732x_dapm_routes,
1555*48e27874SAdam Thomson 	.num_dapm_routes	= ARRAY_SIZE(da732x_dapm_routes),
1556*48e27874SAdam Thomson 	.set_pll		= da732x_set_dai_pll,
1557*48e27874SAdam Thomson 	.reg_cache_size		= ARRAY_SIZE(da732x_reg_cache),
1558*48e27874SAdam Thomson };
1559*48e27874SAdam Thomson 
1560*48e27874SAdam Thomson static __devinit int da732x_i2c_probe(struct i2c_client *i2c,
1561*48e27874SAdam Thomson 				      const struct i2c_device_id *id)
1562*48e27874SAdam Thomson {
1563*48e27874SAdam Thomson 	struct da732x_priv *da732x;
1564*48e27874SAdam Thomson 	unsigned int reg;
1565*48e27874SAdam Thomson 	int ret;
1566*48e27874SAdam Thomson 
1567*48e27874SAdam Thomson 	da732x = devm_kzalloc(&i2c->dev, sizeof(struct da732x_priv),
1568*48e27874SAdam Thomson 			      GFP_KERNEL);
1569*48e27874SAdam Thomson 	if (!da732x)
1570*48e27874SAdam Thomson 		return -ENOMEM;
1571*48e27874SAdam Thomson 
1572*48e27874SAdam Thomson 	i2c_set_clientdata(i2c, da732x);
1573*48e27874SAdam Thomson 
1574*48e27874SAdam Thomson 	da732x->regmap = devm_regmap_init_i2c(i2c, &da732x_regmap);
1575*48e27874SAdam Thomson 	if (IS_ERR(da732x->regmap)) {
1576*48e27874SAdam Thomson 		ret = PTR_ERR(da732x->regmap);
1577*48e27874SAdam Thomson 		dev_err(&i2c->dev, "Failed to initialize regmap\n");
1578*48e27874SAdam Thomson 		goto err;
1579*48e27874SAdam Thomson 	}
1580*48e27874SAdam Thomson 
1581*48e27874SAdam Thomson 	ret = regmap_read(da732x->regmap, DA732X_REG_ID, &reg);
1582*48e27874SAdam Thomson 	if (ret < 0) {
1583*48e27874SAdam Thomson 		dev_err(&i2c->dev, "Failed to read ID register: %d\n", ret);
1584*48e27874SAdam Thomson 		goto err;
1585*48e27874SAdam Thomson 	}
1586*48e27874SAdam Thomson 
1587*48e27874SAdam Thomson 	dev_info(&i2c->dev, "Revision: %d.%d\n",
1588*48e27874SAdam Thomson 		 (reg & DA732X_ID_MAJOR_MASK), (reg & DA732X_ID_MINOR_MASK));
1589*48e27874SAdam Thomson 
1590*48e27874SAdam Thomson 	ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_da732x,
1591*48e27874SAdam Thomson 				     da732x_dai, ARRAY_SIZE(da732x_dai));
1592*48e27874SAdam Thomson 	if (ret != 0)
1593*48e27874SAdam Thomson 		dev_err(&i2c->dev, "Failed to register codec.\n");
1594*48e27874SAdam Thomson 
1595*48e27874SAdam Thomson err:
1596*48e27874SAdam Thomson 	return ret;
1597*48e27874SAdam Thomson }
1598*48e27874SAdam Thomson 
1599*48e27874SAdam Thomson static __devexit int da732x_i2c_remove(struct i2c_client *client)
1600*48e27874SAdam Thomson {
1601*48e27874SAdam Thomson 	snd_soc_unregister_codec(&client->dev);
1602*48e27874SAdam Thomson 
1603*48e27874SAdam Thomson 	return 0;
1604*48e27874SAdam Thomson }
1605*48e27874SAdam Thomson 
1606*48e27874SAdam Thomson static const struct i2c_device_id da732x_i2c_id[] = {
1607*48e27874SAdam Thomson 	{ "da7320", 0},
1608*48e27874SAdam Thomson 	{ }
1609*48e27874SAdam Thomson };
1610*48e27874SAdam Thomson MODULE_DEVICE_TABLE(i2c, da732x_i2c_id);
1611*48e27874SAdam Thomson 
1612*48e27874SAdam Thomson static struct i2c_driver da732x_i2c_driver = {
1613*48e27874SAdam Thomson 	.driver		= {
1614*48e27874SAdam Thomson 		.name	= "da7320",
1615*48e27874SAdam Thomson 		.owner	= THIS_MODULE,
1616*48e27874SAdam Thomson 	},
1617*48e27874SAdam Thomson 	.probe		= da732x_i2c_probe,
1618*48e27874SAdam Thomson 	.remove		= __devexit_p(da732x_i2c_remove),
1619*48e27874SAdam Thomson 	.id_table	= da732x_i2c_id,
1620*48e27874SAdam Thomson };
1621*48e27874SAdam Thomson 
1622*48e27874SAdam Thomson module_i2c_driver(da732x_i2c_driver);
1623*48e27874SAdam Thomson 
1624*48e27874SAdam Thomson 
1625*48e27874SAdam Thomson MODULE_DESCRIPTION("ASoC DA732X driver");
1626*48e27874SAdam Thomson MODULE_AUTHOR("Michal Hajduk <michal.hajduk@diasemi.com>");
1627*48e27874SAdam Thomson MODULE_LICENSE("GPL");
1628