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
35struct 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
112static struct regulator_ops max8907_mbatt_ops = {
113};
114
115static 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
124static 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
130static struct regulator_ops max8907_fixed_ops = {
131	.list_voltage = regulator_list_voltage_linear,
132};
133
134static 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
141static struct regulator_ops max8907_out5v_hwctl_ops = {
142	.list_voltage = regulator_list_voltage_linear,
143};
144
145static 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
151static 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
192static 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
224static 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
251static inline struct regulator_init_data *match_init_data(int index)
252{
253	return max8907_matches[index].init_data;
254}
255
256static inline struct device_node *match_of_node(int index)
257{
258	return max8907_matches[index].of_node;
259}
260#else
261static int max8907_regulator_parse_dt(struct platform_device *pdev)
262{
263	return 0;
264}
265
266static inline struct regulator_init_data *match_init_data(int index)
267{
268	return NULL;
269}
270
271static inline struct device_node *match_of_node(int index)
272{
273	return NULL;
274}
275#endif
276
277static 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	regmap_read(max8907->regmap_gen, MAX8907_REG_II2RR, &val);
303	if ((val & MAX8907_II2RR_VERSION_MASK) ==
304	    MAX8907_II2RR_VERSION_REV_B) {
305		pmic->desc[MAX8907_SD1].min_uV = 637500;
306		pmic->desc[MAX8907_SD1].uV_step = 12500;
307		pmic->desc[MAX8907_SD1].n_voltages =
308						(1425000 - 637500) / 12500 + 1;
309	}
310
311	for (i = 0; i < MAX8907_NUM_REGULATORS; i++) {
312		struct regulator_dev *rdev;
313
314		config.dev = pdev->dev.parent;
315		if (pdata)
316			idata = pdata->init_data[i];
317		else
318			idata = match_init_data(i);
319		config.init_data = idata;
320		config.driver_data = pmic;
321		config.regmap = max8907->regmap_gen;
322		config.of_node = match_of_node(i);
323
324		switch (pmic->desc[i].id) {
325		case MAX8907_MBATT:
326			if (idata && idata->constraints.name)
327				mbatt_rail_name = idata->constraints.name;
328			else
329				mbatt_rail_name = pmic->desc[i].name;
330			break;
331		case MAX8907_BBAT:
332		case MAX8907_SDBY:
333		case MAX8907_VRTC:
334			idata->supply_regulator = mbatt_rail_name;
335			break;
336		}
337
338		if (pmic->desc[i].ops == &max8907_ldo_ops) {
339			regmap_read(config.regmap, pmic->desc[i].enable_reg,
340				    &val);
341			if ((val & MAX8907_MASK_LDO_SEQ) !=
342			    MAX8907_MASK_LDO_SEQ)
343				pmic->desc[i].ops = &max8907_ldo_hwctl_ops;
344		} else if (pmic->desc[i].ops == &max8907_out5v_ops) {
345			regmap_read(config.regmap, pmic->desc[i].enable_reg,
346				    &val);
347			if ((val & (MAX8907_MASK_OUT5V_VINEN |
348						MAX8907_MASK_OUT5V_ENSRC)) !=
349			    MAX8907_MASK_OUT5V_ENSRC)
350				pmic->desc[i].ops = &max8907_out5v_hwctl_ops;
351		}
352
353		rdev = devm_regulator_register(&pdev->dev,
354						&pmic->desc[i], &config);
355		if (IS_ERR(rdev)) {
356			dev_err(&pdev->dev,
357				"failed to register %s regulator\n",
358				pmic->desc[i].name);
359			return PTR_ERR(rdev);
360		}
361	}
362
363	return 0;
364}
365
366static struct platform_driver max8907_regulator_driver = {
367	.driver = {
368		   .name = "max8907-regulator",
369		   },
370	.probe = max8907_regulator_probe,
371};
372
373static int __init max8907_regulator_init(void)
374{
375	return platform_driver_register(&max8907_regulator_driver);
376}
377
378subsys_initcall(max8907_regulator_init);
379
380static void __exit max8907_reg_exit(void)
381{
382	platform_driver_unregister(&max8907_regulator_driver);
383}
384
385module_exit(max8907_reg_exit);
386
387MODULE_DESCRIPTION("MAX8907 regulator driver");
388MODULE_AUTHOR("Gyungoh Yoo <jack.yoo@maxim-ic.com>");
389MODULE_LICENSE("GPL v2");
390MODULE_ALIAS("platform:max8907-regulator");
391