Commit 18b34b95 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/lrg/voltage-2.6

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/lrg/voltage-2.6: (32 commits)
  regulator: twl4030 VAUX3 supports 3.0V
  regulator: Support disabling of unused regulators by machines
  regulator: Don't increment use_count for boot_on regulators
  twl4030-regulator: expose VPLL2
  regulator: refcount fixes
  regulator: Don't warn if we failed to get a regulator
  regulator: Allow boot_on regulators to be disabled by clients
  regulator: Implement list_voltage for WM835x LDOs and DCDCs
  twl4030-regulator: list more VAUX4 voltages
  regulator: Don't warn on omitted voltage constraints
  regulator: Implement list_voltage() for WM8400 DCDCs and LDOs
  MMC: regulator utilities
  regulator: twl4030 voltage enumeration (v2)
  regulator: twl4030 regulators
  regulator: get_status() grows kerneldoc
  regulator: enumerate voltages (v2)
  regulator: Fix get_mode() for WM835x DCDCs
  regulator: Allow regulators to set the initial operating mode
  regulator: Suggest use of datasheet supply or pin names for consumers
  regulator: email - update email address and regulator webpage.
  ...
parents ca1ee219 d6bb69cf
...@@ -4,8 +4,8 @@ KernelVersion: 2.6.26 ...@@ -4,8 +4,8 @@ KernelVersion: 2.6.26
Contact: Liam Girdwood <lrg@slimlogic.co.uk> Contact: Liam Girdwood <lrg@slimlogic.co.uk>
Description: Description:
Some regulator directories will contain a field called Some regulator directories will contain a field called
state. This reports the regulator enable status, for state. This reports the regulator enable control, for
regulators which can report that value. regulators which can report that input value.
This will be one of the following strings: This will be one of the following strings:
...@@ -14,16 +14,54 @@ Description: ...@@ -14,16 +14,54 @@ Description:
'unknown' 'unknown'
'enabled' means the regulator output is ON and is supplying 'enabled' means the regulator output is ON and is supplying
power to the system. power to the system (assuming no error prevents it).
'disabled' means the regulator output is OFF and is not 'disabled' means the regulator output is OFF and is not
supplying power to the system.. supplying power to the system (unless some non-Linux
control has enabled it).
'unknown' means software cannot determine the state, or 'unknown' means software cannot determine the state, or
the reported state is invalid. the reported state is invalid.
NOTE: this field can be used in conjunction with microvolts NOTE: this field can be used in conjunction with microvolts
and microamps to determine regulator output levels. or microamps to determine configured regulator output levels.
What: /sys/class/regulator/.../status
Description:
Some regulator directories will contain a field called
"status". This reports the current regulator status, for
regulators which can report that output value.
This will be one of the following strings:
off
on
error
fast
normal
idle
standby
"off" means the regulator is not supplying power to the
system.
"on" means the regulator is supplying power to the system,
and the regulator can't report a detailed operation mode.
"error" indicates an out-of-regulation status such as being
disabled due to thermal shutdown, or voltage being unstable
because of problems with the input power supply.
"fast", "normal", "idle", and "standby" are all detailed
regulator operation modes (described elsewhere). They
imply "on", but provide more detail.
Note that regulator status is a function of many inputs,
not limited to control inputs from Linux. For example,
the actual load presented may trigger "error" status; or
a regulator may be enabled by another user, even though
Linux did not enable it.
What: /sys/class/regulator/.../type What: /sys/class/regulator/.../type
...@@ -58,7 +96,7 @@ Description: ...@@ -58,7 +96,7 @@ Description:
Some regulator directories will contain a field called Some regulator directories will contain a field called
microvolts. This holds the regulator output voltage setting microvolts. This holds the regulator output voltage setting
measured in microvolts (i.e. E-6 Volts), for regulators measured in microvolts (i.e. E-6 Volts), for regulators
which can report that voltage. which can report the control input for voltage.
NOTE: This value should not be used to determine the regulator NOTE: This value should not be used to determine the regulator
output voltage level as this value is the same regardless of output voltage level as this value is the same regardless of
...@@ -73,7 +111,7 @@ Description: ...@@ -73,7 +111,7 @@ Description:
Some regulator directories will contain a field called Some regulator directories will contain a field called
microamps. This holds the regulator output current limit microamps. This holds the regulator output current limit
setting measured in microamps (i.e. E-6 Amps), for regulators setting measured in microamps (i.e. E-6 Amps), for regulators
which can report that current. which can report the control input for a current limit.
NOTE: This value should not be used to determine the regulator NOTE: This value should not be used to determine the regulator
output current level as this value is the same regardless of output current level as this value is the same regardless of
...@@ -87,7 +125,7 @@ Contact: Liam Girdwood <lrg@slimlogic.co.uk> ...@@ -87,7 +125,7 @@ Contact: Liam Girdwood <lrg@slimlogic.co.uk>
Description: Description:
Some regulator directories will contain a field called Some regulator directories will contain a field called
opmode. This holds the current regulator operating mode, opmode. This holds the current regulator operating mode,
for regulators which can report it. for regulators which can report that control input value.
The opmode value can be one of the following strings: The opmode value can be one of the following strings:
...@@ -101,7 +139,8 @@ Description: ...@@ -101,7 +139,8 @@ Description:
NOTE: This value should not be used to determine the regulator NOTE: This value should not be used to determine the regulator
output operating mode as this value is the same regardless of output operating mode as this value is the same regardless of
whether the regulator is enabled or disabled. whether the regulator is enabled or disabled. A "status"
attribute may be available to determine the actual mode.
What: /sys/class/regulator/.../min_microvolts What: /sys/class/regulator/.../min_microvolts
......
...@@ -4847,7 +4847,7 @@ M: lrg@slimlogic.co.uk ...@@ -4847,7 +4847,7 @@ M: lrg@slimlogic.co.uk
P: Mark Brown P: Mark Brown
M: broonie@opensource.wolfsonmicro.com M: broonie@opensource.wolfsonmicro.com
W: http://opensource.wolfsonmicro.com/node/15 W: http://opensource.wolfsonmicro.com/node/15
W: http://www.slimlogic.co.uk/?page_id=5 W: http://www.slimlogic.co.uk/?p=48
T: git kernel.org/pub/scm/linux/kernel/git/lrg/voltage-2.6.git T: git kernel.org/pub/scm/linux/kernel/git/lrg/voltage-2.6.git
S: Supported S: Supported
......
...@@ -592,11 +592,9 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features) ...@@ -592,11 +592,9 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features)
/* maybe add LDOs that are omitted on cost-reduced parts */ /* maybe add LDOs that are omitted on cost-reduced parts */
if (twl_has_regulator() && !(features & TPS_SUBSET)) { if (twl_has_regulator() && !(features & TPS_SUBSET)) {
/*
child = add_regulator(TWL4030_REG_VPLL2, pdata->vpll2); child = add_regulator(TWL4030_REG_VPLL2, pdata->vpll2);
if (IS_ERR(child)) if (IS_ERR(child))
return PTR_ERR(child); return PTR_ERR(child);
*/
child = add_regulator(TWL4030_REG_VMMC2, pdata->vmmc2); child = add_regulator(TWL4030_REG_VMMC2, pdata->vmmc2);
if (IS_ERR(child)) if (IS_ERR(child))
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include <linux/leds.h> #include <linux/leds.h>
#include <linux/scatterlist.h> #include <linux/scatterlist.h>
#include <linux/log2.h> #include <linux/log2.h>
#include <linux/regulator/consumer.h>
#include <linux/mmc/card.h> #include <linux/mmc/card.h>
#include <linux/mmc/host.h> #include <linux/mmc/host.h>
...@@ -523,6 +524,105 @@ u32 mmc_vddrange_to_ocrmask(int vdd_min, int vdd_max) ...@@ -523,6 +524,105 @@ u32 mmc_vddrange_to_ocrmask(int vdd_min, int vdd_max)
} }
EXPORT_SYMBOL(mmc_vddrange_to_ocrmask); EXPORT_SYMBOL(mmc_vddrange_to_ocrmask);
#ifdef CONFIG_REGULATOR
/**
* mmc_regulator_get_ocrmask - return mask of supported voltages
* @supply: regulator to use
*
* This returns either a negative errno, or a mask of voltages that
* can be provided to MMC/SD/SDIO devices using the specified voltage
* regulator. This would normally be called before registering the
* MMC host adapter.
*/
int mmc_regulator_get_ocrmask(struct regulator *supply)
{
int result = 0;
int count;
int i;
count = regulator_count_voltages(supply);
if (count < 0)
return count;
for (i = 0; i < count; i++) {
int vdd_uV;
int vdd_mV;
vdd_uV = regulator_list_voltage(supply, i);
if (vdd_uV <= 0)
continue;
vdd_mV = vdd_uV / 1000;
result |= mmc_vddrange_to_ocrmask(vdd_mV, vdd_mV);
}
return result;
}
EXPORT_SYMBOL(mmc_regulator_get_ocrmask);
/**
* mmc_regulator_set_ocr - set regulator to match host->ios voltage
* @vdd_bit: zero for power off, else a bit number (host->ios.vdd)
* @supply: regulator to use
*
* Returns zero on success, else negative errno.
*
* MMC host drivers may use this to enable or disable a regulator using
* a particular supply voltage. This would normally be called from the
* set_ios() method.
*/
int mmc_regulator_set_ocr(struct regulator *supply, unsigned short vdd_bit)
{
int result = 0;
int min_uV, max_uV;
int enabled;
enabled = regulator_is_enabled(supply);
if (enabled < 0)
return enabled;
if (vdd_bit) {
int tmp;
int voltage;
/* REVISIT mmc_vddrange_to_ocrmask() may have set some
* bits this regulator doesn't quite support ... don't
* be too picky, most cards and regulators are OK with
* a 0.1V range goof (it's a small error percentage).
*/
tmp = vdd_bit - ilog2(MMC_VDD_165_195);
if (tmp == 0) {
min_uV = 1650 * 1000;
max_uV = 1950 * 1000;
} else {
min_uV = 1900 * 1000 + tmp * 100 * 1000;
max_uV = min_uV + 100 * 1000;
}
/* avoid needless changes to this voltage; the regulator
* might not allow this operation
*/
voltage = regulator_get_voltage(supply);
if (voltage < 0)
result = voltage;
else if (voltage < min_uV || voltage > max_uV)
result = regulator_set_voltage(supply, min_uV, max_uV);
else
result = 0;
if (result == 0 && !enabled)
result = regulator_enable(supply);
} else if (enabled) {
result = regulator_disable(supply);
}
return result;
}
EXPORT_SYMBOL(mmc_regulator_set_ocr);
#endif
/* /*
* Mask off any voltages we don't support and select * Mask off any voltages we don't support and select
* the lowest voltage * the lowest voltage
......
...@@ -29,8 +29,12 @@ config REGULATOR_DEBUG ...@@ -29,8 +29,12 @@ config REGULATOR_DEBUG
Say yes here to enable debugging support. Say yes here to enable debugging support.
config REGULATOR_FIXED_VOLTAGE config REGULATOR_FIXED_VOLTAGE
tristate tristate "Fixed voltage regulator support"
default n default n
help
This driver provides support for fixed voltage regulators,
useful for systems which use a combination of software
managed regulators and simple non-configurable regulators.
config REGULATOR_VIRTUAL_CONSUMER config REGULATOR_VIRTUAL_CONSUMER
tristate "Virtual regulator consumer support" tristate "Virtual regulator consumer support"
...@@ -52,6 +56,13 @@ config REGULATOR_BQ24022 ...@@ -52,6 +56,13 @@ config REGULATOR_BQ24022
charging select between 100 mA and 500 mA charging current charging select between 100 mA and 500 mA charging current
limit. limit.
config REGULATOR_TWL4030
bool "TI TWL4030/TWL5030/TPS695x0 PMIC"
depends on TWL4030_CORE
help
This driver supports the voltage regulators provided by
this family of companion chips.
config REGULATOR_WM8350 config REGULATOR_WM8350
tristate "Wolfson Microelectroncis WM8350 AudioPlus PMIC" tristate "Wolfson Microelectroncis WM8350 AudioPlus PMIC"
depends on MFD_WM8350 depends on MFD_WM8350
......
...@@ -8,6 +8,7 @@ obj-$(CONFIG_REGULATOR_FIXED_VOLTAGE) += fixed.o ...@@ -8,6 +8,7 @@ obj-$(CONFIG_REGULATOR_FIXED_VOLTAGE) += fixed.o
obj-$(CONFIG_REGULATOR_VIRTUAL_CONSUMER) += virtual.o obj-$(CONFIG_REGULATOR_VIRTUAL_CONSUMER) += virtual.o
obj-$(CONFIG_REGULATOR_BQ24022) += bq24022.o obj-$(CONFIG_REGULATOR_BQ24022) += bq24022.o
obj-$(CONFIG_REGULATOR_TWL4030) += twl4030-regulator.o
obj-$(CONFIG_REGULATOR_WM8350) += wm8350-regulator.o obj-$(CONFIG_REGULATOR_WM8350) += wm8350-regulator.o
obj-$(CONFIG_REGULATOR_WM8400) += wm8400-regulator.o obj-$(CONFIG_REGULATOR_WM8400) += wm8400-regulator.o
obj-$(CONFIG_REGULATOR_DA903X) += da903x.o obj-$(CONFIG_REGULATOR_DA903X) += da903x.o
......
...@@ -105,7 +105,8 @@ static int __init bq24022_probe(struct platform_device *pdev) ...@@ -105,7 +105,8 @@ static int __init bq24022_probe(struct platform_device *pdev)
ret = gpio_direction_output(pdata->gpio_iset2, 0); ret = gpio_direction_output(pdata->gpio_iset2, 0);
ret = gpio_direction_output(pdata->gpio_nce, 1); ret = gpio_direction_output(pdata->gpio_nce, 1);
bq24022 = regulator_register(&bq24022_desc, &pdev->dev, pdata); bq24022 = regulator_register(&bq24022_desc, &pdev->dev,
pdata->init_data, pdata);
if (IS_ERR(bq24022)) { if (IS_ERR(bq24022)) {
dev_dbg(&pdev->dev, "couldn't register regulator\n"); dev_dbg(&pdev->dev, "couldn't register regulator\n");
ret = PTR_ERR(bq24022); ret = PTR_ERR(bq24022);
......
This diff is collapsed.
...@@ -471,7 +471,8 @@ static int __devinit da903x_regulator_probe(struct platform_device *pdev) ...@@ -471,7 +471,8 @@ static int __devinit da903x_regulator_probe(struct platform_device *pdev)
if (ri->desc.id == DA9030_ID_LDO1 || ri->desc.id == DA9030_ID_LDO15) if (ri->desc.id == DA9030_ID_LDO1 || ri->desc.id == DA9030_ID_LDO15)
ri->desc.ops = &da9030_regulator_ldo1_15_ops; ri->desc.ops = &da9030_regulator_ldo1_15_ops;
rdev = regulator_register(&ri->desc, &pdev->dev, ri); rdev = regulator_register(&ri->desc, &pdev->dev,
pdev->dev.platform_data, ri);
if (IS_ERR(rdev)) { if (IS_ERR(rdev)) {
dev_err(&pdev->dev, "failed to register regulator %s\n", dev_err(&pdev->dev, "failed to register regulator %s\n",
ri->desc.name); ri->desc.name);
......
...@@ -73,7 +73,8 @@ static int regulator_fixed_voltage_probe(struct platform_device *pdev) ...@@ -73,7 +73,8 @@ static int regulator_fixed_voltage_probe(struct platform_device *pdev)
drvdata->microvolts = config->microvolts; drvdata->microvolts = config->microvolts;
drvdata->dev = regulator_register(&drvdata->desc, drvdata); drvdata->dev = regulator_register(&drvdata->desc, &pdev->dev,
config->init_data, drvdata);
if (IS_ERR(drvdata->dev)) { if (IS_ERR(drvdata->dev)) {
ret = PTR_ERR(drvdata->dev); ret = PTR_ERR(drvdata->dev);
goto err_name; goto err_name;
......
...@@ -284,7 +284,8 @@ static int __devinit pcf50633_regulator_probe(struct platform_device *pdev) ...@@ -284,7 +284,8 @@ static int __devinit pcf50633_regulator_probe(struct platform_device *pdev)
/* Already set by core driver */ /* Already set by core driver */
pcf = platform_get_drvdata(pdev); pcf = platform_get_drvdata(pdev);
rdev = regulator_register(&regulators[pdev->id], &pdev->dev, pcf); rdev = regulator_register(&regulators[pdev->id], &pdev->dev,
pdev->dev.platform_data, pcf);
if (IS_ERR(rdev)) if (IS_ERR(rdev))
return PTR_ERR(rdev); return PTR_ERR(rdev);
......
This diff is collapsed.
...@@ -226,13 +226,17 @@ static ssize_t set_mode(struct device *dev, struct device_attribute *attr, ...@@ -226,13 +226,17 @@ static ssize_t set_mode(struct device *dev, struct device_attribute *attr,
unsigned int mode; unsigned int mode;
int ret; int ret;
if (strncmp(buf, "fast", strlen("fast")) == 0) /*
* sysfs_streq() doesn't need the \n's, but we add them so the strings
* will be shared with show_mode(), above.
*/
if (sysfs_streq(buf, "fast\n") == 0)
mode = REGULATOR_MODE_FAST; mode = REGULATOR_MODE_FAST;
else if (strncmp(buf, "normal", strlen("normal")) == 0) else if (sysfs_streq(buf, "normal\n") == 0)
mode = REGULATOR_MODE_NORMAL; mode = REGULATOR_MODE_NORMAL;
else if (strncmp(buf, "idle", strlen("idle")) == 0) else if (sysfs_streq(buf, "idle\n") == 0)
mode = REGULATOR_MODE_IDLE; mode = REGULATOR_MODE_IDLE;
else if (strncmp(buf, "standby", strlen("standby")) == 0) else if (sysfs_streq(buf, "standby\n") == 0)
mode = REGULATOR_MODE_STANDBY; mode = REGULATOR_MODE_STANDBY;
else { else {
dev_err(dev, "Configuring invalid mode\n"); dev_err(dev, "Configuring invalid mode\n");
...@@ -256,7 +260,7 @@ static DEVICE_ATTR(min_microamps, 0666, show_min_uA, set_min_uA); ...@@ -256,7 +260,7 @@ static DEVICE_ATTR(min_microamps, 0666, show_min_uA, set_min_uA);
static DEVICE_ATTR(max_microamps, 0666, show_max_uA, set_max_uA); static DEVICE_ATTR(max_microamps, 0666, show_max_uA, set_max_uA);
static DEVICE_ATTR(mode, 0666, show_mode, set_mode); static DEVICE_ATTR(mode, 0666, show_mode, set_mode);
struct device_attribute *attributes[] = { static struct device_attribute *attributes[] = {
&dev_attr_min_microvolts, &dev_attr_min_microvolts,
&dev_attr_max_microvolts, &dev_attr_max_microvolts,
&dev_attr_min_microamps, &dev_attr_min_microamps,
......
...@@ -24,6 +24,9 @@ ...@@ -24,6 +24,9 @@
#include <linux/regulator/driver.h> #include <linux/regulator/driver.h>
#include <linux/regulator/machine.h> #include <linux/regulator/machine.h>
/* Maximum value possible for VSEL */
#define WM8350_DCDC_MAX_VSEL 0x66
/* Microamps */ /* Microamps */
static const int isink_cur[] = { static const int isink_cur[] = {
4, 4,
...@@ -385,6 +388,14 @@ static int wm8350_dcdc_get_voltage(struct regulator_dev *rdev) ...@@ -385,6 +388,14 @@ static int wm8350_dcdc_get_voltage(struct regulator_dev *rdev)
return wm8350_dcdc_val_to_mvolts(val) * 1000; return wm8350_dcdc_val_to_mvolts(val) * 1000;
} }
static int wm8350_dcdc_list_voltage(struct regulator_dev *rdev,
unsigned selector)
{
if (selector > WM8350_DCDC_MAX_VSEL)
return -EINVAL;
return wm8350_dcdc_val_to_mvolts(selector) * 1000;
}
static int wm8350_dcdc_set_suspend_voltage(struct regulator_dev *rdev, int uV) static int wm8350_dcdc_set_suspend_voltage(struct regulator_dev *rdev, int uV)
{ {
struct wm8350 *wm8350 = rdev_get_drvdata(rdev); struct wm8350 *wm8350 = rdev_get_drvdata(rdev);
...@@ -775,6 +786,14 @@ static int wm8350_ldo_get_voltage(struct regulator_dev *rdev) ...@@ -775,6 +786,14 @@ static int wm8350_ldo_get_voltage(struct regulator_dev *rdev)
return wm8350_ldo_val_to_mvolts(val) * 1000; return wm8350_ldo_val_to_mvolts(val) * 1000;
} }
static int wm8350_ldo_list_voltage(struct regulator_dev *rdev,
unsigned selector)
{
if (selector > WM8350_LDO1_VSEL_MASK)
return -EINVAL;
return wm8350_ldo_val_to_mvolts(selector) * 1000;
}
int wm8350_dcdc_set_slot(struct wm8350 *wm8350, int dcdc, u16 start, int wm8350_dcdc_set_slot(struct wm8350 *wm8350, int dcdc, u16 start,
u16 stop, u16 fault) u16 stop, u16 fault)
{ {
...@@ -1031,18 +1050,30 @@ static unsigned int wm8350_dcdc_get_mode(struct regulator_dev *rdev) ...@@ -1031,18 +1050,30 @@ static unsigned int wm8350_dcdc_get_mode(struct regulator_dev *rdev)
int dcdc = rdev_get_id(rdev); int dcdc = rdev_get_id(rdev);
u16 mask, sleep, active, force; u16 mask, sleep, active, force;
int mode = REGULATOR_MODE_NORMAL; int mode = REGULATOR_MODE_NORMAL;
int reg;
if (dcdc < WM8350_DCDC_1 || dcdc > WM8350_DCDC_6) switch (dcdc) {
return -EINVAL; case WM8350_DCDC_1:
reg = WM8350_DCDC1_FORCE_PWM;
if (dcdc == WM8350_DCDC_2 || dcdc == WM8350_DCDC_5) break;
case WM8350_DCDC_3:
reg = WM8350_DCDC3_FORCE_PWM;
break;
case WM8350_DCDC_4:
reg = WM8350_DCDC4_FORCE_PWM;
break;
case WM8350_DCDC_6:
reg = WM8350_DCDC6_FORCE_PWM;
break;
default:
return -EINVAL; return -EINVAL;
}
mask = 1 << (dcdc - WM8350_DCDC_1); mask = 1 << (dcdc - WM8350_DCDC_1);
active = wm8350_reg_read(wm8350, WM8350_DCDC_ACTIVE_OPTIONS) & mask; active = wm8350_reg_read(wm8350, WM8350_DCDC_ACTIVE_OPTIONS) & mask;
force = wm8350_reg_read(wm8350, reg) & WM8350_DCDC1_FORCE_PWM_ENA;
sleep = wm8350_reg_read(wm8350, WM8350_DCDC_SLEEP_OPTIONS) & mask; sleep = wm8350_reg_read(wm8350, WM8350_DCDC_SLEEP_OPTIONS) & mask;
force = wm8350_reg_read(wm8350, WM8350_DCDC1_FORCE_PWM)
& WM8350_DCDC1_FORCE_PWM_ENA;
dev_dbg(wm8350->dev, "mask %x active %x sleep %x force %x", dev_dbg(wm8350->dev, "mask %x active %x sleep %x force %x",
mask, active, sleep, force); mask, active, sleep, force);
...@@ -1150,6 +1181,7 @@ static int wm8350_ldo_is_enabled(struct regulator_dev *rdev) ...@@ -1150,6 +1181,7 @@ static int wm8350_ldo_is_enabled(struct regulator_dev *rdev)
static struct regulator_ops wm8350_dcdc_ops = { static struct regulator_ops wm8350_dcdc_ops = {
.set_voltage = wm8350_dcdc_set_voltage, .set_voltage = wm8350_dcdc_set_voltage,
.get_voltage = wm8350_dcdc_get_voltage, .get_voltage = wm8350_dcdc_get_voltage,
.list_voltage = wm8350_dcdc_list_voltage,
.enable = wm8350_dcdc_enable, .enable = wm8350_dcdc_enable,
.disable = wm8350_dcdc_disable, .disable = wm8350_dcdc_disable,
.get_mode = wm8350_dcdc_get_mode, .get_mode = wm8350_dcdc_get_mode,
...@@ -1173,6 +1205,7 @@ static struct regulator_ops wm8350_dcdc2_5_ops = { ...@@ -1173,6 +1205,7 @@ static struct regulator_ops wm8350_dcdc2_5_ops = {
static struct regulator_ops wm8350_ldo_ops = { static struct regulator_ops wm8350_ldo_ops = {
.set_voltage = wm8350_ldo_set_voltage, .set_voltage = wm8350_ldo_set_voltage,
.get_voltage = wm8350_ldo_get_voltage, .get_voltage = wm8350_ldo_get_voltage,
.list_voltage = wm8350_ldo_list_voltage,
.enable = wm8350_ldo_enable, .enable = wm8350_ldo_enable,
.disable = wm8350_ldo_disable, .disable = wm8350_ldo_disable,
.is_enabled = wm8350_ldo_is_enabled, .is_enabled = wm8350_ldo_is_enabled,
...@@ -1197,6 +1230,7 @@ static struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = { ...@@ -1197,6 +1230,7 @@ static struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = {
.ops = &wm8350_dcdc_ops, .ops = &wm8350_dcdc_ops,
.irq = WM8350_IRQ_UV_DC1, .irq = WM8350_IRQ_UV_DC1,
.type = REGULATOR_VOLTAGE, .type = REGULATOR_VOLTAGE,
.n_voltages = WM8350_DCDC_MAX_VSEL + 1,
.owner = THIS_MODULE, .owner = THIS_MODULE,
}, },
{ {
...@@ -1213,6 +1247,7 @@ static struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = { ...@@ -1213,6 +1247,7 @@ static struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = {
.ops = &wm8350_dcdc_ops, .ops = &wm8350_dcdc_ops,
.irq = WM8350_IRQ_UV_DC3, .irq = WM8350_IRQ_UV_DC3,
.type = REGULATOR_VOLTAGE, .type = REGULATOR_VOLTAGE,
.n_voltages = WM8350_DCDC_MAX_VSEL + 1,
.owner = THIS_MODULE, .owner = THIS_MODULE,
}, },
{ {
...@@ -1221,6 +1256,7 @@ static struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = { ...@@ -1221,6 +1256,7 @@ static struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = {
.ops = &wm8350_dcdc_ops, .ops = &wm8350_dcdc_ops,
.irq = WM8350_IRQ_UV_DC4, .irq = WM8350_IRQ_UV_DC4,
.type = REGULATOR_VOLTAGE, .type = REGULATOR_VOLTAGE,
.n_voltages = WM8350_DCDC_MAX_VSEL + 1,
.owner = THIS_MODULE, .owner = THIS_MODULE,
}, },
{ {
...@@ -1237,6 +1273,7 @@ static struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = { ...@@ -1237,6 +1273,7 @@ static struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = {
.ops = &wm8350_dcdc_ops, .ops = &wm8350_dcdc_ops,
.irq = WM8350_IRQ_UV_DC6, .irq = WM8350_IRQ_UV_DC6,
.type = REGULATOR_VOLTAGE, .type = REGULATOR_VOLTAGE,
.n_voltages = WM8350_DCDC_MAX_VSEL + 1,
.owner = THIS_MODULE, .owner = THIS_MODULE,
}, },
{ {
...@@ -1245,6 +1282,7 @@ static struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = { ...@@ -1245,6 +1282,7 @@ static struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = {
.ops = &wm8350_ldo_ops, .ops = &wm8350_ldo_ops,
.irq = WM8350_IRQ_UV_LDO1, .irq = WM8350_IRQ_UV_LDO1,
.type = REGULATOR_VOLTAGE, .type = REGULATOR_VOLTAGE,
.n_voltages = WM8350_LDO1_VSEL_MASK + 1,
.owner = THIS_MODULE, .owner = THIS_MODULE,
}, },
{ {
...@@ -1253,6 +1291,7 @@ static struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = { ...@@ -1253,6 +1291,7 @@ static struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = {
.ops = &wm8350_ldo_ops, .ops = &wm8350_ldo_ops,
.irq = WM8350_IRQ_UV_LDO2, .irq = WM8350_IRQ_UV_LDO2,
.type = REGULATOR_VOLTAGE, .type = REGULATOR_VOLTAGE,
.n_voltages = WM8350_LDO2_VSEL_MASK + 1,
.owner = THIS_MODULE, .owner = THIS_MODULE,
}, },
{ {
...@@ -1261,6 +1300,7 @@ static struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = { ...@@ -1261,6 +1300,7 @@ static struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = {
.ops = &wm8350_ldo_ops, .ops = &wm8350_ldo_ops,
.irq = WM8350_IRQ_UV_LDO3, .irq = WM8350_IRQ_UV_LDO3,
.type = REGULATOR_VOLTAGE, .type = REGULATOR_VOLTAGE,
.n_voltages = WM8350_LDO3_VSEL_MASK + 1,
.owner = THIS_MODULE, .owner = THIS_MODULE,
}, },
{ {
...@@ -1269,6 +1309,7 @@ static struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = { ...@@ -1269,6 +1309,7 @@ static struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = {
.ops = &wm8350_ldo_ops, .ops = &wm8350_ldo_ops,
.irq = WM8350_IRQ_UV_LDO4, .irq = WM8350_IRQ_UV_LDO4,
.type = REGULATOR_VOLTAGE, .type = REGULATOR_VOLTAGE,
.n_voltages = WM8350_LDO4_VSEL_MASK + 1,
.owner = THIS_MODULE, .owner = THIS_MODULE,
}, },
{ {
...@@ -1293,6 +1334,7 @@ static void pmic_uv_handler(struct wm8350 *wm8350, int irq, void *data) ...@@ -1293,6 +1334,7 @@ static void pmic_uv_handler(struct wm8350 *wm8350, int irq, void *data)
{ {
struct regulator_dev *rdev = (struct regulator_dev *)data; struct regulator_dev *rdev = (struct regulator_dev *)data;
mutex_lock(&rdev->mutex);
if (irq == WM8350_IRQ_CS1 || irq == WM8350_IRQ_CS2) if (irq == WM8350_IRQ_CS1 || irq == WM8350_IRQ_CS2)
regulator_notifier_call_chain(rdev, regulator_notifier_call_chain(rdev,
REGULATOR_EVENT_REGULATION_OUT, REGULATOR_EVENT_REGULATION_OUT,
...@@ -1301,6 +1343,7 @@ static void pmic_uv_handler(struct wm8350 *wm8350, int irq, void *data) ...@@ -1301,6 +1343,7 @@ static void pmic_uv_handler(struct wm8350 *wm8350, int irq, void *data)
regulator_notifier_call_chain(rdev, regulator_notifier_call_chain(rdev,
REGULATOR_EVENT_UNDER_VOLTAGE, REGULATOR_EVENT_UNDER_VOLTAGE,
wm8350); wm8350);
mutex_unlock(&rdev->mutex);
} }
static int wm8350_regulator_probe(struct platform_device *pdev) static int wm8350_regulator_probe(struct platform_device *pdev)
...@@ -1333,9 +1376,9 @@ static int wm8350_regulator_probe(struct platform_device *pdev) ...@@ -1333,9 +1376,9 @@ static int wm8350_regulator_probe(struct platform_device *pdev)
break; break;
} }
/* register regulator */ /* register regulator */
rdev = regulator_register(&wm8350_reg[pdev->id], &pdev->dev, rdev = regulator_register(&wm8350_reg[pdev->id], &pdev->dev,
pdev->dev.platform_data,
dev_get_drvdata(&pdev->dev)); dev_get_drvdata(&pdev->dev));
if (IS_ERR(rdev)) { if (IS_ERR(rdev)) {
dev_err(&pdev->dev, "failed to register %s\n", dev_err(&pdev->dev, "failed to register %s\n",
......
...@@ -43,6 +43,18 @@ static int wm8400_ldo_disable(struct regulator_dev *dev) ...@@ -43,6 +43,18 @@ static int wm8400_ldo_disable(struct regulator_dev *dev)
WM8400_LDO1_ENA, 0); WM8400_LDO1_ENA, 0);
} }
static int wm8400_ldo_list_voltage(struct regulator_dev *dev,
unsigned selector)
{
if (selector > WM8400_LDO1_VSEL_MASK)
return -EINVAL;
if (selector < 15)
return 900000 + (selector * 50000);
else
return 1600000 + ((selector - 14) * 100000);
}
static int wm8400_ldo_get_voltage(struct regulator_dev *dev) static int wm8400_ldo_get_voltage(struct regulator_dev *dev)
{ {
struct wm8400 *wm8400 = rdev_get_drvdata(dev); struct wm8400 *wm8400 = rdev_get_drvdata(dev);
...@@ -51,10 +63,7 @@ static int wm8400_ldo_get_voltage(struct regulator_dev *dev) ...@@ -51,10 +63,7 @@ static int wm8400_ldo_get_voltage(struct regulator_dev *dev)
val = wm8400_reg_read(wm8400, WM8400_LDO1_CONTROL + rdev_get_id(dev)); val = wm8400_reg_read(wm8400, WM8400_LDO1_CONTROL + rdev_get_id(dev));
val &= WM8400_LDO1_VSEL_MASK; val &= WM8400_LDO1_VSEL_MASK;
if (val < 15) return wm8400_ldo_list_voltage(dev, val);
return 900000 + (val * 50000);
else
return 1600000 + ((val - 14) * 100000);
} }
static int wm8400_ldo_set_voltage(struct regulator_dev *dev, static int wm8400_ldo_set_voltage(struct regulator_dev *dev,
...@@ -92,6 +101,7 @@ static struct regulator_ops wm8400_ldo_ops = { ...@@ -92,6 +101,7 @@ static struct regulator_ops wm8400_ldo_ops = {
.is_enabled = wm8400_ldo_is_enabled, .is_enabled = wm8400_ldo_is_enabled,
.enable = wm8400_ldo_enable, .enable = wm8400_ldo_enable,
.disable = wm8400_ldo_disable, .disable = wm8400_ldo_disable,
.list_voltage = wm8400_ldo_list_voltage,
.get_voltage = wm8400_ldo_get_voltage, .get_voltage = wm8400_ldo_get_voltage,
.set_voltage = wm8400_ldo_set_voltage, .set_voltage = wm8400_ldo_set_voltage,
}; };
...@@ -124,6 +134,15 @@ static int wm8400_dcdc_disable(struct regulator_dev *dev) ...@@ -124,6 +134,15 @@ static int wm8400_dcdc_disable(struct regulator_dev *dev)
WM8400_DC1_ENA, 0); WM8400_DC1_ENA, 0);
} }
static int wm8400_dcdc_list_voltage(struct regulator_dev *dev,
unsigned selector)
{
if (selector > WM8400_DC1_VSEL_MASK)
return -EINVAL;
return 850000 + (selector * 25000);
}
static int wm8400_dcdc_get_voltage(struct regulator_dev *dev) static int wm8400_dcdc_get_voltage(struct regulator_dev *dev)
{ {
struct wm8400 *wm8400 = rdev_get_drvdata(dev); struct wm8400 *wm8400 = rdev_get_drvdata(dev);
...@@ -237,6 +256,7 @@ static struct regulator_ops wm8400_dcdc_ops = { ...@@ -237,6 +256,7 @@ static struct regulator_ops wm8400_dcdc_ops = {
.is_enabled = wm8400_dcdc_is_enabled, .is_enabled = wm8400_dcdc_is_enabled,
.enable = wm8400_dcdc_enable, .enable = wm8400_dcdc_enable,
.disable = wm8400_dcdc_disable, .disable = wm8400_dcdc_disable,
.list_voltage = wm8400_dcdc_list_voltage,
.get_voltage = wm8400_dcdc_get_voltage, .get_voltage = wm8400_dcdc_get_voltage,
.set_voltage = wm8400_dcdc_set_voltage, .set_voltage = wm8400_dcdc_set_voltage,
.get_mode = wm8400_dcdc_get_mode, .get_mode = wm8400_dcdc_get_mode,
...@@ -249,6 +269,7 @@ static struct regulator_desc regulators[] = { ...@@ -249,6 +269,7 @@ static struct regulator_desc regulators[] = {
.name = "LDO1", .name = "LDO1",
.id = WM8400_LDO1, .id = WM8400_LDO1,
.ops = &wm8400_ldo_ops, .ops = &wm8400_ldo_ops,
.n_voltages = WM8400_LDO1_VSEL_MASK + 1,
.type = REGULATOR_VOLTAGE, .type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE, .owner = THIS_MODULE,
}, },
...@@ -256,6 +277,7 @@ static struct regulator_desc regulators[] = { ...@@ -256,6 +277,7 @@ static struct regulator_desc regulators[] = {
.name = "LDO2", .name = "LDO2",
.id = WM8400_LDO2, .id = WM8400_LDO2,
.ops = &wm8400_ldo_ops, .ops = &wm8400_ldo_ops,
.n_voltages = WM8400_LDO2_VSEL_MASK + 1,
.type = REGULATOR_VOLTAGE, .type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE, .owner = THIS_MODULE,
}, },
...@@ -263,6 +285,7 @@ static struct regulator_desc regulators[] = { ...@@ -263,6 +285,7 @@ static struct regulator_desc regulators[] = {
.name = "LDO3", .name = "LDO3",
.id = WM8400_LDO3, .id = WM8400_LDO3,
.ops = &wm8400_ldo_ops, .ops = &wm8400_ldo_ops,
.n_voltages = WM8400_LDO3_VSEL_MASK + 1,
.type = REGULATOR_VOLTAGE, .type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE, .owner = THIS_MODULE,
}, },
...@@ -270,6 +293,7 @@ static struct regulator_desc regulators[] = { ...@@ -270,6 +293,7 @@ static struct regulator_desc regulators[] = {
.name = "LDO4", .name = "LDO4",
.id = WM8400_LDO4, .id = WM8400_LDO4,
.ops = &wm8400_ldo_ops, .ops = &wm8400_ldo_ops,
.n_voltages = WM8400_LDO4_VSEL_MASK + 1,
.type = REGULATOR_VOLTAGE, .type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE, .owner = THIS_MODULE,
}, },
...@@ -277,6 +301,7 @@ static struct regulator_desc regulators[] = { ...@@ -277,6 +301,7 @@ static struct regulator_desc regulators[] = {
.name = "DCDC1", .name = "DCDC1",
.id = WM8400_DCDC1, .id = WM8400_DCDC1,
.ops = &wm8400_dcdc_ops, .ops = &wm8400_dcdc_ops,
.n_voltages = WM8400_DC1_VSEL_MASK + 1,
.type = REGULATOR_VOLTAGE, .type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE, .owner = THIS_MODULE,
}, },
...@@ -284,6 +309,7 @@ static struct regulator_desc regulators[] = { ...@@ -284,6 +309,7 @@ static struct regulator_desc regulators[] = {
.name = "DCDC2", .name = "DCDC2",
.id = WM8400_DCDC2, .id = WM8400_DCDC2,
.ops = &wm8400_dcdc_ops, .ops = &wm8400_dcdc_ops,
.n_voltages = WM8400_DC2_VSEL_MASK + 1,
.type = REGULATOR_VOLTAGE, .type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE, .owner = THIS_MODULE,
}, },
...@@ -294,7 +320,7 @@ static int __devinit wm8400_regulator_probe(struct platform_device *pdev) ...@@ -294,7 +320,7 @@ static int __devinit wm8400_regulator_probe(struct platform_device *pdev)
struct regulator_dev *rdev; struct regulator_dev *rdev;
rdev = regulator_register(&regulators[pdev->id], &pdev->dev, rdev = regulator_register(&regulators[pdev->id], &pdev->dev,
pdev->dev.driver_data); pdev->dev.platform_data, pdev->dev.driver_data);
if (IS_ERR(rdev)) if (IS_ERR(rdev))
return PTR_ERR(rdev); return PTR_ERR(rdev);
......
...@@ -218,6 +218,53 @@ int twl4030_i2c_read(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes); ...@@ -218,6 +218,53 @@ int twl4030_i2c_read(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes);
/*----------------------------------------------------------------------*/ /*----------------------------------------------------------------------*/
/* Power bus message definitions */
#define DEV_GRP_NULL 0x0
#define DEV_GRP_P1 0x1
#define DEV_GRP_P2 0x2
#define DEV_GRP_P3 0x4
#define RES_GRP_RES 0x0
#define RES_GRP_PP 0x1
#define RES_GRP_RC 0x2
#define RES_GRP_PP_RC 0x3
#define RES_GRP_PR 0x4
#define RES_GRP_PP_PR 0x5
#define RES_GRP_RC_PR 0x6
#define RES_GRP_ALL 0x7
#define RES_TYPE2_R0 0x0
#define RES_TYPE_ALL 0x7
#define RES_STATE_WRST 0xF
#define RES_STATE_ACTIVE 0xE
#define RES_STATE_SLEEP 0x8
#define RES_STATE_OFF 0x0
/*
* Power Bus Message Format ... these can be sent individually by Linux,
* but are usually part of downloaded scripts that are run when various
* power events are triggered.
*
* Broadcast Message (16 Bits):
* DEV_GRP[15:13] MT[12] RES_GRP[11:9] RES_TYPE2[8:7] RES_TYPE[6:4]
* RES_STATE[3:0]
*
* Singular Message (16 Bits):
* DEV_GRP[15:13] MT[12] RES_ID[11:4] RES_STATE[3:0]
*/
#define MSG_BROADCAST(devgrp, grp, type, type2, state) \
( (devgrp) << 13 | 1 << 12 | (grp) << 9 | (type2) << 7 \
| (type) << 4 | (state))
#define MSG_SINGULAR(devgrp, id, state) \
((devgrp) << 13 | 0 << 12 | (id) << 4 | (state))
/*----------------------------------------------------------------------*/
struct twl4030_bci_platform_data { struct twl4030_bci_platform_data {
int *battery_tmp_tbl; int *battery_tmp_tbl;
unsigned int tblsize; unsigned int tblsize;
......
...@@ -192,5 +192,10 @@ static inline void mmc_signal_sdio_irq(struct mmc_host *host) ...@@ -192,5 +192,10 @@ static inline void mmc_signal_sdio_irq(struct mmc_host *host)
wake_up_process(host->sdio_irq_thread); wake_up_process(host->sdio_irq_thread);
} }
struct regulator;
int mmc_regulator_get_ocrmask(struct regulator *supply);
int mmc_regulator_set_ocr(struct regulator *supply, unsigned short vdd_bit);
#endif #endif
...@@ -10,6 +10,8 @@ ...@@ -10,6 +10,8 @@
* *
*/ */
struct regulator_init_data;
/** /**
* bq24022_mach_info - platform data for bq24022 * bq24022_mach_info - platform data for bq24022
* @gpio_nce: GPIO line connected to the nCE pin, used to enable / disable charging * @gpio_nce: GPIO line connected to the nCE pin, used to enable / disable charging
...@@ -18,4 +20,5 @@ ...@@ -18,4 +20,5 @@
struct bq24022_mach_info { struct bq24022_mach_info {
int gpio_nce; int gpio_nce;
int gpio_iset2; int gpio_iset2;
struct regulator_init_data *init_data;
}; };
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* *
* Copyright (C) 2007, 2008 Wolfson Microelectronics PLC. * Copyright (C) 2007, 2008 Wolfson Microelectronics PLC.
* *
* Author: Liam Girdwood <lg@opensource.wolfsonmicro.com> * Author: Liam Girdwood <lrg@slimlogic.co.uk>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as * it under the terms of the GNU General Public License version 2 as
...@@ -88,6 +88,7 @@ ...@@ -88,6 +88,7 @@
* FAIL Regulator output has failed. * FAIL Regulator output has failed.
* OVER_TEMP Regulator over temp. * OVER_TEMP Regulator over temp.
* FORCE_DISABLE Regulator shut down by software. * FORCE_DISABLE Regulator shut down by software.
* VOLTAGE_CHANGE Regulator voltage changed.
* *
* NOTE: These events can be OR'ed together when passed into handler. * NOTE: These events can be OR'ed together when passed into handler.
*/ */
...@@ -98,6 +99,7 @@ ...@@ -98,6 +99,7 @@
#define REGULATOR_EVENT_FAIL 0x08 #define REGULATOR_EVENT_FAIL 0x08
#define REGULATOR_EVENT_OVER_TEMP 0x10 #define REGULATOR_EVENT_OVER_TEMP 0x10
#define REGULATOR_EVENT_FORCE_DISABLE 0x20 #define REGULATOR_EVENT_FORCE_DISABLE 0x20
#define REGULATOR_EVENT_VOLTAGE_CHANGE 0x40
struct regulator; struct regulator;
...@@ -140,6 +142,8 @@ int regulator_bulk_disable(int num_consumers, ...@@ -140,6 +142,8 @@ int regulator_bulk_disable(int num_consumers,
void regulator_bulk_free(int num_consumers, void regulator_bulk_free(int num_consumers,
struct regulator_bulk_data *consumers); struct regulator_bulk_data *consumers);
int regulator_count_voltages(struct regulator *regulator);
int regulator_list_voltage(struct regulator *regulator, unsigned selector);
int regulator_set_voltage(struct regulator *regulator, int min_uV, int max_uV); int regulator_set_voltage(struct regulator *regulator, int min_uV, int max_uV);
int regulator_get_voltage(struct regulator *regulator); int regulator_get_voltage(struct regulator *regulator);
int regulator_set_current_limit(struct regulator *regulator, int regulator_set_current_limit(struct regulator *regulator,
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* *
* Copyright (C) 2007, 2008 Wolfson Microelectronics PLC. * Copyright (C) 2007, 2008 Wolfson Microelectronics PLC.
* *
* Author: Liam Girdwood <lg@opensource.wolfsonmicro.com> * Author: Liam Girdwood <lrg@slimlogic.co.uk>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as * it under the terms of the GNU General Public License version 2 as
...@@ -21,25 +21,38 @@ ...@@ -21,25 +21,38 @@
struct regulator_dev; struct regulator_dev;
struct regulator_init_data; struct regulator_init_data;
enum regulator_status {
REGULATOR_STATUS_OFF,
REGULATOR_STATUS_ON,
REGULATOR_STATUS_ERROR,
/* fast/normal/idle/standby are flavors of "on" */
REGULATOR_STATUS_FAST,
REGULATOR_STATUS_NORMAL,
REGULATOR_STATUS_IDLE,
REGULATOR_STATUS_STANDBY,
};
/** /**
* struct regulator_ops - regulator operations. * struct regulator_ops - regulator operations.
* *
* This struct describes regulator operations which can be implemented by * @enable: Configure the regulator as enabled.
* regulator chip drivers. * @disable: Configure the regulator as disabled.
*
* @enable: Enable the regulator.
* @disable: Disable the regulator.
* @is_enabled: Return 1 if the regulator is enabled, 0 otherwise. * @is_enabled: Return 1 if the regulator is enabled, 0 otherwise.
* *
* @set_voltage: Set the voltage for the regulator within the range specified. * @set_voltage: Set the voltage for the regulator within the range specified.
* The driver should select the voltage closest to min_uV. * The driver should select the voltage closest to min_uV.
* @get_voltage: Return the currently configured voltage for the regulator. * @get_voltage: Return the currently configured voltage for the regulator.
* @list_voltage: Return one of the supported voltages, in microvolts; zero
* if the selector indicates a voltage that is unusable on this system;
* or negative errno. Selectors range from zero to one less than
* regulator_desc.n_voltages. Voltages may be reported in any order.
* *
* @set_current_limit: Configure a limit for a current-limited regulator. * @set_current_limit: Configure a limit for a current-limited regulator.
* @get_current_limit: Get the limit for a current-limited regulator. * @get_current_limit: Get the configured limit for a current-limited regulator.
* *
* @set_mode: Set the operating mode for the regulator. * @get_mode: Get the configured operating mode for the regulator.
* @get_mode: Get the current operating mode for the regulator. * @get_status: Return actual (not as-configured) status of regulator, as a
* REGULATOR_STATUS value (or negative errno)
* @get_optimum_mode: Get the most efficient operating mode for the regulator * @get_optimum_mode: Get the most efficient operating mode for the regulator
* when running with the specified parameters. * when running with the specified parameters.
* *
...@@ -51,9 +64,15 @@ struct regulator_init_data; ...@@ -51,9 +64,15 @@ struct regulator_init_data;
* suspended. * suspended.
* @set_suspend_mode: Set the operating mode for the regulator when the * @set_suspend_mode: Set the operating mode for the regulator when the
* system is suspended. * system is suspended.
*
* This struct describes regulator operations which can be implemented by
* regulator chip drivers.
*/ */
struct regulator_ops { struct regulator_ops {
/* enumerate supported voltages */
int (*list_voltage) (struct regulator_dev *, unsigned selector);
/* get/set regulator voltage */ /* get/set regulator voltage */
int (*set_voltage) (struct regulator_dev *, int min_uV, int max_uV); int (*set_voltage) (struct regulator_dev *, int min_uV, int max_uV);
int (*get_voltage) (struct regulator_dev *); int (*get_voltage) (struct regulator_dev *);
...@@ -72,6 +91,13 @@ struct regulator_ops { ...@@ -72,6 +91,13 @@ struct regulator_ops {
int (*set_mode) (struct regulator_dev *, unsigned int mode); int (*set_mode) (struct regulator_dev *, unsigned int mode);
unsigned int (*get_mode) (struct regulator_dev *); unsigned int (*get_mode) (struct regulator_dev *);
/* report regulator status ... most other accessors report
* control inputs, this reports results of combining inputs
* from Linux (and other sources) with the actual load.
* returns REGULATOR_STATUS_* or negative errno.
*/
int (*get_status)(struct regulator_dev *);
/* get most efficient regulator operating mode for load */ /* get most efficient regulator operating mode for load */
unsigned int (*get_optimum_mode) (struct regulator_dev *, int input_uV, unsigned int (*get_optimum_mode) (struct regulator_dev *, int input_uV,
int output_uV, int load_uA); int output_uV, int load_uA);
...@@ -106,6 +132,7 @@ enum regulator_type { ...@@ -106,6 +132,7 @@ enum regulator_type {
* *
* @name: Identifying name for the regulator. * @name: Identifying name for the regulator.
* @id: Numerical identifier for the regulator. * @id: Numerical identifier for the regulator.
* @n_voltages: Number of selectors available for ops.list_voltage().
* @ops: Regulator operations table. * @ops: Regulator operations table.
* @irq: Interrupt number for the regulator. * @irq: Interrupt number for the regulator.
* @type: Indicates if the regulator is a voltage or current regulator. * @type: Indicates if the regulator is a voltage or current regulator.
...@@ -114,14 +141,48 @@ enum regulator_type { ...@@ -114,14 +141,48 @@ enum regulator_type {
struct regulator_desc { struct regulator_desc {
const char *name; const char *name;
int id; int id;
unsigned n_voltages;
struct regulator_ops *ops; struct regulator_ops *ops;
int irq; int irq;
enum regulator_type type; enum regulator_type type;
struct module *owner; struct module *owner;
}; };
/*
* struct regulator_dev
*
* Voltage / Current regulator class device. One for each
* regulator.
*
* This should *not* be used directly by anything except the regulator
* core and notification injection (which should take the mutex and do
* no other direct access).
*/
struct regulator_dev {
struct regulator_desc *desc;
int use_count;
/* lists we belong to */
struct list_head list; /* list of all regulators */
struct list_head slist; /* list of supplied regulators */
/* lists we own */
struct list_head consumer_list; /* consumers we supply */
struct list_head supply_list; /* regulators we supply */
struct blocking_notifier_head notifier;
struct mutex mutex; /* consumer lock */
struct module *owner;
struct device dev;
struct regulation_constraints *constraints;
struct regulator_dev *supply; /* for tree */
void *reg_data; /* regulator_dev data */
};
struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc, struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,
struct device *dev, void *driver_data); struct device *dev, struct regulator_init_data *init_data,
void *driver_data);
void regulator_unregister(struct regulator_dev *rdev); void regulator_unregister(struct regulator_dev *rdev);
int regulator_notifier_call_chain(struct regulator_dev *rdev, int regulator_notifier_call_chain(struct regulator_dev *rdev,
......
...@@ -14,9 +14,12 @@ ...@@ -14,9 +14,12 @@
#ifndef __REGULATOR_FIXED_H #ifndef __REGULATOR_FIXED_H
#define __REGULATOR_FIXED_H #define __REGULATOR_FIXED_H
struct regulator_init_data;
struct fixed_voltage_config { struct fixed_voltage_config {
const char *supply_name; const char *supply_name;
int microvolts; int microvolts;
struct regulator_init_data *init_data;
}; };
#endif #endif
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* *
* Copyright (C) 2007, 2008 Wolfson Microelectronics PLC. * Copyright (C) 2007, 2008 Wolfson Microelectronics PLC.
* *
* Author: Liam Girdwood <lg@opensource.wolfsonmicro.com> * Author: Liam Girdwood <lrg@slimlogic.co.uk>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as * it under the terms of the GNU General Public License version 2 as
...@@ -73,7 +73,9 @@ struct regulator_state { ...@@ -73,7 +73,9 @@ struct regulator_state {
* *
* @always_on: Set if the regulator should never be disabled. * @always_on: Set if the regulator should never be disabled.
* @boot_on: Set if the regulator is enabled when the system is initially * @boot_on: Set if the regulator is enabled when the system is initially
* started. * started. If the regulator is not enabled by the hardware or
* bootloader then it will be enabled when the constraints are
* applied.
* @apply_uV: Apply the voltage constraint when initialising. * @apply_uV: Apply the voltage constraint when initialising.
* *
* @input_uV: Input voltage for regulator when supplied by another regulator. * @input_uV: Input voltage for regulator when supplied by another regulator.
...@@ -83,6 +85,7 @@ struct regulator_state { ...@@ -83,6 +85,7 @@ struct regulator_state {
* @state_standby: State for regulator when system is suspended in standby * @state_standby: State for regulator when system is suspended in standby
* mode. * mode.
* @initial_state: Suspend state to set by default. * @initial_state: Suspend state to set by default.
* @initial_mode: Mode to set at startup.
*/ */
struct regulation_constraints { struct regulation_constraints {
...@@ -111,6 +114,9 @@ struct regulation_constraints { ...@@ -111,6 +114,9 @@ struct regulation_constraints {
struct regulator_state state_standby; struct regulator_state state_standby;
suspend_state_t initial_state; /* suspend state to set at init */ suspend_state_t initial_state; /* suspend state to set at init */
/* mode to set on startup */
unsigned int initial_mode;
/* constriant flags */ /* constriant flags */
unsigned always_on:1; /* regulator never off when system is on */ unsigned always_on:1; /* regulator never off when system is on */
unsigned boot_on:1; /* bootloader/firmware enabled regulator */ unsigned boot_on:1; /* bootloader/firmware enabled regulator */
...@@ -160,4 +166,6 @@ struct regulator_init_data { ...@@ -160,4 +166,6 @@ struct regulator_init_data {
int regulator_suspend_prepare(suspend_state_t state); int regulator_suspend_prepare(suspend_state_t state);
void regulator_has_full_constraints(void);
#endif #endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment