2
* Regulator support for WM8400
4
* Copyright 2008 Wolfson Microelectronics PLC.
6
* Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
8
* This program is free software; you can redistribute it and/or
9
* modify it under the terms of the GNU General Public License as
10
* published by the Free Software Foundation; either version 2 of the
11
* License, or (at your option) any later version.
15
#include <linux/bug.h>
16
#include <linux/err.h>
17
#include <linux/kernel.h>
18
#include <linux/module.h>
19
#include <linux/regulator/driver.h>
20
#include <linux/mfd/wm8400-private.h>
22
static int wm8400_ldo_is_enabled(struct regulator_dev *dev)
24
struct wm8400 *wm8400 = rdev_get_drvdata(dev);
27
val = wm8400_reg_read(wm8400, WM8400_LDO1_CONTROL + rdev_get_id(dev));
28
return (val & WM8400_LDO1_ENA) != 0;
31
static int wm8400_ldo_enable(struct regulator_dev *dev)
33
struct wm8400 *wm8400 = rdev_get_drvdata(dev);
35
return wm8400_set_bits(wm8400, WM8400_LDO1_CONTROL + rdev_get_id(dev),
36
WM8400_LDO1_ENA, WM8400_LDO1_ENA);
39
static int wm8400_ldo_disable(struct regulator_dev *dev)
41
struct wm8400 *wm8400 = rdev_get_drvdata(dev);
43
return wm8400_set_bits(wm8400, WM8400_LDO1_CONTROL + rdev_get_id(dev),
47
static int wm8400_ldo_list_voltage(struct regulator_dev *dev,
50
if (selector > WM8400_LDO1_VSEL_MASK)
54
return 900000 + (selector * 50000);
56
return 1600000 + ((selector - 14) * 100000);
59
static int wm8400_ldo_get_voltage_sel(struct regulator_dev *dev)
61
struct wm8400 *wm8400 = rdev_get_drvdata(dev);
64
val = wm8400_reg_read(wm8400, WM8400_LDO1_CONTROL + rdev_get_id(dev));
65
val &= WM8400_LDO1_VSEL_MASK;
70
static int wm8400_ldo_set_voltage(struct regulator_dev *dev,
71
int min_uV, int max_uV, unsigned *selector)
73
struct wm8400 *wm8400 = rdev_get_drvdata(dev);
76
if (min_uV < 900000 || min_uV > 3300000)
79
if (min_uV < 1700000) {
80
/* Steps of 50mV from 900mV; */
81
val = (min_uV - 850001) / 50000;
83
if ((val * 50000) + 900000 > max_uV)
85
BUG_ON((val * 50000) + 900000 < min_uV);
87
/* Steps of 100mV from 1700mV */
88
val = ((min_uV - 1600001) / 100000);
90
if ((val * 100000) + 1700000 > max_uV)
92
BUG_ON((val * 100000) + 1700000 < min_uV);
99
return wm8400_set_bits(wm8400, WM8400_LDO1_CONTROL + rdev_get_id(dev),
100
WM8400_LDO1_VSEL_MASK, val);
103
static struct regulator_ops wm8400_ldo_ops = {
104
.is_enabled = wm8400_ldo_is_enabled,
105
.enable = wm8400_ldo_enable,
106
.disable = wm8400_ldo_disable,
107
.list_voltage = wm8400_ldo_list_voltage,
108
.get_voltage_sel = wm8400_ldo_get_voltage_sel,
109
.set_voltage = wm8400_ldo_set_voltage,
112
static int wm8400_dcdc_is_enabled(struct regulator_dev *dev)
114
struct wm8400 *wm8400 = rdev_get_drvdata(dev);
115
int offset = (rdev_get_id(dev) - WM8400_DCDC1) * 2;
118
val = wm8400_reg_read(wm8400, WM8400_DCDC1_CONTROL_1 + offset);
119
return (val & WM8400_DC1_ENA) != 0;
122
static int wm8400_dcdc_enable(struct regulator_dev *dev)
124
struct wm8400 *wm8400 = rdev_get_drvdata(dev);
125
int offset = (rdev_get_id(dev) - WM8400_DCDC1) * 2;
127
return wm8400_set_bits(wm8400, WM8400_DCDC1_CONTROL_1 + offset,
128
WM8400_DC1_ENA, WM8400_DC1_ENA);
131
static int wm8400_dcdc_disable(struct regulator_dev *dev)
133
struct wm8400 *wm8400 = rdev_get_drvdata(dev);
134
int offset = (rdev_get_id(dev) - WM8400_DCDC1) * 2;
136
return wm8400_set_bits(wm8400, WM8400_DCDC1_CONTROL_1 + offset,
140
static int wm8400_dcdc_list_voltage(struct regulator_dev *dev,
143
if (selector > WM8400_DC1_VSEL_MASK)
146
return 850000 + (selector * 25000);
149
static int wm8400_dcdc_get_voltage_sel(struct regulator_dev *dev)
151
struct wm8400 *wm8400 = rdev_get_drvdata(dev);
153
int offset = (rdev_get_id(dev) - WM8400_DCDC1) * 2;
155
val = wm8400_reg_read(wm8400, WM8400_DCDC1_CONTROL_1 + offset);
156
val &= WM8400_DC1_VSEL_MASK;
161
static int wm8400_dcdc_set_voltage(struct regulator_dev *dev,
162
int min_uV, int max_uV, unsigned *selector)
164
struct wm8400 *wm8400 = rdev_get_drvdata(dev);
166
int offset = (rdev_get_id(dev) - WM8400_DCDC1) * 2;
171
val = (min_uV - 825001) / 25000;
173
if (850000 + (25000 * val) > max_uV)
175
BUG_ON(850000 + (25000 * val) < min_uV);
179
return wm8400_set_bits(wm8400, WM8400_DCDC1_CONTROL_1 + offset,
180
WM8400_DC1_VSEL_MASK, val);
183
static unsigned int wm8400_dcdc_get_mode(struct regulator_dev *dev)
185
struct wm8400 *wm8400 = rdev_get_drvdata(dev);
186
int offset = (rdev_get_id(dev) - WM8400_DCDC1) * 2;
190
ret = wm8400_block_read(wm8400, WM8400_DCDC1_CONTROL_1 + offset, 2,
195
/* Datasheet: hibernate */
196
if (data[0] & WM8400_DC1_SLEEP)
197
return REGULATOR_MODE_STANDBY;
199
/* Datasheet: standby */
200
if (!(data[0] & WM8400_DC1_ACTIVE))
201
return REGULATOR_MODE_IDLE;
203
/* Datasheet: active with or without force PWM */
204
if (data[1] & WM8400_DC1_FRC_PWM)
205
return REGULATOR_MODE_FAST;
207
return REGULATOR_MODE_NORMAL;
210
static int wm8400_dcdc_set_mode(struct regulator_dev *dev, unsigned int mode)
212
struct wm8400 *wm8400 = rdev_get_drvdata(dev);
213
int offset = (rdev_get_id(dev) - WM8400_DCDC1) * 2;
217
case REGULATOR_MODE_FAST:
218
/* Datasheet: active with force PWM */
219
ret = wm8400_set_bits(wm8400, WM8400_DCDC1_CONTROL_2 + offset,
220
WM8400_DC1_FRC_PWM, WM8400_DC1_FRC_PWM);
224
return wm8400_set_bits(wm8400, WM8400_DCDC1_CONTROL_1 + offset,
225
WM8400_DC1_ACTIVE | WM8400_DC1_SLEEP,
228
case REGULATOR_MODE_NORMAL:
229
/* Datasheet: active */
230
ret = wm8400_set_bits(wm8400, WM8400_DCDC1_CONTROL_2 + offset,
231
WM8400_DC1_FRC_PWM, 0);
235
return wm8400_set_bits(wm8400, WM8400_DCDC1_CONTROL_1 + offset,
236
WM8400_DC1_ACTIVE | WM8400_DC1_SLEEP,
239
case REGULATOR_MODE_IDLE:
240
/* Datasheet: standby */
241
ret = wm8400_set_bits(wm8400, WM8400_DCDC1_CONTROL_1 + offset,
242
WM8400_DC1_ACTIVE, 0);
245
return wm8400_set_bits(wm8400, WM8400_DCDC1_CONTROL_1 + offset,
246
WM8400_DC1_SLEEP, 0);
253
static unsigned int wm8400_dcdc_get_optimum_mode(struct regulator_dev *dev,
254
int input_uV, int output_uV,
257
return REGULATOR_MODE_NORMAL;
260
static struct regulator_ops wm8400_dcdc_ops = {
261
.is_enabled = wm8400_dcdc_is_enabled,
262
.enable = wm8400_dcdc_enable,
263
.disable = wm8400_dcdc_disable,
264
.list_voltage = wm8400_dcdc_list_voltage,
265
.get_voltage_sel = wm8400_dcdc_get_voltage_sel,
266
.set_voltage = wm8400_dcdc_set_voltage,
267
.get_mode = wm8400_dcdc_get_mode,
268
.set_mode = wm8400_dcdc_set_mode,
269
.get_optimum_mode = wm8400_dcdc_get_optimum_mode,
272
static struct regulator_desc regulators[] = {
276
.ops = &wm8400_ldo_ops,
277
.n_voltages = WM8400_LDO1_VSEL_MASK + 1,
278
.type = REGULATOR_VOLTAGE,
279
.owner = THIS_MODULE,
284
.ops = &wm8400_ldo_ops,
285
.n_voltages = WM8400_LDO2_VSEL_MASK + 1,
286
.type = REGULATOR_VOLTAGE,
287
.owner = THIS_MODULE,
292
.ops = &wm8400_ldo_ops,
293
.n_voltages = WM8400_LDO3_VSEL_MASK + 1,
294
.type = REGULATOR_VOLTAGE,
295
.owner = THIS_MODULE,
300
.ops = &wm8400_ldo_ops,
301
.n_voltages = WM8400_LDO4_VSEL_MASK + 1,
302
.type = REGULATOR_VOLTAGE,
303
.owner = THIS_MODULE,
308
.ops = &wm8400_dcdc_ops,
309
.n_voltages = WM8400_DC1_VSEL_MASK + 1,
310
.type = REGULATOR_VOLTAGE,
311
.owner = THIS_MODULE,
316
.ops = &wm8400_dcdc_ops,
317
.n_voltages = WM8400_DC2_VSEL_MASK + 1,
318
.type = REGULATOR_VOLTAGE,
319
.owner = THIS_MODULE,
323
static int __devinit wm8400_regulator_probe(struct platform_device *pdev)
325
struct wm8400 *wm8400 = container_of(pdev, struct wm8400, regulators[pdev->id]);
326
struct regulator_dev *rdev;
328
rdev = regulator_register(®ulators[pdev->id], &pdev->dev,
329
pdev->dev.platform_data, wm8400);
332
return PTR_ERR(rdev);
334
platform_set_drvdata(pdev, rdev);
339
static int __devexit wm8400_regulator_remove(struct platform_device *pdev)
341
struct regulator_dev *rdev = platform_get_drvdata(pdev);
343
platform_set_drvdata(pdev, NULL);
344
regulator_unregister(rdev);
349
static struct platform_driver wm8400_regulator_driver = {
351
.name = "wm8400-regulator",
353
.probe = wm8400_regulator_probe,
354
.remove = __devexit_p(wm8400_regulator_remove),
358
* wm8400_register_regulator - enable software control of a WM8400 regulator
360
* This function enables software control of a WM8400 regulator via
361
* the regulator API. It is intended to be called from the
362
* platform_init() callback of the WM8400 MFD driver.
364
* @param dev The WM8400 device to operate on.
365
* @param reg The regulator to control.
366
* @param initdata Regulator initdata for the regulator.
368
int wm8400_register_regulator(struct device *dev, int reg,
369
struct regulator_init_data *initdata)
371
struct wm8400 *wm8400 = dev_get_drvdata(dev);
373
if (wm8400->regulators[reg].name)
376
initdata->driver_data = wm8400;
378
wm8400->regulators[reg].name = "wm8400-regulator";
379
wm8400->regulators[reg].id = reg;
380
wm8400->regulators[reg].dev.parent = dev;
381
wm8400->regulators[reg].dev.platform_data = initdata;
383
return platform_device_register(&wm8400->regulators[reg]);
385
EXPORT_SYMBOL_GPL(wm8400_register_regulator);
387
static int __init wm8400_regulator_init(void)
389
return platform_driver_register(&wm8400_regulator_driver);
391
subsys_initcall(wm8400_regulator_init);
393
static void __exit wm8400_regulator_exit(void)
395
platform_driver_unregister(&wm8400_regulator_driver);
397
module_exit(wm8400_regulator_exit);
399
MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
400
MODULE_DESCRIPTION("WM8400 regulator driver");
401
MODULE_LICENSE("GPL");
402
MODULE_ALIAS("platform:wm8400-regulator");