Version:  2.0.40 2.2.26 2.4.37 3.2 3.3 3.4 3.5 3.6 3.7 3.8 3.9 3.10 3.11 3.12 3.13 3.14 3.15 3.16 3.17 3.18

Linux/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 };
 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 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 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 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 struct regulator_ops max8907_out5v_hwctl_ops = {
142         .list_voltage = regulator_list_voltage_linear,
143 };
144 
145 static 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 
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 
251 static inline struct regulator_init_data *match_init_data(int index)
252 {
253         return max8907_matches[index].init_data;
254 }
255 
256 static inline struct device_node *match_of_node(int index)
257 {
258         return max8907_matches[index].of_node;
259 }
260 #else
261 static int max8907_regulator_parse_dt(struct platform_device *pdev)
262 {
263         return 0;
264 }
265 
266 static inline struct regulator_init_data *match_init_data(int index)
267 {
268         return NULL;
269 }
270 
271 static inline struct device_node *match_of_node(int index)
272 {
273         return NULL;
274 }
275 #endif
276 
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         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 
366 static struct platform_driver max8907_regulator_driver = {
367         .driver = {
368                    .name = "max8907-regulator",
369                    .owner = THIS_MODULE,
370                    },
371         .probe = max8907_regulator_probe,
372 };
373 
374 static int __init max8907_regulator_init(void)
375 {
376         return platform_driver_register(&max8907_regulator_driver);
377 }
378 
379 subsys_initcall(max8907_regulator_init);
380 
381 static void __exit max8907_reg_exit(void)
382 {
383         platform_driver_unregister(&max8907_regulator_driver);
384 }
385 
386 module_exit(max8907_reg_exit);
387 
388 MODULE_DESCRIPTION("MAX8907 regulator driver");
389 MODULE_AUTHOR("Gyungoh Yoo <jack.yoo@maxim-ic.com>");
390 MODULE_LICENSE("GPL v2");
391 MODULE_ALIAS("platform:max8907-regulator");
392 

This page was automatically generated by LXR 0.3.1 (source).  •  Linux is a registered trademark of Linus Torvalds  •  Contact us