2 * Copyright (C) ST-Ericsson SA 2010
4 * License Terms: GNU General Public License v2
6 * Authors: Bengt Jonsson <bengt.g.jonsson@stericsson.com>
8 * This file is based on drivers/regulator/ab8500.c
10 * AB8500 external regulators
12 * ab8500-ext supports the following regulators:
15 #include <linux/init.h>
16 #include <linux/kernel.h>
17 #include <linux/err.h>
18 #include <linux/module.h>
20 #include <linux/platform_device.h>
21 #include <linux/regulator/driver.h>
22 #include <linux/regulator/machine.h>
23 #include <linux/regulator/of_regulator.h>
24 #include <linux/mfd/abx500.h>
25 #include <linux/mfd/abx500/ab8500.h>
26 #include <linux/regulator/ab8500.h>
29 * struct ab8500_ext_regulator_info - ab8500 regulator information
30 * @dev: device pointer
31 * @desc: regulator description
32 * @rdev: regulator device
33 * @cfg: regulator configuration (extension of regulator FW configuration)
34 * @update_bank: bank to control on/off
35 * @update_reg: register to control on/off
36 * @update_mask: mask to enable/disable and set mode of regulator
37 * @update_val: bits holding the regulator current mode
38 * @update_val_hp: bits to set EN pin active (LPn pin deactive)
39 * normally this means high power mode
40 * @update_val_lp: bits to set EN pin active and LPn pin active
41 * normally this means low power mode
42 * @update_val_hw: bits to set regulator pins in HW control
43 * SysClkReq pins and logic will choose mode
45 struct ab8500_ext_regulator_info
{
47 struct regulator_desc desc
;
48 struct regulator_dev
*rdev
;
49 struct ab8500_ext_regulator_cfg
*cfg
;
59 static int ab8500_ext_regulator_enable(struct regulator_dev
*rdev
)
62 struct ab8500_ext_regulator_info
*info
= rdev_get_drvdata(rdev
);
66 dev_err(rdev_get_dev(rdev
), "regulator info null pointer\n");
71 * To satisfy both HW high power request and SW request, the regulator
72 * must be on in high power.
74 if (info
->cfg
&& info
->cfg
->hwreq
)
75 regval
= info
->update_val_hp
;
77 regval
= info
->update_val
;
79 ret
= abx500_mask_and_set_register_interruptible(info
->dev
,
80 info
->update_bank
, info
->update_reg
,
81 info
->update_mask
, regval
);
83 dev_err(rdev_get_dev(info
->rdev
),
84 "couldn't set enable bits for regulator\n");
88 dev_dbg(rdev_get_dev(rdev
),
89 "%s-enable (bank, reg, mask, value): 0x%02x, 0x%02x, 0x%02x, 0x%02x\n",
90 info
->desc
.name
, info
->update_bank
, info
->update_reg
,
91 info
->update_mask
, regval
);
96 static int ab8500_ext_regulator_disable(struct regulator_dev
*rdev
)
99 struct ab8500_ext_regulator_info
*info
= rdev_get_drvdata(rdev
);
103 dev_err(rdev_get_dev(rdev
), "regulator info null pointer\n");
108 * Set the regulator in HW request mode if configured
110 if (info
->cfg
&& info
->cfg
->hwreq
)
111 regval
= info
->update_val_hw
;
115 ret
= abx500_mask_and_set_register_interruptible(info
->dev
,
116 info
->update_bank
, info
->update_reg
,
117 info
->update_mask
, regval
);
119 dev_err(rdev_get_dev(info
->rdev
),
120 "couldn't set disable bits for regulator\n");
124 dev_dbg(rdev_get_dev(rdev
), "%s-disable (bank, reg, mask, value):"
125 " 0x%02x, 0x%02x, 0x%02x, 0x%02x\n",
126 info
->desc
.name
, info
->update_bank
, info
->update_reg
,
127 info
->update_mask
, regval
);
132 static int ab8500_ext_regulator_is_enabled(struct regulator_dev
*rdev
)
135 struct ab8500_ext_regulator_info
*info
= rdev_get_drvdata(rdev
);
139 dev_err(rdev_get_dev(rdev
), "regulator info null pointer\n");
143 ret
= abx500_get_register_interruptible(info
->dev
,
144 info
->update_bank
, info
->update_reg
, ®val
);
146 dev_err(rdev_get_dev(rdev
),
147 "couldn't read 0x%x register\n", info
->update_reg
);
151 dev_dbg(rdev_get_dev(rdev
), "%s-is_enabled (bank, reg, mask, value):"
152 " 0x%02x, 0x%02x, 0x%02x, 0x%02x\n",
153 info
->desc
.name
, info
->update_bank
, info
->update_reg
,
154 info
->update_mask
, regval
);
156 if (((regval
& info
->update_mask
) == info
->update_val_lp
) ||
157 ((regval
& info
->update_mask
) == info
->update_val_hp
))
163 static int ab8500_ext_regulator_set_mode(struct regulator_dev
*rdev
,
167 struct ab8500_ext_regulator_info
*info
= rdev_get_drvdata(rdev
);
171 dev_err(rdev_get_dev(rdev
), "regulator info null pointer\n");
176 case REGULATOR_MODE_NORMAL
:
177 regval
= info
->update_val_hp
;
179 case REGULATOR_MODE_IDLE
:
180 regval
= info
->update_val_lp
;
187 /* If regulator is enabled and info->cfg->hwreq is set, the regulator
188 must be on in high power, so we don't need to write the register with
191 if (ab8500_ext_regulator_is_enabled(rdev
) &&
192 !(info
->cfg
&& info
->cfg
->hwreq
)) {
193 ret
= abx500_mask_and_set_register_interruptible(info
->dev
,
194 info
->update_bank
, info
->update_reg
,
195 info
->update_mask
, regval
);
197 dev_err(rdev_get_dev(rdev
),
198 "Could not set regulator mode.\n");
202 dev_dbg(rdev_get_dev(rdev
),
203 "%s-set_mode (bank, reg, mask, value): "
204 "0x%x, 0x%x, 0x%x, 0x%x\n",
205 info
->desc
.name
, info
->update_bank
, info
->update_reg
,
206 info
->update_mask
, regval
);
209 info
->update_val
= regval
;
214 static unsigned int ab8500_ext_regulator_get_mode(struct regulator_dev
*rdev
)
216 struct ab8500_ext_regulator_info
*info
= rdev_get_drvdata(rdev
);
220 dev_err(rdev_get_dev(rdev
), "regulator info null pointer\n");
224 if (info
->update_val
== info
->update_val_hp
)
225 ret
= REGULATOR_MODE_NORMAL
;
226 else if (info
->update_val
== info
->update_val_lp
)
227 ret
= REGULATOR_MODE_IDLE
;
234 static int ab8500_ext_set_voltage(struct regulator_dev
*rdev
, int min_uV
,
235 int max_uV
, unsigned *selector
)
237 struct regulation_constraints
*regu_constraints
= rdev
->constraints
;
239 if (!regu_constraints
) {
240 dev_err(rdev_get_dev(rdev
), "No regulator constraints\n");
244 if (regu_constraints
->min_uV
== min_uV
&&
245 regu_constraints
->max_uV
== max_uV
)
248 dev_err(rdev_get_dev(rdev
),
249 "Requested min %duV max %duV != constrained min %duV max %duV\n",
251 regu_constraints
->min_uV
, regu_constraints
->max_uV
);
256 static int ab8500_ext_list_voltage(struct regulator_dev
*rdev
,
259 struct regulation_constraints
*regu_constraints
= rdev
->constraints
;
261 if (regu_constraints
== NULL
) {
262 dev_err(rdev_get_dev(rdev
), "regulator constraints null pointer\n");
265 /* return the uV for the fixed regulators */
266 if (regu_constraints
->min_uV
&& regu_constraints
->max_uV
) {
267 if (regu_constraints
->min_uV
== regu_constraints
->max_uV
)
268 return regu_constraints
->min_uV
;
273 static struct regulator_ops ab8500_ext_regulator_ops
= {
274 .enable
= ab8500_ext_regulator_enable
,
275 .disable
= ab8500_ext_regulator_disable
,
276 .is_enabled
= ab8500_ext_regulator_is_enabled
,
277 .set_mode
= ab8500_ext_regulator_set_mode
,
278 .get_mode
= ab8500_ext_regulator_get_mode
,
279 .set_voltage
= ab8500_ext_set_voltage
,
280 .list_voltage
= ab8500_ext_list_voltage
,
283 static struct ab8500_ext_regulator_info
284 ab8500_ext_regulator_info
[AB8500_NUM_EXT_REGULATORS
] = {
285 [AB8500_EXT_SUPPLY1
] = {
287 .name
= "VEXTSUPPLY1",
288 .ops
= &ab8500_ext_regulator_ops
,
289 .type
= REGULATOR_VOLTAGE
,
290 .id
= AB8500_EXT_SUPPLY1
,
291 .owner
= THIS_MODULE
,
298 .update_val_hp
= 0x01,
299 .update_val_lp
= 0x03,
300 .update_val_hw
= 0x02,
302 [AB8500_EXT_SUPPLY2
] = {
304 .name
= "VEXTSUPPLY2",
305 .ops
= &ab8500_ext_regulator_ops
,
306 .type
= REGULATOR_VOLTAGE
,
307 .id
= AB8500_EXT_SUPPLY2
,
308 .owner
= THIS_MODULE
,
315 .update_val_hp
= 0x04,
316 .update_val_lp
= 0x0c,
317 .update_val_hw
= 0x08,
319 [AB8500_EXT_SUPPLY3
] = {
321 .name
= "VEXTSUPPLY3",
322 .ops
= &ab8500_ext_regulator_ops
,
323 .type
= REGULATOR_VOLTAGE
,
324 .id
= AB8500_EXT_SUPPLY3
,
325 .owner
= THIS_MODULE
,
332 .update_val_hp
= 0x10,
333 .update_val_lp
= 0x30,
334 .update_val_hw
= 0x20,
338 static struct of_regulator_match ab8500_ext_regulator_match
[] = {
339 { .name
= "ab8500_ext1", .driver_data
= (void *) AB8500_EXT_SUPPLY1
, },
340 { .name
= "ab8500_ext2", .driver_data
= (void *) AB8500_EXT_SUPPLY2
, },
341 { .name
= "ab8500_ext3", .driver_data
= (void *) AB8500_EXT_SUPPLY3
, },
344 static int ab8500_ext_regulator_probe(struct platform_device
*pdev
)
346 struct ab8500
*ab8500
= dev_get_drvdata(pdev
->dev
.parent
);
347 struct ab8500_platform_data
*ppdata
;
348 struct ab8500_regulator_platform_data
*pdata
;
349 struct device_node
*np
= pdev
->dev
.of_node
;
350 struct regulator_config config
= { };
354 err
= of_regulator_match(&pdev
->dev
, np
,
355 ab8500_ext_regulator_match
,
356 ARRAY_SIZE(ab8500_ext_regulator_match
));
359 "Error parsing regulator init data: %d\n", err
);
365 dev_err(&pdev
->dev
, "null mfd parent\n");
369 ppdata
= dev_get_platdata(ab8500
->dev
);
371 dev_err(&pdev
->dev
, "null parent pdata\n");
375 pdata
= ppdata
->regulator
;
377 dev_err(&pdev
->dev
, "null pdata\n");
381 /* make sure the platform data has the correct size */
382 if (pdata
->num_ext_regulator
!= ARRAY_SIZE(ab8500_ext_regulator_info
)) {
383 dev_err(&pdev
->dev
, "Configuration error: size mismatch.\n");
387 /* check for AB8500 2.x */
388 if (is_ab8500_2p0_or_earlier(ab8500
)) {
389 struct ab8500_ext_regulator_info
*info
;
391 /* VextSupply3LPn is inverted on AB8500 2.x */
392 info
= &ab8500_ext_regulator_info
[AB8500_EXT_SUPPLY3
];
393 info
->update_val
= 0x30;
394 info
->update_val_hp
= 0x30;
395 info
->update_val_lp
= 0x10;
398 /* register all regulators */
399 for (i
= 0; i
< ARRAY_SIZE(ab8500_ext_regulator_info
); i
++) {
400 struct ab8500_ext_regulator_info
*info
= NULL
;
402 /* assign per-regulator data */
403 info
= &ab8500_ext_regulator_info
[i
];
404 info
->dev
= &pdev
->dev
;
405 info
->cfg
= (struct ab8500_ext_regulator_cfg
*)
406 pdata
->ext_regulator
[i
].driver_data
;
408 config
.dev
= &pdev
->dev
;
409 config
.driver_data
= info
;
410 config
.of_node
= ab8500_ext_regulator_match
[i
].of_node
;
411 config
.init_data
= (np
) ?
412 ab8500_ext_regulator_match
[i
].init_data
:
413 &pdata
->ext_regulator
[i
];
415 /* register regulator with framework */
416 info
->rdev
= regulator_register(&info
->desc
, &config
);
417 if (IS_ERR(info
->rdev
)) {
418 err
= PTR_ERR(info
->rdev
);
419 dev_err(&pdev
->dev
, "failed to register regulator %s\n",
421 /* when we fail, un-register all earlier regulators */
423 info
= &ab8500_ext_regulator_info
[i
];
424 regulator_unregister(info
->rdev
);
429 dev_dbg(rdev_get_dev(info
->rdev
),
430 "%s-probed\n", info
->desc
.name
);
436 static int ab8500_ext_regulator_remove(struct platform_device
*pdev
)
440 for (i
= 0; i
< ARRAY_SIZE(ab8500_ext_regulator_info
); i
++) {
441 struct ab8500_ext_regulator_info
*info
= NULL
;
442 info
= &ab8500_ext_regulator_info
[i
];
444 dev_vdbg(rdev_get_dev(info
->rdev
),
445 "%s-remove\n", info
->desc
.name
);
447 regulator_unregister(info
->rdev
);
453 static struct platform_driver ab8500_ext_regulator_driver
= {
454 .probe
= ab8500_ext_regulator_probe
,
455 .remove
= ab8500_ext_regulator_remove
,
457 .name
= "ab8500-ext-regulator",
458 .owner
= THIS_MODULE
,
462 static int __init
ab8500_ext_regulator_init(void)
466 ret
= platform_driver_register(&ab8500_ext_regulator_driver
);
468 pr_err("Failed to register ab8500 ext regulator: %d\n", ret
);
472 subsys_initcall(ab8500_ext_regulator_init
);
474 static void __exit
ab8500_ext_regulator_exit(void)
476 platform_driver_unregister(&ab8500_ext_regulator_driver
);
478 module_exit(ab8500_ext_regulator_exit
);
480 MODULE_LICENSE("GPL v2");
481 MODULE_AUTHOR("Bengt Jonsson <bengt.g.jonsson@stericsson.com>");
482 MODULE_DESCRIPTION("AB8500 external regulator driver");
483 MODULE_ALIAS("platform:ab8500-ext-regulator");