]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - drivers/regulator/max8907-regulator.c
ASoC: wm8985: Refactor set_pll code to avoid gcc warnings
[karo-tx-linux.git] / drivers / regulator / max8907-regulator.c
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
252 static inline struct regulator_init_data *match_init_data(int index)
253 {
254         return max8907_matches[index].init_data;
255 }
256
257 static inline struct device_node *match_of_node(int index)
258 {
259         return max8907_matches[index].of_node;
260 }
261 #else
262 static int max8907_regulator_parse_dt(struct platform_device *pdev)
263 {
264         return 0;
265 }
266
267 static inline struct regulator_init_data *match_init_data(int index)
268 {
269         return NULL;
270 }
271
272 static inline struct device_node *match_of_node(int index)
273 {
274         return NULL;
275 }
276 #endif
277
278 static int max8907_regulator_probe(struct platform_device *pdev)
279 {
280         struct max8907 *max8907 = dev_get_drvdata(pdev->dev.parent);
281         struct max8907_platform_data *pdata = dev_get_platdata(max8907->dev);
282         int ret;
283         struct max8907_regulator *pmic;
284         unsigned int val;
285         int i;
286         struct regulator_config config = {};
287         struct regulator_init_data *idata;
288         const char *mbatt_rail_name = NULL;
289
290         ret = max8907_regulator_parse_dt(pdev);
291         if (ret)
292                 return ret;
293
294         pmic = devm_kzalloc(&pdev->dev, sizeof(*pmic), GFP_KERNEL);
295         if (!pmic) {
296                 dev_err(&pdev->dev, "Failed to alloc pmic\n");
297                 return -ENOMEM;
298         }
299         platform_set_drvdata(pdev, pmic);
300
301         memcpy(pmic->desc, max8907_regulators, sizeof(pmic->desc));
302
303         /* Backwards compatibility with MAX8907B; SD1 uses different voltages */
304         regmap_read(max8907->regmap_gen, MAX8907_REG_II2RR, &val);
305         if ((val & MAX8907_II2RR_VERSION_MASK) ==
306             MAX8907_II2RR_VERSION_REV_B) {
307                 pmic->desc[MAX8907_SD1].min_uV = 637500;
308                 pmic->desc[MAX8907_SD1].uV_step = 12500;
309                 pmic->desc[MAX8907_SD1].n_voltages =
310                                                 (1425000 - 637500) / 12500 + 1;
311         }
312
313         for (i = 0; i < MAX8907_NUM_REGULATORS; i++) {
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                 pmic->rdev[i] = regulator_register(&pmic->desc[i], &config);
354                 if (IS_ERR(pmic->rdev[i])) {
355                         dev_err(&pdev->dev,
356                                 "failed to register %s regulator\n",
357                                 pmic->desc[i].name);
358                         ret = PTR_ERR(pmic->rdev[i]);
359                         goto err_unregister_regulator;
360                 }
361         }
362
363         return 0;
364
365 err_unregister_regulator:
366         while (--i >= 0)
367                 regulator_unregister(pmic->rdev[i]);
368         return ret;
369 }
370
371 static int max8907_regulator_remove(struct platform_device *pdev)
372 {
373         struct max8907_regulator *pmic = platform_get_drvdata(pdev);
374         int i;
375
376         for (i = 0; i < MAX8907_NUM_REGULATORS; i++)
377                 regulator_unregister(pmic->rdev[i]);
378
379         return 0;
380 }
381
382 static struct platform_driver max8907_regulator_driver = {
383         .driver = {
384                    .name = "max8907-regulator",
385                    .owner = THIS_MODULE,
386                    },
387         .probe = max8907_regulator_probe,
388         .remove = max8907_regulator_remove,
389 };
390
391 static int __init max8907_regulator_init(void)
392 {
393         return platform_driver_register(&max8907_regulator_driver);
394 }
395
396 subsys_initcall(max8907_regulator_init);
397
398 static void __exit max8907_reg_exit(void)
399 {
400         platform_driver_unregister(&max8907_regulator_driver);
401 }
402
403 module_exit(max8907_reg_exit);
404
405 MODULE_DESCRIPTION("MAX8907 regulator driver");
406 MODULE_AUTHOR("Gyungoh Yoo <jack.yoo@maxim-ic.com>");
407 MODULE_LICENSE("GPL v2");
408 MODULE_ALIAS("platform:max8907-regulator");