1 // SPDX-License-Identifier: GPL-2.0
2 // Copyright (c) 2022, Analog Devices Inc.
4 #include <linux/gpio/consumer.h>
6 #include <linux/module.h>
7 #include <sound/pcm_params.h>
9 #include <linux/gpio.h>
10 #include <sound/tlv.h>
13 static struct reg_default max98396_reg[] = {
14 {MAX98396_R2000_SW_RESET, 0x00},
15 {MAX98396_R2001_INT_RAW1, 0x00},
16 {MAX98396_R2002_INT_RAW2, 0x00},
17 {MAX98396_R2003_INT_RAW3, 0x00},
18 {MAX98396_R2004_INT_RAW4, 0x00},
19 {MAX98396_R2006_INT_STATE1, 0x00},
20 {MAX98396_R2007_INT_STATE2, 0x00},
21 {MAX98396_R2008_INT_STATE3, 0x00},
22 {MAX98396_R2009_INT_STATE4, 0x00},
23 {MAX98396_R200B_INT_FLAG1, 0x00},
24 {MAX98396_R200C_INT_FLAG2, 0x00},
25 {MAX98396_R200D_INT_FLAG3, 0x00},
26 {MAX98396_R200E_INT_FLAG4, 0x00},
27 {MAX98396_R2010_INT_EN1, 0x02},
28 {MAX98396_R2011_INT_EN2, 0x00},
29 {MAX98396_R2012_INT_EN3, 0x00},
30 {MAX98396_R2013_INT_EN4, 0x00},
31 {MAX98396_R2015_INT_FLAG_CLR1, 0x00},
32 {MAX98396_R2016_INT_FLAG_CLR2, 0x00},
33 {MAX98396_R2017_INT_FLAG_CLR3, 0x00},
34 {MAX98396_R2018_INT_FLAG_CLR4, 0x00},
35 {MAX98396_R201F_IRQ_CTRL, 0x00},
36 {MAX98396_R2020_THERM_WARN_THRESH, 0x46},
37 {MAX98396_R2021_THERM_WARN_THRESH2, 0x46},
38 {MAX98396_R2022_THERM_SHDN_THRESH, 0x64},
39 {MAX98396_R2023_THERM_HYSTERESIS, 0x02},
40 {MAX98396_R2024_THERM_FOLDBACK_SET, 0xC5},
41 {MAX98396_R2027_THERM_FOLDBACK_EN, 0x01},
42 {MAX98396_R2030_NOISEGATE_MODE_CTRL, 0x32},
43 {MAX98396_R2033_NOISEGATE_MODE_EN, 0x00},
44 {MAX98396_R2038_CLK_MON_CTRL, 0x00},
45 {MAX98396_R2039_DATA_MON_CTRL, 0x00},
46 {MAX98396_R203F_ENABLE_CTRLS, 0x0F},
47 {MAX98396_R2040_PIN_CFG, 0x55},
48 {MAX98396_R2041_PCM_MODE_CFG, 0xC0},
49 {MAX98396_R2042_PCM_CLK_SETUP, 0x04},
50 {MAX98396_R2043_PCM_SR_SETUP, 0x88},
51 {MAX98396_R2044_PCM_TX_CTRL_1, 0x00},
52 {MAX98396_R2045_PCM_TX_CTRL_2, 0x00},
53 {MAX98396_R2046_PCM_TX_CTRL_3, 0x00},
54 {MAX98396_R2047_PCM_TX_CTRL_4, 0x00},
55 {MAX98396_R2048_PCM_TX_CTRL_5, 0x00},
56 {MAX98396_R2049_PCM_TX_CTRL_6, 0x00},
57 {MAX98396_R204A_PCM_TX_CTRL_7, 0x00},
58 {MAX98396_R204B_PCM_TX_CTRL_8, 0x00},
59 {MAX98396_R204C_PCM_TX_HIZ_CTRL_1, 0xFF},
60 {MAX98396_R204D_PCM_TX_HIZ_CTRL_2, 0xFF},
61 {MAX98396_R204E_PCM_TX_HIZ_CTRL_3, 0xFF},
62 {MAX98396_R204F_PCM_TX_HIZ_CTRL_4, 0xFF},
63 {MAX98396_R2050_PCM_TX_HIZ_CTRL_5, 0xFF},
64 {MAX98396_R2051_PCM_TX_HIZ_CTRL_6, 0xFF},
65 {MAX98396_R2052_PCM_TX_HIZ_CTRL_7, 0xFF},
66 {MAX98396_R2053_PCM_TX_HIZ_CTRL_8, 0xFF},
67 {MAX98396_R2055_PCM_RX_SRC1, 0x00},
68 {MAX98396_R2056_PCM_RX_SRC2, 0x00},
69 {MAX98396_R2058_PCM_BYPASS_SRC, 0x00},
70 {MAX98396_R205D_PCM_TX_SRC_EN, 0x00},
71 {MAX98396_R205E_PCM_RX_EN, 0x00},
72 {MAX98396_R205F_PCM_TX_EN, 0x00},
73 {MAX98396_R2070_ICC_RX_EN_A, 0x00},
74 {MAX98396_R2071_ICC_RX_EN_B, 0x00},
75 {MAX98396_R2072_ICC_TX_CTRL, 0x00},
76 {MAX98396_R207F_ICC_EN, 0x00},
77 {MAX98396_R2083_TONE_GEN_DC_CFG, 0x04},
78 {MAX98396_R2084_TONE_GEN_DC_LVL1, 0x00},
79 {MAX98396_R2085_TONE_GEN_DC_LVL2, 0x00},
80 {MAX98396_R2086_TONE_GEN_DC_LVL3, 0x00},
81 {MAX98396_R208F_TONE_GEN_EN, 0x00},
82 {MAX98396_R2090_AMP_VOL_CTRL, 0x00},
83 {MAX98396_R2091_AMP_PATH_GAIN, 0x0B},
84 {MAX98396_R2092_AMP_DSP_CFG, 0x23},
85 {MAX98396_R2093_SSM_CFG, 0x0D},
86 {MAX98396_R2094_SPK_CLS_DG_THRESH, 0x12},
87 {MAX98396_R2095_SPK_CLS_DG_HDR, 0x17},
88 {MAX98396_R2096_SPK_CLS_DG_HOLD_TIME, 0x17},
89 {MAX98396_R2097_SPK_CLS_DG_DELAY, 0x00},
90 {MAX98396_R2098_SPK_CLS_DG_MODE, 0x00},
91 {MAX98396_R2099_SPK_CLS_DG_VBAT_LVL, 0x03},
92 {MAX98396_R209A_SPK_EDGE_CTRL, 0x00},
93 {MAX98396_R209C_SPK_EDGE_CTRL1, 0x0A},
94 {MAX98396_R209D_SPK_EDGE_CTRL2, 0xAA},
95 {MAX98396_R209E_AMP_CLIP_GAIN, 0x00},
96 {MAX98396_R209F_BYPASS_PATH_CFG, 0x00},
97 {MAX98396_R20A0_AMP_SUPPLY_CTL, 0x00},
98 {MAX98396_R20AF_AMP_EN, 0x00},
99 {MAX98396_R20B0_ADC_SR, 0x30},
100 {MAX98396_R20B1_ADC_PVDD_CFG, 0x00},
101 {MAX98396_R20B2_ADC_VBAT_CFG, 0x00},
102 {MAX98396_R20B3_ADC_THERMAL_CFG, 0x00},
103 {MAX98396_R20B4_ADC_READBACK_CTRL1, 0x00},
104 {MAX98396_R20B5_ADC_READBACK_CTRL2, 0x00},
105 {MAX98396_R20B6_ADC_PVDD_READBACK_MSB, 0x00},
106 {MAX98396_R20B7_ADC_PVDD_READBACK_LSB, 0x00},
107 {MAX98396_R20B8_ADC_VBAT_READBACK_MSB, 0x00},
108 {MAX98396_R20B9_ADC_VBAT_READBACK_LSB, 0x00},
109 {MAX98396_R20BA_ADC_TEMP_READBACK_MSB, 0x00},
110 {MAX98396_R20BB_ADC_TEMP_READBACK_LSB, 0x00},
111 {MAX98396_R20BC_ADC_LO_PVDD_READBACK_MSB, 0x00},
112 {MAX98396_R20BD_ADC_LO_PVDD_READBACK_LSB, 0x00},
113 {MAX98396_R20BE_ADC_LO_VBAT_READBACK_MSB, 0x00},
114 {MAX98396_R20BF_ADC_LO_VBAT_READBACK_LSB, 0x00},
115 {MAX98396_R20C7_ADC_CFG, 0x00},
116 {MAX98396_R20D0_DHT_CFG1, 0x00},
117 {MAX98396_R20D1_LIMITER_CFG1, 0x08},
118 {MAX98396_R20D2_LIMITER_CFG2, 0x00},
119 {MAX98396_R20D3_DHT_CFG2, 0x14},
120 {MAX98396_R20D4_DHT_CFG3, 0x02},
121 {MAX98396_R20D5_DHT_CFG4, 0x04},
122 {MAX98396_R20D6_DHT_HYSTERESIS_CFG, 0x07},
123 {MAX98396_R20DF_DHT_EN, 0x00},
124 {MAX98396_R20E0_IV_SENSE_PATH_CFG, 0x04},
125 {MAX98396_R20E4_IV_SENSE_PATH_EN, 0x00},
126 {MAX98396_R20E5_BPE_STATE, 0x00},
127 {MAX98396_R20E6_BPE_L3_THRESH_MSB, 0x00},
128 {MAX98396_R20E7_BPE_L3_THRESH_LSB, 0x00},
129 {MAX98396_R20E8_BPE_L2_THRESH_MSB, 0x00},
130 {MAX98396_R20E9_BPE_L2_THRESH_LSB, 0x00},
131 {MAX98396_R20EA_BPE_L1_THRESH_MSB, 0x00},
132 {MAX98396_R20EB_BPE_L1_THRESH_LSB, 0x00},
133 {MAX98396_R20EC_BPE_L0_THRESH_MSB, 0x00},
134 {MAX98396_R20ED_BPE_L0_THRESH_LSB, 0x00},
135 {MAX98396_R20EE_BPE_L3_DWELL_HOLD_TIME, 0x00},
136 {MAX98396_R20EF_BPE_L2_DWELL_HOLD_TIME, 0x00},
137 {MAX98396_R20F0_BPE_L1_DWELL_HOLD_TIME, 0x00},
138 {MAX98396_R20F1_BPE_L0_HOLD_TIME, 0x00},
139 {MAX98396_R20F2_BPE_L3_ATTACK_REL_STEP, 0x00},
140 {MAX98396_R20F3_BPE_L2_ATTACK_REL_STEP, 0x00},
141 {MAX98396_R20F4_BPE_L1_ATTACK_REL_STEP, 0x00},
142 {MAX98396_R20F5_BPE_L0_ATTACK_REL_STEP, 0x00},
143 {MAX98396_R20F6_BPE_L3_MAX_GAIN_ATTN, 0x00},
144 {MAX98396_R20F7_BPE_L2_MAX_GAIN_ATTN, 0x00},
145 {MAX98396_R20F8_BPE_L1_MAX_GAIN_ATTN, 0x00},
146 {MAX98396_R20F9_BPE_L0_MAX_GAIN_ATTN, 0x00},
147 {MAX98396_R20FA_BPE_L3_ATT_REL_RATE, 0x00},
148 {MAX98396_R20FB_BPE_L2_ATT_REL_RATE, 0x00},
149 {MAX98396_R20FC_BPE_L1_ATT_REL_RATE, 0x00},
150 {MAX98396_R20FD_BPE_L0_ATT_REL_RATE, 0x00},
151 {MAX98396_R20FE_BPE_L3_LIMITER_CFG, 0x00},
152 {MAX98396_R20FF_BPE_L2_LIMITER_CFG, 0x00},
153 {MAX98396_R2100_BPE_L1_LIMITER_CFG, 0x00},
154 {MAX98396_R2101_BPE_L0_LIMITER_CFG, 0x00},
155 {MAX98396_R2102_BPE_L3_LIM_ATT_REL_RATE, 0x00},
156 {MAX98396_R2103_BPE_L2_LIM_ATT_REL_RATE, 0x00},
157 {MAX98396_R2104_BPE_L1_LIM_ATT_REL_RATE, 0x00},
158 {MAX98396_R2105_BPE_L0_LIM_ATT_REL_RATE, 0x00},
159 {MAX98396_R2106_BPE_THRESH_HYSTERESIS, 0x00},
160 {MAX98396_R2107_BPE_INFINITE_HOLD_CLR, 0x00},
161 {MAX98396_R2108_BPE_SUPPLY_SRC, 0x00},
162 {MAX98396_R2109_BPE_LOW_STATE, 0x00},
163 {MAX98396_R210A_BPE_LOW_GAIN, 0x00},
164 {MAX98396_R210B_BPE_LOW_LIMITER, 0x00},
165 {MAX98396_R210D_BPE_EN, 0x00},
166 {MAX98396_R210E_AUTO_RESTART, 0x00},
167 {MAX98396_R210F_GLOBAL_EN, 0x00},
168 {MAX98396_R21FF_REVISION_ID, 0x00},
171 static struct reg_default max98397_reg[] = {
172 {MAX98396_R2000_SW_RESET, 0x00},
173 {MAX98396_R2001_INT_RAW1, 0x00},
174 {MAX98396_R2002_INT_RAW2, 0x00},
175 {MAX98396_R2003_INT_RAW3, 0x00},
176 {MAX98396_R2004_INT_RAW4, 0x00},
177 {MAX98396_R2006_INT_STATE1, 0x00},
178 {MAX98396_R2007_INT_STATE2, 0x00},
179 {MAX98396_R2008_INT_STATE3, 0x00},
180 {MAX98396_R2009_INT_STATE4, 0x00},
181 {MAX98396_R200B_INT_FLAG1, 0x00},
182 {MAX98396_R200C_INT_FLAG2, 0x00},
183 {MAX98396_R200D_INT_FLAG3, 0x00},
184 {MAX98396_R200E_INT_FLAG4, 0x00},
185 {MAX98396_R2010_INT_EN1, 0x02},
186 {MAX98396_R2011_INT_EN2, 0x00},
187 {MAX98396_R2012_INT_EN3, 0x00},
188 {MAX98396_R2013_INT_EN4, 0x00},
189 {MAX98396_R2015_INT_FLAG_CLR1, 0x00},
190 {MAX98396_R2016_INT_FLAG_CLR2, 0x00},
191 {MAX98396_R2017_INT_FLAG_CLR3, 0x00},
192 {MAX98396_R2018_INT_FLAG_CLR4, 0x00},
193 {MAX98396_R201F_IRQ_CTRL, 0x00},
194 {MAX98396_R2020_THERM_WARN_THRESH, 0x46},
195 {MAX98396_R2021_THERM_WARN_THRESH2, 0x46},
196 {MAX98396_R2022_THERM_SHDN_THRESH, 0x64},
197 {MAX98396_R2023_THERM_HYSTERESIS, 0x02},
198 {MAX98396_R2024_THERM_FOLDBACK_SET, 0xC5},
199 {MAX98396_R2027_THERM_FOLDBACK_EN, 0x01},
200 {MAX98396_R2030_NOISEGATE_MODE_CTRL, 0x32},
201 {MAX98396_R2033_NOISEGATE_MODE_EN, 0x00},
202 {MAX98396_R2038_CLK_MON_CTRL, 0x00},
203 {MAX98396_R2039_DATA_MON_CTRL, 0x00},
204 {MAX98397_R203A_SPK_MON_THRESH, 0x03},
205 {MAX98396_R203F_ENABLE_CTRLS, 0x0F},
206 {MAX98396_R2040_PIN_CFG, 0x55},
207 {MAX98396_R2041_PCM_MODE_CFG, 0xC0},
208 {MAX98396_R2042_PCM_CLK_SETUP, 0x04},
209 {MAX98396_R2043_PCM_SR_SETUP, 0x88},
210 {MAX98396_R2044_PCM_TX_CTRL_1, 0x00},
211 {MAX98396_R2045_PCM_TX_CTRL_2, 0x00},
212 {MAX98396_R2046_PCM_TX_CTRL_3, 0x00},
213 {MAX98396_R2047_PCM_TX_CTRL_4, 0x00},
214 {MAX98396_R2048_PCM_TX_CTRL_5, 0x00},
215 {MAX98396_R2049_PCM_TX_CTRL_6, 0x00},
216 {MAX98396_R204A_PCM_TX_CTRL_7, 0x00},
217 {MAX98396_R204B_PCM_TX_CTRL_8, 0x00},
218 {MAX98397_R204C_PCM_TX_CTRL_9, 0x00},
219 {MAX98397_R204D_PCM_TX_HIZ_CTRL_1, 0xFF},
220 {MAX98397_R204E_PCM_TX_HIZ_CTRL_2, 0xFF},
221 {MAX98397_R204F_PCM_TX_HIZ_CTRL_3, 0xFF},
222 {MAX98397_R2050_PCM_TX_HIZ_CTRL_4, 0xFF},
223 {MAX98397_R2051_PCM_TX_HIZ_CTRL_5, 0xFF},
224 {MAX98397_R2052_PCM_TX_HIZ_CTRL_6, 0xFF},
225 {MAX98397_R2053_PCM_TX_HIZ_CTRL_7, 0xFF},
226 {MAX98397_R2054_PCM_TX_HIZ_CTRL_8, 0xFF},
227 {MAX98397_R2056_PCM_RX_SRC1, 0x00},
228 {MAX98397_R2057_PCM_RX_SRC2, 0x00},
229 {MAX98396_R2058_PCM_BYPASS_SRC, 0x00},
230 {MAX98396_R205D_PCM_TX_SRC_EN, 0x00},
231 {MAX98396_R205E_PCM_RX_EN, 0x00},
232 {MAX98396_R205F_PCM_TX_EN, 0x00},
233 {MAX98397_R2060_PCM_TX_SUPPLY_SEL, 0x00},
234 {MAX98396_R2070_ICC_RX_EN_A, 0x00},
235 {MAX98396_R2071_ICC_RX_EN_B, 0x00},
236 {MAX98396_R2072_ICC_TX_CTRL, 0x00},
237 {MAX98396_R207F_ICC_EN, 0x00},
238 {MAX98396_R2083_TONE_GEN_DC_CFG, 0x04},
239 {MAX98396_R2084_TONE_GEN_DC_LVL1, 0x00},
240 {MAX98396_R2085_TONE_GEN_DC_LVL2, 0x00},
241 {MAX98396_R2086_TONE_GEN_DC_LVL3, 0x00},
242 {MAX98396_R208F_TONE_GEN_EN, 0x00},
243 {MAX98396_R2090_AMP_VOL_CTRL, 0x00},
244 {MAX98396_R2091_AMP_PATH_GAIN, 0x12},
245 {MAX98396_R2092_AMP_DSP_CFG, 0x22},
246 {MAX98396_R2093_SSM_CFG, 0x08},
247 {MAX98396_R2094_SPK_CLS_DG_THRESH, 0x12},
248 {MAX98396_R2095_SPK_CLS_DG_HDR, 0x17},
249 {MAX98396_R2096_SPK_CLS_DG_HOLD_TIME, 0x17},
250 {MAX98396_R2097_SPK_CLS_DG_DELAY, 0x00},
251 {MAX98396_R2098_SPK_CLS_DG_MODE, 0x00},
252 {MAX98396_R2099_SPK_CLS_DG_VBAT_LVL, 0x03},
253 {MAX98396_R209A_SPK_EDGE_CTRL, 0x00},
254 {MAX98397_R209B_SPK_PATH_WB_ONLY, 0x00},
255 {MAX98396_R209C_SPK_EDGE_CTRL1, 0x03},
256 {MAX98396_R209D_SPK_EDGE_CTRL2, 0xFC},
257 {MAX98396_R209E_AMP_CLIP_GAIN, 0x00},
258 {MAX98396_R209F_BYPASS_PATH_CFG, 0x00},
259 {MAX98396_R20AF_AMP_EN, 0x00},
260 {MAX98396_R20B0_ADC_SR, 0x30},
261 {MAX98396_R20B1_ADC_PVDD_CFG, 0x00},
262 {MAX98396_R20B2_ADC_VBAT_CFG, 0x00},
263 {MAX98396_R20B3_ADC_THERMAL_CFG, 0x00},
264 {MAX98397_R20B4_ADC_VDDH_CFG, 0x00},
265 {MAX98397_R20B5_ADC_READBACK_CTRL1, 0x00},
266 {MAX98397_R20B6_ADC_READBACK_CTRL2, 0x00},
267 {MAX98397_R20B7_ADC_PVDD_READBACK_MSB, 0x00},
268 {MAX98397_R20B8_ADC_PVDD_READBACK_LSB, 0x00},
269 {MAX98397_R20B9_ADC_VBAT_READBACK_MSB, 0x00},
270 {MAX98397_R20BA_ADC_VBAT_READBACK_LSB, 0x00},
271 {MAX98397_R20BB_ADC_TEMP_READBACK_MSB, 0x00},
272 {MAX98397_R20BC_ADC_TEMP_READBACK_LSB, 0x00},
273 {MAX98397_R20BD_ADC_VDDH__READBACK_MSB, 0x00},
274 {MAX98397_R20BE_ADC_VDDH_READBACK_LSB, 0x00},
275 {MAX98396_R20BF_ADC_LO_VBAT_READBACK_LSB, 0x00},
276 {MAX98397_R20C3_ADC_LO_VDDH_READBACK_MSB, 0x00},
277 {MAX98397_R20C4_ADC_LO_VDDH_READBACK_LSB, 0x00},
278 {MAX98397_R20C5_MEAS_ADC_OPTIMAL_MODE, 0x04},
279 {MAX98396_R20C7_ADC_CFG, 0x00},
280 {MAX98396_R20D0_DHT_CFG1, 0x00},
281 {MAX98396_R20D1_LIMITER_CFG1, 0x08},
282 {MAX98396_R20D2_LIMITER_CFG2, 0x00},
283 {MAX98396_R20D3_DHT_CFG2, 0x14},
284 {MAX98396_R20D4_DHT_CFG3, 0x02},
285 {MAX98396_R20D5_DHT_CFG4, 0x04},
286 {MAX98396_R20D6_DHT_HYSTERESIS_CFG, 0x07},
287 {MAX98396_R20DF_DHT_EN, 0x00},
288 {MAX98396_R20E0_IV_SENSE_PATH_CFG, 0x04},
289 {MAX98396_R20E4_IV_SENSE_PATH_EN, 0x00},
290 {MAX98396_R20E5_BPE_STATE, 0x00},
291 {MAX98396_R20E6_BPE_L3_THRESH_MSB, 0x00},
292 {MAX98396_R20E7_BPE_L3_THRESH_LSB, 0x00},
293 {MAX98396_R20E8_BPE_L2_THRESH_MSB, 0x00},
294 {MAX98396_R20E9_BPE_L2_THRESH_LSB, 0x00},
295 {MAX98396_R20EA_BPE_L1_THRESH_MSB, 0x00},
296 {MAX98396_R20EB_BPE_L1_THRESH_LSB, 0x00},
297 {MAX98396_R20EC_BPE_L0_THRESH_MSB, 0x00},
298 {MAX98396_R20ED_BPE_L0_THRESH_LSB, 0x00},
299 {MAX98396_R20EE_BPE_L3_DWELL_HOLD_TIME, 0x00},
300 {MAX98396_R20EF_BPE_L2_DWELL_HOLD_TIME, 0x00},
301 {MAX98396_R20F0_BPE_L1_DWELL_HOLD_TIME, 0x00},
302 {MAX98396_R20F1_BPE_L0_HOLD_TIME, 0x00},
303 {MAX98396_R20F2_BPE_L3_ATTACK_REL_STEP, 0x00},
304 {MAX98396_R20F3_BPE_L2_ATTACK_REL_STEP, 0x00},
305 {MAX98396_R20F4_BPE_L1_ATTACK_REL_STEP, 0x00},
306 {MAX98396_R20F5_BPE_L0_ATTACK_REL_STEP, 0x00},
307 {MAX98396_R20F6_BPE_L3_MAX_GAIN_ATTN, 0x00},
308 {MAX98396_R20F7_BPE_L2_MAX_GAIN_ATTN, 0x00},
309 {MAX98396_R20F8_BPE_L1_MAX_GAIN_ATTN, 0x00},
310 {MAX98396_R20F9_BPE_L0_MAX_GAIN_ATTN, 0x00},
311 {MAX98396_R20FA_BPE_L3_ATT_REL_RATE, 0x00},
312 {MAX98396_R20FB_BPE_L2_ATT_REL_RATE, 0x00},
313 {MAX98396_R20FC_BPE_L1_ATT_REL_RATE, 0x00},
314 {MAX98396_R20FD_BPE_L0_ATT_REL_RATE, 0x00},
315 {MAX98396_R20FE_BPE_L3_LIMITER_CFG, 0x00},
316 {MAX98396_R20FF_BPE_L2_LIMITER_CFG, 0x00},
317 {MAX98396_R2100_BPE_L1_LIMITER_CFG, 0x00},
318 {MAX98396_R2101_BPE_L0_LIMITER_CFG, 0x00},
319 {MAX98396_R2102_BPE_L3_LIM_ATT_REL_RATE, 0x00},
320 {MAX98396_R2103_BPE_L2_LIM_ATT_REL_RATE, 0x00},
321 {MAX98396_R2104_BPE_L1_LIM_ATT_REL_RATE, 0x00},
322 {MAX98396_R2105_BPE_L0_LIM_ATT_REL_RATE, 0x00},
323 {MAX98396_R2106_BPE_THRESH_HYSTERESIS, 0x00},
324 {MAX98396_R2107_BPE_INFINITE_HOLD_CLR, 0x00},
325 {MAX98396_R2108_BPE_SUPPLY_SRC, 0x00},
326 {MAX98396_R2109_BPE_LOW_STATE, 0x00},
327 {MAX98396_R210A_BPE_LOW_GAIN, 0x00},
328 {MAX98396_R210B_BPE_LOW_LIMITER, 0x00},
329 {MAX98396_R210D_BPE_EN, 0x00},
330 {MAX98396_R210E_AUTO_RESTART, 0x00},
331 {MAX98396_R210F_GLOBAL_EN, 0x00},
332 {MAX98397_R22FF_REVISION_ID, 0x00},
335 static void max98396_global_enable_onoff(struct regmap *regmap, bool onoff)
337 regmap_write(regmap, MAX98396_R210F_GLOBAL_EN, onoff ? 1 : 0);
338 usleep_range(11000, 12000);
341 static int max98396_dai_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
343 struct snd_soc_component *component = codec_dai->component;
344 struct max98396_priv *max98396 = snd_soc_component_get_drvdata(component);
345 unsigned int format = 0;
346 unsigned int bclk_pol = 0;
351 dev_dbg(component->dev, "%s: fmt 0x%08X\n", __func__, fmt);
353 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
354 case SND_SOC_DAIFMT_NB_NF:
356 case SND_SOC_DAIFMT_NB_IF:
357 format = MAX98396_PCM_MODE_CFG_LRCLKEDGE;
359 case SND_SOC_DAIFMT_IB_NF:
360 bclk_pol = MAX98396_PCM_MODE_CFG_BCLKEDGE;
362 case SND_SOC_DAIFMT_IB_IF:
363 bclk_pol = MAX98396_PCM_MODE_CFG_BCLKEDGE;
364 format = MAX98396_PCM_MODE_CFG_LRCLKEDGE;
368 dev_err(component->dev, "DAI invert mode unsupported\n");
372 /* interface format */
373 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
374 case SND_SOC_DAIFMT_I2S:
375 format |= MAX98396_PCM_FORMAT_I2S;
377 case SND_SOC_DAIFMT_LEFT_J:
378 format |= MAX98396_PCM_FORMAT_LJ;
380 case SND_SOC_DAIFMT_DSP_A:
381 format |= MAX98396_PCM_FORMAT_TDM_MODE1;
383 case SND_SOC_DAIFMT_DSP_B:
384 format |= MAX98396_PCM_FORMAT_TDM_MODE0;
390 ret = regmap_read(max98396->regmap, MAX98396_R210F_GLOBAL_EN, &status);
395 ret = regmap_read(max98396->regmap, MAX98396_R2041_PCM_MODE_CFG, ®);
398 if (format != (reg & MAX98396_PCM_BCLKEDGE_BSEL_MASK)) {
401 ret = regmap_read(max98396->regmap,
402 MAX98396_R2042_PCM_CLK_SETUP, ®);
405 if (bclk_pol != (reg & MAX98396_PCM_MODE_CFG_BCLKEDGE))
408 /* GLOBAL_EN OFF prior to pcm mode, clock configuration change */
410 max98396_global_enable_onoff(max98396->regmap, false);
413 regmap_update_bits(max98396->regmap,
414 MAX98396_R2041_PCM_MODE_CFG,
415 MAX98396_PCM_BCLKEDGE_BSEL_MASK,
418 regmap_update_bits(max98396->regmap,
419 MAX98396_R2042_PCM_CLK_SETUP,
420 MAX98396_PCM_MODE_CFG_BCLKEDGE,
423 if (status && update)
424 max98396_global_enable_onoff(max98396->regmap, true);
429 /* BCLKs per LRCLK */
430 static const int bclk_sel_table[] = {
431 32, 48, 64, 96, 128, 192, 256, 384, 512, 320,
434 static int max98396_get_bclk_sel(int bclk)
437 /* match BCLKs per LRCLK */
438 for (i = 0; i < ARRAY_SIZE(bclk_sel_table); i++) {
439 if (bclk_sel_table[i] == bclk)
445 static int max98396_set_clock(struct snd_soc_component *component,
446 struct snd_pcm_hw_params *params)
448 struct max98396_priv *max98396 = snd_soc_component_get_drvdata(component);
449 /* BCLK/LRCLK ratio calculation */
450 int blr_clk_ratio = params_channels(params) * max98396->ch_size;
453 if (!max98396->tdm_mode) {
454 /* BCLK configuration */
455 value = max98396_get_bclk_sel(blr_clk_ratio);
457 dev_err(component->dev, "format unsupported %d\n",
458 params_format(params));
462 regmap_update_bits(max98396->regmap,
463 MAX98396_R2042_PCM_CLK_SETUP,
464 MAX98396_PCM_CLK_SETUP_BSEL_MASK,
471 static int max98396_dai_hw_params(struct snd_pcm_substream *substream,
472 struct snd_pcm_hw_params *params,
473 struct snd_soc_dai *dai)
475 struct snd_soc_component *component = dai->component;
476 struct max98396_priv *max98396 = snd_soc_component_get_drvdata(component);
477 unsigned int sampling_rate = 0;
478 unsigned int chan_sz = 0;
483 /* pcm mode configuration */
484 switch (snd_pcm_format_width(params_format(params))) {
486 chan_sz = MAX98396_PCM_MODE_CFG_CHANSZ_16;
489 chan_sz = MAX98396_PCM_MODE_CFG_CHANSZ_24;
492 chan_sz = MAX98396_PCM_MODE_CFG_CHANSZ_32;
495 dev_err(component->dev, "format unsupported %d\n",
496 params_format(params));
500 max98396->ch_size = snd_pcm_format_width(params_format(params));
502 dev_dbg(component->dev, "format supported %d",
503 params_format(params));
505 /* sampling rate configuration */
506 switch (params_rate(params)) {
508 sampling_rate = MAX98396_PCM_SR_8000;
511 sampling_rate = MAX98396_PCM_SR_11025;
514 sampling_rate = MAX98396_PCM_SR_12000;
517 sampling_rate = MAX98396_PCM_SR_16000;
520 sampling_rate = MAX98396_PCM_SR_22050;
523 sampling_rate = MAX98396_PCM_SR_24000;
526 sampling_rate = MAX98396_PCM_SR_32000;
529 sampling_rate = MAX98396_PCM_SR_44100;
532 sampling_rate = MAX98396_PCM_SR_48000;
535 sampling_rate = MAX98396_PCM_SR_88200;
538 sampling_rate = MAX98396_PCM_SR_96000;
541 sampling_rate = MAX98396_PCM_SR_192000;
544 dev_err(component->dev, "rate %d not supported\n",
545 params_rate(params));
549 ret = regmap_read(max98396->regmap, MAX98396_R210F_GLOBAL_EN, &status);
554 ret = regmap_read(max98396->regmap, MAX98396_R2041_PCM_MODE_CFG, ®);
557 if (chan_sz != (reg & MAX98396_PCM_MODE_CFG_CHANSZ_MASK)) {
560 ret = regmap_read(max98396->regmap, MAX98396_R2043_PCM_SR_SETUP, ®);
563 if (sampling_rate != (reg & MAX98396_PCM_SR_MASK))
567 /* GLOBAL_EN OFF prior to channel size and sampling rate change */
569 max98396_global_enable_onoff(max98396->regmap, false);
572 /* set channel size */
573 regmap_update_bits(max98396->regmap, MAX98396_R2041_PCM_MODE_CFG,
574 MAX98396_PCM_MODE_CFG_CHANSZ_MASK, chan_sz);
576 /* set DAI_SR to correct LRCLK frequency */
577 regmap_update_bits(max98396->regmap, MAX98396_R2043_PCM_SR_SETUP,
578 MAX98396_PCM_SR_MASK, sampling_rate);
580 /* set sampling rate of IV */
581 if (max98396->interleave_mode &&
582 sampling_rate > MAX98396_PCM_SR_16000)
583 regmap_update_bits(max98396->regmap,
584 MAX98396_R2043_PCM_SR_SETUP,
585 MAX98396_IVADC_SR_MASK,
587 << MAX98396_IVADC_SR_SHIFT);
589 regmap_update_bits(max98396->regmap,
590 MAX98396_R2043_PCM_SR_SETUP,
591 MAX98396_IVADC_SR_MASK,
592 sampling_rate << MAX98396_IVADC_SR_SHIFT);
594 ret = max98396_set_clock(component, params);
596 if (status && update)
597 max98396_global_enable_onoff(max98396->regmap, true);
605 static int max98396_dai_tdm_slot(struct snd_soc_dai *dai,
606 unsigned int tx_mask, unsigned int rx_mask,
607 int slots, int slot_width)
609 struct snd_soc_component *component = dai->component;
610 struct max98396_priv *max98396 =
611 snd_soc_component_get_drvdata(component);
613 unsigned int chan_sz = 0;
618 if (!tx_mask && !rx_mask && !slots && !slot_width)
619 max98396->tdm_mode = false;
621 max98396->tdm_mode = true;
623 /* BCLK configuration */
624 bsel = max98396_get_bclk_sel(slots * slot_width);
626 dev_err(component->dev, "BCLK %d not supported\n",
631 /* Channel size configuration */
632 switch (slot_width) {
634 chan_sz = MAX98396_PCM_MODE_CFG_CHANSZ_16;
637 chan_sz = MAX98396_PCM_MODE_CFG_CHANSZ_24;
640 chan_sz = MAX98396_PCM_MODE_CFG_CHANSZ_32;
643 dev_err(component->dev, "format unsupported %d\n",
648 ret = regmap_read(max98396->regmap, MAX98396_R210F_GLOBAL_EN, &status);
653 ret = regmap_read(max98396->regmap, MAX98396_R2042_PCM_CLK_SETUP, ®);
656 if (bsel != (reg & MAX98396_PCM_CLK_SETUP_BSEL_MASK)) {
659 ret = regmap_read(max98396->regmap, MAX98396_R2041_PCM_MODE_CFG, ®);
662 if (chan_sz != (reg & MAX98396_PCM_MODE_CFG_CHANSZ_MASK))
666 /* GLOBAL_EN OFF prior to channel size and BCLK per LRCLK change */
668 max98396_global_enable_onoff(max98396->regmap, false);
671 regmap_update_bits(max98396->regmap,
672 MAX98396_R2042_PCM_CLK_SETUP,
673 MAX98396_PCM_CLK_SETUP_BSEL_MASK,
676 regmap_update_bits(max98396->regmap,
677 MAX98396_R2041_PCM_MODE_CFG,
678 MAX98396_PCM_MODE_CFG_CHANSZ_MASK, chan_sz);
680 /* Rx slot configuration */
681 if (max98396->device_id == CODEC_TYPE_MAX98396) {
682 regmap_update_bits(max98396->regmap,
683 MAX98396_R2056_PCM_RX_SRC2,
684 MAX98396_PCM_DMIX_CH0_SRC_MASK,
686 regmap_update_bits(max98396->regmap,
687 MAX98396_R2056_PCM_RX_SRC2,
688 MAX98396_PCM_DMIX_CH1_SRC_MASK,
689 rx_mask << MAX98396_PCM_DMIX_CH1_SHIFT);
691 regmap_update_bits(max98396->regmap,
692 MAX98397_R2057_PCM_RX_SRC2,
693 MAX98396_PCM_DMIX_CH0_SRC_MASK,
695 regmap_update_bits(max98396->regmap,
696 MAX98397_R2057_PCM_RX_SRC2,
697 MAX98396_PCM_DMIX_CH1_SRC_MASK,
698 rx_mask << MAX98396_PCM_DMIX_CH1_SHIFT);
701 /* Tx slot Hi-Z configuration */
702 if (max98396->device_id == CODEC_TYPE_MAX98396) {
703 regmap_write(max98396->regmap,
704 MAX98396_R2053_PCM_TX_HIZ_CTRL_8,
706 regmap_write(max98396->regmap,
707 MAX98396_R2052_PCM_TX_HIZ_CTRL_7,
708 (~tx_mask & 0xFF00) >> 8);
710 regmap_write(max98396->regmap,
711 MAX98397_R2054_PCM_TX_HIZ_CTRL_8,
713 regmap_write(max98396->regmap,
714 MAX98397_R2053_PCM_TX_HIZ_CTRL_7,
715 (~tx_mask & 0xFF00) >> 8);
718 if (status && update)
719 max98396_global_enable_onoff(max98396->regmap, true);
724 #define MAX98396_RATES SNDRV_PCM_RATE_8000_192000
726 #define MAX98396_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
727 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
729 static const struct snd_soc_dai_ops max98396_dai_ops = {
730 .set_fmt = max98396_dai_set_fmt,
731 .hw_params = max98396_dai_hw_params,
732 .set_tdm_slot = max98396_dai_tdm_slot,
735 static int max98396_dac_event(struct snd_soc_dapm_widget *w,
736 struct snd_kcontrol *kcontrol, int event)
738 struct snd_soc_component *component =
739 snd_soc_dapm_to_component(w->dapm);
740 struct max98396_priv *max98396 =
741 snd_soc_component_get_drvdata(component);
744 case SND_SOC_DAPM_POST_PMU:
745 max98396_global_enable_onoff(max98396->regmap, true);
747 case SND_SOC_DAPM_PRE_PMD:
748 max98396_global_enable_onoff(max98396->regmap, false);
750 max98396->tdm_mode = false;
758 static bool max98396_readable_register(struct device *dev, unsigned int reg)
761 case MAX98396_R2001_INT_RAW1 ... MAX98396_R2004_INT_RAW4:
762 case MAX98396_R2006_INT_STATE1 ... MAX98396_R2009_INT_STATE4:
763 case MAX98396_R200B_INT_FLAG1 ... MAX98396_R200E_INT_FLAG4:
764 case MAX98396_R2010_INT_EN1 ... MAX98396_R2013_INT_EN4:
765 case MAX98396_R2015_INT_FLAG_CLR1 ... MAX98396_R2018_INT_FLAG_CLR4:
766 case MAX98396_R201F_IRQ_CTRL ... MAX98396_R2024_THERM_FOLDBACK_SET:
767 case MAX98396_R2027_THERM_FOLDBACK_EN:
768 case MAX98396_R2030_NOISEGATE_MODE_CTRL:
769 case MAX98396_R2033_NOISEGATE_MODE_EN:
770 case MAX98396_R2038_CLK_MON_CTRL ... MAX98396_R2039_DATA_MON_CTRL:
771 case MAX98396_R203F_ENABLE_CTRLS ... MAX98396_R2053_PCM_TX_HIZ_CTRL_8:
772 case MAX98396_R2055_PCM_RX_SRC1 ... MAX98396_R2056_PCM_RX_SRC2:
773 case MAX98396_R2058_PCM_BYPASS_SRC:
774 case MAX98396_R205D_PCM_TX_SRC_EN ... MAX98396_R205F_PCM_TX_EN:
775 case MAX98396_R2070_ICC_RX_EN_A... MAX98396_R2072_ICC_TX_CTRL:
776 case MAX98396_R207F_ICC_EN:
777 case MAX98396_R2083_TONE_GEN_DC_CFG ... MAX98396_R2086_TONE_GEN_DC_LVL3:
778 case MAX98396_R208F_TONE_GEN_EN ... MAX98396_R209A_SPK_EDGE_CTRL:
779 case MAX98396_R209C_SPK_EDGE_CTRL1 ... MAX98396_R20A0_AMP_SUPPLY_CTL:
780 case MAX98396_R20AF_AMP_EN ... MAX98396_R20BF_ADC_LO_VBAT_READBACK_LSB:
781 case MAX98396_R20C7_ADC_CFG:
782 case MAX98396_R20D0_DHT_CFG1 ... MAX98396_R20D6_DHT_HYSTERESIS_CFG:
783 case MAX98396_R20DF_DHT_EN:
784 case MAX98396_R20E0_IV_SENSE_PATH_CFG:
785 case MAX98396_R20E4_IV_SENSE_PATH_EN
786 ... MAX98396_R2106_BPE_THRESH_HYSTERESIS:
787 case MAX98396_R2108_BPE_SUPPLY_SRC ... MAX98396_R210B_BPE_LOW_LIMITER:
788 case MAX98396_R210D_BPE_EN ... MAX98396_R210F_GLOBAL_EN:
789 case MAX98396_R21FF_REVISION_ID:
796 static bool max98396_volatile_reg(struct device *dev, unsigned int reg)
799 case MAX98396_R2000_SW_RESET:
800 case MAX98396_R2001_INT_RAW1 ... MAX98396_R200E_INT_FLAG4:
801 case MAX98396_R2041_PCM_MODE_CFG:
802 case MAX98396_R20B6_ADC_PVDD_READBACK_MSB
803 ... MAX98396_R20BF_ADC_LO_VBAT_READBACK_LSB:
804 case MAX98396_R20E5_BPE_STATE:
805 case MAX98396_R2109_BPE_LOW_STATE
806 ... MAX98396_R210B_BPE_LOW_LIMITER:
807 case MAX98396_R210F_GLOBAL_EN:
808 case MAX98396_R21FF_REVISION_ID:
815 static bool max98397_readable_register(struct device *dev, unsigned int reg)
818 case MAX98396_R2001_INT_RAW1 ... MAX98396_R2004_INT_RAW4:
819 case MAX98396_R2006_INT_STATE1 ... MAX98396_R2009_INT_STATE4:
820 case MAX98396_R200B_INT_FLAG1 ... MAX98396_R200E_INT_FLAG4:
821 case MAX98396_R2010_INT_EN1 ... MAX98396_R2013_INT_EN4:
822 case MAX98396_R2015_INT_FLAG_CLR1 ... MAX98396_R2018_INT_FLAG_CLR4:
823 case MAX98396_R201F_IRQ_CTRL ... MAX98396_R2024_THERM_FOLDBACK_SET:
824 case MAX98396_R2027_THERM_FOLDBACK_EN:
825 case MAX98396_R2030_NOISEGATE_MODE_CTRL:
826 case MAX98396_R2033_NOISEGATE_MODE_EN:
827 case MAX98396_R2038_CLK_MON_CTRL ... MAX98397_R203A_SPK_MON_THRESH:
828 case MAX98396_R203F_ENABLE_CTRLS ... MAX98397_R2054_PCM_TX_HIZ_CTRL_8:
829 case MAX98397_R2056_PCM_RX_SRC1... MAX98396_R2058_PCM_BYPASS_SRC:
830 case MAX98396_R205D_PCM_TX_SRC_EN ... MAX98397_R2060_PCM_TX_SUPPLY_SEL:
831 case MAX98396_R2070_ICC_RX_EN_A... MAX98396_R2072_ICC_TX_CTRL:
832 case MAX98396_R207F_ICC_EN:
833 case MAX98396_R2083_TONE_GEN_DC_CFG ... MAX98396_R2086_TONE_GEN_DC_LVL3:
834 case MAX98396_R208F_TONE_GEN_EN ... MAX98396_R209F_BYPASS_PATH_CFG:
835 case MAX98396_R20AF_AMP_EN ... MAX98397_R20C5_MEAS_ADC_OPTIMAL_MODE:
836 case MAX98396_R20C7_ADC_CFG:
837 case MAX98396_R20D0_DHT_CFG1 ... MAX98396_R20D6_DHT_HYSTERESIS_CFG:
838 case MAX98396_R20DF_DHT_EN:
839 case MAX98396_R20E0_IV_SENSE_PATH_CFG:
840 case MAX98396_R20E4_IV_SENSE_PATH_EN
841 ... MAX98396_R2106_BPE_THRESH_HYSTERESIS:
842 case MAX98396_R2108_BPE_SUPPLY_SRC ... MAX98396_R210B_BPE_LOW_LIMITER:
843 case MAX98396_R210D_BPE_EN ... MAX98396_R210F_GLOBAL_EN:
844 case MAX98397_R22FF_REVISION_ID:
851 static bool max98397_volatile_reg(struct device *dev, unsigned int reg)
854 case MAX98396_R2001_INT_RAW1 ... MAX98396_R200E_INT_FLAG4:
855 case MAX98396_R2041_PCM_MODE_CFG:
856 case MAX98397_R20B7_ADC_PVDD_READBACK_MSB
857 ... MAX98397_R20C4_ADC_LO_VDDH_READBACK_LSB:
858 case MAX98396_R20E5_BPE_STATE:
859 case MAX98396_R2109_BPE_LOW_STATE
860 ... MAX98396_R210B_BPE_LOW_LIMITER:
861 case MAX98396_R210F_GLOBAL_EN:
862 case MAX98397_R22FF_REVISION_ID:
869 static const char * const max98396_op_mod_text[] = {
870 "DG", "PVDD", "VBAT",
873 static SOC_ENUM_SINGLE_DECL(max98396_op_mod_enum,
874 MAX98396_R2098_SPK_CLS_DG_MODE,
875 0, max98396_op_mod_text);
877 static DECLARE_TLV_DB_SCALE(max98396_digital_tlv, -6350, 50, 1);
878 static const DECLARE_TLV_DB_RANGE(max98396_spk_tlv,
879 0, 0x11, TLV_DB_SCALE_ITEM(400, 100, 0),
881 static DECLARE_TLV_DB_RANGE(max98397_digital_tlv,
882 0, 0x4A, TLV_DB_SCALE_ITEM(TLV_DB_GAIN_MUTE, 0, 1),
883 0x4B, 0xFF, TLV_DB_SCALE_ITEM(-9000, 50, 0),
885 static const DECLARE_TLV_DB_RANGE(max98397_spk_tlv,
886 0, 0x15, TLV_DB_SCALE_ITEM(600, 100, 0),
889 static int max98396_mux_get(struct snd_kcontrol *kcontrol,
890 struct snd_ctl_elem_value *ucontrol)
892 struct snd_soc_component *component =
893 snd_soc_dapm_kcontrol_component(kcontrol);
894 struct max98396_priv *max98396 = snd_soc_component_get_drvdata(component);
897 if (max98396->device_id == CODEC_TYPE_MAX98396)
898 reg = MAX98396_R2055_PCM_RX_SRC1;
900 reg = MAX98397_R2056_PCM_RX_SRC1;
902 regmap_read(max98396->regmap, reg, &val);
904 ucontrol->value.enumerated.item[0] = val;
909 static int max98396_mux_put(struct snd_kcontrol *kcontrol,
910 struct snd_ctl_elem_value *ucontrol)
912 struct snd_soc_component *component =
913 snd_soc_dapm_kcontrol_component(kcontrol);
914 struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kcontrol);
915 struct max98396_priv *max98396 = snd_soc_component_get_drvdata(component);
916 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
917 unsigned int *item = ucontrol->value.enumerated.item;
921 if (item[0] >= e->items)
924 val = snd_soc_enum_item_to_val(e, item[0]) << e->shift_l;
926 if (max98396->device_id == CODEC_TYPE_MAX98396)
927 reg = MAX98396_R2055_PCM_RX_SRC1;
929 reg = MAX98397_R2056_PCM_RX_SRC1;
931 change = snd_soc_component_test_bits(component, reg,
932 MAX98396_PCM_RX_MASK, val);
935 regmap_update_bits(max98396->regmap, reg,
936 MAX98396_PCM_RX_MASK, val);
938 snd_soc_dapm_mux_update_power(dapm, kcontrol, item[0], e, NULL);
943 static const char * const max98396_switch_text[] = {
944 "Left", "Right", "LeftRight"};
946 static SOC_ENUM_SINGLE_DECL(dai_sel_enum, SND_SOC_NOPM, 0,
947 max98396_switch_text);
949 static const struct snd_kcontrol_new max98396_dai_mux =
950 SOC_DAPM_ENUM_EXT("DAI Sel Mux", dai_sel_enum,
951 max98396_mux_get, max98396_mux_put);
953 static const struct snd_kcontrol_new max98396_vi_control =
954 SOC_DAPM_SINGLE("Switch", MAX98396_R205F_PCM_TX_EN, 0, 1, 0);
956 static const struct snd_soc_dapm_widget max98396_dapm_widgets[] = {
957 SND_SOC_DAPM_DAC_E("Amp Enable", "HiFi Playback",
958 MAX98396_R20AF_AMP_EN, 0, 0, max98396_dac_event,
959 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
960 SND_SOC_DAPM_MUX("DAI Sel Mux", SND_SOC_NOPM, 0, 0,
962 SND_SOC_DAPM_OUTPUT("BE_OUT"),
963 SND_SOC_DAPM_AIF_OUT("Voltage Sense", "HiFi Capture", 0,
964 MAX98396_R20E4_IV_SENSE_PATH_EN, 0, 0),
965 SND_SOC_DAPM_AIF_OUT("Current Sense", "HiFi Capture", 0,
966 MAX98396_R20E4_IV_SENSE_PATH_EN, 1, 0),
967 SND_SOC_DAPM_SWITCH("VI Sense", SND_SOC_NOPM, 0, 0,
968 &max98396_vi_control),
969 SND_SOC_DAPM_SIGGEN("VMON"),
970 SND_SOC_DAPM_SIGGEN("IMON"),
971 SND_SOC_DAPM_SIGGEN("FBMON"),
974 static const char * const max98396_thermal_thresh_text[] = {
975 "50C", "51C", "52C", "53C", "54C", "55C", "56C", "57C",
976 "58C", "59C", "60C", "61C", "62C", "63C", "64C", "65C",
977 "66C", "67C", "68C", "69C", "70C", "71C", "72C", "73C",
978 "74C", "75C", "76C", "77C", "78C", "79C", "80C", "81C",
979 "82C", "83C", "84C", "85C", "86C", "87C", "88C", "89C",
980 "90C", "91C", "92C", "93C", "94C", "95C", "96C", "97C",
981 "98C", "99C", "100C", "101C", "102C", "103C", "104C", "105C",
982 "106C", "107C", "108C", "109C", "110C", "111C", "112C", "113C",
983 "114C", "115C", "116C", "117C", "118C", "119C", "120C", "121C",
984 "122C", "123C", "124C", "125C", "126C", "127C", "128C", "129C",
985 "130C", "131C", "132C", "133C", "134C", "135C", "136C", "137C",
986 "138C", "139C", "140C", "141C", "142C", "143C", "144C", "145C",
987 "146C", "147C", "148C", "149C", "150C"
990 static SOC_ENUM_SINGLE_DECL(max98396_thermal_warn_thresh1_enum,
991 MAX98396_R2020_THERM_WARN_THRESH, 0,
992 max98396_thermal_thresh_text);
994 static SOC_ENUM_SINGLE_DECL(max98396_thermal_warn_thresh2_enum,
995 MAX98396_R2021_THERM_WARN_THRESH2, 0,
996 max98396_thermal_thresh_text);
998 static SOC_ENUM_SINGLE_DECL(max98396_thermal_shdn_thresh_enum,
999 MAX98396_R2022_THERM_SHDN_THRESH, 0,
1000 max98396_thermal_thresh_text);
1002 static const char * const max98396_thermal_hyteresis_text[] = {
1003 "2C", "5C", "7C", "10C"
1006 static SOC_ENUM_SINGLE_DECL(max98396_thermal_hysteresis_enum,
1007 MAX98396_R2023_THERM_HYSTERESIS, 0,
1008 max98396_thermal_hyteresis_text);
1010 static const char * const max98396_foldback_slope_text[] = {
1011 "0.25", "0.5", "1.0", "2.0"
1014 static SOC_ENUM_SINGLE_DECL(max98396_thermal_fb_slope1_enum,
1015 MAX98396_R2024_THERM_FOLDBACK_SET,
1016 MAX98396_THERM_FB_SLOPE1_SHIFT,
1017 max98396_foldback_slope_text);
1019 static SOC_ENUM_SINGLE_DECL(max98396_thermal_fb_slope2_enum,
1020 MAX98396_R2024_THERM_FOLDBACK_SET,
1021 MAX98396_THERM_FB_SLOPE2_SHIFT,
1022 max98396_foldback_slope_text);
1024 static const char * const max98396_foldback_reltime_text[] = {
1025 "3ms", "10ms", "100ms", "300ms"
1028 static SOC_ENUM_SINGLE_DECL(max98396_thermal_fb_reltime_enum,
1029 MAX98396_R2024_THERM_FOLDBACK_SET,
1030 MAX98396_THERM_FB_REL_SHIFT,
1031 max98396_foldback_reltime_text);
1033 static const char * const max98396_foldback_holdtime_text[] = {
1034 "0ms", "20ms", "40ms", "80ms"
1037 static SOC_ENUM_SINGLE_DECL(max98396_thermal_fb_holdtime_enum,
1038 MAX98396_R2024_THERM_FOLDBACK_SET,
1039 MAX98396_THERM_FB_HOLD_SHIFT,
1040 max98396_foldback_holdtime_text);
1042 static int max98396_adc_value_get(struct snd_kcontrol *kcontrol,
1043 struct snd_ctl_elem_value *ucontrol)
1045 struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
1046 struct soc_mixer_control *mc =
1047 (struct soc_mixer_control *)kcontrol->private_value;
1048 struct max98396_priv *max98396 = snd_soc_component_get_drvdata(component);
1053 /* ADC value is not available if the device is powered down */
1054 if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF)
1057 if (max98396->device_id == CODEC_TYPE_MAX98397) {
1059 case MAX98396_R20B6_ADC_PVDD_READBACK_MSB:
1060 reg = MAX98397_R20B7_ADC_PVDD_READBACK_MSB;
1062 case MAX98396_R20B8_ADC_VBAT_READBACK_MSB:
1063 reg = MAX98397_R20B9_ADC_VBAT_READBACK_MSB;
1065 case MAX98396_R20BA_ADC_TEMP_READBACK_MSB:
1066 reg = MAX98397_R20BB_ADC_TEMP_READBACK_MSB;
1073 ret = regmap_raw_read(max98396->regmap, reg, &val, 2);
1077 /* ADC readback bits[8:0] rearrangement */
1078 ucontrol->value.integer.value[0] = (val[0] << 1) | (val[1] & 1);
1082 ucontrol->value.integer.value[0] = 0;
1086 static const struct snd_kcontrol_new max98396_snd_controls[] = {
1088 SOC_SINGLE_TLV("Digital Volume", MAX98396_R2090_AMP_VOL_CTRL,
1089 0, 0x7F, 1, max98396_digital_tlv),
1090 SOC_SINGLE_TLV("Speaker Volume", MAX98396_R2091_AMP_PATH_GAIN,
1091 0, 0x11, 0, max98396_spk_tlv),
1092 /* Volume Ramp Up/Down Enable*/
1093 SOC_SINGLE("Ramp Up Switch", MAX98396_R2092_AMP_DSP_CFG,
1094 MAX98396_DSP_SPK_VOL_RMPUP_SHIFT, 1, 0),
1095 SOC_SINGLE("Ramp Down Switch", MAX98396_R2092_AMP_DSP_CFG,
1096 MAX98396_DSP_SPK_VOL_RMPDN_SHIFT, 1, 0),
1097 /* Clock Monitor Enable */
1098 SOC_SINGLE("CLK Monitor Switch", MAX98396_R203F_ENABLE_CTRLS,
1099 MAX98396_CTRL_CMON_EN_SHIFT, 1, 0),
1101 SOC_SINGLE("Dither Switch", MAX98396_R2092_AMP_DSP_CFG,
1102 MAX98396_DSP_SPK_DITH_EN_SHIFT, 1, 0),
1103 SOC_SINGLE("IV Dither Switch", MAX98396_R20E0_IV_SENSE_PATH_CFG,
1104 MAX98396_IV_SENSE_DITH_EN_SHIFT, 1, 0),
1105 /* DC Blocker Enable */
1106 SOC_SINGLE("DC Blocker Switch", MAX98396_R2092_AMP_DSP_CFG,
1107 MAX98396_DSP_SPK_DCBLK_EN_SHIFT, 1, 0),
1108 SOC_SINGLE("IV DC Blocker Switch", MAX98396_R20E0_IV_SENSE_PATH_CFG,
1109 MAX98396_IV_SENSE_DCBLK_EN_SHIFT, 3, 0),
1110 /* Speaker Safe Mode Enable */
1111 SOC_SINGLE("Safe Mode Switch", MAX98396_R2092_AMP_DSP_CFG,
1112 MAX98396_DSP_SPK_SAFE_EN_SHIFT, 1, 0),
1113 /* Wideband Filter Enable */
1114 SOC_SINGLE("WB Filter Switch", MAX98396_R2092_AMP_DSP_CFG,
1115 MAX98396_DSP_SPK_WB_FLT_EN_SHIFT, 1, 0),
1116 SOC_SINGLE("IV WB Filter Switch", MAX98396_R20E0_IV_SENSE_PATH_CFG,
1117 MAX98396_IV_SENSE_WB_FLT_EN_SHIFT, 1, 0),
1118 /* Dynamic Headroom Tracking */
1119 SOC_SINGLE("DHT Switch", MAX98396_R20DF_DHT_EN, 0, 1, 0),
1120 /* Brownout Protection Engine */
1121 SOC_SINGLE("BPE Switch", MAX98396_R210D_BPE_EN, 0, 1, 0),
1122 SOC_SINGLE("BPE Limiter Switch", MAX98396_R210D_BPE_EN, 1, 1, 0),
1123 /* Bypass Path Enable */
1124 SOC_SINGLE("Bypass Path Switch",
1125 MAX98396_R205E_PCM_RX_EN, 1, 1, 0),
1126 /* Speaker Operation Mode */
1127 SOC_ENUM("OP Mode", max98396_op_mod_enum),
1128 /* Auto Restart functions */
1129 SOC_SINGLE("CMON Auto Restart Switch", MAX98396_R2038_CLK_MON_CTRL,
1130 MAX98396_CLK_MON_AUTO_RESTART_SHIFT, 1, 0),
1131 SOC_SINGLE("PVDD Auto Restart Switch", MAX98396_R210E_AUTO_RESTART,
1132 MAX98396_PVDD_UVLO_RESTART_SHFT, 1, 0),
1133 SOC_SINGLE("VBAT Auto Restart Switch", MAX98396_R210E_AUTO_RESTART,
1134 MAX98396_VBAT_UVLO_RESTART_SHFT, 1, 0),
1135 SOC_SINGLE("THERM Auto Restart Switch", MAX98396_R210E_AUTO_RESTART,
1136 MAX98396_THEM_SHDN_RESTART_SHFT, 1, 0),
1137 SOC_SINGLE("OVC Auto Restart Switch", MAX98396_R210E_AUTO_RESTART,
1138 MAX98396_OVC_RESTART_SHFT, 1, 0),
1139 /* Thermal Threshold */
1140 SOC_ENUM("THERM Thresh1", max98396_thermal_warn_thresh1_enum),
1141 SOC_ENUM("THERM Thresh2", max98396_thermal_warn_thresh2_enum),
1142 SOC_ENUM("THERM SHDN Thresh", max98396_thermal_shdn_thresh_enum),
1143 SOC_ENUM("THERM Hysteresis", max98396_thermal_hysteresis_enum),
1144 SOC_SINGLE("THERM Foldback Switch",
1145 MAX98396_R2027_THERM_FOLDBACK_EN, 0, 1, 0),
1146 SOC_ENUM("THERM Slope1", max98396_thermal_fb_slope1_enum),
1147 SOC_ENUM("THERM Slope2", max98396_thermal_fb_slope2_enum),
1148 SOC_ENUM("THERM Release", max98396_thermal_fb_reltime_enum),
1149 SOC_ENUM("THERM Hold", max98396_thermal_fb_holdtime_enum),
1151 SOC_SINGLE_EXT("ADC PVDD", MAX98396_R20B6_ADC_PVDD_READBACK_MSB, 0, 0x1FF, 0,
1152 max98396_adc_value_get, NULL),
1153 SOC_SINGLE_EXT("ADC VBAT", MAX98396_R20B8_ADC_VBAT_READBACK_MSB, 0, 0x1FF, 0,
1154 max98396_adc_value_get, NULL),
1155 SOC_SINGLE_EXT("ADC TEMP", MAX98396_R20BA_ADC_TEMP_READBACK_MSB, 0, 0x1FF, 0,
1156 max98396_adc_value_get, NULL),
1159 static const struct snd_kcontrol_new max98397_snd_controls[] = {
1161 SOC_SINGLE_TLV("Digital Volume", MAX98396_R2090_AMP_VOL_CTRL,
1162 0, 0xFF, 1, max98397_digital_tlv),
1163 SOC_SINGLE_TLV("Speaker Volume", MAX98396_R2091_AMP_PATH_GAIN,
1164 0, 0x15, 0, max98397_spk_tlv),
1165 /* Volume Ramp Up/Down Enable*/
1166 SOC_SINGLE("Ramp Up Switch", MAX98396_R2092_AMP_DSP_CFG,
1167 MAX98396_DSP_SPK_VOL_RMPUP_SHIFT, 1, 0),
1168 SOC_SINGLE("Ramp Down Switch", MAX98396_R2092_AMP_DSP_CFG,
1169 MAX98396_DSP_SPK_VOL_RMPDN_SHIFT, 1, 0),
1170 /* Clock Monitor Enable */
1171 SOC_SINGLE("CLK Monitor Switch", MAX98396_R203F_ENABLE_CTRLS,
1172 MAX98396_CTRL_CMON_EN_SHIFT, 1, 0),
1174 SOC_SINGLE("Dither Switch", MAX98396_R2092_AMP_DSP_CFG,
1175 MAX98396_DSP_SPK_DITH_EN_SHIFT, 1, 0),
1176 SOC_SINGLE("IV Dither Switch", MAX98396_R20E0_IV_SENSE_PATH_CFG,
1177 MAX98396_IV_SENSE_DITH_EN_SHIFT, 1, 0),
1178 /* DC Blocker Enable */
1179 SOC_SINGLE("DC Blocker Switch", MAX98396_R2092_AMP_DSP_CFG,
1180 MAX98396_DSP_SPK_DCBLK_EN_SHIFT, 1, 0),
1181 SOC_SINGLE("IV DC Blocker Switch", MAX98396_R20E0_IV_SENSE_PATH_CFG,
1182 MAX98396_IV_SENSE_DCBLK_EN_SHIFT, 3, 0),
1183 /* Speaker Safe Mode Enable */
1184 SOC_SINGLE("Safe Mode Switch", MAX98396_R2092_AMP_DSP_CFG,
1185 MAX98396_DSP_SPK_SAFE_EN_SHIFT, 1, 0),
1186 /* Wideband Filter Enable */
1187 SOC_SINGLE("WB Filter Switch", MAX98396_R2092_AMP_DSP_CFG,
1188 MAX98396_DSP_SPK_WB_FLT_EN_SHIFT, 1, 0),
1189 SOC_SINGLE("IV WB Filter Switch", MAX98396_R20E0_IV_SENSE_PATH_CFG,
1190 MAX98396_IV_SENSE_WB_FLT_EN_SHIFT, 1, 0),
1191 /* Dynamic Headroom Tracking */
1192 SOC_SINGLE("DHT Switch", MAX98396_R20DF_DHT_EN, 0, 1, 0),
1193 /* Brownout Protection Engine */
1194 SOC_SINGLE("BPE Switch", MAX98396_R210D_BPE_EN, 0, 1, 0),
1195 SOC_SINGLE("BPE Limiter Switch", MAX98396_R210D_BPE_EN, 1, 1, 0),
1196 /* Bypass Path Enable */
1197 SOC_SINGLE("Bypass Path Switch",
1198 MAX98396_R205E_PCM_RX_EN, 1, 1, 0),
1199 /* Speaker Operation Mode */
1200 SOC_ENUM("OP Mode", max98396_op_mod_enum),
1201 /* Auto Restart functions */
1202 SOC_SINGLE("CMON Auto Restart Switch", MAX98396_R2038_CLK_MON_CTRL,
1203 MAX98396_CLK_MON_AUTO_RESTART_SHIFT, 1, 0),
1204 SOC_SINGLE("PVDD Auto Restart Switch", MAX98396_R210E_AUTO_RESTART,
1205 MAX98396_PVDD_UVLO_RESTART_SHFT, 1, 0),
1206 SOC_SINGLE("VBAT Auto Restart Switch", MAX98396_R210E_AUTO_RESTART,
1207 MAX98396_VBAT_UVLO_RESTART_SHFT, 1, 0),
1208 SOC_SINGLE("THERM Auto Restart Switch", MAX98396_R210E_AUTO_RESTART,
1209 MAX98396_THEM_SHDN_RESTART_SHFT, 1, 0),
1210 SOC_SINGLE("OVC Auto Restart Switch", MAX98396_R210E_AUTO_RESTART,
1211 MAX98396_OVC_RESTART_SHFT, 1, 0),
1212 /* Thermal Threshold */
1213 SOC_ENUM("THERM Thresh1", max98396_thermal_warn_thresh1_enum),
1214 SOC_ENUM("THERM Thresh2", max98396_thermal_warn_thresh2_enum),
1215 SOC_ENUM("THERM SHDN Thresh", max98396_thermal_shdn_thresh_enum),
1216 SOC_ENUM("THERM Hysteresis", max98396_thermal_hysteresis_enum),
1217 SOC_SINGLE("THERM Foldback Switch",
1218 MAX98396_R2027_THERM_FOLDBACK_EN, 0, 1, 0),
1219 SOC_ENUM("THERM Slope1", max98396_thermal_fb_slope1_enum),
1220 SOC_ENUM("THERM Slope2", max98396_thermal_fb_slope2_enum),
1221 SOC_ENUM("THERM Release", max98396_thermal_fb_reltime_enum),
1222 SOC_ENUM("THERM Hold", max98396_thermal_fb_holdtime_enum),
1224 SOC_SINGLE_EXT("ADC PVDD", MAX98396_R20B6_ADC_PVDD_READBACK_MSB, 0, 0x1FF, 0,
1225 max98396_adc_value_get, NULL),
1226 SOC_SINGLE_EXT("ADC VBAT", MAX98396_R20B8_ADC_VBAT_READBACK_MSB, 0, 0x1FF, 0,
1227 max98396_adc_value_get, NULL),
1228 SOC_SINGLE_EXT("ADC TEMP", MAX98396_R20BA_ADC_TEMP_READBACK_MSB, 0, 0x1FF, 0,
1229 max98396_adc_value_get, NULL),
1232 static const struct snd_soc_dapm_route max98396_audio_map[] = {
1234 {"DAI Sel Mux", "Left", "Amp Enable"},
1235 {"DAI Sel Mux", "Right", "Amp Enable"},
1236 {"DAI Sel Mux", "LeftRight", "Amp Enable"},
1237 {"BE_OUT", NULL, "DAI Sel Mux"},
1239 { "VI Sense", "Switch", "VMON" },
1240 { "VI Sense", "Switch", "IMON" },
1241 { "Voltage Sense", NULL, "VI Sense" },
1242 { "Current Sense", NULL, "VI Sense" },
1245 static struct snd_soc_dai_driver max98396_dai[] = {
1247 .name = "max98396-aif1",
1249 .stream_name = "HiFi Playback",
1252 .rates = MAX98396_RATES,
1253 .formats = MAX98396_FORMATS,
1256 .stream_name = "HiFi Capture",
1259 .rates = MAX98396_RATES,
1260 .formats = MAX98396_FORMATS,
1262 .ops = &max98396_dai_ops,
1266 static struct snd_soc_dai_driver max98397_dai[] = {
1268 .name = "max98397-aif1",
1270 .stream_name = "HiFi Playback",
1273 .rates = MAX98396_RATES,
1274 .formats = MAX98396_FORMATS,
1277 .stream_name = "HiFi Capture",
1280 .rates = MAX98396_RATES,
1281 .formats = MAX98396_FORMATS,
1283 .ops = &max98396_dai_ops,
1287 static void max98396_reset(struct max98396_priv *max98396, struct device *dev)
1289 int ret, reg, count;
1291 /* Software Reset */
1292 ret = regmap_write(max98396->regmap,
1293 MAX98396_R2000_SW_RESET, 1);
1295 dev_err(dev, "Reset command failed. (ret:%d)\n", ret);
1299 usleep_range(5000, 6000);
1300 /* Software Reset Verification */
1301 ret = regmap_read(max98396->regmap,
1302 GET_REG_ADDR_REV_ID(max98396->device_id), ®);
1304 dev_info(dev, "Reset completed (retry:%d)\n", count);
1309 dev_err(dev, "Reset failed. (ret:%d)\n", ret);
1312 static int max98396_probe(struct snd_soc_component *component)
1314 struct max98396_priv *max98396 =
1315 snd_soc_component_get_drvdata(component);
1317 /* Software Reset */
1318 max98396_reset(max98396, component->dev);
1320 /* L/R mix configuration */
1321 if (max98396->device_id == CODEC_TYPE_MAX98396) {
1322 regmap_write(max98396->regmap,
1323 MAX98396_R2055_PCM_RX_SRC1, 0x02);
1324 regmap_write(max98396->regmap,
1325 MAX98396_R2056_PCM_RX_SRC2, 0x10);
1327 regmap_write(max98396->regmap,
1328 MAX98397_R2056_PCM_RX_SRC1, 0x02);
1329 regmap_write(max98396->regmap,
1330 MAX98397_R2057_PCM_RX_SRC2, 0x10);
1332 /* Enable DC blocker */
1333 regmap_update_bits(max98396->regmap,
1334 MAX98396_R2092_AMP_DSP_CFG, 1, 1);
1335 /* Enable IV Monitor DC blocker */
1336 regmap_update_bits(max98396->regmap,
1337 MAX98396_R20E0_IV_SENSE_PATH_CFG,
1338 MAX98396_IV_SENSE_DCBLK_EN_MASK,
1339 MAX98396_IV_SENSE_DCBLK_EN_MASK);
1340 /* Configure default data output sources */
1341 regmap_write(max98396->regmap,
1342 MAX98396_R205D_PCM_TX_SRC_EN, 3);
1343 /* Enable Wideband Filter */
1344 regmap_update_bits(max98396->regmap,
1345 MAX98396_R2092_AMP_DSP_CFG, 0x40, 0x40);
1346 /* Enable IV Wideband Filter */
1347 regmap_update_bits(max98396->regmap,
1348 MAX98396_R20E0_IV_SENSE_PATH_CFG, 8, 8);
1350 /* Enable Bypass Source */
1351 regmap_write(max98396->regmap,
1352 MAX98396_R2058_PCM_BYPASS_SRC,
1353 max98396->bypass_slot);
1354 /* Voltage, current slot configuration */
1355 regmap_write(max98396->regmap,
1356 MAX98396_R2044_PCM_TX_CTRL_1,
1358 regmap_write(max98396->regmap,
1359 MAX98396_R2045_PCM_TX_CTRL_2,
1362 if (max98396->v_slot < 8)
1363 if (max98396->device_id == CODEC_TYPE_MAX98396)
1364 regmap_update_bits(max98396->regmap,
1365 MAX98396_R2053_PCM_TX_HIZ_CTRL_8,
1366 1 << max98396->v_slot, 0);
1368 regmap_update_bits(max98396->regmap,
1369 MAX98397_R2054_PCM_TX_HIZ_CTRL_8,
1370 1 << max98396->v_slot, 0);
1372 if (max98396->device_id == CODEC_TYPE_MAX98396)
1373 regmap_update_bits(max98396->regmap,
1374 MAX98396_R2052_PCM_TX_HIZ_CTRL_7,
1375 1 << (max98396->v_slot - 8), 0);
1377 regmap_update_bits(max98396->regmap,
1378 MAX98397_R2053_PCM_TX_HIZ_CTRL_7,
1379 1 << (max98396->v_slot - 8), 0);
1381 if (max98396->i_slot < 8)
1382 if (max98396->device_id == CODEC_TYPE_MAX98396)
1383 regmap_update_bits(max98396->regmap,
1384 MAX98396_R2053_PCM_TX_HIZ_CTRL_8,
1385 1 << max98396->i_slot, 0);
1387 regmap_update_bits(max98396->regmap,
1388 MAX98397_R2054_PCM_TX_HIZ_CTRL_8,
1389 1 << max98396->i_slot, 0);
1391 if (max98396->device_id == CODEC_TYPE_MAX98396)
1392 regmap_update_bits(max98396->regmap,
1393 MAX98396_R2052_PCM_TX_HIZ_CTRL_7,
1394 1 << (max98396->i_slot - 8), 0);
1396 regmap_update_bits(max98396->regmap,
1397 MAX98397_R2053_PCM_TX_HIZ_CTRL_7,
1398 1 << (max98396->i_slot - 8), 0);
1400 /* Set interleave mode */
1401 if (max98396->interleave_mode)
1402 regmap_update_bits(max98396->regmap,
1403 MAX98396_R2041_PCM_MODE_CFG,
1404 MAX98396_PCM_TX_CH_INTERLEAVE_MASK,
1405 MAX98396_PCM_TX_CH_INTERLEAVE_MASK);
1407 regmap_update_bits(max98396->regmap,
1408 MAX98396_R2038_CLK_MON_CTRL,
1409 MAX98396_CLK_MON_AUTO_RESTART_MASK,
1410 MAX98396_CLK_MON_AUTO_RESTART_MASK);
1412 /* Speaker Amplifier PCM RX Enable by default */
1413 regmap_update_bits(max98396->regmap,
1414 MAX98396_R205E_PCM_RX_EN,
1415 MAX98396_PCM_RX_EN_MASK, 1);
1420 #ifdef CONFIG_PM_SLEEP
1421 static int max98396_suspend(struct device *dev)
1423 struct max98396_priv *max98396 = dev_get_drvdata(dev);
1425 regcache_cache_only(max98396->regmap, true);
1426 regcache_mark_dirty(max98396->regmap);
1430 static int max98396_resume(struct device *dev)
1432 struct max98396_priv *max98396 = dev_get_drvdata(dev);
1434 regcache_cache_only(max98396->regmap, false);
1435 max98396_reset(max98396, dev);
1436 regcache_sync(max98396->regmap);
1441 static const struct dev_pm_ops max98396_pm = {
1442 SET_SYSTEM_SLEEP_PM_OPS(max98396_suspend, max98396_resume)
1445 static const struct snd_soc_component_driver soc_codec_dev_max98396 = {
1446 .probe = max98396_probe,
1447 .controls = max98396_snd_controls,
1448 .num_controls = ARRAY_SIZE(max98396_snd_controls),
1449 .dapm_widgets = max98396_dapm_widgets,
1450 .num_dapm_widgets = ARRAY_SIZE(max98396_dapm_widgets),
1451 .dapm_routes = max98396_audio_map,
1452 .num_dapm_routes = ARRAY_SIZE(max98396_audio_map),
1454 .use_pmdown_time = 1,
1456 .non_legacy_dai_naming = 1,
1459 static const struct snd_soc_component_driver soc_codec_dev_max98397 = {
1460 .probe = max98396_probe,
1461 .controls = max98397_snd_controls,
1462 .num_controls = ARRAY_SIZE(max98397_snd_controls),
1463 .dapm_widgets = max98396_dapm_widgets,
1464 .num_dapm_widgets = ARRAY_SIZE(max98396_dapm_widgets),
1465 .dapm_routes = max98396_audio_map,
1466 .num_dapm_routes = ARRAY_SIZE(max98396_audio_map),
1468 .use_pmdown_time = 1,
1470 .non_legacy_dai_naming = 1,
1473 static const struct regmap_config max98396_regmap = {
1476 .max_register = MAX98396_R21FF_REVISION_ID,
1477 .reg_defaults = max98396_reg,
1478 .num_reg_defaults = ARRAY_SIZE(max98396_reg),
1479 .readable_reg = max98396_readable_register,
1480 .volatile_reg = max98396_volatile_reg,
1481 .cache_type = REGCACHE_RBTREE,
1484 static const struct regmap_config max98397_regmap = {
1487 .max_register = MAX98397_R22FF_REVISION_ID,
1488 .reg_defaults = max98397_reg,
1489 .num_reg_defaults = ARRAY_SIZE(max98397_reg),
1490 .readable_reg = max98397_readable_register,
1491 .volatile_reg = max98397_volatile_reg,
1492 .cache_type = REGCACHE_RBTREE,
1495 static void max98396_read_device_property(struct device *dev,
1496 struct max98396_priv *max98396)
1500 if (!device_property_read_u32(dev, "adi,vmon-slot-no", &value))
1501 max98396->v_slot = value & 0xF;
1503 max98396->v_slot = 0;
1505 if (!device_property_read_u32(dev, "adi,imon-slot-no", &value))
1506 max98396->i_slot = value & 0xF;
1508 max98396->i_slot = 1;
1510 if (!device_property_read_u32(dev, "adi,bypass-slot-no", &value))
1511 max98396->bypass_slot = value & 0xF;
1513 max98396->bypass_slot = 0;
1516 static int max98396_i2c_probe(struct i2c_client *i2c,
1517 const struct i2c_device_id *id)
1519 struct max98396_priv *max98396 = NULL;
1522 max98396 = devm_kzalloc(&i2c->dev, sizeof(*max98396), GFP_KERNEL);
1528 i2c_set_clientdata(i2c, max98396);
1530 max98396->device_id = id->driver_data;
1532 /* regmap initialization */
1533 if (max98396->device_id == CODEC_TYPE_MAX98396)
1534 max98396->regmap = devm_regmap_init_i2c(i2c, &max98396_regmap);
1537 max98396->regmap = devm_regmap_init_i2c(i2c, &max98397_regmap);
1539 if (IS_ERR(max98396->regmap)) {
1540 ret = PTR_ERR(max98396->regmap);
1542 "Failed to allocate regmap: %d\n", ret);
1546 /* update interleave mode info */
1547 if (device_property_read_bool(&i2c->dev, "adi,interleave_mode"))
1548 max98396->interleave_mode = true;
1550 max98396->interleave_mode = false;
1552 /* voltage/current slot & gpio configuration */
1553 max98396_read_device_property(&i2c->dev, max98396);
1555 /* Reset the Device */
1556 max98396->reset_gpio = devm_gpiod_get_optional(&i2c->dev,
1557 "reset", GPIOD_OUT_HIGH);
1558 if (IS_ERR(max98396->reset_gpio)) {
1559 ret = PTR_ERR(max98396->reset_gpio);
1560 dev_err(&i2c->dev, "Unable to request GPIO pin: %d.\n", ret);
1564 if (max98396->reset_gpio) {
1565 usleep_range(5000, 6000);
1566 gpiod_set_value_cansleep(max98396->reset_gpio, 0);
1567 /* Wait for the hw reset done */
1568 usleep_range(5000, 6000);
1571 ret = regmap_read(max98396->regmap,
1572 GET_REG_ADDR_REV_ID(max98396->device_id), ®);
1574 dev_err(&i2c->dev, "%s: failed to read revision of the device.\n", id->name);
1577 dev_info(&i2c->dev, "%s revision ID: 0x%02X\n", id->name, reg);
1579 /* codec registration */
1580 if (max98396->device_id == CODEC_TYPE_MAX98396)
1581 ret = devm_snd_soc_register_component(&i2c->dev,
1582 &soc_codec_dev_max98396,
1584 ARRAY_SIZE(max98396_dai));
1586 ret = devm_snd_soc_register_component(&i2c->dev,
1587 &soc_codec_dev_max98397,
1589 ARRAY_SIZE(max98397_dai));
1591 dev_err(&i2c->dev, "Failed to register codec: %d\n", ret);
1596 static const struct i2c_device_id max98396_i2c_id[] = {
1597 { "max98396", CODEC_TYPE_MAX98396},
1598 { "max98397", CODEC_TYPE_MAX98397},
1602 MODULE_DEVICE_TABLE(i2c, max98396_i2c_id);
1604 #if defined(CONFIG_OF)
1605 static const struct of_device_id max98396_of_match[] = {
1606 { .compatible = "adi,max98396", },
1607 { .compatible = "adi,max98397", },
1610 MODULE_DEVICE_TABLE(of, max98396_of_match);
1614 static const struct acpi_device_id max98396_acpi_match[] = {
1619 MODULE_DEVICE_TABLE(acpi, max98396_acpi_match);
1622 static struct i2c_driver max98396_i2c_driver = {
1625 .of_match_table = of_match_ptr(max98396_of_match),
1626 .acpi_match_table = ACPI_PTR(max98396_acpi_match),
1629 .probe = max98396_i2c_probe,
1630 .id_table = max98396_i2c_id,
1633 module_i2c_driver(max98396_i2c_driver)
1635 MODULE_DESCRIPTION("ALSA SoC MAX98396 driver");
1636 MODULE_AUTHOR("Ryan Lee <ryans.lee@analog.com>");
1637 MODULE_LICENSE("GPL");