1 // SPDX-License-Identifier: GPL-2.0
3 // Copyright (C) 2018 BayLibre SAS
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 u32 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");
498 MODULE_LICENSE("GPL v2");