Commit 55a71bc2 authored by Stephen Rothwell's avatar Stephen Rothwell

Merge commit 'voltage/for-next'

Conflicts:
	drivers/regulator/Kconfig
parents 54b59c6a 23b0b60d
......@@ -29,7 +29,7 @@ Some terms used in this document:-
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.
......@@ -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
consumption and status.
See Documentation/ABI/testing/regulator-sysfs.txt
See Documentation/ABI/testing/sysfs-class-regulator
......@@ -10,8 +10,9 @@ Registration
Drivers can register a regulator by calling :-
struct regulator_dev *regulator_register(struct device *dev,
struct regulator_desc *regulator_desc);
struct regulator_dev *regulator_register(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
core.
......
......@@ -52,7 +52,7 @@ config REGULATOR_USERSPACE_CONSUMER
default n
help
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.
If unsure, say no.
......@@ -147,5 +147,21 @@ config REGULATOR_AB3100
AB3100 analog baseband dealing with power regulators
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
......@@ -23,4 +23,7 @@ obj-$(CONFIG_REGULATOR_PCAP) += pcap-regulator.o
obj-$(CONFIG_REGULATOR_MC13783) += mc13783.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
This diff is collapsed.
......@@ -64,6 +64,14 @@
#define DA9034_MDTV2 (0x33)
#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 regulator_desc desc;
......@@ -79,6 +87,10 @@ struct da903x_regulator_info {
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)
{
return rdev_get_dev(rdev)->parent->parent;
......@@ -162,6 +174,17 @@ static int da903x_is_enabled(struct regulator_dev *rdev)
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 */
static int da9030_set_ldo1_15_voltage(struct regulator_dev *rdev,
int min_uV, int max_uV)
......@@ -305,9 +328,18 @@ static int da9034_get_ldo12_voltage(struct regulator_dev *rdev)
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 = {
.set_voltage = da903x_set_ldo_voltage,
.get_voltage = da903x_get_voltage,
.list_voltage = da903x_list_voltage,
.enable = da903x_enable,
.disable = da903x_disable,
.is_enabled = da903x_is_enabled,
......@@ -317,6 +349,7 @@ static struct regulator_ops da903x_regulator_ldo_ops = {
static struct regulator_ops da9030_regulator_ldo14_ops = {
.set_voltage = da9030_set_ldo14_voltage,
.get_voltage = da9030_get_ldo14_voltage,
.list_voltage = da903x_list_voltage,
.enable = da903x_enable,
.disable = da903x_disable,
.is_enabled = da903x_is_enabled,
......@@ -326,6 +359,7 @@ static struct regulator_ops da9030_regulator_ldo14_ops = {
static struct regulator_ops da9030_regulator_ldo1_15_ops = {
.set_voltage = da9030_set_ldo1_15_voltage,
.get_voltage = da903x_get_voltage,
.list_voltage = da903x_list_voltage,
.enable = da903x_enable,
.disable = da903x_disable,
.is_enabled = da903x_is_enabled,
......@@ -334,6 +368,7 @@ static struct regulator_ops da9030_regulator_ldo1_15_ops = {
static struct regulator_ops da9034_regulator_dvc_ops = {
.set_voltage = da9034_set_dvc_voltage,
.get_voltage = da903x_get_voltage,
.list_voltage = da903x_list_voltage,
.enable = da903x_enable,
.disable = da903x_disable,
.is_enabled = da903x_is_enabled,
......@@ -343,6 +378,7 @@ static struct regulator_ops da9034_regulator_dvc_ops = {
static struct regulator_ops da9034_regulator_ldo12_ops = {
.set_voltage = da9034_set_ldo12_voltage,
.get_voltage = da9034_get_ldo12_voltage,
.list_voltage = da9034_list_ldo12_voltage,
.enable = da903x_enable,
.disable = da903x_disable,
.is_enabled = da903x_is_enabled,
......@@ -355,6 +391,7 @@ static struct regulator_ops da9034_regulator_ldo12_ops = {
.ops = &da903x_regulator_ldo_ops, \
.type = REGULATOR_VOLTAGE, \
.id = _pmic##_ID_LDO##_id, \
.n_voltages = (step) ? ((max - min) / step + 1) : 1, \
.owner = THIS_MODULE, \
}, \
.min_uV = (min) * 1000, \
......@@ -367,24 +404,25 @@ static struct regulator_ops da9034_regulator_ldo12_ops = {
.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 = { \
.name = #_id, \
.ops = &da9034_regulator_dvc_ops, \
.type = REGULATOR_VOLTAGE, \
.id = DA9034_ID_##_id, \
.id = _pmic##_ID_##_id, \
.n_voltages = (step) ? ((max - min) / step + 1) : 1, \
.owner = THIS_MODULE, \
}, \
.min_uV = (min) * 1000, \
.max_uV = (max) * 1000, \
.step_uV = (step) * 1000, \
.vol_reg = DA9034_##vreg, \
.vol_reg = _pmic##_##vreg, \
.vol_shift = (0), \
.vol_nbits = (nbits), \
.update_reg = DA9034_##ureg, \
.update_reg = _pmic##_##ureg, \
.update_bit = (ubit), \
.enable_reg = DA9034_##ereg, \
.enable_reg = _pmic##_##ereg, \
.enable_bit = (ebit), \
}
......@@ -394,8 +432,22 @@ static struct regulator_ops da9034_regulator_ldo12_ops = {
#define DA9030_LDO(_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[] = {
/* 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( 2, 1800, 3200, 100, LDO23, 0, 4, RCTL12, 2),
DA9030_LDO( 3, 1800, 3200, 100, LDO23, 4, 4, RCTL12, 3),
......@@ -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 */
/* DA9034 */
DA9034_DVC(BUCK1, 725, 1500, 25, ADTV1, 5, VCC1, 0, OVER1, 0),
DA9034_DVC(BUCK2, 725, 1500, 25, CDTV1, 5, VCC1, 2, OVER1, 1),
DA9034_DVC(LDO2, 725, 1500, 25, SDTV1, 5, VCC1, 4, OVER1, 2),
DA9034_DVC(BUCK1, 725, 1500, 25, ADTV2, 5, VCC1, 0, OVER1, 0),
DA9034_DVC(BUCK2, 725, 1500, 25, CDTV2, 5, VCC1, 2, OVER1, 1),
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_LDO( 3, 1800, 3300, 100, LDO643, 0, 4, OVER3, 5),
......@@ -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(15, 1800, 3300, 100, LDO1514, 4, 4, OVER3, 1),
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)
......@@ -462,8 +517,10 @@ static int __devinit da903x_regulator_probe(struct platform_device *pdev)
}
/* 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.n_voltages = ARRAY_SIZE(da9034_ldo12_data);
}
if (ri->desc.id == DA9030_ID_LDO14)
ri->desc.ops = &da9030_regulator_ldo14_ops;
......
......@@ -5,6 +5,9 @@
*
* 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
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
......@@ -20,20 +23,45 @@
#include <linux/platform_device.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/fixed.h>
#include <linux/gpio.h>
struct fixed_voltage_data {
struct regulator_desc desc;
struct regulator_dev *dev;
int microvolts;
int gpio;
unsigned enable_high:1;
unsigned is_enabled:1;
};
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)
{
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;
}
......@@ -58,6 +86,7 @@ static int fixed_voltage_list_voltage(struct regulator_dev *dev,
static struct regulator_ops fixed_voltage_ops = {
.is_enabled = fixed_voltage_is_enabled,
.enable = fixed_voltage_enable,
.disable = fixed_voltage_disable,
.get_voltage = fixed_voltage_get_voltage,
.list_voltage = fixed_voltage_list_voltage,
};
......@@ -70,12 +99,14 @@ static int regulator_fixed_voltage_probe(struct platform_device *pdev)
drvdata = kzalloc(sizeof(struct fixed_voltage_data), GFP_KERNEL);
if (drvdata == NULL) {
dev_err(&pdev->dev, "Failed to allocate device data\n");
ret = -ENOMEM;
goto err;
}
drvdata->desc.name = kstrdup(config->supply_name, GFP_KERNEL);
if (drvdata->desc.name == NULL) {
dev_err(&pdev->dev, "Failed to allocate supply name\n");
ret = -ENOMEM;
goto err;
}
......@@ -85,12 +116,62 @@ static int regulator_fixed_voltage_probe(struct platform_device *pdev)
drvdata->desc.n_voltages = 1;
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,
config->init_data, drvdata);
if (IS_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);
......@@ -100,6 +181,9 @@ static int regulator_fixed_voltage_probe(struct platform_device *pdev)
return 0;
err_gpio:
if (gpio_is_valid(config->gpio))
gpio_free(config->gpio);
err_name:
kfree(drvdata->desc.name);
err:
......@@ -115,6 +199,9 @@ static int regulator_fixed_voltage_remove(struct platform_device *pdev)
kfree(drvdata->desc.name);
kfree(drvdata);
if (gpio_is_valid(drvdata->gpio))
gpio_free(drvdata->gpio);
return 0;
}
......
......@@ -24,11 +24,12 @@
#include <linux/mfd/pcf50633/core.h>
#include <linux/mfd/pcf50633/pmic.h>
#define PCF50633_REGULATOR(_name, _id) \
#define PCF50633_REGULATOR(_name, _id, _n) \
{ \
.name = _name, \
.id = _id, \
.ops = &pcf50633_regulator_ops, \
.n_voltages = _n, \
.type = REGULATOR_VOLTAGE, \
.owner = THIS_MODULE, \
}
......@@ -149,33 +150,20 @@ static int pcf50633_regulator_set_voltage(struct regulator_dev *rdev,
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 regulator_id, millivolts, volt_bits;
u8 regnr;
pcf = rdev_get_drvdata(rdev);;
int millivolts;
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);
if (volt_bits < 0)
return -1;
switch (regulator_id) {
switch (id) {
case PCF50633_REGULATOR_AUTO:
millivolts = auto_voltage_value(volt_bits);
millivolts = auto_voltage_value(bits);
break;
case PCF50633_REGULATOR_DOWN1:
millivolts = down_voltage_value(volt_bits);
millivolts = down_voltage_value(bits);
break;
case PCF50633_REGULATOR_DOWN2:
millivolts = down_voltage_value(volt_bits);
millivolts = down_voltage_value(bits);
break;
case PCF50633_REGULATOR_LDO1:
case PCF50633_REGULATOR_LDO2:
......@@ -184,7 +172,7 @@ static int pcf50633_regulator_get_voltage(struct regulator_dev *rdev)
case PCF50633_REGULATOR_LDO5:
case PCF50633_REGULATOR_LDO6:
case PCF50633_REGULATOR_HCLDO:
millivolts = ldo_voltage_value(volt_bits);
millivolts = ldo_voltage_value(bits);
break;
default:
return -EINVAL;
......@@ -193,6 +181,49 @@ static int pcf50633_regulator_get_voltage(struct regulator_dev *rdev)
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)
{
struct pcf50633 *pcf = rdev_get_drvdata(rdev);
......@@ -246,6 +277,7 @@ static int pcf50633_regulator_is_enabled(struct regulator_dev *rdev)
static struct regulator_ops pcf50633_regulator_ops = {
.set_voltage = pcf50633_regulator_set_voltage,
.get_voltage = pcf50633_regulator_get_voltage,
.list_voltage = pcf50633_regulator_list_voltage,
.enable = pcf50633_regulator_enable,
.disable = pcf50633_regulator_disable,
.is_enabled = pcf50633_regulator_is_enabled,
......@@ -253,27 +285,27 @@ static struct regulator_ops pcf50633_regulator_ops = {
static struct regulator_desc regulators[] = {
[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, 95),
[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, 27),
[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, 27),
[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, 27),
[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, 26),
[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)
......
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,
static DEVICE_ATTR(name, 0444, reg_show_name, NULL);
static DEVICE_ATTR(state, 0644, reg_show_state, reg_set_state);
static struct device_attribute *attributes[] = {
&dev_attr_name,
&dev_attr_state,
static struct attribute *attributes[] = {
&dev_attr_name.attr,
&dev_attr_state.attr,
NULL,
};
static const struct attribute_group attr_group = {
.attrs = attributes,
};
static int regulator_userspace_consumer_probe(struct platform_device *pdev)
{
struct regulator_userspace_consumer_data *pdata;
struct userspace_consumer_data *drvdata;
int ret, i;
int ret;
pdata = pdev->dev.platform_data;
if (!pdata)
......@@ -125,31 +130,29 @@ static int regulator_userspace_consumer_probe(struct platform_device *pdev)
goto err_alloc_supplies;
}
for (i = 0; i < ARRAY_SIZE(attributes); i++) {
ret = device_create_file(&pdev->dev, attributes[i]);
ret = sysfs_create_group(&pdev->dev.kobj, &attr_group);
if (ret != 0)
goto err_create_attrs;
}
if (pdata->init_on)
if (pdata->init_on) {
ret = regulator_bulk_enable(drvdata->num_supplies,
drvdata->supplies);
drvdata->enabled = pdata->init_on;
if (ret) {
dev_err(&pdev->dev, "Failed to set initial state: %d\n", ret);
goto err_create_attrs;
dev_err(&pdev->dev,
"Failed to set initial state: %d\n", ret);
goto err_enable;
}
}
drvdata->enabled = pdata->init_on;
platform_set_drvdata(pdev, drvdata);
return 0;
err_create_attrs:
for (i = 0; i < ARRAY_SIZE(attributes); i++)
device_remove_file(&pdev->dev, attributes[i]);
err_enable:
sysfs_remove_group(&pdev->dev.kobj, &attr_group);
err_create_attrs:
regulator_bulk_free(drvdata->num_supplies, drvdata->supplies);
err_alloc_supplies:
......@@ -160,10 +163,8 @@ err_alloc_supplies:
static int regulator_userspace_consumer_remove(struct platform_device *pdev)
{
struct userspace_consumer_data *data = platform_get_drvdata(pdev);
int i;
for (i = 0; i < ARRAY_SIZE(attributes); i++)
device_remove_file(&pdev->dev, attributes[i]);
sysfs_remove_group(&pdev->dev.kobj, &attr_group);
if (data->enabled)
regulator_bulk_disable(data->num_supplies, data->supplies);
......
......@@ -27,71 +27,81 @@ struct virtual_consumer_data {
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;
if (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,
data->min_uV, data->max_uV);
if (ret != 0) {
printk(KERN_ERR "regulator_set_voltage() failed: %d\n",
ret);
dev_err(dev,
"regulator_set_voltage() failed: %d\n", ret);
return;
}
}
if (data->min_uV && data->max_uV && !data->enabled) {
dev_dbg(dev, "Enabling regulator\n");
ret = regulator_enable(data->regulator);
if (ret == 0)
data->enabled = 1;
else
printk(KERN_ERR "regulator_enable() failed: %d\n",
dev_err(dev, "regulator_enable() failed: %d\n",
ret);
}
if (!(data->min_uV && data->max_uV) && data->enabled) {
dev_dbg(dev, "Disabling regulator\n");
ret = regulator_disable(data->regulator);
if (ret == 0)
data->enabled = 0;
else
printk(KERN_ERR "regulator_disable() failed: %d\n",
dev_err(dev, "regulator_disable() failed: %d\n",
ret);
}
}
static void update_current_limit_constraints(struct virtual_consumer_data
*data)
static void update_current_limit_constraints(struct device *dev,
struct virtual_consumer_data *data)
{
int ret;
if (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,
data->min_uA, data->max_uA);
if (ret != 0) {
pr_err("regulator_set_current_limit() failed: %d\n",
dev_err(dev,
"regulator_set_current_limit() failed: %d\n",
ret);
return;
}
}
if (data->max_uA && !data->enabled) {
dev_dbg(dev, "Enabling regulator\n");
ret = regulator_enable(data->regulator);
if (ret == 0)
data->enabled = 1;
else
printk(KERN_ERR "regulator_enable() failed: %d\n",
dev_err(dev, "regulator_enable() failed: %d\n",
ret);
}
if (!(data->min_uA && data->max_uA) && data->enabled) {
dev_dbg(dev, "Disabling regulator\n");
ret = regulator_disable(data->regulator);
if (ret == 0)
data->enabled = 0;
else
printk(KERN_ERR "regulator_disable() failed: %d\n",
dev_err(dev, "regulator_disable() failed: %d\n",
ret);
}
}
......@@ -115,7 +125,7 @@ static ssize_t set_min_uV(struct device *dev, struct device_attribute *attr,
mutex_lock(&data->lock);
data->min_uV = val;
update_voltage_constraints(data);
update_voltage_constraints(dev, data);
mutex_unlock(&data->lock);
......@@ -141,7 +151,7 @@ static ssize_t set_max_uV(struct device *dev, struct device_attribute *attr,
mutex_lock(&data->lock);
data->max_uV = val;
update_voltage_constraints(data);
update_voltage_constraints(dev, data);
mutex_unlock(&data->lock);
......@@ -167,7 +177,7 @@ static ssize_t set_min_uA(struct device *dev, struct device_attribute *attr,
mutex_lock(&data->lock);
data->min_uA = val;
update_current_limit_constraints(data);
update_current_limit_constraints(dev, data);
mutex_unlock(&data->lock);
......@@ -193,7 +203,7 @@ static ssize_t set_max_uA(struct device *dev, struct device_attribute *attr,
mutex_lock(&data->lock);
data->max_uA = val;
update_current_limit_constraints(data);
update_current_limit_constraints(dev, data);
mutex_unlock(&data->lock);
......@@ -276,8 +286,7 @@ static int regulator_virtual_consumer_probe(struct platform_device *pdev)
drvdata = kzalloc(sizeof(struct virtual_consumer_data), GFP_KERNEL);
if (drvdata == NULL) {
ret = -ENOMEM;
goto err;
return -ENOMEM;
}
mutex_init(&drvdata->lock);
......@@ -285,13 +294,18 @@ static int regulator_virtual_consumer_probe(struct platform_device *pdev)
drvdata->regulator = regulator_get(&pdev->dev, reg_id);
if (IS_ERR(drvdata->regulator)) {
ret = PTR_ERR(drvdata->regulator);
dev_err(&pdev->dev, "Failed to obtain supply '%s': %d\n",
reg_id, ret);
goto err;
}
for (i = 0; i < ARRAY_SIZE(attributes); i++) {
ret = device_create_file(&pdev->dev, attributes[i]);
if (ret != 0)
goto err;
if (ret != 0) {
dev_err(&pdev->dev, "Failed to create attr %d: %d\n",
i, ret);
goto err_regulator;
}
}
drvdata->mode = regulator_get_mode(drvdata->regulator);
......@@ -300,6 +314,8 @@ static int regulator_virtual_consumer_probe(struct platform_device *pdev)
return 0;
err_regulator:
regulator_put(drvdata->regulator);
err:
for (i = 0; i < ARRAY_SIZE(attributes); i++)
device_remove_file(&pdev->dev, attributes[i]);
......
......@@ -1419,6 +1419,8 @@ int wm8350_register_regulator(struct wm8350 *wm8350, int reg,
{
struct platform_device *pdev;
int ret;
if (reg < 0 || reg >= NUM_WM8350_REGULATORS)
return -EINVAL;
if (wm8350->pmic.pdev[reg])
return -EBUSY;
......
#ifndef __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 {
DA9030_ID_LED_1,
DA9030_ID_LED_2,
......@@ -57,6 +57,8 @@ enum {
DA9034_ID_LDO13,
DA9034_ID_LDO14,
DA9034_ID_LDO15,
DA9035_ID_BUCK3,
};
/*
......
......@@ -125,6 +125,8 @@ struct regulator_bulk_data {
/* regulator get and put */
struct regulator *__must_check regulator_get(struct device *dev,
const char *id);
struct regulator *__must_check regulator_get_exclusive(struct device *dev,
const char *id);
void regulator_put(struct regulator *regulator);
/* regulator output control and status */
......@@ -144,6 +146,8 @@ void regulator_bulk_free(int num_consumers,
int regulator_count_voltages(struct regulator *regulator);
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_get_voltage(struct regulator *regulator);
int regulator_set_current_limit(struct regulator *regulator,
......
......@@ -162,6 +162,8 @@ struct regulator_desc {
struct regulator_dev {
struct regulator_desc *desc;
int use_count;
int open_count;
int exclusive;
/* lists we belong to */
struct list_head list; /* list of all regulators */
......
......@@ -5,6 +5,9 @@
*
* 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
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
......@@ -16,9 +19,30 @@
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 {
const char *supply_name;
int microvolts;
int gpio;
unsigned enable_high:1;
unsigned enabled_at_boot:1;
struct regulator_init_data *init_data;
};
......
......@@ -126,16 +126,28 @@ struct regulation_constraints {
/**
* 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_name: Result of dev_name() for the consumer.
* @supply: Name for the supply.
*/
struct regulator_consumer_supply {
struct device *dev; /* consumer */
const char *dev_name; /* dev_name() for consumer */
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.
*
......@@ -166,6 +178,12 @@ struct regulator_init_data {
int regulator_suspend_prepare(suspend_state_t state);
#ifdef CONFIG_REGULATOR
void regulator_has_full_constraints(void);
#else
static inline 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