1 /*
2  * max8907-regulator.c -- support regulators in max8907
3  *
4  * Copyright (C) 2010 Gyungoh Yoo <jack.yoo@maxim-ic.com>
5  * Copyright (C) 2010-2012, NVIDIA CORPORATION. All rights reserved.
6  *
7  * Portions based on drivers/regulator/tps65910-regulator.c,
8  *     Copyright 2010 Texas Instruments Inc.
9  *     Author: Graeme Gregory <gg@slimlogic.co.uk>
10  *     Author: Jorge Eduardo Candelaria <jedu@slimlogic.co.uk>
11  *
12  * This program is free software; you can redistribute it and/or modify
13  * it under the terms of the GNU General Public License version 2 as
14  * published by the Free Software Foundation.
15  */
16 
17 #include <linux/err.h>
18 #include <linux/init.h>
19 #include <linux/mfd/core.h>
20 #include <linux/mfd/max8907.h>
21 #include <linux/module.h>
22 #include <linux/of.h>
23 #include <linux/platform_device.h>
24 #include <linux/regulator/driver.h>
25 #include <linux/regulator/machine.h>
26 #include <linux/regulator/of_regulator.h>
27 #include <linux/regmap.h>
28 #include <linux/slab.h>
29 
30 #define MAX8907_II2RR_VERSION_MASK	0xF0
31 #define MAX8907_II2RR_VERSION_REV_A	0x00
32 #define MAX8907_II2RR_VERSION_REV_B	0x10
33 #define MAX8907_II2RR_VERSION_REV_C	0x30
34 
35 struct max8907_regulator {
36 	struct regulator_desc desc[MAX8907_NUM_REGULATORS];
37 };
38 
39 #define REG_MBATT() \
40 	[MAX8907_MBATT] = { \
41 		.name = "MBATT", \
42 		.supply_name = "mbatt", \
43 		.id = MAX8907_MBATT, \
44 		.ops = &max8907_mbatt_ops, \
45 		.type = REGULATOR_VOLTAGE, \
46 		.owner = THIS_MODULE, \
47 	}
48 
49 #define REG_LDO(ids, supply, base, min, max, step) \
50 	[MAX8907_##ids] = { \
51 		.name = #ids, \
52 		.supply_name = supply, \
53 		.id = MAX8907_##ids, \
54 		.n_voltages = ((max) - (min)) / (step) + 1, \
55 		.ops = &max8907_ldo_ops, \
56 		.type = REGULATOR_VOLTAGE, \
57 		.owner = THIS_MODULE, \
58 		.min_uV = (min), \
59 		.uV_step = (step), \
60 		.vsel_reg = (base) + MAX8907_VOUT, \
61 		.vsel_mask = 0x3f, \
62 		.enable_reg = (base) + MAX8907_CTL, \
63 		.enable_mask = MAX8907_MASK_LDO_EN, \
64 	}
65 
66 #define REG_FIXED(ids, supply, voltage) \
67 	[MAX8907_##ids] = { \
68 		.name = #ids, \
69 		.supply_name = supply, \
70 		.id = MAX8907_##ids, \
71 		.n_voltages = 1, \
72 		.ops = &max8907_fixed_ops, \
73 		.type = REGULATOR_VOLTAGE, \
74 		.owner = THIS_MODULE, \
75 		.min_uV = (voltage), \
76 	}
77 
78 #define REG_OUT5V(ids, supply, base, voltage) \
79 	[MAX8907_##ids] = { \
80 		.name = #ids, \
81 		.supply_name = supply, \
82 		.id = MAX8907_##ids, \
83 		.n_voltages = 1, \
84 		.ops = &max8907_out5v_ops, \
85 		.type = REGULATOR_VOLTAGE, \
86 		.owner = THIS_MODULE, \
87 		.min_uV = (voltage), \
88 		.enable_reg = (base), \
89 		.enable_mask = MAX8907_MASK_OUT5V_EN, \
90 	}
91 
92 #define REG_BBAT(ids, supply, base, min, max, step) \
93 	[MAX8907_##ids] = { \
94 		.name = #ids, \
95 		.supply_name = supply, \
96 		.id = MAX8907_##ids, \
97 		.n_voltages = ((max) - (min)) / (step) + 1, \
98 		.ops = &max8907_bbat_ops, \
99 		.type = REGULATOR_VOLTAGE, \
100 		.owner = THIS_MODULE, \
101 		.min_uV = (min), \
102 		.uV_step = (step), \
103 		.vsel_reg = (base), \
104 		.vsel_mask = MAX8907_MASK_VBBATTCV, \
105 	}
106 
107 #define LDO_750_50(id, supply, base) REG_LDO(id, supply, (base), \
108 			750000, 3900000, 50000)
109 #define LDO_650_25(id, supply, base) REG_LDO(id, supply, (base), \
110 			650000, 2225000, 25000)
111 
112 static const struct regulator_ops max8907_mbatt_ops = {
113 };
114 
115 static struct regulator_ops max8907_ldo_ops = {
116 	.list_voltage = regulator_list_voltage_linear,
117 	.set_voltage_sel = regulator_set_voltage_sel_regmap,
118 	.get_voltage_sel = regulator_get_voltage_sel_regmap,
119 	.enable = regulator_enable_regmap,
120 	.disable = regulator_disable_regmap,
121 	.is_enabled = regulator_is_enabled_regmap,
122 };
123 
124 static const struct regulator_ops max8907_ldo_hwctl_ops = {
125 	.list_voltage = regulator_list_voltage_linear,
126 	.set_voltage_sel = regulator_set_voltage_sel_regmap,
127 	.get_voltage_sel = regulator_get_voltage_sel_regmap,
128 };
129 
130 static const struct regulator_ops max8907_fixed_ops = {
131 	.list_voltage = regulator_list_voltage_linear,
132 };
133 
134 static struct regulator_ops max8907_out5v_ops = {
135 	.list_voltage = regulator_list_voltage_linear,
136 	.enable = regulator_enable_regmap,
137 	.disable = regulator_disable_regmap,
138 	.is_enabled = regulator_is_enabled_regmap,
139 };
140 
141 static const struct regulator_ops max8907_out5v_hwctl_ops = {
142 	.list_voltage = regulator_list_voltage_linear,
143 };
144 
145 static const struct regulator_ops max8907_bbat_ops = {
146 	.list_voltage = regulator_list_voltage_linear,
147 	.set_voltage_sel = regulator_set_voltage_sel_regmap,
148 	.get_voltage_sel = regulator_get_voltage_sel_regmap,
149 };
150 
151 static struct regulator_desc max8907_regulators[] = {
152 	REG_MBATT(),
153 	REG_LDO(SD1, "in-v1", MAX8907_REG_SDCTL1, 650000, 2225000, 25000),
154 	REG_LDO(SD2, "in-v2", MAX8907_REG_SDCTL2, 637500, 1425000, 12500),
155 	REG_LDO(SD3, "in-v3", MAX8907_REG_SDCTL3, 750000, 3900000, 50000),
156 	LDO_750_50(LDO1, "in1", MAX8907_REG_LDOCTL1),
157 	LDO_650_25(LDO2, "in2", MAX8907_REG_LDOCTL2),
158 	LDO_650_25(LDO3, "in3", MAX8907_REG_LDOCTL3),
159 	LDO_750_50(LDO4, "in4", MAX8907_REG_LDOCTL4),
160 	LDO_750_50(LDO5, "in5", MAX8907_REG_LDOCTL5),
161 	LDO_750_50(LDO6, "in6", MAX8907_REG_LDOCTL6),
162 	LDO_750_50(LDO7, "in7", MAX8907_REG_LDOCTL7),
163 	LDO_750_50(LDO8, "in8", MAX8907_REG_LDOCTL8),
164 	LDO_750_50(LDO9, "in9", MAX8907_REG_LDOCTL9),
165 	LDO_750_50(LDO10, "in10", MAX8907_REG_LDOCTL10),
166 	LDO_750_50(LDO11, "in11", MAX8907_REG_LDOCTL11),
167 	LDO_750_50(LDO12, "in12", MAX8907_REG_LDOCTL12),
168 	LDO_750_50(LDO13, "in13", MAX8907_REG_LDOCTL13),
169 	LDO_750_50(LDO14, "in14", MAX8907_REG_LDOCTL14),
170 	LDO_750_50(LDO15, "in15", MAX8907_REG_LDOCTL15),
171 	LDO_750_50(LDO16, "in16", MAX8907_REG_LDOCTL16),
172 	LDO_650_25(LDO17, "in17", MAX8907_REG_LDOCTL17),
173 	LDO_650_25(LDO18, "in18", MAX8907_REG_LDOCTL18),
174 	LDO_750_50(LDO19, "in19", MAX8907_REG_LDOCTL19),
175 	LDO_750_50(LDO20, "in20", MAX8907_REG_LDOCTL20),
176 	REG_OUT5V(OUT5V, "mbatt", MAX8907_REG_OUT5VEN, 5000000),
177 	REG_OUT5V(OUT33V, "mbatt",  MAX8907_REG_OUT33VEN, 3300000),
178 	REG_BBAT(BBAT, "MBATT", MAX8907_REG_BBAT_CNFG,
179 						2400000, 3000000, 200000),
180 	REG_FIXED(SDBY, "MBATT", 1200000),
181 	REG_FIXED(VRTC, "MBATT", 3300000),
182 };
183 
184 #ifdef CONFIG_OF
185 
186 #define MATCH(_name, _id) \
187 	[MAX8907_##_id] = { \
188 		.name = #_name, \
189 		.driver_data = (void *)&max8907_regulators[MAX8907_##_id], \
190 	}
191 
192 static struct of_regulator_match max8907_matches[] = {
193 	MATCH(mbatt, MBATT),
194 	MATCH(sd1, SD1),
195 	MATCH(sd2, SD2),
196 	MATCH(sd3, SD3),
197 	MATCH(ldo1, LDO1),
198 	MATCH(ldo2, LDO2),
199 	MATCH(ldo3, LDO3),
200 	MATCH(ldo4, LDO4),
201 	MATCH(ldo5, LDO5),
202 	MATCH(ldo6, LDO6),
203 	MATCH(ldo7, LDO7),
204 	MATCH(ldo8, LDO8),
205 	MATCH(ldo9, LDO9),
206 	MATCH(ldo10, LDO10),
207 	MATCH(ldo11, LDO11),
208 	MATCH(ldo12, LDO12),
209 	MATCH(ldo13, LDO13),
210 	MATCH(ldo14, LDO14),
211 	MATCH(ldo15, LDO15),
212 	MATCH(ldo16, LDO16),
213 	MATCH(ldo17, LDO17),
214 	MATCH(ldo18, LDO18),
215 	MATCH(ldo19, LDO19),
216 	MATCH(ldo20, LDO20),
217 	MATCH(out5v, OUT5V),
218 	MATCH(out33v, OUT33V),
219 	MATCH(bbat, BBAT),
220 	MATCH(sdby, SDBY),
221 	MATCH(vrtc, VRTC),
222 };
223 
max8907_regulator_parse_dt(struct platform_device * pdev)224 static int max8907_regulator_parse_dt(struct platform_device *pdev)
225 {
226 	struct device_node *np, *regulators;
227 	int ret;
228 
229 	np = pdev->dev.parent->of_node;
230 	if (!np)
231 		return 0;
232 
233 	regulators = of_get_child_by_name(np, "regulators");
234 	if (!regulators) {
235 		dev_err(&pdev->dev, "regulators node not found\n");
236 		return -EINVAL;
237 	}
238 
239 	ret = of_regulator_match(&pdev->dev, regulators, max8907_matches,
240 				 ARRAY_SIZE(max8907_matches));
241 	of_node_put(regulators);
242 	if (ret < 0) {
243 		dev_err(&pdev->dev, "Error parsing regulator init data: %d\n",
244 			ret);
245 		return ret;
246 	}
247 
248 	return 0;
249 }
250 
match_init_data(int index)251 static inline struct regulator_init_data *match_init_data(int index)
252 {
253 	return max8907_matches[index].init_data;
254 }
255 
match_of_node(int index)256 static inline struct device_node *match_of_node(int index)
257 {
258 	return max8907_matches[index].of_node;
259 }
260 #else
max8907_regulator_parse_dt(struct platform_device * pdev)261 static int max8907_regulator_parse_dt(struct platform_device *pdev)
262 {
263 	return 0;
264 }
265 
match_init_data(int index)266 static inline struct regulator_init_data *match_init_data(int index)
267 {
268 	return NULL;
269 }
270 
match_of_node(int index)271 static inline struct device_node *match_of_node(int index)
272 {
273 	return NULL;
274 }
275 #endif
276 
max8907_regulator_probe(struct platform_device * pdev)277 static int max8907_regulator_probe(struct platform_device *pdev)
278 {
279 	struct max8907 *max8907 = dev_get_drvdata(pdev->dev.parent);
280 	struct max8907_platform_data *pdata = dev_get_platdata(max8907->dev);
281 	int ret;
282 	struct max8907_regulator *pmic;
283 	unsigned int val;
284 	int i;
285 	struct regulator_config config = {};
286 	struct regulator_init_data *idata;
287 	const char *mbatt_rail_name = NULL;
288 
289 	ret = max8907_regulator_parse_dt(pdev);
290 	if (ret)
291 		return ret;
292 
293 	pmic = devm_kzalloc(&pdev->dev, sizeof(*pmic), GFP_KERNEL);
294 	if (!pmic)
295 		return -ENOMEM;
296 
297 	platform_set_drvdata(pdev, pmic);
298 
299 	memcpy(pmic->desc, max8907_regulators, sizeof(pmic->desc));
300 
301 	/* Backwards compatibility with MAX8907B; SD1 uses different voltages */
302 	ret = regmap_read(max8907->regmap_gen, MAX8907_REG_II2RR, &val);
303 	if (ret)
304 		return ret;
305 
306 	if ((val & MAX8907_II2RR_VERSION_MASK) ==
307 	    MAX8907_II2RR_VERSION_REV_B) {
308 		pmic->desc[MAX8907_SD1].min_uV = 637500;
309 		pmic->desc[MAX8907_SD1].uV_step = 12500;
310 		pmic->desc[MAX8907_SD1].n_voltages =
311 						(1425000 - 637500) / 12500 + 1;
312 	}
313 
314 	for (i = 0; i < MAX8907_NUM_REGULATORS; i++) {
315 		struct regulator_dev *rdev;
316 
317 		config.dev = pdev->dev.parent;
318 		if (pdata)
319 			idata = pdata->init_data[i];
320 		else
321 			idata = match_init_data(i);
322 		config.init_data = idata;
323 		config.driver_data = pmic;
324 		config.regmap = max8907->regmap_gen;
325 		config.of_node = match_of_node(i);
326 
327 		switch (pmic->desc[i].id) {
328 		case MAX8907_MBATT:
329 			if (idata && idata->constraints.name)
330 				mbatt_rail_name = idata->constraints.name;
331 			else
332 				mbatt_rail_name = pmic->desc[i].name;
333 			break;
334 		case MAX8907_BBAT:
335 		case MAX8907_SDBY:
336 		case MAX8907_VRTC:
337 			idata->supply_regulator = mbatt_rail_name;
338 			break;
339 		}
340 
341 		if (pmic->desc[i].ops == &max8907_ldo_ops) {
342 			ret = regmap_read(config.regmap, pmic->desc[i].enable_reg,
343 				    &val);
344 			if (ret)
345 				return ret;
346 
347 			if ((val & MAX8907_MASK_LDO_SEQ) !=
348 			    MAX8907_MASK_LDO_SEQ)
349 				pmic->desc[i].ops = &max8907_ldo_hwctl_ops;
350 		} else if (pmic->desc[i].ops == &max8907_out5v_ops) {
351 			ret = regmap_read(config.regmap, pmic->desc[i].enable_reg,
352 				    &val);
353 			if (ret)
354 				return ret;
355 
356 			if ((val & (MAX8907_MASK_OUT5V_VINEN |
357 						MAX8907_MASK_OUT5V_ENSRC)) !=
358 			    MAX8907_MASK_OUT5V_ENSRC)
359 				pmic->desc[i].ops = &max8907_out5v_hwctl_ops;
360 		}
361 
362 		rdev = devm_regulator_register(&pdev->dev,
363 						&pmic->desc[i], &config);
364 		if (IS_ERR(rdev)) {
365 			dev_err(&pdev->dev,
366 				"failed to register %s regulator\n",
367 				pmic->desc[i].name);
368 			return PTR_ERR(rdev);
369 		}
370 	}
371 
372 	return 0;
373 }
374 
375 static struct platform_driver max8907_regulator_driver = {
376 	.driver = {
377 		   .name = "max8907-regulator",
378 		   },
379 	.probe = max8907_regulator_probe,
380 };
381 
max8907_regulator_init(void)382 static int __init max8907_regulator_init(void)
383 {
384 	return platform_driver_register(&max8907_regulator_driver);
385 }
386 
387 subsys_initcall(max8907_regulator_init);
388 
max8907_reg_exit(void)389 static void __exit max8907_reg_exit(void)
390 {
391 	platform_driver_unregister(&max8907_regulator_driver);
392 }
393 
394 module_exit(max8907_reg_exit);
395 
396 MODULE_DESCRIPTION("MAX8907 regulator driver");
397 MODULE_AUTHOR("Gyungoh Yoo <jack.yoo@maxim-ic.com>");
398 MODULE_LICENSE("GPL v2");
399 MODULE_ALIAS("platform:max8907-regulator");
400