Commit fd8b327e 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: (41 commits)
  regulator: Add some brief design documentation
  regulator: fix voltage range in da9034 ldo12
  regulator/driver: be more specific in nanodoc for is_enabled
  regulator/lp3971: drop unnecessary initialization
  regulator: drop 'default n'
  regulator: fix typos
  regulator: fix calculation of voltage range in da9034_set_ldo12_voltage()
  regulator: update a filename in documentation
  drivers/regulator/Kconfig: fix typo (s/Usersapce/Userspace/) in REGULATOR_USERSPACE_CONSUMER description
  REGULATOR Handle positive returncode from enable
  regulator: tps650xx - build fixes for x86_64
  Fix some regulator documentation
  Regulator: Adding TPS65023 and TPS6507x in Kconfig and Makefile
  Regulator: Add TPS6507x regulator driver
  Regulator: Add TPS65023 regulator driver
  regulator: userspace: use sysfs_create_group
  regulator: Add GPIO enable control to fixed voltage regulator driver
  Regulator: Implement list_voltage for pcf50633 regulator driver.
  regulator: regulator_enable() permission checking
  regulator: Push locking for regulator_is_enabled() out
  ...
parents 0c9af280 63209a71
Regulator API design notes
==========================
This document provides a brief, partially structured, overview of some
of the design considerations which impact the regulator API design.
Safety
------
- Errors in regulator configuration can have very serious consequences
for the system, potentially including lasting hardware damage.
- It is not possible to automatically determine the power confugration
of the system - software-equivalent variants of the same chip may
have different power requirments, and not all components with power
requirements are visible to software.
=> The API should make no changes to the hardware state unless it has
specific knowledge that these changes are safe to do perform on
this particular system.
Consumer use cases
------------------
- The overwhelming majority of devices in a system will have no
requirement to do any runtime configuration of their power beyond
being able to turn it on or off.
- Many of the power supplies in the system will be shared between many
different consumers.
=> The consumer API should be structured so that these use cases are
very easy to handle and so that consumers will work with shared
supplies without any additional effort.
...@@ -87,7 +87,7 @@ static struct platform_device regulator_devices[] = { ...@@ -87,7 +87,7 @@ static struct platform_device regulator_devices[] = {
}, },
}; };
/* register regulator 1 device */ /* register regulator 1 device */
platform_device_register(&wm8350_regulator_devices[0]); platform_device_register(&regulator_devices[0]);
/* register regulator 2 device */ /* register regulator 2 device */
platform_device_register(&wm8350_regulator_devices[1]); platform_device_register(&regulator_devices[1]);
...@@ -29,7 +29,7 @@ Some terms used in this document:- ...@@ -29,7 +29,7 @@ Some terms used in this document:-
o PMIC - Power Management IC. An IC that contains numerous regulators o PMIC - Power Management IC. An IC that contains numerous regulators
and often contains other susbsystems. and often contains other subsystems.
o Consumer - Electronic device that is supplied power by a regulator. o Consumer - Electronic device that is supplied power by a regulator.
...@@ -168,4 +168,4 @@ relevant to non SoC devices and is split into the following four interfaces:- ...@@ -168,4 +168,4 @@ relevant to non SoC devices and is split into the following four interfaces:-
userspace via sysfs. This could be used to help monitor device power userspace via sysfs. This could be used to help monitor device power
consumption and status. consumption and status.
See Documentation/ABI/testing/regulator-sysfs.txt See Documentation/ABI/testing/sysfs-class-regulator
...@@ -10,8 +10,9 @@ Registration ...@@ -10,8 +10,9 @@ Registration
Drivers can register a regulator by calling :- Drivers can register a regulator by calling :-
struct regulator_dev *regulator_register(struct device *dev, struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,
struct regulator_desc *regulator_desc); struct device *dev, struct regulator_init_data *init_data,
void *driver_data);
This will register the regulators capabilities and operations to the regulator This will register the regulators capabilities and operations to the regulator
core. core.
......
menuconfig REGULATOR menuconfig REGULATOR
bool "Voltage and Current Regulator Support" bool "Voltage and Current Regulator Support"
default n
help help
Generic Voltage and Current Regulator support. Generic Voltage and Current Regulator support.
...@@ -30,7 +29,6 @@ config REGULATOR_DEBUG ...@@ -30,7 +29,6 @@ config REGULATOR_DEBUG
config REGULATOR_FIXED_VOLTAGE config REGULATOR_FIXED_VOLTAGE
tristate "Fixed voltage regulator support" tristate "Fixed voltage regulator support"
default n
help help
This driver provides support for fixed voltage regulators, This driver provides support for fixed voltage regulators,
useful for systems which use a combination of software useful for systems which use a combination of software
...@@ -38,7 +36,6 @@ config REGULATOR_FIXED_VOLTAGE ...@@ -38,7 +36,6 @@ config REGULATOR_FIXED_VOLTAGE
config REGULATOR_VIRTUAL_CONSUMER config REGULATOR_VIRTUAL_CONSUMER
tristate "Virtual regulator consumer support" tristate "Virtual regulator consumer support"
default n
help help
This driver provides a virtual consumer for the voltage and This driver provides a virtual consumer for the voltage and
current regulator API which provides sysfs controls for current regulator API which provides sysfs controls for
...@@ -49,17 +46,15 @@ config REGULATOR_VIRTUAL_CONSUMER ...@@ -49,17 +46,15 @@ config REGULATOR_VIRTUAL_CONSUMER
config REGULATOR_USERSPACE_CONSUMER config REGULATOR_USERSPACE_CONSUMER
tristate "Userspace regulator consumer support" tristate "Userspace regulator consumer support"
default n
help help
There are some classes of devices that are controlled entirely There are some classes of devices that are controlled entirely
from user space. Usersapce consumer driver provides ability to from user space. Userspace consumer driver provides ability to
control power supplies for such devices. control power supplies for such devices.
If unsure, say no. If unsure, say no.
config REGULATOR_BQ24022 config REGULATOR_BQ24022
tristate "TI bq24022 Dual Input 1-Cell Li-Ion Charger IC" tristate "TI bq24022 Dual Input 1-Cell Li-Ion Charger IC"
default n
help help
This driver controls a TI bq24022 Charger attached via This driver controls a TI bq24022 Charger attached via
GPIOs. The provided current regulator can enable/disable GPIOs. The provided current regulator can enable/disable
...@@ -69,7 +64,6 @@ config REGULATOR_BQ24022 ...@@ -69,7 +64,6 @@ config REGULATOR_BQ24022
config REGULATOR_MAX1586 config REGULATOR_MAX1586
tristate "Maxim 1586/1587 voltage regulator" tristate "Maxim 1586/1587 voltage regulator"
depends on I2C depends on I2C
default n
help help
This driver controls a Maxim 1586 or 1587 voltage output This driver controls a Maxim 1586 or 1587 voltage output
regulator via I2C bus. The provided regulator is suitable regulator via I2C bus. The provided regulator is suitable
...@@ -147,5 +141,21 @@ config REGULATOR_AB3100 ...@@ -147,5 +141,21 @@ config REGULATOR_AB3100
AB3100 analog baseband dealing with power regulators AB3100 analog baseband dealing with power regulators
for the system. for the system.
config REGULATOR_TPS65023
tristate "TI TPS65023 Power regulators"
depends on I2C
help
This driver supports TPS65023 voltage regulator chips. TPS65023 provides
three step-down converters and two general-purpose LDO voltage regulators.
It supports TI's software based Class-2 SmartReflex implementation.
config REGULATOR_TPS6507X
tristate "TI TPS6507X Power regulators"
depends on I2C
help
This driver supports TPS6507X voltage regulator chips. TPS6507X provides
three step-down converters and two general-purpose LDO voltage regulators.
It supports TI's software based Class-2 SmartReflex implementation.
endif endif
...@@ -23,4 +23,7 @@ obj-$(CONFIG_REGULATOR_PCAP) += pcap-regulator.o ...@@ -23,4 +23,7 @@ obj-$(CONFIG_REGULATOR_PCAP) += pcap-regulator.o
obj-$(CONFIG_REGULATOR_MC13783) += mc13783.o obj-$(CONFIG_REGULATOR_MC13783) += mc13783.o
obj-$(CONFIG_REGULATOR_AB3100) += ab3100.o obj-$(CONFIG_REGULATOR_AB3100) += ab3100.o
obj-$(CONFIG_REGULATOR_TPS65023) += tps65023-regulator.o
obj-$(CONFIG_REGULATOR_TPS6507X) += tps6507x-regulator.o
ccflags-$(CONFIG_REGULATOR_DEBUG) += -DDEBUG ccflags-$(CONFIG_REGULATOR_DEBUG) += -DDEBUG
This diff is collapsed.
...@@ -64,6 +64,14 @@ ...@@ -64,6 +64,14 @@
#define DA9034_MDTV2 (0x33) #define DA9034_MDTV2 (0x33)
#define DA9034_MVRC (0x34) #define DA9034_MVRC (0x34)
/* DA9035 Registers. DA9034 Registers are comptabile to DA9035. */
#define DA9035_OVER3 (0x12)
#define DA9035_VCC2 (0x1f)
#define DA9035_3DTV1 (0x2c)
#define DA9035_3DTV2 (0x2d)
#define DA9035_3VRC (0x2e)
#define DA9035_AUTOSKIP (0x2f)
struct da903x_regulator_info { struct da903x_regulator_info {
struct regulator_desc desc; struct regulator_desc desc;
...@@ -79,6 +87,10 @@ struct da903x_regulator_info { ...@@ -79,6 +87,10 @@ struct da903x_regulator_info {
int enable_bit; int enable_bit;
}; };
static int da9034_ldo12_data[] = { 1700, 1750, 1800, 1850, 1900, 1950,
2000, 2050, 2700, 2750, 2800, 2850,
2900, 2950, 3000, 3050 };
static inline struct device *to_da903x_dev(struct regulator_dev *rdev) static inline struct device *to_da903x_dev(struct regulator_dev *rdev)
{ {
return rdev_get_dev(rdev)->parent->parent; return rdev_get_dev(rdev)->parent->parent;
...@@ -162,6 +174,17 @@ static int da903x_is_enabled(struct regulator_dev *rdev) ...@@ -162,6 +174,17 @@ static int da903x_is_enabled(struct regulator_dev *rdev)
return !!(reg_val & (1 << info->enable_bit)); return !!(reg_val & (1 << info->enable_bit));
} }
static int da903x_list_voltage(struct regulator_dev *rdev, unsigned selector)
{
struct da903x_regulator_info *info = rdev_get_drvdata(rdev);
int ret;
ret = info->min_uV + info->step_uV * selector;
if (ret > info->max_uV)
return -EINVAL;
return ret;
}
/* DA9030 specific operations */ /* DA9030 specific operations */
static int da9030_set_ldo1_15_voltage(struct regulator_dev *rdev, static int da9030_set_ldo1_15_voltage(struct regulator_dev *rdev,
int min_uV, int max_uV) int min_uV, int max_uV)
...@@ -278,7 +301,7 @@ static int da9034_set_ldo12_voltage(struct regulator_dev *rdev, ...@@ -278,7 +301,7 @@ static int da9034_set_ldo12_voltage(struct regulator_dev *rdev,
} }
val = (min_uV - info->min_uV + info->step_uV - 1) / info->step_uV; val = (min_uV - info->min_uV + info->step_uV - 1) / info->step_uV;
val = (val > 7 || val < 20) ? 8 : val - 12; val = (val >= 20) ? val - 12 : ((val > 7) ? 8 : val);
val <<= info->vol_shift; val <<= info->vol_shift;
mask = ((1 << info->vol_nbits) - 1) << info->vol_shift; mask = ((1 << info->vol_nbits) - 1) << info->vol_shift;
...@@ -305,9 +328,18 @@ static int da9034_get_ldo12_voltage(struct regulator_dev *rdev) ...@@ -305,9 +328,18 @@ static int da9034_get_ldo12_voltage(struct regulator_dev *rdev)
return info->min_uV + info->step_uV * val; return info->min_uV + info->step_uV * val;
} }
static int da9034_list_ldo12_voltage(struct regulator_dev *rdev,
unsigned selector)
{
if (selector > ARRAY_SIZE(da9034_ldo12_data))
return -EINVAL;
return da9034_ldo12_data[selector] * 1000;
}
static struct regulator_ops da903x_regulator_ldo_ops = { static struct regulator_ops da903x_regulator_ldo_ops = {
.set_voltage = da903x_set_ldo_voltage, .set_voltage = da903x_set_ldo_voltage,
.get_voltage = da903x_get_voltage, .get_voltage = da903x_get_voltage,
.list_voltage = da903x_list_voltage,
.enable = da903x_enable, .enable = da903x_enable,
.disable = da903x_disable, .disable = da903x_disable,
.is_enabled = da903x_is_enabled, .is_enabled = da903x_is_enabled,
...@@ -317,6 +349,7 @@ static struct regulator_ops da903x_regulator_ldo_ops = { ...@@ -317,6 +349,7 @@ static struct regulator_ops da903x_regulator_ldo_ops = {
static struct regulator_ops da9030_regulator_ldo14_ops = { static struct regulator_ops da9030_regulator_ldo14_ops = {
.set_voltage = da9030_set_ldo14_voltage, .set_voltage = da9030_set_ldo14_voltage,
.get_voltage = da9030_get_ldo14_voltage, .get_voltage = da9030_get_ldo14_voltage,
.list_voltage = da903x_list_voltage,
.enable = da903x_enable, .enable = da903x_enable,
.disable = da903x_disable, .disable = da903x_disable,
.is_enabled = da903x_is_enabled, .is_enabled = da903x_is_enabled,
...@@ -326,6 +359,7 @@ static struct regulator_ops da9030_regulator_ldo14_ops = { ...@@ -326,6 +359,7 @@ static struct regulator_ops da9030_regulator_ldo14_ops = {
static struct regulator_ops da9030_regulator_ldo1_15_ops = { static struct regulator_ops da9030_regulator_ldo1_15_ops = {
.set_voltage = da9030_set_ldo1_15_voltage, .set_voltage = da9030_set_ldo1_15_voltage,
.get_voltage = da903x_get_voltage, .get_voltage = da903x_get_voltage,
.list_voltage = da903x_list_voltage,
.enable = da903x_enable, .enable = da903x_enable,
.disable = da903x_disable, .disable = da903x_disable,
.is_enabled = da903x_is_enabled, .is_enabled = da903x_is_enabled,
...@@ -334,6 +368,7 @@ static struct regulator_ops da9030_regulator_ldo1_15_ops = { ...@@ -334,6 +368,7 @@ static struct regulator_ops da9030_regulator_ldo1_15_ops = {
static struct regulator_ops da9034_regulator_dvc_ops = { static struct regulator_ops da9034_regulator_dvc_ops = {
.set_voltage = da9034_set_dvc_voltage, .set_voltage = da9034_set_dvc_voltage,
.get_voltage = da903x_get_voltage, .get_voltage = da903x_get_voltage,
.list_voltage = da903x_list_voltage,
.enable = da903x_enable, .enable = da903x_enable,
.disable = da903x_disable, .disable = da903x_disable,
.is_enabled = da903x_is_enabled, .is_enabled = da903x_is_enabled,
...@@ -343,6 +378,7 @@ static struct regulator_ops da9034_regulator_dvc_ops = { ...@@ -343,6 +378,7 @@ static struct regulator_ops da9034_regulator_dvc_ops = {
static struct regulator_ops da9034_regulator_ldo12_ops = { static struct regulator_ops da9034_regulator_ldo12_ops = {
.set_voltage = da9034_set_ldo12_voltage, .set_voltage = da9034_set_ldo12_voltage,
.get_voltage = da9034_get_ldo12_voltage, .get_voltage = da9034_get_ldo12_voltage,
.list_voltage = da9034_list_ldo12_voltage,
.enable = da903x_enable, .enable = da903x_enable,
.disable = da903x_disable, .disable = da903x_disable,
.is_enabled = da903x_is_enabled, .is_enabled = da903x_is_enabled,
...@@ -355,6 +391,7 @@ static struct regulator_ops da9034_regulator_ldo12_ops = { ...@@ -355,6 +391,7 @@ static struct regulator_ops da9034_regulator_ldo12_ops = {
.ops = &da903x_regulator_ldo_ops, \ .ops = &da903x_regulator_ldo_ops, \
.type = REGULATOR_VOLTAGE, \ .type = REGULATOR_VOLTAGE, \
.id = _pmic##_ID_LDO##_id, \ .id = _pmic##_ID_LDO##_id, \
.n_voltages = (step) ? ((max - min) / step + 1) : 1, \
.owner = THIS_MODULE, \ .owner = THIS_MODULE, \
}, \ }, \
.min_uV = (min) * 1000, \ .min_uV = (min) * 1000, \
...@@ -367,24 +404,25 @@ static struct regulator_ops da9034_regulator_ldo12_ops = { ...@@ -367,24 +404,25 @@ static struct regulator_ops da9034_regulator_ldo12_ops = {
.enable_bit = (ebit), \ .enable_bit = (ebit), \
} }
#define DA9034_DVC(_id, min, max, step, vreg, nbits, ureg, ubit, ereg, ebit) \ #define DA903x_DVC(_pmic, _id, min, max, step, vreg, nbits, ureg, ubit, ereg, ebit) \
{ \ { \
.desc = { \ .desc = { \
.name = #_id, \ .name = #_id, \
.ops = &da9034_regulator_dvc_ops, \ .ops = &da9034_regulator_dvc_ops, \
.type = REGULATOR_VOLTAGE, \ .type = REGULATOR_VOLTAGE, \
.id = DA9034_ID_##_id, \ .id = _pmic##_ID_##_id, \
.n_voltages = (step) ? ((max - min) / step + 1) : 1, \
.owner = THIS_MODULE, \ .owner = THIS_MODULE, \
}, \ }, \
.min_uV = (min) * 1000, \ .min_uV = (min) * 1000, \
.max_uV = (max) * 1000, \ .max_uV = (max) * 1000, \
.step_uV = (step) * 1000, \ .step_uV = (step) * 1000, \
.vol_reg = DA9034_##vreg, \ .vol_reg = _pmic##_##vreg, \
.vol_shift = (0), \ .vol_shift = (0), \
.vol_nbits = (nbits), \ .vol_nbits = (nbits), \
.update_reg = DA9034_##ureg, \ .update_reg = _pmic##_##ureg, \
.update_bit = (ubit), \ .update_bit = (ubit), \
.enable_reg = DA9034_##ereg, \ .enable_reg = _pmic##_##ereg, \
.enable_bit = (ebit), \ .enable_bit = (ebit), \
} }
...@@ -394,8 +432,22 @@ static struct regulator_ops da9034_regulator_ldo12_ops = { ...@@ -394,8 +432,22 @@ static struct regulator_ops da9034_regulator_ldo12_ops = {
#define DA9030_LDO(_id, min, max, step, vreg, shift, nbits, ereg, ebit) \ #define DA9030_LDO(_id, min, max, step, vreg, shift, nbits, ereg, ebit) \
DA903x_LDO(DA9030, _id, min, max, step, vreg, shift, nbits, ereg, ebit) DA903x_LDO(DA9030, _id, min, max, step, vreg, shift, nbits, ereg, ebit)
#define DA9030_DVC(_id, min, max, step, vreg, nbits, ureg, ubit, ereg, ebit) \
DA903x_DVC(DA9030, _id, min, max, step, vreg, nbits, ureg, ubit, \
ereg, ebit)
#define DA9034_DVC(_id, min, max, step, vreg, nbits, ureg, ubit, ereg, ebit) \
DA903x_DVC(DA9034, _id, min, max, step, vreg, nbits, ureg, ubit, \
ereg, ebit)
#define DA9035_DVC(_id, min, max, step, vreg, nbits, ureg, ubit, ereg, ebit) \
DA903x_DVC(DA9035, _id, min, max, step, vreg, nbits, ureg, ubit, \
ereg, ebit)
static struct da903x_regulator_info da903x_regulator_info[] = { static struct da903x_regulator_info da903x_regulator_info[] = {
/* DA9030 */ /* DA9030 */
DA9030_DVC(BUCK2, 850, 1625, 25, BUCK2DVM1, 5, BUCK2DVM1, 7, RCTL11, 0),
DA9030_LDO( 1, 1200, 3200, 100, LDO1, 0, 5, RCTL12, 1), DA9030_LDO( 1, 1200, 3200, 100, LDO1, 0, 5, RCTL12, 1),
DA9030_LDO( 2, 1800, 3200, 100, LDO23, 0, 4, RCTL12, 2), DA9030_LDO( 2, 1800, 3200, 100, LDO23, 0, 4, RCTL12, 2),
DA9030_LDO( 3, 1800, 3200, 100, LDO23, 4, 4, RCTL12, 3), DA9030_LDO( 3, 1800, 3200, 100, LDO23, 4, 4, RCTL12, 3),
...@@ -417,9 +469,9 @@ static struct da903x_regulator_info da903x_regulator_info[] = { ...@@ -417,9 +469,9 @@ static struct da903x_regulator_info da903x_regulator_info[] = {
DA9030_LDO(13, 2100, 2100, 0, INVAL, 0, 0, RCTL11, 3), /* fixed @2.1V */ DA9030_LDO(13, 2100, 2100, 0, INVAL, 0, 0, RCTL11, 3), /* fixed @2.1V */
/* DA9034 */ /* DA9034 */
DA9034_DVC(BUCK1, 725, 1500, 25, ADTV1, 5, VCC1, 0, OVER1, 0), DA9034_DVC(BUCK1, 725, 1500, 25, ADTV2, 5, VCC1, 0, OVER1, 0),
DA9034_DVC(BUCK2, 725, 1500, 25, CDTV1, 5, VCC1, 2, OVER1, 1), DA9034_DVC(BUCK2, 725, 1500, 25, CDTV2, 5, VCC1, 2, OVER1, 1),
DA9034_DVC(LDO2, 725, 1500, 25, SDTV1, 5, VCC1, 4, OVER1, 2), DA9034_DVC(LDO2, 725, 1500, 25, SDTV2, 5, VCC1, 4, OVER1, 2),
DA9034_DVC(LDO1, 1700, 2075, 25, MDTV1, 4, VCC1, 6, OVER3, 4), DA9034_DVC(LDO1, 1700, 2075, 25, MDTV1, 4, VCC1, 6, OVER3, 4),
DA9034_LDO( 3, 1800, 3300, 100, LDO643, 0, 4, OVER3, 5), DA9034_LDO( 3, 1800, 3300, 100, LDO643, 0, 4, OVER3, 5),
...@@ -435,6 +487,9 @@ static struct da903x_regulator_info da903x_regulator_info[] = { ...@@ -435,6 +487,9 @@ static struct da903x_regulator_info da903x_regulator_info[] = {
DA9034_LDO(14, 1800, 3300, 100, LDO1514, 0, 4, OVER3, 0), DA9034_LDO(14, 1800, 3300, 100, LDO1514, 0, 4, OVER3, 0),
DA9034_LDO(15, 1800, 3300, 100, LDO1514, 4, 4, OVER3, 1), DA9034_LDO(15, 1800, 3300, 100, LDO1514, 4, 4, OVER3, 1),
DA9034_LDO(5, 3100, 3100, 0, INVAL, 0, 0, OVER3, 7), /* fixed @3.1V */ DA9034_LDO(5, 3100, 3100, 0, INVAL, 0, 0, OVER3, 7), /* fixed @3.1V */
/* DA9035 */
DA9035_DVC(BUCK3, 1800, 2200, 100, 3DTV1, 3, VCC2, 0, OVER3, 3),
}; };
static inline struct da903x_regulator_info *find_regulator_info(int id) static inline struct da903x_regulator_info *find_regulator_info(int id)
...@@ -462,8 +517,10 @@ static int __devinit da903x_regulator_probe(struct platform_device *pdev) ...@@ -462,8 +517,10 @@ static int __devinit da903x_regulator_probe(struct platform_device *pdev)
} }
/* Workaround for the weird LDO12 voltage setting */ /* Workaround for the weird LDO12 voltage setting */
if (ri->desc.id == DA9034_ID_LDO12) if (ri->desc.id == DA9034_ID_LDO12) {
ri->desc.ops = &da9034_regulator_ldo12_ops; ri->desc.ops = &da9034_regulator_ldo12_ops;
ri->desc.n_voltages = ARRAY_SIZE(da9034_ldo12_data);
}
if (ri->desc.id == DA9030_ID_LDO14) if (ri->desc.id == DA9030_ID_LDO14)
ri->desc.ops = &da9030_regulator_ldo14_ops; ri->desc.ops = &da9030_regulator_ldo14_ops;
......
...@@ -5,6 +5,9 @@ ...@@ -5,6 +5,9 @@
* *
* Author: Mark Brown <broonie@opensource.wolfsonmicro.com> * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
* *
* Copyright (c) 2009 Nokia Corporation
* Roger Quadros <ext-roger.quadros@nokia.com>
*
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the * published by the Free Software Foundation; either version 2 of the
...@@ -20,20 +23,45 @@ ...@@ -20,20 +23,45 @@
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/regulator/driver.h> #include <linux/regulator/driver.h>
#include <linux/regulator/fixed.h> #include <linux/regulator/fixed.h>
#include <linux/gpio.h>
struct fixed_voltage_data { struct fixed_voltage_data {
struct regulator_desc desc; struct regulator_desc desc;
struct regulator_dev *dev; struct regulator_dev *dev;
int microvolts; int microvolts;
int gpio;
unsigned enable_high:1;
unsigned is_enabled:1;
}; };
static int fixed_voltage_is_enabled(struct regulator_dev *dev) static int fixed_voltage_is_enabled(struct regulator_dev *dev)
{ {
return 1; struct fixed_voltage_data *data = rdev_get_drvdata(dev);
return data->is_enabled;
} }
static int fixed_voltage_enable(struct regulator_dev *dev) static int fixed_voltage_enable(struct regulator_dev *dev)
{ {
struct fixed_voltage_data *data = rdev_get_drvdata(dev);
if (gpio_is_valid(data->gpio)) {
gpio_set_value_cansleep(data->gpio, data->enable_high);
data->is_enabled = 1;
}
return 0;
}
static int fixed_voltage_disable(struct regulator_dev *dev)
{
struct fixed_voltage_data *data = rdev_get_drvdata(dev);
if (gpio_is_valid(data->gpio)) {
gpio_set_value_cansleep(data->gpio, !data->enable_high);
data->is_enabled = 0;
}
return 0; return 0;
} }
...@@ -58,6 +86,7 @@ static int fixed_voltage_list_voltage(struct regulator_dev *dev, ...@@ -58,6 +86,7 @@ static int fixed_voltage_list_voltage(struct regulator_dev *dev,
static struct regulator_ops fixed_voltage_ops = { static struct regulator_ops fixed_voltage_ops = {
.is_enabled = fixed_voltage_is_enabled, .is_enabled = fixed_voltage_is_enabled,
.enable = fixed_voltage_enable, .enable = fixed_voltage_enable,
.disable = fixed_voltage_disable,
.get_voltage = fixed_voltage_get_voltage, .get_voltage = fixed_voltage_get_voltage,
.list_voltage = fixed_voltage_list_voltage, .list_voltage = fixed_voltage_list_voltage,
}; };
...@@ -70,12 +99,14 @@ static int regulator_fixed_voltage_probe(struct platform_device *pdev) ...@@ -70,12 +99,14 @@ static int regulator_fixed_voltage_probe(struct platform_device *pdev)
drvdata = kzalloc(sizeof(struct fixed_voltage_data), GFP_KERNEL); drvdata = kzalloc(sizeof(struct fixed_voltage_data), GFP_KERNEL);
if (drvdata == NULL) { if (drvdata == NULL) {
dev_err(&pdev->dev, "Failed to allocate device data\n");
ret = -ENOMEM; ret = -ENOMEM;
goto err; goto err;
} }
drvdata->desc.name = kstrdup(config->supply_name, GFP_KERNEL); drvdata->desc.name = kstrdup(config->supply_name, GFP_KERNEL);
if (drvdata->desc.name == NULL) { if (drvdata->desc.name == NULL) {
dev_err(&pdev->dev, "Failed to allocate supply name\n");
ret = -ENOMEM; ret = -ENOMEM;
goto err; goto err;
} }
...@@ -85,12 +116,62 @@ static int regulator_fixed_voltage_probe(struct platform_device *pdev) ...@@ -85,12 +116,62 @@ static int regulator_fixed_voltage_probe(struct platform_device *pdev)
drvdata->desc.n_voltages = 1; drvdata->desc.n_voltages = 1;
drvdata->microvolts = config->microvolts; drvdata->microvolts = config->microvolts;
drvdata->gpio = config->gpio;
if (gpio_is_valid(config->gpio)) {
drvdata->enable_high = config->enable_high;
/* FIXME: Remove below print warning
*
* config->gpio must be set to -EINVAL by platform code if
* GPIO control is not required. However, early adopters
* not requiring GPIO control may forget to initialize
* config->gpio to -EINVAL. This will cause GPIO 0 to be used
* for GPIO control.
*
* This warning will be removed once there are a couple of users
* for this driver.
*/
if (!config->gpio)
dev_warn(&pdev->dev,
"using GPIO 0 for regulator enable control\n");
ret = gpio_request(config->gpio, config->supply_name);
if (ret) {
dev_err(&pdev->dev,
"Could not obtain regulator enable GPIO %d: %d\n",
config->gpio, ret);
goto err_name;
}
/* set output direction without changing state
* to prevent glitch
*/
drvdata->is_enabled = config->enabled_at_boot;
ret = drvdata->is_enabled ?
config->enable_high : !config->enable_high;
ret = gpio_direction_output(config->gpio, ret);
if (ret) {
dev_err(&pdev->dev,
"Could not configure regulator enable GPIO %d direction: %d\n",
config->gpio, ret);
goto err_gpio;
}
} else {
/* Regulator without GPIO control is considered
* always enabled
*/
drvdata->is_enabled = 1;
}
drvdata->dev = regulator_register(&drvdata->desc, &pdev->dev, drvdata->dev = regulator_register(&drvdata->desc, &pdev->dev,
config->init_data, drvdata); 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; dev_err(&pdev->dev, "Failed to register regulator: %d\n", ret);
goto err_gpio;
} }
platform_set_drvdata(pdev, drvdata); platform_set_drvdata(pdev, drvdata);
...@@ -100,6 +181,9 @@ static int regulator_fixed_voltage_probe(struct platform_device *pdev) ...@@ -100,6 +181,9 @@ static int regulator_fixed_voltage_probe(struct platform_device *pdev)
return 0; return 0;
err_gpio:
if (gpio_is_valid(config->gpio))
gpio_free(config->gpio);
err_name: err_name:
kfree(drvdata->desc.name); kfree(drvdata->desc.name);
err: err:
...@@ -115,6 +199,9 @@ static int regulator_fixed_voltage_remove(struct platform_device *pdev) ...@@ -115,6 +199,9 @@ static int regulator_fixed_voltage_remove(struct platform_device *pdev)
kfree(drvdata->desc.name); kfree(drvdata->desc.name);
kfree(drvdata); kfree(drvdata);
if (gpio_is_valid(drvdata->gpio))
gpio_free(drvdata->gpio);
return 0; return 0;
} }
......
...@@ -541,7 +541,7 @@ static struct i2c_driver lp3971_i2c_driver = { ...@@ -541,7 +541,7 @@ static struct i2c_driver lp3971_i2c_driver = {
static int __init lp3971_module_init(void) static int __init lp3971_module_init(void)
{ {
int ret = -ENODEV; int ret;
ret = i2c_add_driver(&lp3971_i2c_driver); ret = i2c_add_driver(&lp3971_i2c_driver);
if (ret != 0) if (ret != 0)
......
...@@ -24,11 +24,12 @@ ...@@ -24,11 +24,12 @@
#include <linux/mfd/pcf50633/core.h> #include <linux/mfd/pcf50633/core.h>
#include <linux/mfd/pcf50633/pmic.h> #include <linux/mfd/pcf50633/pmic.h>
#define PCF50633_REGULATOR(_name, _id) \ #define PCF50633_REGULATOR(_name, _id, _n) \
{ \ { \
.name = _name, \ .name = _name, \
.id = _id, \ .id = _id, \
.ops = &pcf50633_regulator_ops, \ .ops = &pcf50633_regulator_ops, \
.n_voltages = _n, \
.type = REGULATOR_VOLTAGE, \ .type = REGULATOR_VOLTAGE, \
.owner = THIS_MODULE, \ .owner = THIS_MODULE, \
} }
...@@ -149,33 +150,20 @@ static int pcf50633_regulator_set_voltage(struct regulator_dev *rdev, ...@@ -149,33 +150,20 @@ static int pcf50633_regulator_set_voltage(struct regulator_dev *rdev,
return pcf50633_reg_write(pcf, regnr, volt_bits); return pcf50633_reg_write(pcf, regnr, volt_bits);
} }
static int pcf50633_regulator_get_voltage(struct regulator_dev *rdev) static int pcf50633_regulator_voltage_value(enum pcf50633_regulator_id id,
u8 bits)
{ {
struct pcf50633 *pcf; int millivolts;
int regulator_id, millivolts, volt_bits;
u8 regnr;
pcf = rdev_get_drvdata(rdev);;
regulator_id = rdev_get_id(rdev); switch (id) {
if (regulator_id >= PCF50633_NUM_REGULATORS)
return -EINVAL;
regnr = pcf50633_regulator_registers[regulator_id];
volt_bits = pcf50633_reg_read(pcf, regnr);
if (volt_bits < 0)
return -1;
switch (regulator_id) {
case PCF50633_REGULATOR_AUTO: case PCF50633_REGULATOR_AUTO:
millivolts = auto_voltage_value(volt_bits); millivolts = auto_voltage_value(bits);
break; break;
case PCF50633_REGULATOR_DOWN1: case PCF50633_REGULATOR_DOWN1:
millivolts = down_voltage_value(volt_bits); millivolts = down_voltage_value(bits);
break; break;
case PCF50633_REGULATOR_DOWN2: case PCF50633_REGULATOR_DOWN2:
millivolts = down_voltage_value(volt_bits); millivolts = down_voltage_value(bits);
break; break;
case PCF50633_REGULATOR_LDO1: case PCF50633_REGULATOR_LDO1:
case PCF50633_REGULATOR_LDO2: case PCF50633_REGULATOR_LDO2:
...@@ -184,7 +172,7 @@ static int pcf50633_regulator_get_voltage(struct regulator_dev *rdev) ...@@ -184,7 +172,7 @@ static int pcf50633_regulator_get_voltage(struct regulator_dev *rdev)
case PCF50633_REGULATOR_LDO5: case PCF50633_REGULATOR_LDO5:
case PCF50633_REGULATOR_LDO6: case PCF50633_REGULATOR_LDO6:
case PCF50633_REGULATOR_HCLDO: case PCF50633_REGULATOR_HCLDO:
millivolts = ldo_voltage_value(volt_bits); millivolts = ldo_voltage_value(bits);
break; break;
default: default:
return -EINVAL; return -EINVAL;
...@@ -193,6 +181,49 @@ static int pcf50633_regulator_get_voltage(struct regulator_dev *rdev) ...@@ -193,6 +181,49 @@ static int pcf50633_regulator_get_voltage(struct regulator_dev *rdev)
return millivolts * 1000; return millivolts * 1000;
} }
static int pcf50633_regulator_get_voltage(struct regulator_dev *rdev)
{
struct pcf50633 *pcf;
int regulator_id;
u8 volt_bits, regnr;
pcf = rdev_get_drvdata(rdev);
regulator_id = rdev_get_id(rdev);
if (regulator_id >= PCF50633_NUM_REGULATORS)
return -EINVAL;
regnr = pcf50633_regulator_registers[regulator_id];
volt_bits = pcf50633_reg_read(pcf, regnr);
return pcf50633_regulator_voltage_value(regulator_id, volt_bits);
}
static int pcf50633_regulator_list_voltage(struct regulator_dev *rdev,
unsigned int index)
{
struct pcf50633 *pcf;
int regulator_id;
pcf = rdev_get_drvdata(rdev);
regulator_id = rdev_get_id(rdev);
switch (regulator_id) {
case PCF50633_REGULATOR_AUTO:
index += 0x2f;
break;
case PCF50633_REGULATOR_HCLDO:
index += 0x01;
break;
default:
break;
}
return pcf50633_regulator_voltage_value(regulator_id, index);
}
static int pcf50633_regulator_enable(struct regulator_dev *rdev) static int pcf50633_regulator_enable(struct regulator_dev *rdev)
{ {
struct pcf50633 *pcf = rdev_get_drvdata(rdev); struct pcf50633 *pcf = rdev_get_drvdata(rdev);
...@@ -246,6 +277,7 @@ static int pcf50633_regulator_is_enabled(struct regulator_dev *rdev) ...@@ -246,6 +277,7 @@ static int pcf50633_regulator_is_enabled(struct regulator_dev *rdev)
static struct regulator_ops pcf50633_regulator_ops = { static struct regulator_ops pcf50633_regulator_ops = {
.set_voltage = pcf50633_regulator_set_voltage, .set_voltage = pcf50633_regulator_set_voltage,
.get_voltage = pcf50633_regulator_get_voltage, .get_voltage = pcf50633_regulator_get_voltage,
.list_voltage = pcf50633_regulator_list_voltage,
.enable = pcf50633_regulator_enable, .enable = pcf50633_regulator_enable,
.disable = pcf50633_regulator_disable, .disable = pcf50633_regulator_disable,
.is_enabled = pcf50633_regulator_is_enabled, .is_enabled = pcf50633_regulator_is_enabled,
...@@ -253,27 +285,27 @@ static struct regulator_ops pcf50633_regulator_ops = { ...@@ -253,27 +285,27 @@ static struct regulator_ops pcf50633_regulator_ops = {
static struct regulator_desc regulators[] = { static struct regulator_desc regulators[] = {
[PCF50633_REGULATOR_AUTO] = [PCF50633_REGULATOR_AUTO] =
PCF50633_REGULATOR("auto", PCF50633_REGULATOR_AUTO), PCF50633_REGULATOR("auto", PCF50633_REGULATOR_AUTO, 80),
[PCF50633_REGULATOR_DOWN1] = [PCF50633_REGULATOR_DOWN1] =
PCF50633_REGULATOR("down1", PCF50633_REGULATOR_DOWN1), PCF50633_REGULATOR("down1", PCF50633_REGULATOR_DOWN1, 95),
[PCF50633_REGULATOR_DOWN2] = [PCF50633_REGULATOR_DOWN2] =
PCF50633_REGULATOR("down2", PCF50633_REGULATOR_DOWN2), PCF50633_REGULATOR("down2", PCF50633_REGULATOR_DOWN2, 95),
[PCF50633_REGULATOR_LDO1] = [PCF50633_REGULATOR_LDO1] =
PCF50633_REGULATOR("ldo1", PCF50633_REGULATOR_LDO1), PCF50633_REGULATOR("ldo1", PCF50633_REGULATOR_LDO1, 27),
[PCF50633_REGULATOR_LDO2] = [PCF50633_REGULATOR_LDO2] =
PCF50633_REGULATOR("ldo2", PCF50633_REGULATOR_LDO2), PCF50633_REGULATOR("ldo2", PCF50633_REGULATOR_LDO2, 27),
[PCF50633_REGULATOR_LDO3] = [PCF50633_REGULATOR_LDO3] =
PCF50633_REGULATOR("ldo3", PCF50633_REGULATOR_LDO3), PCF50633_REGULATOR("ldo3", PCF50633_REGULATOR_LDO3, 27),
[PCF50633_REGULATOR_LDO4] = [PCF50633_REGULATOR_LDO4] =
PCF50633_REGULATOR("ldo4", PCF50633_REGULATOR_LDO4), PCF50633_REGULATOR("ldo4", PCF50633_REGULATOR_LDO4, 27),
[PCF50633_REGULATOR_LDO5] = [PCF50633_REGULATOR_LDO5] =
PCF50633_REGULATOR("ldo5", PCF50633_REGULATOR_LDO5), PCF50633_REGULATOR("ldo5", PCF50633_REGULATOR_LDO5, 27),
[PCF50633_REGULATOR_LDO6] = [PCF50633_REGULATOR_LDO6] =
PCF50633_REGULATOR("ldo6", PCF50633_REGULATOR_LDO6), PCF50633_REGULATOR("ldo6", PCF50633_REGULATOR_LDO6, 27),
[PCF50633_REGULATOR_HCLDO] = [PCF50633_REGULATOR_HCLDO] =
PCF50633_REGULATOR("hcldo", PCF50633_REGULATOR_HCLDO), PCF50633_REGULATOR("hcldo", PCF50633_REGULATOR_HCLDO, 26),
[PCF50633_REGULATOR_MEMLDO] = [PCF50633_REGULATOR_MEMLDO] =
PCF50633_REGULATOR("memldo", PCF50633_REGULATOR_MEMLDO), PCF50633_REGULATOR("memldo", PCF50633_REGULATOR_MEMLDO, 0),
}; };
static int __devinit pcf50633_regulator_probe(struct platform_device *pdev) static int __devinit pcf50633_regulator_probe(struct platform_device *pdev)
......
This diff is collapsed.
This diff is collapsed.
...@@ -93,16 +93,21 @@ static ssize_t reg_set_state(struct device *dev, struct device_attribute *attr, ...@@ -93,16 +93,21 @@ static ssize_t reg_set_state(struct device *dev, struct device_attribute *attr,
static DEVICE_ATTR(name, 0444, reg_show_name, NULL); static DEVICE_ATTR(name, 0444, reg_show_name, NULL);
static DEVICE_ATTR(state, 0644, reg_show_state, reg_set_state); static DEVICE_ATTR(state, 0644, reg_show_state, reg_set_state);
static struct device_attribute *attributes[] = { static struct attribute *attributes[] = {
&dev_attr_name, &dev_attr_name.attr,
&dev_attr_state, &dev_attr_state.attr,
NULL,
};
static const struct attribute_group attr_group = {
.attrs = attributes,
}; };
static int regulator_userspace_consumer_probe(struct platform_device *pdev) static int regulator_userspace_consumer_probe(struct platform_device *pdev)
{ {
struct regulator_userspace_consumer_data *pdata; struct regulator_userspace_consumer_data *pdata;
struct userspace_consumer_data *drvdata; struct userspace_consumer_data *drvdata;
int ret, i; int ret;
pdata = pdev->dev.platform_data; pdata = pdev->dev.platform_data;
if (!pdata) if (!pdata)
...@@ -125,31 +130,29 @@ static int regulator_userspace_consumer_probe(struct platform_device *pdev) ...@@ -125,31 +130,29 @@ static int regulator_userspace_consumer_probe(struct platform_device *pdev)
goto err_alloc_supplies; goto err_alloc_supplies;
} }
for (i = 0; i < ARRAY_SIZE(attributes); i++) { ret = sysfs_create_group(&pdev->dev.kobj, &attr_group);
ret = device_create_file(&pdev->dev, attributes[i]); if (ret != 0)
if (ret != 0) goto err_create_attrs;
goto err_create_attrs;
}
if (pdata->init_on) if (pdata->init_on) {
ret = regulator_bulk_enable(drvdata->num_supplies, ret = regulator_bulk_enable(drvdata->num_supplies,
drvdata->supplies); drvdata->supplies);
if (ret) {
drvdata->enabled = pdata->init_on; dev_err(&pdev->dev,
"Failed to set initial state: %d\n", ret);
if (ret) { goto err_enable;
dev_err(&pdev->dev, "Failed to set initial state: %d\n", ret); }
goto err_create_attrs;
} }
drvdata->enabled = pdata->init_on;
platform_set_drvdata(pdev, drvdata); platform_set_drvdata(pdev, drvdata);
return 0; return 0;
err_create_attrs: err_enable:
for (i = 0; i < ARRAY_SIZE(attributes); i++) sysfs_remove_group(&pdev->dev.kobj, &attr_group);
device_remove_file(&pdev->dev, attributes[i]);
err_create_attrs:
regulator_bulk_free(drvdata->num_supplies, drvdata->supplies); regulator_bulk_free(drvdata->num_supplies, drvdata->supplies);
err_alloc_supplies: err_alloc_supplies:
...@@ -160,10 +163,8 @@ static int regulator_userspace_consumer_probe(struct platform_device *pdev) ...@@ -160,10 +163,8 @@ static int regulator_userspace_consumer_probe(struct platform_device *pdev)
static int regulator_userspace_consumer_remove(struct platform_device *pdev) static int regulator_userspace_consumer_remove(struct platform_device *pdev)
{ {
struct userspace_consumer_data *data = platform_get_drvdata(pdev); struct userspace_consumer_data *data = platform_get_drvdata(pdev);
int i;
for (i = 0; i < ARRAY_SIZE(attributes); i++) sysfs_remove_group(&pdev->dev.kobj, &attr_group);
device_remove_file(&pdev->dev, attributes[i]);
if (data->enabled) if (data->enabled)
regulator_bulk_disable(data->num_supplies, data->supplies); regulator_bulk_disable(data->num_supplies, data->supplies);
......
...@@ -27,71 +27,81 @@ struct virtual_consumer_data { ...@@ -27,71 +27,81 @@ struct virtual_consumer_data {
unsigned int mode; unsigned int mode;
}; };
static void update_voltage_constraints(struct virtual_consumer_data *data) static void update_voltage_constraints(struct device *dev,
struct virtual_consumer_data *data)
{ {
int ret; int ret;
if (data->min_uV && data->max_uV if (data->min_uV && data->max_uV
&& data->min_uV <= data->max_uV) { && data->min_uV <= data->max_uV) {
dev_dbg(dev, "Requesting %d-%duV\n",
data->min_uV, data->max_uV);
ret = regulator_set_voltage(data->regulator, ret = regulator_set_voltage(data->regulator,
data->min_uV, data->max_uV); data->min_uV, data->max_uV);
if (ret != 0) { if (ret != 0) {
printk(KERN_ERR "regulator_set_voltage() failed: %d\n", dev_err(dev,
ret); "regulator_set_voltage() failed: %d\n", ret);
return; return;
} }
} }
if (data->min_uV && data->max_uV && !data->enabled) { if (data->min_uV && data->max_uV && !data->enabled) {
dev_dbg(dev, "Enabling regulator\n");
ret = regulator_enable(data->regulator); ret = regulator_enable(data->regulator);
if (ret == 0) if (ret == 0)
data->enabled = 1; data->enabled = 1;
else else
printk(KERN_ERR "regulator_enable() failed: %d\n", dev_err(dev, "regulator_enable() failed: %d\n",
ret); ret);
} }
if (!(data->min_uV && data->max_uV) && data->enabled) { if (!(data->min_uV && data->max_uV) && data->enabled) {
dev_dbg(dev, "Disabling regulator\n");
ret = regulator_disable(data->regulator); ret = regulator_disable(data->regulator);
if (ret == 0) if (ret == 0)
data->enabled = 0; data->enabled = 0;
else else
printk(KERN_ERR "regulator_disable() failed: %d\n", dev_err(dev, "regulator_disable() failed: %d\n",
ret); ret);
} }
} }
static void update_current_limit_constraints(struct virtual_consumer_data static void update_current_limit_constraints(struct device *dev,
*data) struct virtual_consumer_data *data)
{ {
int ret; int ret;
if (data->max_uA if (data->max_uA
&& data->min_uA <= data->max_uA) { && data->min_uA <= data->max_uA) {
dev_dbg(dev, "Requesting %d-%duA\n",
data->min_uA, data->max_uA);
ret = regulator_set_current_limit(data->regulator, ret = regulator_set_current_limit(data->regulator,
data->min_uA, data->max_uA); data->min_uA, data->max_uA);
if (ret != 0) { if (ret != 0) {
pr_err("regulator_set_current_limit() failed: %d\n", dev_err(dev,
ret); "regulator_set_current_limit() failed: %d\n",
ret);
return; return;
} }
} }
if (data->max_uA && !data->enabled) { if (data->max_uA && !data->enabled) {
dev_dbg(dev, "Enabling regulator\n");
ret = regulator_enable(data->regulator); ret = regulator_enable(data->regulator);
if (ret == 0) if (ret == 0)
data->enabled = 1; data->enabled = 1;
else else
printk(KERN_ERR "regulator_enable() failed: %d\n", dev_err(dev, "regulator_enable() failed: %d\n",
ret); ret);
} }
if (!(data->min_uA && data->max_uA) && data->enabled) { if (!(data->min_uA && data->max_uA) && data->enabled) {
dev_dbg(dev, "Disabling regulator\n");
ret = regulator_disable(data->regulator); ret = regulator_disable(data->regulator);
if (ret == 0) if (ret == 0)
data->enabled = 0; data->enabled = 0;
else else
printk(KERN_ERR "regulator_disable() failed: %d\n", dev_err(dev, "regulator_disable() failed: %d\n",
ret); ret);
} }
} }
...@@ -115,7 +125,7 @@ static ssize_t set_min_uV(struct device *dev, struct device_attribute *attr, ...@@ -115,7 +125,7 @@ static ssize_t set_min_uV(struct device *dev, struct device_attribute *attr,
mutex_lock(&data->lock); mutex_lock(&data->lock);
data->min_uV = val; data->min_uV = val;
update_voltage_constraints(data); update_voltage_constraints(dev, data);
mutex_unlock(&data->lock); mutex_unlock(&data->lock);
...@@ -141,7 +151,7 @@ static ssize_t set_max_uV(struct device *dev, struct device_attribute *attr, ...@@ -141,7 +151,7 @@ static ssize_t set_max_uV(struct device *dev, struct device_attribute *attr,
mutex_lock(&data->lock); mutex_lock(&data->lock);
data->max_uV = val; data->max_uV = val;
update_voltage_constraints(data); update_voltage_constraints(dev, data);
mutex_unlock(&data->lock); mutex_unlock(&data->lock);
...@@ -167,7 +177,7 @@ static ssize_t set_min_uA(struct device *dev, struct device_attribute *attr, ...@@ -167,7 +177,7 @@ static ssize_t set_min_uA(struct device *dev, struct device_attribute *attr,
mutex_lock(&data->lock); mutex_lock(&data->lock);
data->min_uA = val; data->min_uA = val;
update_current_limit_constraints(data); update_current_limit_constraints(dev, data);
mutex_unlock(&data->lock); mutex_unlock(&data->lock);
...@@ -193,7 +203,7 @@ static ssize_t set_max_uA(struct device *dev, struct device_attribute *attr, ...@@ -193,7 +203,7 @@ static ssize_t set_max_uA(struct device *dev, struct device_attribute *attr,
mutex_lock(&data->lock); mutex_lock(&data->lock);
data->max_uA = val; data->max_uA = val;
update_current_limit_constraints(data); update_current_limit_constraints(dev, data);
mutex_unlock(&data->lock); mutex_unlock(&data->lock);
...@@ -276,8 +286,7 @@ static int regulator_virtual_consumer_probe(struct platform_device *pdev) ...@@ -276,8 +286,7 @@ static int regulator_virtual_consumer_probe(struct platform_device *pdev)
drvdata = kzalloc(sizeof(struct virtual_consumer_data), GFP_KERNEL); drvdata = kzalloc(sizeof(struct virtual_consumer_data), GFP_KERNEL);
if (drvdata == NULL) { if (drvdata == NULL) {
ret = -ENOMEM; return -ENOMEM;
goto err;
} }
mutex_init(&drvdata->lock); mutex_init(&drvdata->lock);
...@@ -285,13 +294,18 @@ static int regulator_virtual_consumer_probe(struct platform_device *pdev) ...@@ -285,13 +294,18 @@ static int regulator_virtual_consumer_probe(struct platform_device *pdev)
drvdata->regulator = regulator_get(&pdev->dev, reg_id); drvdata->regulator = regulator_get(&pdev->dev, reg_id);
if (IS_ERR(drvdata->regulator)) { if (IS_ERR(drvdata->regulator)) {
ret = PTR_ERR(drvdata->regulator); ret = PTR_ERR(drvdata->regulator);
dev_err(&pdev->dev, "Failed to obtain supply '%s': %d\n",
reg_id, ret);
goto err; goto err;
} }
for (i = 0; i < ARRAY_SIZE(attributes); i++) { for (i = 0; i < ARRAY_SIZE(attributes); i++) {
ret = device_create_file(&pdev->dev, attributes[i]); ret = device_create_file(&pdev->dev, attributes[i]);
if (ret != 0) if (ret != 0) {
goto err; dev_err(&pdev->dev, "Failed to create attr %d: %d\n",
i, ret);
goto err_regulator;
}
} }
drvdata->mode = regulator_get_mode(drvdata->regulator); drvdata->mode = regulator_get_mode(drvdata->regulator);
...@@ -300,6 +314,8 @@ static int regulator_virtual_consumer_probe(struct platform_device *pdev) ...@@ -300,6 +314,8 @@ static int regulator_virtual_consumer_probe(struct platform_device *pdev)
return 0; return 0;
err_regulator:
regulator_put(drvdata->regulator);
err: err:
for (i = 0; i < ARRAY_SIZE(attributes); i++) for (i = 0; i < ARRAY_SIZE(attributes); i++)
device_remove_file(&pdev->dev, attributes[i]); device_remove_file(&pdev->dev, attributes[i]);
......
...@@ -1419,6 +1419,8 @@ int wm8350_register_regulator(struct wm8350 *wm8350, int reg, ...@@ -1419,6 +1419,8 @@ int wm8350_register_regulator(struct wm8350 *wm8350, int reg,
{ {
struct platform_device *pdev; struct platform_device *pdev;
int ret; int ret;
if (reg < 0 || reg >= NUM_WM8350_REGULATORS)
return -EINVAL;
if (wm8350->pmic.pdev[reg]) if (wm8350->pmic.pdev[reg])
return -EBUSY; return -EBUSY;
......
#ifndef __LINUX_PMIC_DA903X_H #ifndef __LINUX_PMIC_DA903X_H
#define __LINUX_PMIC_DA903X_H #define __LINUX_PMIC_DA903X_H
/* Unified sub device IDs for DA9030/DA9034 */ /* Unified sub device IDs for DA9030/DA9034/DA9035 */
enum { enum {
DA9030_ID_LED_1, DA9030_ID_LED_1,
DA9030_ID_LED_2, DA9030_ID_LED_2,
...@@ -57,6 +57,8 @@ enum { ...@@ -57,6 +57,8 @@ enum {
DA9034_ID_LDO13, DA9034_ID_LDO13,
DA9034_ID_LDO14, DA9034_ID_LDO14,
DA9034_ID_LDO15, DA9034_ID_LDO15,
DA9035_ID_BUCK3,
}; };
/* /*
......
...@@ -125,6 +125,8 @@ struct regulator_bulk_data { ...@@ -125,6 +125,8 @@ struct regulator_bulk_data {
/* regulator get and put */ /* regulator get and put */
struct regulator *__must_check regulator_get(struct device *dev, struct regulator *__must_check regulator_get(struct device *dev,
const char *id); const char *id);
struct regulator *__must_check regulator_get_exclusive(struct device *dev,
const char *id);
void regulator_put(struct regulator *regulator); void regulator_put(struct regulator *regulator);
/* regulator output control and status */ /* regulator output control and status */
...@@ -144,6 +146,8 @@ void regulator_bulk_free(int num_consumers, ...@@ -144,6 +146,8 @@ void regulator_bulk_free(int num_consumers,
int regulator_count_voltages(struct regulator *regulator); int regulator_count_voltages(struct regulator *regulator);
int regulator_list_voltage(struct regulator *regulator, unsigned selector); int regulator_list_voltage(struct regulator *regulator, unsigned selector);
int regulator_is_supported_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_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,
......
...@@ -37,7 +37,8 @@ enum regulator_status { ...@@ -37,7 +37,8 @@ enum regulator_status {
* *
* @enable: Configure the regulator as enabled. * @enable: Configure the regulator as enabled.
* @disable: Configure the regulator as disabled. * @disable: Configure the regulator as disabled.
* @is_enabled: Return 1 if the regulator is enabled, 0 otherwise. * @is_enabled: Return 1 if the regulator is enabled, 0 if not.
* May also return negative errno.
* *
* @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.
...@@ -162,6 +163,8 @@ struct regulator_desc { ...@@ -162,6 +163,8 @@ struct regulator_desc {
struct regulator_dev { struct regulator_dev {
struct regulator_desc *desc; struct regulator_desc *desc;
int use_count; int use_count;
int open_count;
int exclusive;
/* lists we belong to */ /* lists we belong to */
struct list_head list; /* list of all regulators */ struct list_head list; /* list of all regulators */
......
...@@ -5,6 +5,9 @@ ...@@ -5,6 +5,9 @@
* *
* Author: Mark Brown <broonie@opensource.wolfsonmicro.com> * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
* *
* Copyright (c) 2009 Nokia Corporation
* Roger Quadros <ext-roger.quadros@nokia.com>
*
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the * published by the Free Software Foundation; either version 2 of the
...@@ -16,9 +19,30 @@ ...@@ -16,9 +19,30 @@
struct regulator_init_data; struct regulator_init_data;
/**
* struct fixed_voltage_config - fixed_voltage_config structure
* @supply_name: Name of the regulator supply
* @microvolts: Output voltage of regulator
* @gpio: GPIO to use for enable control
* set to -EINVAL if not used
* @enable_high: Polarity of enable GPIO
* 1 = Active high, 0 = Active low
* @enabled_at_boot: Whether regulator has been enabled at
* boot or not. 1 = Yes, 0 = No
* This is used to keep the regulator at
* the default state
* @init_data: regulator_init_data
*
* This structure contains fixed voltage regulator configuration
* information that must be passed by platform code to the fixed
* voltage regulator driver.
*/
struct fixed_voltage_config { struct fixed_voltage_config {
const char *supply_name; const char *supply_name;
int microvolts; int microvolts;
int gpio;
unsigned enable_high:1;
unsigned enabled_at_boot:1;
struct regulator_init_data *init_data; struct regulator_init_data *init_data;
}; };
......
...@@ -41,7 +41,7 @@ struct regulator; ...@@ -41,7 +41,7 @@ struct regulator;
#define REGULATOR_CHANGE_DRMS 0x10 #define REGULATOR_CHANGE_DRMS 0x10
/** /**
* struct regulator_state - regulator state during low power syatem states * struct regulator_state - regulator state during low power system states
* *
* This describes a regulators state during a system wide low power state. * This describes a regulators state during a system wide low power state.
* *
...@@ -117,25 +117,37 @@ struct regulation_constraints { ...@@ -117,25 +117,37 @@ struct regulation_constraints {
/* mode to set on startup */ /* mode to set on startup */
unsigned int initial_mode; unsigned int initial_mode;
/* constriant flags */ /* constraint 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 */
unsigned apply_uV:1; /* apply uV constraint iff min == max */ unsigned apply_uV:1; /* apply uV constraint if min == max */
}; };
/** /**
* struct regulator_consumer_supply - supply -> device mapping * struct regulator_consumer_supply - supply -> device mapping
* *
* This maps a supply name to a device. * This maps a supply name to a device. Only one of dev or dev_name
* can be specified. Use of dev_name allows support for buses which
* make struct device available late such as I2C and is the preferred
* form.
* *
* @dev: Device structure for the consumer. * @dev: Device structure for the consumer.
* @dev_name: Result of dev_name() for the consumer.
* @supply: Name for the supply. * @supply: Name for the supply.
*/ */
struct regulator_consumer_supply { struct regulator_consumer_supply {
struct device *dev; /* consumer */ struct device *dev; /* consumer */
const char *dev_name; /* dev_name() for consumer */
const char *supply; /* consumer supply - e.g. "vcc" */ const char *supply; /* consumer supply - e.g. "vcc" */
}; };
/* Initialize struct regulator_consumer_supply */
#define REGULATOR_SUPPLY(_name, _dev_name) \
{ \
.supply = _name, \
.dev_name = _dev_name, \
}
/** /**
* struct regulator_init_data - regulator platform initialisation data. * struct regulator_init_data - regulator platform initialisation data.
* *
...@@ -166,6 +178,12 @@ struct regulator_init_data { ...@@ -166,6 +178,12 @@ struct regulator_init_data {
int regulator_suspend_prepare(suspend_state_t state); int regulator_suspend_prepare(suspend_state_t state);
#ifdef CONFIG_REGULATOR
void regulator_has_full_constraints(void); void regulator_has_full_constraints(void);
#else
static inline void regulator_has_full_constraints(void)
{
}
#endif
#endif #endif
...@@ -36,7 +36,7 @@ ...@@ -36,7 +36,7 @@
* max1586_subdev_data - regulator data * max1586_subdev_data - regulator data
* @id: regulator Id (either MAX1586_V3 or MAX1586_V6) * @id: regulator Id (either MAX1586_V3 or MAX1586_V6)
* @name: regulator cute name (example for V3: "vcc_core") * @name: regulator cute name (example for V3: "vcc_core")
* @platform_data: regulator init data (contraints, supplies, ...) * @platform_data: regulator init data (constraints, supplies, ...)
*/ */
struct max1586_subdev_data { struct max1586_subdev_data {
int id; int id;
...@@ -46,7 +46,7 @@ struct max1586_subdev_data { ...@@ -46,7 +46,7 @@ struct max1586_subdev_data {
/** /**
* max1586_platform_data - platform data for max1586 * max1586_platform_data - platform data for max1586
* @num_subdevs: number of regultors used (may be 1 or 2) * @num_subdevs: number of regulators used (may be 1 or 2)
* @subdevs: regulator used * @subdevs: regulator used
* At most, there will be a regulator for V3 and one for V6 voltages. * At most, there will be a regulator for V3 and one for V6 voltages.
* @v3_gain: gain on the V3 voltage output multiplied by 1e6. * @v3_gain: gain on the V3 voltage output multiplied by 1e6.
......
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