xref: /linux/drivers/regulator/max77675-regulator.c (revision c17ee635fd3a482b2ad2bf5e269755c2eae5f25e)
1*9e92c559SJoan Na // SPDX-License-Identifier: GPL-2.0-or-later
2*9e92c559SJoan Na /*
3*9e92c559SJoan Na  * Copyright (c) 2025 Analog Devices, Inc.
4*9e92c559SJoan Na  * ADI regulator driver for MAX77675.
5*9e92c559SJoan Na  */
6*9e92c559SJoan Na 
7*9e92c559SJoan Na #include <linux/module.h>
8*9e92c559SJoan Na #include <linux/mod_devicetable.h>
9*9e92c559SJoan Na #include <linux/cleanup.h>
10*9e92c559SJoan Na #include <linux/slab.h>
11*9e92c559SJoan Na #include <linux/of.h>
12*9e92c559SJoan Na #include <linux/i2c.h>
13*9e92c559SJoan Na #include <linux/regmap.h>
14*9e92c559SJoan Na #include <linux/platform_device.h>
15*9e92c559SJoan Na #include <linux/regulator/driver.h>
16*9e92c559SJoan Na #include <linux/regulator/consumer.h>
17*9e92c559SJoan Na #include <linux/regulator/of_regulator.h>
18*9e92c559SJoan Na #include <linux/bitfield.h>
19*9e92c559SJoan Na #include <linux/bitops.h>
20*9e92c559SJoan Na 
21*9e92c559SJoan Na /* Register Addresses */
22*9e92c559SJoan Na #define MAX77675_REG_CNFG_GLBL_A     0x00
23*9e92c559SJoan Na #define MAX77675_REG_CNFG_GLBL_B     0x01
24*9e92c559SJoan Na #define MAX77675_REG_INT_GLBL        0x02
25*9e92c559SJoan Na #define MAX77675_REG_INTM_GLBL       0x03
26*9e92c559SJoan Na #define MAX77675_REG_STAT_GLBL       0x04
27*9e92c559SJoan Na #define MAX77675_REG_ERCF_GLBL       0x05
28*9e92c559SJoan Na #define MAX77675_REG_CID             0x06
29*9e92c559SJoan Na #define MAX77675_REG_CNFG_SBB_TOP_A  0x07
30*9e92c559SJoan Na #define MAX77675_REG_CNFG_SBB0_A     0x08
31*9e92c559SJoan Na #define MAX77675_REG_CNFG_SBB0_B     0x09
32*9e92c559SJoan Na #define MAX77675_REG_CNFG_SBB1_A     0x0A
33*9e92c559SJoan Na #define MAX77675_REG_CNFG_SBB1_B     0x0B
34*9e92c559SJoan Na #define MAX77675_REG_CNFG_SBB2_A     0x0C
35*9e92c559SJoan Na #define MAX77675_REG_CNFG_SBB2_B     0x0D
36*9e92c559SJoan Na #define MAX77675_REG_CNFG_SBB3_A     0x0E
37*9e92c559SJoan Na #define MAX77675_REG_CNFG_SBB3_B     0x0F
38*9e92c559SJoan Na #define MAX77675_REG_CNFG_SBB_TOP_B  0x10
39*9e92c559SJoan Na 
40*9e92c559SJoan Na /* CNFG_GLBL_A (0x00) bit masks and shifts */
41*9e92c559SJoan Na #define MAX77675_MRT_MASK           GENMASK(7, 6)    /* Manual Reset Time (bits 7:6) */
42*9e92c559SJoan Na #define MAX77675_MRT_SHIFT          6
43*9e92c559SJoan Na #define MAX77675_PU_DIS_BIT         BIT(5)           /* Pullup Disable (bit 5) */
44*9e92c559SJoan Na #define MAX77675_PU_DIS_SHIFT       5
45*9e92c559SJoan Na #define MAX77675_BIAS_LPM_BIT       BIT(4)           /* Bias Low Power Mode (bit 4) */
46*9e92c559SJoan Na #define MAX77675_BIAS_LPM_SHIFT     4
47*9e92c559SJoan Na #define MAX77675_SIMO_CH_DIS_BIT    BIT(3)           /* SIMO Internal Channel Disable (bit 3) */
48*9e92c559SJoan Na #define MAX77675_SIMO_CH_DIS_SHIFT  3
49*9e92c559SJoan Na #define MAX77675_EN_MODE_MASK       GENMASK(2, 1)    /* nEN Mode (bits 2:1) */
50*9e92c559SJoan Na #define MAX77675_EN_MODE_SHIFT      1
51*9e92c559SJoan Na #define MAX77675_DBEN_EN_BIT        BIT(0)           /* Debounce Enable (bit 0) */
52*9e92c559SJoan Na #define MAX77675_DBEN_EN_SHIFT      0
53*9e92c559SJoan Na 
54*9e92c559SJoan Na /* CNFG_GLBL_B (0x01) */
55*9e92c559SJoan Na #define MAX77675_SFT_CTRL_MASK      GENMASK(2, 0)    /* Soft Start Control */
56*9e92c559SJoan Na #define MAX77675_SFT_CTRL_SHIFT     0
57*9e92c559SJoan Na 
58*9e92c559SJoan Na /* INT_GLBL (0x02) bit bits and shifts */
59*9e92c559SJoan Na #define MAX77675_INT_SBB3_F_BIT     BIT(7)
60*9e92c559SJoan Na #define MAX77675_INT_SBB3_F_SHIFT   7
61*9e92c559SJoan Na #define MAX77675_INT_SBB2_F_BIT     BIT(6)
62*9e92c559SJoan Na #define MAX77675_INT_SBB2_F_SHIFT   6
63*9e92c559SJoan Na #define MAX77675_INT_SBB1_F_BIT     BIT(5)
64*9e92c559SJoan Na #define MAX77675_INT_SBB1_F_SHIFT   5
65*9e92c559SJoan Na #define MAX77675_INT_SBB0_F_BIT     BIT(4)
66*9e92c559SJoan Na #define MAX77675_INT_SBB0_F_SHIFT   4
67*9e92c559SJoan Na #define MAX77675_INT_TJAL2_R_BIT    BIT(3)
68*9e92c559SJoan Na #define MAX77675_INT_TJAL2_R_SHIFT  3
69*9e92c559SJoan Na #define MAX77675_INT_TJAL1_R_BIT    BIT(2)
70*9e92c559SJoan Na #define MAX77675_INT_TJAL1_R_SHIFT  2
71*9e92c559SJoan Na #define MAX77675_INT_EN_R_BIT       BIT(1)
72*9e92c559SJoan Na #define MAX77675_INT_EN_R_SHIFT     1
73*9e92c559SJoan Na #define MAX77675_INT_EN_F_BIT       BIT(0)
74*9e92c559SJoan Na #define MAX77675_INT_EN_F_SHIFT     0
75*9e92c559SJoan Na 
76*9e92c559SJoan Na /* INTM_GLBL (0x03) bits and shifts */
77*9e92c559SJoan Na #define MAX77675_INTM_SBB3_F_BIT    BIT(7)
78*9e92c559SJoan Na #define MAX77675_INTM_SBB3_F_SHIFT  7
79*9e92c559SJoan Na #define MAX77675_INTM_SBB2_F_BIT    BIT(6)
80*9e92c559SJoan Na #define MAX77675_INTM_SBB2_F_SHIFT  6
81*9e92c559SJoan Na #define MAX77675_INTM_SBB1_F_BIT    BIT(5)
82*9e92c559SJoan Na #define MAX77675_INTM_SBB1_F_SHIFT  5
83*9e92c559SJoan Na #define MAX77675_INTM_SBB0_F_BIT    BIT(4)
84*9e92c559SJoan Na #define MAX77675_INTM_SBB0_F_SHIFT  4
85*9e92c559SJoan Na #define MAX77675_INTM_TJAL2_R_BIT   BIT(3)
86*9e92c559SJoan Na #define MAX77675_INTM_TJAL2_R_SHIFT 3
87*9e92c559SJoan Na #define MAX77675_INTM_TJAL1_R_BIT   BIT(2)
88*9e92c559SJoan Na #define MAX77675_INTM_TJAL1_R_SHIFT 2
89*9e92c559SJoan Na #define MAX77675_INTM_EN_R_BIT      BIT(1)
90*9e92c559SJoan Na #define MAX77675_INTM_EN_R_SHIFT    1
91*9e92c559SJoan Na #define MAX77675_INTM_EN_F_BIT      BIT(0)
92*9e92c559SJoan Na #define MAX77675_INTM_EN_F_SHIFT    0
93*9e92c559SJoan Na 
94*9e92c559SJoan Na /* STAT_GLBL (0x04) bits and shifts */
95*9e92c559SJoan Na #define MAX77675_STAT_SBB3_S_BIT    BIT(7)
96*9e92c559SJoan Na #define MAX77675_STAT_SBB3_S_SHIFT  7
97*9e92c559SJoan Na #define MAX77675_STAT_SBB2_S_BIT    BIT(6)
98*9e92c559SJoan Na #define MAX77675_STAT_SBB2_S_SHIFT  6
99*9e92c559SJoan Na #define MAX77675_STAT_SBB1_S_BIT    BIT(5)
100*9e92c559SJoan Na #define MAX77675_STAT_SBB1_S_SHIFT  5
101*9e92c559SJoan Na #define MAX77675_STAT_SBB0_S_BIT    BIT(4)
102*9e92c559SJoan Na #define MAX77675_STAT_SBB0_S_SHIFT  4
103*9e92c559SJoan Na #define MAX77675_STAT_TJAL2_S_BIT   BIT(2)
104*9e92c559SJoan Na #define MAX77675_STAT_TJAL2_S_SHIFT 2
105*9e92c559SJoan Na #define MAX77675_STAT_TJAL1_S_BIT   BIT(1)
106*9e92c559SJoan Na #define MAX77675_STAT_TJAL1_S_SHIFT 1
107*9e92c559SJoan Na #define MAX77675_STAT_STAT_EN_BIT   BIT(0)
108*9e92c559SJoan Na #define MAX77675_STAT_STAT_EN_SHIFT 0
109*9e92c559SJoan Na 
110*9e92c559SJoan Na #define MAX77675_STAT_STAT_EN_BIT   BIT(0)
111*9e92c559SJoan Na #define MAX77675_STAT_STAT_EN_SHIFT 0
112*9e92c559SJoan Na 
113*9e92c559SJoan Na /* ERCFLAG (0x05) bits and shifts */
114*9e92c559SJoan Na #define MAX77675_SFT_CRST_F_BIT     BIT(5)  /* Software Cold Reset Flag */
115*9e92c559SJoan Na #define MAX77675_SFT_CRST_F_SHIFT   5
116*9e92c559SJoan Na #define MAX77675_SFT_OFF_F_BIT      BIT(4)  /* Software Off Flag */
117*9e92c559SJoan Na #define MAX77675_SFT_OFF_F_SHIFT    4
118*9e92c559SJoan Na #define MAX77675_MRST_BIT           BIT(3)  /* Manual Reset Timer Flag */
119*9e92c559SJoan Na #define MAX77675_MRST_SHIFT         3
120*9e92c559SJoan Na #define MAX77675_UVLO_BIT           BIT(2)  /* Undervoltage Lockout Flag */
121*9e92c559SJoan Na #define MAX77675_UVLO_SHIFT         2
122*9e92c559SJoan Na #define MAX77675_OVLO_BIT           BIT(1)  /* Overvoltage Lockout Flag */
123*9e92c559SJoan Na #define MAX77675_OVLO_SHIFT         1
124*9e92c559SJoan Na #define MAX77675_TOVLD_BIT          BIT(0)  /* Thermal Overload Flag */
125*9e92c559SJoan Na #define MAX77675_TOVLD_SHIFT        0
126*9e92c559SJoan Na 
127*9e92c559SJoan Na /* CID (0x06) bits and shifts */
128*9e92c559SJoan Na #define MAX77675_CID_MASK           GENMASK(4, 0)  /* Chip Identification Code mask */
129*9e92c559SJoan Na #define MAX77675_CID_SHIFT          0              /* Starts at bit 0 */
130*9e92c559SJoan Na 
131*9e92c559SJoan Na /* CNFG_SBB_TOP_A (0x07) bits and shifts */
132*9e92c559SJoan Na #define MAX77675_STEP_SZ_SBB3_BIT   BIT(5)
133*9e92c559SJoan Na #define MAX77675_STEP_SZ_SBB3_SHIFT 5
134*9e92c559SJoan Na #define MAX77675_STEP_SZ_SBB2_BIT   BIT(4)
135*9e92c559SJoan Na #define MAX77675_STEP_SZ_SBB2_SHIFT 4
136*9e92c559SJoan Na #define MAX77675_STEP_SZ_SBB1_BIT   BIT(3)
137*9e92c559SJoan Na #define MAX77675_STEP_SZ_SBB1_SHIFT 3
138*9e92c559SJoan Na #define MAX77675_STEP_SZ_SBB0_BIT   BIT(2)
139*9e92c559SJoan Na #define MAX77675_STEP_SZ_SBB0_SHIFT 2
140*9e92c559SJoan Na #define MAX77675_DRV_SBB_MASK       GENMASK(1, 0)
141*9e92c559SJoan Na #define MAX77675_DRV_SBB_SHIFT      0
142*9e92c559SJoan Na 
143*9e92c559SJoan Na /* CNFG_SBB0_A (0x08) bits and shifts */
144*9e92c559SJoan Na #define MAX77675_TV_SBB0_MASK       GENMASK(7, 0)
145*9e92c559SJoan Na #define MAX77675_TV_SBB0_SHIFT      0
146*9e92c559SJoan Na 
147*9e92c559SJoan Na /* CNFG_SBB0_B (0x09) bits and shifts */
148*9e92c559SJoan Na #define MAX77675_ADE_SBB0_BIT       BIT(3)
149*9e92c559SJoan Na #define MAX77675_ADE_SBB0_SHIFT     3
150*9e92c559SJoan Na #define MAX77675_EN_SBB0_MASK       GENMASK(2, 0)
151*9e92c559SJoan Na #define MAX77675_EN_SBB0_SHIFT      0
152*9e92c559SJoan Na 
153*9e92c559SJoan Na /* CNFG_SBB1_A (0x0A) bits and shifts */
154*9e92c559SJoan Na #define MAX77675_TV_SBB1_MASK       GENMASK(7, 0)
155*9e92c559SJoan Na #define MAX77675_TV_SBB1_SHIFT      0
156*9e92c559SJoan Na 
157*9e92c559SJoan Na /* CNFG_SBB1_B (0x0B) bits and shifts */
158*9e92c559SJoan Na #define MAX77675_ADE_SBB1_BIT       BIT(3)
159*9e92c559SJoan Na #define MAX77675_ADE_SBB1_SHIFT     3
160*9e92c559SJoan Na #define MAX77675_EN_SBB1_MASK       GENMASK(2, 0)
161*9e92c559SJoan Na #define MAX77675_EN_SBB1_SHIFT      0
162*9e92c559SJoan Na 
163*9e92c559SJoan Na /* CNFG_SBB2_A (0x0C) bits and shifts */
164*9e92c559SJoan Na #define MAX77675_TV_SBB2_MASK       GENMASK(7, 0)
165*9e92c559SJoan Na #define MAX77675_TV_SBB2_SHIFT      0
166*9e92c559SJoan Na 
167*9e92c559SJoan Na /* CNFG_SBB2_B (0x0D) bits and shifts */
168*9e92c559SJoan Na #define MAX77675_ADE_SBB2_BIT       BIT(3)
169*9e92c559SJoan Na #define MAX77675_ADE_SBB2_SHIFT     3
170*9e92c559SJoan Na #define MAX77675_EN_SBB2_MASK       GENMASK(2, 0)
171*9e92c559SJoan Na #define MAX77675_EN_SBB2_SHIFT      0
172*9e92c559SJoan Na 
173*9e92c559SJoan Na /* CNFG_SBB3_A (0x0E) bits and shifts */
174*9e92c559SJoan Na #define MAX77675_TV_SBB3_MASK       GENMASK(7, 0)
175*9e92c559SJoan Na #define MAX77675_TV_SBB3_SHIFT      0
176*9e92c559SJoan Na 
177*9e92c559SJoan Na /* CNFG_SBB3_B (0x0F) bits and shifts */
178*9e92c559SJoan Na #define MAX77675_ADE_SBB3_BIT       BIT(3)
179*9e92c559SJoan Na #define MAX77675_ADE_SBB3_SHIFT     3
180*9e92c559SJoan Na #define MAX77675_EN_SBB3_MASK       GENMASK(2, 0)
181*9e92c559SJoan Na #define MAX77675_EN_SBB3_SHIFT      0
182*9e92c559SJoan Na 
183*9e92c559SJoan Na #define MAX77675_EN_SBB_MASK        GENMASK(2, 0)
184*9e92c559SJoan Na 
185*9e92c559SJoan Na /* CNFG_SBB_TOP_B (0x10) bits and shifts */
186*9e92c559SJoan Na #define MAX77675_DVS_SLEW_BIT       BIT(5)
187*9e92c559SJoan Na #define MAX77675_DVS_SLEW_SHIFT     5
188*9e92c559SJoan Na #define MAX77675_LAT_MODE_BIT       BIT(4)
189*9e92c559SJoan Na #define MAX77675_LAT_MODE_SHIFT     4
190*9e92c559SJoan Na #define MAX77675_SR_SBB3_BIT        BIT(3)
191*9e92c559SJoan Na #define MAX77675_SR_SBB3_SHIFT      3
192*9e92c559SJoan Na #define MAX77675_SR_SBB2_BIT        BIT(2)
193*9e92c559SJoan Na #define MAX77675_SR_SBB2_SHIFT      2
194*9e92c559SJoan Na #define MAX77675_SR_SBB1_BIT        BIT(1)
195*9e92c559SJoan Na #define MAX77675_SR_SBB1_SHIFT      1
196*9e92c559SJoan Na #define MAX77675_SR_SBB0_BIT        BIT(0)
197*9e92c559SJoan Na #define MAX77675_SR_SBB0_SHIFT      0
198*9e92c559SJoan Na 
199*9e92c559SJoan Na #define MAX77675_MAX_REGISTER       0x10
200*9e92c559SJoan Na 
201*9e92c559SJoan Na /* Common minimum voltage (in microvolts) */
202*9e92c559SJoan Na #define MAX77675_MIN_UV             500000     // 500 mV
203*9e92c559SJoan Na 
204*9e92c559SJoan Na /* Voltage step configuration for 25mV mode */
205*9e92c559SJoan Na #define MAX77675_STEP_25MV          25000      // Step size: 25 mV
206*9e92c559SJoan Na #define MAX77675_MAX_UV_25MV        5500000    // Max voltage: 5.5 V
207*9e92c559SJoan Na #define MAX77675_NUM_LEVELS_25MV    201        // levels = (5500mV - 500mV) / 25mV + 1
208*9e92c559SJoan Na 
209*9e92c559SJoan Na /* Voltage step configuration for 12.5mV mode */
210*9e92c559SJoan Na #define MAX77675_STEP_12_5MV        12500      // Step size: 12.5 mV
211*9e92c559SJoan Na #define MAX77675_MAX_UV_12_5MV      3687500    // Max voltage: 3.6875 V
212*9e92c559SJoan Na #define MAX77675_NUM_LEVELS_12_5MV  255        // levels = (3687.5mV - 500mV) / 12.5mV + 1
213*9e92c559SJoan Na 
214*9e92c559SJoan Na #define MAX77675_ENABLE_OFF         0x04
215*9e92c559SJoan Na #define MAX77675_ENABLE_ON          0x06
216*9e92c559SJoan Na 
217*9e92c559SJoan Na #define MAX77675_REGULATOR_AD_OFF   0x00
218*9e92c559SJoan Na #define MAX77675_REGULATOR_AD_ON    BIT(3)
219*9e92c559SJoan Na 
220*9e92c559SJoan Na /* FPS source */
221*9e92c559SJoan Na #define MAX77675_FPS_SLOT_0         0x0
222*9e92c559SJoan Na #define MAX77675_FPS_SLOT_1         0x1
223*9e92c559SJoan Na #define MAX77675_FPS_SLOT_2         0x2
224*9e92c559SJoan Na #define MAX77675_FPS_SLOT_3         0x3
225*9e92c559SJoan Na #define MAX77675_FPS_DEF            0x4
226*9e92c559SJoan Na 
227*9e92c559SJoan Na /* nEN Manual Reset Time Configuration (MRT) */
228*9e92c559SJoan Na #define MAX77675_MRT_4S             0x0
229*9e92c559SJoan Na #define MAX77675_MRT_8S             0x1
230*9e92c559SJoan Na #define MAX77675_MRT_12S            0x2
231*9e92c559SJoan Na #define MAX77675_MRT_16S            0x3
232*9e92c559SJoan Na 
233*9e92c559SJoan Na /* nEN Mode Configuration */
234*9e92c559SJoan Na #define MAX77675_EN_PUSH_BUTTON     0x0
235*9e92c559SJoan Na #define MAX77675_EN_SLIDE_SWITCH    0x1
236*9e92c559SJoan Na #define MAX77675_EN_LOGIC           0x2
237*9e92c559SJoan Na 
238*9e92c559SJoan Na /* Debounce Timer Enable (DBEN_nEN) */
239*9e92c559SJoan Na #define MAX77675_DBEN_100US         0x0
240*9e92c559SJoan Na #define MAX77675_DBEN_30000US       0x1
241*9e92c559SJoan Na 
242*9e92c559SJoan Na /* Rising slew rate control for SBB0 when ramping up */
243*9e92c559SJoan Na #define MAX77675_SR_2MV_PER_US      0x0  // 2 mV/us
244*9e92c559SJoan Na #define MAX77675_SR_USE_DVS         0x1  // Use DVS slew rate setting (adi,dvs-slew-rate)
245*9e92c559SJoan Na 
246*9e92c559SJoan Na /* Latency Mode */
247*9e92c559SJoan Na #define MAX77675_HIGH_LATENCY_MODE  0x0   // High latency, low quiescent current (~100us)
248*9e92c559SJoan Na #define MAX77675_LOW_LATENCY_MODE   0x1   // Low latency, high quiescent current (~10us)
249*9e92c559SJoan Na 
250*9e92c559SJoan Na /* Dynamic Voltage Scaling (DVS) Slew Rate */
251*9e92c559SJoan Na #define MAX77675_DVS_SLEW_5MV_PER_US   0x0  // 5 mV/us
252*9e92c559SJoan Na #define MAX77675_DVS_SLEW_10MV_PER_US  0x1  // 10 mV/us
253*9e92c559SJoan Na 
254*9e92c559SJoan Na /* SIMO Buck-Boost Drive Strength (All Channels) */
255*9e92c559SJoan Na #define MAX77675_DRV_SBB_STRENGTH_MAX  0x0  // Maximum drive strength (~0.6 ns transition time)
256*9e92c559SJoan Na #define MAX77675_DRV_SBB_STRENGTH_HIGH 0x1  // High drive strength (~1.2 ns transition time)
257*9e92c559SJoan Na #define MAX77675_DRV_SBB_STRENGTH_LOW  0x2  // Low drive strength (~1.8 ns transition time)
258*9e92c559SJoan Na #define MAX77675_DRV_SBB_STRENGTH_MIN  0x3  // Minimum drive strength (~8 ns transition time)
259*9e92c559SJoan Na 
260*9e92c559SJoan Na /* Regulator ID enumeration */
261*9e92c559SJoan Na enum max77675_regulator_id {
262*9e92c559SJoan Na 	MAX77675_ID_SBB0 = 0,
263*9e92c559SJoan Na 	MAX77675_ID_SBB1,
264*9e92c559SJoan Na 	MAX77675_ID_SBB2,
265*9e92c559SJoan Na 	MAX77675_ID_SBB3,
266*9e92c559SJoan Na 	MAX77675_ID_NUM_MAX,
267*9e92c559SJoan Na };
268*9e92c559SJoan Na 
269*9e92c559SJoan Na struct max77675_regulator_sbb_setting {
270*9e92c559SJoan Na 	u8   fps_slot;
271*9e92c559SJoan Na 	bool fixed_slew_rate;
272*9e92c559SJoan Na };
273*9e92c559SJoan Na 
274*9e92c559SJoan Na struct max77675_config {
275*9e92c559SJoan Na 	u8   en_mode;
276*9e92c559SJoan Na 	u8   voltage_change_latency;
277*9e92c559SJoan Na 	u8   drv_sbb_strength;
278*9e92c559SJoan Na 	u8   dvs_slew_rate;
279*9e92c559SJoan Na 	u8   debounce_time;
280*9e92c559SJoan Na 	u8   manual_reset_time;
281*9e92c559SJoan Na 	bool en_pullup_disable;
282*9e92c559SJoan Na 	bool bias_low_power_request;
283*9e92c559SJoan Na 	bool simo_ldo_always_on;
284*9e92c559SJoan Na };
285*9e92c559SJoan Na 
286*9e92c559SJoan Na struct max77675_regulator {
287*9e92c559SJoan Na 	struct device *dev;
288*9e92c559SJoan Na 	struct regmap *regmap;
289*9e92c559SJoan Na 	struct max77675_config config;
290*9e92c559SJoan Na 	struct max77675_regulator_sbb_setting sbb_setting[MAX77675_ID_NUM_MAX];
291*9e92c559SJoan Na };
292*9e92c559SJoan Na 
293*9e92c559SJoan Na static int max77675_regulator_get_fps_src(struct max77675_regulator *maxreg, int id)
294*9e92c559SJoan Na {
295*9e92c559SJoan Na 	unsigned int reg_addr;
296*9e92c559SJoan Na 	unsigned int val;
297*9e92c559SJoan Na 	int ret;
298*9e92c559SJoan Na 
299*9e92c559SJoan Na 	switch (id) {
300*9e92c559SJoan Na 	case MAX77675_ID_SBB0:
301*9e92c559SJoan Na 		reg_addr = MAX77675_REG_CNFG_SBB0_B;
302*9e92c559SJoan Na 		break;
303*9e92c559SJoan Na 	case MAX77675_ID_SBB1:
304*9e92c559SJoan Na 		reg_addr = MAX77675_REG_CNFG_SBB1_B;
305*9e92c559SJoan Na 		break;
306*9e92c559SJoan Na 	case MAX77675_ID_SBB2:
307*9e92c559SJoan Na 		reg_addr = MAX77675_REG_CNFG_SBB2_B;
308*9e92c559SJoan Na 		break;
309*9e92c559SJoan Na 	case MAX77675_ID_SBB3:
310*9e92c559SJoan Na 		reg_addr = MAX77675_REG_CNFG_SBB3_B;
311*9e92c559SJoan Na 		break;
312*9e92c559SJoan Na 	default:
313*9e92c559SJoan Na 		dev_err(maxreg->dev, "Invalid regulator id: %d\n", id);
314*9e92c559SJoan Na 		return -EINVAL;
315*9e92c559SJoan Na 	}
316*9e92c559SJoan Na 
317*9e92c559SJoan Na 	ret = regmap_read(maxreg->regmap, reg_addr, &val);
318*9e92c559SJoan Na 	if (ret < 0) {
319*9e92c559SJoan Na 		dev_err(maxreg->dev, "Failed to read FPS source (reg 0x%02x): %d\n",
320*9e92c559SJoan Na 			reg_addr, ret);
321*9e92c559SJoan Na 		return ret;
322*9e92c559SJoan Na 	}
323*9e92c559SJoan Na 
324*9e92c559SJoan Na 	return FIELD_GET(MAX77675_EN_SBB_MASK, val);
325*9e92c559SJoan Na }
326*9e92c559SJoan Na 
327*9e92c559SJoan Na static int max77675_regulator_set_fps_src(struct max77675_regulator *maxreg, int id, u8 fps_src)
328*9e92c559SJoan Na {
329*9e92c559SJoan Na 	unsigned int reg_addr;
330*9e92c559SJoan Na 
331*9e92c559SJoan Na 	switch (id) {
332*9e92c559SJoan Na 	case MAX77675_ID_SBB0:
333*9e92c559SJoan Na 		reg_addr = MAX77675_REG_CNFG_SBB0_B;
334*9e92c559SJoan Na 		break;
335*9e92c559SJoan Na 	case MAX77675_ID_SBB1:
336*9e92c559SJoan Na 		reg_addr = MAX77675_REG_CNFG_SBB1_B;
337*9e92c559SJoan Na 		break;
338*9e92c559SJoan Na 	case MAX77675_ID_SBB2:
339*9e92c559SJoan Na 		reg_addr = MAX77675_REG_CNFG_SBB2_B;
340*9e92c559SJoan Na 		break;
341*9e92c559SJoan Na 	case MAX77675_ID_SBB3:
342*9e92c559SJoan Na 		reg_addr = MAX77675_REG_CNFG_SBB3_B;
343*9e92c559SJoan Na 		break;
344*9e92c559SJoan Na 	default:
345*9e92c559SJoan Na 		dev_err(maxreg->dev, "Invalid regulator id: %d\n", id);
346*9e92c559SJoan Na 		return -EINVAL;
347*9e92c559SJoan Na 	}
348*9e92c559SJoan Na 
349*9e92c559SJoan Na 	return regmap_update_bits(maxreg->regmap, reg_addr, MAX77675_EN_SBB_MASK, fps_src);
350*9e92c559SJoan Na }
351*9e92c559SJoan Na 
352*9e92c559SJoan Na static int max77675_set_sbb_slew_rate_fixed(struct max77675_regulator *maxreg, int id, bool fixed)
353*9e92c559SJoan Na {
354*9e92c559SJoan Na 	u8 mask, value;
355*9e92c559SJoan Na 	u8 slew_src_ctrl_bit = fixed ? 0 : 1;
356*9e92c559SJoan Na 
357*9e92c559SJoan Na 	switch (id) {
358*9e92c559SJoan Na 	case MAX77675_ID_SBB0:
359*9e92c559SJoan Na 		mask = MAX77675_SR_SBB0_BIT;
360*9e92c559SJoan Na 		value = FIELD_PREP(MAX77675_SR_SBB0_BIT, slew_src_ctrl_bit);
361*9e92c559SJoan Na 		break;
362*9e92c559SJoan Na 
363*9e92c559SJoan Na 	case MAX77675_ID_SBB1:
364*9e92c559SJoan Na 		mask = MAX77675_SR_SBB1_BIT;
365*9e92c559SJoan Na 		value = FIELD_PREP(MAX77675_SR_SBB1_BIT, slew_src_ctrl_bit);
366*9e92c559SJoan Na 		break;
367*9e92c559SJoan Na 
368*9e92c559SJoan Na 	case MAX77675_ID_SBB2:
369*9e92c559SJoan Na 		mask = MAX77675_SR_SBB2_BIT;
370*9e92c559SJoan Na 		value = FIELD_PREP(MAX77675_SR_SBB2_BIT, slew_src_ctrl_bit);
371*9e92c559SJoan Na 		break;
372*9e92c559SJoan Na 
373*9e92c559SJoan Na 	case MAX77675_ID_SBB3:
374*9e92c559SJoan Na 		mask = MAX77675_SR_SBB3_BIT;
375*9e92c559SJoan Na 		value = FIELD_PREP(MAX77675_SR_SBB3_BIT, slew_src_ctrl_bit);
376*9e92c559SJoan Na 		break;
377*9e92c559SJoan Na 
378*9e92c559SJoan Na 	default:
379*9e92c559SJoan Na 		return -EINVAL;
380*9e92c559SJoan Na 	}
381*9e92c559SJoan Na 
382*9e92c559SJoan Na 	return regmap_update_bits(maxreg->regmap, MAX77675_REG_CNFG_SBB_TOP_B, mask, value);
383*9e92c559SJoan Na }
384*9e92c559SJoan Na 
385*9e92c559SJoan Na static int max77675_init_regulator(struct max77675_regulator *maxreg, int id)
386*9e92c559SJoan Na {
387*9e92c559SJoan Na 	struct max77675_regulator_sbb_setting *sbb_setting = &maxreg->sbb_setting[id];
388*9e92c559SJoan Na 	int ret;
389*9e92c559SJoan Na 
390*9e92c559SJoan Na 	if (sbb_setting->fps_slot == MAX77675_FPS_DEF) {
391*9e92c559SJoan Na 		ret = max77675_regulator_get_fps_src(maxreg, id);
392*9e92c559SJoan Na 		if (ret < 0)
393*9e92c559SJoan Na 			return ret;
394*9e92c559SJoan Na 
395*9e92c559SJoan Na 		sbb_setting->fps_slot = ret;
396*9e92c559SJoan Na 	} else {
397*9e92c559SJoan Na 		ret = max77675_regulator_set_fps_src(maxreg, id, sbb_setting->fps_slot);
398*9e92c559SJoan Na 		if (ret < 0)
399*9e92c559SJoan Na 			return ret;
400*9e92c559SJoan Na 	}
401*9e92c559SJoan Na 
402*9e92c559SJoan Na 	ret = max77675_set_sbb_slew_rate_fixed(maxreg, id, sbb_setting->fixed_slew_rate);
403*9e92c559SJoan Na 	if (ret < 0)
404*9e92c559SJoan Na 		return ret;
405*9e92c559SJoan Na 
406*9e92c559SJoan Na 	return 0;
407*9e92c559SJoan Na }
408*9e92c559SJoan Na 
409*9e92c559SJoan Na static int max77675_of_parse_cb(struct device_node *np,
410*9e92c559SJoan Na 				const struct regulator_desc *desc,
411*9e92c559SJoan Na 				struct regulator_config *config)
412*9e92c559SJoan Na {
413*9e92c559SJoan Na 	struct max77675_regulator *maxreg = config->driver_data;
414*9e92c559SJoan Na 	struct max77675_regulator_sbb_setting *sbb_setting = &maxreg->sbb_setting[desc->id];
415*9e92c559SJoan Na 	static const char * const fps_slots[] = { "slot0", "slot1", "slot2", "slot3", "default" };
416*9e92c559SJoan Na 	const char *fps_str;
417*9e92c559SJoan Na 	int slot;
418*9e92c559SJoan Na 
419*9e92c559SJoan Na 	/* Parse FPS slot from DT */
420*9e92c559SJoan Na 	if (of_property_read_string(np, "adi,fps-slot", &fps_str)) {
421*9e92c559SJoan Na 		/* Property not set, use default */
422*9e92c559SJoan Na 		sbb_setting->fps_slot = MAX77675_FPS_DEF;
423*9e92c559SJoan Na 	} else {
424*9e92c559SJoan Na 		/* Match string to index */
425*9e92c559SJoan Na 		slot = match_string(fps_slots, ARRAY_SIZE(fps_slots), fps_str);
426*9e92c559SJoan Na 		if (slot < 0) {
427*9e92c559SJoan Na 			dev_dbg(maxreg->dev, "Invalid fps-slot '%s', using default\n", fps_str);
428*9e92c559SJoan Na 			sbb_setting->fps_slot = MAX77675_FPS_DEF;
429*9e92c559SJoan Na 		} else {
430*9e92c559SJoan Na 			sbb_setting->fps_slot = slot;
431*9e92c559SJoan Na 		}
432*9e92c559SJoan Na 	}
433*9e92c559SJoan Na 
434*9e92c559SJoan Na 	/* Parse slew rate control source */
435*9e92c559SJoan Na 	sbb_setting->fixed_slew_rate = of_property_read_bool(np, "adi,fixed-slew-rate");
436*9e92c559SJoan Na 
437*9e92c559SJoan Na 	/* Apply parsed configuration */
438*9e92c559SJoan Na 	return max77675_init_regulator(maxreg, desc->id);
439*9e92c559SJoan Na }
440*9e92c559SJoan Na 
441*9e92c559SJoan Na static int max77675_get_error_flags(struct regulator_dev *rdev, unsigned int *flags)
442*9e92c559SJoan Na {
443*9e92c559SJoan Na 	struct max77675_regulator *maxreg = rdev_get_drvdata(rdev);
444*9e92c559SJoan Na 	unsigned int int_flags;
445*9e92c559SJoan Na 	int id = rdev_get_id(rdev);
446*9e92c559SJoan Na 	int ret;
447*9e92c559SJoan Na 
448*9e92c559SJoan Na 	ret = regmap_read(maxreg->regmap, MAX77675_REG_INT_GLBL, &int_flags);
449*9e92c559SJoan Na 	if (ret) {
450*9e92c559SJoan Na 		dev_err(maxreg->dev, "Failed to read INT_GLBL: %d\n", ret);
451*9e92c559SJoan Na 		return ret;
452*9e92c559SJoan Na 	}
453*9e92c559SJoan Na 
454*9e92c559SJoan Na 	*flags = 0;
455*9e92c559SJoan Na 
456*9e92c559SJoan Na 	switch (id) {
457*9e92c559SJoan Na 	case MAX77675_ID_SBB0:
458*9e92c559SJoan Na 		if (int_flags & MAX77675_INT_SBB0_F_BIT)
459*9e92c559SJoan Na 			*flags |= REGULATOR_ERROR_FAIL;
460*9e92c559SJoan Na 		break;
461*9e92c559SJoan Na 	case MAX77675_ID_SBB1:
462*9e92c559SJoan Na 		if (int_flags & MAX77675_INT_SBB1_F_BIT)
463*9e92c559SJoan Na 			*flags |= REGULATOR_ERROR_FAIL;
464*9e92c559SJoan Na 		break;
465*9e92c559SJoan Na 	case MAX77675_ID_SBB2:
466*9e92c559SJoan Na 		if (int_flags & MAX77675_INT_SBB2_F_BIT)
467*9e92c559SJoan Na 			*flags |= REGULATOR_ERROR_FAIL;
468*9e92c559SJoan Na 		break;
469*9e92c559SJoan Na 	case MAX77675_ID_SBB3:
470*9e92c559SJoan Na 		if (int_flags & MAX77675_INT_SBB3_F_BIT)
471*9e92c559SJoan Na 			*flags |= REGULATOR_ERROR_FAIL;
472*9e92c559SJoan Na 		break;
473*9e92c559SJoan Na 	default:
474*9e92c559SJoan Na 		dev_warn(maxreg->dev, "Unsupported regulator ID: %d\n", id);
475*9e92c559SJoan Na 		break;
476*9e92c559SJoan Na 	}
477*9e92c559SJoan Na 
478*9e92c559SJoan Na 	if (int_flags & MAX77675_INT_TJAL2_R_BIT) {
479*9e92c559SJoan Na 		/* TJAL2 interrupt: Over-temperature condition (above 120 degree) */
480*9e92c559SJoan Na 		*flags |= REGULATOR_ERROR_OVER_TEMP;
481*9e92c559SJoan Na 	}
482*9e92c559SJoan Na 
483*9e92c559SJoan Na 	return 0;
484*9e92c559SJoan Na }
485*9e92c559SJoan Na 
486*9e92c559SJoan Na static const struct regulator_ops max77675_regulator_ops = {
487*9e92c559SJoan Na 	.list_voltage         = regulator_list_voltage_linear,
488*9e92c559SJoan Na 	.enable               = regulator_enable_regmap,
489*9e92c559SJoan Na 	.disable              = regulator_disable_regmap,
490*9e92c559SJoan Na 	.is_enabled           = regulator_is_enabled_regmap,
491*9e92c559SJoan Na 	.map_voltage          = regulator_map_voltage_linear,
492*9e92c559SJoan Na 	.set_voltage_sel      = regulator_set_voltage_sel_regmap,
493*9e92c559SJoan Na 	.get_voltage_sel      = regulator_get_voltage_sel_regmap,
494*9e92c559SJoan Na 	.set_active_discharge = regulator_set_active_discharge_regmap,
495*9e92c559SJoan Na 	.get_error_flags      = max77675_get_error_flags,
496*9e92c559SJoan Na };
497*9e92c559SJoan Na 
498*9e92c559SJoan Na static struct regulator_desc max77675_regulators[MAX77675_ID_NUM_MAX] = {
499*9e92c559SJoan Na 	{
500*9e92c559SJoan Na 		.name                  = "sbb0",
501*9e92c559SJoan Na 		.of_match              = of_match_ptr("sbb0"),
502*9e92c559SJoan Na 		.regulators_node       = of_match_ptr("regulators"),
503*9e92c559SJoan Na 		.of_parse_cb           = max77675_of_parse_cb,
504*9e92c559SJoan Na 		.id                    = MAX77675_ID_SBB0,
505*9e92c559SJoan Na 		.ops                   = &max77675_regulator_ops,
506*9e92c559SJoan Na 		.type                  = REGULATOR_VOLTAGE,
507*9e92c559SJoan Na 		.owner                 = THIS_MODULE,
508*9e92c559SJoan Na 		.n_voltages            = MAX77675_NUM_LEVELS_25MV,
509*9e92c559SJoan Na 		.min_uV                = MAX77675_MIN_UV,
510*9e92c559SJoan Na 		.uV_step               = MAX77675_STEP_25MV,
511*9e92c559SJoan Na 		.vsel_reg              = MAX77675_REG_CNFG_SBB0_A,
512*9e92c559SJoan Na 		.vsel_mask             = MAX77675_TV_SBB0_MASK,
513*9e92c559SJoan Na 		.enable_reg            = MAX77675_REG_CNFG_SBB0_B,
514*9e92c559SJoan Na 		.enable_mask           = MAX77675_EN_SBB0_MASK,
515*9e92c559SJoan Na 		.enable_val            = MAX77675_ENABLE_ON,
516*9e92c559SJoan Na 		.disable_val           = MAX77675_ENABLE_OFF,
517*9e92c559SJoan Na 		.active_discharge_off  = MAX77675_REGULATOR_AD_OFF,
518*9e92c559SJoan Na 		.active_discharge_on   = MAX77675_REGULATOR_AD_ON,
519*9e92c559SJoan Na 		.active_discharge_mask = MAX77675_ADE_SBB0_BIT,
520*9e92c559SJoan Na 		.active_discharge_reg  = MAX77675_REG_CNFG_SBB0_B,
521*9e92c559SJoan Na 	},
522*9e92c559SJoan Na 	{
523*9e92c559SJoan Na 		.name                  = "sbb1",
524*9e92c559SJoan Na 		.of_match              = of_match_ptr("sbb1"),
525*9e92c559SJoan Na 		.regulators_node       = of_match_ptr("regulators"),
526*9e92c559SJoan Na 		.of_parse_cb           = max77675_of_parse_cb,
527*9e92c559SJoan Na 		.id                    = MAX77675_ID_SBB1,
528*9e92c559SJoan Na 		.ops                   = &max77675_regulator_ops,
529*9e92c559SJoan Na 		.type                  = REGULATOR_VOLTAGE,
530*9e92c559SJoan Na 		.owner                 = THIS_MODULE,
531*9e92c559SJoan Na 		.n_voltages            = MAX77675_NUM_LEVELS_25MV,
532*9e92c559SJoan Na 		.min_uV                = MAX77675_MIN_UV,
533*9e92c559SJoan Na 		.uV_step               = MAX77675_STEP_25MV,
534*9e92c559SJoan Na 		.vsel_reg              = MAX77675_REG_CNFG_SBB1_A,
535*9e92c559SJoan Na 		.vsel_mask             = MAX77675_TV_SBB1_MASK,
536*9e92c559SJoan Na 		.enable_reg            = MAX77675_REG_CNFG_SBB1_B,
537*9e92c559SJoan Na 		.enable_mask           = MAX77675_EN_SBB1_MASK,
538*9e92c559SJoan Na 		.enable_val            = MAX77675_ENABLE_ON,
539*9e92c559SJoan Na 		.disable_val           = MAX77675_ENABLE_OFF,
540*9e92c559SJoan Na 		.active_discharge_off  = MAX77675_REGULATOR_AD_OFF,
541*9e92c559SJoan Na 		.active_discharge_on   = MAX77675_REGULATOR_AD_ON,
542*9e92c559SJoan Na 		.active_discharge_mask = MAX77675_ADE_SBB1_BIT,
543*9e92c559SJoan Na 		.active_discharge_reg  = MAX77675_REG_CNFG_SBB1_B,
544*9e92c559SJoan Na 	},
545*9e92c559SJoan Na 	{
546*9e92c559SJoan Na 		.name                  = "sbb2",
547*9e92c559SJoan Na 		.of_match              = of_match_ptr("sbb2"),
548*9e92c559SJoan Na 		.regulators_node       = of_match_ptr("regulators"),
549*9e92c559SJoan Na 		.of_parse_cb           = max77675_of_parse_cb,
550*9e92c559SJoan Na 		.id                    = MAX77675_ID_SBB2,
551*9e92c559SJoan Na 		.ops                   = &max77675_regulator_ops,
552*9e92c559SJoan Na 		.type                  = REGULATOR_VOLTAGE,
553*9e92c559SJoan Na 		.owner                 = THIS_MODULE,
554*9e92c559SJoan Na 		.n_voltages            = MAX77675_NUM_LEVELS_25MV,
555*9e92c559SJoan Na 		.min_uV                = MAX77675_MIN_UV,
556*9e92c559SJoan Na 		.uV_step               = MAX77675_STEP_25MV,
557*9e92c559SJoan Na 		.vsel_reg              = MAX77675_REG_CNFG_SBB2_A,
558*9e92c559SJoan Na 		.vsel_mask             = MAX77675_TV_SBB2_MASK,
559*9e92c559SJoan Na 		.enable_reg            = MAX77675_REG_CNFG_SBB2_B,
560*9e92c559SJoan Na 		.enable_mask           = MAX77675_EN_SBB2_MASK,
561*9e92c559SJoan Na 		.enable_val            = MAX77675_ENABLE_ON,
562*9e92c559SJoan Na 		.disable_val           = MAX77675_ENABLE_OFF,
563*9e92c559SJoan Na 		.active_discharge_off  = MAX77675_REGULATOR_AD_OFF,
564*9e92c559SJoan Na 		.active_discharge_on   = MAX77675_REGULATOR_AD_ON,
565*9e92c559SJoan Na 		.active_discharge_mask = MAX77675_ADE_SBB2_BIT,
566*9e92c559SJoan Na 		.active_discharge_reg  = MAX77675_REG_CNFG_SBB2_B,
567*9e92c559SJoan Na 	},
568*9e92c559SJoan Na 	{
569*9e92c559SJoan Na 		.name                  = "sbb3",
570*9e92c559SJoan Na 		.of_match              = of_match_ptr("sbb3"),
571*9e92c559SJoan Na 		.regulators_node       = of_match_ptr("regulators"),
572*9e92c559SJoan Na 		.of_parse_cb           = max77675_of_parse_cb,
573*9e92c559SJoan Na 		.id                    = MAX77675_ID_SBB3,
574*9e92c559SJoan Na 		.ops                   = &max77675_regulator_ops,
575*9e92c559SJoan Na 		.type                  = REGULATOR_VOLTAGE,
576*9e92c559SJoan Na 		.owner                 = THIS_MODULE,
577*9e92c559SJoan Na 		.n_voltages            = MAX77675_NUM_LEVELS_25MV,
578*9e92c559SJoan Na 		.min_uV                = MAX77675_MIN_UV,
579*9e92c559SJoan Na 		.uV_step               = MAX77675_STEP_25MV,
580*9e92c559SJoan Na 		.vsel_reg              = MAX77675_REG_CNFG_SBB3_A,
581*9e92c559SJoan Na 		.vsel_mask             = MAX77675_TV_SBB3_MASK,
582*9e92c559SJoan Na 		.enable_reg            = MAX77675_REG_CNFG_SBB3_B,
583*9e92c559SJoan Na 		.enable_mask           = MAX77675_EN_SBB3_MASK,
584*9e92c559SJoan Na 		.enable_val            = MAX77675_ENABLE_ON,
585*9e92c559SJoan Na 		.disable_val           = MAX77675_ENABLE_OFF,
586*9e92c559SJoan Na 		.active_discharge_off  = MAX77675_REGULATOR_AD_OFF,
587*9e92c559SJoan Na 		.active_discharge_on   = MAX77675_REGULATOR_AD_ON,
588*9e92c559SJoan Na 		.active_discharge_mask = MAX77675_ADE_SBB3_BIT,
589*9e92c559SJoan Na 		.active_discharge_reg  = MAX77675_REG_CNFG_SBB3_B,
590*9e92c559SJoan Na 	},
591*9e92c559SJoan Na };
592*9e92c559SJoan Na 
593*9e92c559SJoan Na static bool max77675_volatile_reg(struct device *dev, unsigned int reg)
594*9e92c559SJoan Na {
595*9e92c559SJoan Na 	switch (reg) {
596*9e92c559SJoan Na 	case MAX77675_REG_CNFG_GLBL_B:
597*9e92c559SJoan Na 		/* This register can be updated by an internal state machine */
598*9e92c559SJoan Na 	case MAX77675_REG_INT_GLBL:
599*9e92c559SJoan Na 	case MAX77675_REG_STAT_GLBL:
600*9e92c559SJoan Na 	case MAX77675_REG_ERCF_GLBL:
601*9e92c559SJoan Na 		return true;
602*9e92c559SJoan Na 	default:
603*9e92c559SJoan Na 		return false;
604*9e92c559SJoan Na 	}
605*9e92c559SJoan Na }
606*9e92c559SJoan Na 
607*9e92c559SJoan Na static const struct regmap_config max77675_regmap_config = {
608*9e92c559SJoan Na 	.reg_bits = 8,
609*9e92c559SJoan Na 	.val_bits = 8,
610*9e92c559SJoan Na 	.max_register = MAX77675_MAX_REGISTER,
611*9e92c559SJoan Na 	.cache_type = REGCACHE_MAPLE,
612*9e92c559SJoan Na 	.volatile_reg = max77675_volatile_reg,
613*9e92c559SJoan Na };
614*9e92c559SJoan Na 
615*9e92c559SJoan Na static int max77675_apply_config(struct max77675_regulator *maxreg)
616*9e92c559SJoan Na {
617*9e92c559SJoan Na 	const struct max77675_config *cfg = &maxreg->config;
618*9e92c559SJoan Na 	int ret;
619*9e92c559SJoan Na 
620*9e92c559SJoan Na 	/* Set EN pin mode */
621*9e92c559SJoan Na 	ret = regmap_update_bits(maxreg->regmap, MAX77675_REG_CNFG_GLBL_A,
622*9e92c559SJoan Na 				 MAX77675_EN_MODE_MASK,
623*9e92c559SJoan Na 				 FIELD_PREP(MAX77675_EN_MODE_MASK, cfg->en_mode));
624*9e92c559SJoan Na 	if (ret) {
625*9e92c559SJoan Na 		dev_err(maxreg->dev, "Failed to set EN mode: %d\n", ret);
626*9e92c559SJoan Na 		return ret;
627*9e92c559SJoan Na 	}
628*9e92c559SJoan Na 
629*9e92c559SJoan Na 	/* Set the latency between output voltage change and SBBx voltage ramp start */
630*9e92c559SJoan Na 	ret = regmap_update_bits(maxreg->regmap, MAX77675_REG_CNFG_SBB_TOP_B,
631*9e92c559SJoan Na 				 MAX77675_LAT_MODE_BIT,
632*9e92c559SJoan Na 				 FIELD_PREP(MAX77675_LAT_MODE_BIT, cfg->voltage_change_latency));
633*9e92c559SJoan Na 	if (ret) {
634*9e92c559SJoan Na 		dev_err(maxreg->dev, "Failed to set latency mode: %d\n", ret);
635*9e92c559SJoan Na 		return ret;
636*9e92c559SJoan Na 	}
637*9e92c559SJoan Na 
638*9e92c559SJoan Na 	/* Set drive strength */
639*9e92c559SJoan Na 	ret = regmap_update_bits(maxreg->regmap, MAX77675_REG_CNFG_SBB_TOP_A,
640*9e92c559SJoan Na 				 MAX77675_DRV_SBB_MASK,
641*9e92c559SJoan Na 				 FIELD_PREP(MAX77675_DRV_SBB_MASK, cfg->drv_sbb_strength));
642*9e92c559SJoan Na 	if (ret) {
643*9e92c559SJoan Na 		dev_err(maxreg->dev, "Failed to set drive strength: %d\n", ret);
644*9e92c559SJoan Na 		return ret;
645*9e92c559SJoan Na 	}
646*9e92c559SJoan Na 
647*9e92c559SJoan Na 	/* Set DVS slew rate */
648*9e92c559SJoan Na 	ret = regmap_update_bits(maxreg->regmap, MAX77675_REG_CNFG_SBB_TOP_B,
649*9e92c559SJoan Na 				 MAX77675_DVS_SLEW_BIT,
650*9e92c559SJoan Na 				 FIELD_PREP(MAX77675_DVS_SLEW_BIT, cfg->dvs_slew_rate));
651*9e92c559SJoan Na 	if (ret) {
652*9e92c559SJoan Na 		dev_err(maxreg->dev, "Failed to set DVS slew rate: %d\n", ret);
653*9e92c559SJoan Na 		return ret;
654*9e92c559SJoan Na 	}
655*9e92c559SJoan Na 
656*9e92c559SJoan Na 	/* Set debounce time for EN pin */
657*9e92c559SJoan Na 	ret = regmap_update_bits(maxreg->regmap, MAX77675_REG_CNFG_GLBL_A,
658*9e92c559SJoan Na 				 MAX77675_DBEN_EN_BIT,
659*9e92c559SJoan Na 				 FIELD_PREP(MAX77675_DBEN_EN_BIT, cfg->debounce_time));
660*9e92c559SJoan Na 	if (ret) {
661*9e92c559SJoan Na 		dev_err(maxreg->dev, "Failed to set EN debounce time: %d\n", ret);
662*9e92c559SJoan Na 		return ret;
663*9e92c559SJoan Na 	}
664*9e92c559SJoan Na 
665*9e92c559SJoan Na 	/* Set manual reset time (MRT) for EN pin */
666*9e92c559SJoan Na 	ret = regmap_update_bits(maxreg->regmap, MAX77675_REG_CNFG_GLBL_A,
667*9e92c559SJoan Na 				 MAX77675_MRT_MASK,
668*9e92c559SJoan Na 				 FIELD_PREP(MAX77675_MRT_MASK, cfg->manual_reset_time));
669*9e92c559SJoan Na 	if (ret) {
670*9e92c559SJoan Na 		dev_err(maxreg->dev, "Failed to set manual reset time: %d\n", ret);
671*9e92c559SJoan Na 		return ret;
672*9e92c559SJoan Na 	}
673*9e92c559SJoan Na 
674*9e92c559SJoan Na 	/* Enable or disable internal pull-up resistor on EN pin */
675*9e92c559SJoan Na 	ret = regmap_update_bits(maxreg->regmap, MAX77675_REG_CNFG_GLBL_A,
676*9e92c559SJoan Na 				 MAX77675_PU_DIS_BIT,
677*9e92c559SJoan Na 				 FIELD_PREP(MAX77675_PU_DIS_BIT, cfg->en_pullup_disable));
678*9e92c559SJoan Na 	if (ret) {
679*9e92c559SJoan Na 		dev_err(maxreg->dev, "Failed to set EN pull-up disable: %d\n", ret);
680*9e92c559SJoan Na 		return ret;
681*9e92c559SJoan Na 	}
682*9e92c559SJoan Na 
683*9e92c559SJoan Na 	/* Request main bias to enter low-power mode */
684*9e92c559SJoan Na 	ret = regmap_update_bits(maxreg->regmap, MAX77675_REG_CNFG_GLBL_A,
685*9e92c559SJoan Na 				 MAX77675_BIAS_LPM_BIT,
686*9e92c559SJoan Na 				 FIELD_PREP(MAX77675_BIAS_LPM_BIT, cfg->bias_low_power_request));
687*9e92c559SJoan Na 	if (ret) {
688*9e92c559SJoan Na 		dev_err(maxreg->dev, "Failed to set bias low-power request: %d\n", ret);
689*9e92c559SJoan Na 		return ret;
690*9e92c559SJoan Na 	}
691*9e92c559SJoan Na 
692*9e92c559SJoan Na 	/* Force SIMO internal LDO to always supply 1.8V */
693*9e92c559SJoan Na 	ret = regmap_update_bits(maxreg->regmap, MAX77675_REG_CNFG_GLBL_A,
694*9e92c559SJoan Na 				 MAX77675_SIMO_CH_DIS_BIT,
695*9e92c559SJoan Na 				 FIELD_PREP(MAX77675_SIMO_CH_DIS_BIT, cfg->simo_ldo_always_on));
696*9e92c559SJoan Na 	if (ret) {
697*9e92c559SJoan Na 		dev_err(maxreg->dev, "Failed to set SIMO internal LDO always-on: %d\n", ret);
698*9e92c559SJoan Na 		return ret;
699*9e92c559SJoan Na 	}
700*9e92c559SJoan Na 
701*9e92c559SJoan Na 	return 0;
702*9e92c559SJoan Na }
703*9e92c559SJoan Na 
704*9e92c559SJoan Na static int max77675_parse_en_mode(struct device *dev,
705*9e92c559SJoan Na 				  struct device_node *np,
706*9e92c559SJoan Na 				  u8 *en_mode)
707*9e92c559SJoan Na {
708*9e92c559SJoan Na 	static const char * const en_modes[] = {"push-button", "slide-switch", "logic"};
709*9e92c559SJoan Na 	const char *str;
710*9e92c559SJoan Na 	int index;
711*9e92c559SJoan Na 
712*9e92c559SJoan Na 	*en_mode = MAX77675_EN_SLIDE_SWITCH;
713*9e92c559SJoan Na 
714*9e92c559SJoan Na 	if (of_property_read_string(np, "adi,en-mode", &str))
715*9e92c559SJoan Na 		return 0;
716*9e92c559SJoan Na 
717*9e92c559SJoan Na 	index = match_string(en_modes, ARRAY_SIZE(en_modes), str);
718*9e92c559SJoan Na 	if (index < 0) {
719*9e92c559SJoan Na 		dev_err(dev, "Invalid 'adi,en-mode' value '%s'\n", str);
720*9e92c559SJoan Na 		return -EINVAL;
721*9e92c559SJoan Na 	}
722*9e92c559SJoan Na 
723*9e92c559SJoan Na 	*en_mode = index;
724*9e92c559SJoan Na 
725*9e92c559SJoan Na 	return 0;
726*9e92c559SJoan Na }
727*9e92c559SJoan Na 
728*9e92c559SJoan Na static int max77675_parse_voltage_change_latency(struct device *dev,
729*9e92c559SJoan Na 						 struct device_node *np,
730*9e92c559SJoan Na 						 u8 *latency_mode)
731*9e92c559SJoan Na {
732*9e92c559SJoan Na 	u32 val;
733*9e92c559SJoan Na 
734*9e92c559SJoan Na 	*latency_mode = MAX77675_HIGH_LATENCY_MODE;
735*9e92c559SJoan Na 
736*9e92c559SJoan Na 	if (!of_property_read_u32(np, "adi,voltage-change-latency-us", &val)) {
737*9e92c559SJoan Na 		switch (val) {
738*9e92c559SJoan Na 		case 10:
739*9e92c559SJoan Na 			*latency_mode = MAX77675_LOW_LATENCY_MODE;
740*9e92c559SJoan Na 			break;
741*9e92c559SJoan Na 		case 100:
742*9e92c559SJoan Na 			*latency_mode = MAX77675_HIGH_LATENCY_MODE;
743*9e92c559SJoan Na 			break;
744*9e92c559SJoan Na 		default:
745*9e92c559SJoan Na 			dev_err(dev, "Invalid voltage-change-latency-us value: %u\n", val);
746*9e92c559SJoan Na 			return -EINVAL;
747*9e92c559SJoan Na 		}
748*9e92c559SJoan Na 	}
749*9e92c559SJoan Na 
750*9e92c559SJoan Na 	return 0;
751*9e92c559SJoan Na }
752*9e92c559SJoan Na 
753*9e92c559SJoan Na static int max77675_parse_manual_reset_time(struct device *dev,
754*9e92c559SJoan Na 					    struct device_node *np,
755*9e92c559SJoan Na 					    u8 *reset_time)
756*9e92c559SJoan Na {
757*9e92c559SJoan Na 	u32 val;
758*9e92c559SJoan Na 
759*9e92c559SJoan Na 	*reset_time = MAX77675_MRT_4S;
760*9e92c559SJoan Na 
761*9e92c559SJoan Na 	if (!of_property_read_u32(np, "reset-time-sec", &val)) {
762*9e92c559SJoan Na 		switch (val) {
763*9e92c559SJoan Na 		case 4:
764*9e92c559SJoan Na 			*reset_time = MAX77675_MRT_4S;
765*9e92c559SJoan Na 			break;
766*9e92c559SJoan Na 		case 8:
767*9e92c559SJoan Na 			*reset_time = MAX77675_MRT_8S;
768*9e92c559SJoan Na 			break;
769*9e92c559SJoan Na 		case 12:
770*9e92c559SJoan Na 			*reset_time = MAX77675_MRT_12S;
771*9e92c559SJoan Na 			break;
772*9e92c559SJoan Na 		case 16:
773*9e92c559SJoan Na 			*reset_time = MAX77675_MRT_16S;
774*9e92c559SJoan Na 			break;
775*9e92c559SJoan Na 		default:
776*9e92c559SJoan Na 			dev_err(dev, "Invalid reset-time-sec value: %u\n", val);
777*9e92c559SJoan Na 			return -EINVAL;
778*9e92c559SJoan Na 		}
779*9e92c559SJoan Na 	}
780*9e92c559SJoan Na 
781*9e92c559SJoan Na 	return 0;
782*9e92c559SJoan Na }
783*9e92c559SJoan Na 
784*9e92c559SJoan Na static int max77675_parse_dvs_slew_rate(struct device *dev, struct device_node *np, u8 *slew_rate)
785*9e92c559SJoan Na {
786*9e92c559SJoan Na 	u32 val;
787*9e92c559SJoan Na 
788*9e92c559SJoan Na 	/* Set default: 5 mV/us */
789*9e92c559SJoan Na 	*slew_rate = MAX77675_DVS_SLEW_5MV_PER_US;
790*9e92c559SJoan Na 
791*9e92c559SJoan Na 	if (!of_property_read_u32(np, "adi,dvs-slew-rate-mv-per-us", &val)) {
792*9e92c559SJoan Na 		switch (val) {
793*9e92c559SJoan Na 		case 5:
794*9e92c559SJoan Na 			*slew_rate = MAX77675_DVS_SLEW_5MV_PER_US;
795*9e92c559SJoan Na 			break;
796*9e92c559SJoan Na 		case 10:
797*9e92c559SJoan Na 			*slew_rate = MAX77675_DVS_SLEW_10MV_PER_US;
798*9e92c559SJoan Na 			break;
799*9e92c559SJoan Na 		default:
800*9e92c559SJoan Na 			dev_err(dev, "Invalid dvs-slew-rate-mv-per-us value: %u\n", val);
801*9e92c559SJoan Na 			return -EINVAL;
802*9e92c559SJoan Na 		}
803*9e92c559SJoan Na 	}
804*9e92c559SJoan Na 
805*9e92c559SJoan Na 	return 0;
806*9e92c559SJoan Na }
807*9e92c559SJoan Na 
808*9e92c559SJoan Na static int max77675_parse_drv_sbb_strength(struct device *dev, struct device_node *np, u8 *strength)
809*9e92c559SJoan Na {
810*9e92c559SJoan Na 	static const char * const strength_names[] = {"max", "high", "low", "min"};
811*9e92c559SJoan Na 	const char *str;
812*9e92c559SJoan Na 	int index;
813*9e92c559SJoan Na 
814*9e92c559SJoan Na 	/* Set default: maximum drive strength */
815*9e92c559SJoan Na 	*strength = MAX77675_DRV_SBB_STRENGTH_MAX;
816*9e92c559SJoan Na 
817*9e92c559SJoan Na 	if (of_property_read_string(np, "adi,drv-sbb-strength", &str))
818*9e92c559SJoan Na 		return 0;
819*9e92c559SJoan Na 
820*9e92c559SJoan Na 	index = match_string(strength_names, ARRAY_SIZE(strength_names), str);
821*9e92c559SJoan Na 	if (index < 0) {
822*9e92c559SJoan Na 		dev_err(dev, "Invalid 'adi,drv-sbb-strength' value: '%s'\n", str);
823*9e92c559SJoan Na 		return -EINVAL;
824*9e92c559SJoan Na 	}
825*9e92c559SJoan Na 
826*9e92c559SJoan Na 	*strength = index;
827*9e92c559SJoan Na 
828*9e92c559SJoan Na 	return 0;
829*9e92c559SJoan Na }
830*9e92c559SJoan Na 
831*9e92c559SJoan Na static int max77675_parse_debounce_time_us(struct device *dev,
832*9e92c559SJoan Na 					   struct device_node *np,
833*9e92c559SJoan Na 					   u8 *debounce_time)
834*9e92c559SJoan Na {
835*9e92c559SJoan Na 	u32 val;
836*9e92c559SJoan Na 
837*9e92c559SJoan Na 	*debounce_time = MAX77675_DBEN_100US;
838*9e92c559SJoan Na 
839*9e92c559SJoan Na 	if (!of_property_read_u32(np, "input-debounce", &val)) {
840*9e92c559SJoan Na 		switch (val) {
841*9e92c559SJoan Na 		case 100:
842*9e92c559SJoan Na 			*debounce_time = MAX77675_DBEN_100US;
843*9e92c559SJoan Na 			break;
844*9e92c559SJoan Na 		case 30000:
845*9e92c559SJoan Na 			*debounce_time = MAX77675_DBEN_30000US;
846*9e92c559SJoan Na 			break;
847*9e92c559SJoan Na 		default:
848*9e92c559SJoan Na 			dev_err(dev, "Invalid input-debounce value: %u\n", val);
849*9e92c559SJoan Na 			return -EINVAL;
850*9e92c559SJoan Na 		}
851*9e92c559SJoan Na 	}
852*9e92c559SJoan Na 
853*9e92c559SJoan Na 	return 0;
854*9e92c559SJoan Na }
855*9e92c559SJoan Na 
856*9e92c559SJoan Na static int max77675_parse_config(struct max77675_regulator *maxreg)
857*9e92c559SJoan Na {
858*9e92c559SJoan Na 	struct device_node *np = maxreg->dev->of_node;
859*9e92c559SJoan Na 	struct max77675_config *cfg = &maxreg->config;
860*9e92c559SJoan Na 	int ret;
861*9e92c559SJoan Na 
862*9e92c559SJoan Na 	/* EN pin mode */
863*9e92c559SJoan Na 	ret = max77675_parse_en_mode(maxreg->dev, np, &cfg->en_mode);
864*9e92c559SJoan Na 	if (ret < 0)
865*9e92c559SJoan Na 		return ret;
866*9e92c559SJoan Na 
867*9e92c559SJoan Na 	/* voltage change latency */
868*9e92c559SJoan Na 	ret = max77675_parse_voltage_change_latency(maxreg->dev, np, &cfg->voltage_change_latency);
869*9e92c559SJoan Na 	if (ret < 0)
870*9e92c559SJoan Na 		return ret;
871*9e92c559SJoan Na 
872*9e92c559SJoan Na 	/* drive strength */
873*9e92c559SJoan Na 	ret = max77675_parse_drv_sbb_strength(maxreg->dev, np, &cfg->drv_sbb_strength);
874*9e92c559SJoan Na 	if (ret < 0)
875*9e92c559SJoan Na 		return ret;
876*9e92c559SJoan Na 
877*9e92c559SJoan Na 	/* dvs slew rate */
878*9e92c559SJoan Na 	ret = max77675_parse_dvs_slew_rate(maxreg->dev, np, &cfg->dvs_slew_rate);
879*9e92c559SJoan Na 	if (ret < 0)
880*9e92c559SJoan Na 		return ret;
881*9e92c559SJoan Na 
882*9e92c559SJoan Na 	/* Debounce time for EN pin */
883*9e92c559SJoan Na 	ret = max77675_parse_debounce_time_us(maxreg->dev, np, &cfg->debounce_time);
884*9e92c559SJoan Na 	if (ret < 0)
885*9e92c559SJoan Na 		return ret;
886*9e92c559SJoan Na 
887*9e92c559SJoan Na 	/* Manual reset time for EN pin */
888*9e92c559SJoan Na 	ret = max77675_parse_manual_reset_time(maxreg->dev, np, &cfg->manual_reset_time);
889*9e92c559SJoan Na 	if (ret < 0)
890*9e92c559SJoan Na 		return ret;
891*9e92c559SJoan Na 
892*9e92c559SJoan Na 	/* Disable internal pull-up resistor on EN pin */
893*9e92c559SJoan Na 	cfg->en_pullup_disable = of_property_read_bool(np, "bias-disable");
894*9e92c559SJoan Na 
895*9e92c559SJoan Na 	/* Request low-power mode for main bias */
896*9e92c559SJoan Na 	cfg->bias_low_power_request = of_property_read_bool(np, "adi,bias-low-power-request");
897*9e92c559SJoan Na 
898*9e92c559SJoan Na 	/* Force internal LDO to always supply 1.8V */
899*9e92c559SJoan Na 	cfg->simo_ldo_always_on = of_property_read_bool(np, "adi,simo-ldo-always-on");
900*9e92c559SJoan Na 
901*9e92c559SJoan Na 	return ret;
902*9e92c559SJoan Na }
903*9e92c559SJoan Na 
904*9e92c559SJoan Na static int max77675_init_event(struct max77675_regulator *maxreg)
905*9e92c559SJoan Na {
906*9e92c559SJoan Na 	unsigned int ercflag, int_glbl;
907*9e92c559SJoan Na 	int ret;
908*9e92c559SJoan Na 
909*9e92c559SJoan Na 	ret = regmap_read(maxreg->regmap, MAX77675_REG_ERCF_GLBL, &ercflag);
910*9e92c559SJoan Na 	if (ret) {
911*9e92c559SJoan Na 		dev_err(maxreg->dev, "Failed to read CID register: %d\n", ret);
912*9e92c559SJoan Na 		return ret;
913*9e92c559SJoan Na 	}
914*9e92c559SJoan Na 
915*9e92c559SJoan Na 	ret = regmap_read(maxreg->regmap, MAX77675_REG_INT_GLBL, &int_glbl);
916*9e92c559SJoan Na 	if (ret) {
917*9e92c559SJoan Na 		dev_err(maxreg->dev, "Failed to read INT_GLBL register: %d\n", ret);
918*9e92c559SJoan Na 		return ret;
919*9e92c559SJoan Na 	}
920*9e92c559SJoan Na 
921*9e92c559SJoan Na 	if (ercflag & MAX77675_SFT_CRST_F_BIT)
922*9e92c559SJoan Na 		dev_dbg(maxreg->dev, "Software Cold Reset Flag is set\n");
923*9e92c559SJoan Na 
924*9e92c559SJoan Na 	if (ercflag & MAX77675_SFT_OFF_F_BIT)
925*9e92c559SJoan Na 		dev_dbg(maxreg->dev, "Software Off Flag is set\n");
926*9e92c559SJoan Na 
927*9e92c559SJoan Na 	if (ercflag & MAX77675_MRST_BIT)
928*9e92c559SJoan Na 		dev_dbg(maxreg->dev, "Manual Reset Timer Flag is set\n");
929*9e92c559SJoan Na 
930*9e92c559SJoan Na 	if (ercflag & MAX77675_UVLO_BIT)
931*9e92c559SJoan Na 		dev_dbg(maxreg->dev, "Undervoltage Lockout Flag is set\n");
932*9e92c559SJoan Na 
933*9e92c559SJoan Na 	if (ercflag & MAX77675_OVLO_BIT)
934*9e92c559SJoan Na 		dev_dbg(maxreg->dev, "Overvoltage Lockout Flag is set\n");
935*9e92c559SJoan Na 
936*9e92c559SJoan Na 	if (ercflag & MAX77675_TOVLD_BIT)
937*9e92c559SJoan Na 		dev_dbg(maxreg->dev, "Thermal Overload Flag is set\n");
938*9e92c559SJoan Na 
939*9e92c559SJoan Na 	if (int_glbl & MAX77675_INT_SBB3_F_BIT)
940*9e92c559SJoan Na 		dev_dbg(maxreg->dev, "SBB3 Channel Fault Interrupt occurred\n");
941*9e92c559SJoan Na 
942*9e92c559SJoan Na 	if (int_glbl & MAX77675_INT_SBB2_F_BIT)
943*9e92c559SJoan Na 		dev_dbg(maxreg->dev, "SBB2 Channel Fault Interrupt occurred\n");
944*9e92c559SJoan Na 
945*9e92c559SJoan Na 	if (int_glbl & MAX77675_INT_SBB1_F_BIT)
946*9e92c559SJoan Na 		dev_dbg(maxreg->dev, "SBB1 Channel Fault Interrupt occurred\n");
947*9e92c559SJoan Na 
948*9e92c559SJoan Na 	if (int_glbl & MAX77675_INT_SBB0_F_BIT)
949*9e92c559SJoan Na 		dev_dbg(maxreg->dev, "SBB0 Channel Fault Interrupt occurred\n");
950*9e92c559SJoan Na 
951*9e92c559SJoan Na 	if (int_glbl & MAX77675_INT_TJAL2_R_BIT)
952*9e92c559SJoan Na 		dev_dbg(maxreg->dev, "Thermal Alarm 2 Rising Interrupt occurred\n");
953*9e92c559SJoan Na 
954*9e92c559SJoan Na 	if (int_glbl & MAX77675_INT_TJAL1_R_BIT)
955*9e92c559SJoan Na 		dev_dbg(maxreg->dev, "Thermal Alarm 1 Rising Interrupt occurred\n");
956*9e92c559SJoan Na 
957*9e92c559SJoan Na 	if (int_glbl & MAX77675_INT_EN_R_BIT)
958*9e92c559SJoan Na 		dev_dbg(maxreg->dev, "nEN Rising Edge Interrupt occurred\n");
959*9e92c559SJoan Na 
960*9e92c559SJoan Na 	if (int_glbl & MAX77675_INT_EN_F_BIT)
961*9e92c559SJoan Na 		dev_dbg(maxreg->dev, "nEN Falling Edge Interrupt occurred\n");
962*9e92c559SJoan Na 
963*9e92c559SJoan Na 	return 0;
964*9e92c559SJoan Na }
965*9e92c559SJoan Na 
966*9e92c559SJoan Na static int max77675_regulator_probe(struct i2c_client *client)
967*9e92c559SJoan Na {
968*9e92c559SJoan Na 	struct max77675_regulator *maxreg;
969*9e92c559SJoan Na 	struct regulator_config config = {};
970*9e92c559SJoan Na 	int i, ret;
971*9e92c559SJoan Na 
972*9e92c559SJoan Na 	maxreg = devm_kzalloc(&client->dev, sizeof(*maxreg), GFP_KERNEL);
973*9e92c559SJoan Na 	if (!maxreg)
974*9e92c559SJoan Na 		return -ENOMEM;
975*9e92c559SJoan Na 
976*9e92c559SJoan Na 	maxreg->dev = &client->dev;
977*9e92c559SJoan Na 
978*9e92c559SJoan Na 	maxreg->regmap = devm_regmap_init_i2c(client, &max77675_regmap_config);
979*9e92c559SJoan Na 	if (IS_ERR(maxreg->regmap))
980*9e92c559SJoan Na 		return dev_err_probe(maxreg->dev,
981*9e92c559SJoan Na 				     PTR_ERR(maxreg->regmap),
982*9e92c559SJoan Na 				     "Failed to init regmap\n");
983*9e92c559SJoan Na 
984*9e92c559SJoan Na 	ret = max77675_init_event(maxreg);
985*9e92c559SJoan Na 	if (ret < 0)
986*9e92c559SJoan Na 		return dev_err_probe(maxreg->dev, ret, "Failed to init event\n");
987*9e92c559SJoan Na 
988*9e92c559SJoan Na 	ret = max77675_parse_config(maxreg);
989*9e92c559SJoan Na 	if (ret < 0)
990*9e92c559SJoan Na 		return dev_err_probe(maxreg->dev, ret, "Failed to parse config\n");
991*9e92c559SJoan Na 
992*9e92c559SJoan Na 	ret = max77675_apply_config(maxreg);
993*9e92c559SJoan Na 	if (ret < 0)
994*9e92c559SJoan Na 		return dev_err_probe(maxreg->dev, ret, "Failed to apply config\n");
995*9e92c559SJoan Na 
996*9e92c559SJoan Na 	config.dev = &client->dev;
997*9e92c559SJoan Na 	config.regmap = maxreg->regmap;
998*9e92c559SJoan Na 	config.driver_data = maxreg;
999*9e92c559SJoan Na 
1000*9e92c559SJoan Na 	struct device_node *regulators_np __free(device_node) =
1001*9e92c559SJoan Na 		of_get_child_by_name(client->dev.of_node, "regulators");
1002*9e92c559SJoan Na 	if (!regulators_np) {
1003*9e92c559SJoan Na 		dev_err(maxreg->dev, "No 'regulators' subnode found in DT\n");
1004*9e92c559SJoan Na 		return -EINVAL;
1005*9e92c559SJoan Na 	}
1006*9e92c559SJoan Na 
1007*9e92c559SJoan Na 	for (i = 0; i < MAX77675_ID_NUM_MAX; i++) {
1008*9e92c559SJoan Na 		const struct regulator_desc *desc = &max77675_regulators[i];
1009*9e92c559SJoan Na 		struct regulator_dev *rdev;
1010*9e92c559SJoan Na 
1011*9e92c559SJoan Na 		struct device_node *child_np __free(device_node) =
1012*9e92c559SJoan Na 			of_get_child_by_name(regulators_np, desc->name);
1013*9e92c559SJoan Na 		if (!child_np) {
1014*9e92c559SJoan Na 			dev_warn(maxreg->dev, "No DT node for regulator %s\n", desc->name);
1015*9e92c559SJoan Na 			continue;
1016*9e92c559SJoan Na 		}
1017*9e92c559SJoan Na 
1018*9e92c559SJoan Na 		config.of_node = child_np;
1019*9e92c559SJoan Na 
1020*9e92c559SJoan Na 		rdev = devm_regulator_register(&client->dev, desc, &config);
1021*9e92c559SJoan Na 		if (IS_ERR(rdev)) {
1022*9e92c559SJoan Na 			return dev_err_probe(maxreg->dev, PTR_ERR(rdev),
1023*9e92c559SJoan Na 				"Failed to register regulator %d (%s)\n",
1024*9e92c559SJoan Na 				i, desc->name);
1025*9e92c559SJoan Na 		}
1026*9e92c559SJoan Na 	}
1027*9e92c559SJoan Na 
1028*9e92c559SJoan Na 	return 0;
1029*9e92c559SJoan Na }
1030*9e92c559SJoan Na 
1031*9e92c559SJoan Na static const struct i2c_device_id max77675_i2c_id[] = {
1032*9e92c559SJoan Na 	{ "max77675", 0 },
1033*9e92c559SJoan Na 	{ }
1034*9e92c559SJoan Na };
1035*9e92c559SJoan Na MODULE_DEVICE_TABLE(i2c, max77675_i2c_id);
1036*9e92c559SJoan Na 
1037*9e92c559SJoan Na static const struct of_device_id __maybe_unused max77675_of_match[] = {
1038*9e92c559SJoan Na 	{ .compatible = "adi,max77675", },
1039*9e92c559SJoan Na 	{ }
1040*9e92c559SJoan Na };
1041*9e92c559SJoan Na MODULE_DEVICE_TABLE(of, max77675_of_match);
1042*9e92c559SJoan Na 
1043*9e92c559SJoan Na static struct i2c_driver max77675_regulator_driver = {
1044*9e92c559SJoan Na 	.driver = {
1045*9e92c559SJoan Na 		.name = "max77675",
1046*9e92c559SJoan Na 		.of_match_table = of_match_ptr(max77675_of_match),
1047*9e92c559SJoan Na 	},
1048*9e92c559SJoan Na 	.probe = max77675_regulator_probe,
1049*9e92c559SJoan Na 	.id_table = max77675_i2c_id,
1050*9e92c559SJoan Na };
1051*9e92c559SJoan Na 
1052*9e92c559SJoan Na module_i2c_driver(max77675_regulator_driver);
1053*9e92c559SJoan Na 
1054*9e92c559SJoan Na MODULE_DESCRIPTION("MAX77675 Regulator Driver");
1055*9e92c559SJoan Na MODULE_AUTHOR("Joan Na <joan.na@analog.com>");
1056*9e92c559SJoan Na MODULE_LICENSE("GPL");
1057