1// SPDX-License-Identifier: GPL-2.0
2// Copyright (c) 2022, Analog Devices Inc.
3
4#include <linux/gpio/consumer.h>
5#include <linux/i2c.h>
6#include <linux/module.h>
7#include <sound/pcm_params.h>
8#include <linux/regulator/consumer.h>
9#include <sound/soc.h>
10#include <sound/tlv.h>
11#include "max98396.h"
12
13static const char * const max98396_core_supplies[MAX98396_NUM_CORE_SUPPLIES] = {
14 "avdd",
15 "dvdd",
16 "dvddio",
17};
18
19static struct reg_default max98396_reg[] = {
20 {MAX98396_R2000_SW_RESET, 0x00},
21 {MAX98396_R2001_INT_RAW1, 0x00},
22 {MAX98396_R2002_INT_RAW2, 0x00},
23 {MAX98396_R2003_INT_RAW3, 0x00},
24 {MAX98396_R2004_INT_RAW4, 0x00},
25 {MAX98396_R2006_INT_STATE1, 0x00},
26 {MAX98396_R2007_INT_STATE2, 0x00},
27 {MAX98396_R2008_INT_STATE3, 0x00},
28 {MAX98396_R2009_INT_STATE4, 0x00},
29 {MAX98396_R200B_INT_FLAG1, 0x00},
30 {MAX98396_R200C_INT_FLAG2, 0x00},
31 {MAX98396_R200D_INT_FLAG3, 0x00},
32 {MAX98396_R200E_INT_FLAG4, 0x00},
33 {MAX98396_R2010_INT_EN1, 0x02},
34 {MAX98396_R2011_INT_EN2, 0x00},
35 {MAX98396_R2012_INT_EN3, 0x00},
36 {MAX98396_R2013_INT_EN4, 0x00},
37 {MAX98396_R2015_INT_FLAG_CLR1, 0x00},
38 {MAX98396_R2016_INT_FLAG_CLR2, 0x00},
39 {MAX98396_R2017_INT_FLAG_CLR3, 0x00},
40 {MAX98396_R2018_INT_FLAG_CLR4, 0x00},
41 {MAX98396_R201F_IRQ_CTRL, 0x00},
42 {MAX98396_R2020_THERM_WARN_THRESH, 0x46},
43 {MAX98396_R2021_THERM_WARN_THRESH2, 0x46},
44 {MAX98396_R2022_THERM_SHDN_THRESH, 0x64},
45 {MAX98396_R2023_THERM_HYSTERESIS, 0x02},
46 {MAX98396_R2024_THERM_FOLDBACK_SET, 0xC5},
47 {MAX98396_R2027_THERM_FOLDBACK_EN, 0x01},
48 {MAX98396_R2030_NOISEGATE_MODE_CTRL, 0x32},
49 {MAX98396_R2033_NOISEGATE_MODE_EN, 0x00},
50 {MAX98396_R2038_CLK_MON_CTRL, 0x00},
51 {MAX98396_R2039_DATA_MON_CTRL, 0x00},
52 {MAX98396_R203F_ENABLE_CTRLS, 0x0F},
53 {MAX98396_R2040_PIN_CFG, 0x55},
54 {MAX98396_R2041_PCM_MODE_CFG, 0xC0},
55 {MAX98396_R2042_PCM_CLK_SETUP, 0x04},
56 {MAX98396_R2043_PCM_SR_SETUP, 0x88},
57 {MAX98396_R2044_PCM_TX_CTRL_1, 0x00},
58 {MAX98396_R2045_PCM_TX_CTRL_2, 0x00},
59 {MAX98396_R2046_PCM_TX_CTRL_3, 0x00},
60 {MAX98396_R2047_PCM_TX_CTRL_4, 0x00},
61 {MAX98396_R2048_PCM_TX_CTRL_5, 0x00},
62 {MAX98396_R2049_PCM_TX_CTRL_6, 0x00},
63 {MAX98396_R204A_PCM_TX_CTRL_7, 0x00},
64 {MAX98396_R204B_PCM_TX_CTRL_8, 0x00},
65 {MAX98396_R204C_PCM_TX_HIZ_CTRL_1, 0xFF},
66 {MAX98396_R204D_PCM_TX_HIZ_CTRL_2, 0xFF},
67 {MAX98396_R204E_PCM_TX_HIZ_CTRL_3, 0xFF},
68 {MAX98396_R204F_PCM_TX_HIZ_CTRL_4, 0xFF},
69 {MAX98396_R2050_PCM_TX_HIZ_CTRL_5, 0xFF},
70 {MAX98396_R2051_PCM_TX_HIZ_CTRL_6, 0xFF},
71 {MAX98396_R2052_PCM_TX_HIZ_CTRL_7, 0xFF},
72 {MAX98396_R2053_PCM_TX_HIZ_CTRL_8, 0xFF},
73 {MAX98396_R2055_PCM_RX_SRC1, 0x00},
74 {MAX98396_R2056_PCM_RX_SRC2, 0x00},
75 {MAX98396_R2058_PCM_BYPASS_SRC, 0x00},
76 {MAX98396_R205D_PCM_TX_SRC_EN, 0x00},
77 {MAX98396_R205E_PCM_RX_EN, 0x00},
78 {MAX98396_R205F_PCM_TX_EN, 0x00},
79 {MAX98396_R2070_ICC_RX_EN_A, 0x00},
80 {MAX98396_R2071_ICC_RX_EN_B, 0x00},
81 {MAX98396_R2072_ICC_TX_CTRL, 0x00},
82 {MAX98396_R207F_ICC_EN, 0x00},
83 {MAX98396_R2083_TONE_GEN_DC_CFG, 0x04},
84 {MAX98396_R2084_TONE_GEN_DC_LVL1, 0x00},
85 {MAX98396_R2085_TONE_GEN_DC_LVL2, 0x00},
86 {MAX98396_R2086_TONE_GEN_DC_LVL3, 0x00},
87 {MAX98396_R208F_TONE_GEN_EN, 0x00},
88 {MAX98396_R2090_AMP_VOL_CTRL, 0x00},
89 {MAX98396_R2091_AMP_PATH_GAIN, 0x0B},
90 {MAX98396_R2092_AMP_DSP_CFG, 0x23},
91 {MAX98396_R2093_SSM_CFG, 0x0D},
92 {MAX98396_R2094_SPK_CLS_DG_THRESH, 0x12},
93 {MAX98396_R2095_SPK_CLS_DG_HDR, 0x17},
94 {MAX98396_R2096_SPK_CLS_DG_HOLD_TIME, 0x17},
95 {MAX98396_R2097_SPK_CLS_DG_DELAY, 0x00},
96 {MAX98396_R2098_SPK_CLS_DG_MODE, 0x00},
97 {MAX98396_R2099_SPK_CLS_DG_VBAT_LVL, 0x03},
98 {MAX98396_R209A_SPK_EDGE_CTRL, 0x00},
99 {MAX98396_R209C_SPK_EDGE_CTRL1, 0x0A},
100 {MAX98396_R209D_SPK_EDGE_CTRL2, 0xAA},
101 {MAX98396_R209E_AMP_CLIP_GAIN, 0x00},
102 {MAX98396_R209F_BYPASS_PATH_CFG, 0x00},
103 {MAX98396_R20A0_AMP_SUPPLY_CTL, 0x00},
104 {MAX98396_R20AF_AMP_EN, 0x00},
105 {MAX98396_R20B0_ADC_SR, 0x30},
106 {MAX98396_R20B1_ADC_PVDD_CFG, 0x00},
107 {MAX98396_R20B2_ADC_VBAT_CFG, 0x00},
108 {MAX98396_R20B3_ADC_THERMAL_CFG, 0x00},
109 {MAX98396_R20B4_ADC_READBACK_CTRL1, 0x00},
110 {MAX98396_R20B5_ADC_READBACK_CTRL2, 0x00},
111 {MAX98396_R20B6_ADC_PVDD_READBACK_MSB, 0x00},
112 {MAX98396_R20B7_ADC_PVDD_READBACK_LSB, 0x00},
113 {MAX98396_R20B8_ADC_VBAT_READBACK_MSB, 0x00},
114 {MAX98396_R20B9_ADC_VBAT_READBACK_LSB, 0x00},
115 {MAX98396_R20BA_ADC_TEMP_READBACK_MSB, 0x00},
116 {MAX98396_R20BB_ADC_TEMP_READBACK_LSB, 0x00},
117 {MAX98396_R20BC_ADC_LO_PVDD_READBACK_MSB, 0x00},
118 {MAX98396_R20BD_ADC_LO_PVDD_READBACK_LSB, 0x00},
119 {MAX98396_R20BE_ADC_LO_VBAT_READBACK_MSB, 0x00},
120 {MAX98396_R20BF_ADC_LO_VBAT_READBACK_LSB, 0x00},
121 {MAX98396_R20C7_ADC_CFG, 0x00},
122 {MAX98396_R20D0_DHT_CFG1, 0x00},
123 {MAX98396_R20D1_LIMITER_CFG1, 0x08},
124 {MAX98396_R20D2_LIMITER_CFG2, 0x00},
125 {MAX98396_R20D3_DHT_CFG2, 0x14},
126 {MAX98396_R20D4_DHT_CFG3, 0x02},
127 {MAX98396_R20D5_DHT_CFG4, 0x04},
128 {MAX98396_R20D6_DHT_HYSTERESIS_CFG, 0x07},
129 {MAX98396_R20DF_DHT_EN, 0x00},
130 {MAX98396_R20E0_IV_SENSE_PATH_CFG, 0x04},
131 {MAX98396_R20E4_IV_SENSE_PATH_EN, 0x00},
132 {MAX98396_R20E5_BPE_STATE, 0x00},
133 {MAX98396_R20E6_BPE_L3_THRESH_MSB, 0x00},
134 {MAX98396_R20E7_BPE_L3_THRESH_LSB, 0x00},
135 {MAX98396_R20E8_BPE_L2_THRESH_MSB, 0x00},
136 {MAX98396_R20E9_BPE_L2_THRESH_LSB, 0x00},
137 {MAX98396_R20EA_BPE_L1_THRESH_MSB, 0x00},
138 {MAX98396_R20EB_BPE_L1_THRESH_LSB, 0x00},
139 {MAX98396_R20EC_BPE_L0_THRESH_MSB, 0x00},
140 {MAX98396_R20ED_BPE_L0_THRESH_LSB, 0x00},
141 {MAX98396_R20EE_BPE_L3_DWELL_HOLD_TIME, 0x00},
142 {MAX98396_R20EF_BPE_L2_DWELL_HOLD_TIME, 0x00},
143 {MAX98396_R20F0_BPE_L1_DWELL_HOLD_TIME, 0x00},
144 {MAX98396_R20F1_BPE_L0_HOLD_TIME, 0x00},
145 {MAX98396_R20F2_BPE_L3_ATTACK_REL_STEP, 0x00},
146 {MAX98396_R20F3_BPE_L2_ATTACK_REL_STEP, 0x00},
147 {MAX98396_R20F4_BPE_L1_ATTACK_REL_STEP, 0x00},
148 {MAX98396_R20F5_BPE_L0_ATTACK_REL_STEP, 0x00},
149 {MAX98396_R20F6_BPE_L3_MAX_GAIN_ATTN, 0x00},
150 {MAX98396_R20F7_BPE_L2_MAX_GAIN_ATTN, 0x00},
151 {MAX98396_R20F8_BPE_L1_MAX_GAIN_ATTN, 0x00},
152 {MAX98396_R20F9_BPE_L0_MAX_GAIN_ATTN, 0x00},
153 {MAX98396_R20FA_BPE_L3_ATT_REL_RATE, 0x00},
154 {MAX98396_R20FB_BPE_L2_ATT_REL_RATE, 0x00},
155 {MAX98396_R20FC_BPE_L1_ATT_REL_RATE, 0x00},
156 {MAX98396_R20FD_BPE_L0_ATT_REL_RATE, 0x00},
157 {MAX98396_R20FE_BPE_L3_LIMITER_CFG, 0x00},
158 {MAX98396_R20FF_BPE_L2_LIMITER_CFG, 0x00},
159 {MAX98396_R2100_BPE_L1_LIMITER_CFG, 0x00},
160 {MAX98396_R2101_BPE_L0_LIMITER_CFG, 0x00},
161 {MAX98396_R2102_BPE_L3_LIM_ATT_REL_RATE, 0x00},
162 {MAX98396_R2103_BPE_L2_LIM_ATT_REL_RATE, 0x00},
163 {MAX98396_R2104_BPE_L1_LIM_ATT_REL_RATE, 0x00},
164 {MAX98396_R2105_BPE_L0_LIM_ATT_REL_RATE, 0x00},
165 {MAX98396_R2106_BPE_THRESH_HYSTERESIS, 0x00},
166 {MAX98396_R2107_BPE_INFINITE_HOLD_CLR, 0x00},
167 {MAX98396_R2108_BPE_SUPPLY_SRC, 0x00},
168 {MAX98396_R2109_BPE_LOW_STATE, 0x00},
169 {MAX98396_R210A_BPE_LOW_GAIN, 0x00},
170 {MAX98396_R210B_BPE_LOW_LIMITER, 0x00},
171 {MAX98396_R210D_BPE_EN, 0x00},
172 {MAX98396_R210E_AUTO_RESTART, 0x00},
173 {MAX98396_R210F_GLOBAL_EN, 0x00},
174 {MAX98396_R21FF_REVISION_ID, 0x00},
175};
176
177static struct reg_default max98397_reg[] = {
178 {MAX98396_R2000_SW_RESET, 0x00},
179 {MAX98396_R2001_INT_RAW1, 0x00},
180 {MAX98396_R2002_INT_RAW2, 0x00},
181 {MAX98396_R2003_INT_RAW3, 0x00},
182 {MAX98396_R2004_INT_RAW4, 0x00},
183 {MAX98396_R2006_INT_STATE1, 0x00},
184 {MAX98396_R2007_INT_STATE2, 0x00},
185 {MAX98396_R2008_INT_STATE3, 0x00},
186 {MAX98396_R2009_INT_STATE4, 0x00},
187 {MAX98396_R200B_INT_FLAG1, 0x00},
188 {MAX98396_R200C_INT_FLAG2, 0x00},
189 {MAX98396_R200D_INT_FLAG3, 0x00},
190 {MAX98396_R200E_INT_FLAG4, 0x00},
191 {MAX98396_R2010_INT_EN1, 0x02},
192 {MAX98396_R2011_INT_EN2, 0x00},
193 {MAX98396_R2012_INT_EN3, 0x00},
194 {MAX98396_R2013_INT_EN4, 0x00},
195 {MAX98396_R2015_INT_FLAG_CLR1, 0x00},
196 {MAX98396_R2016_INT_FLAG_CLR2, 0x00},
197 {MAX98396_R2017_INT_FLAG_CLR3, 0x00},
198 {MAX98396_R2018_INT_FLAG_CLR4, 0x00},
199 {MAX98396_R201F_IRQ_CTRL, 0x00},
200 {MAX98396_R2020_THERM_WARN_THRESH, 0x46},
201 {MAX98396_R2021_THERM_WARN_THRESH2, 0x46},
202 {MAX98396_R2022_THERM_SHDN_THRESH, 0x64},
203 {MAX98396_R2023_THERM_HYSTERESIS, 0x02},
204 {MAX98396_R2024_THERM_FOLDBACK_SET, 0xC5},
205 {MAX98396_R2027_THERM_FOLDBACK_EN, 0x01},
206 {MAX98396_R2030_NOISEGATE_MODE_CTRL, 0x32},
207 {MAX98396_R2033_NOISEGATE_MODE_EN, 0x00},
208 {MAX98396_R2038_CLK_MON_CTRL, 0x00},
209 {MAX98396_R2039_DATA_MON_CTRL, 0x00},
210 {MAX98397_R203A_SPK_MON_THRESH, 0x03},
211 {MAX98396_R203F_ENABLE_CTRLS, 0x0F},
212 {MAX98396_R2040_PIN_CFG, 0x55},
213 {MAX98396_R2041_PCM_MODE_CFG, 0xC0},
214 {MAX98396_R2042_PCM_CLK_SETUP, 0x04},
215 {MAX98396_R2043_PCM_SR_SETUP, 0x88},
216 {MAX98396_R2044_PCM_TX_CTRL_1, 0x00},
217 {MAX98396_R2045_PCM_TX_CTRL_2, 0x00},
218 {MAX98396_R2046_PCM_TX_CTRL_3, 0x00},
219 {MAX98396_R2047_PCM_TX_CTRL_4, 0x00},
220 {MAX98396_R2048_PCM_TX_CTRL_5, 0x00},
221 {MAX98396_R2049_PCM_TX_CTRL_6, 0x00},
222 {MAX98396_R204A_PCM_TX_CTRL_7, 0x00},
223 {MAX98396_R204B_PCM_TX_CTRL_8, 0x00},
224 {MAX98397_R204C_PCM_TX_CTRL_9, 0x00},
225 {MAX98397_R204D_PCM_TX_HIZ_CTRL_1, 0xFF},
226 {MAX98397_R204E_PCM_TX_HIZ_CTRL_2, 0xFF},
227 {MAX98397_R204F_PCM_TX_HIZ_CTRL_3, 0xFF},
228 {MAX98397_R2050_PCM_TX_HIZ_CTRL_4, 0xFF},
229 {MAX98397_R2051_PCM_TX_HIZ_CTRL_5, 0xFF},
230 {MAX98397_R2052_PCM_TX_HIZ_CTRL_6, 0xFF},
231 {MAX98397_R2053_PCM_TX_HIZ_CTRL_7, 0xFF},
232 {MAX98397_R2054_PCM_TX_HIZ_CTRL_8, 0xFF},
233 {MAX98397_R2056_PCM_RX_SRC1, 0x00},
234 {MAX98397_R2057_PCM_RX_SRC2, 0x00},
235 {MAX98396_R2058_PCM_BYPASS_SRC, 0x00},
236 {MAX98396_R205D_PCM_TX_SRC_EN, 0x00},
237 {MAX98396_R205E_PCM_RX_EN, 0x00},
238 {MAX98396_R205F_PCM_TX_EN, 0x00},
239 {MAX98397_R2060_PCM_TX_SUPPLY_SEL, 0x00},
240 {MAX98396_R2070_ICC_RX_EN_A, 0x00},
241 {MAX98396_R2071_ICC_RX_EN_B, 0x00},
242 {MAX98396_R2072_ICC_TX_CTRL, 0x00},
243 {MAX98396_R207F_ICC_EN, 0x00},
244 {MAX98396_R2083_TONE_GEN_DC_CFG, 0x04},
245 {MAX98396_R2084_TONE_GEN_DC_LVL1, 0x00},
246 {MAX98396_R2085_TONE_GEN_DC_LVL2, 0x00},
247 {MAX98396_R2086_TONE_GEN_DC_LVL3, 0x00},
248 {MAX98396_R208F_TONE_GEN_EN, 0x00},
249 {MAX98396_R2090_AMP_VOL_CTRL, 0x00},
250 {MAX98396_R2091_AMP_PATH_GAIN, 0x12},
251 {MAX98396_R2092_AMP_DSP_CFG, 0x22},
252 {MAX98396_R2093_SSM_CFG, 0x08},
253 {MAX98396_R2094_SPK_CLS_DG_THRESH, 0x12},
254 {MAX98396_R2095_SPK_CLS_DG_HDR, 0x17},
255 {MAX98396_R2096_SPK_CLS_DG_HOLD_TIME, 0x17},
256 {MAX98396_R2097_SPK_CLS_DG_DELAY, 0x00},
257 {MAX98396_R2098_SPK_CLS_DG_MODE, 0x00},
258 {MAX98396_R2099_SPK_CLS_DG_VBAT_LVL, 0x03},
259 {MAX98396_R209A_SPK_EDGE_CTRL, 0x00},
260 {MAX98397_R209B_SPK_PATH_WB_ONLY, 0x00},
261 {MAX98396_R209C_SPK_EDGE_CTRL1, 0x03},
262 {MAX98396_R209D_SPK_EDGE_CTRL2, 0xFC},
263 {MAX98396_R209E_AMP_CLIP_GAIN, 0x00},
264 {MAX98396_R209F_BYPASS_PATH_CFG, 0x00},
265 {MAX98396_R20AF_AMP_EN, 0x00},
266 {MAX98396_R20B0_ADC_SR, 0x30},
267 {MAX98396_R20B1_ADC_PVDD_CFG, 0x00},
268 {MAX98396_R20B2_ADC_VBAT_CFG, 0x00},
269 {MAX98396_R20B3_ADC_THERMAL_CFG, 0x00},
270 {MAX98397_R20B4_ADC_VDDH_CFG, 0x00},
271 {MAX98397_R20B5_ADC_READBACK_CTRL1, 0x00},
272 {MAX98397_R20B6_ADC_READBACK_CTRL2, 0x00},
273 {MAX98397_R20B7_ADC_PVDD_READBACK_MSB, 0x00},
274 {MAX98397_R20B8_ADC_PVDD_READBACK_LSB, 0x00},
275 {MAX98397_R20B9_ADC_VBAT_READBACK_MSB, 0x00},
276 {MAX98397_R20BA_ADC_VBAT_READBACK_LSB, 0x00},
277 {MAX98397_R20BB_ADC_TEMP_READBACK_MSB, 0x00},
278 {MAX98397_R20BC_ADC_TEMP_READBACK_LSB, 0x00},
279 {MAX98397_R20BD_ADC_VDDH__READBACK_MSB, 0x00},
280 {MAX98397_R20BE_ADC_VDDH_READBACK_LSB, 0x00},
281 {MAX98396_R20BF_ADC_LO_VBAT_READBACK_LSB, 0x00},
282 {MAX98397_R20C3_ADC_LO_VDDH_READBACK_MSB, 0x00},
283 {MAX98397_R20C4_ADC_LO_VDDH_READBACK_LSB, 0x00},
284 {MAX98397_R20C5_MEAS_ADC_OPTIMAL_MODE, 0x04},
285 {MAX98396_R20C7_ADC_CFG, 0x00},
286 {MAX98396_R20D0_DHT_CFG1, 0x00},
287 {MAX98396_R20D1_LIMITER_CFG1, 0x08},
288 {MAX98396_R20D2_LIMITER_CFG2, 0x00},
289 {MAX98396_R20D3_DHT_CFG2, 0x14},
290 {MAX98396_R20D4_DHT_CFG3, 0x02},
291 {MAX98396_R20D5_DHT_CFG4, 0x04},
292 {MAX98396_R20D6_DHT_HYSTERESIS_CFG, 0x07},
293 {MAX98396_R20DF_DHT_EN, 0x00},
294 {MAX98396_R20E0_IV_SENSE_PATH_CFG, 0x04},
295 {MAX98396_R20E4_IV_SENSE_PATH_EN, 0x00},
296 {MAX98396_R20E5_BPE_STATE, 0x00},
297 {MAX98396_R20E6_BPE_L3_THRESH_MSB, 0x00},
298 {MAX98396_R20E7_BPE_L3_THRESH_LSB, 0x00},
299 {MAX98396_R20E8_BPE_L2_THRESH_MSB, 0x00},
300 {MAX98396_R20E9_BPE_L2_THRESH_LSB, 0x00},
301 {MAX98396_R20EA_BPE_L1_THRESH_MSB, 0x00},
302 {MAX98396_R20EB_BPE_L1_THRESH_LSB, 0x00},
303 {MAX98396_R20EC_BPE_L0_THRESH_MSB, 0x00},
304 {MAX98396_R20ED_BPE_L0_THRESH_LSB, 0x00},
305 {MAX98396_R20EE_BPE_L3_DWELL_HOLD_TIME, 0x00},
306 {MAX98396_R20EF_BPE_L2_DWELL_HOLD_TIME, 0x00},
307 {MAX98396_R20F0_BPE_L1_DWELL_HOLD_TIME, 0x00},
308 {MAX98396_R20F1_BPE_L0_HOLD_TIME, 0x00},
309 {MAX98396_R20F2_BPE_L3_ATTACK_REL_STEP, 0x00},
310 {MAX98396_R20F3_BPE_L2_ATTACK_REL_STEP, 0x00},
311 {MAX98396_R20F4_BPE_L1_ATTACK_REL_STEP, 0x00},
312 {MAX98396_R20F5_BPE_L0_ATTACK_REL_STEP, 0x00},
313 {MAX98396_R20F6_BPE_L3_MAX_GAIN_ATTN, 0x00},
314 {MAX98396_R20F7_BPE_L2_MAX_GAIN_ATTN, 0x00},
315 {MAX98396_R20F8_BPE_L1_MAX_GAIN_ATTN, 0x00},
316 {MAX98396_R20F9_BPE_L0_MAX_GAIN_ATTN, 0x00},
317 {MAX98396_R20FA_BPE_L3_ATT_REL_RATE, 0x00},
318 {MAX98396_R20FB_BPE_L2_ATT_REL_RATE, 0x00},
319 {MAX98396_R20FC_BPE_L1_ATT_REL_RATE, 0x00},
320 {MAX98396_R20FD_BPE_L0_ATT_REL_RATE, 0x00},
321 {MAX98396_R20FE_BPE_L3_LIMITER_CFG, 0x00},
322 {MAX98396_R20FF_BPE_L2_LIMITER_CFG, 0x00},
323 {MAX98396_R2100_BPE_L1_LIMITER_CFG, 0x00},
324 {MAX98396_R2101_BPE_L0_LIMITER_CFG, 0x00},
325 {MAX98396_R2102_BPE_L3_LIM_ATT_REL_RATE, 0x00},
326 {MAX98396_R2103_BPE_L2_LIM_ATT_REL_RATE, 0x00},
327 {MAX98396_R2104_BPE_L1_LIM_ATT_REL_RATE, 0x00},
328 {MAX98396_R2105_BPE_L0_LIM_ATT_REL_RATE, 0x00},
329 {MAX98396_R2106_BPE_THRESH_HYSTERESIS, 0x00},
330 {MAX98396_R2107_BPE_INFINITE_HOLD_CLR, 0x00},
331 {MAX98396_R2108_BPE_SUPPLY_SRC, 0x00},
332 {MAX98396_R2109_BPE_LOW_STATE, 0x00},
333 {MAX98396_R210A_BPE_LOW_GAIN, 0x00},
334 {MAX98396_R210B_BPE_LOW_LIMITER, 0x00},
335 {MAX98396_R210D_BPE_EN, 0x00},
336 {MAX98396_R210E_AUTO_RESTART, 0x00},
337 {MAX98396_R210F_GLOBAL_EN, 0x00},
338 {MAX98397_R22FF_REVISION_ID, 0x00},
339};
340
341static void max98396_global_enable_onoff(struct regmap *regmap, bool onoff)
342{
343 regmap_write(map: regmap, MAX98396_R210F_GLOBAL_EN, val: onoff ? 1 : 0);
344 usleep_range(min: 11000, max: 12000);
345}
346
347static int max98396_dai_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
348{
349 struct snd_soc_component *component = codec_dai->component;
350 struct max98396_priv *max98396 = snd_soc_component_get_drvdata(c: component);
351 unsigned int format_mask, format = 0;
352 unsigned int bclk_pol = 0;
353 int ret, status;
354 int reg;
355 bool update = false;
356
357 format_mask = MAX98396_PCM_MODE_CFG_FORMAT_MASK |
358 MAX98396_PCM_MODE_CFG_LRCLKEDGE;
359
360 dev_dbg(component->dev, "%s: fmt 0x%08X\n", __func__, fmt);
361
362 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
363 case SND_SOC_DAIFMT_NB_NF:
364 break;
365 case SND_SOC_DAIFMT_NB_IF:
366 format = MAX98396_PCM_MODE_CFG_LRCLKEDGE;
367 break;
368 case SND_SOC_DAIFMT_IB_NF:
369 bclk_pol = MAX98396_PCM_MODE_CFG_BCLKEDGE;
370 break;
371 case SND_SOC_DAIFMT_IB_IF:
372 bclk_pol = MAX98396_PCM_MODE_CFG_BCLKEDGE;
373 format = MAX98396_PCM_MODE_CFG_LRCLKEDGE;
374 break;
375
376 default:
377 dev_err(component->dev, "DAI invert mode %d unsupported\n",
378 fmt & SND_SOC_DAIFMT_INV_MASK);
379 return -EINVAL;
380 }
381
382 /* interface format */
383 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
384 case SND_SOC_DAIFMT_I2S:
385 format |= MAX98396_PCM_FORMAT_I2S;
386 break;
387 case SND_SOC_DAIFMT_LEFT_J:
388 format |= MAX98396_PCM_FORMAT_LJ;
389 break;
390 case SND_SOC_DAIFMT_DSP_A:
391 format |= MAX98396_PCM_FORMAT_TDM_MODE1;
392 break;
393 case SND_SOC_DAIFMT_DSP_B:
394 format |= MAX98396_PCM_FORMAT_TDM_MODE0;
395 break;
396 default:
397 dev_err(component->dev, "DAI format %d unsupported\n",
398 fmt & SND_SOC_DAIFMT_FORMAT_MASK);
399 return -EINVAL;
400 }
401
402 ret = regmap_read(map: max98396->regmap, MAX98396_R210F_GLOBAL_EN, val: &status);
403 if (ret < 0)
404 return -EINVAL;
405
406 if (status) {
407 ret = regmap_read(map: max98396->regmap, MAX98396_R2041_PCM_MODE_CFG, val: &reg);
408 if (ret < 0)
409 return -EINVAL;
410 if (format != (reg & format_mask)) {
411 update = true;
412 } else {
413 ret = regmap_read(map: max98396->regmap,
414 MAX98396_R2042_PCM_CLK_SETUP, val: &reg);
415 if (ret < 0)
416 return -EINVAL;
417 if (bclk_pol != (reg & MAX98396_PCM_MODE_CFG_BCLKEDGE))
418 update = true;
419 }
420 /* GLOBAL_EN OFF prior to pcm mode, clock configuration change */
421 if (update)
422 max98396_global_enable_onoff(regmap: max98396->regmap, onoff: false);
423 }
424
425 regmap_update_bits(map: max98396->regmap,
426 MAX98396_R2041_PCM_MODE_CFG,
427 mask: format_mask, val: format);
428
429 regmap_update_bits(map: max98396->regmap,
430 MAX98396_R2042_PCM_CLK_SETUP,
431 MAX98396_PCM_MODE_CFG_BCLKEDGE,
432 val: bclk_pol);
433
434 if (status && update)
435 max98396_global_enable_onoff(regmap: max98396->regmap, onoff: true);
436
437 return 0;
438}
439
440#define MAX98396_BSEL_32 0x2
441#define MAX98396_BSEL_48 0x3
442#define MAX98396_BSEL_64 0x4
443#define MAX98396_BSEL_96 0x5
444#define MAX98396_BSEL_128 0x6
445#define MAX98396_BSEL_192 0x7
446#define MAX98396_BSEL_256 0x8
447#define MAX98396_BSEL_384 0x9
448#define MAX98396_BSEL_512 0xa
449#define MAX98396_BSEL_320 0xb
450#define MAX98396_BSEL_250 0xc
451#define MAX98396_BSEL_125 0xd
452
453/* Refer to table 5 in the datasheet */
454static const struct max98396_pcm_config {
455 int in, out, width, bsel, max_sr;
456} max98396_pcm_configs[] = {
457 { .in = 2, .out = 4, .width = 16, .bsel = MAX98396_BSEL_32, .max_sr = 192000 },
458 { .in = 2, .out = 6, .width = 24, .bsel = MAX98396_BSEL_48, .max_sr = 192000 },
459 { .in = 2, .out = 8, .width = 32, .bsel = MAX98396_BSEL_64, .max_sr = 192000 },
460 { .in = 3, .out = 15, .width = 32, .bsel = MAX98396_BSEL_125, .max_sr = 192000 },
461 { .in = 4, .out = 8, .width = 16, .bsel = MAX98396_BSEL_64, .max_sr = 192000 },
462 { .in = 4, .out = 12, .width = 24, .bsel = MAX98396_BSEL_96, .max_sr = 192000 },
463 { .in = 4, .out = 16, .width = 32, .bsel = MAX98396_BSEL_128, .max_sr = 192000 },
464 { .in = 5, .out = 15, .width = 24, .bsel = MAX98396_BSEL_125, .max_sr = 192000 },
465 { .in = 7, .out = 15, .width = 16, .bsel = MAX98396_BSEL_125, .max_sr = 192000 },
466 { .in = 2, .out = 4, .width = 16, .bsel = MAX98396_BSEL_32, .max_sr = 96000 },
467 { .in = 2, .out = 6, .width = 24, .bsel = MAX98396_BSEL_48, .max_sr = 96000 },
468 { .in = 2, .out = 8, .width = 32, .bsel = MAX98396_BSEL_64, .max_sr = 96000 },
469 { .in = 3, .out = 15, .width = 32, .bsel = MAX98396_BSEL_125, .max_sr = 96000 },
470 { .in = 4, .out = 8, .width = 16, .bsel = MAX98396_BSEL_64, .max_sr = 96000 },
471 { .in = 4, .out = 12, .width = 24, .bsel = MAX98396_BSEL_96, .max_sr = 96000 },
472 { .in = 4, .out = 16, .width = 32, .bsel = MAX98396_BSEL_128, .max_sr = 96000 },
473 { .in = 5, .out = 15, .width = 24, .bsel = MAX98396_BSEL_125, .max_sr = 96000 },
474 { .in = 7, .out = 15, .width = 16, .bsel = MAX98396_BSEL_125, .max_sr = 96000 },
475 { .in = 7, .out = 31, .width = 32, .bsel = MAX98396_BSEL_250, .max_sr = 96000 },
476 { .in = 8, .out = 16, .width = 16, .bsel = MAX98396_BSEL_128, .max_sr = 96000 },
477 { .in = 8, .out = 24, .width = 24, .bsel = MAX98396_BSEL_192, .max_sr = 96000 },
478 { .in = 8, .out = 32, .width = 32, .bsel = MAX98396_BSEL_256, .max_sr = 96000 },
479 { .in = 10, .out = 31, .width = 24, .bsel = MAX98396_BSEL_250, .max_sr = 96000 },
480 { .in = 15, .out = 31, .width = 16, .bsel = MAX98396_BSEL_250, .max_sr = 96000 },
481 { .in = 16, .out = 32, .width = 16, .bsel = MAX98396_BSEL_256, .max_sr = 96000 },
482 { .in = 7, .out = 31, .width = 32, .bsel = MAX98396_BSEL_250, .max_sr = 48000 },
483 { .in = 10, .out = 31, .width = 24, .bsel = MAX98396_BSEL_250, .max_sr = 48000 },
484 { .in = 10, .out = 40, .width = 32, .bsel = MAX98396_BSEL_320, .max_sr = 48000 },
485 { .in = 15, .out = 31, .width = 16, .bsel = MAX98396_BSEL_250, .max_sr = 48000 },
486 { .in = 16, .out = 48, .width = 24, .bsel = MAX98396_BSEL_384, .max_sr = 48000 },
487 { .in = 16, .out = 64, .width = 32, .bsel = MAX98396_BSEL_512, .max_sr = 48000 },
488};
489
490static int max98396_pcm_config_index(int in_slots, int out_slots, int width)
491{
492 int i;
493
494 for (i = 0; i < ARRAY_SIZE(max98396_pcm_configs); i++) {
495 const struct max98396_pcm_config *c = &max98396_pcm_configs[i];
496
497 if (in_slots == c->in && out_slots <= c->out && width == c->width)
498 return i;
499 }
500
501 return -1;
502}
503
504static int max98396_dai_hw_params(struct snd_pcm_substream *substream,
505 struct snd_pcm_hw_params *params,
506 struct snd_soc_dai *dai)
507{
508 struct snd_soc_component *component = dai->component;
509 struct max98396_priv *max98396 = snd_soc_component_get_drvdata(c: component);
510 unsigned int sampling_rate = 0;
511 unsigned int chan_sz = 0;
512 int ret, reg, status, bsel = 0;
513 bool update = false;
514
515 /* pcm mode configuration */
516 switch (snd_pcm_format_width(format: params_format(p: params))) {
517 case 16:
518 chan_sz = MAX98396_PCM_MODE_CFG_CHANSZ_16;
519 break;
520 case 24:
521 chan_sz = MAX98396_PCM_MODE_CFG_CHANSZ_24;
522 break;
523 case 32:
524 chan_sz = MAX98396_PCM_MODE_CFG_CHANSZ_32;
525 break;
526 default:
527 dev_err(component->dev, "format unsupported %d\n",
528 params_format(params));
529 goto err;
530 }
531
532 dev_dbg(component->dev, "format supported %d",
533 params_format(params));
534
535 /* sampling rate configuration */
536 switch (params_rate(p: params)) {
537 case 8000:
538 sampling_rate = MAX98396_PCM_SR_8000;
539 break;
540 case 11025:
541 sampling_rate = MAX98396_PCM_SR_11025;
542 break;
543 case 12000:
544 sampling_rate = MAX98396_PCM_SR_12000;
545 break;
546 case 16000:
547 sampling_rate = MAX98396_PCM_SR_16000;
548 break;
549 case 22050:
550 sampling_rate = MAX98396_PCM_SR_22050;
551 break;
552 case 24000:
553 sampling_rate = MAX98396_PCM_SR_24000;
554 break;
555 case 32000:
556 sampling_rate = MAX98396_PCM_SR_32000;
557 break;
558 case 44100:
559 sampling_rate = MAX98396_PCM_SR_44100;
560 break;
561 case 48000:
562 sampling_rate = MAX98396_PCM_SR_48000;
563 break;
564 case 88200:
565 sampling_rate = MAX98396_PCM_SR_88200;
566 break;
567 case 96000:
568 sampling_rate = MAX98396_PCM_SR_96000;
569 break;
570 case 192000:
571 sampling_rate = MAX98396_PCM_SR_192000;
572 break;
573 default:
574 dev_err(component->dev, "rate %d not supported\n",
575 params_rate(params));
576 goto err;
577 }
578
579 if (max98396->tdm_mode) {
580 if (params_rate(p: params) > max98396->tdm_max_samplerate) {
581 dev_err(component->dev, "TDM sample rate %d too high",
582 params_rate(params));
583 goto err;
584 }
585 } else {
586 /* BCLK configuration */
587 ret = max98396_pcm_config_index(in_slots: params_channels(p: params),
588 out_slots: params_channels(p: params),
589 width: snd_pcm_format_width(format: params_format(p: params)));
590 if (ret < 0) {
591 dev_err(component->dev,
592 "no PCM config for %d channels, format %d\n",
593 params_channels(params), params_format(params));
594 goto err;
595 }
596
597 bsel = max98396_pcm_configs[ret].bsel;
598
599 if (params_rate(p: params) > max98396_pcm_configs[ret].max_sr) {
600 dev_err(component->dev, "sample rate %d too high",
601 params_rate(params));
602 goto err;
603 }
604 }
605
606 ret = regmap_read(map: max98396->regmap, MAX98396_R210F_GLOBAL_EN, val: &status);
607 if (ret < 0)
608 goto err;
609
610 if (status) {
611 ret = regmap_read(map: max98396->regmap, MAX98396_R2041_PCM_MODE_CFG, val: &reg);
612 if (ret < 0)
613 goto err;
614 if (chan_sz != (reg & MAX98396_PCM_MODE_CFG_CHANSZ_MASK)) {
615 update = true;
616 } else {
617 ret = regmap_read(map: max98396->regmap, MAX98396_R2043_PCM_SR_SETUP, val: &reg);
618 if (ret < 0)
619 goto err;
620 if (sampling_rate != (reg & MAX98396_PCM_SR_MASK))
621 update = true;
622 }
623
624 /* GLOBAL_EN OFF prior to channel size and sampling rate change */
625 if (update)
626 max98396_global_enable_onoff(regmap: max98396->regmap, onoff: false);
627 }
628
629 /* set channel size */
630 regmap_update_bits(map: max98396->regmap, MAX98396_R2041_PCM_MODE_CFG,
631 MAX98396_PCM_MODE_CFG_CHANSZ_MASK, val: chan_sz);
632
633 /* set DAI_SR to correct LRCLK frequency */
634 regmap_update_bits(map: max98396->regmap, MAX98396_R2043_PCM_SR_SETUP,
635 MAX98396_PCM_SR_MASK, val: sampling_rate);
636
637 /* set sampling rate of IV */
638 if (max98396->interleave_mode &&
639 sampling_rate > MAX98396_PCM_SR_16000)
640 regmap_update_bits(map: max98396->regmap,
641 MAX98396_R2043_PCM_SR_SETUP,
642 MAX98396_IVADC_SR_MASK,
643 val: (sampling_rate - 3)
644 << MAX98396_IVADC_SR_SHIFT);
645 else
646 regmap_update_bits(map: max98396->regmap,
647 MAX98396_R2043_PCM_SR_SETUP,
648 MAX98396_IVADC_SR_MASK,
649 val: sampling_rate << MAX98396_IVADC_SR_SHIFT);
650
651 if (bsel)
652 regmap_update_bits(map: max98396->regmap,
653 MAX98396_R2042_PCM_CLK_SETUP,
654 MAX98396_PCM_CLK_SETUP_BSEL_MASK,
655 val: bsel);
656
657 if (status && update)
658 max98396_global_enable_onoff(regmap: max98396->regmap, onoff: true);
659
660 return 0;
661
662err:
663 return -EINVAL;
664}
665
666static int max98396_dai_tdm_slot(struct snd_soc_dai *dai,
667 unsigned int tx_mask, unsigned int rx_mask,
668 int slots, int slot_width)
669{
670 struct snd_soc_component *component = dai->component;
671 struct max98396_priv *max98396 =
672 snd_soc_component_get_drvdata(c: component);
673 int bsel;
674 unsigned int chan_sz = 0;
675 int ret, status;
676 int reg;
677 bool update = false;
678
679 if (!tx_mask && !rx_mask && !slots && !slot_width)
680 max98396->tdm_mode = false;
681 else
682 max98396->tdm_mode = true;
683
684 /* BCLK configuration */
685 ret = max98396_pcm_config_index(in_slots: slots, out_slots: slots, width: slot_width);
686 if (ret < 0) {
687 dev_err(component->dev, "no TDM config for %d slots %d bits\n",
688 slots, slot_width);
689 return -EINVAL;
690 }
691
692 bsel = max98396_pcm_configs[ret].bsel;
693 max98396->tdm_max_samplerate = max98396_pcm_configs[ret].max_sr;
694
695 /* Channel size configuration */
696 switch (slot_width) {
697 case 16:
698 chan_sz = MAX98396_PCM_MODE_CFG_CHANSZ_16;
699 break;
700 case 24:
701 chan_sz = MAX98396_PCM_MODE_CFG_CHANSZ_24;
702 break;
703 case 32:
704 chan_sz = MAX98396_PCM_MODE_CFG_CHANSZ_32;
705 break;
706 default:
707 dev_err(component->dev, "slot width %d unsupported\n",
708 slot_width);
709 return -EINVAL;
710 }
711
712 ret = regmap_read(map: max98396->regmap, MAX98396_R210F_GLOBAL_EN, val: &status);
713 if (ret < 0)
714 return -EINVAL;
715
716 if (status) {
717 ret = regmap_read(map: max98396->regmap, MAX98396_R2042_PCM_CLK_SETUP, val: &reg);
718 if (ret < 0)
719 return -EINVAL;
720 if (bsel != (reg & MAX98396_PCM_CLK_SETUP_BSEL_MASK)) {
721 update = true;
722 } else {
723 ret = regmap_read(map: max98396->regmap, MAX98396_R2041_PCM_MODE_CFG, val: &reg);
724 if (ret < 0)
725 return -EINVAL;
726 if (chan_sz != (reg & MAX98396_PCM_MODE_CFG_CHANSZ_MASK))
727 update = true;
728 }
729
730 /* GLOBAL_EN OFF prior to channel size and BCLK per LRCLK change */
731 if (update)
732 max98396_global_enable_onoff(regmap: max98396->regmap, onoff: false);
733 }
734
735 regmap_update_bits(map: max98396->regmap,
736 MAX98396_R2042_PCM_CLK_SETUP,
737 MAX98396_PCM_CLK_SETUP_BSEL_MASK,
738 val: bsel);
739
740 regmap_update_bits(map: max98396->regmap,
741 MAX98396_R2041_PCM_MODE_CFG,
742 MAX98396_PCM_MODE_CFG_CHANSZ_MASK, val: chan_sz);
743
744 /* Rx slot configuration */
745 if (max98396->device_id == CODEC_TYPE_MAX98396) {
746 regmap_update_bits(map: max98396->regmap,
747 MAX98396_R2056_PCM_RX_SRC2,
748 MAX98396_PCM_DMIX_CH0_SRC_MASK,
749 val: rx_mask);
750 regmap_update_bits(map: max98396->regmap,
751 MAX98396_R2056_PCM_RX_SRC2,
752 MAX98396_PCM_DMIX_CH1_SRC_MASK,
753 val: rx_mask << MAX98396_PCM_DMIX_CH1_SHIFT);
754 } else {
755 regmap_update_bits(map: max98396->regmap,
756 MAX98397_R2057_PCM_RX_SRC2,
757 MAX98396_PCM_DMIX_CH0_SRC_MASK,
758 val: rx_mask);
759 regmap_update_bits(map: max98396->regmap,
760 MAX98397_R2057_PCM_RX_SRC2,
761 MAX98396_PCM_DMIX_CH1_SRC_MASK,
762 val: rx_mask << MAX98396_PCM_DMIX_CH1_SHIFT);
763 }
764
765 /* Tx slot Hi-Z configuration */
766 if (max98396->device_id == CODEC_TYPE_MAX98396) {
767 regmap_write(map: max98396->regmap,
768 MAX98396_R2053_PCM_TX_HIZ_CTRL_8,
769 val: ~tx_mask & 0xFF);
770 regmap_write(map: max98396->regmap,
771 MAX98396_R2052_PCM_TX_HIZ_CTRL_7,
772 val: (~tx_mask & 0xFF00) >> 8);
773 } else {
774 regmap_write(map: max98396->regmap,
775 MAX98397_R2054_PCM_TX_HIZ_CTRL_8,
776 val: ~tx_mask & 0xFF);
777 regmap_write(map: max98396->regmap,
778 MAX98397_R2053_PCM_TX_HIZ_CTRL_7,
779 val: (~tx_mask & 0xFF00) >> 8);
780 }
781
782 if (status && update)
783 max98396_global_enable_onoff(regmap: max98396->regmap, onoff: true);
784
785 return 0;
786}
787
788#define MAX98396_RATES SNDRV_PCM_RATE_8000_192000
789
790#define MAX98396_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
791 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
792
793static const struct snd_soc_dai_ops max98396_dai_ops = {
794 .set_fmt = max98396_dai_set_fmt,
795 .hw_params = max98396_dai_hw_params,
796 .set_tdm_slot = max98396_dai_tdm_slot,
797};
798
799static int max98396_dac_event(struct snd_soc_dapm_widget *w,
800 struct snd_kcontrol *kcontrol, int event)
801{
802 struct snd_soc_component *component =
803 snd_soc_dapm_to_component(dapm: w->dapm);
804 struct max98396_priv *max98396 =
805 snd_soc_component_get_drvdata(c: component);
806
807 switch (event) {
808 case SND_SOC_DAPM_POST_PMU:
809 max98396_global_enable_onoff(regmap: max98396->regmap, onoff: true);
810 break;
811 case SND_SOC_DAPM_PRE_PMD:
812 max98396_global_enable_onoff(regmap: max98396->regmap, onoff: false);
813
814 max98396->tdm_mode = false;
815 break;
816 default:
817 return 0;
818 }
819 return 0;
820}
821
822static bool max98396_readable_register(struct device *dev, unsigned int reg)
823{
824 switch (reg) {
825 case MAX98396_R2001_INT_RAW1 ... MAX98396_R2004_INT_RAW4:
826 case MAX98396_R2006_INT_STATE1 ... MAX98396_R2009_INT_STATE4:
827 case MAX98396_R200B_INT_FLAG1 ... MAX98396_R200E_INT_FLAG4:
828 case MAX98396_R2010_INT_EN1 ... MAX98396_R2013_INT_EN4:
829 case MAX98396_R2015_INT_FLAG_CLR1 ... MAX98396_R2018_INT_FLAG_CLR4:
830 case MAX98396_R201F_IRQ_CTRL ... MAX98396_R2024_THERM_FOLDBACK_SET:
831 case MAX98396_R2027_THERM_FOLDBACK_EN:
832 case MAX98396_R2030_NOISEGATE_MODE_CTRL:
833 case MAX98396_R2033_NOISEGATE_MODE_EN:
834 case MAX98396_R2038_CLK_MON_CTRL ... MAX98396_R2039_DATA_MON_CTRL:
835 case MAX98396_R203F_ENABLE_CTRLS ... MAX98396_R2053_PCM_TX_HIZ_CTRL_8:
836 case MAX98396_R2055_PCM_RX_SRC1 ... MAX98396_R2056_PCM_RX_SRC2:
837 case MAX98396_R2058_PCM_BYPASS_SRC:
838 case MAX98396_R205D_PCM_TX_SRC_EN ... MAX98396_R205F_PCM_TX_EN:
839 case MAX98396_R2070_ICC_RX_EN_A... MAX98396_R2072_ICC_TX_CTRL:
840 case MAX98396_R207F_ICC_EN:
841 case MAX98396_R2083_TONE_GEN_DC_CFG ... MAX98396_R2086_TONE_GEN_DC_LVL3:
842 case MAX98396_R208F_TONE_GEN_EN ... MAX98396_R209A_SPK_EDGE_CTRL:
843 case MAX98396_R209C_SPK_EDGE_CTRL1 ... MAX98396_R20A0_AMP_SUPPLY_CTL:
844 case MAX98396_R20AF_AMP_EN ... MAX98396_R20BF_ADC_LO_VBAT_READBACK_LSB:
845 case MAX98396_R20C7_ADC_CFG:
846 case MAX98396_R20D0_DHT_CFG1 ... MAX98396_R20D6_DHT_HYSTERESIS_CFG:
847 case MAX98396_R20DF_DHT_EN:
848 case MAX98396_R20E0_IV_SENSE_PATH_CFG:
849 case MAX98396_R20E4_IV_SENSE_PATH_EN
850 ... MAX98396_R2106_BPE_THRESH_HYSTERESIS:
851 case MAX98396_R2108_BPE_SUPPLY_SRC ... MAX98396_R210B_BPE_LOW_LIMITER:
852 case MAX98396_R210D_BPE_EN ... MAX98396_R210F_GLOBAL_EN:
853 case MAX98396_R21FF_REVISION_ID:
854 return true;
855 default:
856 return false;
857 }
858};
859
860static bool max98396_volatile_reg(struct device *dev, unsigned int reg)
861{
862 switch (reg) {
863 case MAX98396_R2000_SW_RESET:
864 case MAX98396_R2001_INT_RAW1 ... MAX98396_R200E_INT_FLAG4:
865 case MAX98396_R2041_PCM_MODE_CFG:
866 case MAX98396_R20B6_ADC_PVDD_READBACK_MSB
867 ... MAX98396_R20BF_ADC_LO_VBAT_READBACK_LSB:
868 case MAX98396_R20E5_BPE_STATE:
869 case MAX98396_R2109_BPE_LOW_STATE
870 ... MAX98396_R210B_BPE_LOW_LIMITER:
871 case MAX98396_R210F_GLOBAL_EN:
872 case MAX98396_R21FF_REVISION_ID:
873 return true;
874 default:
875 return false;
876 }
877}
878
879static bool max98397_readable_register(struct device *dev, unsigned int reg)
880{
881 switch (reg) {
882 case MAX98396_R2001_INT_RAW1 ... MAX98396_R2004_INT_RAW4:
883 case MAX98396_R2006_INT_STATE1 ... MAX98396_R2009_INT_STATE4:
884 case MAX98396_R200B_INT_FLAG1 ... MAX98396_R200E_INT_FLAG4:
885 case MAX98396_R2010_INT_EN1 ... MAX98396_R2013_INT_EN4:
886 case MAX98396_R2015_INT_FLAG_CLR1 ... MAX98396_R2018_INT_FLAG_CLR4:
887 case MAX98396_R201F_IRQ_CTRL ... MAX98396_R2024_THERM_FOLDBACK_SET:
888 case MAX98396_R2027_THERM_FOLDBACK_EN:
889 case MAX98396_R2030_NOISEGATE_MODE_CTRL:
890 case MAX98396_R2033_NOISEGATE_MODE_EN:
891 case MAX98396_R2038_CLK_MON_CTRL ... MAX98397_R203A_SPK_MON_THRESH:
892 case MAX98396_R203F_ENABLE_CTRLS ... MAX98397_R2054_PCM_TX_HIZ_CTRL_8:
893 case MAX98397_R2056_PCM_RX_SRC1... MAX98396_R2058_PCM_BYPASS_SRC:
894 case MAX98396_R205D_PCM_TX_SRC_EN ... MAX98397_R2060_PCM_TX_SUPPLY_SEL:
895 case MAX98396_R2070_ICC_RX_EN_A... MAX98396_R2072_ICC_TX_CTRL:
896 case MAX98396_R207F_ICC_EN:
897 case MAX98396_R2083_TONE_GEN_DC_CFG ... MAX98396_R2086_TONE_GEN_DC_LVL3:
898 case MAX98396_R208F_TONE_GEN_EN ... MAX98396_R209F_BYPASS_PATH_CFG:
899 case MAX98396_R20AF_AMP_EN ... MAX98397_R20C5_MEAS_ADC_OPTIMAL_MODE:
900 case MAX98396_R20C7_ADC_CFG:
901 case MAX98396_R20D0_DHT_CFG1 ... MAX98396_R20D6_DHT_HYSTERESIS_CFG:
902 case MAX98396_R20DF_DHT_EN:
903 case MAX98396_R20E0_IV_SENSE_PATH_CFG:
904 case MAX98396_R20E4_IV_SENSE_PATH_EN
905 ... MAX98396_R2106_BPE_THRESH_HYSTERESIS:
906 case MAX98396_R2108_BPE_SUPPLY_SRC ... MAX98396_R210B_BPE_LOW_LIMITER:
907 case MAX98396_R210D_BPE_EN ... MAX98396_R210F_GLOBAL_EN:
908 case MAX98397_R22FF_REVISION_ID:
909 return true;
910 default:
911 return false;
912 }
913};
914
915static bool max98397_volatile_reg(struct device *dev, unsigned int reg)
916{
917 switch (reg) {
918 case MAX98396_R2001_INT_RAW1 ... MAX98396_R200E_INT_FLAG4:
919 case MAX98396_R2041_PCM_MODE_CFG:
920 case MAX98397_R20B7_ADC_PVDD_READBACK_MSB
921 ... MAX98397_R20C4_ADC_LO_VDDH_READBACK_LSB:
922 case MAX98396_R20E5_BPE_STATE:
923 case MAX98396_R2109_BPE_LOW_STATE
924 ... MAX98396_R210B_BPE_LOW_LIMITER:
925 case MAX98396_R210F_GLOBAL_EN:
926 case MAX98397_R22FF_REVISION_ID:
927 return true;
928 default:
929 return false;
930 }
931}
932
933static const char * const max98396_op_mod_text[] = {
934 "DG", "PVDD", "VBAT",
935};
936
937static SOC_ENUM_SINGLE_DECL(max98396_op_mod_enum,
938 MAX98396_R2098_SPK_CLS_DG_MODE,
939 0, max98396_op_mod_text);
940
941static DECLARE_TLV_DB_SCALE(max98396_digital_tlv, -6350, 50, 1);
942static const DECLARE_TLV_DB_RANGE(max98396_spk_tlv,
943 0, 0x11, TLV_DB_SCALE_ITEM(400, 100, 0),
944);
945static DECLARE_TLV_DB_RANGE(max98397_digital_tlv,
946 0, 0x4A, TLV_DB_SCALE_ITEM(TLV_DB_GAIN_MUTE, 0, 1),
947 0x4B, 0xFF, TLV_DB_SCALE_ITEM(-9000, 50, 0),
948);
949static const DECLARE_TLV_DB_RANGE(max98397_spk_tlv,
950 0, 0x15, TLV_DB_SCALE_ITEM(600, 100, 0),
951);
952
953static int max98396_mux_get(struct snd_kcontrol *kcontrol,
954 struct snd_ctl_elem_value *ucontrol)
955{
956 struct snd_soc_component *component =
957 snd_soc_dapm_kcontrol_component(kcontrol);
958 struct max98396_priv *max98396 = snd_soc_component_get_drvdata(c: component);
959 int reg, val;
960
961 if (max98396->device_id == CODEC_TYPE_MAX98396)
962 reg = MAX98396_R2055_PCM_RX_SRC1;
963 else
964 reg = MAX98397_R2056_PCM_RX_SRC1;
965
966 regmap_read(map: max98396->regmap, reg, val: &val);
967
968 ucontrol->value.enumerated.item[0] = val;
969
970 return 0;
971}
972
973static int max98396_mux_put(struct snd_kcontrol *kcontrol,
974 struct snd_ctl_elem_value *ucontrol)
975{
976 struct snd_soc_component *component =
977 snd_soc_dapm_kcontrol_component(kcontrol);
978 struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kcontrol);
979 struct max98396_priv *max98396 = snd_soc_component_get_drvdata(c: component);
980 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
981 unsigned int *item = ucontrol->value.enumerated.item;
982 int reg, val;
983 int change;
984
985 if (item[0] >= e->items)
986 return -EINVAL;
987
988 val = snd_soc_enum_item_to_val(e, item: item[0]) << e->shift_l;
989
990 if (max98396->device_id == CODEC_TYPE_MAX98396)
991 reg = MAX98396_R2055_PCM_RX_SRC1;
992 else
993 reg = MAX98397_R2056_PCM_RX_SRC1;
994
995 change = snd_soc_component_test_bits(component, reg,
996 MAX98396_PCM_RX_MASK, value: val);
997
998 if (change)
999 regmap_update_bits(map: max98396->regmap, reg,
1000 MAX98396_PCM_RX_MASK, val);
1001
1002 snd_soc_dapm_mux_update_power(dapm, kcontrol, mux: item[0], e, NULL);
1003
1004 return change;
1005}
1006
1007static const char * const max98396_switch_text[] = {
1008 "Left", "Right", "LeftRight"};
1009
1010static SOC_ENUM_SINGLE_DECL(dai_sel_enum, SND_SOC_NOPM, 0,
1011 max98396_switch_text);
1012
1013static const struct snd_kcontrol_new max98396_dai_mux =
1014 SOC_DAPM_ENUM_EXT("DAI Sel Mux", dai_sel_enum,
1015 max98396_mux_get, max98396_mux_put);
1016
1017static const struct snd_kcontrol_new max98396_vi_control =
1018 SOC_DAPM_SINGLE("Switch", MAX98396_R205F_PCM_TX_EN, 0, 1, 0);
1019
1020static const struct snd_soc_dapm_widget max98396_dapm_widgets[] = {
1021 SND_SOC_DAPM_DAC_E("Amp Enable", "HiFi Playback",
1022 MAX98396_R20AF_AMP_EN, 0, 0, max98396_dac_event,
1023 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
1024 SND_SOC_DAPM_MUX("DAI Sel Mux", SND_SOC_NOPM, 0, 0,
1025 &max98396_dai_mux),
1026 SND_SOC_DAPM_OUTPUT("BE_OUT"),
1027 SND_SOC_DAPM_AIF_OUT("Voltage Sense", "HiFi Capture", 0,
1028 MAX98396_R20E4_IV_SENSE_PATH_EN, 0, 0),
1029 SND_SOC_DAPM_AIF_OUT("Current Sense", "HiFi Capture", 0,
1030 MAX98396_R20E4_IV_SENSE_PATH_EN, 1, 0),
1031 SND_SOC_DAPM_SWITCH("VI Sense", SND_SOC_NOPM, 0, 0,
1032 &max98396_vi_control),
1033 SND_SOC_DAPM_SIGGEN("VMON"),
1034 SND_SOC_DAPM_SIGGEN("IMON"),
1035 SND_SOC_DAPM_SIGGEN("FBMON"),
1036};
1037
1038static const char * const max98396_thermal_thresh_text[] = {
1039 "50C", "51C", "52C", "53C", "54C", "55C", "56C", "57C",
1040 "58C", "59C", "60C", "61C", "62C", "63C", "64C", "65C",
1041 "66C", "67C", "68C", "69C", "70C", "71C", "72C", "73C",
1042 "74C", "75C", "76C", "77C", "78C", "79C", "80C", "81C",
1043 "82C", "83C", "84C", "85C", "86C", "87C", "88C", "89C",
1044 "90C", "91C", "92C", "93C", "94C", "95C", "96C", "97C",
1045 "98C", "99C", "100C", "101C", "102C", "103C", "104C", "105C",
1046 "106C", "107C", "108C", "109C", "110C", "111C", "112C", "113C",
1047 "114C", "115C", "116C", "117C", "118C", "119C", "120C", "121C",
1048 "122C", "123C", "124C", "125C", "126C", "127C", "128C", "129C",
1049 "130C", "131C", "132C", "133C", "134C", "135C", "136C", "137C",
1050 "138C", "139C", "140C", "141C", "142C", "143C", "144C", "145C",
1051 "146C", "147C", "148C", "149C", "150C"
1052};
1053
1054static SOC_ENUM_SINGLE_DECL(max98396_thermal_warn_thresh1_enum,
1055 MAX98396_R2020_THERM_WARN_THRESH, 0,
1056 max98396_thermal_thresh_text);
1057
1058static SOC_ENUM_SINGLE_DECL(max98396_thermal_warn_thresh2_enum,
1059 MAX98396_R2021_THERM_WARN_THRESH2, 0,
1060 max98396_thermal_thresh_text);
1061
1062static SOC_ENUM_SINGLE_DECL(max98396_thermal_shdn_thresh_enum,
1063 MAX98396_R2022_THERM_SHDN_THRESH, 0,
1064 max98396_thermal_thresh_text);
1065
1066static const char * const max98396_thermal_hyteresis_text[] = {
1067 "2C", "5C", "7C", "10C"
1068};
1069
1070static SOC_ENUM_SINGLE_DECL(max98396_thermal_hysteresis_enum,
1071 MAX98396_R2023_THERM_HYSTERESIS, 0,
1072 max98396_thermal_hyteresis_text);
1073
1074static const char * const max98396_foldback_slope_text[] = {
1075 "0.25", "0.5", "1.0", "2.0"
1076};
1077
1078static SOC_ENUM_SINGLE_DECL(max98396_thermal_fb_slope1_enum,
1079 MAX98396_R2024_THERM_FOLDBACK_SET,
1080 MAX98396_THERM_FB_SLOPE1_SHIFT,
1081 max98396_foldback_slope_text);
1082
1083static SOC_ENUM_SINGLE_DECL(max98396_thermal_fb_slope2_enum,
1084 MAX98396_R2024_THERM_FOLDBACK_SET,
1085 MAX98396_THERM_FB_SLOPE2_SHIFT,
1086 max98396_foldback_slope_text);
1087
1088static const char * const max98396_foldback_reltime_text[] = {
1089 "3ms", "10ms", "100ms", "300ms"
1090};
1091
1092static SOC_ENUM_SINGLE_DECL(max98396_thermal_fb_reltime_enum,
1093 MAX98396_R2024_THERM_FOLDBACK_SET,
1094 MAX98396_THERM_FB_REL_SHIFT,
1095 max98396_foldback_reltime_text);
1096
1097static const char * const max98396_foldback_holdtime_text[] = {
1098 "0ms", "20ms", "40ms", "80ms"
1099};
1100
1101static SOC_ENUM_SINGLE_DECL(max98396_thermal_fb_holdtime_enum,
1102 MAX98396_R2024_THERM_FOLDBACK_SET,
1103 MAX98396_THERM_FB_HOLD_SHIFT,
1104 max98396_foldback_holdtime_text);
1105
1106static int max98396_adc_value_get(struct snd_kcontrol *kcontrol,
1107 struct snd_ctl_elem_value *ucontrol)
1108{
1109 struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
1110 struct soc_mixer_control *mc =
1111 (struct soc_mixer_control *)kcontrol->private_value;
1112 struct max98396_priv *max98396 = snd_soc_component_get_drvdata(c: component);
1113 int ret;
1114 u8 val[2];
1115 int reg = mc->reg;
1116
1117 /* ADC value is not available if the device is powered down */
1118 if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF)
1119 goto exit;
1120
1121 if (max98396->device_id == CODEC_TYPE_MAX98397) {
1122 switch (mc->reg) {
1123 case MAX98396_R20B6_ADC_PVDD_READBACK_MSB:
1124 reg = MAX98397_R20B7_ADC_PVDD_READBACK_MSB;
1125 break;
1126 case MAX98396_R20B8_ADC_VBAT_READBACK_MSB:
1127 reg = MAX98397_R20B9_ADC_VBAT_READBACK_MSB;
1128 break;
1129 case MAX98396_R20BA_ADC_TEMP_READBACK_MSB:
1130 reg = MAX98397_R20BB_ADC_TEMP_READBACK_MSB;
1131 break;
1132 default:
1133 goto exit;
1134 }
1135 }
1136
1137 ret = regmap_raw_read(map: max98396->regmap, reg, val: &val, val_len: 2);
1138 if (ret)
1139 goto exit;
1140
1141 /* ADC readback bits[8:0] rearrangement */
1142 ucontrol->value.integer.value[0] = (val[0] << 1) | (val[1] & 1);
1143 return 0;
1144
1145exit:
1146 ucontrol->value.integer.value[0] = 0;
1147 return 0;
1148}
1149
1150static const struct snd_kcontrol_new max98396_snd_controls[] = {
1151 /* Volume */
1152 SOC_SINGLE_TLV("Digital Volume", MAX98396_R2090_AMP_VOL_CTRL,
1153 0, 0x7F, 1, max98396_digital_tlv),
1154 SOC_SINGLE_TLV("Speaker Volume", MAX98396_R2091_AMP_PATH_GAIN,
1155 0, 0x11, 0, max98396_spk_tlv),
1156 /* Volume Ramp Up/Down Enable*/
1157 SOC_SINGLE("Ramp Up Switch", MAX98396_R2092_AMP_DSP_CFG,
1158 MAX98396_DSP_SPK_VOL_RMPUP_SHIFT, 1, 0),
1159 SOC_SINGLE("Ramp Down Switch", MAX98396_R2092_AMP_DSP_CFG,
1160 MAX98396_DSP_SPK_VOL_RMPDN_SHIFT, 1, 0),
1161 /* Clock Monitor Enable */
1162 SOC_SINGLE("CLK Monitor Switch", MAX98396_R203F_ENABLE_CTRLS,
1163 MAX98396_CTRL_CMON_EN_SHIFT, 1, 0),
1164 /* Dither Enable */
1165 SOC_SINGLE("Dither Switch", MAX98396_R2092_AMP_DSP_CFG,
1166 MAX98396_DSP_SPK_DITH_EN_SHIFT, 1, 0),
1167 SOC_SINGLE("IV Dither Switch", MAX98396_R20E0_IV_SENSE_PATH_CFG,
1168 MAX98396_IV_SENSE_DITH_EN_SHIFT, 1, 0),
1169 /* DC Blocker Enable */
1170 SOC_SINGLE("DC Blocker Switch", MAX98396_R2092_AMP_DSP_CFG,
1171 MAX98396_DSP_SPK_DCBLK_EN_SHIFT, 1, 0),
1172 SOC_SINGLE("IV DC Blocker Switch", MAX98396_R20E0_IV_SENSE_PATH_CFG,
1173 MAX98396_IV_SENSE_DCBLK_EN_SHIFT, 3, 0),
1174 /* Speaker Safe Mode Enable */
1175 SOC_SINGLE("Safe Mode Switch", MAX98396_R2092_AMP_DSP_CFG,
1176 MAX98396_DSP_SPK_SAFE_EN_SHIFT, 1, 0),
1177 /* Wideband Filter Enable */
1178 SOC_SINGLE("WB Filter Switch", MAX98396_R2092_AMP_DSP_CFG,
1179 MAX98396_DSP_SPK_WB_FLT_EN_SHIFT, 1, 0),
1180 SOC_SINGLE("IV WB Filter Switch", MAX98396_R20E0_IV_SENSE_PATH_CFG,
1181 MAX98396_IV_SENSE_WB_FLT_EN_SHIFT, 1, 0),
1182 /* Dynamic Headroom Tracking */
1183 SOC_SINGLE("DHT Switch", MAX98396_R20DF_DHT_EN, 0, 1, 0),
1184 /* Brownout Protection Engine */
1185 SOC_SINGLE("BPE Switch", MAX98396_R210D_BPE_EN, 0, 1, 0),
1186 SOC_SINGLE("BPE Limiter Switch", MAX98396_R210D_BPE_EN, 1, 1, 0),
1187 /* Bypass Path Enable */
1188 SOC_SINGLE("Bypass Path Switch",
1189 MAX98396_R205E_PCM_RX_EN, 1, 1, 0),
1190 /* Speaker Operation Mode */
1191 SOC_ENUM("OP Mode", max98396_op_mod_enum),
1192 /* Auto Restart functions */
1193 SOC_SINGLE("CMON Auto Restart Switch", MAX98396_R2038_CLK_MON_CTRL,
1194 MAX98396_CLK_MON_AUTO_RESTART_SHIFT, 1, 0),
1195 SOC_SINGLE("PVDD Auto Restart Switch", MAX98396_R210E_AUTO_RESTART,
1196 MAX98396_PVDD_UVLO_RESTART_SHFT, 1, 0),
1197 SOC_SINGLE("VBAT Auto Restart Switch", MAX98396_R210E_AUTO_RESTART,
1198 MAX98396_VBAT_UVLO_RESTART_SHFT, 1, 0),
1199 SOC_SINGLE("THERM Auto Restart Switch", MAX98396_R210E_AUTO_RESTART,
1200 MAX98396_THEM_SHDN_RESTART_SHFT, 1, 0),
1201 SOC_SINGLE("OVC Auto Restart Switch", MAX98396_R210E_AUTO_RESTART,
1202 MAX98396_OVC_RESTART_SHFT, 1, 0),
1203 /* Thermal Threshold */
1204 SOC_ENUM("THERM Thresh1", max98396_thermal_warn_thresh1_enum),
1205 SOC_ENUM("THERM Thresh2", max98396_thermal_warn_thresh2_enum),
1206 SOC_ENUM("THERM SHDN Thresh", max98396_thermal_shdn_thresh_enum),
1207 SOC_ENUM("THERM Hysteresis", max98396_thermal_hysteresis_enum),
1208 SOC_SINGLE("THERM Foldback Switch",
1209 MAX98396_R2027_THERM_FOLDBACK_EN, 0, 1, 0),
1210 SOC_ENUM("THERM Slope1", max98396_thermal_fb_slope1_enum),
1211 SOC_ENUM("THERM Slope2", max98396_thermal_fb_slope2_enum),
1212 SOC_ENUM("THERM Release", max98396_thermal_fb_reltime_enum),
1213 SOC_ENUM("THERM Hold", max98396_thermal_fb_holdtime_enum),
1214 /* ADC */
1215 SOC_SINGLE_EXT("ADC PVDD", MAX98396_R20B6_ADC_PVDD_READBACK_MSB, 0, 0x1FF, 0,
1216 max98396_adc_value_get, NULL),
1217 SOC_SINGLE_EXT("ADC VBAT", MAX98396_R20B8_ADC_VBAT_READBACK_MSB, 0, 0x1FF, 0,
1218 max98396_adc_value_get, NULL),
1219 SOC_SINGLE_EXT("ADC TEMP", MAX98396_R20BA_ADC_TEMP_READBACK_MSB, 0, 0x1FF, 0,
1220 max98396_adc_value_get, NULL),
1221};
1222
1223static const struct snd_kcontrol_new max98397_snd_controls[] = {
1224 /* Volume */
1225 SOC_SINGLE_TLV("Digital Volume", MAX98396_R2090_AMP_VOL_CTRL,
1226 0, 0xFF, 1, max98397_digital_tlv),
1227 SOC_SINGLE_TLV("Speaker Volume", MAX98396_R2091_AMP_PATH_GAIN,
1228 0, 0x15, 0, max98397_spk_tlv),
1229 /* Volume Ramp Up/Down Enable*/
1230 SOC_SINGLE("Ramp Up Switch", MAX98396_R2092_AMP_DSP_CFG,
1231 MAX98396_DSP_SPK_VOL_RMPUP_SHIFT, 1, 0),
1232 SOC_SINGLE("Ramp Down Switch", MAX98396_R2092_AMP_DSP_CFG,
1233 MAX98396_DSP_SPK_VOL_RMPDN_SHIFT, 1, 0),
1234 /* Clock Monitor Enable */
1235 SOC_SINGLE("CLK Monitor Switch", MAX98396_R203F_ENABLE_CTRLS,
1236 MAX98396_CTRL_CMON_EN_SHIFT, 1, 0),
1237 /* Dither Enable */
1238 SOC_SINGLE("Dither Switch", MAX98396_R2092_AMP_DSP_CFG,
1239 MAX98396_DSP_SPK_DITH_EN_SHIFT, 1, 0),
1240 SOC_SINGLE("IV Dither Switch", MAX98396_R20E0_IV_SENSE_PATH_CFG,
1241 MAX98396_IV_SENSE_DITH_EN_SHIFT, 1, 0),
1242 /* DC Blocker Enable */
1243 SOC_SINGLE("DC Blocker Switch", MAX98396_R2092_AMP_DSP_CFG,
1244 MAX98396_DSP_SPK_DCBLK_EN_SHIFT, 1, 0),
1245 SOC_SINGLE("IV DC Blocker Switch", MAX98396_R20E0_IV_SENSE_PATH_CFG,
1246 MAX98396_IV_SENSE_DCBLK_EN_SHIFT, 3, 0),
1247 /* Speaker Safe Mode Enable */
1248 SOC_SINGLE("Safe Mode Switch", MAX98396_R2092_AMP_DSP_CFG,
1249 MAX98396_DSP_SPK_SAFE_EN_SHIFT, 1, 0),
1250 /* Wideband Filter Enable */
1251 SOC_SINGLE("WB Filter Switch", MAX98396_R2092_AMP_DSP_CFG,
1252 MAX98396_DSP_SPK_WB_FLT_EN_SHIFT, 1, 0),
1253 SOC_SINGLE("IV WB Filter Switch", MAX98396_R20E0_IV_SENSE_PATH_CFG,
1254 MAX98396_IV_SENSE_WB_FLT_EN_SHIFT, 1, 0),
1255 /* Dynamic Headroom Tracking */
1256 SOC_SINGLE("DHT Switch", MAX98396_R20DF_DHT_EN, 0, 1, 0),
1257 /* Brownout Protection Engine */
1258 SOC_SINGLE("BPE Switch", MAX98396_R210D_BPE_EN, 0, 1, 0),
1259 SOC_SINGLE("BPE Limiter Switch", MAX98396_R210D_BPE_EN, 1, 1, 0),
1260 /* Bypass Path Enable */
1261 SOC_SINGLE("Bypass Path Switch",
1262 MAX98396_R205E_PCM_RX_EN, 1, 1, 0),
1263 /* Speaker Operation Mode */
1264 SOC_ENUM("OP Mode", max98396_op_mod_enum),
1265 /* Auto Restart functions */
1266 SOC_SINGLE("CMON Auto Restart Switch", MAX98396_R2038_CLK_MON_CTRL,
1267 MAX98396_CLK_MON_AUTO_RESTART_SHIFT, 1, 0),
1268 SOC_SINGLE("PVDD Auto Restart Switch", MAX98396_R210E_AUTO_RESTART,
1269 MAX98396_PVDD_UVLO_RESTART_SHFT, 1, 0),
1270 SOC_SINGLE("VBAT Auto Restart Switch", MAX98396_R210E_AUTO_RESTART,
1271 MAX98396_VBAT_UVLO_RESTART_SHFT, 1, 0),
1272 SOC_SINGLE("THERM Auto Restart Switch", MAX98396_R210E_AUTO_RESTART,
1273 MAX98396_THEM_SHDN_RESTART_SHFT, 1, 0),
1274 SOC_SINGLE("OVC Auto Restart Switch", MAX98396_R210E_AUTO_RESTART,
1275 MAX98396_OVC_RESTART_SHFT, 1, 0),
1276 /* Thermal Threshold */
1277 SOC_ENUM("THERM Thresh1", max98396_thermal_warn_thresh1_enum),
1278 SOC_ENUM("THERM Thresh2", max98396_thermal_warn_thresh2_enum),
1279 SOC_ENUM("THERM SHDN Thresh", max98396_thermal_shdn_thresh_enum),
1280 SOC_ENUM("THERM Hysteresis", max98396_thermal_hysteresis_enum),
1281 SOC_SINGLE("THERM Foldback Switch",
1282 MAX98396_R2027_THERM_FOLDBACK_EN, 0, 1, 0),
1283 SOC_ENUM("THERM Slope1", max98396_thermal_fb_slope1_enum),
1284 SOC_ENUM("THERM Slope2", max98396_thermal_fb_slope2_enum),
1285 SOC_ENUM("THERM Release", max98396_thermal_fb_reltime_enum),
1286 SOC_ENUM("THERM Hold", max98396_thermal_fb_holdtime_enum),
1287 /* ADC */
1288 SOC_SINGLE_EXT("ADC PVDD", MAX98396_R20B6_ADC_PVDD_READBACK_MSB, 0, 0x1FF, 0,
1289 max98396_adc_value_get, NULL),
1290 SOC_SINGLE_EXT("ADC VBAT", MAX98396_R20B8_ADC_VBAT_READBACK_MSB, 0, 0x1FF, 0,
1291 max98396_adc_value_get, NULL),
1292 SOC_SINGLE_EXT("ADC TEMP", MAX98396_R20BA_ADC_TEMP_READBACK_MSB, 0, 0x1FF, 0,
1293 max98396_adc_value_get, NULL),
1294};
1295
1296static const struct snd_soc_dapm_route max98396_audio_map[] = {
1297 /* Plabyack */
1298 {"DAI Sel Mux", "Left", "Amp Enable"},
1299 {"DAI Sel Mux", "Right", "Amp Enable"},
1300 {"DAI Sel Mux", "LeftRight", "Amp Enable"},
1301 {"BE_OUT", NULL, "DAI Sel Mux"},
1302 /* Capture */
1303 { "VI Sense", "Switch", "VMON" },
1304 { "VI Sense", "Switch", "IMON" },
1305 { "Voltage Sense", NULL, "VI Sense" },
1306 { "Current Sense", NULL, "VI Sense" },
1307};
1308
1309static struct snd_soc_dai_driver max98396_dai[] = {
1310 {
1311 .name = "max98396-aif1",
1312 .playback = {
1313 .stream_name = "HiFi Playback",
1314 .channels_min = 1,
1315 .channels_max = 2,
1316 .rates = MAX98396_RATES,
1317 .formats = MAX98396_FORMATS,
1318 },
1319 .capture = {
1320 .stream_name = "HiFi Capture",
1321 .channels_min = 1,
1322 .channels_max = 2,
1323 .rates = MAX98396_RATES,
1324 .formats = MAX98396_FORMATS,
1325 },
1326 .ops = &max98396_dai_ops,
1327 }
1328};
1329
1330static struct snd_soc_dai_driver max98397_dai[] = {
1331 {
1332 .name = "max98397-aif1",
1333 .playback = {
1334 .stream_name = "HiFi Playback",
1335 .channels_min = 1,
1336 .channels_max = 2,
1337 .rates = MAX98396_RATES,
1338 .formats = MAX98396_FORMATS,
1339 },
1340 .capture = {
1341 .stream_name = "HiFi Capture",
1342 .channels_min = 1,
1343 .channels_max = 2,
1344 .rates = MAX98396_RATES,
1345 .formats = MAX98396_FORMATS,
1346 },
1347 .ops = &max98396_dai_ops,
1348 }
1349};
1350
1351static void max98396_reset(struct max98396_priv *max98396, struct device *dev)
1352{
1353 int ret, reg, count;
1354
1355 /* Software Reset */
1356 ret = regmap_write(map: max98396->regmap,
1357 MAX98396_R2000_SW_RESET, val: 1);
1358 if (ret)
1359 dev_err(dev, "Reset command failed. (ret:%d)\n", ret);
1360
1361 count = 0;
1362 while (count < 3) {
1363 usleep_range(min: 5000, max: 6000);
1364 /* Software Reset Verification */
1365 ret = regmap_read(map: max98396->regmap,
1366 GET_REG_ADDR_REV_ID(max98396->device_id), val: &reg);
1367 if (!ret) {
1368 dev_info(dev, "Reset completed (retry:%d)\n", count);
1369 return;
1370 }
1371 count++;
1372 }
1373 dev_err(dev, "Reset failed. (ret:%d)\n", ret);
1374}
1375
1376static int max98396_probe(struct snd_soc_component *component)
1377{
1378 struct max98396_priv *max98396 =
1379 snd_soc_component_get_drvdata(c: component);
1380
1381 /* Software Reset */
1382 max98396_reset(max98396, dev: component->dev);
1383
1384 /* L/R mix configuration */
1385 if (max98396->device_id == CODEC_TYPE_MAX98396) {
1386 regmap_write(map: max98396->regmap,
1387 MAX98396_R2055_PCM_RX_SRC1, val: 0x02);
1388 regmap_write(map: max98396->regmap,
1389 MAX98396_R2056_PCM_RX_SRC2, val: 0x10);
1390 } else {
1391 regmap_write(map: max98396->regmap,
1392 MAX98397_R2056_PCM_RX_SRC1, val: 0x02);
1393 regmap_write(map: max98396->regmap,
1394 MAX98397_R2057_PCM_RX_SRC2, val: 0x10);
1395 }
1396 /* Supply control */
1397 regmap_update_bits(map: max98396->regmap,
1398 MAX98396_R20A0_AMP_SUPPLY_CTL,
1399 MAX98396_AMP_SUPPLY_NOVBAT,
1400 val: (max98396->vbat == NULL) ?
1401 MAX98396_AMP_SUPPLY_NOVBAT : 0);
1402 /* Enable DC blocker */
1403 regmap_update_bits(map: max98396->regmap,
1404 MAX98396_R2092_AMP_DSP_CFG, mask: 1, val: 1);
1405 /* Enable IV Monitor DC blocker */
1406 regmap_update_bits(map: max98396->regmap,
1407 MAX98396_R20E0_IV_SENSE_PATH_CFG,
1408 MAX98396_IV_SENSE_DCBLK_EN_MASK,
1409 MAX98396_IV_SENSE_DCBLK_EN_MASK);
1410 /* Configure default data output sources */
1411 regmap_write(map: max98396->regmap,
1412 MAX98396_R205D_PCM_TX_SRC_EN, val: 3);
1413 /* Enable Wideband Filter */
1414 regmap_update_bits(map: max98396->regmap,
1415 MAX98396_R2092_AMP_DSP_CFG, mask: 0x40, val: 0x40);
1416 /* Enable IV Wideband Filter */
1417 regmap_update_bits(map: max98396->regmap,
1418 MAX98396_R20E0_IV_SENSE_PATH_CFG, mask: 8, val: 8);
1419
1420 /* Enable Bypass Source */
1421 regmap_write(map: max98396->regmap,
1422 MAX98396_R2058_PCM_BYPASS_SRC,
1423 val: max98396->bypass_slot);
1424 /* Voltage, current slot configuration */
1425 regmap_write(map: max98396->regmap,
1426 MAX98396_R2044_PCM_TX_CTRL_1,
1427 val: max98396->v_slot);
1428 regmap_write(map: max98396->regmap,
1429 MAX98396_R2045_PCM_TX_CTRL_2,
1430 val: max98396->i_slot);
1431 regmap_write(map: max98396->regmap,
1432 MAX98396_R204A_PCM_TX_CTRL_7,
1433 val: max98396->spkfb_slot);
1434
1435 if (max98396->v_slot < 8)
1436 if (max98396->device_id == CODEC_TYPE_MAX98396)
1437 regmap_update_bits(map: max98396->regmap,
1438 MAX98396_R2053_PCM_TX_HIZ_CTRL_8,
1439 mask: 1 << max98396->v_slot, val: 0);
1440 else
1441 regmap_update_bits(map: max98396->regmap,
1442 MAX98397_R2054_PCM_TX_HIZ_CTRL_8,
1443 mask: 1 << max98396->v_slot, val: 0);
1444 else
1445 if (max98396->device_id == CODEC_TYPE_MAX98396)
1446 regmap_update_bits(map: max98396->regmap,
1447 MAX98396_R2052_PCM_TX_HIZ_CTRL_7,
1448 mask: 1 << (max98396->v_slot - 8), val: 0);
1449 else
1450 regmap_update_bits(map: max98396->regmap,
1451 MAX98397_R2053_PCM_TX_HIZ_CTRL_7,
1452 mask: 1 << (max98396->v_slot - 8), val: 0);
1453
1454 if (max98396->i_slot < 8)
1455 if (max98396->device_id == CODEC_TYPE_MAX98396)
1456 regmap_update_bits(map: max98396->regmap,
1457 MAX98396_R2053_PCM_TX_HIZ_CTRL_8,
1458 mask: 1 << max98396->i_slot, val: 0);
1459 else
1460 regmap_update_bits(map: max98396->regmap,
1461 MAX98397_R2054_PCM_TX_HIZ_CTRL_8,
1462 mask: 1 << max98396->i_slot, val: 0);
1463 else
1464 if (max98396->device_id == CODEC_TYPE_MAX98396)
1465 regmap_update_bits(map: max98396->regmap,
1466 MAX98396_R2052_PCM_TX_HIZ_CTRL_7,
1467 mask: 1 << (max98396->i_slot - 8), val: 0);
1468 else
1469 regmap_update_bits(map: max98396->regmap,
1470 MAX98397_R2053_PCM_TX_HIZ_CTRL_7,
1471 mask: 1 << (max98396->i_slot - 8), val: 0);
1472
1473 /* Set interleave mode */
1474 if (max98396->interleave_mode)
1475 regmap_update_bits(map: max98396->regmap,
1476 MAX98396_R2041_PCM_MODE_CFG,
1477 MAX98396_PCM_TX_CH_INTERLEAVE_MASK,
1478 MAX98396_PCM_TX_CH_INTERLEAVE_MASK);
1479
1480 regmap_update_bits(map: max98396->regmap,
1481 MAX98396_R2038_CLK_MON_CTRL,
1482 MAX98396_CLK_MON_AUTO_RESTART_MASK,
1483 MAX98396_CLK_MON_AUTO_RESTART_MASK);
1484
1485 regmap_update_bits(map: max98396->regmap,
1486 MAX98396_R203F_ENABLE_CTRLS,
1487 MAX98396_CTRL_DMON_STUCK_EN_MASK,
1488 val: max98396->dmon_stuck_enable ?
1489 MAX98396_CTRL_DMON_STUCK_EN_MASK : 0);
1490
1491 regmap_update_bits(map: max98396->regmap,
1492 MAX98396_R203F_ENABLE_CTRLS,
1493 MAX98396_CTRL_DMON_MAG_EN_MASK,
1494 val: max98396->dmon_mag_enable ?
1495 MAX98396_CTRL_DMON_MAG_EN_MASK : 0);
1496
1497 switch (max98396->dmon_duration) {
1498 case 64:
1499 regmap_update_bits(map: max98396->regmap,
1500 MAX98396_R2039_DATA_MON_CTRL,
1501 MAX98396_DMON_DURATION_MASK, val: 0);
1502 break;
1503 case 256:
1504 regmap_update_bits(map: max98396->regmap,
1505 MAX98396_R2039_DATA_MON_CTRL,
1506 MAX98396_DMON_DURATION_MASK, val: 1);
1507 break;
1508 case 1024:
1509 regmap_update_bits(map: max98396->regmap,
1510 MAX98396_R2039_DATA_MON_CTRL,
1511 MAX98396_DMON_DURATION_MASK, val: 2);
1512 break;
1513 case 4096:
1514 regmap_update_bits(map: max98396->regmap,
1515 MAX98396_R2039_DATA_MON_CTRL,
1516 MAX98396_DMON_DURATION_MASK, val: 3);
1517 break;
1518 default:
1519 dev_err(component->dev, "Invalid DMON duration %d\n",
1520 max98396->dmon_duration);
1521 }
1522
1523 switch (max98396->dmon_stuck_threshold) {
1524 case 15:
1525 regmap_update_bits(map: max98396->regmap,
1526 MAX98396_R2039_DATA_MON_CTRL,
1527 MAX98396_DMON_STUCK_THRESH_MASK,
1528 val: 0 << MAX98396_DMON_STUCK_THRESH_SHIFT);
1529 break;
1530 case 13:
1531 regmap_update_bits(map: max98396->regmap,
1532 MAX98396_R2039_DATA_MON_CTRL,
1533 MAX98396_DMON_STUCK_THRESH_MASK,
1534 val: 1 << MAX98396_DMON_STUCK_THRESH_SHIFT);
1535 break;
1536 case 22:
1537 regmap_update_bits(map: max98396->regmap,
1538 MAX98396_R2039_DATA_MON_CTRL,
1539 MAX98396_DMON_STUCK_THRESH_MASK,
1540 val: 2 << MAX98396_DMON_STUCK_THRESH_SHIFT);
1541 break;
1542 case 9:
1543 regmap_update_bits(map: max98396->regmap,
1544 MAX98396_R2039_DATA_MON_CTRL,
1545 MAX98396_DMON_STUCK_THRESH_MASK,
1546 val: 3 << MAX98396_DMON_STUCK_THRESH_SHIFT);
1547 break;
1548 default:
1549 dev_err(component->dev, "Invalid DMON stuck threshold %d\n",
1550 max98396->dmon_stuck_threshold);
1551 }
1552
1553 switch (max98396->dmon_mag_threshold) {
1554 case 2 ... 5:
1555 regmap_update_bits(map: max98396->regmap,
1556 MAX98396_R2039_DATA_MON_CTRL,
1557 MAX98396_DMON_STUCK_THRESH_MASK,
1558 val: (5 - max98396->dmon_mag_threshold)
1559 << MAX98396_DMON_MAG_THRESH_SHIFT);
1560 break;
1561 default:
1562 dev_err(component->dev, "Invalid DMON magnitude threshold %d\n",
1563 max98396->dmon_mag_threshold);
1564 }
1565
1566 /* Speaker Amplifier PCM RX Enable by default */
1567 regmap_update_bits(map: max98396->regmap,
1568 MAX98396_R205E_PCM_RX_EN,
1569 MAX98396_PCM_RX_EN_MASK, val: 1);
1570
1571 return 0;
1572}
1573
1574#ifdef CONFIG_PM_SLEEP
1575static int max98396_suspend(struct device *dev)
1576{
1577 struct max98396_priv *max98396 = dev_get_drvdata(dev);
1578
1579 regcache_cache_only(map: max98396->regmap, enable: true);
1580 regcache_mark_dirty(map: max98396->regmap);
1581 regulator_bulk_disable(MAX98396_NUM_CORE_SUPPLIES,
1582 consumers: max98396->core_supplies);
1583 if (max98396->pvdd)
1584 regulator_disable(regulator: max98396->pvdd);
1585
1586 if (max98396->vbat)
1587 regulator_disable(regulator: max98396->vbat);
1588
1589 return 0;
1590}
1591
1592static int max98396_resume(struct device *dev)
1593{
1594 struct max98396_priv *max98396 = dev_get_drvdata(dev);
1595 int ret;
1596
1597 ret = regulator_bulk_enable(MAX98396_NUM_CORE_SUPPLIES,
1598 consumers: max98396->core_supplies);
1599 if (ret < 0)
1600 return ret;
1601
1602 if (max98396->pvdd) {
1603 ret = regulator_enable(regulator: max98396->pvdd);
1604 if (ret < 0)
1605 return ret;
1606 }
1607
1608 if (max98396->vbat) {
1609 ret = regulator_enable(regulator: max98396->vbat);
1610 if (ret < 0)
1611 return ret;
1612 }
1613
1614 regcache_cache_only(map: max98396->regmap, enable: false);
1615 max98396_reset(max98396, dev);
1616 regcache_sync(map: max98396->regmap);
1617 return 0;
1618}
1619#endif
1620
1621static const struct dev_pm_ops max98396_pm = {
1622 SET_SYSTEM_SLEEP_PM_OPS(max98396_suspend, max98396_resume)
1623};
1624
1625static const struct snd_soc_component_driver soc_codec_dev_max98396 = {
1626 .probe = max98396_probe,
1627 .controls = max98396_snd_controls,
1628 .num_controls = ARRAY_SIZE(max98396_snd_controls),
1629 .dapm_widgets = max98396_dapm_widgets,
1630 .num_dapm_widgets = ARRAY_SIZE(max98396_dapm_widgets),
1631 .dapm_routes = max98396_audio_map,
1632 .num_dapm_routes = ARRAY_SIZE(max98396_audio_map),
1633 .idle_bias_on = 1,
1634 .use_pmdown_time = 1,
1635 .endianness = 1,
1636};
1637
1638static const struct snd_soc_component_driver soc_codec_dev_max98397 = {
1639 .probe = max98396_probe,
1640 .controls = max98397_snd_controls,
1641 .num_controls = ARRAY_SIZE(max98397_snd_controls),
1642 .dapm_widgets = max98396_dapm_widgets,
1643 .num_dapm_widgets = ARRAY_SIZE(max98396_dapm_widgets),
1644 .dapm_routes = max98396_audio_map,
1645 .num_dapm_routes = ARRAY_SIZE(max98396_audio_map),
1646 .idle_bias_on = 1,
1647 .use_pmdown_time = 1,
1648 .endianness = 1,
1649};
1650
1651static const struct regmap_config max98396_regmap = {
1652 .reg_bits = 16,
1653 .val_bits = 8,
1654 .max_register = MAX98396_R21FF_REVISION_ID,
1655 .reg_defaults = max98396_reg,
1656 .num_reg_defaults = ARRAY_SIZE(max98396_reg),
1657 .readable_reg = max98396_readable_register,
1658 .volatile_reg = max98396_volatile_reg,
1659 .cache_type = REGCACHE_RBTREE,
1660};
1661
1662static const struct regmap_config max98397_regmap = {
1663 .reg_bits = 16,
1664 .val_bits = 8,
1665 .max_register = MAX98397_R22FF_REVISION_ID,
1666 .reg_defaults = max98397_reg,
1667 .num_reg_defaults = ARRAY_SIZE(max98397_reg),
1668 .readable_reg = max98397_readable_register,
1669 .volatile_reg = max98397_volatile_reg,
1670 .cache_type = REGCACHE_RBTREE,
1671};
1672
1673static void max98396_read_device_property(struct device *dev,
1674 struct max98396_priv *max98396)
1675{
1676 int value;
1677
1678 if (!device_property_read_u32(dev, propname: "adi,vmon-slot-no", val: &value))
1679 max98396->v_slot = value & 0xF;
1680 else
1681 max98396->v_slot = 0;
1682
1683 if (!device_property_read_u32(dev, propname: "adi,imon-slot-no", val: &value))
1684 max98396->i_slot = value & 0xF;
1685 else
1686 max98396->i_slot = 1;
1687
1688 if (!device_property_read_u32(dev, propname: "adi,spkfb-slot-no", val: &value))
1689 max98396->spkfb_slot = value & 0xF;
1690 else
1691 max98396->spkfb_slot = 2;
1692
1693 if (!device_property_read_u32(dev, propname: "adi,bypass-slot-no", val: &value))
1694 max98396->bypass_slot = value & 0xF;
1695 else
1696 max98396->bypass_slot = 0;
1697
1698 max98396->dmon_stuck_enable =
1699 device_property_read_bool(dev, propname: "adi,dmon-stuck-enable");
1700
1701 if (!device_property_read_u32(dev, propname: "adi,dmon-stuck-threshold-bits", val: &value))
1702 max98396->dmon_stuck_threshold = value;
1703 else
1704 max98396->dmon_stuck_threshold = 15;
1705
1706 max98396->dmon_mag_enable =
1707 device_property_read_bool(dev, propname: "adi,dmon-magnitude-enable");
1708
1709 if (!device_property_read_u32(dev, propname: "adi,dmon-magnitude-threshold-bits", val: &value))
1710 max98396->dmon_mag_threshold = value;
1711 else
1712 max98396->dmon_mag_threshold = 5;
1713
1714 if (!device_property_read_u32(dev, propname: "adi,dmon-duration-ms", val: &value))
1715 max98396->dmon_duration = value;
1716 else
1717 max98396->dmon_duration = 64;
1718}
1719
1720static void max98396_core_supplies_disable(void *priv)
1721{
1722 struct max98396_priv *max98396 = priv;
1723
1724 regulator_bulk_disable(MAX98396_NUM_CORE_SUPPLIES,
1725 consumers: max98396->core_supplies);
1726}
1727
1728static void max98396_supply_disable(void *r)
1729{
1730 regulator_disable(regulator: (struct regulator *) r);
1731}
1732
1733static int max98396_i2c_probe(struct i2c_client *i2c)
1734{
1735 const struct i2c_device_id *id = i2c_client_get_device_id(client: i2c);
1736 struct max98396_priv *max98396 = NULL;
1737 int i, ret, reg;
1738
1739 max98396 = devm_kzalloc(dev: &i2c->dev, size: sizeof(*max98396), GFP_KERNEL);
1740
1741 if (!max98396) {
1742 ret = -ENOMEM;
1743 return ret;
1744 }
1745 i2c_set_clientdata(client: i2c, data: max98396);
1746
1747 max98396->device_id = id->driver_data;
1748
1749 /* regmap initialization */
1750 if (max98396->device_id == CODEC_TYPE_MAX98396)
1751 max98396->regmap = devm_regmap_init_i2c(i2c, &max98396_regmap);
1752
1753 else
1754 max98396->regmap = devm_regmap_init_i2c(i2c, &max98397_regmap);
1755
1756 if (IS_ERR(ptr: max98396->regmap)) {
1757 ret = PTR_ERR(ptr: max98396->regmap);
1758 dev_err(&i2c->dev,
1759 "Failed to allocate regmap: %d\n", ret);
1760 return ret;
1761 }
1762
1763 /* Obtain regulator supplies */
1764 for (i = 0; i < MAX98396_NUM_CORE_SUPPLIES; i++)
1765 max98396->core_supplies[i].supply = max98396_core_supplies[i];
1766
1767 ret = devm_regulator_bulk_get(dev: &i2c->dev, MAX98396_NUM_CORE_SUPPLIES,
1768 consumers: max98396->core_supplies);
1769 if (ret < 0) {
1770 dev_err(&i2c->dev, "Failed to request core supplies: %d\n", ret);
1771 return ret;
1772 }
1773
1774 max98396->vbat = devm_regulator_get_optional(dev: &i2c->dev, id: "vbat");
1775 if (IS_ERR(ptr: max98396->vbat)) {
1776 if (PTR_ERR(ptr: max98396->vbat) == -EPROBE_DEFER)
1777 return -EPROBE_DEFER;
1778
1779 max98396->vbat = NULL;
1780 }
1781
1782 max98396->pvdd = devm_regulator_get_optional(dev: &i2c->dev, id: "pvdd");
1783 if (IS_ERR(ptr: max98396->pvdd)) {
1784 if (PTR_ERR(ptr: max98396->pvdd) == -EPROBE_DEFER)
1785 return -EPROBE_DEFER;
1786
1787 max98396->pvdd = NULL;
1788 }
1789
1790 ret = regulator_bulk_enable(MAX98396_NUM_CORE_SUPPLIES,
1791 consumers: max98396->core_supplies);
1792 if (ret < 0) {
1793 dev_err(&i2c->dev, "Unable to enable core supplies: %d", ret);
1794 return ret;
1795 }
1796
1797 ret = devm_add_action_or_reset(&i2c->dev, max98396_core_supplies_disable,
1798 max98396);
1799 if (ret < 0)
1800 return ret;
1801
1802 if (max98396->pvdd) {
1803 ret = regulator_enable(regulator: max98396->pvdd);
1804 if (ret < 0)
1805 return ret;
1806
1807 ret = devm_add_action_or_reset(&i2c->dev,
1808 max98396_supply_disable,
1809 max98396->pvdd);
1810 if (ret < 0)
1811 return ret;
1812 }
1813
1814 if (max98396->vbat) {
1815 ret = regulator_enable(regulator: max98396->vbat);
1816 if (ret < 0)
1817 return ret;
1818
1819 ret = devm_add_action_or_reset(&i2c->dev,
1820 max98396_supply_disable,
1821 max98396->vbat);
1822 if (ret < 0)
1823 return ret;
1824 }
1825
1826 /* update interleave mode info */
1827 if (device_property_read_bool(dev: &i2c->dev, propname: "adi,interleave_mode"))
1828 max98396->interleave_mode = true;
1829 else
1830 max98396->interleave_mode = false;
1831
1832 /* voltage/current slot & gpio configuration */
1833 max98396_read_device_property(dev: &i2c->dev, max98396);
1834
1835 /* Reset the Device */
1836 max98396->reset_gpio = devm_gpiod_get_optional(dev: &i2c->dev,
1837 con_id: "reset", flags: GPIOD_OUT_HIGH);
1838 if (IS_ERR(ptr: max98396->reset_gpio)) {
1839 ret = PTR_ERR(ptr: max98396->reset_gpio);
1840 dev_err(&i2c->dev, "Unable to request GPIO pin: %d.\n", ret);
1841 return ret;
1842 }
1843
1844 if (max98396->reset_gpio) {
1845 usleep_range(min: 5000, max: 6000);
1846 gpiod_set_value_cansleep(desc: max98396->reset_gpio, value: 0);
1847 /* Wait for the hw reset done */
1848 usleep_range(min: 5000, max: 6000);
1849 }
1850
1851 ret = regmap_read(map: max98396->regmap,
1852 GET_REG_ADDR_REV_ID(max98396->device_id), val: &reg);
1853 if (ret < 0) {
1854 dev_err(&i2c->dev, "%s: failed to read revision of the device.\n", id->name);
1855 return ret;
1856 }
1857 dev_info(&i2c->dev, "%s revision ID: 0x%02X\n", id->name, reg);
1858
1859 /* codec registration */
1860 if (max98396->device_id == CODEC_TYPE_MAX98396)
1861 ret = devm_snd_soc_register_component(dev: &i2c->dev,
1862 component_driver: &soc_codec_dev_max98396,
1863 dai_drv: max98396_dai,
1864 ARRAY_SIZE(max98396_dai));
1865 else
1866 ret = devm_snd_soc_register_component(dev: &i2c->dev,
1867 component_driver: &soc_codec_dev_max98397,
1868 dai_drv: max98397_dai,
1869 ARRAY_SIZE(max98397_dai));
1870 if (ret < 0)
1871 dev_err(&i2c->dev, "Failed to register codec: %d\n", ret);
1872
1873 return ret;
1874}
1875
1876static const struct i2c_device_id max98396_i2c_id[] = {
1877 { "max98396", CODEC_TYPE_MAX98396},
1878 { "max98397", CODEC_TYPE_MAX98397},
1879 { },
1880};
1881
1882MODULE_DEVICE_TABLE(i2c, max98396_i2c_id);
1883
1884#if defined(CONFIG_OF)
1885static const struct of_device_id max98396_of_match[] = {
1886 { .compatible = "adi,max98396", },
1887 { .compatible = "adi,max98397", },
1888 { }
1889};
1890MODULE_DEVICE_TABLE(of, max98396_of_match);
1891#endif
1892
1893#ifdef CONFIG_ACPI
1894static const struct acpi_device_id max98396_acpi_match[] = {
1895 { "ADS8396", 0 },
1896 { "ADS8397", 0 },
1897 {},
1898};
1899MODULE_DEVICE_TABLE(acpi, max98396_acpi_match);
1900#endif
1901
1902static struct i2c_driver max98396_i2c_driver = {
1903 .driver = {
1904 .name = "max98396",
1905 .of_match_table = of_match_ptr(max98396_of_match),
1906 .acpi_match_table = ACPI_PTR(max98396_acpi_match),
1907 .pm = &max98396_pm,
1908 },
1909 .probe = max98396_i2c_probe,
1910 .id_table = max98396_i2c_id,
1911};
1912
1913module_i2c_driver(max98396_i2c_driver)
1914
1915MODULE_DESCRIPTION("ALSA SoC MAX98396 driver");
1916MODULE_AUTHOR("Ryan Lee <ryans.lee@analog.com>");
1917MODULE_LICENSE("GPL");
1918

source code of linux/sound/soc/codecs/max98396.c