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>
8 #include <linux/regulator/consumer.h>
10 #include <linux/gpio.h>
11 #include <sound/tlv.h>
14 static const char * const max98396_core_supplies[MAX98396_NUM_CORE_SUPPLIES] = {
20 static struct reg_default max98396_reg[] = {
21 {MAX98396_R2000_SW_RESET, 0x00},
22 {MAX98396_R2001_INT_RAW1, 0x00},
23 {MAX98396_R2002_INT_RAW2, 0x00},
24 {MAX98396_R2003_INT_RAW3, 0x00},
25 {MAX98396_R2004_INT_RAW4, 0x00},
26 {MAX98396_R2006_INT_STATE1, 0x00},
27 {MAX98396_R2007_INT_STATE2, 0x00},
28 {MAX98396_R2008_INT_STATE3, 0x00},
29 {MAX98396_R2009_INT_STATE4, 0x00},
30 {MAX98396_R200B_INT_FLAG1, 0x00},
31 {MAX98396_R200C_INT_FLAG2, 0x00},
32 {MAX98396_R200D_INT_FLAG3, 0x00},
33 {MAX98396_R200E_INT_FLAG4, 0x00},
34 {MAX98396_R2010_INT_EN1, 0x02},
35 {MAX98396_R2011_INT_EN2, 0x00},
36 {MAX98396_R2012_INT_EN3, 0x00},
37 {MAX98396_R2013_INT_EN4, 0x00},
38 {MAX98396_R2015_INT_FLAG_CLR1, 0x00},
39 {MAX98396_R2016_INT_FLAG_CLR2, 0x00},
40 {MAX98396_R2017_INT_FLAG_CLR3, 0x00},
41 {MAX98396_R2018_INT_FLAG_CLR4, 0x00},
42 {MAX98396_R201F_IRQ_CTRL, 0x00},
43 {MAX98396_R2020_THERM_WARN_THRESH, 0x46},
44 {MAX98396_R2021_THERM_WARN_THRESH2, 0x46},
45 {MAX98396_R2022_THERM_SHDN_THRESH, 0x64},
46 {MAX98396_R2023_THERM_HYSTERESIS, 0x02},
47 {MAX98396_R2024_THERM_FOLDBACK_SET, 0xC5},
48 {MAX98396_R2027_THERM_FOLDBACK_EN, 0x01},
49 {MAX98396_R2030_NOISEGATE_MODE_CTRL, 0x32},
50 {MAX98396_R2033_NOISEGATE_MODE_EN, 0x00},
51 {MAX98396_R2038_CLK_MON_CTRL, 0x00},
52 {MAX98396_R2039_DATA_MON_CTRL, 0x00},
53 {MAX98396_R203F_ENABLE_CTRLS, 0x0F},
54 {MAX98396_R2040_PIN_CFG, 0x55},
55 {MAX98396_R2041_PCM_MODE_CFG, 0xC0},
56 {MAX98396_R2042_PCM_CLK_SETUP, 0x04},
57 {MAX98396_R2043_PCM_SR_SETUP, 0x88},
58 {MAX98396_R2044_PCM_TX_CTRL_1, 0x00},
59 {MAX98396_R2045_PCM_TX_CTRL_2, 0x00},
60 {MAX98396_R2046_PCM_TX_CTRL_3, 0x00},
61 {MAX98396_R2047_PCM_TX_CTRL_4, 0x00},
62 {MAX98396_R2048_PCM_TX_CTRL_5, 0x00},
63 {MAX98396_R2049_PCM_TX_CTRL_6, 0x00},
64 {MAX98396_R204A_PCM_TX_CTRL_7, 0x00},
65 {MAX98396_R204B_PCM_TX_CTRL_8, 0x00},
66 {MAX98396_R204C_PCM_TX_HIZ_CTRL_1, 0xFF},
67 {MAX98396_R204D_PCM_TX_HIZ_CTRL_2, 0xFF},
68 {MAX98396_R204E_PCM_TX_HIZ_CTRL_3, 0xFF},
69 {MAX98396_R204F_PCM_TX_HIZ_CTRL_4, 0xFF},
70 {MAX98396_R2050_PCM_TX_HIZ_CTRL_5, 0xFF},
71 {MAX98396_R2051_PCM_TX_HIZ_CTRL_6, 0xFF},
72 {MAX98396_R2052_PCM_TX_HIZ_CTRL_7, 0xFF},
73 {MAX98396_R2053_PCM_TX_HIZ_CTRL_8, 0xFF},
74 {MAX98396_R2055_PCM_RX_SRC1, 0x00},
75 {MAX98396_R2056_PCM_RX_SRC2, 0x00},
76 {MAX98396_R2058_PCM_BYPASS_SRC, 0x00},
77 {MAX98396_R205D_PCM_TX_SRC_EN, 0x00},
78 {MAX98396_R205E_PCM_RX_EN, 0x00},
79 {MAX98396_R205F_PCM_TX_EN, 0x00},
80 {MAX98396_R2070_ICC_RX_EN_A, 0x00},
81 {MAX98396_R2071_ICC_RX_EN_B, 0x00},
82 {MAX98396_R2072_ICC_TX_CTRL, 0x00},
83 {MAX98396_R207F_ICC_EN, 0x00},
84 {MAX98396_R2083_TONE_GEN_DC_CFG, 0x04},
85 {MAX98396_R2084_TONE_GEN_DC_LVL1, 0x00},
86 {MAX98396_R2085_TONE_GEN_DC_LVL2, 0x00},
87 {MAX98396_R2086_TONE_GEN_DC_LVL3, 0x00},
88 {MAX98396_R208F_TONE_GEN_EN, 0x00},
89 {MAX98396_R2090_AMP_VOL_CTRL, 0x00},
90 {MAX98396_R2091_AMP_PATH_GAIN, 0x0B},
91 {MAX98396_R2092_AMP_DSP_CFG, 0x23},
92 {MAX98396_R2093_SSM_CFG, 0x0D},
93 {MAX98396_R2094_SPK_CLS_DG_THRESH, 0x12},
94 {MAX98396_R2095_SPK_CLS_DG_HDR, 0x17},
95 {MAX98396_R2096_SPK_CLS_DG_HOLD_TIME, 0x17},
96 {MAX98396_R2097_SPK_CLS_DG_DELAY, 0x00},
97 {MAX98396_R2098_SPK_CLS_DG_MODE, 0x00},
98 {MAX98396_R2099_SPK_CLS_DG_VBAT_LVL, 0x03},
99 {MAX98396_R209A_SPK_EDGE_CTRL, 0x00},
100 {MAX98396_R209C_SPK_EDGE_CTRL1, 0x0A},
101 {MAX98396_R209D_SPK_EDGE_CTRL2, 0xAA},
102 {MAX98396_R209E_AMP_CLIP_GAIN, 0x00},
103 {MAX98396_R209F_BYPASS_PATH_CFG, 0x00},
104 {MAX98396_R20A0_AMP_SUPPLY_CTL, 0x00},
105 {MAX98396_R20AF_AMP_EN, 0x00},
106 {MAX98396_R20B0_ADC_SR, 0x30},
107 {MAX98396_R20B1_ADC_PVDD_CFG, 0x00},
108 {MAX98396_R20B2_ADC_VBAT_CFG, 0x00},
109 {MAX98396_R20B3_ADC_THERMAL_CFG, 0x00},
110 {MAX98396_R20B4_ADC_READBACK_CTRL1, 0x00},
111 {MAX98396_R20B5_ADC_READBACK_CTRL2, 0x00},
112 {MAX98396_R20B6_ADC_PVDD_READBACK_MSB, 0x00},
113 {MAX98396_R20B7_ADC_PVDD_READBACK_LSB, 0x00},
114 {MAX98396_R20B8_ADC_VBAT_READBACK_MSB, 0x00},
115 {MAX98396_R20B9_ADC_VBAT_READBACK_LSB, 0x00},
116 {MAX98396_R20BA_ADC_TEMP_READBACK_MSB, 0x00},
117 {MAX98396_R20BB_ADC_TEMP_READBACK_LSB, 0x00},
118 {MAX98396_R20BC_ADC_LO_PVDD_READBACK_MSB, 0x00},
119 {MAX98396_R20BD_ADC_LO_PVDD_READBACK_LSB, 0x00},
120 {MAX98396_R20BE_ADC_LO_VBAT_READBACK_MSB, 0x00},
121 {MAX98396_R20BF_ADC_LO_VBAT_READBACK_LSB, 0x00},
122 {MAX98396_R20C7_ADC_CFG, 0x00},
123 {MAX98396_R20D0_DHT_CFG1, 0x00},
124 {MAX98396_R20D1_LIMITER_CFG1, 0x08},
125 {MAX98396_R20D2_LIMITER_CFG2, 0x00},
126 {MAX98396_R20D3_DHT_CFG2, 0x14},
127 {MAX98396_R20D4_DHT_CFG3, 0x02},
128 {MAX98396_R20D5_DHT_CFG4, 0x04},
129 {MAX98396_R20D6_DHT_HYSTERESIS_CFG, 0x07},
130 {MAX98396_R20DF_DHT_EN, 0x00},
131 {MAX98396_R20E0_IV_SENSE_PATH_CFG, 0x04},
132 {MAX98396_R20E4_IV_SENSE_PATH_EN, 0x00},
133 {MAX98396_R20E5_BPE_STATE, 0x00},
134 {MAX98396_R20E6_BPE_L3_THRESH_MSB, 0x00},
135 {MAX98396_R20E7_BPE_L3_THRESH_LSB, 0x00},
136 {MAX98396_R20E8_BPE_L2_THRESH_MSB, 0x00},
137 {MAX98396_R20E9_BPE_L2_THRESH_LSB, 0x00},
138 {MAX98396_R20EA_BPE_L1_THRESH_MSB, 0x00},
139 {MAX98396_R20EB_BPE_L1_THRESH_LSB, 0x00},
140 {MAX98396_R20EC_BPE_L0_THRESH_MSB, 0x00},
141 {MAX98396_R20ED_BPE_L0_THRESH_LSB, 0x00},
142 {MAX98396_R20EE_BPE_L3_DWELL_HOLD_TIME, 0x00},
143 {MAX98396_R20EF_BPE_L2_DWELL_HOLD_TIME, 0x00},
144 {MAX98396_R20F0_BPE_L1_DWELL_HOLD_TIME, 0x00},
145 {MAX98396_R20F1_BPE_L0_HOLD_TIME, 0x00},
146 {MAX98396_R20F2_BPE_L3_ATTACK_REL_STEP, 0x00},
147 {MAX98396_R20F3_BPE_L2_ATTACK_REL_STEP, 0x00},
148 {MAX98396_R20F4_BPE_L1_ATTACK_REL_STEP, 0x00},
149 {MAX98396_R20F5_BPE_L0_ATTACK_REL_STEP, 0x00},
150 {MAX98396_R20F6_BPE_L3_MAX_GAIN_ATTN, 0x00},
151 {MAX98396_R20F7_BPE_L2_MAX_GAIN_ATTN, 0x00},
152 {MAX98396_R20F8_BPE_L1_MAX_GAIN_ATTN, 0x00},
153 {MAX98396_R20F9_BPE_L0_MAX_GAIN_ATTN, 0x00},
154 {MAX98396_R20FA_BPE_L3_ATT_REL_RATE, 0x00},
155 {MAX98396_R20FB_BPE_L2_ATT_REL_RATE, 0x00},
156 {MAX98396_R20FC_BPE_L1_ATT_REL_RATE, 0x00},
157 {MAX98396_R20FD_BPE_L0_ATT_REL_RATE, 0x00},
158 {MAX98396_R20FE_BPE_L3_LIMITER_CFG, 0x00},
159 {MAX98396_R20FF_BPE_L2_LIMITER_CFG, 0x00},
160 {MAX98396_R2100_BPE_L1_LIMITER_CFG, 0x00},
161 {MAX98396_R2101_BPE_L0_LIMITER_CFG, 0x00},
162 {MAX98396_R2102_BPE_L3_LIM_ATT_REL_RATE, 0x00},
163 {MAX98396_R2103_BPE_L2_LIM_ATT_REL_RATE, 0x00},
164 {MAX98396_R2104_BPE_L1_LIM_ATT_REL_RATE, 0x00},
165 {MAX98396_R2105_BPE_L0_LIM_ATT_REL_RATE, 0x00},
166 {MAX98396_R2106_BPE_THRESH_HYSTERESIS, 0x00},
167 {MAX98396_R2107_BPE_INFINITE_HOLD_CLR, 0x00},
168 {MAX98396_R2108_BPE_SUPPLY_SRC, 0x00},
169 {MAX98396_R2109_BPE_LOW_STATE, 0x00},
170 {MAX98396_R210A_BPE_LOW_GAIN, 0x00},
171 {MAX98396_R210B_BPE_LOW_LIMITER, 0x00},
172 {MAX98396_R210D_BPE_EN, 0x00},
173 {MAX98396_R210E_AUTO_RESTART, 0x00},
174 {MAX98396_R210F_GLOBAL_EN, 0x00},
175 {MAX98396_R21FF_REVISION_ID, 0x00},
178 static struct reg_default max98397_reg[] = {
179 {MAX98396_R2000_SW_RESET, 0x00},
180 {MAX98396_R2001_INT_RAW1, 0x00},
181 {MAX98396_R2002_INT_RAW2, 0x00},
182 {MAX98396_R2003_INT_RAW3, 0x00},
183 {MAX98396_R2004_INT_RAW4, 0x00},
184 {MAX98396_R2006_INT_STATE1, 0x00},
185 {MAX98396_R2007_INT_STATE2, 0x00},
186 {MAX98396_R2008_INT_STATE3, 0x00},
187 {MAX98396_R2009_INT_STATE4, 0x00},
188 {MAX98396_R200B_INT_FLAG1, 0x00},
189 {MAX98396_R200C_INT_FLAG2, 0x00},
190 {MAX98396_R200D_INT_FLAG3, 0x00},
191 {MAX98396_R200E_INT_FLAG4, 0x00},
192 {MAX98396_R2010_INT_EN1, 0x02},
193 {MAX98396_R2011_INT_EN2, 0x00},
194 {MAX98396_R2012_INT_EN3, 0x00},
195 {MAX98396_R2013_INT_EN4, 0x00},
196 {MAX98396_R2015_INT_FLAG_CLR1, 0x00},
197 {MAX98396_R2016_INT_FLAG_CLR2, 0x00},
198 {MAX98396_R2017_INT_FLAG_CLR3, 0x00},
199 {MAX98396_R2018_INT_FLAG_CLR4, 0x00},
200 {MAX98396_R201F_IRQ_CTRL, 0x00},
201 {MAX98396_R2020_THERM_WARN_THRESH, 0x46},
202 {MAX98396_R2021_THERM_WARN_THRESH2, 0x46},
203 {MAX98396_R2022_THERM_SHDN_THRESH, 0x64},
204 {MAX98396_R2023_THERM_HYSTERESIS, 0x02},
205 {MAX98396_R2024_THERM_FOLDBACK_SET, 0xC5},
206 {MAX98396_R2027_THERM_FOLDBACK_EN, 0x01},
207 {MAX98396_R2030_NOISEGATE_MODE_CTRL, 0x32},
208 {MAX98396_R2033_NOISEGATE_MODE_EN, 0x00},
209 {MAX98396_R2038_CLK_MON_CTRL, 0x00},
210 {MAX98396_R2039_DATA_MON_CTRL, 0x00},
211 {MAX98397_R203A_SPK_MON_THRESH, 0x03},
212 {MAX98396_R203F_ENABLE_CTRLS, 0x0F},
213 {MAX98396_R2040_PIN_CFG, 0x55},
214 {MAX98396_R2041_PCM_MODE_CFG, 0xC0},
215 {MAX98396_R2042_PCM_CLK_SETUP, 0x04},
216 {MAX98396_R2043_PCM_SR_SETUP, 0x88},
217 {MAX98396_R2044_PCM_TX_CTRL_1, 0x00},
218 {MAX98396_R2045_PCM_TX_CTRL_2, 0x00},
219 {MAX98396_R2046_PCM_TX_CTRL_3, 0x00},
220 {MAX98396_R2047_PCM_TX_CTRL_4, 0x00},
221 {MAX98396_R2048_PCM_TX_CTRL_5, 0x00},
222 {MAX98396_R2049_PCM_TX_CTRL_6, 0x00},
223 {MAX98396_R204A_PCM_TX_CTRL_7, 0x00},
224 {MAX98396_R204B_PCM_TX_CTRL_8, 0x00},
225 {MAX98397_R204C_PCM_TX_CTRL_9, 0x00},
226 {MAX98397_R204D_PCM_TX_HIZ_CTRL_1, 0xFF},
227 {MAX98397_R204E_PCM_TX_HIZ_CTRL_2, 0xFF},
228 {MAX98397_R204F_PCM_TX_HIZ_CTRL_3, 0xFF},
229 {MAX98397_R2050_PCM_TX_HIZ_CTRL_4, 0xFF},
230 {MAX98397_R2051_PCM_TX_HIZ_CTRL_5, 0xFF},
231 {MAX98397_R2052_PCM_TX_HIZ_CTRL_6, 0xFF},
232 {MAX98397_R2053_PCM_TX_HIZ_CTRL_7, 0xFF},
233 {MAX98397_R2054_PCM_TX_HIZ_CTRL_8, 0xFF},
234 {MAX98397_R2056_PCM_RX_SRC1, 0x00},
235 {MAX98397_R2057_PCM_RX_SRC2, 0x00},
236 {MAX98396_R2058_PCM_BYPASS_SRC, 0x00},
237 {MAX98396_R205D_PCM_TX_SRC_EN, 0x00},
238 {MAX98396_R205E_PCM_RX_EN, 0x00},
239 {MAX98396_R205F_PCM_TX_EN, 0x00},
240 {MAX98397_R2060_PCM_TX_SUPPLY_SEL, 0x00},
241 {MAX98396_R2070_ICC_RX_EN_A, 0x00},
242 {MAX98396_R2071_ICC_RX_EN_B, 0x00},
243 {MAX98396_R2072_ICC_TX_CTRL, 0x00},
244 {MAX98396_R207F_ICC_EN, 0x00},
245 {MAX98396_R2083_TONE_GEN_DC_CFG, 0x04},
246 {MAX98396_R2084_TONE_GEN_DC_LVL1, 0x00},
247 {MAX98396_R2085_TONE_GEN_DC_LVL2, 0x00},
248 {MAX98396_R2086_TONE_GEN_DC_LVL3, 0x00},
249 {MAX98396_R208F_TONE_GEN_EN, 0x00},
250 {MAX98396_R2090_AMP_VOL_CTRL, 0x00},
251 {MAX98396_R2091_AMP_PATH_GAIN, 0x12},
252 {MAX98396_R2092_AMP_DSP_CFG, 0x22},
253 {MAX98396_R2093_SSM_CFG, 0x08},
254 {MAX98396_R2094_SPK_CLS_DG_THRESH, 0x12},
255 {MAX98396_R2095_SPK_CLS_DG_HDR, 0x17},
256 {MAX98396_R2096_SPK_CLS_DG_HOLD_TIME, 0x17},
257 {MAX98396_R2097_SPK_CLS_DG_DELAY, 0x00},
258 {MAX98396_R2098_SPK_CLS_DG_MODE, 0x00},
259 {MAX98396_R2099_SPK_CLS_DG_VBAT_LVL, 0x03},
260 {MAX98396_R209A_SPK_EDGE_CTRL, 0x00},
261 {MAX98397_R209B_SPK_PATH_WB_ONLY, 0x00},
262 {MAX98396_R209C_SPK_EDGE_CTRL1, 0x03},
263 {MAX98396_R209D_SPK_EDGE_CTRL2, 0xFC},
264 {MAX98396_R209E_AMP_CLIP_GAIN, 0x00},
265 {MAX98396_R209F_BYPASS_PATH_CFG, 0x00},
266 {MAX98396_R20AF_AMP_EN, 0x00},
267 {MAX98396_R20B0_ADC_SR, 0x30},
268 {MAX98396_R20B1_ADC_PVDD_CFG, 0x00},
269 {MAX98396_R20B2_ADC_VBAT_CFG, 0x00},
270 {MAX98396_R20B3_ADC_THERMAL_CFG, 0x00},
271 {MAX98397_R20B4_ADC_VDDH_CFG, 0x00},
272 {MAX98397_R20B5_ADC_READBACK_CTRL1, 0x00},
273 {MAX98397_R20B6_ADC_READBACK_CTRL2, 0x00},
274 {MAX98397_R20B7_ADC_PVDD_READBACK_MSB, 0x00},
275 {MAX98397_R20B8_ADC_PVDD_READBACK_LSB, 0x00},
276 {MAX98397_R20B9_ADC_VBAT_READBACK_MSB, 0x00},
277 {MAX98397_R20BA_ADC_VBAT_READBACK_LSB, 0x00},
278 {MAX98397_R20BB_ADC_TEMP_READBACK_MSB, 0x00},
279 {MAX98397_R20BC_ADC_TEMP_READBACK_LSB, 0x00},
280 {MAX98397_R20BD_ADC_VDDH__READBACK_MSB, 0x00},
281 {MAX98397_R20BE_ADC_VDDH_READBACK_LSB, 0x00},
282 {MAX98396_R20BF_ADC_LO_VBAT_READBACK_LSB, 0x00},
283 {MAX98397_R20C3_ADC_LO_VDDH_READBACK_MSB, 0x00},
284 {MAX98397_R20C4_ADC_LO_VDDH_READBACK_LSB, 0x00},
285 {MAX98397_R20C5_MEAS_ADC_OPTIMAL_MODE, 0x04},
286 {MAX98396_R20C7_ADC_CFG, 0x00},
287 {MAX98396_R20D0_DHT_CFG1, 0x00},
288 {MAX98396_R20D1_LIMITER_CFG1, 0x08},
289 {MAX98396_R20D2_LIMITER_CFG2, 0x00},
290 {MAX98396_R20D3_DHT_CFG2, 0x14},
291 {MAX98396_R20D4_DHT_CFG3, 0x02},
292 {MAX98396_R20D5_DHT_CFG4, 0x04},
293 {MAX98396_R20D6_DHT_HYSTERESIS_CFG, 0x07},
294 {MAX98396_R20DF_DHT_EN, 0x00},
295 {MAX98396_R20E0_IV_SENSE_PATH_CFG, 0x04},
296 {MAX98396_R20E4_IV_SENSE_PATH_EN, 0x00},
297 {MAX98396_R20E5_BPE_STATE, 0x00},
298 {MAX98396_R20E6_BPE_L3_THRESH_MSB, 0x00},
299 {MAX98396_R20E7_BPE_L3_THRESH_LSB, 0x00},
300 {MAX98396_R20E8_BPE_L2_THRESH_MSB, 0x00},
301 {MAX98396_R20E9_BPE_L2_THRESH_LSB, 0x00},
302 {MAX98396_R20EA_BPE_L1_THRESH_MSB, 0x00},
303 {MAX98396_R20EB_BPE_L1_THRESH_LSB, 0x00},
304 {MAX98396_R20EC_BPE_L0_THRESH_MSB, 0x00},
305 {MAX98396_R20ED_BPE_L0_THRESH_LSB, 0x00},
306 {MAX98396_R20EE_BPE_L3_DWELL_HOLD_TIME, 0x00},
307 {MAX98396_R20EF_BPE_L2_DWELL_HOLD_TIME, 0x00},
308 {MAX98396_R20F0_BPE_L1_DWELL_HOLD_TIME, 0x00},
309 {MAX98396_R20F1_BPE_L0_HOLD_TIME, 0x00},
310 {MAX98396_R20F2_BPE_L3_ATTACK_REL_STEP, 0x00},
311 {MAX98396_R20F3_BPE_L2_ATTACK_REL_STEP, 0x00},
312 {MAX98396_R20F4_BPE_L1_ATTACK_REL_STEP, 0x00},
313 {MAX98396_R20F5_BPE_L0_ATTACK_REL_STEP, 0x00},
314 {MAX98396_R20F6_BPE_L3_MAX_GAIN_ATTN, 0x00},
315 {MAX98396_R20F7_BPE_L2_MAX_GAIN_ATTN, 0x00},
316 {MAX98396_R20F8_BPE_L1_MAX_GAIN_ATTN, 0x00},
317 {MAX98396_R20F9_BPE_L0_MAX_GAIN_ATTN, 0x00},
318 {MAX98396_R20FA_BPE_L3_ATT_REL_RATE, 0x00},
319 {MAX98396_R20FB_BPE_L2_ATT_REL_RATE, 0x00},
320 {MAX98396_R20FC_BPE_L1_ATT_REL_RATE, 0x00},
321 {MAX98396_R20FD_BPE_L0_ATT_REL_RATE, 0x00},
322 {MAX98396_R20FE_BPE_L3_LIMITER_CFG, 0x00},
323 {MAX98396_R20FF_BPE_L2_LIMITER_CFG, 0x00},
324 {MAX98396_R2100_BPE_L1_LIMITER_CFG, 0x00},
325 {MAX98396_R2101_BPE_L0_LIMITER_CFG, 0x00},
326 {MAX98396_R2102_BPE_L3_LIM_ATT_REL_RATE, 0x00},
327 {MAX98396_R2103_BPE_L2_LIM_ATT_REL_RATE, 0x00},
328 {MAX98396_R2104_BPE_L1_LIM_ATT_REL_RATE, 0x00},
329 {MAX98396_R2105_BPE_L0_LIM_ATT_REL_RATE, 0x00},
330 {MAX98396_R2106_BPE_THRESH_HYSTERESIS, 0x00},
331 {MAX98396_R2107_BPE_INFINITE_HOLD_CLR, 0x00},
332 {MAX98396_R2108_BPE_SUPPLY_SRC, 0x00},
333 {MAX98396_R2109_BPE_LOW_STATE, 0x00},
334 {MAX98396_R210A_BPE_LOW_GAIN, 0x00},
335 {MAX98396_R210B_BPE_LOW_LIMITER, 0x00},
336 {MAX98396_R210D_BPE_EN, 0x00},
337 {MAX98396_R210E_AUTO_RESTART, 0x00},
338 {MAX98396_R210F_GLOBAL_EN, 0x00},
339 {MAX98397_R22FF_REVISION_ID, 0x00},
342 static void max98396_global_enable_onoff(struct regmap *regmap, bool onoff)
344 regmap_write(regmap, MAX98396_R210F_GLOBAL_EN, onoff ? 1 : 0);
345 usleep_range(11000, 12000);
348 static int max98396_dai_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
350 struct snd_soc_component *component = codec_dai->component;
351 struct max98396_priv *max98396 = snd_soc_component_get_drvdata(component);
352 unsigned int format_mask, format = 0;
353 unsigned int bclk_pol = 0;
358 format_mask = MAX98396_PCM_MODE_CFG_FORMAT_MASK |
359 MAX98396_PCM_MODE_CFG_LRCLKEDGE;
361 dev_dbg(component->dev, "%s: fmt 0x%08X\n", __func__, fmt);
363 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
364 case SND_SOC_DAIFMT_NB_NF:
366 case SND_SOC_DAIFMT_NB_IF:
367 format = MAX98396_PCM_MODE_CFG_LRCLKEDGE;
369 case SND_SOC_DAIFMT_IB_NF:
370 bclk_pol = MAX98396_PCM_MODE_CFG_BCLKEDGE;
372 case SND_SOC_DAIFMT_IB_IF:
373 bclk_pol = MAX98396_PCM_MODE_CFG_BCLKEDGE;
374 format = MAX98396_PCM_MODE_CFG_LRCLKEDGE;
378 dev_err(component->dev, "DAI invert mode %d unsupported\n",
379 fmt & SND_SOC_DAIFMT_INV_MASK);
383 /* interface format */
384 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
385 case SND_SOC_DAIFMT_I2S:
386 format |= MAX98396_PCM_FORMAT_I2S;
388 case SND_SOC_DAIFMT_LEFT_J:
389 format |= MAX98396_PCM_FORMAT_LJ;
391 case SND_SOC_DAIFMT_DSP_A:
392 format |= MAX98396_PCM_FORMAT_TDM_MODE1;
394 case SND_SOC_DAIFMT_DSP_B:
395 format |= MAX98396_PCM_FORMAT_TDM_MODE0;
398 dev_err(component->dev, "DAI format %d unsupported\n",
399 fmt & SND_SOC_DAIFMT_FORMAT_MASK);
403 ret = regmap_read(max98396->regmap, MAX98396_R210F_GLOBAL_EN, &status);
408 ret = regmap_read(max98396->regmap, MAX98396_R2041_PCM_MODE_CFG, ®);
411 if (format != (reg & format_mask)) {
414 ret = regmap_read(max98396->regmap,
415 MAX98396_R2042_PCM_CLK_SETUP, ®);
418 if (bclk_pol != (reg & MAX98396_PCM_MODE_CFG_BCLKEDGE))
421 /* GLOBAL_EN OFF prior to pcm mode, clock configuration change */
423 max98396_global_enable_onoff(max98396->regmap, false);
426 regmap_update_bits(max98396->regmap,
427 MAX98396_R2041_PCM_MODE_CFG,
428 format_mask, format);
430 regmap_update_bits(max98396->regmap,
431 MAX98396_R2042_PCM_CLK_SETUP,
432 MAX98396_PCM_MODE_CFG_BCLKEDGE,
435 if (status && update)
436 max98396_global_enable_onoff(max98396->regmap, true);
441 #define MAX98396_BSEL_32 0x2
442 #define MAX98396_BSEL_48 0x3
443 #define MAX98396_BSEL_64 0x4
444 #define MAX98396_BSEL_96 0x5
445 #define MAX98396_BSEL_128 0x6
446 #define MAX98396_BSEL_192 0x7
447 #define MAX98396_BSEL_256 0x8
448 #define MAX98396_BSEL_384 0x9
449 #define MAX98396_BSEL_512 0xa
450 #define MAX98396_BSEL_320 0xb
451 #define MAX98396_BSEL_250 0xc
452 #define MAX98396_BSEL_125 0xd
454 /* Refer to table 5 in the datasheet */
455 static const struct max98396_pcm_config {
456 int in, out, width, bsel, max_sr;
457 } max98396_pcm_configs[] = {
458 { .in = 2, .out = 4, .width = 16, .bsel = MAX98396_BSEL_32, .max_sr = 192000 },
459 { .in = 2, .out = 6, .width = 24, .bsel = MAX98396_BSEL_48, .max_sr = 192000 },
460 { .in = 2, .out = 8, .width = 32, .bsel = MAX98396_BSEL_64, .max_sr = 192000 },
461 { .in = 3, .out = 15, .width = 32, .bsel = MAX98396_BSEL_125, .max_sr = 192000 },
462 { .in = 4, .out = 8, .width = 16, .bsel = MAX98396_BSEL_64, .max_sr = 192000 },
463 { .in = 4, .out = 12, .width = 24, .bsel = MAX98396_BSEL_96, .max_sr = 192000 },
464 { .in = 4, .out = 16, .width = 32, .bsel = MAX98396_BSEL_128, .max_sr = 192000 },
465 { .in = 5, .out = 15, .width = 24, .bsel = MAX98396_BSEL_125, .max_sr = 192000 },
466 { .in = 7, .out = 15, .width = 16, .bsel = MAX98396_BSEL_125, .max_sr = 192000 },
467 { .in = 2, .out = 4, .width = 16, .bsel = MAX98396_BSEL_32, .max_sr = 96000 },
468 { .in = 2, .out = 6, .width = 24, .bsel = MAX98396_BSEL_48, .max_sr = 96000 },
469 { .in = 2, .out = 8, .width = 32, .bsel = MAX98396_BSEL_64, .max_sr = 96000 },
470 { .in = 3, .out = 15, .width = 32, .bsel = MAX98396_BSEL_125, .max_sr = 96000 },
471 { .in = 4, .out = 8, .width = 16, .bsel = MAX98396_BSEL_64, .max_sr = 96000 },
472 { .in = 4, .out = 12, .width = 24, .bsel = MAX98396_BSEL_96, .max_sr = 96000 },
473 { .in = 4, .out = 16, .width = 32, .bsel = MAX98396_BSEL_128, .max_sr = 96000 },
474 { .in = 5, .out = 15, .width = 24, .bsel = MAX98396_BSEL_125, .max_sr = 96000 },
475 { .in = 7, .out = 15, .width = 16, .bsel = MAX98396_BSEL_125, .max_sr = 96000 },
476 { .in = 7, .out = 31, .width = 32, .bsel = MAX98396_BSEL_250, .max_sr = 96000 },
477 { .in = 8, .out = 16, .width = 16, .bsel = MAX98396_BSEL_128, .max_sr = 96000 },
478 { .in = 8, .out = 24, .width = 24, .bsel = MAX98396_BSEL_192, .max_sr = 96000 },
479 { .in = 8, .out = 32, .width = 32, .bsel = MAX98396_BSEL_256, .max_sr = 96000 },
480 { .in = 10, .out = 31, .width = 24, .bsel = MAX98396_BSEL_250, .max_sr = 96000 },
481 { .in = 15, .out = 31, .width = 16, .bsel = MAX98396_BSEL_250, .max_sr = 96000 },
482 { .in = 16, .out = 32, .width = 16, .bsel = MAX98396_BSEL_256, .max_sr = 96000 },
483 { .in = 7, .out = 31, .width = 32, .bsel = MAX98396_BSEL_250, .max_sr = 48000 },
484 { .in = 10, .out = 31, .width = 24, .bsel = MAX98396_BSEL_250, .max_sr = 48000 },
485 { .in = 10, .out = 40, .width = 32, .bsel = MAX98396_BSEL_320, .max_sr = 48000 },
486 { .in = 15, .out = 31, .width = 16, .bsel = MAX98396_BSEL_250, .max_sr = 48000 },
487 { .in = 16, .out = 48, .width = 24, .bsel = MAX98396_BSEL_384, .max_sr = 48000 },
488 { .in = 16, .out = 64, .width = 32, .bsel = MAX98396_BSEL_512, .max_sr = 48000 },
491 static int max98396_pcm_config_index(int in_slots, int out_slots, int width)
495 for (i = 0; i < ARRAY_SIZE(max98396_pcm_configs); i++) {
496 const struct max98396_pcm_config *c = &max98396_pcm_configs[i];
498 if (in_slots == c->in && out_slots <= c->out && width == c->width)
505 static int max98396_dai_hw_params(struct snd_pcm_substream *substream,
506 struct snd_pcm_hw_params *params,
507 struct snd_soc_dai *dai)
509 struct snd_soc_component *component = dai->component;
510 struct max98396_priv *max98396 = snd_soc_component_get_drvdata(component);
511 unsigned int sampling_rate = 0;
512 unsigned int chan_sz = 0;
513 int ret, reg, status, bsel = 0;
516 /* pcm mode configuration */
517 switch (snd_pcm_format_width(params_format(params))) {
519 chan_sz = MAX98396_PCM_MODE_CFG_CHANSZ_16;
522 chan_sz = MAX98396_PCM_MODE_CFG_CHANSZ_24;
525 chan_sz = MAX98396_PCM_MODE_CFG_CHANSZ_32;
528 dev_err(component->dev, "format unsupported %d\n",
529 params_format(params));
533 dev_dbg(component->dev, "format supported %d",
534 params_format(params));
536 /* sampling rate configuration */
537 switch (params_rate(params)) {
539 sampling_rate = MAX98396_PCM_SR_8000;
542 sampling_rate = MAX98396_PCM_SR_11025;
545 sampling_rate = MAX98396_PCM_SR_12000;
548 sampling_rate = MAX98396_PCM_SR_16000;
551 sampling_rate = MAX98396_PCM_SR_22050;
554 sampling_rate = MAX98396_PCM_SR_24000;
557 sampling_rate = MAX98396_PCM_SR_32000;
560 sampling_rate = MAX98396_PCM_SR_44100;
563 sampling_rate = MAX98396_PCM_SR_48000;
566 sampling_rate = MAX98396_PCM_SR_88200;
569 sampling_rate = MAX98396_PCM_SR_96000;
572 sampling_rate = MAX98396_PCM_SR_192000;
575 dev_err(component->dev, "rate %d not supported\n",
576 params_rate(params));
580 if (max98396->tdm_mode) {
581 if (params_rate(params) > max98396->tdm_max_samplerate) {
582 dev_err(component->dev, "TDM sample rate %d too high",
583 params_rate(params));
587 /* BCLK configuration */
588 ret = max98396_pcm_config_index(params_channels(params),
589 params_channels(params),
590 snd_pcm_format_width(params_format(params)));
592 dev_err(component->dev,
593 "no PCM config for %d channels, format %d\n",
594 params_channels(params), params_format(params));
598 bsel = max98396_pcm_configs[ret].bsel;
600 if (params_rate(params) > max98396_pcm_configs[ret].max_sr) {
601 dev_err(component->dev, "sample rate %d too high",
602 params_rate(params));
607 ret = regmap_read(max98396->regmap, MAX98396_R210F_GLOBAL_EN, &status);
612 ret = regmap_read(max98396->regmap, MAX98396_R2041_PCM_MODE_CFG, ®);
615 if (chan_sz != (reg & MAX98396_PCM_MODE_CFG_CHANSZ_MASK)) {
618 ret = regmap_read(max98396->regmap, MAX98396_R2043_PCM_SR_SETUP, ®);
621 if (sampling_rate != (reg & MAX98396_PCM_SR_MASK))
625 /* GLOBAL_EN OFF prior to channel size and sampling rate change */
627 max98396_global_enable_onoff(max98396->regmap, false);
630 /* set channel size */
631 regmap_update_bits(max98396->regmap, MAX98396_R2041_PCM_MODE_CFG,
632 MAX98396_PCM_MODE_CFG_CHANSZ_MASK, chan_sz);
634 /* set DAI_SR to correct LRCLK frequency */
635 regmap_update_bits(max98396->regmap, MAX98396_R2043_PCM_SR_SETUP,
636 MAX98396_PCM_SR_MASK, sampling_rate);
638 /* set sampling rate of IV */
639 if (max98396->interleave_mode &&
640 sampling_rate > MAX98396_PCM_SR_16000)
641 regmap_update_bits(max98396->regmap,
642 MAX98396_R2043_PCM_SR_SETUP,
643 MAX98396_IVADC_SR_MASK,
645 << MAX98396_IVADC_SR_SHIFT);
647 regmap_update_bits(max98396->regmap,
648 MAX98396_R2043_PCM_SR_SETUP,
649 MAX98396_IVADC_SR_MASK,
650 sampling_rate << MAX98396_IVADC_SR_SHIFT);
653 regmap_update_bits(max98396->regmap,
654 MAX98396_R2042_PCM_CLK_SETUP,
655 MAX98396_PCM_CLK_SETUP_BSEL_MASK,
658 if (status && update)
659 max98396_global_enable_onoff(max98396->regmap, true);
667 static int max98396_dai_tdm_slot(struct snd_soc_dai *dai,
668 unsigned int tx_mask, unsigned int rx_mask,
669 int slots, int slot_width)
671 struct snd_soc_component *component = dai->component;
672 struct max98396_priv *max98396 =
673 snd_soc_component_get_drvdata(component);
675 unsigned int chan_sz = 0;
680 if (!tx_mask && !rx_mask && !slots && !slot_width)
681 max98396->tdm_mode = false;
683 max98396->tdm_mode = true;
685 /* BCLK configuration */
686 ret = max98396_pcm_config_index(slots, slots, slot_width);
688 dev_err(component->dev, "no TDM config for %d slots %d bits\n",
693 bsel = max98396_pcm_configs[ret].bsel;
694 max98396->tdm_max_samplerate = max98396_pcm_configs[ret].max_sr;
696 /* Channel size configuration */
697 switch (slot_width) {
699 chan_sz = MAX98396_PCM_MODE_CFG_CHANSZ_16;
702 chan_sz = MAX98396_PCM_MODE_CFG_CHANSZ_24;
705 chan_sz = MAX98396_PCM_MODE_CFG_CHANSZ_32;
708 dev_err(component->dev, "slot width %d unsupported\n",
713 ret = regmap_read(max98396->regmap, MAX98396_R210F_GLOBAL_EN, &status);
718 ret = regmap_read(max98396->regmap, MAX98396_R2042_PCM_CLK_SETUP, ®);
721 if (bsel != (reg & MAX98396_PCM_CLK_SETUP_BSEL_MASK)) {
724 ret = regmap_read(max98396->regmap, MAX98396_R2041_PCM_MODE_CFG, ®);
727 if (chan_sz != (reg & MAX98396_PCM_MODE_CFG_CHANSZ_MASK))
731 /* GLOBAL_EN OFF prior to channel size and BCLK per LRCLK change */
733 max98396_global_enable_onoff(max98396->regmap, false);
736 regmap_update_bits(max98396->regmap,
737 MAX98396_R2042_PCM_CLK_SETUP,
738 MAX98396_PCM_CLK_SETUP_BSEL_MASK,
741 regmap_update_bits(max98396->regmap,
742 MAX98396_R2041_PCM_MODE_CFG,
743 MAX98396_PCM_MODE_CFG_CHANSZ_MASK, chan_sz);
745 /* Rx slot configuration */
746 if (max98396->device_id == CODEC_TYPE_MAX98396) {
747 regmap_update_bits(max98396->regmap,
748 MAX98396_R2056_PCM_RX_SRC2,
749 MAX98396_PCM_DMIX_CH0_SRC_MASK,
751 regmap_update_bits(max98396->regmap,
752 MAX98396_R2056_PCM_RX_SRC2,
753 MAX98396_PCM_DMIX_CH1_SRC_MASK,
754 rx_mask << MAX98396_PCM_DMIX_CH1_SHIFT);
756 regmap_update_bits(max98396->regmap,
757 MAX98397_R2057_PCM_RX_SRC2,
758 MAX98396_PCM_DMIX_CH0_SRC_MASK,
760 regmap_update_bits(max98396->regmap,
761 MAX98397_R2057_PCM_RX_SRC2,
762 MAX98396_PCM_DMIX_CH1_SRC_MASK,
763 rx_mask << MAX98396_PCM_DMIX_CH1_SHIFT);
766 /* Tx slot Hi-Z configuration */
767 if (max98396->device_id == CODEC_TYPE_MAX98396) {
768 regmap_write(max98396->regmap,
769 MAX98396_R2053_PCM_TX_HIZ_CTRL_8,
771 regmap_write(max98396->regmap,
772 MAX98396_R2052_PCM_TX_HIZ_CTRL_7,
773 (~tx_mask & 0xFF00) >> 8);
775 regmap_write(max98396->regmap,
776 MAX98397_R2054_PCM_TX_HIZ_CTRL_8,
778 regmap_write(max98396->regmap,
779 MAX98397_R2053_PCM_TX_HIZ_CTRL_7,
780 (~tx_mask & 0xFF00) >> 8);
783 if (status && update)
784 max98396_global_enable_onoff(max98396->regmap, true);
789 #define MAX98396_RATES SNDRV_PCM_RATE_8000_192000
791 #define MAX98396_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
792 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
794 static const struct snd_soc_dai_ops max98396_dai_ops = {
795 .set_fmt = max98396_dai_set_fmt,
796 .hw_params = max98396_dai_hw_params,
797 .set_tdm_slot = max98396_dai_tdm_slot,
800 static int max98396_dac_event(struct snd_soc_dapm_widget *w,
801 struct snd_kcontrol *kcontrol, int event)
803 struct snd_soc_component *component =
804 snd_soc_dapm_to_component(w->dapm);
805 struct max98396_priv *max98396 =
806 snd_soc_component_get_drvdata(component);
809 case SND_SOC_DAPM_POST_PMU:
810 max98396_global_enable_onoff(max98396->regmap, true);
812 case SND_SOC_DAPM_PRE_PMD:
813 max98396_global_enable_onoff(max98396->regmap, false);
815 max98396->tdm_mode = false;
823 static bool max98396_readable_register(struct device *dev, unsigned int reg)
826 case MAX98396_R2001_INT_RAW1 ... MAX98396_R2004_INT_RAW4:
827 case MAX98396_R2006_INT_STATE1 ... MAX98396_R2009_INT_STATE4:
828 case MAX98396_R200B_INT_FLAG1 ... MAX98396_R200E_INT_FLAG4:
829 case MAX98396_R2010_INT_EN1 ... MAX98396_R2013_INT_EN4:
830 case MAX98396_R2015_INT_FLAG_CLR1 ... MAX98396_R2018_INT_FLAG_CLR4:
831 case MAX98396_R201F_IRQ_CTRL ... MAX98396_R2024_THERM_FOLDBACK_SET:
832 case MAX98396_R2027_THERM_FOLDBACK_EN:
833 case MAX98396_R2030_NOISEGATE_MODE_CTRL:
834 case MAX98396_R2033_NOISEGATE_MODE_EN:
835 case MAX98396_R2038_CLK_MON_CTRL ... MAX98396_R2039_DATA_MON_CTRL:
836 case MAX98396_R203F_ENABLE_CTRLS ... MAX98396_R2053_PCM_TX_HIZ_CTRL_8:
837 case MAX98396_R2055_PCM_RX_SRC1 ... MAX98396_R2056_PCM_RX_SRC2:
838 case MAX98396_R2058_PCM_BYPASS_SRC:
839 case MAX98396_R205D_PCM_TX_SRC_EN ... MAX98396_R205F_PCM_TX_EN:
840 case MAX98396_R2070_ICC_RX_EN_A... MAX98396_R2072_ICC_TX_CTRL:
841 case MAX98396_R207F_ICC_EN:
842 case MAX98396_R2083_TONE_GEN_DC_CFG ... MAX98396_R2086_TONE_GEN_DC_LVL3:
843 case MAX98396_R208F_TONE_GEN_EN ... MAX98396_R209A_SPK_EDGE_CTRL:
844 case MAX98396_R209C_SPK_EDGE_CTRL1 ... MAX98396_R20A0_AMP_SUPPLY_CTL:
845 case MAX98396_R20AF_AMP_EN ... MAX98396_R20BF_ADC_LO_VBAT_READBACK_LSB:
846 case MAX98396_R20C7_ADC_CFG:
847 case MAX98396_R20D0_DHT_CFG1 ... MAX98396_R20D6_DHT_HYSTERESIS_CFG:
848 case MAX98396_R20DF_DHT_EN:
849 case MAX98396_R20E0_IV_SENSE_PATH_CFG:
850 case MAX98396_R20E4_IV_SENSE_PATH_EN
851 ... MAX98396_R2106_BPE_THRESH_HYSTERESIS:
852 case MAX98396_R2108_BPE_SUPPLY_SRC ... MAX98396_R210B_BPE_LOW_LIMITER:
853 case MAX98396_R210D_BPE_EN ... MAX98396_R210F_GLOBAL_EN:
854 case MAX98396_R21FF_REVISION_ID:
861 static bool max98396_volatile_reg(struct device *dev, unsigned int reg)
864 case MAX98396_R2000_SW_RESET:
865 case MAX98396_R2001_INT_RAW1 ... MAX98396_R200E_INT_FLAG4:
866 case MAX98396_R2041_PCM_MODE_CFG:
867 case MAX98396_R20B6_ADC_PVDD_READBACK_MSB
868 ... MAX98396_R20BF_ADC_LO_VBAT_READBACK_LSB:
869 case MAX98396_R20E5_BPE_STATE:
870 case MAX98396_R2109_BPE_LOW_STATE
871 ... MAX98396_R210B_BPE_LOW_LIMITER:
872 case MAX98396_R210F_GLOBAL_EN:
873 case MAX98396_R21FF_REVISION_ID:
880 static bool max98397_readable_register(struct device *dev, unsigned int reg)
883 case MAX98396_R2001_INT_RAW1 ... MAX98396_R2004_INT_RAW4:
884 case MAX98396_R2006_INT_STATE1 ... MAX98396_R2009_INT_STATE4:
885 case MAX98396_R200B_INT_FLAG1 ... MAX98396_R200E_INT_FLAG4:
886 case MAX98396_R2010_INT_EN1 ... MAX98396_R2013_INT_EN4:
887 case MAX98396_R2015_INT_FLAG_CLR1 ... MAX98396_R2018_INT_FLAG_CLR4:
888 case MAX98396_R201F_IRQ_CTRL ... MAX98396_R2024_THERM_FOLDBACK_SET:
889 case MAX98396_R2027_THERM_FOLDBACK_EN:
890 case MAX98396_R2030_NOISEGATE_MODE_CTRL:
891 case MAX98396_R2033_NOISEGATE_MODE_EN:
892 case MAX98396_R2038_CLK_MON_CTRL ... MAX98397_R203A_SPK_MON_THRESH:
893 case MAX98396_R203F_ENABLE_CTRLS ... MAX98397_R2054_PCM_TX_HIZ_CTRL_8:
894 case MAX98397_R2056_PCM_RX_SRC1... MAX98396_R2058_PCM_BYPASS_SRC:
895 case MAX98396_R205D_PCM_TX_SRC_EN ... MAX98397_R2060_PCM_TX_SUPPLY_SEL:
896 case MAX98396_R2070_ICC_RX_EN_A... MAX98396_R2072_ICC_TX_CTRL:
897 case MAX98396_R207F_ICC_EN:
898 case MAX98396_R2083_TONE_GEN_DC_CFG ... MAX98396_R2086_TONE_GEN_DC_LVL3:
899 case MAX98396_R208F_TONE_GEN_EN ... MAX98396_R209F_BYPASS_PATH_CFG:
900 case MAX98396_R20AF_AMP_EN ... MAX98397_R20C5_MEAS_ADC_OPTIMAL_MODE:
901 case MAX98396_R20C7_ADC_CFG:
902 case MAX98396_R20D0_DHT_CFG1 ... MAX98396_R20D6_DHT_HYSTERESIS_CFG:
903 case MAX98396_R20DF_DHT_EN:
904 case MAX98396_R20E0_IV_SENSE_PATH_CFG:
905 case MAX98396_R20E4_IV_SENSE_PATH_EN
906 ... MAX98396_R2106_BPE_THRESH_HYSTERESIS:
907 case MAX98396_R2108_BPE_SUPPLY_SRC ... MAX98396_R210B_BPE_LOW_LIMITER:
908 case MAX98396_R210D_BPE_EN ... MAX98396_R210F_GLOBAL_EN:
909 case MAX98397_R22FF_REVISION_ID:
916 static bool max98397_volatile_reg(struct device *dev, unsigned int reg)
919 case MAX98396_R2001_INT_RAW1 ... MAX98396_R200E_INT_FLAG4:
920 case MAX98396_R2041_PCM_MODE_CFG:
921 case MAX98397_R20B7_ADC_PVDD_READBACK_MSB
922 ... MAX98397_R20C4_ADC_LO_VDDH_READBACK_LSB:
923 case MAX98396_R20E5_BPE_STATE:
924 case MAX98396_R2109_BPE_LOW_STATE
925 ... MAX98396_R210B_BPE_LOW_LIMITER:
926 case MAX98396_R210F_GLOBAL_EN:
927 case MAX98397_R22FF_REVISION_ID:
934 static const char * const max98396_op_mod_text[] = {
935 "DG", "PVDD", "VBAT",
938 static SOC_ENUM_SINGLE_DECL(max98396_op_mod_enum,
939 MAX98396_R2098_SPK_CLS_DG_MODE,
940 0, max98396_op_mod_text);
942 static DECLARE_TLV_DB_SCALE(max98396_digital_tlv, -6350, 50, 1);
943 static const DECLARE_TLV_DB_RANGE(max98396_spk_tlv,
944 0, 0x11, TLV_DB_SCALE_ITEM(400, 100, 0),
946 static DECLARE_TLV_DB_RANGE(max98397_digital_tlv,
947 0, 0x4A, TLV_DB_SCALE_ITEM(TLV_DB_GAIN_MUTE, 0, 1),
948 0x4B, 0xFF, TLV_DB_SCALE_ITEM(-9000, 50, 0),
950 static const DECLARE_TLV_DB_RANGE(max98397_spk_tlv,
951 0, 0x15, TLV_DB_SCALE_ITEM(600, 100, 0),
954 static int max98396_mux_get(struct snd_kcontrol *kcontrol,
955 struct snd_ctl_elem_value *ucontrol)
957 struct snd_soc_component *component =
958 snd_soc_dapm_kcontrol_component(kcontrol);
959 struct max98396_priv *max98396 = snd_soc_component_get_drvdata(component);
962 if (max98396->device_id == CODEC_TYPE_MAX98396)
963 reg = MAX98396_R2055_PCM_RX_SRC1;
965 reg = MAX98397_R2056_PCM_RX_SRC1;
967 regmap_read(max98396->regmap, reg, &val);
969 ucontrol->value.enumerated.item[0] = val;
974 static int max98396_mux_put(struct snd_kcontrol *kcontrol,
975 struct snd_ctl_elem_value *ucontrol)
977 struct snd_soc_component *component =
978 snd_soc_dapm_kcontrol_component(kcontrol);
979 struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kcontrol);
980 struct max98396_priv *max98396 = snd_soc_component_get_drvdata(component);
981 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
982 unsigned int *item = ucontrol->value.enumerated.item;
986 if (item[0] >= e->items)
989 val = snd_soc_enum_item_to_val(e, item[0]) << e->shift_l;
991 if (max98396->device_id == CODEC_TYPE_MAX98396)
992 reg = MAX98396_R2055_PCM_RX_SRC1;
994 reg = MAX98397_R2056_PCM_RX_SRC1;
996 change = snd_soc_component_test_bits(component, reg,
997 MAX98396_PCM_RX_MASK, val);
1000 regmap_update_bits(max98396->regmap, reg,
1001 MAX98396_PCM_RX_MASK, val);
1003 snd_soc_dapm_mux_update_power(dapm, kcontrol, item[0], e, NULL);
1008 static const char * const max98396_switch_text[] = {
1009 "Left", "Right", "LeftRight"};
1011 static SOC_ENUM_SINGLE_DECL(dai_sel_enum, SND_SOC_NOPM, 0,
1012 max98396_switch_text);
1014 static const struct snd_kcontrol_new max98396_dai_mux =
1015 SOC_DAPM_ENUM_EXT("DAI Sel Mux", dai_sel_enum,
1016 max98396_mux_get, max98396_mux_put);
1018 static const struct snd_kcontrol_new max98396_vi_control =
1019 SOC_DAPM_SINGLE("Switch", MAX98396_R205F_PCM_TX_EN, 0, 1, 0);
1021 static const struct snd_soc_dapm_widget max98396_dapm_widgets[] = {
1022 SND_SOC_DAPM_DAC_E("Amp Enable", "HiFi Playback",
1023 MAX98396_R20AF_AMP_EN, 0, 0, max98396_dac_event,
1024 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
1025 SND_SOC_DAPM_MUX("DAI Sel Mux", SND_SOC_NOPM, 0, 0,
1027 SND_SOC_DAPM_OUTPUT("BE_OUT"),
1028 SND_SOC_DAPM_AIF_OUT("Voltage Sense", "HiFi Capture", 0,
1029 MAX98396_R20E4_IV_SENSE_PATH_EN, 0, 0),
1030 SND_SOC_DAPM_AIF_OUT("Current Sense", "HiFi Capture", 0,
1031 MAX98396_R20E4_IV_SENSE_PATH_EN, 1, 0),
1032 SND_SOC_DAPM_SWITCH("VI Sense", SND_SOC_NOPM, 0, 0,
1033 &max98396_vi_control),
1034 SND_SOC_DAPM_SIGGEN("VMON"),
1035 SND_SOC_DAPM_SIGGEN("IMON"),
1036 SND_SOC_DAPM_SIGGEN("FBMON"),
1039 static const char * const max98396_thermal_thresh_text[] = {
1040 "50C", "51C", "52C", "53C", "54C", "55C", "56C", "57C",
1041 "58C", "59C", "60C", "61C", "62C", "63C", "64C", "65C",
1042 "66C", "67C", "68C", "69C", "70C", "71C", "72C", "73C",
1043 "74C", "75C", "76C", "77C", "78C", "79C", "80C", "81C",
1044 "82C", "83C", "84C", "85C", "86C", "87C", "88C", "89C",
1045 "90C", "91C", "92C", "93C", "94C", "95C", "96C", "97C",
1046 "98C", "99C", "100C", "101C", "102C", "103C", "104C", "105C",
1047 "106C", "107C", "108C", "109C", "110C", "111C", "112C", "113C",
1048 "114C", "115C", "116C", "117C", "118C", "119C", "120C", "121C",
1049 "122C", "123C", "124C", "125C", "126C", "127C", "128C", "129C",
1050 "130C", "131C", "132C", "133C", "134C", "135C", "136C", "137C",
1051 "138C", "139C", "140C", "141C", "142C", "143C", "144C", "145C",
1052 "146C", "147C", "148C", "149C", "150C"
1055 static SOC_ENUM_SINGLE_DECL(max98396_thermal_warn_thresh1_enum,
1056 MAX98396_R2020_THERM_WARN_THRESH, 0,
1057 max98396_thermal_thresh_text);
1059 static SOC_ENUM_SINGLE_DECL(max98396_thermal_warn_thresh2_enum,
1060 MAX98396_R2021_THERM_WARN_THRESH2, 0,
1061 max98396_thermal_thresh_text);
1063 static SOC_ENUM_SINGLE_DECL(max98396_thermal_shdn_thresh_enum,
1064 MAX98396_R2022_THERM_SHDN_THRESH, 0,
1065 max98396_thermal_thresh_text);
1067 static const char * const max98396_thermal_hyteresis_text[] = {
1068 "2C", "5C", "7C", "10C"
1071 static SOC_ENUM_SINGLE_DECL(max98396_thermal_hysteresis_enum,
1072 MAX98396_R2023_THERM_HYSTERESIS, 0,
1073 max98396_thermal_hyteresis_text);
1075 static const char * const max98396_foldback_slope_text[] = {
1076 "0.25", "0.5", "1.0", "2.0"
1079 static SOC_ENUM_SINGLE_DECL(max98396_thermal_fb_slope1_enum,
1080 MAX98396_R2024_THERM_FOLDBACK_SET,
1081 MAX98396_THERM_FB_SLOPE1_SHIFT,
1082 max98396_foldback_slope_text);
1084 static SOC_ENUM_SINGLE_DECL(max98396_thermal_fb_slope2_enum,
1085 MAX98396_R2024_THERM_FOLDBACK_SET,
1086 MAX98396_THERM_FB_SLOPE2_SHIFT,
1087 max98396_foldback_slope_text);
1089 static const char * const max98396_foldback_reltime_text[] = {
1090 "3ms", "10ms", "100ms", "300ms"
1093 static SOC_ENUM_SINGLE_DECL(max98396_thermal_fb_reltime_enum,
1094 MAX98396_R2024_THERM_FOLDBACK_SET,
1095 MAX98396_THERM_FB_REL_SHIFT,
1096 max98396_foldback_reltime_text);
1098 static const char * const max98396_foldback_holdtime_text[] = {
1099 "0ms", "20ms", "40ms", "80ms"
1102 static SOC_ENUM_SINGLE_DECL(max98396_thermal_fb_holdtime_enum,
1103 MAX98396_R2024_THERM_FOLDBACK_SET,
1104 MAX98396_THERM_FB_HOLD_SHIFT,
1105 max98396_foldback_holdtime_text);
1107 static int max98396_adc_value_get(struct snd_kcontrol *kcontrol,
1108 struct snd_ctl_elem_value *ucontrol)
1110 struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
1111 struct soc_mixer_control *mc =
1112 (struct soc_mixer_control *)kcontrol->private_value;
1113 struct max98396_priv *max98396 = snd_soc_component_get_drvdata(component);
1118 /* ADC value is not available if the device is powered down */
1119 if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF)
1122 if (max98396->device_id == CODEC_TYPE_MAX98397) {
1124 case MAX98396_R20B6_ADC_PVDD_READBACK_MSB:
1125 reg = MAX98397_R20B7_ADC_PVDD_READBACK_MSB;
1127 case MAX98396_R20B8_ADC_VBAT_READBACK_MSB:
1128 reg = MAX98397_R20B9_ADC_VBAT_READBACK_MSB;
1130 case MAX98396_R20BA_ADC_TEMP_READBACK_MSB:
1131 reg = MAX98397_R20BB_ADC_TEMP_READBACK_MSB;
1138 ret = regmap_raw_read(max98396->regmap, reg, &val, 2);
1142 /* ADC readback bits[8:0] rearrangement */
1143 ucontrol->value.integer.value[0] = (val[0] << 1) | (val[1] & 1);
1147 ucontrol->value.integer.value[0] = 0;
1151 static const struct snd_kcontrol_new max98396_snd_controls[] = {
1153 SOC_SINGLE_TLV("Digital Volume", MAX98396_R2090_AMP_VOL_CTRL,
1154 0, 0x7F, 1, max98396_digital_tlv),
1155 SOC_SINGLE_TLV("Speaker Volume", MAX98396_R2091_AMP_PATH_GAIN,
1156 0, 0x11, 0, max98396_spk_tlv),
1157 /* Volume Ramp Up/Down Enable*/
1158 SOC_SINGLE("Ramp Up Switch", MAX98396_R2092_AMP_DSP_CFG,
1159 MAX98396_DSP_SPK_VOL_RMPUP_SHIFT, 1, 0),
1160 SOC_SINGLE("Ramp Down Switch", MAX98396_R2092_AMP_DSP_CFG,
1161 MAX98396_DSP_SPK_VOL_RMPDN_SHIFT, 1, 0),
1162 /* Clock Monitor Enable */
1163 SOC_SINGLE("CLK Monitor Switch", MAX98396_R203F_ENABLE_CTRLS,
1164 MAX98396_CTRL_CMON_EN_SHIFT, 1, 0),
1166 SOC_SINGLE("Dither Switch", MAX98396_R2092_AMP_DSP_CFG,
1167 MAX98396_DSP_SPK_DITH_EN_SHIFT, 1, 0),
1168 SOC_SINGLE("IV Dither Switch", MAX98396_R20E0_IV_SENSE_PATH_CFG,
1169 MAX98396_IV_SENSE_DITH_EN_SHIFT, 1, 0),
1170 /* DC Blocker Enable */
1171 SOC_SINGLE("DC Blocker Switch", MAX98396_R2092_AMP_DSP_CFG,
1172 MAX98396_DSP_SPK_DCBLK_EN_SHIFT, 1, 0),
1173 SOC_SINGLE("IV DC Blocker Switch", MAX98396_R20E0_IV_SENSE_PATH_CFG,
1174 MAX98396_IV_SENSE_DCBLK_EN_SHIFT, 3, 0),
1175 /* Speaker Safe Mode Enable */
1176 SOC_SINGLE("Safe Mode Switch", MAX98396_R2092_AMP_DSP_CFG,
1177 MAX98396_DSP_SPK_SAFE_EN_SHIFT, 1, 0),
1178 /* Wideband Filter Enable */
1179 SOC_SINGLE("WB Filter Switch", MAX98396_R2092_AMP_DSP_CFG,
1180 MAX98396_DSP_SPK_WB_FLT_EN_SHIFT, 1, 0),
1181 SOC_SINGLE("IV WB Filter Switch", MAX98396_R20E0_IV_SENSE_PATH_CFG,
1182 MAX98396_IV_SENSE_WB_FLT_EN_SHIFT, 1, 0),
1183 /* Dynamic Headroom Tracking */
1184 SOC_SINGLE("DHT Switch", MAX98396_R20DF_DHT_EN, 0, 1, 0),
1185 /* Brownout Protection Engine */
1186 SOC_SINGLE("BPE Switch", MAX98396_R210D_BPE_EN, 0, 1, 0),
1187 SOC_SINGLE("BPE Limiter Switch", MAX98396_R210D_BPE_EN, 1, 1, 0),
1188 /* Bypass Path Enable */
1189 SOC_SINGLE("Bypass Path Switch",
1190 MAX98396_R205E_PCM_RX_EN, 1, 1, 0),
1191 /* Speaker Operation Mode */
1192 SOC_ENUM("OP Mode", max98396_op_mod_enum),
1193 /* Auto Restart functions */
1194 SOC_SINGLE("CMON Auto Restart Switch", MAX98396_R2038_CLK_MON_CTRL,
1195 MAX98396_CLK_MON_AUTO_RESTART_SHIFT, 1, 0),
1196 SOC_SINGLE("PVDD Auto Restart Switch", MAX98396_R210E_AUTO_RESTART,
1197 MAX98396_PVDD_UVLO_RESTART_SHFT, 1, 0),
1198 SOC_SINGLE("VBAT Auto Restart Switch", MAX98396_R210E_AUTO_RESTART,
1199 MAX98396_VBAT_UVLO_RESTART_SHFT, 1, 0),
1200 SOC_SINGLE("THERM Auto Restart Switch", MAX98396_R210E_AUTO_RESTART,
1201 MAX98396_THEM_SHDN_RESTART_SHFT, 1, 0),
1202 SOC_SINGLE("OVC Auto Restart Switch", MAX98396_R210E_AUTO_RESTART,
1203 MAX98396_OVC_RESTART_SHFT, 1, 0),
1204 /* Thermal Threshold */
1205 SOC_ENUM("THERM Thresh1", max98396_thermal_warn_thresh1_enum),
1206 SOC_ENUM("THERM Thresh2", max98396_thermal_warn_thresh2_enum),
1207 SOC_ENUM("THERM SHDN Thresh", max98396_thermal_shdn_thresh_enum),
1208 SOC_ENUM("THERM Hysteresis", max98396_thermal_hysteresis_enum),
1209 SOC_SINGLE("THERM Foldback Switch",
1210 MAX98396_R2027_THERM_FOLDBACK_EN, 0, 1, 0),
1211 SOC_ENUM("THERM Slope1", max98396_thermal_fb_slope1_enum),
1212 SOC_ENUM("THERM Slope2", max98396_thermal_fb_slope2_enum),
1213 SOC_ENUM("THERM Release", max98396_thermal_fb_reltime_enum),
1214 SOC_ENUM("THERM Hold", max98396_thermal_fb_holdtime_enum),
1216 SOC_SINGLE_EXT("ADC PVDD", MAX98396_R20B6_ADC_PVDD_READBACK_MSB, 0, 0x1FF, 0,
1217 max98396_adc_value_get, NULL),
1218 SOC_SINGLE_EXT("ADC VBAT", MAX98396_R20B8_ADC_VBAT_READBACK_MSB, 0, 0x1FF, 0,
1219 max98396_adc_value_get, NULL),
1220 SOC_SINGLE_EXT("ADC TEMP", MAX98396_R20BA_ADC_TEMP_READBACK_MSB, 0, 0x1FF, 0,
1221 max98396_adc_value_get, NULL),
1224 static const struct snd_kcontrol_new max98397_snd_controls[] = {
1226 SOC_SINGLE_TLV("Digital Volume", MAX98396_R2090_AMP_VOL_CTRL,
1227 0, 0xFF, 1, max98397_digital_tlv),
1228 SOC_SINGLE_TLV("Speaker Volume", MAX98396_R2091_AMP_PATH_GAIN,
1229 0, 0x15, 0, max98397_spk_tlv),
1230 /* Volume Ramp Up/Down Enable*/
1231 SOC_SINGLE("Ramp Up Switch", MAX98396_R2092_AMP_DSP_CFG,
1232 MAX98396_DSP_SPK_VOL_RMPUP_SHIFT, 1, 0),
1233 SOC_SINGLE("Ramp Down Switch", MAX98396_R2092_AMP_DSP_CFG,
1234 MAX98396_DSP_SPK_VOL_RMPDN_SHIFT, 1, 0),
1235 /* Clock Monitor Enable */
1236 SOC_SINGLE("CLK Monitor Switch", MAX98396_R203F_ENABLE_CTRLS,
1237 MAX98396_CTRL_CMON_EN_SHIFT, 1, 0),
1239 SOC_SINGLE("Dither Switch", MAX98396_R2092_AMP_DSP_CFG,
1240 MAX98396_DSP_SPK_DITH_EN_SHIFT, 1, 0),
1241 SOC_SINGLE("IV Dither Switch", MAX98396_R20E0_IV_SENSE_PATH_CFG,
1242 MAX98396_IV_SENSE_DITH_EN_SHIFT, 1, 0),
1243 /* DC Blocker Enable */
1244 SOC_SINGLE("DC Blocker Switch", MAX98396_R2092_AMP_DSP_CFG,
1245 MAX98396_DSP_SPK_DCBLK_EN_SHIFT, 1, 0),
1246 SOC_SINGLE("IV DC Blocker Switch", MAX98396_R20E0_IV_SENSE_PATH_CFG,
1247 MAX98396_IV_SENSE_DCBLK_EN_SHIFT, 3, 0),
1248 /* Speaker Safe Mode Enable */
1249 SOC_SINGLE("Safe Mode Switch", MAX98396_R2092_AMP_DSP_CFG,
1250 MAX98396_DSP_SPK_SAFE_EN_SHIFT, 1, 0),
1251 /* Wideband Filter Enable */
1252 SOC_SINGLE("WB Filter Switch", MAX98396_R2092_AMP_DSP_CFG,
1253 MAX98396_DSP_SPK_WB_FLT_EN_SHIFT, 1, 0),
1254 SOC_SINGLE("IV WB Filter Switch", MAX98396_R20E0_IV_SENSE_PATH_CFG,
1255 MAX98396_IV_SENSE_WB_FLT_EN_SHIFT, 1, 0),
1256 /* Dynamic Headroom Tracking */
1257 SOC_SINGLE("DHT Switch", MAX98396_R20DF_DHT_EN, 0, 1, 0),
1258 /* Brownout Protection Engine */
1259 SOC_SINGLE("BPE Switch", MAX98396_R210D_BPE_EN, 0, 1, 0),
1260 SOC_SINGLE("BPE Limiter Switch", MAX98396_R210D_BPE_EN, 1, 1, 0),
1261 /* Bypass Path Enable */
1262 SOC_SINGLE("Bypass Path Switch",
1263 MAX98396_R205E_PCM_RX_EN, 1, 1, 0),
1264 /* Speaker Operation Mode */
1265 SOC_ENUM("OP Mode", max98396_op_mod_enum),
1266 /* Auto Restart functions */
1267 SOC_SINGLE("CMON Auto Restart Switch", MAX98396_R2038_CLK_MON_CTRL,
1268 MAX98396_CLK_MON_AUTO_RESTART_SHIFT, 1, 0),
1269 SOC_SINGLE("PVDD Auto Restart Switch", MAX98396_R210E_AUTO_RESTART,
1270 MAX98396_PVDD_UVLO_RESTART_SHFT, 1, 0),
1271 SOC_SINGLE("VBAT Auto Restart Switch", MAX98396_R210E_AUTO_RESTART,
1272 MAX98396_VBAT_UVLO_RESTART_SHFT, 1, 0),
1273 SOC_SINGLE("THERM Auto Restart Switch", MAX98396_R210E_AUTO_RESTART,
1274 MAX98396_THEM_SHDN_RESTART_SHFT, 1, 0),
1275 SOC_SINGLE("OVC Auto Restart Switch", MAX98396_R210E_AUTO_RESTART,
1276 MAX98396_OVC_RESTART_SHFT, 1, 0),
1277 /* Thermal Threshold */
1278 SOC_ENUM("THERM Thresh1", max98396_thermal_warn_thresh1_enum),
1279 SOC_ENUM("THERM Thresh2", max98396_thermal_warn_thresh2_enum),
1280 SOC_ENUM("THERM SHDN Thresh", max98396_thermal_shdn_thresh_enum),
1281 SOC_ENUM("THERM Hysteresis", max98396_thermal_hysteresis_enum),
1282 SOC_SINGLE("THERM Foldback Switch",
1283 MAX98396_R2027_THERM_FOLDBACK_EN, 0, 1, 0),
1284 SOC_ENUM("THERM Slope1", max98396_thermal_fb_slope1_enum),
1285 SOC_ENUM("THERM Slope2", max98396_thermal_fb_slope2_enum),
1286 SOC_ENUM("THERM Release", max98396_thermal_fb_reltime_enum),
1287 SOC_ENUM("THERM Hold", max98396_thermal_fb_holdtime_enum),
1289 SOC_SINGLE_EXT("ADC PVDD", MAX98396_R20B6_ADC_PVDD_READBACK_MSB, 0, 0x1FF, 0,
1290 max98396_adc_value_get, NULL),
1291 SOC_SINGLE_EXT("ADC VBAT", MAX98396_R20B8_ADC_VBAT_READBACK_MSB, 0, 0x1FF, 0,
1292 max98396_adc_value_get, NULL),
1293 SOC_SINGLE_EXT("ADC TEMP", MAX98396_R20BA_ADC_TEMP_READBACK_MSB, 0, 0x1FF, 0,
1294 max98396_adc_value_get, NULL),
1297 static const struct snd_soc_dapm_route max98396_audio_map[] = {
1299 {"DAI Sel Mux", "Left", "Amp Enable"},
1300 {"DAI Sel Mux", "Right", "Amp Enable"},
1301 {"DAI Sel Mux", "LeftRight", "Amp Enable"},
1302 {"BE_OUT", NULL, "DAI Sel Mux"},
1304 { "VI Sense", "Switch", "VMON" },
1305 { "VI Sense", "Switch", "IMON" },
1306 { "Voltage Sense", NULL, "VI Sense" },
1307 { "Current Sense", NULL, "VI Sense" },
1310 static struct snd_soc_dai_driver max98396_dai[] = {
1312 .name = "max98396-aif1",
1314 .stream_name = "HiFi Playback",
1317 .rates = MAX98396_RATES,
1318 .formats = MAX98396_FORMATS,
1321 .stream_name = "HiFi Capture",
1324 .rates = MAX98396_RATES,
1325 .formats = MAX98396_FORMATS,
1327 .ops = &max98396_dai_ops,
1331 static struct snd_soc_dai_driver max98397_dai[] = {
1333 .name = "max98397-aif1",
1335 .stream_name = "HiFi Playback",
1338 .rates = MAX98396_RATES,
1339 .formats = MAX98396_FORMATS,
1342 .stream_name = "HiFi Capture",
1345 .rates = MAX98396_RATES,
1346 .formats = MAX98396_FORMATS,
1348 .ops = &max98396_dai_ops,
1352 static void max98396_reset(struct max98396_priv *max98396, struct device *dev)
1354 int ret, reg, count;
1356 /* Software Reset */
1357 ret = regmap_write(max98396->regmap,
1358 MAX98396_R2000_SW_RESET, 1);
1360 dev_err(dev, "Reset command failed. (ret:%d)\n", ret);
1364 usleep_range(5000, 6000);
1365 /* Software Reset Verification */
1366 ret = regmap_read(max98396->regmap,
1367 GET_REG_ADDR_REV_ID(max98396->device_id), ®);
1369 dev_info(dev, "Reset completed (retry:%d)\n", count);
1374 dev_err(dev, "Reset failed. (ret:%d)\n", ret);
1377 static int max98396_probe(struct snd_soc_component *component)
1379 struct max98396_priv *max98396 =
1380 snd_soc_component_get_drvdata(component);
1382 /* Software Reset */
1383 max98396_reset(max98396, component->dev);
1385 /* L/R mix configuration */
1386 if (max98396->device_id == CODEC_TYPE_MAX98396) {
1387 regmap_write(max98396->regmap,
1388 MAX98396_R2055_PCM_RX_SRC1, 0x02);
1389 regmap_write(max98396->regmap,
1390 MAX98396_R2056_PCM_RX_SRC2, 0x10);
1392 regmap_write(max98396->regmap,
1393 MAX98397_R2056_PCM_RX_SRC1, 0x02);
1394 regmap_write(max98396->regmap,
1395 MAX98397_R2057_PCM_RX_SRC2, 0x10);
1397 /* Supply control */
1398 regmap_update_bits(max98396->regmap,
1399 MAX98396_R20A0_AMP_SUPPLY_CTL,
1400 MAX98396_AMP_SUPPLY_NOVBAT,
1401 (max98396->vbat == NULL) ?
1402 MAX98396_AMP_SUPPLY_NOVBAT : 0);
1403 /* Enable DC blocker */
1404 regmap_update_bits(max98396->regmap,
1405 MAX98396_R2092_AMP_DSP_CFG, 1, 1);
1406 /* Enable IV Monitor DC blocker */
1407 regmap_update_bits(max98396->regmap,
1408 MAX98396_R20E0_IV_SENSE_PATH_CFG,
1409 MAX98396_IV_SENSE_DCBLK_EN_MASK,
1410 MAX98396_IV_SENSE_DCBLK_EN_MASK);
1411 /* Configure default data output sources */
1412 regmap_write(max98396->regmap,
1413 MAX98396_R205D_PCM_TX_SRC_EN, 3);
1414 /* Enable Wideband Filter */
1415 regmap_update_bits(max98396->regmap,
1416 MAX98396_R2092_AMP_DSP_CFG, 0x40, 0x40);
1417 /* Enable IV Wideband Filter */
1418 regmap_update_bits(max98396->regmap,
1419 MAX98396_R20E0_IV_SENSE_PATH_CFG, 8, 8);
1421 /* Enable Bypass Source */
1422 regmap_write(max98396->regmap,
1423 MAX98396_R2058_PCM_BYPASS_SRC,
1424 max98396->bypass_slot);
1425 /* Voltage, current slot configuration */
1426 regmap_write(max98396->regmap,
1427 MAX98396_R2044_PCM_TX_CTRL_1,
1429 regmap_write(max98396->regmap,
1430 MAX98396_R2045_PCM_TX_CTRL_2,
1432 regmap_write(max98396->regmap,
1433 MAX98396_R204A_PCM_TX_CTRL_7,
1434 max98396->spkfb_slot);
1436 if (max98396->v_slot < 8)
1437 if (max98396->device_id == CODEC_TYPE_MAX98396)
1438 regmap_update_bits(max98396->regmap,
1439 MAX98396_R2053_PCM_TX_HIZ_CTRL_8,
1440 1 << max98396->v_slot, 0);
1442 regmap_update_bits(max98396->regmap,
1443 MAX98397_R2054_PCM_TX_HIZ_CTRL_8,
1444 1 << max98396->v_slot, 0);
1446 if (max98396->device_id == CODEC_TYPE_MAX98396)
1447 regmap_update_bits(max98396->regmap,
1448 MAX98396_R2052_PCM_TX_HIZ_CTRL_7,
1449 1 << (max98396->v_slot - 8), 0);
1451 regmap_update_bits(max98396->regmap,
1452 MAX98397_R2053_PCM_TX_HIZ_CTRL_7,
1453 1 << (max98396->v_slot - 8), 0);
1455 if (max98396->i_slot < 8)
1456 if (max98396->device_id == CODEC_TYPE_MAX98396)
1457 regmap_update_bits(max98396->regmap,
1458 MAX98396_R2053_PCM_TX_HIZ_CTRL_8,
1459 1 << max98396->i_slot, 0);
1461 regmap_update_bits(max98396->regmap,
1462 MAX98397_R2054_PCM_TX_HIZ_CTRL_8,
1463 1 << max98396->i_slot, 0);
1465 if (max98396->device_id == CODEC_TYPE_MAX98396)
1466 regmap_update_bits(max98396->regmap,
1467 MAX98396_R2052_PCM_TX_HIZ_CTRL_7,
1468 1 << (max98396->i_slot - 8), 0);
1470 regmap_update_bits(max98396->regmap,
1471 MAX98397_R2053_PCM_TX_HIZ_CTRL_7,
1472 1 << (max98396->i_slot - 8), 0);
1474 /* Set interleave mode */
1475 if (max98396->interleave_mode)
1476 regmap_update_bits(max98396->regmap,
1477 MAX98396_R2041_PCM_MODE_CFG,
1478 MAX98396_PCM_TX_CH_INTERLEAVE_MASK,
1479 MAX98396_PCM_TX_CH_INTERLEAVE_MASK);
1481 regmap_update_bits(max98396->regmap,
1482 MAX98396_R2038_CLK_MON_CTRL,
1483 MAX98396_CLK_MON_AUTO_RESTART_MASK,
1484 MAX98396_CLK_MON_AUTO_RESTART_MASK);
1486 regmap_update_bits(max98396->regmap,
1487 MAX98396_R203F_ENABLE_CTRLS,
1488 MAX98396_CTRL_DMON_STUCK_EN_MASK,
1489 max98396->dmon_stuck_enable ?
1490 MAX98396_CTRL_DMON_STUCK_EN_MASK : 0);
1492 regmap_update_bits(max98396->regmap,
1493 MAX98396_R203F_ENABLE_CTRLS,
1494 MAX98396_CTRL_DMON_MAG_EN_MASK,
1495 max98396->dmon_mag_enable ?
1496 MAX98396_CTRL_DMON_MAG_EN_MASK : 0);
1498 switch (max98396->dmon_duration) {
1500 regmap_update_bits(max98396->regmap,
1501 MAX98396_R2039_DATA_MON_CTRL,
1502 MAX98396_DMON_DURATION_MASK, 0);
1505 regmap_update_bits(max98396->regmap,
1506 MAX98396_R2039_DATA_MON_CTRL,
1507 MAX98396_DMON_DURATION_MASK, 1);
1510 regmap_update_bits(max98396->regmap,
1511 MAX98396_R2039_DATA_MON_CTRL,
1512 MAX98396_DMON_DURATION_MASK, 2);
1515 regmap_update_bits(max98396->regmap,
1516 MAX98396_R2039_DATA_MON_CTRL,
1517 MAX98396_DMON_DURATION_MASK, 3);
1520 dev_err(component->dev, "Invalid DMON duration %d\n",
1521 max98396->dmon_duration);
1524 switch (max98396->dmon_stuck_threshold) {
1526 regmap_update_bits(max98396->regmap,
1527 MAX98396_R2039_DATA_MON_CTRL,
1528 MAX98396_DMON_STUCK_THRESH_MASK,
1529 0 << MAX98396_DMON_STUCK_THRESH_SHIFT);
1532 regmap_update_bits(max98396->regmap,
1533 MAX98396_R2039_DATA_MON_CTRL,
1534 MAX98396_DMON_STUCK_THRESH_MASK,
1535 1 << MAX98396_DMON_STUCK_THRESH_SHIFT);
1538 regmap_update_bits(max98396->regmap,
1539 MAX98396_R2039_DATA_MON_CTRL,
1540 MAX98396_DMON_STUCK_THRESH_MASK,
1541 2 << MAX98396_DMON_STUCK_THRESH_SHIFT);
1544 regmap_update_bits(max98396->regmap,
1545 MAX98396_R2039_DATA_MON_CTRL,
1546 MAX98396_DMON_STUCK_THRESH_MASK,
1547 3 << MAX98396_DMON_STUCK_THRESH_SHIFT);
1550 dev_err(component->dev, "Invalid DMON stuck threshold %d\n",
1551 max98396->dmon_stuck_threshold);
1554 switch (max98396->dmon_mag_threshold) {
1556 regmap_update_bits(max98396->regmap,
1557 MAX98396_R2039_DATA_MON_CTRL,
1558 MAX98396_DMON_STUCK_THRESH_MASK,
1559 (5 - max98396->dmon_mag_threshold)
1560 << MAX98396_DMON_MAG_THRESH_SHIFT);
1563 dev_err(component->dev, "Invalid DMON magnitude threshold %d\n",
1564 max98396->dmon_mag_threshold);
1567 /* Speaker Amplifier PCM RX Enable by default */
1568 regmap_update_bits(max98396->regmap,
1569 MAX98396_R205E_PCM_RX_EN,
1570 MAX98396_PCM_RX_EN_MASK, 1);
1575 #ifdef CONFIG_PM_SLEEP
1576 static int max98396_suspend(struct device *dev)
1578 struct max98396_priv *max98396 = dev_get_drvdata(dev);
1580 regcache_cache_only(max98396->regmap, true);
1581 regcache_mark_dirty(max98396->regmap);
1582 regulator_bulk_disable(MAX98396_NUM_CORE_SUPPLIES,
1583 max98396->core_supplies);
1585 regulator_disable(max98396->pvdd);
1588 regulator_disable(max98396->vbat);
1593 static int max98396_resume(struct device *dev)
1595 struct max98396_priv *max98396 = dev_get_drvdata(dev);
1598 ret = regulator_bulk_enable(MAX98396_NUM_CORE_SUPPLIES,
1599 max98396->core_supplies);
1603 if (max98396->pvdd) {
1604 ret = regulator_enable(max98396->pvdd);
1609 if (max98396->vbat) {
1610 ret = regulator_enable(max98396->vbat);
1615 regcache_cache_only(max98396->regmap, false);
1616 max98396_reset(max98396, dev);
1617 regcache_sync(max98396->regmap);
1622 static const struct dev_pm_ops max98396_pm = {
1623 SET_SYSTEM_SLEEP_PM_OPS(max98396_suspend, max98396_resume)
1626 static const struct snd_soc_component_driver soc_codec_dev_max98396 = {
1627 .probe = max98396_probe,
1628 .controls = max98396_snd_controls,
1629 .num_controls = ARRAY_SIZE(max98396_snd_controls),
1630 .dapm_widgets = max98396_dapm_widgets,
1631 .num_dapm_widgets = ARRAY_SIZE(max98396_dapm_widgets),
1632 .dapm_routes = max98396_audio_map,
1633 .num_dapm_routes = ARRAY_SIZE(max98396_audio_map),
1635 .use_pmdown_time = 1,
1639 static const struct snd_soc_component_driver soc_codec_dev_max98397 = {
1640 .probe = max98396_probe,
1641 .controls = max98397_snd_controls,
1642 .num_controls = ARRAY_SIZE(max98397_snd_controls),
1643 .dapm_widgets = max98396_dapm_widgets,
1644 .num_dapm_widgets = ARRAY_SIZE(max98396_dapm_widgets),
1645 .dapm_routes = max98396_audio_map,
1646 .num_dapm_routes = ARRAY_SIZE(max98396_audio_map),
1648 .use_pmdown_time = 1,
1652 static const struct regmap_config max98396_regmap = {
1655 .max_register = MAX98396_R21FF_REVISION_ID,
1656 .reg_defaults = max98396_reg,
1657 .num_reg_defaults = ARRAY_SIZE(max98396_reg),
1658 .readable_reg = max98396_readable_register,
1659 .volatile_reg = max98396_volatile_reg,
1660 .cache_type = REGCACHE_RBTREE,
1663 static const struct regmap_config max98397_regmap = {
1666 .max_register = MAX98397_R22FF_REVISION_ID,
1667 .reg_defaults = max98397_reg,
1668 .num_reg_defaults = ARRAY_SIZE(max98397_reg),
1669 .readable_reg = max98397_readable_register,
1670 .volatile_reg = max98397_volatile_reg,
1671 .cache_type = REGCACHE_RBTREE,
1674 static void max98396_read_device_property(struct device *dev,
1675 struct max98396_priv *max98396)
1679 if (!device_property_read_u32(dev, "adi,vmon-slot-no", &value))
1680 max98396->v_slot = value & 0xF;
1682 max98396->v_slot = 0;
1684 if (!device_property_read_u32(dev, "adi,imon-slot-no", &value))
1685 max98396->i_slot = value & 0xF;
1687 max98396->i_slot = 1;
1689 if (!device_property_read_u32(dev, "adi,spkfb-slot-no", &value))
1690 max98396->spkfb_slot = value & 0xF;
1692 max98396->spkfb_slot = 2;
1694 if (!device_property_read_u32(dev, "adi,bypass-slot-no", &value))
1695 max98396->bypass_slot = value & 0xF;
1697 max98396->bypass_slot = 0;
1699 max98396->dmon_stuck_enable =
1700 device_property_read_bool(dev, "adi,dmon-stuck-enable");
1702 if (!device_property_read_u32(dev, "adi,dmon-stuck-threshold-bits", &value))
1703 max98396->dmon_stuck_threshold = value;
1705 max98396->dmon_stuck_threshold = 15;
1707 max98396->dmon_mag_enable =
1708 device_property_read_bool(dev, "adi,dmon-magnitude-enable");
1710 if (!device_property_read_u32(dev, "adi,dmon-magnitude-threshold-bits", &value))
1711 max98396->dmon_mag_threshold = value;
1713 max98396->dmon_mag_threshold = 5;
1715 if (!device_property_read_u32(dev, "adi,dmon-duration-ms", &value))
1716 max98396->dmon_duration = value;
1718 max98396->dmon_duration = 64;
1721 static void max98396_core_supplies_disable(void *priv)
1723 struct max98396_priv *max98396 = priv;
1725 regulator_bulk_disable(MAX98396_NUM_CORE_SUPPLIES,
1726 max98396->core_supplies);
1729 static void max98396_supply_disable(void *r)
1731 regulator_disable((struct regulator *) r);
1734 static int max98396_i2c_probe(struct i2c_client *i2c,
1735 const struct i2c_device_id *id)
1737 struct max98396_priv *max98396 = NULL;
1740 max98396 = devm_kzalloc(&i2c->dev, sizeof(*max98396), GFP_KERNEL);
1746 i2c_set_clientdata(i2c, max98396);
1748 max98396->device_id = id->driver_data;
1750 /* regmap initialization */
1751 if (max98396->device_id == CODEC_TYPE_MAX98396)
1752 max98396->regmap = devm_regmap_init_i2c(i2c, &max98396_regmap);
1755 max98396->regmap = devm_regmap_init_i2c(i2c, &max98397_regmap);
1757 if (IS_ERR(max98396->regmap)) {
1758 ret = PTR_ERR(max98396->regmap);
1760 "Failed to allocate regmap: %d\n", ret);
1764 /* Obtain regulator supplies */
1765 for (i = 0; i < MAX98396_NUM_CORE_SUPPLIES; i++)
1766 max98396->core_supplies[i].supply = max98396_core_supplies[i];
1768 ret = devm_regulator_bulk_get(&i2c->dev, MAX98396_NUM_CORE_SUPPLIES,
1769 max98396->core_supplies);
1771 dev_err(&i2c->dev, "Failed to request core supplies: %d\n", ret);
1775 max98396->vbat = devm_regulator_get_optional(&i2c->dev, "vbat");
1776 if (IS_ERR(max98396->vbat)) {
1777 if (PTR_ERR(max98396->vbat) == -EPROBE_DEFER)
1778 return -EPROBE_DEFER;
1780 max98396->vbat = NULL;
1783 max98396->pvdd = devm_regulator_get_optional(&i2c->dev, "pvdd");
1784 if (IS_ERR(max98396->pvdd)) {
1785 if (PTR_ERR(max98396->pvdd) == -EPROBE_DEFER)
1786 return -EPROBE_DEFER;
1788 max98396->pvdd = NULL;
1791 ret = regulator_bulk_enable(MAX98396_NUM_CORE_SUPPLIES,
1792 max98396->core_supplies);
1794 dev_err(&i2c->dev, "Unable to enable core supplies: %d", ret);
1798 ret = devm_add_action_or_reset(&i2c->dev, max98396_core_supplies_disable,
1803 if (max98396->pvdd) {
1804 ret = regulator_enable(max98396->pvdd);
1808 ret = devm_add_action_or_reset(&i2c->dev,
1809 max98396_supply_disable,
1815 if (max98396->vbat) {
1816 ret = regulator_enable(max98396->vbat);
1820 ret = devm_add_action_or_reset(&i2c->dev,
1821 max98396_supply_disable,
1827 /* update interleave mode info */
1828 if (device_property_read_bool(&i2c->dev, "adi,interleave_mode"))
1829 max98396->interleave_mode = true;
1831 max98396->interleave_mode = false;
1833 /* voltage/current slot & gpio configuration */
1834 max98396_read_device_property(&i2c->dev, max98396);
1836 /* Reset the Device */
1837 max98396->reset_gpio = devm_gpiod_get_optional(&i2c->dev,
1838 "reset", GPIOD_OUT_HIGH);
1839 if (IS_ERR(max98396->reset_gpio)) {
1840 ret = PTR_ERR(max98396->reset_gpio);
1841 dev_err(&i2c->dev, "Unable to request GPIO pin: %d.\n", ret);
1845 if (max98396->reset_gpio) {
1846 usleep_range(5000, 6000);
1847 gpiod_set_value_cansleep(max98396->reset_gpio, 0);
1848 /* Wait for the hw reset done */
1849 usleep_range(5000, 6000);
1852 ret = regmap_read(max98396->regmap,
1853 GET_REG_ADDR_REV_ID(max98396->device_id), ®);
1855 dev_err(&i2c->dev, "%s: failed to read revision of the device.\n", id->name);
1858 dev_info(&i2c->dev, "%s revision ID: 0x%02X\n", id->name, reg);
1860 /* codec registration */
1861 if (max98396->device_id == CODEC_TYPE_MAX98396)
1862 ret = devm_snd_soc_register_component(&i2c->dev,
1863 &soc_codec_dev_max98396,
1865 ARRAY_SIZE(max98396_dai));
1867 ret = devm_snd_soc_register_component(&i2c->dev,
1868 &soc_codec_dev_max98397,
1870 ARRAY_SIZE(max98397_dai));
1872 dev_err(&i2c->dev, "Failed to register codec: %d\n", ret);
1877 static const struct i2c_device_id max98396_i2c_id[] = {
1878 { "max98396", CODEC_TYPE_MAX98396},
1879 { "max98397", CODEC_TYPE_MAX98397},
1883 MODULE_DEVICE_TABLE(i2c, max98396_i2c_id);
1885 #if defined(CONFIG_OF)
1886 static const struct of_device_id max98396_of_match[] = {
1887 { .compatible = "adi,max98396", },
1888 { .compatible = "adi,max98397", },
1891 MODULE_DEVICE_TABLE(of, max98396_of_match);
1895 static const struct acpi_device_id max98396_acpi_match[] = {
1900 MODULE_DEVICE_TABLE(acpi, max98396_acpi_match);
1903 static struct i2c_driver max98396_i2c_driver = {
1906 .of_match_table = of_match_ptr(max98396_of_match),
1907 .acpi_match_table = ACPI_PTR(max98396_acpi_match),
1910 .probe = max98396_i2c_probe,
1911 .id_table = max98396_i2c_id,
1914 module_i2c_driver(max98396_i2c_driver)
1916 MODULE_DESCRIPTION("ALSA SoC MAX98396 driver");
1917 MODULE_AUTHOR("Ryan Lee <ryans.lee@analog.com>");
1918 MODULE_LICENSE("GPL");