xref: /linux/drivers/regulator/max77650-regulator.c (revision 9a8f32038a74cb800e9649afbf4b3dba2b7d6539)
1 // SPDX-License-Identifier: GPL-2.0
2 //
3 // Copyright (C) 2018 BayLibre SAS
4 // Author: Bartosz Golaszewski <bgolaszewski@baylibre.com>
5 //
6 // Regulator driver for MAXIM 77650/77651 charger/power-supply.
7 
8 #include <linux/of.h>
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>
14 
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)
20 
21 #define MAX77650_REGULATOR_V_LDO_MASK		GENMASK(6, 0)
22 #define MAX77650_REGULATOR_V_SBB_MASK		GENMASK(5, 0)
23 
24 #define MAX77650_REGULATOR_AD_MASK		BIT(3)
25 #define MAX77650_REGULATOR_AD_DISABLED		0x00
26 #define MAX77650_REGULATOR_AD_ENABLED		BIT(3)
27 
28 #define MAX77650_REGULATOR_CURR_LIM_MASK	GENMASK(7, 6)
29 
30 enum {
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,
36 };
37 
38 struct max77650_regulator_desc {
39 	struct regulator_desc desc;
40 	unsigned int regA;
41 	unsigned int regB;
42 };
43 
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,
61 };
62 
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))
67 
68 #define MAX77650_REGULATOR_SBB1_SEL_DECR(_val)				\
69 	do {								\
70 		_val = MAX77651_REGULATOR_SBB1_SEL_DEC(_val);		\
71 		_val--;							\
72 		_val = MAX77651_REGULATOR_SBB1_SEL_ENC(_val);		\
73 	} while (0)
74 
75 #define MAX77650_REGULATOR_SBB1_SEL_INCR(_val)				\
76 	do {								\
77 		_val = MAX77651_REGULATOR_SBB1_SEL_DEC(_val);		\
78 		_val++;							\
79 		_val = MAX77651_REGULATOR_SBB1_SEL_ENC(_val);		\
80 	} while (0)
81 
82 static const unsigned int max77650_current_limit_table[] = {
83 	1000000, 866000, 707000, 500000,
84 };
85 
86 static int max77650_regulator_is_enabled(struct regulator_dev *rdev)
87 {
88 	struct max77650_regulator_desc *rdesc;
89 	struct regmap *map;
90 	int val, rv, en;
91 
92 	rdesc = rdev_get_drvdata(rdev);
93 	map = rdev_get_regmap(rdev);
94 
95 	rv = regmap_read(map, rdesc->regB, &val);
96 	if (rv)
97 		return rv;
98 
99 	en = MAX77650_REGULATOR_EN_CTRL_BITS(val);
100 
101 	return en != MAX77650_REGULATOR_DISABLED;
102 }
103 
104 static int max77650_regulator_enable(struct regulator_dev *rdev)
105 {
106 	struct max77650_regulator_desc *rdesc;
107 	struct regmap *map;
108 
109 	rdesc = rdev_get_drvdata(rdev);
110 	map = rdev_get_regmap(rdev);
111 
112 	return regmap_update_bits(map, rdesc->regB,
113 				  MAX77650_REGULATOR_EN_CTRL_MASK,
114 				  MAX77650_REGULATOR_ENABLED);
115 }
116 
117 static int max77650_regulator_disable(struct regulator_dev *rdev)
118 {
119 	struct max77650_regulator_desc *rdesc;
120 	struct regmap *map;
121 
122 	rdesc = rdev_get_drvdata(rdev);
123 	map = rdev_get_regmap(rdev);
124 
125 	return regmap_update_bits(map, rdesc->regB,
126 				  MAX77650_REGULATOR_EN_CTRL_MASK,
127 				  MAX77650_REGULATOR_DISABLED);
128 }
129 
130 static int max77650_regulator_set_voltage_sel(struct regulator_dev *rdev,
131 					      unsigned int sel)
132 {
133 	int rv = 0, curr, diff;
134 	bool ascending;
135 
136 	/*
137 	 * If the regulator is disabled, we can program the desired
138 	 * voltage right away.
139 	 */
140 	if (!max77650_regulator_is_enabled(rdev))
141 		return regulator_set_voltage_sel_regmap(rdev, sel);
142 
143 	/*
144 	 * Otherwise we need to manually ramp the output voltage up/down
145 	 * one step at a time.
146 	 */
147 
148 	curr = regulator_get_voltage_sel_regmap(rdev);
149 	if (curr < 0)
150 		return curr;
151 
152 	diff = curr - sel;
153 	if (diff == 0)
154 		return 0; /* Already there. */
155 	else if (diff > 0)
156 		ascending = false;
157 	else
158 		ascending = true;
159 
160 	/*
161 	 * Make sure we'll get to the right voltage and break the loop even if
162 	 * the selector equals 0.
163 	 */
164 	for (ascending ? curr++ : curr--;; ascending ? curr++ : curr--) {
165 		rv = regulator_set_voltage_sel_regmap(rdev, curr);
166 		if (rv)
167 			return rv;
168 
169 		if (curr == sel)
170 			break;
171 	}
172 
173 	return 0;
174 }
175 
176 /*
177  * Special case: non-linear voltage table for max77651 SBB1 - software
178  * must ensure the voltage is ramped in 50mV increments.
179  */
180 static int max77651_regulator_sbb1_set_voltage_sel(struct regulator_dev *rdev,
181 						   unsigned int sel)
182 {
183 	int rv = 0, curr, vcurr, vdest, vdiff;
184 
185 	/*
186 	 * If the regulator is disabled, we can program the desired
187 	 * voltage right away.
188 	 */
189 	if (!max77650_regulator_is_enabled(rdev))
190 		return regulator_set_voltage_sel_regmap(rdev, sel);
191 
192 	curr = regulator_get_voltage_sel_regmap(rdev);
193 	if (curr < 0)
194 		return curr;
195 
196 	if (curr == sel)
197 		return 0; /* Already there. */
198 
199 	vcurr = max77651_sbb1_regulator_volt_table[curr];
200 	vdest = max77651_sbb1_regulator_volt_table[sel];
201 	vdiff = vcurr - vdest;
202 
203 	for (;;) {
204 		if (vdiff > 0)
205 			MAX77650_REGULATOR_SBB1_SEL_DECR(curr);
206 		else
207 			MAX77650_REGULATOR_SBB1_SEL_INCR(curr);
208 
209 		rv = regulator_set_voltage_sel_regmap(rdev, curr);
210 		if (rv)
211 			return rv;
212 
213 		if (curr == sel)
214 			break;
215 	};
216 
217 	return 0;
218 }
219 
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,
229 };
230 
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,
242 };
243 
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,
255 };
256 
257 static struct max77650_regulator_desc max77650_LDO_desc = {
258 	.desc = {
259 		.name			= "ldo",
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,
265 		.min_uV			= 1350000,
266 		.uV_step		= 12500,
267 		.n_voltages		= 128,
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,
274 		.enable_time		= 100,
275 		.type			= REGULATOR_VOLTAGE,
276 		.owner			= THIS_MODULE,
277 	},
278 	.regA		= MAX77650_REG_CNFG_LDO_A,
279 	.regB		= MAX77650_REG_CNFG_LDO_B,
280 };
281 
282 static struct max77650_regulator_desc max77650_SBB0_desc = {
283 	.desc = {
284 		.name			= "sbb0",
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,
290 		.min_uV			= 800000,
291 		.uV_step		= 25000,
292 		.n_voltages		= 64,
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,
299 		.enable_time		= 100,
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),
306 	},
307 	.regA		= MAX77650_REG_CNFG_SBB0_A,
308 	.regB		= MAX77650_REG_CNFG_SBB0_B,
309 };
310 
311 static struct max77650_regulator_desc max77650_SBB1_desc = {
312 	.desc = {
313 		.name			= "sbb1",
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,
319 		.min_uV			= 800000,
320 		.uV_step		= 12500,
321 		.n_voltages		= 64,
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,
328 		.enable_time		= 100,
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),
335 	},
336 	.regA		= MAX77650_REG_CNFG_SBB1_A,
337 	.regB		= MAX77650_REG_CNFG_SBB1_B,
338 };
339 
340 static struct max77650_regulator_desc max77651_SBB1_desc = {
341 	.desc = {
342 		.name			= "sbb1",
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,
356 		.enable_time		= 100,
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),
363 	},
364 	.regA		= MAX77650_REG_CNFG_SBB1_A,
365 	.regB		= MAX77650_REG_CNFG_SBB1_B,
366 };
367 
368 static struct max77650_regulator_desc max77650_SBB2_desc = {
369 	.desc = {
370 		.name			= "sbb2",
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,
376 		.min_uV			= 800000,
377 		.uV_step		= 50000,
378 		.n_voltages		= 64,
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,
385 		.enable_time		= 100,
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),
392 	},
393 	.regA		= MAX77650_REG_CNFG_SBB2_A,
394 	.regB		= MAX77650_REG_CNFG_SBB2_B,
395 };
396 
397 static struct max77650_regulator_desc max77651_SBB2_desc = {
398 	.desc = {
399 		.name			= "sbb2",
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,
405 		.min_uV			= 2400000,
406 		.uV_step		= 50000,
407 		.n_voltages		= 64,
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,
414 		.enable_time		= 100,
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),
421 	},
422 	.regA		= MAX77650_REG_CNFG_SBB2_A,
423 	.regB		= MAX77650_REG_CNFG_SBB2_B,
424 };
425 
426 static int max77650_regulator_probe(struct platform_device *pdev)
427 {
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;
433 	struct regmap *map;
434 	unsigned int val;
435 	int i, rv;
436 
437 	dev = &pdev->dev;
438 	parent = dev->parent;
439 
440 	if (!dev->of_node)
441 		dev->of_node = parent->of_node;
442 
443 	rdescs = devm_kcalloc(dev, MAX77650_REGULATOR_NUM_REGULATORS,
444 			      sizeof(*rdescs), GFP_KERNEL);
445 	if (!rdescs)
446 		return -ENOMEM;
447 
448 	map = dev_get_regmap(parent, NULL);
449 	if (!map)
450 		return -ENODEV;
451 
452 	rv = regmap_read(map, MAX77650_REG_CID, &val);
453 	if (rv)
454 		return rv;
455 
456 	rdescs[MAX77650_REGULATOR_ID_LDO] = &max77650_LDO_desc;
457 	rdescs[MAX77650_REGULATOR_ID_SBB0] = &max77650_SBB0_desc;
458 
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;
464 		break;
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;
469 		break;
470 	default:
471 		return -ENODEV;
472 	}
473 
474 	config.dev = parent;
475 
476 	for (i = 0; i < MAX77650_REGULATOR_NUM_REGULATORS; i++) {
477 		rdesc = rdescs[i];
478 		config.driver_data = rdesc;
479 
480 		rdev = devm_regulator_register(dev, &rdesc->desc, &config);
481 		if (IS_ERR(rdev))
482 			return PTR_ERR(rdev);
483 	}
484 
485 	return 0;
486 }
487 
488 static struct platform_driver max77650_regulator_driver = {
489 	.driver = {
490 		.name = "max77650-regulator",
491 	},
492 	.probe = max77650_regulator_probe,
493 };
494 module_platform_driver(max77650_regulator_driver);
495 
496 MODULE_DESCRIPTION("MAXIM 77650/77651 regulator driver");
497 MODULE_AUTHOR("Bartosz Golaszewski <bgolaszewski@baylibre.com>");
498 MODULE_LICENSE("GPL v2");
499