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#define MAX77651_REGULATOR_V_SBB1_MASK		GENMASK(5, 2)
24#define MAX77651_REGULATOR_V_SBB1_RANGE_MASK	GENMASK(1, 0)
25
26#define MAX77650_REGULATOR_AD_MASK		BIT(3)
27#define MAX77650_REGULATOR_AD_DISABLED		0x00
28#define MAX77650_REGULATOR_AD_ENABLED		BIT(3)
29
30#define MAX77650_REGULATOR_CURR_LIM_MASK	GENMASK(7, 6)
31
32enum {
33	MAX77650_REGULATOR_ID_LDO = 0,
34	MAX77650_REGULATOR_ID_SBB0,
35	MAX77650_REGULATOR_ID_SBB1,
36	MAX77650_REGULATOR_ID_SBB2,
37	MAX77650_REGULATOR_NUM_REGULATORS,
38};
39
40struct max77650_regulator_desc {
41	struct regulator_desc desc;
42	unsigned int regA;
43	unsigned int regB;
44};
45
46static struct max77650_regulator_desc max77651_SBB1_desc;
47
48static const unsigned int max77651_sbb1_volt_range_sel[] = {
49	0x0, 0x1, 0x2, 0x3
50};
51
52static const struct linear_range max77651_sbb1_volt_ranges[] = {
53	/* range index 0 */
54	REGULATOR_LINEAR_RANGE(2400000, 0x00, 0x0f, 50000),
55	/* range index 1 */
56	REGULATOR_LINEAR_RANGE(3200000, 0x00, 0x0f, 50000),
57	/* range index 2 */
58	REGULATOR_LINEAR_RANGE(4000000, 0x00, 0x0f, 50000),
59	/* range index 3 */
60	REGULATOR_LINEAR_RANGE(4800000, 0x00, 0x09, 50000),
61};
62
63static const unsigned int max77650_current_limit_table[] = {
64	1000000, 866000, 707000, 500000,
65};
66
67static int max77650_regulator_is_enabled(struct regulator_dev *rdev)
68{
69	struct max77650_regulator_desc *rdesc;
70	struct regmap *map;
71	int val, rv, en;
72
73	rdesc = rdev_get_drvdata(rdev);
74	map = rdev_get_regmap(rdev);
75
76	rv = regmap_read(map, rdesc->regB, &val);
77	if (rv)
78		return rv;
79
80	en = MAX77650_REGULATOR_EN_CTRL_BITS(val);
81
82	return en != MAX77650_REGULATOR_DISABLED;
83}
84
85static int max77650_regulator_enable(struct regulator_dev *rdev)
86{
87	struct max77650_regulator_desc *rdesc;
88	struct regmap *map;
89
90	rdesc = rdev_get_drvdata(rdev);
91	map = rdev_get_regmap(rdev);
92
93	return regmap_update_bits(map, rdesc->regB,
94				  MAX77650_REGULATOR_EN_CTRL_MASK,
95				  MAX77650_REGULATOR_ENABLED);
96}
97
98static int max77650_regulator_disable(struct regulator_dev *rdev)
99{
100	struct max77650_regulator_desc *rdesc;
101	struct regmap *map;
102
103	rdesc = rdev_get_drvdata(rdev);
104	map = rdev_get_regmap(rdev);
105
106	return regmap_update_bits(map, rdesc->regB,
107				  MAX77650_REGULATOR_EN_CTRL_MASK,
108				  MAX77650_REGULATOR_DISABLED);
109}
110
111static const struct regulator_ops max77650_regulator_LDO_ops = {
112	.is_enabled		= max77650_regulator_is_enabled,
113	.enable			= max77650_regulator_enable,
114	.disable		= max77650_regulator_disable,
115	.list_voltage		= regulator_list_voltage_linear,
116	.map_voltage		= regulator_map_voltage_linear,
117	.get_voltage_sel	= regulator_get_voltage_sel_regmap,
118	.set_voltage_sel	= regulator_set_voltage_sel_regmap,
119	.set_active_discharge	= regulator_set_active_discharge_regmap,
120};
121
122static const struct regulator_ops max77650_regulator_SBB_ops = {
123	.is_enabled		= max77650_regulator_is_enabled,
124	.enable			= max77650_regulator_enable,
125	.disable		= max77650_regulator_disable,
126	.list_voltage		= regulator_list_voltage_linear,
127	.map_voltage		= regulator_map_voltage_linear,
128	.get_voltage_sel	= regulator_get_voltage_sel_regmap,
129	.set_voltage_sel	= regulator_set_voltage_sel_regmap,
130	.get_current_limit	= regulator_get_current_limit_regmap,
131	.set_current_limit	= regulator_set_current_limit_regmap,
132	.set_active_discharge	= regulator_set_active_discharge_regmap,
133};
134
135/* Special case for max77651 SBB1 - pickable linear-range voltage mapping. */
136static const struct regulator_ops max77651_SBB1_regulator_ops = {
137	.is_enabled		= max77650_regulator_is_enabled,
138	.enable			= max77650_regulator_enable,
139	.disable		= max77650_regulator_disable,
140	.list_voltage		= regulator_list_voltage_pickable_linear_range,
141	.get_voltage_sel	= regulator_get_voltage_sel_pickable_regmap,
142	.set_voltage_sel	= regulator_set_voltage_sel_pickable_regmap,
143	.get_current_limit	= regulator_get_current_limit_regmap,
144	.set_current_limit	= regulator_set_current_limit_regmap,
145	.set_active_discharge	= regulator_set_active_discharge_regmap,
146};
147
148static struct max77650_regulator_desc max77650_LDO_desc = {
149	.desc = {
150		.name			= "ldo",
151		.of_match		= of_match_ptr("ldo"),
152		.regulators_node	= of_match_ptr("regulators"),
153		.supply_name		= "in-ldo",
154		.id			= MAX77650_REGULATOR_ID_LDO,
155		.ops			= &max77650_regulator_LDO_ops,
156		.min_uV			= 1350000,
157		.uV_step		= 12500,
158		.n_voltages		= 128,
159		.vsel_step		= 1,
160		.vsel_mask		= MAX77650_REGULATOR_V_LDO_MASK,
161		.vsel_reg		= MAX77650_REG_CNFG_LDO_A,
162		.active_discharge_off	= MAX77650_REGULATOR_AD_DISABLED,
163		.active_discharge_on	= MAX77650_REGULATOR_AD_ENABLED,
164		.active_discharge_mask	= MAX77650_REGULATOR_AD_MASK,
165		.active_discharge_reg	= MAX77650_REG_CNFG_LDO_B,
166		.enable_time		= 100,
167		.type			= REGULATOR_VOLTAGE,
168		.owner			= THIS_MODULE,
169	},
170	.regA		= MAX77650_REG_CNFG_LDO_A,
171	.regB		= MAX77650_REG_CNFG_LDO_B,
172};
173
174static struct max77650_regulator_desc max77650_SBB0_desc = {
175	.desc = {
176		.name			= "sbb0",
177		.of_match		= of_match_ptr("sbb0"),
178		.regulators_node	= of_match_ptr("regulators"),
179		.supply_name		= "in-sbb0",
180		.id			= MAX77650_REGULATOR_ID_SBB0,
181		.ops			= &max77650_regulator_SBB_ops,
182		.min_uV			= 800000,
183		.uV_step		= 25000,
184		.n_voltages		= 64,
185		.vsel_step		= 1,
186		.vsel_mask		= MAX77650_REGULATOR_V_SBB_MASK,
187		.vsel_reg		= MAX77650_REG_CNFG_SBB0_A,
188		.active_discharge_off	= MAX77650_REGULATOR_AD_DISABLED,
189		.active_discharge_on	= MAX77650_REGULATOR_AD_ENABLED,
190		.active_discharge_mask	= MAX77650_REGULATOR_AD_MASK,
191		.active_discharge_reg	= MAX77650_REG_CNFG_SBB0_B,
192		.enable_time		= 100,
193		.type			= REGULATOR_VOLTAGE,
194		.owner			= THIS_MODULE,
195		.csel_reg		= MAX77650_REG_CNFG_SBB0_A,
196		.csel_mask		= MAX77650_REGULATOR_CURR_LIM_MASK,
197		.curr_table		= max77650_current_limit_table,
198		.n_current_limits = ARRAY_SIZE(max77650_current_limit_table),
199	},
200	.regA		= MAX77650_REG_CNFG_SBB0_A,
201	.regB		= MAX77650_REG_CNFG_SBB0_B,
202};
203
204static struct max77650_regulator_desc max77650_SBB1_desc = {
205	.desc = {
206		.name			= "sbb1",
207		.of_match		= of_match_ptr("sbb1"),
208		.regulators_node	= of_match_ptr("regulators"),
209		.supply_name		= "in-sbb1",
210		.id			= MAX77650_REGULATOR_ID_SBB1,
211		.ops			= &max77650_regulator_SBB_ops,
212		.min_uV			= 800000,
213		.uV_step		= 12500,
214		.n_voltages		= 64,
215		.vsel_step		= 1,
216		.vsel_mask		= MAX77650_REGULATOR_V_SBB_MASK,
217		.vsel_reg		= MAX77650_REG_CNFG_SBB1_A,
218		.active_discharge_off	= MAX77650_REGULATOR_AD_DISABLED,
219		.active_discharge_on	= MAX77650_REGULATOR_AD_ENABLED,
220		.active_discharge_mask	= MAX77650_REGULATOR_AD_MASK,
221		.active_discharge_reg	= MAX77650_REG_CNFG_SBB1_B,
222		.enable_time		= 100,
223		.type			= REGULATOR_VOLTAGE,
224		.owner			= THIS_MODULE,
225		.csel_reg		= MAX77650_REG_CNFG_SBB1_A,
226		.csel_mask		= MAX77650_REGULATOR_CURR_LIM_MASK,
227		.curr_table		= max77650_current_limit_table,
228		.n_current_limits = ARRAY_SIZE(max77650_current_limit_table),
229	},
230	.regA		= MAX77650_REG_CNFG_SBB1_A,
231	.regB		= MAX77650_REG_CNFG_SBB1_B,
232};
233
234static struct max77650_regulator_desc max77651_SBB1_desc = {
235	.desc = {
236		.name			= "sbb1",
237		.of_match		= of_match_ptr("sbb1"),
238		.regulators_node	= of_match_ptr("regulators"),
239		.supply_name		= "in-sbb1",
240		.id			= MAX77650_REGULATOR_ID_SBB1,
241		.ops			= &max77651_SBB1_regulator_ops,
242		.linear_range_selectors_bitfield	= max77651_sbb1_volt_range_sel,
243		.linear_ranges		= max77651_sbb1_volt_ranges,
244		.n_linear_ranges	= ARRAY_SIZE(max77651_sbb1_volt_ranges),
245		.n_voltages		= 58,
246		.vsel_step		= 1,
247		.vsel_range_mask	= MAX77651_REGULATOR_V_SBB1_RANGE_MASK,
248		.vsel_range_reg		= MAX77650_REG_CNFG_SBB1_A,
249		.vsel_mask		= MAX77651_REGULATOR_V_SBB1_MASK,
250		.vsel_reg		= MAX77650_REG_CNFG_SBB1_A,
251		.active_discharge_off	= MAX77650_REGULATOR_AD_DISABLED,
252		.active_discharge_on	= MAX77650_REGULATOR_AD_ENABLED,
253		.active_discharge_mask	= MAX77650_REGULATOR_AD_MASK,
254		.active_discharge_reg	= MAX77650_REG_CNFG_SBB1_B,
255		.enable_time		= 100,
256		.type			= REGULATOR_VOLTAGE,
257		.owner			= THIS_MODULE,
258		.csel_reg		= MAX77650_REG_CNFG_SBB1_A,
259		.csel_mask		= MAX77650_REGULATOR_CURR_LIM_MASK,
260		.curr_table		= max77650_current_limit_table,
261		.n_current_limits = ARRAY_SIZE(max77650_current_limit_table),
262	},
263	.regA		= MAX77650_REG_CNFG_SBB1_A,
264	.regB		= MAX77650_REG_CNFG_SBB1_B,
265};
266
267static struct max77650_regulator_desc max77650_SBB2_desc = {
268	.desc = {
269		.name			= "sbb2",
270		.of_match		= of_match_ptr("sbb2"),
271		.regulators_node	= of_match_ptr("regulators"),
272		.supply_name		= "in-sbb0",
273		.id			= MAX77650_REGULATOR_ID_SBB2,
274		.ops			= &max77650_regulator_SBB_ops,
275		.min_uV			= 800000,
276		.uV_step		= 50000,
277		.n_voltages		= 64,
278		.vsel_step		= 1,
279		.vsel_mask		= MAX77650_REGULATOR_V_SBB_MASK,
280		.vsel_reg		= MAX77650_REG_CNFG_SBB2_A,
281		.active_discharge_off	= MAX77650_REGULATOR_AD_DISABLED,
282		.active_discharge_on	= MAX77650_REGULATOR_AD_ENABLED,
283		.active_discharge_mask	= MAX77650_REGULATOR_AD_MASK,
284		.active_discharge_reg	= MAX77650_REG_CNFG_SBB2_B,
285		.enable_time		= 100,
286		.type			= REGULATOR_VOLTAGE,
287		.owner			= THIS_MODULE,
288		.csel_reg		= MAX77650_REG_CNFG_SBB2_A,
289		.csel_mask		= MAX77650_REGULATOR_CURR_LIM_MASK,
290		.curr_table		= max77650_current_limit_table,
291		.n_current_limits = ARRAY_SIZE(max77650_current_limit_table),
292	},
293	.regA		= MAX77650_REG_CNFG_SBB2_A,
294	.regB		= MAX77650_REG_CNFG_SBB2_B,
295};
296
297static struct max77650_regulator_desc max77651_SBB2_desc = {
298	.desc = {
299		.name			= "sbb2",
300		.of_match		= of_match_ptr("sbb2"),
301		.regulators_node	= of_match_ptr("regulators"),
302		.supply_name		= "in-sbb0",
303		.id			= MAX77650_REGULATOR_ID_SBB2,
304		.ops			= &max77650_regulator_SBB_ops,
305		.min_uV			= 2400000,
306		.uV_step		= 50000,
307		.n_voltages		= 64,
308		.vsel_step		= 1,
309		.vsel_mask		= MAX77650_REGULATOR_V_SBB_MASK,
310		.vsel_reg		= MAX77650_REG_CNFG_SBB2_A,
311		.active_discharge_off	= MAX77650_REGULATOR_AD_DISABLED,
312		.active_discharge_on	= MAX77650_REGULATOR_AD_ENABLED,
313		.active_discharge_mask	= MAX77650_REGULATOR_AD_MASK,
314		.active_discharge_reg	= MAX77650_REG_CNFG_SBB2_B,
315		.enable_time		= 100,
316		.type			= REGULATOR_VOLTAGE,
317		.owner			= THIS_MODULE,
318		.csel_reg		= MAX77650_REG_CNFG_SBB2_A,
319		.csel_mask		= MAX77650_REGULATOR_CURR_LIM_MASK,
320		.curr_table		= max77650_current_limit_table,
321		.n_current_limits = ARRAY_SIZE(max77650_current_limit_table),
322	},
323	.regA		= MAX77650_REG_CNFG_SBB2_A,
324	.regB		= MAX77650_REG_CNFG_SBB2_B,
325};
326
327static int max77650_regulator_probe(struct platform_device *pdev)
328{
329	struct max77650_regulator_desc **rdescs;
330	struct max77650_regulator_desc *rdesc;
331	struct regulator_config config = { };
332	struct device *dev, *parent;
333	struct regulator_dev *rdev;
334	struct regmap *map;
335	unsigned int val;
336	int i, rv;
337
338	dev = &pdev->dev;
339	parent = dev->parent;
340
341	if (!dev->of_node)
342		dev->of_node = parent->of_node;
343
344	rdescs = devm_kcalloc(dev, MAX77650_REGULATOR_NUM_REGULATORS,
345			      sizeof(*rdescs), GFP_KERNEL);
346	if (!rdescs)
347		return -ENOMEM;
348
349	map = dev_get_regmap(parent, NULL);
350	if (!map)
351		return -ENODEV;
352
353	rv = regmap_read(map, MAX77650_REG_CID, &val);
354	if (rv)
355		return rv;
356
357	rdescs[MAX77650_REGULATOR_ID_LDO] = &max77650_LDO_desc;
358	rdescs[MAX77650_REGULATOR_ID_SBB0] = &max77650_SBB0_desc;
359
360	switch (MAX77650_CID_BITS(val)) {
361	case MAX77650_CID_77650A:
362	case MAX77650_CID_77650C:
363		rdescs[MAX77650_REGULATOR_ID_SBB1] = &max77650_SBB1_desc;
364		rdescs[MAX77650_REGULATOR_ID_SBB2] = &max77650_SBB2_desc;
365		break;
366	case MAX77650_CID_77651A:
367	case MAX77650_CID_77651B:
368		rdescs[MAX77650_REGULATOR_ID_SBB1] = &max77651_SBB1_desc;
369		rdescs[MAX77650_REGULATOR_ID_SBB2] = &max77651_SBB2_desc;
370		break;
371	default:
372		return -ENODEV;
373	}
374
375	config.dev = parent;
376
377	for (i = 0; i < MAX77650_REGULATOR_NUM_REGULATORS; i++) {
378		rdesc = rdescs[i];
379		config.driver_data = rdesc;
380
381		rdev = devm_regulator_register(dev, &rdesc->desc, &config);
382		if (IS_ERR(rdev))
383			return PTR_ERR(rdev);
384	}
385
386	return 0;
387}
388
389static const struct of_device_id max77650_regulator_of_match[] = {
390	{ .compatible = "maxim,max77650-regulator" },
391	{ }
392};
393MODULE_DEVICE_TABLE(of, max77650_regulator_of_match);
394
395static struct platform_driver max77650_regulator_driver = {
396	.driver = {
397		.name = "max77650-regulator",
398		.probe_type = PROBE_PREFER_ASYNCHRONOUS,
399		.of_match_table = max77650_regulator_of_match,
400	},
401	.probe = max77650_regulator_probe,
402};
403module_platform_driver(max77650_regulator_driver);
404
405MODULE_DESCRIPTION("MAXIM 77650/77651 regulator driver");
406MODULE_AUTHOR("Bartosz Golaszewski <bgolaszewski@baylibre.com>");
407MODULE_LICENSE("GPL v2");
408MODULE_ALIAS("platform:max77650-regulator");
409