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