1 // SPDX-License-Identifier: GPL-2.0
3 // Copyright (C) 2018 BayLibre SAS
4 // Author: Bartosz Golaszewski <bgolaszewski@baylibre.com>
6 // Regulator driver for MAXIM 77650/77651 charger/power-supply.
9 #include <linux/mfd/max77650.h>
10 #include <linux/module.h>
11 #include <linux/platform_device.h>
12 #include <linux/regmap.h>
13 #include <linux/regulator/driver.h>
15 #define MAX77650_REGULATOR_EN_CTRL_MASK GENMASK(3, 0)
16 #define MAX77650_REGULATOR_EN_CTRL_BITS(_reg) \
17 ((_reg) & MAX77650_REGULATOR_EN_CTRL_MASK)
18 #define MAX77650_REGULATOR_ENABLED GENMASK(2, 1)
19 #define MAX77650_REGULATOR_DISABLED BIT(2)
21 #define MAX77650_REGULATOR_V_LDO_MASK GENMASK(6, 0)
22 #define MAX77650_REGULATOR_V_SBB_MASK GENMASK(5, 0)
24 #define MAX77650_REGULATOR_AD_MASK BIT(3)
25 #define MAX77650_REGULATOR_AD_DISABLED 0x00
26 #define MAX77650_REGULATOR_AD_ENABLED BIT(3)
28 #define MAX77650_REGULATOR_CURR_LIM_MASK GENMASK(7, 6)
31 MAX77650_REGULATOR_ID_LDO
= 0,
32 MAX77650_REGULATOR_ID_SBB0
,
33 MAX77650_REGULATOR_ID_SBB1
,
34 MAX77650_REGULATOR_ID_SBB2
,
35 MAX77650_REGULATOR_NUM_REGULATORS
,
38 struct max77650_regulator_desc
{
39 struct regulator_desc desc
;
44 static const unsigned int max77651_sbb1_regulator_volt_table
[] = {
45 2400000, 3200000, 4000000, 4800000,
46 2450000, 3250000, 4050000, 4850000,
47 2500000, 3300000, 4100000, 4900000,
48 2550000, 3350000, 4150000, 4950000,
49 2600000, 3400000, 4200000, 5000000,
50 2650000, 3450000, 4250000, 5050000,
51 2700000, 3500000, 4300000, 5100000,
52 2750000, 3550000, 4350000, 5150000,
53 2800000, 3600000, 4400000, 5200000,
54 2850000, 3650000, 4450000, 5250000,
55 2900000, 3700000, 4500000, 0,
56 2950000, 3750000, 4550000, 0,
57 3000000, 3800000, 4600000, 0,
58 3050000, 3850000, 4650000, 0,
59 3100000, 3900000, 4700000, 0,
60 3150000, 3950000, 4750000, 0,
63 #define MAX77651_REGULATOR_SBB1_SEL_DEC(_val) \
64 (((_val & 0x3c) >> 2) | ((_val & 0x03) << 4))
65 #define MAX77651_REGULATOR_SBB1_SEL_ENC(_val) \
66 (((_val & 0x30) >> 4) | ((_val & 0x0f) << 2))
68 #define MAX77650_REGULATOR_SBB1_SEL_DECR(_val) \
70 _val = MAX77651_REGULATOR_SBB1_SEL_DEC(_val); \
72 _val = MAX77651_REGULATOR_SBB1_SEL_ENC(_val); \
75 #define MAX77650_REGULATOR_SBB1_SEL_INCR(_val) \
77 _val = MAX77651_REGULATOR_SBB1_SEL_DEC(_val); \
79 _val = MAX77651_REGULATOR_SBB1_SEL_ENC(_val); \
82 static const unsigned int max77650_current_limit_table
[] = {
83 1000000, 866000, 707000, 500000,
86 static int max77650_regulator_is_enabled(struct regulator_dev
*rdev
)
88 struct max77650_regulator_desc
*rdesc
;
92 rdesc
= rdev_get_drvdata(rdev
);
93 map
= rdev_get_regmap(rdev
);
95 rv
= regmap_read(map
, rdesc
->regB
, &val
);
99 en
= MAX77650_REGULATOR_EN_CTRL_BITS(val
);
101 return en
!= MAX77650_REGULATOR_DISABLED
;
104 static int max77650_regulator_enable(struct regulator_dev
*rdev
)
106 struct max77650_regulator_desc
*rdesc
;
109 rdesc
= rdev_get_drvdata(rdev
);
110 map
= rdev_get_regmap(rdev
);
112 return regmap_update_bits(map
, rdesc
->regB
,
113 MAX77650_REGULATOR_EN_CTRL_MASK
,
114 MAX77650_REGULATOR_ENABLED
);
117 static int max77650_regulator_disable(struct regulator_dev
*rdev
)
119 struct max77650_regulator_desc
*rdesc
;
122 rdesc
= rdev_get_drvdata(rdev
);
123 map
= rdev_get_regmap(rdev
);
125 return regmap_update_bits(map
, rdesc
->regB
,
126 MAX77650_REGULATOR_EN_CTRL_MASK
,
127 MAX77650_REGULATOR_DISABLED
);
130 static int max77650_regulator_set_voltage_sel(struct regulator_dev
*rdev
,
133 int rv
= 0, curr
, diff
;
137 * If the regulator is disabled, we can program the desired
138 * voltage right away.
140 if (!max77650_regulator_is_enabled(rdev
))
141 return regulator_set_voltage_sel_regmap(rdev
, sel
);
144 * Otherwise we need to manually ramp the output voltage up/down
145 * one step at a time.
148 curr
= regulator_get_voltage_sel_regmap(rdev
);
154 return 0; /* Already there. */
161 * Make sure we'll get to the right voltage and break the loop even if
162 * the selector equals 0.
164 for (ascending
? curr
++ : curr
--;; ascending
? curr
++ : curr
--) {
165 rv
= regulator_set_voltage_sel_regmap(rdev
, curr
);
177 * Special case: non-linear voltage table for max77651 SBB1 - software
178 * must ensure the voltage is ramped in 50mV increments.
180 static int max77651_regulator_sbb1_set_voltage_sel(struct regulator_dev
*rdev
,
183 int rv
= 0, curr
, vcurr
, vdest
, vdiff
;
186 * If the regulator is disabled, we can program the desired
187 * voltage right away.
189 if (!max77650_regulator_is_enabled(rdev
))
190 return regulator_set_voltage_sel_regmap(rdev
, sel
);
192 curr
= regulator_get_voltage_sel_regmap(rdev
);
197 return 0; /* Already there. */
199 vcurr
= max77651_sbb1_regulator_volt_table
[curr
];
200 vdest
= max77651_sbb1_regulator_volt_table
[sel
];
201 vdiff
= vcurr
- vdest
;
205 MAX77650_REGULATOR_SBB1_SEL_DECR(curr
);
207 MAX77650_REGULATOR_SBB1_SEL_INCR(curr
);
209 rv
= regulator_set_voltage_sel_regmap(rdev
, curr
);
220 static const struct regulator_ops max77650_regulator_LDO_ops
= {
221 .is_enabled
= max77650_regulator_is_enabled
,
222 .enable
= max77650_regulator_enable
,
223 .disable
= max77650_regulator_disable
,
224 .list_voltage
= regulator_list_voltage_linear
,
225 .map_voltage
= regulator_map_voltage_linear
,
226 .get_voltage_sel
= regulator_get_voltage_sel_regmap
,
227 .set_voltage_sel
= max77650_regulator_set_voltage_sel
,
228 .set_active_discharge
= regulator_set_active_discharge_regmap
,
231 static const struct regulator_ops max77650_regulator_SBB_ops
= {
232 .is_enabled
= max77650_regulator_is_enabled
,
233 .enable
= max77650_regulator_enable
,
234 .disable
= max77650_regulator_disable
,
235 .list_voltage
= regulator_list_voltage_linear
,
236 .map_voltage
= regulator_map_voltage_linear
,
237 .get_voltage_sel
= regulator_get_voltage_sel_regmap
,
238 .set_voltage_sel
= max77650_regulator_set_voltage_sel
,
239 .get_current_limit
= regulator_get_current_limit_regmap
,
240 .set_current_limit
= regulator_set_current_limit_regmap
,
241 .set_active_discharge
= regulator_set_active_discharge_regmap
,
244 /* Special case for max77651 SBB1 - non-linear voltage mapping. */
245 static const struct regulator_ops max77651_SBB1_regulator_ops
= {
246 .is_enabled
= max77650_regulator_is_enabled
,
247 .enable
= max77650_regulator_enable
,
248 .disable
= max77650_regulator_disable
,
249 .list_voltage
= regulator_list_voltage_table
,
250 .get_voltage_sel
= regulator_get_voltage_sel_regmap
,
251 .set_voltage_sel
= max77651_regulator_sbb1_set_voltage_sel
,
252 .get_current_limit
= regulator_get_current_limit_regmap
,
253 .set_current_limit
= regulator_set_current_limit_regmap
,
254 .set_active_discharge
= regulator_set_active_discharge_regmap
,
257 static struct max77650_regulator_desc max77650_LDO_desc
= {
260 .of_match
= of_match_ptr("ldo"),
261 .regulators_node
= of_match_ptr("regulators"),
262 .supply_name
= "in-ldo",
263 .id
= MAX77650_REGULATOR_ID_LDO
,
264 .ops
= &max77650_regulator_LDO_ops
,
268 .vsel_mask
= MAX77650_REGULATOR_V_LDO_MASK
,
269 .vsel_reg
= MAX77650_REG_CNFG_LDO_A
,
270 .active_discharge_off
= MAX77650_REGULATOR_AD_DISABLED
,
271 .active_discharge_on
= MAX77650_REGULATOR_AD_ENABLED
,
272 .active_discharge_mask
= MAX77650_REGULATOR_AD_MASK
,
273 .active_discharge_reg
= MAX77650_REG_CNFG_LDO_B
,
275 .type
= REGULATOR_VOLTAGE
,
276 .owner
= THIS_MODULE
,
278 .regA
= MAX77650_REG_CNFG_LDO_A
,
279 .regB
= MAX77650_REG_CNFG_LDO_B
,
282 static struct max77650_regulator_desc max77650_SBB0_desc
= {
285 .of_match
= of_match_ptr("sbb0"),
286 .regulators_node
= of_match_ptr("regulators"),
287 .supply_name
= "in-sbb0",
288 .id
= MAX77650_REGULATOR_ID_SBB0
,
289 .ops
= &max77650_regulator_SBB_ops
,
293 .vsel_mask
= MAX77650_REGULATOR_V_SBB_MASK
,
294 .vsel_reg
= MAX77650_REG_CNFG_SBB0_A
,
295 .active_discharge_off
= MAX77650_REGULATOR_AD_DISABLED
,
296 .active_discharge_on
= MAX77650_REGULATOR_AD_ENABLED
,
297 .active_discharge_mask
= MAX77650_REGULATOR_AD_MASK
,
298 .active_discharge_reg
= MAX77650_REG_CNFG_SBB0_B
,
300 .type
= REGULATOR_VOLTAGE
,
301 .owner
= THIS_MODULE
,
302 .csel_reg
= MAX77650_REG_CNFG_SBB0_A
,
303 .csel_mask
= MAX77650_REGULATOR_CURR_LIM_MASK
,
304 .curr_table
= max77650_current_limit_table
,
305 .n_current_limits
= ARRAY_SIZE(max77650_current_limit_table
),
307 .regA
= MAX77650_REG_CNFG_SBB0_A
,
308 .regB
= MAX77650_REG_CNFG_SBB0_B
,
311 static struct max77650_regulator_desc max77650_SBB1_desc
= {
314 .of_match
= of_match_ptr("sbb1"),
315 .regulators_node
= of_match_ptr("regulators"),
316 .supply_name
= "in-sbb1",
317 .id
= MAX77650_REGULATOR_ID_SBB1
,
318 .ops
= &max77650_regulator_SBB_ops
,
322 .vsel_mask
= MAX77650_REGULATOR_V_SBB_MASK
,
323 .vsel_reg
= MAX77650_REG_CNFG_SBB1_A
,
324 .active_discharge_off
= MAX77650_REGULATOR_AD_DISABLED
,
325 .active_discharge_on
= MAX77650_REGULATOR_AD_ENABLED
,
326 .active_discharge_mask
= MAX77650_REGULATOR_AD_MASK
,
327 .active_discharge_reg
= MAX77650_REG_CNFG_SBB1_B
,
329 .type
= REGULATOR_VOLTAGE
,
330 .owner
= THIS_MODULE
,
331 .csel_reg
= MAX77650_REG_CNFG_SBB1_A
,
332 .csel_mask
= MAX77650_REGULATOR_CURR_LIM_MASK
,
333 .curr_table
= max77650_current_limit_table
,
334 .n_current_limits
= ARRAY_SIZE(max77650_current_limit_table
),
336 .regA
= MAX77650_REG_CNFG_SBB1_A
,
337 .regB
= MAX77650_REG_CNFG_SBB1_B
,
340 static struct max77650_regulator_desc max77651_SBB1_desc
= {
343 .of_match
= of_match_ptr("sbb1"),
344 .regulators_node
= of_match_ptr("regulators"),
345 .supply_name
= "in-sbb1",
346 .id
= MAX77650_REGULATOR_ID_SBB1
,
347 .ops
= &max77651_SBB1_regulator_ops
,
348 .volt_table
= max77651_sbb1_regulator_volt_table
,
349 .n_voltages
= ARRAY_SIZE(max77651_sbb1_regulator_volt_table
),
350 .vsel_mask
= MAX77650_REGULATOR_V_SBB_MASK
,
351 .vsel_reg
= MAX77650_REG_CNFG_SBB1_A
,
352 .active_discharge_off
= MAX77650_REGULATOR_AD_DISABLED
,
353 .active_discharge_on
= MAX77650_REGULATOR_AD_ENABLED
,
354 .active_discharge_mask
= MAX77650_REGULATOR_AD_MASK
,
355 .active_discharge_reg
= MAX77650_REG_CNFG_SBB1_B
,
357 .type
= REGULATOR_VOLTAGE
,
358 .owner
= THIS_MODULE
,
359 .csel_reg
= MAX77650_REG_CNFG_SBB1_A
,
360 .csel_mask
= MAX77650_REGULATOR_CURR_LIM_MASK
,
361 .curr_table
= max77650_current_limit_table
,
362 .n_current_limits
= ARRAY_SIZE(max77650_current_limit_table
),
364 .regA
= MAX77650_REG_CNFG_SBB1_A
,
365 .regB
= MAX77650_REG_CNFG_SBB1_B
,
368 static struct max77650_regulator_desc max77650_SBB2_desc
= {
371 .of_match
= of_match_ptr("sbb2"),
372 .regulators_node
= of_match_ptr("regulators"),
373 .supply_name
= "in-sbb0",
374 .id
= MAX77650_REGULATOR_ID_SBB2
,
375 .ops
= &max77650_regulator_SBB_ops
,
379 .vsel_mask
= MAX77650_REGULATOR_V_SBB_MASK
,
380 .vsel_reg
= MAX77650_REG_CNFG_SBB2_A
,
381 .active_discharge_off
= MAX77650_REGULATOR_AD_DISABLED
,
382 .active_discharge_on
= MAX77650_REGULATOR_AD_ENABLED
,
383 .active_discharge_mask
= MAX77650_REGULATOR_AD_MASK
,
384 .active_discharge_reg
= MAX77650_REG_CNFG_SBB2_B
,
386 .type
= REGULATOR_VOLTAGE
,
387 .owner
= THIS_MODULE
,
388 .csel_reg
= MAX77650_REG_CNFG_SBB2_A
,
389 .csel_mask
= MAX77650_REGULATOR_CURR_LIM_MASK
,
390 .curr_table
= max77650_current_limit_table
,
391 .n_current_limits
= ARRAY_SIZE(max77650_current_limit_table
),
393 .regA
= MAX77650_REG_CNFG_SBB2_A
,
394 .regB
= MAX77650_REG_CNFG_SBB2_B
,
397 static struct max77650_regulator_desc max77651_SBB2_desc
= {
400 .of_match
= of_match_ptr("sbb2"),
401 .regulators_node
= of_match_ptr("regulators"),
402 .supply_name
= "in-sbb0",
403 .id
= MAX77650_REGULATOR_ID_SBB2
,
404 .ops
= &max77650_regulator_SBB_ops
,
408 .vsel_mask
= MAX77650_REGULATOR_V_SBB_MASK
,
409 .vsel_reg
= MAX77650_REG_CNFG_SBB2_A
,
410 .active_discharge_off
= MAX77650_REGULATOR_AD_DISABLED
,
411 .active_discharge_on
= MAX77650_REGULATOR_AD_ENABLED
,
412 .active_discharge_mask
= MAX77650_REGULATOR_AD_MASK
,
413 .active_discharge_reg
= MAX77650_REG_CNFG_SBB2_B
,
415 .type
= REGULATOR_VOLTAGE
,
416 .owner
= THIS_MODULE
,
417 .csel_reg
= MAX77650_REG_CNFG_SBB2_A
,
418 .csel_mask
= MAX77650_REGULATOR_CURR_LIM_MASK
,
419 .curr_table
= max77650_current_limit_table
,
420 .n_current_limits
= ARRAY_SIZE(max77650_current_limit_table
),
422 .regA
= MAX77650_REG_CNFG_SBB2_A
,
423 .regB
= MAX77650_REG_CNFG_SBB2_B
,
426 static int max77650_regulator_probe(struct platform_device
*pdev
)
428 struct max77650_regulator_desc
**rdescs
;
429 struct max77650_regulator_desc
*rdesc
;
430 struct regulator_config config
= { };
431 struct device
*dev
, *parent
;
432 struct regulator_dev
*rdev
;
438 parent
= dev
->parent
;
441 dev
->of_node
= parent
->of_node
;
443 rdescs
= devm_kcalloc(dev
, MAX77650_REGULATOR_NUM_REGULATORS
,
444 sizeof(*rdescs
), GFP_KERNEL
);
448 map
= dev_get_regmap(parent
, NULL
);
452 rv
= regmap_read(map
, MAX77650_REG_CID
, &val
);
456 rdescs
[MAX77650_REGULATOR_ID_LDO
] = &max77650_LDO_desc
;
457 rdescs
[MAX77650_REGULATOR_ID_SBB0
] = &max77650_SBB0_desc
;
459 switch (MAX77650_CID_BITS(val
)) {
460 case MAX77650_CID_77650A
:
461 case MAX77650_CID_77650C
:
462 rdescs
[MAX77650_REGULATOR_ID_SBB1
] = &max77650_SBB1_desc
;
463 rdescs
[MAX77650_REGULATOR_ID_SBB2
] = &max77650_SBB2_desc
;
465 case MAX77650_CID_77651A
:
466 case MAX77650_CID_77651B
:
467 rdescs
[MAX77650_REGULATOR_ID_SBB1
] = &max77651_SBB1_desc
;
468 rdescs
[MAX77650_REGULATOR_ID_SBB2
] = &max77651_SBB2_desc
;
476 for (i
= 0; i
< MAX77650_REGULATOR_NUM_REGULATORS
; i
++) {
478 config
.driver_data
= rdesc
;
480 rdev
= devm_regulator_register(dev
, &rdesc
->desc
, &config
);
482 return PTR_ERR(rdev
);
488 static struct platform_driver max77650_regulator_driver
= {
490 .name
= "max77650-regulator",
492 .probe
= max77650_regulator_probe
,
494 module_platform_driver(max77650_regulator_driver
);
496 MODULE_DESCRIPTION("MAXIM 77650/77651 regulator driver");
497 MODULE_AUTHOR("Bartosz Golaszewski <bgolaszewski@baylibre.com>");
498 MODULE_LICENSE("GPL v2");