13f22e31dSJohan Hovold // SPDX-License-Identifier: GPL-2.0
23f22e31dSJohan Hovold // Copyright (c) 2016, The Linux Foundation. All rights reserved.
33f22e31dSJohan Hovold
4585e881eSSrinivas Kandagatla #include <linux/module.h>
5585e881eSSrinivas Kandagatla #include <linux/err.h>
6585e881eSSrinivas Kandagatla #include <linux/kernel.h>
7585e881eSSrinivas Kandagatla #include <linux/delay.h>
8585e881eSSrinivas Kandagatla #include <linux/regulator/consumer.h>
9585e881eSSrinivas Kandagatla #include <linux/types.h>
10585e881eSSrinivas Kandagatla #include <linux/of.h>
11585e881eSSrinivas Kandagatla #include <linux/platform_device.h>
12585e881eSSrinivas Kandagatla #include <linux/regmap.h>
13585e881eSSrinivas Kandagatla #include <sound/soc.h>
14585e881eSSrinivas Kandagatla #include <sound/pcm.h>
15585e881eSSrinivas Kandagatla #include <sound/pcm_params.h>
16585e881eSSrinivas Kandagatla #include <sound/tlv.h>
17de66b345SSrinivas Kandagatla #include <sound/jack.h>
18585e881eSSrinivas Kandagatla
19585e881eSSrinivas Kandagatla #define CDC_D_REVISION1 (0xf000)
20585e881eSSrinivas Kandagatla #define CDC_D_PERPH_SUBTYPE (0xf005)
21ff69c97eSSrinivas Kandagatla #define CDC_D_INT_EN_SET (0xf015)
22ff69c97eSSrinivas Kandagatla #define CDC_D_INT_EN_CLR (0xf016)
23de66b345SSrinivas Kandagatla #define MBHC_SWITCH_INT BIT(7)
24de66b345SSrinivas Kandagatla #define MBHC_MIC_ELECTRICAL_INS_REM_DET BIT(6)
25de66b345SSrinivas Kandagatla #define MBHC_BUTTON_PRESS_DET BIT(5)
26de66b345SSrinivas Kandagatla #define MBHC_BUTTON_RELEASE_DET BIT(4)
27585e881eSSrinivas Kandagatla #define CDC_D_CDC_RST_CTL (0xf046)
28585e881eSSrinivas Kandagatla #define RST_CTL_DIG_SW_RST_N_MASK BIT(7)
29585e881eSSrinivas Kandagatla #define RST_CTL_DIG_SW_RST_N_RESET 0
30585e881eSSrinivas Kandagatla #define RST_CTL_DIG_SW_RST_N_REMOVE_RESET BIT(7)
31585e881eSSrinivas Kandagatla
32585e881eSSrinivas Kandagatla #define CDC_D_CDC_TOP_CLK_CTL (0xf048)
33585e881eSSrinivas Kandagatla #define TOP_CLK_CTL_A_MCLK_MCLK2_EN_MASK (BIT(2) | BIT(3))
34585e881eSSrinivas Kandagatla #define TOP_CLK_CTL_A_MCLK_EN_ENABLE BIT(2)
35585e881eSSrinivas Kandagatla #define TOP_CLK_CTL_A_MCLK2_EN_ENABLE BIT(3)
36585e881eSSrinivas Kandagatla
37585e881eSSrinivas Kandagatla #define CDC_D_CDC_ANA_CLK_CTL (0xf049)
38585e881eSSrinivas Kandagatla #define ANA_CLK_CTL_EAR_HPHR_CLK_EN_MASK BIT(0)
39585e881eSSrinivas Kandagatla #define ANA_CLK_CTL_EAR_HPHR_CLK_EN BIT(0)
40585e881eSSrinivas Kandagatla #define ANA_CLK_CTL_EAR_HPHL_CLK_EN BIT(1)
41585e881eSSrinivas Kandagatla #define ANA_CLK_CTL_SPKR_CLK_EN_MASK BIT(4)
42585e881eSSrinivas Kandagatla #define ANA_CLK_CTL_SPKR_CLK_EN BIT(4)
43585e881eSSrinivas Kandagatla #define ANA_CLK_CTL_TXA_CLK25_EN BIT(5)
44585e881eSSrinivas Kandagatla
45585e881eSSrinivas Kandagatla #define CDC_D_CDC_DIG_CLK_CTL (0xf04A)
46585e881eSSrinivas Kandagatla #define DIG_CLK_CTL_RXD1_CLK_EN BIT(0)
47585e881eSSrinivas Kandagatla #define DIG_CLK_CTL_RXD2_CLK_EN BIT(1)
48deab4563SDamien Riegel #define DIG_CLK_CTL_RXD3_CLK_EN BIT(2)
49de66b345SSrinivas Kandagatla #define DIG_CLK_CTL_D_MBHC_CLK_EN_MASK BIT(3)
50de66b345SSrinivas Kandagatla #define DIG_CLK_CTL_D_MBHC_CLK_EN BIT(3)
51585e881eSSrinivas Kandagatla #define DIG_CLK_CTL_TXD_CLK_EN BIT(4)
52585e881eSSrinivas Kandagatla #define DIG_CLK_CTL_NCP_CLK_EN_MASK BIT(6)
53585e881eSSrinivas Kandagatla #define DIG_CLK_CTL_NCP_CLK_EN BIT(6)
54585e881eSSrinivas Kandagatla #define DIG_CLK_CTL_RXD_PDM_CLK_EN_MASK BIT(7)
55585e881eSSrinivas Kandagatla #define DIG_CLK_CTL_RXD_PDM_CLK_EN BIT(7)
56585e881eSSrinivas Kandagatla
57585e881eSSrinivas Kandagatla #define CDC_D_CDC_CONN_TX1_CTL (0xf050)
58585e881eSSrinivas Kandagatla #define CONN_TX1_SERIAL_TX1_MUX GENMASK(1, 0)
59585e881eSSrinivas Kandagatla #define CONN_TX1_SERIAL_TX1_ADC_1 0x0
60585e881eSSrinivas Kandagatla #define CONN_TX1_SERIAL_TX1_RX_PDM_LB 0x1
61585e881eSSrinivas Kandagatla #define CONN_TX1_SERIAL_TX1_ZERO 0x2
62585e881eSSrinivas Kandagatla
63585e881eSSrinivas Kandagatla #define CDC_D_CDC_CONN_TX2_CTL (0xf051)
64585e881eSSrinivas Kandagatla #define CONN_TX2_SERIAL_TX2_MUX GENMASK(1, 0)
65585e881eSSrinivas Kandagatla #define CONN_TX2_SERIAL_TX2_ADC_2 0x0
66585e881eSSrinivas Kandagatla #define CONN_TX2_SERIAL_TX2_RX_PDM_LB 0x1
67585e881eSSrinivas Kandagatla #define CONN_TX2_SERIAL_TX2_ZERO 0x2
68585e881eSSrinivas Kandagatla #define CDC_D_CDC_CONN_HPHR_DAC_CTL (0xf052)
69585e881eSSrinivas Kandagatla #define CDC_D_CDC_CONN_RX1_CTL (0xf053)
70585e881eSSrinivas Kandagatla #define CDC_D_CDC_CONN_RX2_CTL (0xf054)
71585e881eSSrinivas Kandagatla #define CDC_D_CDC_CONN_RX3_CTL (0xf055)
72585e881eSSrinivas Kandagatla #define CDC_D_CDC_CONN_RX_LB_CTL (0xf056)
73585e881eSSrinivas Kandagatla #define CDC_D_SEC_ACCESS (0xf0D0)
74585e881eSSrinivas Kandagatla #define CDC_D_PERPH_RESET_CTL3 (0xf0DA)
75585e881eSSrinivas Kandagatla #define CDC_D_PERPH_RESET_CTL4 (0xf0DB)
76585e881eSSrinivas Kandagatla #define CDC_A_REVISION1 (0xf100)
77585e881eSSrinivas Kandagatla #define CDC_A_REVISION2 (0xf101)
78585e881eSSrinivas Kandagatla #define CDC_A_REVISION3 (0xf102)
79585e881eSSrinivas Kandagatla #define CDC_A_REVISION4 (0xf103)
80585e881eSSrinivas Kandagatla #define CDC_A_PERPH_TYPE (0xf104)
81585e881eSSrinivas Kandagatla #define CDC_A_PERPH_SUBTYPE (0xf105)
82585e881eSSrinivas Kandagatla #define CDC_A_INT_RT_STS (0xf110)
83585e881eSSrinivas Kandagatla #define CDC_A_INT_SET_TYPE (0xf111)
84585e881eSSrinivas Kandagatla #define CDC_A_INT_POLARITY_HIGH (0xf112)
85585e881eSSrinivas Kandagatla #define CDC_A_INT_POLARITY_LOW (0xf113)
86585e881eSSrinivas Kandagatla #define CDC_A_INT_LATCHED_CLR (0xf114)
87585e881eSSrinivas Kandagatla #define CDC_A_INT_EN_SET (0xf115)
88585e881eSSrinivas Kandagatla #define CDC_A_INT_EN_CLR (0xf116)
89585e881eSSrinivas Kandagatla #define CDC_A_INT_LATCHED_STS (0xf118)
90585e881eSSrinivas Kandagatla #define CDC_A_INT_PENDING_STS (0xf119)
91585e881eSSrinivas Kandagatla #define CDC_A_INT_MID_SEL (0xf11A)
92585e881eSSrinivas Kandagatla #define CDC_A_INT_PRIORITY (0xf11B)
93585e881eSSrinivas Kandagatla #define CDC_A_MICB_1_EN (0xf140)
94585e881eSSrinivas Kandagatla #define MICB_1_EN_MICB_ENABLE BIT(7)
95585e881eSSrinivas Kandagatla #define MICB_1_EN_BYP_CAP_MASK BIT(6)
96585e881eSSrinivas Kandagatla #define MICB_1_EN_NO_EXT_BYP_CAP BIT(6)
97585e881eSSrinivas Kandagatla #define MICB_1_EN_EXT_BYP_CAP 0
98585e881eSSrinivas Kandagatla #define MICB_1_EN_PULL_DOWN_EN_MASK BIT(5)
99585e881eSSrinivas Kandagatla #define MICB_1_EN_PULL_DOWN_EN_ENABLE BIT(5)
100585e881eSSrinivas Kandagatla #define MICB_1_EN_OPA_STG2_TAIL_CURR_MASK GENMASK(3, 1)
101585e881eSSrinivas Kandagatla #define MICB_1_EN_OPA_STG2_TAIL_CURR_1_60UA (0x4)
102585e881eSSrinivas Kandagatla #define MICB_1_EN_PULL_UP_EN_MASK BIT(4)
103585e881eSSrinivas Kandagatla #define MICB_1_EN_TX3_GND_SEL_MASK BIT(0)
104585e881eSSrinivas Kandagatla #define MICB_1_EN_TX3_GND_SEL_TX_GND 0
105585e881eSSrinivas Kandagatla
106585e881eSSrinivas Kandagatla #define CDC_A_MICB_1_VAL (0xf141)
107e269998dSSrinivas Kandagatla #define MICB_MIN_VAL 1600
108e269998dSSrinivas Kandagatla #define MICB_STEP_SIZE 50
109664611e7SJean-François Têtu #define MICB_VOLTAGE_REGVAL(v) (((v - MICB_MIN_VAL)/MICB_STEP_SIZE) << 3)
110585e881eSSrinivas Kandagatla #define MICB_1_VAL_MICB_OUT_VAL_MASK GENMASK(7, 3)
111585e881eSSrinivas Kandagatla #define MICB_1_VAL_MICB_OUT_VAL_V2P70V ((0x16) << 3)
112e269998dSSrinivas Kandagatla #define MICB_1_VAL_MICB_OUT_VAL_V1P80V ((0x4) << 3)
113585e881eSSrinivas Kandagatla #define CDC_A_MICB_1_CTL (0xf142)
114585e881eSSrinivas Kandagatla
115585e881eSSrinivas Kandagatla #define MICB_1_CTL_CFILT_REF_SEL_MASK BIT(1)
116585e881eSSrinivas Kandagatla #define MICB_1_CTL_CFILT_REF_SEL_HPF_REF BIT(1)
117585e881eSSrinivas Kandagatla #define MICB_1_CTL_EXT_PRECHARG_EN_MASK BIT(5)
118585e881eSSrinivas Kandagatla #define MICB_1_CTL_EXT_PRECHARG_EN_ENABLE BIT(5)
119585e881eSSrinivas Kandagatla #define MICB_1_CTL_INT_PRECHARG_BYP_MASK BIT(6)
120585e881eSSrinivas Kandagatla #define MICB_1_CTL_INT_PRECHARG_BYP_EXT_PRECHRG_SEL BIT(6)
121585e881eSSrinivas Kandagatla
122585e881eSSrinivas Kandagatla #define CDC_A_MICB_1_INT_RBIAS (0xf143)
123585e881eSSrinivas Kandagatla #define MICB_1_INT_TX1_INT_RBIAS_EN_MASK BIT(7)
124585e881eSSrinivas Kandagatla #define MICB_1_INT_TX1_INT_RBIAS_EN_ENABLE BIT(7)
125585e881eSSrinivas Kandagatla #define MICB_1_INT_TX1_INT_RBIAS_EN_DISABLE 0
126585e881eSSrinivas Kandagatla
127585e881eSSrinivas Kandagatla #define MICB_1_INT_TX1_INT_PULLUP_EN_MASK BIT(6)
128585e881eSSrinivas Kandagatla #define MICB_1_INT_TX1_INT_PULLUP_EN_TX1N_TO_MICBIAS BIT(6)
129585e881eSSrinivas Kandagatla #define MICB_1_INT_TX1_INT_PULLUP_EN_TX1N_TO_GND 0
130585e881eSSrinivas Kandagatla
131585e881eSSrinivas Kandagatla #define MICB_1_INT_TX2_INT_RBIAS_EN_MASK BIT(4)
132585e881eSSrinivas Kandagatla #define MICB_1_INT_TX2_INT_RBIAS_EN_ENABLE BIT(4)
133585e881eSSrinivas Kandagatla #define MICB_1_INT_TX2_INT_RBIAS_EN_DISABLE 0
134585e881eSSrinivas Kandagatla #define MICB_1_INT_TX2_INT_PULLUP_EN_MASK BIT(3)
135585e881eSSrinivas Kandagatla #define MICB_1_INT_TX2_INT_PULLUP_EN_TX1N_TO_MICBIAS BIT(3)
136585e881eSSrinivas Kandagatla #define MICB_1_INT_TX2_INT_PULLUP_EN_TX1N_TO_GND 0
137585e881eSSrinivas Kandagatla
138585e881eSSrinivas Kandagatla #define MICB_1_INT_TX3_INT_RBIAS_EN_MASK BIT(1)
139585e881eSSrinivas Kandagatla #define MICB_1_INT_TX3_INT_RBIAS_EN_ENABLE BIT(1)
140585e881eSSrinivas Kandagatla #define MICB_1_INT_TX3_INT_RBIAS_EN_DISABLE 0
141585e881eSSrinivas Kandagatla #define MICB_1_INT_TX3_INT_PULLUP_EN_MASK BIT(0)
142585e881eSSrinivas Kandagatla #define MICB_1_INT_TX3_INT_PULLUP_EN_TX1N_TO_MICBIAS BIT(0)
143585e881eSSrinivas Kandagatla #define MICB_1_INT_TX3_INT_PULLUP_EN_TX1N_TO_GND 0
144585e881eSSrinivas Kandagatla
145585e881eSSrinivas Kandagatla #define CDC_A_MICB_2_EN (0xf144)
146de66b345SSrinivas Kandagatla #define CDC_A_MICB_2_EN_ENABLE BIT(7)
147de66b345SSrinivas Kandagatla #define CDC_A_MICB_2_PULL_DOWN_EN_MASK BIT(5)
148de66b345SSrinivas Kandagatla #define CDC_A_MICB_2_PULL_DOWN_EN BIT(5)
149585e881eSSrinivas Kandagatla #define CDC_A_TX_1_2_ATEST_CTL_2 (0xf145)
150585e881eSSrinivas Kandagatla #define CDC_A_MASTER_BIAS_CTL (0xf146)
151de66b345SSrinivas Kandagatla #define CDC_A_MBHC_DET_CTL_1 (0xf147)
152de66b345SSrinivas Kandagatla #define CDC_A_MBHC_DET_CTL_L_DET_EN BIT(7)
153de66b345SSrinivas Kandagatla #define CDC_A_MBHC_DET_CTL_GND_DET_EN BIT(6)
154de66b345SSrinivas Kandagatla #define CDC_A_MBHC_DET_CTL_MECH_DET_TYPE_INSERTION BIT(5)
155de66b345SSrinivas Kandagatla #define CDC_A_MBHC_DET_CTL_MECH_DET_TYPE_REMOVAL (0)
156de66b345SSrinivas Kandagatla #define CDC_A_MBHC_DET_CTL_MECH_DET_TYPE_MASK BIT(5)
157de66b345SSrinivas Kandagatla #define CDC_A_MBHC_DET_CTL_MECH_DET_TYPE_SHIFT (5)
158de66b345SSrinivas Kandagatla #define CDC_A_MBHC_DET_CTL_MIC_CLAMP_CTL_AUTO BIT(4)
159de66b345SSrinivas Kandagatla #define CDC_A_MBHC_DET_CTL_MIC_CLAMP_CTL_MANUAL BIT(3)
160de66b345SSrinivas Kandagatla #define CDC_A_MBHC_DET_CTL_MIC_CLAMP_CTL_MASK GENMASK(4, 3)
161de66b345SSrinivas Kandagatla #define CDC_A_MBHC_DET_CTL_MBHC_BIAS_EN BIT(2)
162de66b345SSrinivas Kandagatla #define CDC_A_MBHC_DET_CTL_2 (0xf150)
163de66b345SSrinivas Kandagatla #define CDC_A_MBHC_DET_CTL_HS_L_DET_PULL_UP_CTRL_I_3P0 (BIT(7) | BIT(6))
164de66b345SSrinivas Kandagatla #define CDC_A_MBHC_DET_CTL_HS_L_DET_COMPA_CTRL_V0P9_VDD BIT(5)
165de66b345SSrinivas Kandagatla #define CDC_A_PLUG_TYPE_MASK GENMASK(4, 3)
166de66b345SSrinivas Kandagatla #define CDC_A_HPHL_PLUG_TYPE_NO BIT(4)
167de66b345SSrinivas Kandagatla #define CDC_A_GND_PLUG_TYPE_NO BIT(3)
168de66b345SSrinivas Kandagatla #define CDC_A_MBHC_DET_CTL_HPHL_100K_TO_GND_EN_MASK BIT(0)
169de66b345SSrinivas Kandagatla #define CDC_A_MBHC_DET_CTL_HPHL_100K_TO_GND_EN BIT(0)
170de66b345SSrinivas Kandagatla #define CDC_A_MBHC_FSM_CTL (0xf151)
171de66b345SSrinivas Kandagatla #define CDC_A_MBHC_FSM_CTL_MBHC_FSM_EN BIT(7)
172de66b345SSrinivas Kandagatla #define CDC_A_MBHC_FSM_CTL_MBHC_FSM_EN_MASK BIT(7)
173de66b345SSrinivas Kandagatla #define CDC_A_MBHC_FSM_CTL_BTN_ISRC_CTRL_I_100UA (0x3 << 4)
174de66b345SSrinivas Kandagatla #define CDC_A_MBHC_FSM_CTL_BTN_ISRC_CTRL_MASK GENMASK(6, 4)
175de66b345SSrinivas Kandagatla #define CDC_A_MBHC_DBNC_TIMER (0xf152)
176de66b345SSrinivas Kandagatla #define CDC_A_MBHC_DBNC_TIMER_BTN_DBNC_T_16MS BIT(3)
177de66b345SSrinivas Kandagatla #define CDC_A_MBHC_DBNC_TIMER_INSREM_DBNC_T_256_MS (0x9 << 4)
178de66b345SSrinivas Kandagatla #define CDC_A_MBHC_BTN0_ZDET_CTL_0 (0xf153)
179de66b345SSrinivas Kandagatla #define CDC_A_MBHC_BTN1_ZDET_CTL_1 (0xf154)
180de66b345SSrinivas Kandagatla #define CDC_A_MBHC_BTN2_ZDET_CTL_2 (0xf155)
181de66b345SSrinivas Kandagatla #define CDC_A_MBHC_BTN3_CTL (0xf156)
182de66b345SSrinivas Kandagatla #define CDC_A_MBHC_BTN4_CTL (0xf157)
183de66b345SSrinivas Kandagatla #define CDC_A_MBHC_BTN_VREF_FINE_SHIFT (2)
184de66b345SSrinivas Kandagatla #define CDC_A_MBHC_BTN_VREF_FINE_MASK GENMASK(4, 2)
185de66b345SSrinivas Kandagatla #define CDC_A_MBHC_BTN_VREF_COARSE_MASK GENMASK(7, 5)
186de66b345SSrinivas Kandagatla #define CDC_A_MBHC_BTN_VREF_COARSE_SHIFT (5)
187de66b345SSrinivas Kandagatla #define CDC_A_MBHC_BTN_VREF_MASK (CDC_A_MBHC_BTN_VREF_COARSE_MASK | \
188de66b345SSrinivas Kandagatla CDC_A_MBHC_BTN_VREF_FINE_MASK)
189de66b345SSrinivas Kandagatla #define CDC_A_MBHC_RESULT_1 (0xf158)
190de66b345SSrinivas Kandagatla #define CDC_A_MBHC_RESULT_1_BTN_RESULT_MASK GENMASK(4, 0)
191585e881eSSrinivas Kandagatla #define CDC_A_TX_1_EN (0xf160)
192585e881eSSrinivas Kandagatla #define CDC_A_TX_2_EN (0xf161)
193585e881eSSrinivas Kandagatla #define CDC_A_TX_1_2_TEST_CTL_1 (0xf162)
194585e881eSSrinivas Kandagatla #define CDC_A_TX_1_2_TEST_CTL_2 (0xf163)
195585e881eSSrinivas Kandagatla #define CDC_A_TX_1_2_ATEST_CTL (0xf164)
196585e881eSSrinivas Kandagatla #define CDC_A_TX_1_2_OPAMP_BIAS (0xf165)
197585e881eSSrinivas Kandagatla #define CDC_A_TX_3_EN (0xf167)
198585e881eSSrinivas Kandagatla #define CDC_A_NCP_EN (0xf180)
199585e881eSSrinivas Kandagatla #define CDC_A_NCP_CLK (0xf181)
200585e881eSSrinivas Kandagatla #define CDC_A_NCP_FBCTRL (0xf183)
201585e881eSSrinivas Kandagatla #define CDC_A_NCP_FBCTRL_FB_CLK_INV_MASK BIT(5)
202585e881eSSrinivas Kandagatla #define CDC_A_NCP_FBCTRL_FB_CLK_INV BIT(5)
203585e881eSSrinivas Kandagatla #define CDC_A_NCP_BIAS (0xf184)
204585e881eSSrinivas Kandagatla #define CDC_A_NCP_VCTRL (0xf185)
205585e881eSSrinivas Kandagatla #define CDC_A_NCP_TEST (0xf186)
206585e881eSSrinivas Kandagatla #define CDC_A_NCP_CLIM_ADDR (0xf187)
207585e881eSSrinivas Kandagatla #define CDC_A_RX_CLOCK_DIVIDER (0xf190)
208585e881eSSrinivas Kandagatla #define CDC_A_RX_COM_OCP_CTL (0xf191)
209585e881eSSrinivas Kandagatla #define CDC_A_RX_COM_OCP_COUNT (0xf192)
210585e881eSSrinivas Kandagatla #define CDC_A_RX_COM_BIAS_DAC (0xf193)
211585e881eSSrinivas Kandagatla #define RX_COM_BIAS_DAC_RX_BIAS_EN_MASK BIT(7)
212585e881eSSrinivas Kandagatla #define RX_COM_BIAS_DAC_RX_BIAS_EN_ENABLE BIT(7)
213585e881eSSrinivas Kandagatla #define RX_COM_BIAS_DAC_DAC_REF_EN_MASK BIT(0)
214585e881eSSrinivas Kandagatla #define RX_COM_BIAS_DAC_DAC_REF_EN_ENABLE BIT(0)
215585e881eSSrinivas Kandagatla
216585e881eSSrinivas Kandagatla #define CDC_A_RX_HPH_BIAS_PA (0xf194)
217585e881eSSrinivas Kandagatla #define CDC_A_RX_HPH_BIAS_LDO_OCP (0xf195)
218585e881eSSrinivas Kandagatla #define CDC_A_RX_HPH_BIAS_CNP (0xf196)
219585e881eSSrinivas Kandagatla #define CDC_A_RX_HPH_CNP_EN (0xf197)
220585e881eSSrinivas Kandagatla #define CDC_A_RX_HPH_L_PA_DAC_CTL (0xf19B)
221585e881eSSrinivas Kandagatla #define RX_HPA_L_PA_DAC_CTL_DATA_RESET_MASK BIT(1)
222585e881eSSrinivas Kandagatla #define RX_HPA_L_PA_DAC_CTL_DATA_RESET_RESET BIT(1)
223585e881eSSrinivas Kandagatla #define CDC_A_RX_HPH_R_PA_DAC_CTL (0xf19D)
224585e881eSSrinivas Kandagatla #define RX_HPH_R_PA_DAC_CTL_DATA_RESET BIT(1)
225585e881eSSrinivas Kandagatla #define RX_HPH_R_PA_DAC_CTL_DATA_RESET_MASK BIT(1)
226585e881eSSrinivas Kandagatla
227585e881eSSrinivas Kandagatla #define CDC_A_RX_EAR_CTL (0xf19E)
228585e881eSSrinivas Kandagatla #define RX_EAR_CTL_SPK_VBAT_LDO_EN_MASK BIT(0)
229585e881eSSrinivas Kandagatla #define RX_EAR_CTL_SPK_VBAT_LDO_EN_ENABLE BIT(0)
2307d2f70f2SStephan Gerhold #define RX_EAR_CTL_PA_EAR_PA_EN_MASK BIT(6)
2317d2f70f2SStephan Gerhold #define RX_EAR_CTL_PA_EAR_PA_EN_ENABLE BIT(6)
2327d2f70f2SStephan Gerhold #define RX_EAR_CTL_PA_SEL_MASK BIT(7)
2337d2f70f2SStephan Gerhold #define RX_EAR_CTL_PA_SEL BIT(7)
234585e881eSSrinivas Kandagatla
235585e881eSSrinivas Kandagatla #define CDC_A_SPKR_DAC_CTL (0xf1B0)
236585e881eSSrinivas Kandagatla #define SPKR_DAC_CTL_DAC_RESET_MASK BIT(4)
237585e881eSSrinivas Kandagatla #define SPKR_DAC_CTL_DAC_RESET_NORMAL 0
238585e881eSSrinivas Kandagatla
239585e881eSSrinivas Kandagatla #define CDC_A_SPKR_DRV_CTL (0xf1B2)
240585e881eSSrinivas Kandagatla #define SPKR_DRV_CTL_DEF_MASK 0xEF
241585e881eSSrinivas Kandagatla #define SPKR_DRV_CLASSD_PA_EN_MASK BIT(7)
242585e881eSSrinivas Kandagatla #define SPKR_DRV_CLASSD_PA_EN_ENABLE BIT(7)
243585e881eSSrinivas Kandagatla #define SPKR_DRV_CAL_EN BIT(6)
244585e881eSSrinivas Kandagatla #define SPKR_DRV_SETTLE_EN BIT(5)
245585e881eSSrinivas Kandagatla #define SPKR_DRV_FW_EN BIT(3)
246585e881eSSrinivas Kandagatla #define SPKR_DRV_BOOST_SET BIT(2)
247585e881eSSrinivas Kandagatla #define SPKR_DRV_CMFB_SET BIT(1)
248585e881eSSrinivas Kandagatla #define SPKR_DRV_GAIN_SET BIT(0)
249585e881eSSrinivas Kandagatla #define SPKR_DRV_CTL_DEF_VAL (SPKR_DRV_CLASSD_PA_EN_ENABLE | \
250585e881eSSrinivas Kandagatla SPKR_DRV_CAL_EN | SPKR_DRV_SETTLE_EN | \
251585e881eSSrinivas Kandagatla SPKR_DRV_FW_EN | SPKR_DRV_BOOST_SET | \
252585e881eSSrinivas Kandagatla SPKR_DRV_CMFB_SET | SPKR_DRV_GAIN_SET)
253585e881eSSrinivas Kandagatla #define CDC_A_SPKR_OCP_CTL (0xf1B4)
254585e881eSSrinivas Kandagatla #define CDC_A_SPKR_PWRSTG_CTL (0xf1B5)
255585e881eSSrinivas Kandagatla #define SPKR_PWRSTG_CTL_DAC_EN_MASK BIT(0)
256585e881eSSrinivas Kandagatla #define SPKR_PWRSTG_CTL_DAC_EN BIT(0)
257585e881eSSrinivas Kandagatla #define SPKR_PWRSTG_CTL_MASK 0xE0
258585e881eSSrinivas Kandagatla #define SPKR_PWRSTG_CTL_BBM_MASK BIT(7)
259585e881eSSrinivas Kandagatla #define SPKR_PWRSTG_CTL_BBM_EN BIT(7)
260585e881eSSrinivas Kandagatla #define SPKR_PWRSTG_CTL_HBRDGE_EN_MASK BIT(6)
261585e881eSSrinivas Kandagatla #define SPKR_PWRSTG_CTL_HBRDGE_EN BIT(6)
262585e881eSSrinivas Kandagatla #define SPKR_PWRSTG_CTL_CLAMP_EN_MASK BIT(5)
263585e881eSSrinivas Kandagatla #define SPKR_PWRSTG_CTL_CLAMP_EN BIT(5)
264585e881eSSrinivas Kandagatla
265585e881eSSrinivas Kandagatla #define CDC_A_SPKR_DRV_DBG (0xf1B7)
266585e881eSSrinivas Kandagatla #define CDC_A_CURRENT_LIMIT (0xf1C0)
267585e881eSSrinivas Kandagatla #define CDC_A_BOOST_EN_CTL (0xf1C3)
268585e881eSSrinivas Kandagatla #define CDC_A_SLOPE_COMP_IP_ZERO (0xf1C4)
269585e881eSSrinivas Kandagatla #define CDC_A_SEC_ACCESS (0xf1D0)
270585e881eSSrinivas Kandagatla #define CDC_A_PERPH_RESET_CTL3 (0xf1DA)
271585e881eSSrinivas Kandagatla #define CDC_A_PERPH_RESET_CTL4 (0xf1DB)
272585e881eSSrinivas Kandagatla
273585e881eSSrinivas Kandagatla #define MSM8916_WCD_ANALOG_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
274585e881eSSrinivas Kandagatla SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000)
275585e881eSSrinivas Kandagatla #define MSM8916_WCD_ANALOG_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
27651f493aeSSrinivas Kandagatla SNDRV_PCM_FMTBIT_S32_LE)
277585e881eSSrinivas Kandagatla
278de66b345SSrinivas Kandagatla static int btn_mask = SND_JACK_BTN_0 | SND_JACK_BTN_1 |
279de66b345SSrinivas Kandagatla SND_JACK_BTN_2 | SND_JACK_BTN_3 | SND_JACK_BTN_4;
280de66b345SSrinivas Kandagatla static int hs_jack_mask = SND_JACK_HEADPHONE | SND_JACK_HEADSET;
281de66b345SSrinivas Kandagatla
282585e881eSSrinivas Kandagatla static const char * const supply_names[] = {
283585e881eSSrinivas Kandagatla "vdd-cdc-io",
284585e881eSSrinivas Kandagatla "vdd-cdc-tx-rx-cx",
285585e881eSSrinivas Kandagatla };
286585e881eSSrinivas Kandagatla
287de66b345SSrinivas Kandagatla #define MBHC_MAX_BUTTONS (5)
288de66b345SSrinivas Kandagatla
289585e881eSSrinivas Kandagatla struct pm8916_wcd_analog_priv {
290585e881eSSrinivas Kandagatla u16 pmic_rev;
291585e881eSSrinivas Kandagatla u16 codec_version;
292de66b345SSrinivas Kandagatla bool mbhc_btn_enabled;
293de66b345SSrinivas Kandagatla /* special event to detect accessory type */
294d430a7e3SDamien Riegel int mbhc_btn0_released;
295de66b345SSrinivas Kandagatla bool detect_accessory_type;
296585e881eSSrinivas Kandagatla struct clk *mclk;
297732ae454SKuninori Morimoto struct snd_soc_component *component;
298585e881eSSrinivas Kandagatla struct regulator_bulk_data supplies[ARRAY_SIZE(supply_names)];
299de66b345SSrinivas Kandagatla struct snd_soc_jack *jack;
300de66b345SSrinivas Kandagatla bool hphl_jack_type_normally_open;
301de66b345SSrinivas Kandagatla bool gnd_jack_type_normally_open;
302de66b345SSrinivas Kandagatla /* Voltage threshold when internal current source of 100uA is used */
303de66b345SSrinivas Kandagatla u32 vref_btn_cs[MBHC_MAX_BUTTONS];
304de66b345SSrinivas Kandagatla /* Voltage threshold when microphone bias is ON */
305de66b345SSrinivas Kandagatla u32 vref_btn_micb[MBHC_MAX_BUTTONS];
3069f3b777fSTakashi Sakamoto unsigned int micbias1_cap_mode;
3079f3b777fSTakashi Sakamoto unsigned int micbias2_cap_mode;
308e269998dSSrinivas Kandagatla unsigned int micbias_mv;
309585e881eSSrinivas Kandagatla };
310585e881eSSrinivas Kandagatla
311585e881eSSrinivas Kandagatla static const char *const adc2_mux_text[] = { "ZERO", "INP2", "INP3" };
3129110d1b0SStephan Gerhold static const char *const rdac2_mux_text[] = { "RX1", "RX2" };
313585e881eSSrinivas Kandagatla static const char *const hph_text[] = { "ZERO", "Switch", };
314585e881eSSrinivas Kandagatla
315585e881eSSrinivas Kandagatla static const struct soc_enum hph_enum = SOC_ENUM_SINGLE_VIRT(
316585e881eSSrinivas Kandagatla ARRAY_SIZE(hph_text), hph_text);
317585e881eSSrinivas Kandagatla
3187d2f70f2SStephan Gerhold static const struct snd_kcontrol_new ear_mux = SOC_DAPM_ENUM("EAR_S", hph_enum);
319585e881eSSrinivas Kandagatla static const struct snd_kcontrol_new hphl_mux = SOC_DAPM_ENUM("HPHL", hph_enum);
320585e881eSSrinivas Kandagatla static const struct snd_kcontrol_new hphr_mux = SOC_DAPM_ENUM("HPHR", hph_enum);
321585e881eSSrinivas Kandagatla
322585e881eSSrinivas Kandagatla /* ADC2 MUX */
323585e881eSSrinivas Kandagatla static const struct soc_enum adc2_enum = SOC_ENUM_SINGLE_VIRT(
324585e881eSSrinivas Kandagatla ARRAY_SIZE(adc2_mux_text), adc2_mux_text);
325585e881eSSrinivas Kandagatla
326585e881eSSrinivas Kandagatla /* RDAC2 MUX */
327585e881eSSrinivas Kandagatla static const struct soc_enum rdac2_mux_enum = SOC_ENUM_SINGLE(
3289110d1b0SStephan Gerhold CDC_D_CDC_CONN_HPHR_DAC_CTL, 0, 2, rdac2_mux_text);
329585e881eSSrinivas Kandagatla
330585e881eSSrinivas Kandagatla static const struct snd_kcontrol_new spkr_switch[] = {
331585e881eSSrinivas Kandagatla SOC_DAPM_SINGLE("Switch", CDC_A_SPKR_DAC_CTL, 7, 1, 0)
332585e881eSSrinivas Kandagatla };
333585e881eSSrinivas Kandagatla
334585e881eSSrinivas Kandagatla static const struct snd_kcontrol_new rdac2_mux = SOC_DAPM_ENUM(
335585e881eSSrinivas Kandagatla "RDAC2 MUX Mux", rdac2_mux_enum);
336585e881eSSrinivas Kandagatla static const struct snd_kcontrol_new tx_adc2_mux = SOC_DAPM_ENUM(
337585e881eSSrinivas Kandagatla "ADC2 MUX Mux", adc2_enum);
338585e881eSSrinivas Kandagatla
339585e881eSSrinivas Kandagatla /* Analog Gain control 0 dB to +24 dB in 6 dB steps */
340585e881eSSrinivas Kandagatla static const DECLARE_TLV_DB_SCALE(analog_gain, 0, 600, 0);
341585e881eSSrinivas Kandagatla
342585e881eSSrinivas Kandagatla static const struct snd_kcontrol_new pm8916_wcd_analog_snd_controls[] = {
343585e881eSSrinivas Kandagatla SOC_SINGLE_TLV("ADC1 Volume", CDC_A_TX_1_EN, 3, 8, 0, analog_gain),
344585e881eSSrinivas Kandagatla SOC_SINGLE_TLV("ADC2 Volume", CDC_A_TX_2_EN, 3, 8, 0, analog_gain),
345585e881eSSrinivas Kandagatla SOC_SINGLE_TLV("ADC3 Volume", CDC_A_TX_3_EN, 3, 8, 0, analog_gain),
346585e881eSSrinivas Kandagatla };
347585e881eSSrinivas Kandagatla
pm8916_wcd_analog_micbias_enable(struct snd_soc_component * component)348732ae454SKuninori Morimoto static void pm8916_wcd_analog_micbias_enable(struct snd_soc_component *component)
349585e881eSSrinivas Kandagatla {
350732ae454SKuninori Morimoto struct pm8916_wcd_analog_priv *wcd = snd_soc_component_get_drvdata(component);
351e269998dSSrinivas Kandagatla
352732ae454SKuninori Morimoto snd_soc_component_update_bits(component, CDC_A_MICB_1_CTL,
353585e881eSSrinivas Kandagatla MICB_1_CTL_EXT_PRECHARG_EN_MASK |
354585e881eSSrinivas Kandagatla MICB_1_CTL_INT_PRECHARG_BYP_MASK,
355585e881eSSrinivas Kandagatla MICB_1_CTL_INT_PRECHARG_BYP_EXT_PRECHRG_SEL
356585e881eSSrinivas Kandagatla | MICB_1_CTL_EXT_PRECHARG_EN_ENABLE);
357585e881eSSrinivas Kandagatla
358e269998dSSrinivas Kandagatla if (wcd->micbias_mv) {
359732ae454SKuninori Morimoto snd_soc_component_update_bits(component, CDC_A_MICB_1_VAL,
360664611e7SJean-François Têtu MICB_1_VAL_MICB_OUT_VAL_MASK,
361e269998dSSrinivas Kandagatla MICB_VOLTAGE_REGVAL(wcd->micbias_mv));
362585e881eSSrinivas Kandagatla /*
363585e881eSSrinivas Kandagatla * Special headset needs MICBIAS as 2.7V so wait for
364585e881eSSrinivas Kandagatla * 50 msec for the MICBIAS to reach 2.7 volts.
365585e881eSSrinivas Kandagatla */
366e269998dSSrinivas Kandagatla if (wcd->micbias_mv >= 2700)
367585e881eSSrinivas Kandagatla msleep(50);
368e269998dSSrinivas Kandagatla }
369e269998dSSrinivas Kandagatla
370732ae454SKuninori Morimoto snd_soc_component_update_bits(component, CDC_A_MICB_1_CTL,
371585e881eSSrinivas Kandagatla MICB_1_CTL_EXT_PRECHARG_EN_MASK |
372585e881eSSrinivas Kandagatla MICB_1_CTL_INT_PRECHARG_BYP_MASK, 0);
373585e881eSSrinivas Kandagatla
374585e881eSSrinivas Kandagatla }
375585e881eSSrinivas Kandagatla
pm8916_wcd_analog_enable_micbias(struct snd_soc_component * component,int event,unsigned int cap_mode)37665fe457eSStephan Gerhold static int pm8916_wcd_analog_enable_micbias(struct snd_soc_component *component,
37765fe457eSStephan Gerhold int event, unsigned int cap_mode)
378585e881eSSrinivas Kandagatla {
379585e881eSSrinivas Kandagatla switch (event) {
380585e881eSSrinivas Kandagatla case SND_SOC_DAPM_POST_PMU:
381732ae454SKuninori Morimoto pm8916_wcd_analog_micbias_enable(component);
382732ae454SKuninori Morimoto snd_soc_component_update_bits(component, CDC_A_MICB_1_EN,
383585e881eSSrinivas Kandagatla MICB_1_EN_BYP_CAP_MASK, cap_mode);
384585e881eSSrinivas Kandagatla break;
385585e881eSSrinivas Kandagatla }
386585e881eSSrinivas Kandagatla
387585e881eSSrinivas Kandagatla return 0;
388585e881eSSrinivas Kandagatla }
389585e881eSSrinivas Kandagatla
pm8916_wcd_analog_enable_micbias_int(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)39065fe457eSStephan Gerhold static int pm8916_wcd_analog_enable_micbias_int(struct snd_soc_dapm_widget *w,
39165fe457eSStephan Gerhold struct snd_kcontrol *kcontrol,
39265fe457eSStephan Gerhold int event)
393585e881eSSrinivas Kandagatla {
39465fe457eSStephan Gerhold struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
395585e881eSSrinivas Kandagatla
396585e881eSSrinivas Kandagatla switch (event) {
397585e881eSSrinivas Kandagatla case SND_SOC_DAPM_PRE_PMU:
398732ae454SKuninori Morimoto snd_soc_component_update_bits(component, CDC_A_MICB_1_EN,
399585e881eSSrinivas Kandagatla MICB_1_EN_OPA_STG2_TAIL_CURR_MASK,
400585e881eSSrinivas Kandagatla MICB_1_EN_OPA_STG2_TAIL_CURR_1_60UA);
401585e881eSSrinivas Kandagatla break;
402585e881eSSrinivas Kandagatla }
403585e881eSSrinivas Kandagatla
404585e881eSSrinivas Kandagatla return 0;
405585e881eSSrinivas Kandagatla }
406585e881eSSrinivas Kandagatla
pm8916_wcd_analog_enable_micbias1(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)40765fe457eSStephan Gerhold static int pm8916_wcd_analog_enable_micbias1(struct snd_soc_dapm_widget *w,
40865fe457eSStephan Gerhold struct snd_kcontrol *kcontrol,
40965fe457eSStephan Gerhold int event)
410585e881eSSrinivas Kandagatla {
411732ae454SKuninori Morimoto struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
412732ae454SKuninori Morimoto struct pm8916_wcd_analog_priv *wcd = snd_soc_component_get_drvdata(component);
413585e881eSSrinivas Kandagatla
41465fe457eSStephan Gerhold return pm8916_wcd_analog_enable_micbias(component, event,
415585e881eSSrinivas Kandagatla wcd->micbias1_cap_mode);
416585e881eSSrinivas Kandagatla }
417585e881eSSrinivas Kandagatla
pm8916_wcd_analog_enable_micbias2(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)41865fe457eSStephan Gerhold static int pm8916_wcd_analog_enable_micbias2(struct snd_soc_dapm_widget *w,
41965fe457eSStephan Gerhold struct snd_kcontrol *kcontrol,
42065fe457eSStephan Gerhold int event)
421585e881eSSrinivas Kandagatla {
422732ae454SKuninori Morimoto struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
423732ae454SKuninori Morimoto struct pm8916_wcd_analog_priv *wcd = snd_soc_component_get_drvdata(component);
424585e881eSSrinivas Kandagatla
42565fe457eSStephan Gerhold return pm8916_wcd_analog_enable_micbias(component, event,
426585e881eSSrinivas Kandagatla wcd->micbias2_cap_mode);
427585e881eSSrinivas Kandagatla
428585e881eSSrinivas Kandagatla }
429585e881eSSrinivas Kandagatla
pm8916_mbhc_configure_bias(struct pm8916_wcd_analog_priv * priv,bool micbias2_enabled)430de66b345SSrinivas Kandagatla static int pm8916_mbhc_configure_bias(struct pm8916_wcd_analog_priv *priv,
431de66b345SSrinivas Kandagatla bool micbias2_enabled)
432de66b345SSrinivas Kandagatla {
433732ae454SKuninori Morimoto struct snd_soc_component *component = priv->component;
434de66b345SSrinivas Kandagatla u32 coarse, fine, reg_val, reg_addr;
435de66b345SSrinivas Kandagatla int *vrefs, i;
436de66b345SSrinivas Kandagatla
437de66b345SSrinivas Kandagatla if (!micbias2_enabled) { /* use internal 100uA Current source */
438de66b345SSrinivas Kandagatla /* Enable internal 2.2k Internal Rbias Resistor */
439732ae454SKuninori Morimoto snd_soc_component_update_bits(component, CDC_A_MICB_1_INT_RBIAS,
440de66b345SSrinivas Kandagatla MICB_1_INT_TX2_INT_RBIAS_EN_MASK,
441de66b345SSrinivas Kandagatla MICB_1_INT_TX2_INT_RBIAS_EN_ENABLE);
442de66b345SSrinivas Kandagatla /* Remove pull down on MIC BIAS2 */
443732ae454SKuninori Morimoto snd_soc_component_update_bits(component, CDC_A_MICB_2_EN,
444de66b345SSrinivas Kandagatla CDC_A_MICB_2_PULL_DOWN_EN_MASK,
445de66b345SSrinivas Kandagatla 0);
446de66b345SSrinivas Kandagatla /* enable 100uA internal current source */
447732ae454SKuninori Morimoto snd_soc_component_update_bits(component, CDC_A_MBHC_FSM_CTL,
448de66b345SSrinivas Kandagatla CDC_A_MBHC_FSM_CTL_BTN_ISRC_CTRL_MASK,
449de66b345SSrinivas Kandagatla CDC_A_MBHC_FSM_CTL_BTN_ISRC_CTRL_I_100UA);
450de66b345SSrinivas Kandagatla }
451732ae454SKuninori Morimoto snd_soc_component_update_bits(component, CDC_A_MBHC_FSM_CTL,
452de66b345SSrinivas Kandagatla CDC_A_MBHC_FSM_CTL_MBHC_FSM_EN_MASK,
453de66b345SSrinivas Kandagatla CDC_A_MBHC_FSM_CTL_MBHC_FSM_EN);
454de66b345SSrinivas Kandagatla
455de66b345SSrinivas Kandagatla if (micbias2_enabled)
456de66b345SSrinivas Kandagatla vrefs = &priv->vref_btn_micb[0];
457de66b345SSrinivas Kandagatla else
458de66b345SSrinivas Kandagatla vrefs = &priv->vref_btn_cs[0];
459de66b345SSrinivas Kandagatla
460de66b345SSrinivas Kandagatla /* program vref ranges for all the buttons */
461de66b345SSrinivas Kandagatla reg_addr = CDC_A_MBHC_BTN0_ZDET_CTL_0;
462de66b345SSrinivas Kandagatla for (i = 0; i < MBHC_MAX_BUTTONS; i++) {
463de66b345SSrinivas Kandagatla /* split mv in to coarse parts of 100mv & fine parts of 12mv */
464de66b345SSrinivas Kandagatla coarse = (vrefs[i] / 100);
465de66b345SSrinivas Kandagatla fine = ((vrefs[i] % 100) / 12);
466de66b345SSrinivas Kandagatla reg_val = (coarse << CDC_A_MBHC_BTN_VREF_COARSE_SHIFT) |
467de66b345SSrinivas Kandagatla (fine << CDC_A_MBHC_BTN_VREF_FINE_SHIFT);
468732ae454SKuninori Morimoto snd_soc_component_update_bits(component, reg_addr,
469de66b345SSrinivas Kandagatla CDC_A_MBHC_BTN_VREF_MASK,
470de66b345SSrinivas Kandagatla reg_val);
471de66b345SSrinivas Kandagatla reg_addr++;
472de66b345SSrinivas Kandagatla }
473de66b345SSrinivas Kandagatla
474de66b345SSrinivas Kandagatla return 0;
475de66b345SSrinivas Kandagatla }
476de66b345SSrinivas Kandagatla
pm8916_wcd_setup_mbhc(struct pm8916_wcd_analog_priv * wcd)47779f01fe6SDamien Riegel static void pm8916_wcd_setup_mbhc(struct pm8916_wcd_analog_priv *wcd)
47879f01fe6SDamien Riegel {
479732ae454SKuninori Morimoto struct snd_soc_component *component = wcd->component;
48079f01fe6SDamien Riegel bool micbias_enabled = false;
48179f01fe6SDamien Riegel u32 plug_type = 0;
48279f01fe6SDamien Riegel u32 int_en_mask;
48379f01fe6SDamien Riegel
484732ae454SKuninori Morimoto snd_soc_component_write(component, CDC_A_MBHC_DET_CTL_1,
48579f01fe6SDamien Riegel CDC_A_MBHC_DET_CTL_L_DET_EN |
48679f01fe6SDamien Riegel CDC_A_MBHC_DET_CTL_MECH_DET_TYPE_INSERTION |
48779f01fe6SDamien Riegel CDC_A_MBHC_DET_CTL_MIC_CLAMP_CTL_AUTO |
48879f01fe6SDamien Riegel CDC_A_MBHC_DET_CTL_MBHC_BIAS_EN);
48979f01fe6SDamien Riegel
49079f01fe6SDamien Riegel if (wcd->hphl_jack_type_normally_open)
49179f01fe6SDamien Riegel plug_type |= CDC_A_HPHL_PLUG_TYPE_NO;
49279f01fe6SDamien Riegel
49379f01fe6SDamien Riegel if (wcd->gnd_jack_type_normally_open)
49479f01fe6SDamien Riegel plug_type |= CDC_A_GND_PLUG_TYPE_NO;
49579f01fe6SDamien Riegel
496732ae454SKuninori Morimoto snd_soc_component_write(component, CDC_A_MBHC_DET_CTL_2,
49779f01fe6SDamien Riegel CDC_A_MBHC_DET_CTL_HS_L_DET_PULL_UP_CTRL_I_3P0 |
49879f01fe6SDamien Riegel CDC_A_MBHC_DET_CTL_HS_L_DET_COMPA_CTRL_V0P9_VDD |
49979f01fe6SDamien Riegel plug_type |
50079f01fe6SDamien Riegel CDC_A_MBHC_DET_CTL_HPHL_100K_TO_GND_EN);
50179f01fe6SDamien Riegel
50279f01fe6SDamien Riegel
503732ae454SKuninori Morimoto snd_soc_component_write(component, CDC_A_MBHC_DBNC_TIMER,
50479f01fe6SDamien Riegel CDC_A_MBHC_DBNC_TIMER_INSREM_DBNC_T_256_MS |
50579f01fe6SDamien Riegel CDC_A_MBHC_DBNC_TIMER_BTN_DBNC_T_16MS);
50679f01fe6SDamien Riegel
50779f01fe6SDamien Riegel /* enable MBHC clock */
508732ae454SKuninori Morimoto snd_soc_component_update_bits(component, CDC_D_CDC_DIG_CLK_CTL,
50979f01fe6SDamien Riegel DIG_CLK_CTL_D_MBHC_CLK_EN_MASK,
51079f01fe6SDamien Riegel DIG_CLK_CTL_D_MBHC_CLK_EN);
51179f01fe6SDamien Riegel
512a6f80d99SKuninori Morimoto if (snd_soc_component_read(component, CDC_A_MICB_2_EN) & CDC_A_MICB_2_EN_ENABLE)
51379f01fe6SDamien Riegel micbias_enabled = true;
51479f01fe6SDamien Riegel
51579f01fe6SDamien Riegel pm8916_mbhc_configure_bias(wcd, micbias_enabled);
51679f01fe6SDamien Riegel
51779f01fe6SDamien Riegel int_en_mask = MBHC_SWITCH_INT;
51879f01fe6SDamien Riegel if (wcd->mbhc_btn_enabled)
51979f01fe6SDamien Riegel int_en_mask |= MBHC_BUTTON_PRESS_DET | MBHC_BUTTON_RELEASE_DET;
52079f01fe6SDamien Riegel
521732ae454SKuninori Morimoto snd_soc_component_update_bits(component, CDC_D_INT_EN_CLR, int_en_mask, 0);
522732ae454SKuninori Morimoto snd_soc_component_update_bits(component, CDC_D_INT_EN_SET, int_en_mask, int_en_mask);
52379f01fe6SDamien Riegel wcd->mbhc_btn0_released = false;
52479f01fe6SDamien Riegel wcd->detect_accessory_type = true;
52579f01fe6SDamien Riegel }
52679f01fe6SDamien Riegel
pm8916_wcd_analog_enable_micbias_int2(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)527b4f89a0cSAxel Lin static int pm8916_wcd_analog_enable_micbias_int2(struct
528585e881eSSrinivas Kandagatla snd_soc_dapm_widget
529585e881eSSrinivas Kandagatla *w, struct snd_kcontrol
530585e881eSSrinivas Kandagatla *kcontrol, int event)
531585e881eSSrinivas Kandagatla {
532732ae454SKuninori Morimoto struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
533732ae454SKuninori Morimoto struct pm8916_wcd_analog_priv *wcd = snd_soc_component_get_drvdata(component);
534585e881eSSrinivas Kandagatla
535de66b345SSrinivas Kandagatla switch (event) {
536057efcf9SStephan Gerhold case SND_SOC_DAPM_PRE_PMU:
53765fe457eSStephan Gerhold snd_soc_component_update_bits(component, CDC_A_MICB_2_EN,
53865fe457eSStephan Gerhold CDC_A_MICB_2_PULL_DOWN_EN_MASK, 0);
539057efcf9SStephan Gerhold break;
540de66b345SSrinivas Kandagatla case SND_SOC_DAPM_POST_PMU:
541de66b345SSrinivas Kandagatla pm8916_mbhc_configure_bias(wcd, true);
542de66b345SSrinivas Kandagatla break;
543de66b345SSrinivas Kandagatla case SND_SOC_DAPM_POST_PMD:
544de66b345SSrinivas Kandagatla pm8916_mbhc_configure_bias(wcd, false);
545de66b345SSrinivas Kandagatla break;
546de66b345SSrinivas Kandagatla }
547de66b345SSrinivas Kandagatla
54865fe457eSStephan Gerhold return pm8916_wcd_analog_enable_micbias_int(w, kcontrol, event);
549585e881eSSrinivas Kandagatla }
550585e881eSSrinivas Kandagatla
pm8916_wcd_analog_enable_adc(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)551585e881eSSrinivas Kandagatla static int pm8916_wcd_analog_enable_adc(struct snd_soc_dapm_widget *w,
552585e881eSSrinivas Kandagatla struct snd_kcontrol *kcontrol,
553585e881eSSrinivas Kandagatla int event)
554585e881eSSrinivas Kandagatla {
555732ae454SKuninori Morimoto struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
556585e881eSSrinivas Kandagatla u16 adc_reg = CDC_A_TX_1_2_TEST_CTL_2;
557585e881eSSrinivas Kandagatla u8 init_bit_shift;
558585e881eSSrinivas Kandagatla
559585e881eSSrinivas Kandagatla if (w->reg == CDC_A_TX_1_EN)
560585e881eSSrinivas Kandagatla init_bit_shift = 5;
561585e881eSSrinivas Kandagatla else
562585e881eSSrinivas Kandagatla init_bit_shift = 4;
563585e881eSSrinivas Kandagatla
564585e881eSSrinivas Kandagatla switch (event) {
565585e881eSSrinivas Kandagatla case SND_SOC_DAPM_PRE_PMU:
566585e881eSSrinivas Kandagatla if (w->reg == CDC_A_TX_2_EN)
567732ae454SKuninori Morimoto snd_soc_component_update_bits(component, CDC_A_MICB_1_CTL,
568585e881eSSrinivas Kandagatla MICB_1_CTL_CFILT_REF_SEL_MASK,
569585e881eSSrinivas Kandagatla MICB_1_CTL_CFILT_REF_SEL_HPF_REF);
570585e881eSSrinivas Kandagatla /*
571585e881eSSrinivas Kandagatla * Add delay of 10 ms to give sufficient time for the voltage
572585e881eSSrinivas Kandagatla * to shoot up and settle so that the txfe init does not
573585e881eSSrinivas Kandagatla * happen when the input voltage is changing too much.
574585e881eSSrinivas Kandagatla */
575585e881eSSrinivas Kandagatla usleep_range(10000, 10010);
576732ae454SKuninori Morimoto snd_soc_component_update_bits(component, adc_reg, 1 << init_bit_shift,
577585e881eSSrinivas Kandagatla 1 << init_bit_shift);
578585e881eSSrinivas Kandagatla switch (w->reg) {
579585e881eSSrinivas Kandagatla case CDC_A_TX_1_EN:
580732ae454SKuninori Morimoto snd_soc_component_update_bits(component, CDC_D_CDC_CONN_TX1_CTL,
581585e881eSSrinivas Kandagatla CONN_TX1_SERIAL_TX1_MUX,
582585e881eSSrinivas Kandagatla CONN_TX1_SERIAL_TX1_ADC_1);
583585e881eSSrinivas Kandagatla break;
584585e881eSSrinivas Kandagatla case CDC_A_TX_2_EN:
585585e881eSSrinivas Kandagatla case CDC_A_TX_3_EN:
586732ae454SKuninori Morimoto snd_soc_component_update_bits(component, CDC_D_CDC_CONN_TX2_CTL,
587585e881eSSrinivas Kandagatla CONN_TX2_SERIAL_TX2_MUX,
588585e881eSSrinivas Kandagatla CONN_TX2_SERIAL_TX2_ADC_2);
589585e881eSSrinivas Kandagatla break;
590585e881eSSrinivas Kandagatla }
591585e881eSSrinivas Kandagatla break;
592585e881eSSrinivas Kandagatla case SND_SOC_DAPM_POST_PMU:
593585e881eSSrinivas Kandagatla /*
594585e881eSSrinivas Kandagatla * Add delay of 12 ms before deasserting the init
595585e881eSSrinivas Kandagatla * to reduce the tx pop
596585e881eSSrinivas Kandagatla */
597585e881eSSrinivas Kandagatla usleep_range(12000, 12010);
598732ae454SKuninori Morimoto snd_soc_component_update_bits(component, adc_reg, 1 << init_bit_shift, 0x00);
599585e881eSSrinivas Kandagatla break;
600585e881eSSrinivas Kandagatla case SND_SOC_DAPM_POST_PMD:
601585e881eSSrinivas Kandagatla switch (w->reg) {
602585e881eSSrinivas Kandagatla case CDC_A_TX_1_EN:
603732ae454SKuninori Morimoto snd_soc_component_update_bits(component, CDC_D_CDC_CONN_TX1_CTL,
604585e881eSSrinivas Kandagatla CONN_TX1_SERIAL_TX1_MUX,
605585e881eSSrinivas Kandagatla CONN_TX1_SERIAL_TX1_ZERO);
606585e881eSSrinivas Kandagatla break;
607585e881eSSrinivas Kandagatla case CDC_A_TX_2_EN:
608732ae454SKuninori Morimoto snd_soc_component_update_bits(component, CDC_A_MICB_1_CTL,
609585e881eSSrinivas Kandagatla MICB_1_CTL_CFILT_REF_SEL_MASK, 0);
6103e146b55SGustavo A. R. Silva fallthrough;
611585e881eSSrinivas Kandagatla case CDC_A_TX_3_EN:
612732ae454SKuninori Morimoto snd_soc_component_update_bits(component, CDC_D_CDC_CONN_TX2_CTL,
613585e881eSSrinivas Kandagatla CONN_TX2_SERIAL_TX2_MUX,
614585e881eSSrinivas Kandagatla CONN_TX2_SERIAL_TX2_ZERO);
615585e881eSSrinivas Kandagatla break;
616585e881eSSrinivas Kandagatla }
617585e881eSSrinivas Kandagatla
618585e881eSSrinivas Kandagatla
619585e881eSSrinivas Kandagatla break;
620585e881eSSrinivas Kandagatla }
621585e881eSSrinivas Kandagatla return 0;
622585e881eSSrinivas Kandagatla }
623585e881eSSrinivas Kandagatla
pm8916_wcd_analog_enable_spk_pa(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)624585e881eSSrinivas Kandagatla static int pm8916_wcd_analog_enable_spk_pa(struct snd_soc_dapm_widget *w,
625585e881eSSrinivas Kandagatla struct snd_kcontrol *kcontrol,
626585e881eSSrinivas Kandagatla int event)
627585e881eSSrinivas Kandagatla {
628732ae454SKuninori Morimoto struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
629585e881eSSrinivas Kandagatla
630585e881eSSrinivas Kandagatla switch (event) {
631585e881eSSrinivas Kandagatla case SND_SOC_DAPM_PRE_PMU:
632732ae454SKuninori Morimoto snd_soc_component_update_bits(component, CDC_A_SPKR_PWRSTG_CTL,
633585e881eSSrinivas Kandagatla SPKR_PWRSTG_CTL_DAC_EN_MASK |
634585e881eSSrinivas Kandagatla SPKR_PWRSTG_CTL_BBM_MASK |
635585e881eSSrinivas Kandagatla SPKR_PWRSTG_CTL_HBRDGE_EN_MASK |
636585e881eSSrinivas Kandagatla SPKR_PWRSTG_CTL_CLAMP_EN_MASK,
637585e881eSSrinivas Kandagatla SPKR_PWRSTG_CTL_DAC_EN|
638585e881eSSrinivas Kandagatla SPKR_PWRSTG_CTL_BBM_EN |
639585e881eSSrinivas Kandagatla SPKR_PWRSTG_CTL_HBRDGE_EN |
640585e881eSSrinivas Kandagatla SPKR_PWRSTG_CTL_CLAMP_EN);
641585e881eSSrinivas Kandagatla
642732ae454SKuninori Morimoto snd_soc_component_update_bits(component, CDC_A_RX_EAR_CTL,
643585e881eSSrinivas Kandagatla RX_EAR_CTL_SPK_VBAT_LDO_EN_MASK,
644585e881eSSrinivas Kandagatla RX_EAR_CTL_SPK_VBAT_LDO_EN_ENABLE);
645585e881eSSrinivas Kandagatla break;
646585e881eSSrinivas Kandagatla case SND_SOC_DAPM_POST_PMU:
647732ae454SKuninori Morimoto snd_soc_component_update_bits(component, CDC_A_SPKR_DRV_CTL,
648585e881eSSrinivas Kandagatla SPKR_DRV_CTL_DEF_MASK,
649585e881eSSrinivas Kandagatla SPKR_DRV_CTL_DEF_VAL);
650732ae454SKuninori Morimoto snd_soc_component_update_bits(component, w->reg,
651585e881eSSrinivas Kandagatla SPKR_DRV_CLASSD_PA_EN_MASK,
652585e881eSSrinivas Kandagatla SPKR_DRV_CLASSD_PA_EN_ENABLE);
653585e881eSSrinivas Kandagatla break;
654585e881eSSrinivas Kandagatla case SND_SOC_DAPM_POST_PMD:
655732ae454SKuninori Morimoto snd_soc_component_update_bits(component, CDC_A_SPKR_PWRSTG_CTL,
656585e881eSSrinivas Kandagatla SPKR_PWRSTG_CTL_DAC_EN_MASK|
657585e881eSSrinivas Kandagatla SPKR_PWRSTG_CTL_BBM_MASK |
658585e881eSSrinivas Kandagatla SPKR_PWRSTG_CTL_HBRDGE_EN_MASK |
659585e881eSSrinivas Kandagatla SPKR_PWRSTG_CTL_CLAMP_EN_MASK, 0);
660585e881eSSrinivas Kandagatla
661732ae454SKuninori Morimoto snd_soc_component_update_bits(component, CDC_A_SPKR_DAC_CTL,
662585e881eSSrinivas Kandagatla SPKR_DAC_CTL_DAC_RESET_MASK,
663585e881eSSrinivas Kandagatla SPKR_DAC_CTL_DAC_RESET_NORMAL);
664732ae454SKuninori Morimoto snd_soc_component_update_bits(component, CDC_A_RX_EAR_CTL,
665585e881eSSrinivas Kandagatla RX_EAR_CTL_SPK_VBAT_LDO_EN_MASK, 0);
666585e881eSSrinivas Kandagatla break;
667585e881eSSrinivas Kandagatla }
668585e881eSSrinivas Kandagatla return 0;
669585e881eSSrinivas Kandagatla }
670585e881eSSrinivas Kandagatla
pm8916_wcd_analog_enable_ear_pa(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)6717d2f70f2SStephan Gerhold static int pm8916_wcd_analog_enable_ear_pa(struct snd_soc_dapm_widget *w,
6727d2f70f2SStephan Gerhold struct snd_kcontrol *kcontrol,
6737d2f70f2SStephan Gerhold int event)
6747d2f70f2SStephan Gerhold {
6757d2f70f2SStephan Gerhold struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
6767d2f70f2SStephan Gerhold
6777d2f70f2SStephan Gerhold switch (event) {
6787d2f70f2SStephan Gerhold case SND_SOC_DAPM_PRE_PMU:
6797d2f70f2SStephan Gerhold snd_soc_component_update_bits(component, CDC_A_RX_EAR_CTL,
6807d2f70f2SStephan Gerhold RX_EAR_CTL_PA_SEL_MASK, RX_EAR_CTL_PA_SEL);
6817d2f70f2SStephan Gerhold break;
6827d2f70f2SStephan Gerhold case SND_SOC_DAPM_POST_PMU:
6837d2f70f2SStephan Gerhold snd_soc_component_update_bits(component, CDC_A_RX_EAR_CTL,
6847d2f70f2SStephan Gerhold RX_EAR_CTL_PA_EAR_PA_EN_MASK,
6857d2f70f2SStephan Gerhold RX_EAR_CTL_PA_EAR_PA_EN_ENABLE);
6867d2f70f2SStephan Gerhold break;
6877d2f70f2SStephan Gerhold case SND_SOC_DAPM_POST_PMD:
6887d2f70f2SStephan Gerhold snd_soc_component_update_bits(component, CDC_A_RX_EAR_CTL,
6897d2f70f2SStephan Gerhold RX_EAR_CTL_PA_EAR_PA_EN_MASK, 0);
6907d2f70f2SStephan Gerhold /* Delay to reduce ear turn off pop */
6917d2f70f2SStephan Gerhold usleep_range(7000, 7100);
6927d2f70f2SStephan Gerhold snd_soc_component_update_bits(component, CDC_A_RX_EAR_CTL,
6937d2f70f2SStephan Gerhold RX_EAR_CTL_PA_SEL_MASK, 0);
6947d2f70f2SStephan Gerhold break;
6957d2f70f2SStephan Gerhold }
6967d2f70f2SStephan Gerhold return 0;
6977d2f70f2SStephan Gerhold }
6987d2f70f2SStephan Gerhold
699585e881eSSrinivas Kandagatla static const struct reg_default wcd_reg_defaults_2_0[] = {
700585e881eSSrinivas Kandagatla {CDC_A_RX_COM_OCP_CTL, 0xD1},
701585e881eSSrinivas Kandagatla {CDC_A_RX_COM_OCP_COUNT, 0xFF},
702585e881eSSrinivas Kandagatla {CDC_D_SEC_ACCESS, 0xA5},
703585e881eSSrinivas Kandagatla {CDC_D_PERPH_RESET_CTL3, 0x0F},
704585e881eSSrinivas Kandagatla {CDC_A_TX_1_2_OPAMP_BIAS, 0x4F},
705585e881eSSrinivas Kandagatla {CDC_A_NCP_FBCTRL, 0x28},
706585e881eSSrinivas Kandagatla {CDC_A_SPKR_DRV_CTL, 0x69},
707585e881eSSrinivas Kandagatla {CDC_A_SPKR_DRV_DBG, 0x01},
708585e881eSSrinivas Kandagatla {CDC_A_BOOST_EN_CTL, 0x5F},
709585e881eSSrinivas Kandagatla {CDC_A_SLOPE_COMP_IP_ZERO, 0x88},
710585e881eSSrinivas Kandagatla {CDC_A_SEC_ACCESS, 0xA5},
711585e881eSSrinivas Kandagatla {CDC_A_PERPH_RESET_CTL3, 0x0F},
712585e881eSSrinivas Kandagatla {CDC_A_CURRENT_LIMIT, 0x82},
713585e881eSSrinivas Kandagatla {CDC_A_SPKR_DAC_CTL, 0x03},
714585e881eSSrinivas Kandagatla {CDC_A_SPKR_OCP_CTL, 0xE1},
715585e881eSSrinivas Kandagatla {CDC_A_MASTER_BIAS_CTL, 0x30},
716585e881eSSrinivas Kandagatla };
717585e881eSSrinivas Kandagatla
pm8916_wcd_analog_probe(struct snd_soc_component * component)718732ae454SKuninori Morimoto static int pm8916_wcd_analog_probe(struct snd_soc_component *component)
719585e881eSSrinivas Kandagatla {
720732ae454SKuninori Morimoto struct pm8916_wcd_analog_priv *priv = dev_get_drvdata(component->dev);
721585e881eSSrinivas Kandagatla int err, reg;
722585e881eSSrinivas Kandagatla
723585e881eSSrinivas Kandagatla err = regulator_bulk_enable(ARRAY_SIZE(priv->supplies), priv->supplies);
724585e881eSSrinivas Kandagatla if (err != 0) {
725732ae454SKuninori Morimoto dev_err(component->dev, "failed to enable regulators (%d)\n", err);
726585e881eSSrinivas Kandagatla return err;
727585e881eSSrinivas Kandagatla }
728585e881eSSrinivas Kandagatla
729732ae454SKuninori Morimoto snd_soc_component_init_regmap(component,
730732ae454SKuninori Morimoto dev_get_regmap(component->dev->parent, NULL));
731732ae454SKuninori Morimoto snd_soc_component_set_drvdata(component, priv);
732a6f80d99SKuninori Morimoto priv->pmic_rev = snd_soc_component_read(component, CDC_D_REVISION1);
733a6f80d99SKuninori Morimoto priv->codec_version = snd_soc_component_read(component, CDC_D_PERPH_SUBTYPE);
734585e881eSSrinivas Kandagatla
735732ae454SKuninori Morimoto dev_info(component->dev, "PMIC REV: %d\t CODEC Version: %d\n",
736585e881eSSrinivas Kandagatla priv->pmic_rev, priv->codec_version);
737585e881eSSrinivas Kandagatla
738732ae454SKuninori Morimoto snd_soc_component_write(component, CDC_D_PERPH_RESET_CTL4, 0x01);
739732ae454SKuninori Morimoto snd_soc_component_write(component, CDC_A_PERPH_RESET_CTL4, 0x01);
740585e881eSSrinivas Kandagatla
741585e881eSSrinivas Kandagatla for (reg = 0; reg < ARRAY_SIZE(wcd_reg_defaults_2_0); reg++)
742732ae454SKuninori Morimoto snd_soc_component_write(component, wcd_reg_defaults_2_0[reg].reg,
743585e881eSSrinivas Kandagatla wcd_reg_defaults_2_0[reg].def);
744585e881eSSrinivas Kandagatla
745732ae454SKuninori Morimoto priv->component = component;
746de66b345SSrinivas Kandagatla
747732ae454SKuninori Morimoto snd_soc_component_update_bits(component, CDC_D_CDC_RST_CTL,
74852981e29SSrinivas Kandagatla RST_CTL_DIG_SW_RST_N_MASK,
74952981e29SSrinivas Kandagatla RST_CTL_DIG_SW_RST_N_REMOVE_RESET);
750de66b345SSrinivas Kandagatla
751de66b345SSrinivas Kandagatla pm8916_wcd_setup_mbhc(priv);
752de66b345SSrinivas Kandagatla
753585e881eSSrinivas Kandagatla return 0;
754585e881eSSrinivas Kandagatla }
755585e881eSSrinivas Kandagatla
pm8916_wcd_analog_remove(struct snd_soc_component * component)756732ae454SKuninori Morimoto static void pm8916_wcd_analog_remove(struct snd_soc_component *component)
757585e881eSSrinivas Kandagatla {
758732ae454SKuninori Morimoto struct pm8916_wcd_analog_priv *priv = dev_get_drvdata(component->dev);
759585e881eSSrinivas Kandagatla
760732ae454SKuninori Morimoto snd_soc_component_update_bits(component, CDC_D_CDC_RST_CTL,
76152981e29SSrinivas Kandagatla RST_CTL_DIG_SW_RST_N_MASK, 0);
76252981e29SSrinivas Kandagatla
763732ae454SKuninori Morimoto regulator_bulk_disable(ARRAY_SIZE(priv->supplies),
764585e881eSSrinivas Kandagatla priv->supplies);
765585e881eSSrinivas Kandagatla }
766585e881eSSrinivas Kandagatla
767585e881eSSrinivas Kandagatla static const struct snd_soc_dapm_route pm8916_wcd_analog_audio_map[] = {
768585e881eSSrinivas Kandagatla
769585e881eSSrinivas Kandagatla {"PDM_RX1", NULL, "PDM Playback"},
770585e881eSSrinivas Kandagatla {"PDM_RX2", NULL, "PDM Playback"},
771585e881eSSrinivas Kandagatla {"PDM_RX3", NULL, "PDM Playback"},
772585e881eSSrinivas Kandagatla {"PDM Capture", NULL, "PDM_TX"},
773585e881eSSrinivas Kandagatla
774585e881eSSrinivas Kandagatla /* ADC Connections */
775585e881eSSrinivas Kandagatla {"PDM_TX", NULL, "ADC2"},
776585e881eSSrinivas Kandagatla {"PDM_TX", NULL, "ADC3"},
777585e881eSSrinivas Kandagatla {"ADC2", NULL, "ADC2 MUX"},
778585e881eSSrinivas Kandagatla {"ADC3", NULL, "ADC2 MUX"},
779585e881eSSrinivas Kandagatla {"ADC2 MUX", "INP2", "ADC2_INP2"},
780585e881eSSrinivas Kandagatla {"ADC2 MUX", "INP3", "ADC2_INP3"},
781585e881eSSrinivas Kandagatla
782585e881eSSrinivas Kandagatla {"PDM_TX", NULL, "ADC1"},
783585e881eSSrinivas Kandagatla {"ADC1", NULL, "AMIC1"},
784585e881eSSrinivas Kandagatla {"ADC2_INP2", NULL, "AMIC2"},
785585e881eSSrinivas Kandagatla {"ADC2_INP3", NULL, "AMIC3"},
786585e881eSSrinivas Kandagatla
787585e881eSSrinivas Kandagatla /* RDAC Connections */
788585e881eSSrinivas Kandagatla {"HPHR DAC", NULL, "RDAC2 MUX"},
789585e881eSSrinivas Kandagatla {"RDAC2 MUX", "RX1", "PDM_RX1"},
790585e881eSSrinivas Kandagatla {"RDAC2 MUX", "RX2", "PDM_RX2"},
791585e881eSSrinivas Kandagatla {"HPHL DAC", NULL, "PDM_RX1"},
792585e881eSSrinivas Kandagatla {"PDM_RX1", NULL, "RXD1_CLK"},
793585e881eSSrinivas Kandagatla {"PDM_RX2", NULL, "RXD2_CLK"},
794585e881eSSrinivas Kandagatla {"PDM_RX3", NULL, "RXD3_CLK"},
795585e881eSSrinivas Kandagatla
796585e881eSSrinivas Kandagatla {"PDM_RX1", NULL, "RXD_PDM_CLK"},
797585e881eSSrinivas Kandagatla {"PDM_RX2", NULL, "RXD_PDM_CLK"},
798585e881eSSrinivas Kandagatla {"PDM_RX3", NULL, "RXD_PDM_CLK"},
799585e881eSSrinivas Kandagatla
800585e881eSSrinivas Kandagatla {"ADC1", NULL, "TXD_CLK"},
801585e881eSSrinivas Kandagatla {"ADC2", NULL, "TXD_CLK"},
802585e881eSSrinivas Kandagatla {"ADC3", NULL, "TXD_CLK"},
803585e881eSSrinivas Kandagatla
804585e881eSSrinivas Kandagatla {"ADC1", NULL, "TXA_CLK25"},
805585e881eSSrinivas Kandagatla {"ADC2", NULL, "TXA_CLK25"},
806585e881eSSrinivas Kandagatla {"ADC3", NULL, "TXA_CLK25"},
807585e881eSSrinivas Kandagatla
808585e881eSSrinivas Kandagatla {"PDM_RX1", NULL, "A_MCLK2"},
809585e881eSSrinivas Kandagatla {"PDM_RX2", NULL, "A_MCLK2"},
810585e881eSSrinivas Kandagatla {"PDM_RX3", NULL, "A_MCLK2"},
811585e881eSSrinivas Kandagatla
812585e881eSSrinivas Kandagatla {"PDM_TX", NULL, "A_MCLK2"},
813585e881eSSrinivas Kandagatla {"A_MCLK2", NULL, "A_MCLK"},
814585e881eSSrinivas Kandagatla
8157d2f70f2SStephan Gerhold /* Earpiece (RX MIX1) */
8167d2f70f2SStephan Gerhold {"EAR", NULL, "EAR_S"},
8177d2f70f2SStephan Gerhold {"EAR_S", "Switch", "EAR PA"},
8187d2f70f2SStephan Gerhold {"EAR PA", NULL, "RX_BIAS"},
8197d2f70f2SStephan Gerhold {"EAR PA", NULL, "HPHL DAC"},
8207d2f70f2SStephan Gerhold {"EAR PA", NULL, "HPHR DAC"},
8217d2f70f2SStephan Gerhold {"EAR PA", NULL, "EAR CP"},
8227d2f70f2SStephan Gerhold
823585e881eSSrinivas Kandagatla /* Headset (RX MIX1 and RX MIX2) */
824319a0533SStephan Gerhold {"HPH_L", NULL, "HPHL PA"},
825319a0533SStephan Gerhold {"HPH_R", NULL, "HPHR PA"},
826585e881eSSrinivas Kandagatla
8277d2f70f2SStephan Gerhold {"HPHL DAC", NULL, "EAR_HPHL_CLK"},
8287d2f70f2SStephan Gerhold {"HPHR DAC", NULL, "EAR_HPHR_CLK"},
829585e881eSSrinivas Kandagatla
830585e881eSSrinivas Kandagatla {"CP", NULL, "NCP_CLK"},
831585e881eSSrinivas Kandagatla
832585e881eSSrinivas Kandagatla {"HPHL PA", NULL, "HPHL"},
833585e881eSSrinivas Kandagatla {"HPHR PA", NULL, "HPHR"},
834585e881eSSrinivas Kandagatla {"HPHL PA", NULL, "CP"},
835585e881eSSrinivas Kandagatla {"HPHL PA", NULL, "RX_BIAS"},
836585e881eSSrinivas Kandagatla {"HPHR PA", NULL, "CP"},
837585e881eSSrinivas Kandagatla {"HPHR PA", NULL, "RX_BIAS"},
838585e881eSSrinivas Kandagatla {"HPHL", "Switch", "HPHL DAC"},
839585e881eSSrinivas Kandagatla {"HPHR", "Switch", "HPHR DAC"},
840585e881eSSrinivas Kandagatla
841585e881eSSrinivas Kandagatla {"RX_BIAS", NULL, "DAC_REF"},
842585e881eSSrinivas Kandagatla
843585e881eSSrinivas Kandagatla {"SPK_OUT", NULL, "SPK PA"},
844585e881eSSrinivas Kandagatla {"SPK PA", NULL, "RX_BIAS"},
845585e881eSSrinivas Kandagatla {"SPK PA", NULL, "SPKR_CLK"},
846585e881eSSrinivas Kandagatla {"SPK PA", NULL, "SPK DAC"},
847585e881eSSrinivas Kandagatla {"SPK DAC", "Switch", "PDM_RX3"},
848585e881eSSrinivas Kandagatla
84965fe457eSStephan Gerhold {"MIC_BIAS1", NULL, "INT_LDO_H"},
85065fe457eSStephan Gerhold {"MIC_BIAS2", NULL, "INT_LDO_H"},
85165fe457eSStephan Gerhold {"MIC_BIAS1", NULL, "vdd-micbias"},
85265fe457eSStephan Gerhold {"MIC_BIAS2", NULL, "vdd-micbias"},
85365fe457eSStephan Gerhold
85465fe457eSStephan Gerhold {"MIC BIAS External1", NULL, "MIC_BIAS1"},
85565fe457eSStephan Gerhold {"MIC BIAS Internal1", NULL, "MIC_BIAS1"},
85665fe457eSStephan Gerhold {"MIC BIAS External2", NULL, "MIC_BIAS2"},
85765fe457eSStephan Gerhold {"MIC BIAS Internal2", NULL, "MIC_BIAS2"},
85800d85232SStephan Gerhold {"MIC BIAS Internal3", NULL, "MIC_BIAS1"},
859585e881eSSrinivas Kandagatla };
860585e881eSSrinivas Kandagatla
861585e881eSSrinivas Kandagatla static const struct snd_soc_dapm_widget pm8916_wcd_analog_dapm_widgets[] = {
862585e881eSSrinivas Kandagatla
863585e881eSSrinivas Kandagatla SND_SOC_DAPM_AIF_IN("PDM_RX1", NULL, 0, SND_SOC_NOPM, 0, 0),
864585e881eSSrinivas Kandagatla SND_SOC_DAPM_AIF_IN("PDM_RX2", NULL, 0, SND_SOC_NOPM, 0, 0),
865585e881eSSrinivas Kandagatla SND_SOC_DAPM_AIF_IN("PDM_RX3", NULL, 0, SND_SOC_NOPM, 0, 0),
866585e881eSSrinivas Kandagatla SND_SOC_DAPM_AIF_OUT("PDM_TX", NULL, 0, SND_SOC_NOPM, 0, 0),
867585e881eSSrinivas Kandagatla
868585e881eSSrinivas Kandagatla SND_SOC_DAPM_INPUT("AMIC1"),
869585e881eSSrinivas Kandagatla SND_SOC_DAPM_INPUT("AMIC3"),
870585e881eSSrinivas Kandagatla SND_SOC_DAPM_INPUT("AMIC2"),
8717d2f70f2SStephan Gerhold SND_SOC_DAPM_OUTPUT("EAR"),
872319a0533SStephan Gerhold SND_SOC_DAPM_OUTPUT("HPH_L"),
873319a0533SStephan Gerhold SND_SOC_DAPM_OUTPUT("HPH_R"),
874585e881eSSrinivas Kandagatla
875585e881eSSrinivas Kandagatla /* RX stuff */
876585e881eSSrinivas Kandagatla SND_SOC_DAPM_SUPPLY("INT_LDO_H", SND_SOC_NOPM, 1, 0, NULL, 0),
877585e881eSSrinivas Kandagatla
8787d2f70f2SStephan Gerhold SND_SOC_DAPM_PGA_E("EAR PA", SND_SOC_NOPM,
8797d2f70f2SStephan Gerhold 0, 0, NULL, 0,
8807d2f70f2SStephan Gerhold pm8916_wcd_analog_enable_ear_pa,
8817d2f70f2SStephan Gerhold SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
8827d2f70f2SStephan Gerhold SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
8837d2f70f2SStephan Gerhold SND_SOC_DAPM_MUX("EAR_S", SND_SOC_NOPM, 0, 0, &ear_mux),
8847d2f70f2SStephan Gerhold SND_SOC_DAPM_SUPPLY("EAR CP", CDC_A_NCP_EN, 4, 0, NULL, 0),
8857d2f70f2SStephan Gerhold
886585e881eSSrinivas Kandagatla SND_SOC_DAPM_PGA("HPHL PA", CDC_A_RX_HPH_CNP_EN, 5, 0, NULL, 0),
887585e881eSSrinivas Kandagatla SND_SOC_DAPM_MUX("HPHL", SND_SOC_NOPM, 0, 0, &hphl_mux),
888585e881eSSrinivas Kandagatla SND_SOC_DAPM_MIXER("HPHL DAC", CDC_A_RX_HPH_L_PA_DAC_CTL, 3, 0, NULL,
889585e881eSSrinivas Kandagatla 0),
890585e881eSSrinivas Kandagatla SND_SOC_DAPM_PGA("HPHR PA", CDC_A_RX_HPH_CNP_EN, 4, 0, NULL, 0),
891585e881eSSrinivas Kandagatla SND_SOC_DAPM_MUX("HPHR", SND_SOC_NOPM, 0, 0, &hphr_mux),
892585e881eSSrinivas Kandagatla SND_SOC_DAPM_MIXER("HPHR DAC", CDC_A_RX_HPH_R_PA_DAC_CTL, 3, 0, NULL,
893585e881eSSrinivas Kandagatla 0),
894585e881eSSrinivas Kandagatla SND_SOC_DAPM_MIXER("SPK DAC", SND_SOC_NOPM, 0, 0,
895585e881eSSrinivas Kandagatla spkr_switch, ARRAY_SIZE(spkr_switch)),
896585e881eSSrinivas Kandagatla
897585e881eSSrinivas Kandagatla /* Speaker */
898585e881eSSrinivas Kandagatla SND_SOC_DAPM_OUTPUT("SPK_OUT"),
899585e881eSSrinivas Kandagatla SND_SOC_DAPM_PGA_E("SPK PA", CDC_A_SPKR_DRV_CTL,
900585e881eSSrinivas Kandagatla 6, 0, NULL, 0,
901585e881eSSrinivas Kandagatla pm8916_wcd_analog_enable_spk_pa,
902585e881eSSrinivas Kandagatla SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
903585e881eSSrinivas Kandagatla SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
904585e881eSSrinivas Kandagatla SND_SOC_DAPM_REGULATOR_SUPPLY("vdd-micbias", 0, 0),
905585e881eSSrinivas Kandagatla SND_SOC_DAPM_SUPPLY("CP", CDC_A_NCP_EN, 0, 0, NULL, 0),
906585e881eSSrinivas Kandagatla
907585e881eSSrinivas Kandagatla SND_SOC_DAPM_SUPPLY("DAC_REF", CDC_A_RX_COM_BIAS_DAC, 0, 0, NULL, 0),
908585e881eSSrinivas Kandagatla SND_SOC_DAPM_SUPPLY("RX_BIAS", CDC_A_RX_COM_BIAS_DAC, 7, 0, NULL, 0),
909585e881eSSrinivas Kandagatla
910585e881eSSrinivas Kandagatla /* TX */
91165fe457eSStephan Gerhold SND_SOC_DAPM_SUPPLY("MIC_BIAS1", CDC_A_MICB_1_EN, 7, 0,
91265fe457eSStephan Gerhold pm8916_wcd_analog_enable_micbias1,
91365fe457eSStephan Gerhold SND_SOC_DAPM_POST_PMU),
91465fe457eSStephan Gerhold SND_SOC_DAPM_SUPPLY("MIC_BIAS2", CDC_A_MICB_2_EN, 7, 0,
91565fe457eSStephan Gerhold pm8916_wcd_analog_enable_micbias2,
91665fe457eSStephan Gerhold SND_SOC_DAPM_POST_PMU),
91765fe457eSStephan Gerhold
91865fe457eSStephan Gerhold SND_SOC_DAPM_SUPPLY("MIC BIAS External1", SND_SOC_NOPM, 0, 0, NULL, 0),
91965fe457eSStephan Gerhold SND_SOC_DAPM_SUPPLY("MIC BIAS External2", SND_SOC_NOPM, 0, 0, NULL, 0),
92065fe457eSStephan Gerhold
92165fe457eSStephan Gerhold SND_SOC_DAPM_SUPPLY("MIC BIAS Internal1", CDC_A_MICB_1_INT_RBIAS, 7, 0,
92265fe457eSStephan Gerhold pm8916_wcd_analog_enable_micbias_int,
92365fe457eSStephan Gerhold SND_SOC_DAPM_PRE_PMU),
92465fe457eSStephan Gerhold SND_SOC_DAPM_SUPPLY("MIC BIAS Internal2", CDC_A_MICB_1_INT_RBIAS, 4, 0,
925585e881eSSrinivas Kandagatla pm8916_wcd_analog_enable_micbias_int2,
926585e881eSSrinivas Kandagatla SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
927585e881eSSrinivas Kandagatla SND_SOC_DAPM_POST_PMD),
92800d85232SStephan Gerhold SND_SOC_DAPM_SUPPLY("MIC BIAS Internal3", CDC_A_MICB_1_INT_RBIAS, 1, 0,
92900d85232SStephan Gerhold pm8916_wcd_analog_enable_micbias_int,
93000d85232SStephan Gerhold SND_SOC_DAPM_PRE_PMU),
931585e881eSSrinivas Kandagatla
932585e881eSSrinivas Kandagatla SND_SOC_DAPM_ADC_E("ADC1", NULL, CDC_A_TX_1_EN, 7, 0,
933585e881eSSrinivas Kandagatla pm8916_wcd_analog_enable_adc,
934585e881eSSrinivas Kandagatla SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
935585e881eSSrinivas Kandagatla SND_SOC_DAPM_POST_PMD),
936585e881eSSrinivas Kandagatla SND_SOC_DAPM_ADC_E("ADC2_INP2", NULL, CDC_A_TX_2_EN, 7, 0,
937585e881eSSrinivas Kandagatla pm8916_wcd_analog_enable_adc,
938585e881eSSrinivas Kandagatla SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
939585e881eSSrinivas Kandagatla SND_SOC_DAPM_POST_PMD),
940585e881eSSrinivas Kandagatla SND_SOC_DAPM_ADC_E("ADC2_INP3", NULL, CDC_A_TX_3_EN, 7, 0,
941585e881eSSrinivas Kandagatla pm8916_wcd_analog_enable_adc,
942585e881eSSrinivas Kandagatla SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
943585e881eSSrinivas Kandagatla SND_SOC_DAPM_POST_PMD),
944585e881eSSrinivas Kandagatla
945585e881eSSrinivas Kandagatla SND_SOC_DAPM_MIXER("ADC2", SND_SOC_NOPM, 0, 0, NULL, 0),
946585e881eSSrinivas Kandagatla SND_SOC_DAPM_MIXER("ADC3", SND_SOC_NOPM, 0, 0, NULL, 0),
947585e881eSSrinivas Kandagatla
948585e881eSSrinivas Kandagatla SND_SOC_DAPM_MUX("ADC2 MUX", SND_SOC_NOPM, 0, 0, &tx_adc2_mux),
949585e881eSSrinivas Kandagatla SND_SOC_DAPM_MUX("RDAC2 MUX", SND_SOC_NOPM, 0, 0, &rdac2_mux),
950585e881eSSrinivas Kandagatla
951585e881eSSrinivas Kandagatla /* Analog path clocks */
952585e881eSSrinivas Kandagatla SND_SOC_DAPM_SUPPLY("EAR_HPHR_CLK", CDC_D_CDC_ANA_CLK_CTL, 0, 0, NULL,
953585e881eSSrinivas Kandagatla 0),
954585e881eSSrinivas Kandagatla SND_SOC_DAPM_SUPPLY("EAR_HPHL_CLK", CDC_D_CDC_ANA_CLK_CTL, 1, 0, NULL,
955585e881eSSrinivas Kandagatla 0),
956585e881eSSrinivas Kandagatla SND_SOC_DAPM_SUPPLY("SPKR_CLK", CDC_D_CDC_ANA_CLK_CTL, 4, 0, NULL, 0),
957585e881eSSrinivas Kandagatla SND_SOC_DAPM_SUPPLY("TXA_CLK25", CDC_D_CDC_ANA_CLK_CTL, 5, 0, NULL, 0),
958585e881eSSrinivas Kandagatla
959585e881eSSrinivas Kandagatla /* Digital path clocks */
960585e881eSSrinivas Kandagatla
961585e881eSSrinivas Kandagatla SND_SOC_DAPM_SUPPLY("RXD1_CLK", CDC_D_CDC_DIG_CLK_CTL, 0, 0, NULL, 0),
962585e881eSSrinivas Kandagatla SND_SOC_DAPM_SUPPLY("RXD2_CLK", CDC_D_CDC_DIG_CLK_CTL, 1, 0, NULL, 0),
963585e881eSSrinivas Kandagatla SND_SOC_DAPM_SUPPLY("RXD3_CLK", CDC_D_CDC_DIG_CLK_CTL, 2, 0, NULL, 0),
964585e881eSSrinivas Kandagatla
965585e881eSSrinivas Kandagatla SND_SOC_DAPM_SUPPLY("TXD_CLK", CDC_D_CDC_DIG_CLK_CTL, 4, 0, NULL, 0),
966585e881eSSrinivas Kandagatla SND_SOC_DAPM_SUPPLY("NCP_CLK", CDC_D_CDC_DIG_CLK_CTL, 6, 0, NULL, 0),
967585e881eSSrinivas Kandagatla SND_SOC_DAPM_SUPPLY("RXD_PDM_CLK", CDC_D_CDC_DIG_CLK_CTL, 7, 0, NULL,
968585e881eSSrinivas Kandagatla 0),
969585e881eSSrinivas Kandagatla
970585e881eSSrinivas Kandagatla /* System Clock source */
971585e881eSSrinivas Kandagatla SND_SOC_DAPM_SUPPLY("A_MCLK", CDC_D_CDC_TOP_CLK_CTL, 2, 0, NULL, 0),
972585e881eSSrinivas Kandagatla /* TX ADC and RX DAC Clock source. */
973585e881eSSrinivas Kandagatla SND_SOC_DAPM_SUPPLY("A_MCLK2", CDC_D_CDC_TOP_CLK_CTL, 3, 0, NULL, 0),
974585e881eSSrinivas Kandagatla };
975585e881eSSrinivas Kandagatla
pm8916_wcd_analog_set_jack(struct snd_soc_component * component,struct snd_soc_jack * jack,void * data)976732ae454SKuninori Morimoto static int pm8916_wcd_analog_set_jack(struct snd_soc_component *component,
977de66b345SSrinivas Kandagatla struct snd_soc_jack *jack,
978de66b345SSrinivas Kandagatla void *data)
979de66b345SSrinivas Kandagatla {
980732ae454SKuninori Morimoto struct pm8916_wcd_analog_priv *wcd = snd_soc_component_get_drvdata(component);
981de66b345SSrinivas Kandagatla
982de66b345SSrinivas Kandagatla wcd->jack = jack;
983de66b345SSrinivas Kandagatla
984de66b345SSrinivas Kandagatla return 0;
985de66b345SSrinivas Kandagatla }
986de66b345SSrinivas Kandagatla
mbhc_btn_release_irq_handler(int irq,void * arg)987de66b345SSrinivas Kandagatla static irqreturn_t mbhc_btn_release_irq_handler(int irq, void *arg)
988de66b345SSrinivas Kandagatla {
989de66b345SSrinivas Kandagatla struct pm8916_wcd_analog_priv *priv = arg;
990de66b345SSrinivas Kandagatla
991de66b345SSrinivas Kandagatla if (priv->detect_accessory_type) {
992732ae454SKuninori Morimoto struct snd_soc_component *component = priv->component;
993a6f80d99SKuninori Morimoto u32 val = snd_soc_component_read(component, CDC_A_MBHC_RESULT_1);
994de66b345SSrinivas Kandagatla
995de66b345SSrinivas Kandagatla /* check if its BTN0 thats released */
99656026714SDan Carpenter if ((val != -1) && !(val & CDC_A_MBHC_RESULT_1_BTN_RESULT_MASK))
997d430a7e3SDamien Riegel priv->mbhc_btn0_released = true;
998de66b345SSrinivas Kandagatla
999de66b345SSrinivas Kandagatla } else {
1000de66b345SSrinivas Kandagatla snd_soc_jack_report(priv->jack, 0, btn_mask);
1001de66b345SSrinivas Kandagatla }
1002de66b345SSrinivas Kandagatla
1003de66b345SSrinivas Kandagatla return IRQ_HANDLED;
1004de66b345SSrinivas Kandagatla }
1005de66b345SSrinivas Kandagatla
mbhc_btn_press_irq_handler(int irq,void * arg)1006de66b345SSrinivas Kandagatla static irqreturn_t mbhc_btn_press_irq_handler(int irq, void *arg)
1007de66b345SSrinivas Kandagatla {
1008de66b345SSrinivas Kandagatla struct pm8916_wcd_analog_priv *priv = arg;
1009732ae454SKuninori Morimoto struct snd_soc_component *component = priv->component;
1010de66b345SSrinivas Kandagatla u32 btn_result;
1011de66b345SSrinivas Kandagatla
1012a6f80d99SKuninori Morimoto btn_result = snd_soc_component_read(component, CDC_A_MBHC_RESULT_1) &
1013de66b345SSrinivas Kandagatla CDC_A_MBHC_RESULT_1_BTN_RESULT_MASK;
1014de66b345SSrinivas Kandagatla
1015de66b345SSrinivas Kandagatla switch (btn_result) {
1016de66b345SSrinivas Kandagatla case 0xf:
1017de66b345SSrinivas Kandagatla snd_soc_jack_report(priv->jack, SND_JACK_BTN_4, btn_mask);
1018de66b345SSrinivas Kandagatla break;
1019de66b345SSrinivas Kandagatla case 0x7:
1020de66b345SSrinivas Kandagatla snd_soc_jack_report(priv->jack, SND_JACK_BTN_3, btn_mask);
1021de66b345SSrinivas Kandagatla break;
1022de66b345SSrinivas Kandagatla case 0x3:
1023de66b345SSrinivas Kandagatla snd_soc_jack_report(priv->jack, SND_JACK_BTN_2, btn_mask);
1024de66b345SSrinivas Kandagatla break;
1025de66b345SSrinivas Kandagatla case 0x1:
1026de66b345SSrinivas Kandagatla snd_soc_jack_report(priv->jack, SND_JACK_BTN_1, btn_mask);
1027de66b345SSrinivas Kandagatla break;
1028de66b345SSrinivas Kandagatla case 0x0:
1029de66b345SSrinivas Kandagatla /* handle BTN_0 specially for type detection */
1030d430a7e3SDamien Riegel if (!priv->detect_accessory_type)
1031de66b345SSrinivas Kandagatla snd_soc_jack_report(priv->jack,
1032de66b345SSrinivas Kandagatla SND_JACK_BTN_0, btn_mask);
1033de66b345SSrinivas Kandagatla break;
1034de66b345SSrinivas Kandagatla default:
1035732ae454SKuninori Morimoto dev_err(component->dev,
1036de66b345SSrinivas Kandagatla "Unexpected button press result (%x)", btn_result);
1037de66b345SSrinivas Kandagatla break;
1038de66b345SSrinivas Kandagatla }
1039de66b345SSrinivas Kandagatla
1040de66b345SSrinivas Kandagatla return IRQ_HANDLED;
1041de66b345SSrinivas Kandagatla }
1042de66b345SSrinivas Kandagatla
pm8916_mbhc_switch_irq_handler(int irq,void * arg)1043de66b345SSrinivas Kandagatla static irqreturn_t pm8916_mbhc_switch_irq_handler(int irq, void *arg)
1044de66b345SSrinivas Kandagatla {
1045de66b345SSrinivas Kandagatla struct pm8916_wcd_analog_priv *priv = arg;
1046732ae454SKuninori Morimoto struct snd_soc_component *component = priv->component;
1047de66b345SSrinivas Kandagatla bool ins = false;
1048de66b345SSrinivas Kandagatla
1049a6f80d99SKuninori Morimoto if (snd_soc_component_read(component, CDC_A_MBHC_DET_CTL_1) &
1050de66b345SSrinivas Kandagatla CDC_A_MBHC_DET_CTL_MECH_DET_TYPE_MASK)
1051de66b345SSrinivas Kandagatla ins = true;
1052de66b345SSrinivas Kandagatla
1053de66b345SSrinivas Kandagatla /* Set the detection type appropriately */
1054732ae454SKuninori Morimoto snd_soc_component_update_bits(component, CDC_A_MBHC_DET_CTL_1,
1055de66b345SSrinivas Kandagatla CDC_A_MBHC_DET_CTL_MECH_DET_TYPE_MASK,
1056de66b345SSrinivas Kandagatla (!ins << CDC_A_MBHC_DET_CTL_MECH_DET_TYPE_SHIFT));
1057de66b345SSrinivas Kandagatla
1058de66b345SSrinivas Kandagatla
1059de66b345SSrinivas Kandagatla if (ins) { /* hs insertion */
1060de66b345SSrinivas Kandagatla bool micbias_enabled = false;
1061de66b345SSrinivas Kandagatla
1062a6f80d99SKuninori Morimoto if (snd_soc_component_read(component, CDC_A_MICB_2_EN) &
1063de66b345SSrinivas Kandagatla CDC_A_MICB_2_EN_ENABLE)
1064de66b345SSrinivas Kandagatla micbias_enabled = true;
1065de66b345SSrinivas Kandagatla
1066de66b345SSrinivas Kandagatla pm8916_mbhc_configure_bias(priv, micbias_enabled);
1067de66b345SSrinivas Kandagatla
1068de66b345SSrinivas Kandagatla /*
1069de66b345SSrinivas Kandagatla * if only a btn0 press event is receive just before
1070de66b345SSrinivas Kandagatla * insert event then its a 3 pole headphone else if
1071de66b345SSrinivas Kandagatla * both press and release event received then its
1072de66b345SSrinivas Kandagatla * a headset.
1073de66b345SSrinivas Kandagatla */
1074d430a7e3SDamien Riegel if (priv->mbhc_btn0_released)
1075de66b345SSrinivas Kandagatla snd_soc_jack_report(priv->jack,
1076de66b345SSrinivas Kandagatla SND_JACK_HEADSET, hs_jack_mask);
1077d430a7e3SDamien Riegel else
1078d430a7e3SDamien Riegel snd_soc_jack_report(priv->jack,
1079d430a7e3SDamien Riegel SND_JACK_HEADPHONE, hs_jack_mask);
1080de66b345SSrinivas Kandagatla
1081de66b345SSrinivas Kandagatla priv->detect_accessory_type = false;
1082de66b345SSrinivas Kandagatla
1083de66b345SSrinivas Kandagatla } else { /* removal */
1084de66b345SSrinivas Kandagatla snd_soc_jack_report(priv->jack, 0, hs_jack_mask);
1085de66b345SSrinivas Kandagatla priv->detect_accessory_type = true;
1086d430a7e3SDamien Riegel priv->mbhc_btn0_released = false;
1087de66b345SSrinivas Kandagatla }
1088de66b345SSrinivas Kandagatla
1089de66b345SSrinivas Kandagatla return IRQ_HANDLED;
1090de66b345SSrinivas Kandagatla }
1091de66b345SSrinivas Kandagatla
1092585e881eSSrinivas Kandagatla static struct snd_soc_dai_driver pm8916_wcd_analog_dai[] = {
1093585e881eSSrinivas Kandagatla [0] = {
1094585e881eSSrinivas Kandagatla .name = "pm8916_wcd_analog_pdm_rx",
1095585e881eSSrinivas Kandagatla .id = 0,
1096585e881eSSrinivas Kandagatla .playback = {
1097585e881eSSrinivas Kandagatla .stream_name = "PDM Playback",
1098585e881eSSrinivas Kandagatla .rates = MSM8916_WCD_ANALOG_RATES,
1099585e881eSSrinivas Kandagatla .formats = MSM8916_WCD_ANALOG_FORMATS,
1100585e881eSSrinivas Kandagatla .channels_min = 1,
1101585e881eSSrinivas Kandagatla .channels_max = 3,
1102585e881eSSrinivas Kandagatla },
1103585e881eSSrinivas Kandagatla },
1104585e881eSSrinivas Kandagatla [1] = {
1105585e881eSSrinivas Kandagatla .name = "pm8916_wcd_analog_pdm_tx",
1106585e881eSSrinivas Kandagatla .id = 1,
1107585e881eSSrinivas Kandagatla .capture = {
1108585e881eSSrinivas Kandagatla .stream_name = "PDM Capture",
1109585e881eSSrinivas Kandagatla .rates = MSM8916_WCD_ANALOG_RATES,
1110585e881eSSrinivas Kandagatla .formats = MSM8916_WCD_ANALOG_FORMATS,
1111585e881eSSrinivas Kandagatla .channels_min = 1,
1112585e881eSSrinivas Kandagatla .channels_max = 4,
1113585e881eSSrinivas Kandagatla },
1114585e881eSSrinivas Kandagatla },
1115585e881eSSrinivas Kandagatla };
1116585e881eSSrinivas Kandagatla
1117732ae454SKuninori Morimoto static const struct snd_soc_component_driver pm8916_wcd_analog = {
1118585e881eSSrinivas Kandagatla .probe = pm8916_wcd_analog_probe,
1119585e881eSSrinivas Kandagatla .remove = pm8916_wcd_analog_remove,
1120de66b345SSrinivas Kandagatla .set_jack = pm8916_wcd_analog_set_jack,
1121585e881eSSrinivas Kandagatla .controls = pm8916_wcd_analog_snd_controls,
1122585e881eSSrinivas Kandagatla .num_controls = ARRAY_SIZE(pm8916_wcd_analog_snd_controls),
1123585e881eSSrinivas Kandagatla .dapm_widgets = pm8916_wcd_analog_dapm_widgets,
1124585e881eSSrinivas Kandagatla .num_dapm_widgets = ARRAY_SIZE(pm8916_wcd_analog_dapm_widgets),
1125585e881eSSrinivas Kandagatla .dapm_routes = pm8916_wcd_analog_audio_map,
1126585e881eSSrinivas Kandagatla .num_dapm_routes = ARRAY_SIZE(pm8916_wcd_analog_audio_map),
1127732ae454SKuninori Morimoto .idle_bias_on = 1,
1128732ae454SKuninori Morimoto .use_pmdown_time = 1,
1129732ae454SKuninori Morimoto .endianness = 1,
1130585e881eSSrinivas Kandagatla };
1131585e881eSSrinivas Kandagatla
pm8916_wcd_analog_parse_dt(struct device * dev,struct pm8916_wcd_analog_priv * priv)1132585e881eSSrinivas Kandagatla static int pm8916_wcd_analog_parse_dt(struct device *dev,
1133585e881eSSrinivas Kandagatla struct pm8916_wcd_analog_priv *priv)
1134585e881eSSrinivas Kandagatla {
1135de66b345SSrinivas Kandagatla int rval;
1136585e881eSSrinivas Kandagatla
1137585e881eSSrinivas Kandagatla if (of_property_read_bool(dev->of_node, "qcom,micbias1-ext-cap"))
1138585e881eSSrinivas Kandagatla priv->micbias1_cap_mode = MICB_1_EN_EXT_BYP_CAP;
1139585e881eSSrinivas Kandagatla else
1140585e881eSSrinivas Kandagatla priv->micbias1_cap_mode = MICB_1_EN_NO_EXT_BYP_CAP;
1141585e881eSSrinivas Kandagatla
1142585e881eSSrinivas Kandagatla if (of_property_read_bool(dev->of_node, "qcom,micbias2-ext-cap"))
1143585e881eSSrinivas Kandagatla priv->micbias2_cap_mode = MICB_1_EN_EXT_BYP_CAP;
1144585e881eSSrinivas Kandagatla else
1145585e881eSSrinivas Kandagatla priv->micbias2_cap_mode = MICB_1_EN_NO_EXT_BYP_CAP;
1146585e881eSSrinivas Kandagatla
1147e269998dSSrinivas Kandagatla of_property_read_u32(dev->of_node, "qcom,micbias-lvl",
1148e269998dSSrinivas Kandagatla &priv->micbias_mv);
1149e269998dSSrinivas Kandagatla
1150de66b345SSrinivas Kandagatla if (of_property_read_bool(dev->of_node,
1151de66b345SSrinivas Kandagatla "qcom,hphl-jack-type-normally-open"))
1152de66b345SSrinivas Kandagatla priv->hphl_jack_type_normally_open = true;
1153de66b345SSrinivas Kandagatla else
1154de66b345SSrinivas Kandagatla priv->hphl_jack_type_normally_open = false;
1155de66b345SSrinivas Kandagatla
1156de66b345SSrinivas Kandagatla if (of_property_read_bool(dev->of_node,
1157de66b345SSrinivas Kandagatla "qcom,gnd-jack-type-normally-open"))
1158de66b345SSrinivas Kandagatla priv->gnd_jack_type_normally_open = true;
1159de66b345SSrinivas Kandagatla else
1160de66b345SSrinivas Kandagatla priv->gnd_jack_type_normally_open = false;
1161de66b345SSrinivas Kandagatla
1162de66b345SSrinivas Kandagatla priv->mbhc_btn_enabled = true;
1163de66b345SSrinivas Kandagatla rval = of_property_read_u32_array(dev->of_node,
1164de66b345SSrinivas Kandagatla "qcom,mbhc-vthreshold-low",
1165de66b345SSrinivas Kandagatla &priv->vref_btn_cs[0],
1166de66b345SSrinivas Kandagatla MBHC_MAX_BUTTONS);
1167de66b345SSrinivas Kandagatla if (rval < 0) {
1168de66b345SSrinivas Kandagatla priv->mbhc_btn_enabled = false;
1169de66b345SSrinivas Kandagatla } else {
1170de66b345SSrinivas Kandagatla rval = of_property_read_u32_array(dev->of_node,
1171de66b345SSrinivas Kandagatla "qcom,mbhc-vthreshold-high",
1172de66b345SSrinivas Kandagatla &priv->vref_btn_micb[0],
1173de66b345SSrinivas Kandagatla MBHC_MAX_BUTTONS);
1174de66b345SSrinivas Kandagatla if (rval < 0)
1175de66b345SSrinivas Kandagatla priv->mbhc_btn_enabled = false;
1176de66b345SSrinivas Kandagatla }
1177de66b345SSrinivas Kandagatla
1178de66b345SSrinivas Kandagatla if (!priv->mbhc_btn_enabled)
1179de66b345SSrinivas Kandagatla dev_err(dev,
1180de66b345SSrinivas Kandagatla "DT property missing, MBHC btn detection disabled\n");
1181de66b345SSrinivas Kandagatla
1182de66b345SSrinivas Kandagatla
11834323ec25SSrinivas Kandagatla return 0;
11844323ec25SSrinivas Kandagatla }
11854323ec25SSrinivas Kandagatla
pm8916_wcd_analog_spmi_probe(struct platform_device * pdev)11864323ec25SSrinivas Kandagatla static int pm8916_wcd_analog_spmi_probe(struct platform_device *pdev)
11874323ec25SSrinivas Kandagatla {
11884323ec25SSrinivas Kandagatla struct pm8916_wcd_analog_priv *priv;
11894323ec25SSrinivas Kandagatla struct device *dev = &pdev->dev;
1190de66b345SSrinivas Kandagatla int ret, i, irq;
11914323ec25SSrinivas Kandagatla
11924323ec25SSrinivas Kandagatla priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
11934323ec25SSrinivas Kandagatla if (!priv)
11944323ec25SSrinivas Kandagatla return -ENOMEM;
11954323ec25SSrinivas Kandagatla
11964323ec25SSrinivas Kandagatla ret = pm8916_wcd_analog_parse_dt(dev, priv);
11974323ec25SSrinivas Kandagatla if (ret < 0)
11984323ec25SSrinivas Kandagatla return ret;
11994323ec25SSrinivas Kandagatla
1200585e881eSSrinivas Kandagatla for (i = 0; i < ARRAY_SIZE(supply_names); i++)
1201585e881eSSrinivas Kandagatla priv->supplies[i].supply = supply_names[i];
1202585e881eSSrinivas Kandagatla
1203585e881eSSrinivas Kandagatla ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(priv->supplies),
1204585e881eSSrinivas Kandagatla priv->supplies);
1205585e881eSSrinivas Kandagatla if (ret) {
1206585e881eSSrinivas Kandagatla dev_err(dev, "Failed to get regulator supplies %d\n", ret);
1207585e881eSSrinivas Kandagatla return ret;
1208585e881eSSrinivas Kandagatla }
1209585e881eSSrinivas Kandagatla
1210de66b345SSrinivas Kandagatla irq = platform_get_irq_byname(pdev, "mbhc_switch_int");
121197f29c1aSStephan Gerhold if (irq < 0)
121297f29c1aSStephan Gerhold return irq;
1213de66b345SSrinivas Kandagatla
1214a8419a0cSSrinivas Kandagatla ret = devm_request_threaded_irq(dev, irq, NULL,
1215a8419a0cSSrinivas Kandagatla pm8916_mbhc_switch_irq_handler,
1216de66b345SSrinivas Kandagatla IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING |
1217de66b345SSrinivas Kandagatla IRQF_ONESHOT,
1218de66b345SSrinivas Kandagatla "mbhc switch irq", priv);
1219*5c0f9652SStephan Gerhold if (ret) {
1220de66b345SSrinivas Kandagatla dev_err(dev, "cannot request mbhc switch irq\n");
1221*5c0f9652SStephan Gerhold return ret;
1222*5c0f9652SStephan Gerhold }
1223de66b345SSrinivas Kandagatla
1224de66b345SSrinivas Kandagatla if (priv->mbhc_btn_enabled) {
1225de66b345SSrinivas Kandagatla irq = platform_get_irq_byname(pdev, "mbhc_but_press_det");
122697f29c1aSStephan Gerhold if (irq < 0)
122797f29c1aSStephan Gerhold return irq;
1228de66b345SSrinivas Kandagatla
1229a8419a0cSSrinivas Kandagatla ret = devm_request_threaded_irq(dev, irq, NULL,
1230a8419a0cSSrinivas Kandagatla mbhc_btn_press_irq_handler,
1231de66b345SSrinivas Kandagatla IRQF_TRIGGER_RISING |
1232de66b345SSrinivas Kandagatla IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
1233de66b345SSrinivas Kandagatla "mbhc btn press irq", priv);
1234*5c0f9652SStephan Gerhold if (ret) {
1235de66b345SSrinivas Kandagatla dev_err(dev, "cannot request mbhc button press irq\n");
1236*5c0f9652SStephan Gerhold return ret;
1237*5c0f9652SStephan Gerhold }
1238de66b345SSrinivas Kandagatla
1239de66b345SSrinivas Kandagatla irq = platform_get_irq_byname(pdev, "mbhc_but_rel_det");
124097f29c1aSStephan Gerhold if (irq < 0)
124197f29c1aSStephan Gerhold return irq;
1242de66b345SSrinivas Kandagatla
1243a8419a0cSSrinivas Kandagatla ret = devm_request_threaded_irq(dev, irq, NULL,
1244a8419a0cSSrinivas Kandagatla mbhc_btn_release_irq_handler,
1245de66b345SSrinivas Kandagatla IRQF_TRIGGER_RISING |
1246de66b345SSrinivas Kandagatla IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
1247de66b345SSrinivas Kandagatla "mbhc btn release irq", priv);
1248*5c0f9652SStephan Gerhold if (ret) {
1249de66b345SSrinivas Kandagatla dev_err(dev, "cannot request mbhc button release irq\n");
1250*5c0f9652SStephan Gerhold return ret;
1251*5c0f9652SStephan Gerhold }
1252de66b345SSrinivas Kandagatla }
1253de66b345SSrinivas Kandagatla
1254585e881eSSrinivas Kandagatla dev_set_drvdata(dev, priv);
1255585e881eSSrinivas Kandagatla
1256732ae454SKuninori Morimoto return devm_snd_soc_register_component(dev, &pm8916_wcd_analog,
1257585e881eSSrinivas Kandagatla pm8916_wcd_analog_dai,
1258585e881eSSrinivas Kandagatla ARRAY_SIZE(pm8916_wcd_analog_dai));
1259585e881eSSrinivas Kandagatla }
1260585e881eSSrinivas Kandagatla
1261585e881eSSrinivas Kandagatla static const struct of_device_id pm8916_wcd_analog_spmi_match_table[] = {
1262585e881eSSrinivas Kandagatla { .compatible = "qcom,pm8916-wcd-analog-codec", },
1263585e881eSSrinivas Kandagatla { }
1264585e881eSSrinivas Kandagatla };
1265585e881eSSrinivas Kandagatla
126646d69e14SNicolas Dechesne MODULE_DEVICE_TABLE(of, pm8916_wcd_analog_spmi_match_table);
126746d69e14SNicolas Dechesne
1268585e881eSSrinivas Kandagatla static struct platform_driver pm8916_wcd_analog_spmi_driver = {
1269585e881eSSrinivas Kandagatla .driver = {
1270585e881eSSrinivas Kandagatla .name = "qcom,pm8916-wcd-spmi-codec",
1271585e881eSSrinivas Kandagatla .of_match_table = pm8916_wcd_analog_spmi_match_table,
1272585e881eSSrinivas Kandagatla },
1273585e881eSSrinivas Kandagatla .probe = pm8916_wcd_analog_spmi_probe,
1274585e881eSSrinivas Kandagatla };
1275585e881eSSrinivas Kandagatla
1276585e881eSSrinivas Kandagatla module_platform_driver(pm8916_wcd_analog_spmi_driver);
1277585e881eSSrinivas Kandagatla
1278585e881eSSrinivas Kandagatla MODULE_AUTHOR("Srinivas Kandagatla <srinivas.kandagatla@linaro.org>");
1279585e881eSSrinivas Kandagatla MODULE_DESCRIPTION("PMIC PM8916 WCD Analog Codec driver");
1280585e881eSSrinivas Kandagatla MODULE_LICENSE("GPL v2");
1281