Merge remote-tracking branches 'regulator/topic/core', 'regulator/topic/regmap' and 'regulator/topic/register' into regulator-next

This commit is contained in:
Mark Brown 2012-05-12 11:09:47 +01:00
commit 178e43aef2
60 changed files with 2077 additions and 2218 deletions

View File

@ -11,8 +11,7 @@ Registration
Drivers can register a regulator by calling :-
struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,
struct device *dev, struct regulator_init_data *init_data,
void *driver_data, struct device_node *of_node);
const struct regulator_config *config);
This will register the regulators capabilities and operations to the regulator
core.

View File

@ -78,17 +78,6 @@ static struct mfd_cell tps65090s[] = {
},
};
struct tps65090 {
struct mutex lock;
struct device *dev;
struct i2c_client *client;
struct regmap *rmap;
struct irq_chip irq_chip;
struct mutex irq_lock;
int irq_base;
unsigned int id;
};
int tps65090_write(struct device *dev, int reg, uint8_t val)
{
struct tps65090 *tps = dev_get_drvdata(dev);

View File

@ -27,13 +27,8 @@ struct pm8607_regulator_info {
unsigned int *vol_table;
unsigned int *vol_suspend;
int vol_reg;
int vol_shift;
int vol_nbits;
int update_reg;
int update_bit;
int enable_reg;
int enable_bit;
int slope_double;
};
@ -216,7 +211,7 @@ static int pm8607_list_voltage(struct regulator_dev *rdev, unsigned index)
struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
int ret = -EINVAL;
if (info->vol_table && (index < (1 << info->vol_nbits))) {
if (info->vol_table && (index < rdev->desc->n_voltages)) {
ret = info->vol_table[index];
if (info->slope_double)
ret <<= 1;
@ -224,51 +219,16 @@ static int pm8607_list_voltage(struct regulator_dev *rdev, unsigned index)
return ret;
}
static int choose_voltage(struct regulator_dev *rdev, int min_uV, int max_uV)
static int pm8607_set_voltage_sel(struct regulator_dev *rdev, unsigned selector)
{
struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
int i, ret = -ENOENT;
if (info->slope_double) {
min_uV = min_uV >> 1;
max_uV = max_uV >> 1;
}
if (info->vol_table) {
for (i = 0; i < (1 << info->vol_nbits); i++) {
if (!info->vol_table[i])
break;
if ((min_uV <= info->vol_table[i])
&& (max_uV >= info->vol_table[i])) {
ret = i;
break;
}
}
}
if (ret < 0)
pr_err("invalid voltage range (%d %d) uV\n", min_uV, max_uV);
return ret;
}
static int pm8607_set_voltage(struct regulator_dev *rdev,
int min_uV, int max_uV, unsigned *selector)
{
struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
uint8_t val, mask;
uint8_t val;
int ret;
if (min_uV > max_uV) {
pr_err("invalid voltage range (%d, %d) uV\n", min_uV, max_uV);
return -EINVAL;
}
val = (uint8_t)(selector << (ffs(rdev->desc->vsel_mask) - 1));
ret = choose_voltage(rdev, min_uV, max_uV);
if (ret < 0)
return -EINVAL;
*selector = ret;
val = (uint8_t)(ret << info->vol_shift);
mask = ((1 << info->vol_nbits) - 1) << info->vol_shift;
ret = pm860x_set_bits(info->i2c, info->vol_reg, mask, val);
ret = pm860x_set_bits(info->i2c, rdev->desc->vsel_reg,
rdev->desc->vsel_mask, val);
if (ret)
return ret;
switch (info->desc.id) {
@ -282,60 +242,16 @@ static int pm8607_set_voltage(struct regulator_dev *rdev,
return ret;
}
static int pm8607_get_voltage(struct regulator_dev *rdev)
{
struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
uint8_t val, mask;
int ret;
ret = pm860x_reg_read(info->i2c, info->vol_reg);
if (ret < 0)
return ret;
mask = ((1 << info->vol_nbits) - 1) << info->vol_shift;
val = ((unsigned char)ret & mask) >> info->vol_shift;
return pm8607_list_voltage(rdev, val);
}
static int pm8607_enable(struct regulator_dev *rdev)
{
struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
return pm860x_set_bits(info->i2c, info->enable_reg,
1 << info->enable_bit,
1 << info->enable_bit);
}
static int pm8607_disable(struct regulator_dev *rdev)
{
struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
return pm860x_set_bits(info->i2c, info->enable_reg,
1 << info->enable_bit, 0);
}
static int pm8607_is_enabled(struct regulator_dev *rdev)
{
struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
int ret;
ret = pm860x_reg_read(info->i2c, info->enable_reg);
if (ret < 0)
return ret;
return !!((unsigned char)ret & (1 << info->enable_bit));
}
static struct regulator_ops pm8607_regulator_ops = {
.set_voltage = pm8607_set_voltage,
.get_voltage = pm8607_get_voltage,
.enable = pm8607_enable,
.disable = pm8607_disable,
.is_enabled = pm8607_is_enabled,
.list_voltage = pm8607_list_voltage,
.set_voltage_sel = pm8607_set_voltage_sel,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,
};
#define PM8607_DVC(vreg, nbits, ureg, ubit, ereg, ebit) \
#define PM8607_DVC(vreg, ureg, ubit, ereg, ebit) \
{ \
.desc = { \
.name = #vreg, \
@ -343,20 +259,20 @@ static struct regulator_ops pm8607_regulator_ops = {
.type = REGULATOR_VOLTAGE, \
.id = PM8607_ID_##vreg, \
.owner = THIS_MODULE, \
.n_voltages = ARRAY_SIZE(vreg##_table), \
.vsel_reg = PM8607_##vreg, \
.vsel_mask = ARRAY_SIZE(vreg##_table) - 1, \
.enable_reg = PM8607_##ereg, \
.enable_mask = 1 << (ebit), \
}, \
.vol_reg = PM8607_##vreg, \
.vol_shift = (0), \
.vol_nbits = (nbits), \
.update_reg = PM8607_##ureg, \
.update_bit = (ubit), \
.enable_reg = PM8607_##ereg, \
.enable_bit = (ebit), \
.slope_double = (0), \
.vol_table = (unsigned int *)&vreg##_table, \
.vol_suspend = (unsigned int *)&vreg##_suspend_table, \
}
#define PM8607_LDO(_id, vreg, shift, nbits, ereg, ebit) \
#define PM8607_LDO(_id, vreg, shift, ereg, ebit) \
{ \
.desc = { \
.name = "LDO" #_id, \
@ -364,35 +280,35 @@ static struct regulator_ops pm8607_regulator_ops = {
.type = REGULATOR_VOLTAGE, \
.id = PM8607_ID_LDO##_id, \
.owner = THIS_MODULE, \
.n_voltages = ARRAY_SIZE(LDO##_id##_table), \
.vsel_reg = PM8607_##vreg, \
.vsel_mask = (ARRAY_SIZE(LDO##_id##_table) - 1) << (shift), \
.enable_reg = PM8607_##ereg, \
.enable_mask = 1 << (ebit), \
}, \
.vol_reg = PM8607_##vreg, \
.vol_shift = (shift), \
.vol_nbits = (nbits), \
.enable_reg = PM8607_##ereg, \
.enable_bit = (ebit), \
.slope_double = (0), \
.vol_table = (unsigned int *)&LDO##_id##_table, \
.vol_suspend = (unsigned int *)&LDO##_id##_suspend_table, \
}
static struct pm8607_regulator_info pm8607_regulator_info[] = {
PM8607_DVC(BUCK1, 6, GO, 0, SUPPLIES_EN11, 0),
PM8607_DVC(BUCK2, 6, GO, 1, SUPPLIES_EN11, 1),
PM8607_DVC(BUCK3, 6, GO, 2, SUPPLIES_EN11, 2),
PM8607_DVC(BUCK1, GO, 0, SUPPLIES_EN11, 0),
PM8607_DVC(BUCK2, GO, 1, SUPPLIES_EN11, 1),
PM8607_DVC(BUCK3, GO, 2, SUPPLIES_EN11, 2),
PM8607_LDO( 1, LDO1, 0, 2, SUPPLIES_EN11, 3),
PM8607_LDO( 2, LDO2, 0, 3, SUPPLIES_EN11, 4),
PM8607_LDO( 3, LDO3, 0, 3, SUPPLIES_EN11, 5),
PM8607_LDO( 4, LDO4, 0, 3, SUPPLIES_EN11, 6),
PM8607_LDO( 5, LDO5, 0, 2, SUPPLIES_EN11, 7),
PM8607_LDO( 6, LDO6, 0, 3, SUPPLIES_EN12, 0),
PM8607_LDO( 7, LDO7, 0, 3, SUPPLIES_EN12, 1),
PM8607_LDO( 8, LDO8, 0, 3, SUPPLIES_EN12, 2),
PM8607_LDO( 9, LDO9, 0, 3, SUPPLIES_EN12, 3),
PM8607_LDO(10, LDO10, 0, 4, SUPPLIES_EN12, 4),
PM8607_LDO(12, LDO12, 0, 4, SUPPLIES_EN12, 5),
PM8607_LDO(13, VIBRATOR_SET, 1, 3, VIBRATOR_SET, 0),
PM8607_LDO(14, LDO14, 0, 3, SUPPLIES_EN12, 6),
PM8607_LDO(1, LDO1, 0, SUPPLIES_EN11, 3),
PM8607_LDO(2, LDO2, 0, SUPPLIES_EN11, 4),
PM8607_LDO(3, LDO3, 0, SUPPLIES_EN11, 5),
PM8607_LDO(4, LDO4, 0, SUPPLIES_EN11, 6),
PM8607_LDO(5, LDO5, 0, SUPPLIES_EN11, 7),
PM8607_LDO(6, LDO6, 0, SUPPLIES_EN12, 0),
PM8607_LDO(7, LDO7, 0, SUPPLIES_EN12, 1),
PM8607_LDO(8, LDO8, 0, SUPPLIES_EN12, 2),
PM8607_LDO(9, LDO9, 0, SUPPLIES_EN12, 3),
PM8607_LDO(10, LDO10, 0, SUPPLIES_EN12, 4),
PM8607_LDO(12, LDO12, 0, SUPPLIES_EN12, 5),
PM8607_LDO(13, VIBRATOR_SET, 1, VIBRATOR_SET, 0),
PM8607_LDO(14, LDO14, 0, SUPPLIES_EN12, 6),
};
static int __devinit pm8607_regulator_probe(struct platform_device *pdev)
@ -400,6 +316,7 @@ static int __devinit pm8607_regulator_probe(struct platform_device *pdev)
struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
struct pm8607_regulator_info *info = NULL;
struct regulator_init_data *pdata = pdev->dev.platform_data;
struct regulator_config config = { };
struct resource *res;
int i;
@ -425,9 +342,17 @@ static int __devinit pm8607_regulator_probe(struct platform_device *pdev)
if ((i == PM8607_ID_BUCK3) && info->chip->buck3_double)
info->slope_double = 1;
config.dev = &pdev->dev;
config.init_data = pdata;
config.driver_data = info;
if (chip->id == CHIP_PM8607)
config.regmap = chip->regmap;
else
config.regmap = chip->regmap_companion;
/* replace driver_data with info */
info->regulator = regulator_register(&info->desc, &pdev->dev,
pdata, info, NULL);
info->regulator = regulator_register(&info->desc, &config);
if (IS_ERR(info->regulator)) {
dev_err(&pdev->dev, "failed to register regulator %s\n",
info->desc.name);

View File

@ -223,6 +223,16 @@ config REGULATOR_PCF50633
Say Y here to support the voltage regulators and convertors
on PCF50633
config REGULATOR_RC5T583
tristate "RICOH RC5T583 Power regulators"
depends on MFD_RC5T583
help
Select this option to enable the power regulator of RICOH
PMIC RC5T583.
This driver supports the control of different power rails of device
through regulator interface. The device supports multiple DCDC/LDO
outputs which can be controlled by i2c communication.
config REGULATOR_S5M8767
tristate "Samsung S5M8767A voltage regulator"
depends on MFD_S5M_CORE
@ -268,11 +278,11 @@ config REGULATOR_TPS6105X
audio amplifiers.
config REGULATOR_TPS62360
tristate "TI TPS62360 Power Regulator"
tristate "TI TPS6236x Power Regulator"
depends on I2C
select REGMAP_I2C
help
This driver supports TPS62360 voltage regulator chip. This
This driver supports TPS6236x voltage regulator chip. This
regulator is meant for processor core supply. This chip is
high-frequency synchronous step down dc-dc converter optimized
for battery-powered portable applications.
@ -294,6 +304,13 @@ config REGULATOR_TPS6507X
three step-down converters and two general-purpose LDO voltage regulators.
It supports TI's software based Class-2 SmartReflex implementation.
config REGULATOR_TPS65090
tristate "TI TPS65090 Power regulator"
depends on MFD_TPS65090
help
This driver provides support for the voltage regulators on the
TI TPS65090 PMIC.
config REGULATOR_TPS65217
tristate "TI TPS65217 Power regulators"
depends on MFD_TPS65217

View File

@ -9,7 +9,6 @@ obj-$(CONFIG_REGULATOR_FIXED_VOLTAGE) += fixed.o
obj-$(CONFIG_REGULATOR_VIRTUAL_CONSUMER) += virtual.o
obj-$(CONFIG_REGULATOR_USERSPACE_CONSUMER) += userspace-consumer.o
obj-$(CONFIG_REGULATOR_GPIO) += gpio-regulator.o
obj-$(CONFIG_REGULATOR_88PM8607) += 88pm8607.o
obj-$(CONFIG_REGULATOR_AAT2870) += aat2870-regulator.o
obj-$(CONFIG_REGULATOR_AB3100) += ab3100.o
@ -20,6 +19,7 @@ obj-$(CONFIG_REGULATOR_DA903X) += da903x.o
obj-$(CONFIG_REGULATOR_DA9052) += da9052-regulator.o
obj-$(CONFIG_REGULATOR_DBX500_PRCMU) += dbx500-prcmu.o
obj-$(CONFIG_REGULATOR_DB8500_PRCMU) += db8500-prcmu.o
obj-$(CONFIG_REGULATOR_GPIO) += gpio-regulator.o
obj-$(CONFIG_REGULATOR_ISL6271A) += isl6271a-regulator.o
obj-$(CONFIG_REGULATOR_LP3971) += lp3971.o
obj-$(CONFIG_REGULATOR_LP3972) += lp3972.o
@ -35,11 +35,13 @@ obj-$(CONFIG_REGULATOR_MC13892) += mc13892-regulator.o
obj-$(CONFIG_REGULATOR_MC13XXX_CORE) += mc13xxx-regulator-core.o
obj-$(CONFIG_REGULATOR_PCAP) += pcap-regulator.o
obj-$(CONFIG_REGULATOR_PCF50633) += pcf50633-regulator.o
obj-$(CONFIG_REGULATOR_RC5T583) += rc5t583-regulator.o
obj-$(CONFIG_REGULATOR_S5M8767) += s5m8767.o
obj-$(CONFIG_REGULATOR_TPS6105X) += tps6105x-regulator.o
obj-$(CONFIG_REGULATOR_TPS62360) += tps62360-regulator.o
obj-$(CONFIG_REGULATOR_TPS65023) += tps65023-regulator.o
obj-$(CONFIG_REGULATOR_TPS6507X) += tps6507x-regulator.o
obj-$(CONFIG_REGULATOR_TPS65090) += tps65090-regulator.o
obj-$(CONFIG_REGULATOR_TPS65217) += tps65217-regulator.o
obj-$(CONFIG_REGULATOR_TPS6524X) += tps6524x-regulator.o
obj-$(CONFIG_REGULATOR_TPS6586X) += tps6586x-regulator.o

View File

@ -178,6 +178,7 @@ static struct aat2870_regulator *aat2870_get_regulator(int id)
static int aat2870_regulator_probe(struct platform_device *pdev)
{
struct aat2870_regulator *ri;
struct regulator_config config = { 0 };
struct regulator_dev *rdev;
ri = aat2870_get_regulator(pdev->id);
@ -187,8 +188,11 @@ static int aat2870_regulator_probe(struct platform_device *pdev)
}
ri->aat2870 = dev_get_drvdata(pdev->dev.parent);
rdev = regulator_register(&ri->desc, &pdev->dev,
pdev->dev.platform_data, ri, NULL);
config.dev = &pdev->dev;
config.driver_data = ri;
config.init_data = pdev->dev.platform_data;
rdev = regulator_register(&ri->desc, &config);
if (IS_ERR(rdev)) {
dev_err(&pdev->dev, "Failed to register regulator %s\n",
ri->desc.name);
@ -231,3 +235,4 @@ module_exit(aat2870_regulator_exit);
MODULE_DESCRIPTION("AnalogicTech AAT2870 Regulator");
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Jin Park <jinyoungp@nvidia.com>");
MODULE_ALIAS("platform:aat2870-regulator");

View File

@ -338,20 +338,12 @@ static int ab3100_get_best_voltage_index(struct regulator_dev *reg,
return bestindex;
}
static int ab3100_set_voltage_regulator(struct regulator_dev *reg,
int min_uV, int max_uV,
unsigned *selector)
static int ab3100_set_voltage_regulator_sel(struct regulator_dev *reg,
unsigned selector)
{
struct ab3100_regulator *abreg = reg->reg_data;
u8 regval;
int err;
int bestindex;
bestindex = ab3100_get_best_voltage_index(reg, min_uV, max_uV);
if (bestindex < 0)
return bestindex;
*selector = bestindex;
err = abx500_get_register_interruptible(abreg->dev, 0,
abreg->regreg, &regval);
@ -364,7 +356,7 @@ static int ab3100_set_voltage_regulator(struct regulator_dev *reg,
/* The highest three bits control the variable regulators */
regval &= ~0xE0;
regval |= (bestindex << 5);
regval |= (selector << 5);
err = abx500_set_register_interruptible(abreg->dev, 0,
abreg->regreg, regval);
@ -464,7 +456,7 @@ static struct regulator_ops regulator_ops_variable = {
.disable = ab3100_disable_regulator,
.is_enabled = ab3100_is_enabled_regulator,
.get_voltage = ab3100_get_voltage_regulator,
.set_voltage = ab3100_set_voltage_regulator,
.set_voltage_sel = ab3100_set_voltage_regulator_sel,
.list_voltage = ab3100_list_voltage_regulator,
.enable_time = ab3100_enable_time_regulator,
};
@ -474,7 +466,7 @@ static struct regulator_ops regulator_ops_variable_sleepable = {
.disable = ab3100_disable_regulator,
.is_enabled = ab3100_is_enabled_regulator,
.get_voltage = ab3100_get_voltage_regulator,
.set_voltage = ab3100_set_voltage_regulator,
.set_voltage_sel = ab3100_set_voltage_regulator_sel,
.set_suspend_voltage = ab3100_set_suspend_voltage_regulator,
.list_voltage = ab3100_list_voltage_regulator,
.enable_time = ab3100_enable_time_regulator,
@ -582,6 +574,7 @@ ab3100_regulator_desc[AB3100_NUM_REGULATORS] = {
static int __devinit ab3100_regulators_probe(struct platform_device *pdev)
{
struct ab3100_platform_data *plfdata = pdev->dev.platform_data;
struct regulator_config config = { };
int err = 0;
u8 data;
int i;
@ -627,15 +620,15 @@ static int __devinit ab3100_regulators_probe(struct platform_device *pdev)
reg->dev = &pdev->dev;
reg->plfdata = plfdata;
config.dev = &pdev->dev;
config.driver_data = reg;
config.init_data = &plfdata->reg_constraints[i];
/*
* Register the regulator, pass around
* the ab3100_regulator struct
*/
rdev = regulator_register(&ab3100_regulator_desc[i],
&pdev->dev,
&plfdata->reg_constraints[i],
reg, NULL);
rdev = regulator_register(&ab3100_regulator_desc[i], &config);
if (IS_ERR(rdev)) {
err = PTR_ERR(rdev);
dev_err(&pdev->dev,

View File

@ -234,25 +234,8 @@ static int ab8500_regulator_get_voltage_sel(struct regulator_dev *rdev)
return val;
}
static int ab8500_get_best_voltage_index(struct regulator_dev *rdev,
int min_uV, int max_uV)
{
struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
int i;
/* check the supported voltage */
for (i = 0; i < info->voltages_len; i++) {
if ((info->voltages[i] >= min_uV) &&
(info->voltages[i] <= max_uV))
return i;
}
return -EINVAL;
}
static int ab8500_regulator_set_voltage(struct regulator_dev *rdev,
int min_uV, int max_uV,
unsigned *selector)
static int ab8500_regulator_set_voltage_sel(struct regulator_dev *rdev,
unsigned selector)
{
int ret;
struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
@ -263,18 +246,8 @@ static int ab8500_regulator_set_voltage(struct regulator_dev *rdev,
return -EINVAL;
}
/* get the appropriate voltages within the range */
ret = ab8500_get_best_voltage_index(rdev, min_uV, max_uV);
if (ret < 0) {
dev_err(rdev_get_dev(rdev),
"couldn't get best voltage for regulator\n");
return ret;
}
*selector = ret;
/* set the registers for the request */
regval = (u8)ret;
regval = (u8)selector;
ret = abx500_mask_and_set_register_interruptible(info->dev,
info->voltage_bank, info->voltage_reg,
info->voltage_mask, regval);
@ -319,7 +292,7 @@ static struct regulator_ops ab8500_regulator_ops = {
.disable = ab8500_regulator_disable,
.is_enabled = ab8500_regulator_is_enabled,
.get_voltage_sel = ab8500_regulator_get_voltage_sel,
.set_voltage = ab8500_regulator_set_voltage,
.set_voltage_sel = ab8500_regulator_set_voltage_sel,
.list_voltage = ab8500_list_voltage,
.enable_time = ab8500_regulator_enable_time,
.set_voltage_time_sel = ab8500_regulator_set_voltage_time_sel,
@ -739,6 +712,7 @@ static __devinit int ab8500_regulator_probe(struct platform_device *pdev)
{
struct ab8500 *ab8500 = dev_get_drvdata(pdev->dev.parent);
struct ab8500_platform_data *pdata;
struct regulator_config config = { };
int i, err;
if (!ab8500) {
@ -806,6 +780,10 @@ static __devinit int ab8500_regulator_probe(struct platform_device *pdev)
info = &ab8500_regulator_info[i];
info->dev = &pdev->dev;
config.dev = &pdev->dev;
config.init_data = &pdata->regulator[i];
config.driver_data = info;
/* fix for hardware before ab8500v2.0 */
if (abx500_get_chip_id(info->dev) < 0x20) {
if (info->desc.id == AB8500_LDO_AUX3) {
@ -819,8 +797,7 @@ static __devinit int ab8500_regulator_probe(struct platform_device *pdev)
}
/* register regulator with framework */
info->regulator = regulator_register(&info->desc, &pdev->dev,
&pdata->regulator[i], info, NULL);
info->regulator = regulator_register(&info->desc, &config);
if (IS_ERR(info->regulator)) {
err = PTR_ERR(info->regulator);
dev_err(&pdev->dev, "failed to register regulator %s\n",

View File

@ -99,8 +99,8 @@ static int ad5398_set_current_limit(struct regulator_dev *rdev, int min_uA, int
if (ad5398_calc_current(chip, selector) > max_uA)
return -EINVAL;
dev_dbg(&client->dev, "changing current %dmA\n",
ad5398_calc_current(chip, selector) / 1000);
dev_dbg(&client->dev, "changing current %duA\n",
ad5398_calc_current(chip, selector));
/* read chip enable bit */
ret = ad5398_read_reg(client, &data);
@ -184,7 +184,7 @@ static struct regulator_ops ad5398_ops = {
.is_enabled = ad5398_is_enabled,
};
static struct regulator_desc ad5398_reg = {
static const struct regulator_desc ad5398_reg = {
.name = "isink",
.id = 0,
.ops = &ad5398_ops,
@ -212,6 +212,7 @@ static int __devinit ad5398_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct regulator_init_data *init_data = client->dev.platform_data;
struct regulator_config config = { };
struct ad5398_chip_info *chip;
const struct ad5398_current_data_format *df =
(struct ad5398_current_data_format *)id->driver_data;
@ -220,10 +221,14 @@ static int __devinit ad5398_probe(struct i2c_client *client,
if (!init_data)
return -EINVAL;
chip = kzalloc(sizeof(*chip), GFP_KERNEL);
chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL);
if (!chip)
return -ENOMEM;
config.dev = &client->dev;
config.init_data = init_data;
config.driver_data = chip;
chip->client = client;
chip->min_uA = df->min_uA;
@ -232,8 +237,7 @@ static int __devinit ad5398_probe(struct i2c_client *client,
chip->current_offset = df->current_offset;
chip->current_mask = (chip->current_level - 1) << chip->current_offset;
chip->rdev = regulator_register(&ad5398_reg, &client->dev,
init_data, chip, NULL);
chip->rdev = regulator_register(&ad5398_reg, &config);
if (IS_ERR(chip->rdev)) {
ret = PTR_ERR(chip->rdev);
dev_err(&client->dev, "failed to register %s %s\n",
@ -246,7 +250,6 @@ static int __devinit ad5398_probe(struct i2c_client *client,
return 0;
err:
kfree(chip);
return ret;
}
@ -255,8 +258,6 @@ static int __devexit ad5398_remove(struct i2c_client *client)
struct ad5398_chip_info *chip = i2c_get_clientdata(client);
regulator_unregister(chip->rdev);
kfree(chip);
return 0;
}

View File

@ -122,6 +122,7 @@ static int __devinit anatop_regulator_probe(struct platform_device *pdev)
struct anatop_regulator *sreg;
struct regulator_init_data *initdata;
struct anatop *anatopmfd = dev_get_drvdata(pdev->dev.parent);
struct regulator_config config = { };
int ret = 0;
initdata = of_get_regulator_init_data(dev, np);
@ -178,9 +179,13 @@ static int __devinit anatop_regulator_probe(struct platform_device *pdev)
rdesc->n_voltages = (sreg->max_voltage - sreg->min_voltage)
/ 25000 + 1;
config.dev = &pdev->dev;
config.init_data = initdata;
config.driver_data = sreg;
config.of_node = pdev->dev.of_node;
/* register regulator */
rdev = regulator_register(rdesc, dev,
initdata, sreg, pdev->dev.of_node);
rdev = regulator_register(rdesc, &config);
if (IS_ERR(rdev)) {
dev_err(dev, "failed to register %s\n",
rdesc->name);

View File

@ -24,6 +24,7 @@
#include <linux/suspend.h>
#include <linux/delay.h>
#include <linux/of.h>
#include <linux/regmap.h>
#include <linux/regulator/of_regulator.h>
#include <linux/regulator/consumer.h>
#include <linux/regulator/driver.h>
@ -74,6 +75,7 @@ struct regulator_map {
struct regulator {
struct device *dev;
struct list_head list;
unsigned int always_on:1;
int uA_load;
int min_uV;
int max_uV;
@ -155,6 +157,17 @@ static struct device_node *of_get_regulator(struct device *dev, const char *supp
return regnode;
}
static int _regulator_can_change_status(struct regulator_dev *rdev)
{
if (!rdev->constraints)
return 0;
if (rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_STATUS)
return 1;
else
return 0;
}
/* Platform voltage constraint check */
static int regulator_check_voltage(struct regulator_dev *rdev,
int *min_uV, int *max_uV)
@ -649,7 +662,7 @@ static void drms_uA_update(struct regulator_dev *rdev)
/* get input voltage */
input_uV = 0;
if (rdev->supply)
input_uV = _regulator_get_voltage(rdev);
input_uV = regulator_get_voltage(rdev->supply);
if (input_uV <= 0)
input_uV = rdev->constraints->input_uV;
if (input_uV <= 0)
@ -673,17 +686,14 @@ static int suspend_set_state(struct regulator_dev *rdev,
struct regulator_state *rstate)
{
int ret = 0;
bool can_set_state;
can_set_state = rdev->desc->ops->set_suspend_enable &&
rdev->desc->ops->set_suspend_disable;
/* If we have no suspend mode configration don't set anything;
* only warn if the driver actually makes the suspend mode
* configurable.
* only warn if the driver implements set_suspend_voltage or
* set_suspend_mode callback.
*/
if (!rstate->enabled && !rstate->disabled) {
if (can_set_state)
if (rdev->desc->ops->set_suspend_voltage ||
rdev->desc->ops->set_suspend_mode)
rdev_warn(rdev, "No configuration\n");
return 0;
}
@ -693,15 +703,13 @@ static int suspend_set_state(struct regulator_dev *rdev,
return -EINVAL;
}
if (!can_set_state) {
rdev_err(rdev, "no way to set suspend state\n");
return -EINVAL;
}
if (rstate->enabled)
if (rstate->enabled && rdev->desc->ops->set_suspend_enable)
ret = rdev->desc->ops->set_suspend_enable(rdev);
else
else if (rstate->disabled && rdev->desc->ops->set_suspend_disable)
ret = rdev->desc->ops->set_suspend_disable(rdev);
else /* OK if set_suspend_enable or set_suspend_disable is NULL */
ret = 0;
if (ret < 0) {
rdev_err(rdev, "failed to enabled/disable\n");
return ret;
@ -1146,6 +1154,15 @@ static struct regulator *create_regulator(struct regulator_dev *rdev,
&regulator->max_uV);
}
/*
* Check now if the regulator is an always on regulator - if
* it is then we don't need to do nearly so much work for
* enable/disable calls.
*/
if (!_regulator_can_change_status(rdev) &&
_regulator_is_enabled(rdev))
regulator->always_on = true;
mutex_unlock(&rdev->mutex);
return regulator;
link_name_err:
@ -1169,26 +1186,52 @@ static int _regulator_get_enable_time(struct regulator_dev *rdev)
}
static struct regulator_dev *regulator_dev_lookup(struct device *dev,
const char *supply)
const char *supply,
int *ret)
{
struct regulator_dev *r;
struct device_node *node;
struct regulator_map *map;
const char *devname = NULL;
/* first do a dt based lookup */
if (dev && dev->of_node) {
node = of_get_regulator(dev, supply);
if (node)
if (node) {
list_for_each_entry(r, &regulator_list, list)
if (r->dev.parent &&
node == r->dev.of_node)
return r;
} else {
/*
* If we couldn't even get the node then it's
* not just that the device didn't register
* yet, there's no node and we'll never
* succeed.
*/
*ret = -ENODEV;
}
}
/* if not found, try doing it non-dt way */
if (dev)
devname = dev_name(dev);
list_for_each_entry(r, &regulator_list, list)
if (strcmp(rdev_get_name(r), supply) == 0)
return r;
list_for_each_entry(map, &regulator_map_list, list) {
/* If the mapping has a device set up it must match */
if (map->dev_name &&
(!devname || strcmp(map->dev_name, devname)))
continue;
if (strcmp(map->supply, supply) == 0)
return map->regulator;
}
return NULL;
}
@ -1197,7 +1240,6 @@ static struct regulator *_regulator_get(struct device *dev, const char *id,
int exclusive)
{
struct regulator_dev *rdev;
struct regulator_map *map;
struct regulator *regulator = ERR_PTR(-EPROBE_DEFER);
const char *devname = NULL;
int ret;
@ -1212,22 +1254,10 @@ static struct regulator *_regulator_get(struct device *dev, const char *id,
mutex_lock(&regulator_list_mutex);
rdev = regulator_dev_lookup(dev, id);
rdev = regulator_dev_lookup(dev, id, &ret);
if (rdev)
goto found;
list_for_each_entry(map, &regulator_map_list, list) {
/* If the mapping has a device set up it must match */
if (map->dev_name &&
(!devname || strcmp(map->dev_name, devname)))
continue;
if (strcmp(map->supply, id) == 0) {
rdev = map->regulator;
goto found;
}
}
if (board_wants_dummy_regulator) {
rdev = dummy_regulator_rdev;
goto found;
@ -1435,17 +1465,6 @@ void devm_regulator_put(struct regulator *regulator)
}
EXPORT_SYMBOL_GPL(devm_regulator_put);
static int _regulator_can_change_status(struct regulator_dev *rdev)
{
if (!rdev->constraints)
return 0;
if (rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_STATUS)
return 1;
else
return 0;
}
/* locks held by regulator_enable() */
static int _regulator_enable(struct regulator_dev *rdev)
{
@ -1525,6 +1544,9 @@ int regulator_enable(struct regulator *regulator)
struct regulator_dev *rdev = regulator->rdev;
int ret = 0;
if (regulator->always_on)
return 0;
if (rdev->supply) {
ret = regulator_enable(rdev->supply);
if (ret != 0)
@ -1603,6 +1625,9 @@ int regulator_disable(struct regulator *regulator)
struct regulator_dev *rdev = regulator->rdev;
int ret = 0;
if (regulator->always_on)
return 0;
mutex_lock(&rdev->mutex);
ret = _regulator_disable(rdev);
mutex_unlock(&rdev->mutex);
@ -1711,6 +1736,9 @@ int regulator_disable_deferred(struct regulator *regulator, int ms)
struct regulator_dev *rdev = regulator->rdev;
int ret;
if (regulator->always_on)
return 0;
mutex_lock(&rdev->mutex);
rdev->deferred_disables++;
mutex_unlock(&rdev->mutex);
@ -1724,6 +1752,61 @@ int regulator_disable_deferred(struct regulator *regulator, int ms)
}
EXPORT_SYMBOL_GPL(regulator_disable_deferred);
/**
* regulator_is_enabled_regmap - standard is_enabled() for regmap users
*
* @rdev: regulator to operate on
*
* Regulators that use regmap for their register I/O can set the
* enable_reg and enable_mask fields in their descriptor and then use
* this as their is_enabled operation, saving some code.
*/
int regulator_is_enabled_regmap(struct regulator_dev *rdev)
{
unsigned int val;
int ret;
ret = regmap_read(rdev->regmap, rdev->desc->enable_reg, &val);
if (ret != 0)
return ret;
return (val & rdev->desc->enable_mask) != 0;
}
EXPORT_SYMBOL_GPL(regulator_is_enabled_regmap);
/**
* regulator_enable_regmap - standard enable() for regmap users
*
* @rdev: regulator to operate on
*
* Regulators that use regmap for their register I/O can set the
* enable_reg and enable_mask fields in their descriptor and then use
* this as their enable() operation, saving some code.
*/
int regulator_enable_regmap(struct regulator_dev *rdev)
{
return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
rdev->desc->enable_mask,
rdev->desc->enable_mask);
}
EXPORT_SYMBOL_GPL(regulator_enable_regmap);
/**
* regulator_disable_regmap - standard disable() for regmap users
*
* @rdev: regulator to operate on
*
* Regulators that use regmap for their register I/O can set the
* enable_reg and enable_mask fields in their descriptor and then use
* this as their disable() operation, saving some code.
*/
int regulator_disable_regmap(struct regulator_dev *rdev)
{
return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
rdev->desc->enable_mask, 0);
}
EXPORT_SYMBOL_GPL(regulator_disable_regmap);
static int _regulator_is_enabled(struct regulator_dev *rdev)
{
/* If we don't know then assume that the regulator is always on */
@ -1749,6 +1832,9 @@ int regulator_is_enabled(struct regulator *regulator)
{
int ret;
if (regulator->always_on)
return 1;
mutex_lock(&regulator->rdev->mutex);
ret = _regulator_is_enabled(regulator->rdev);
mutex_unlock(&regulator->rdev->mutex);
@ -1837,29 +1923,85 @@ int regulator_is_supported_voltage(struct regulator *regulator,
}
EXPORT_SYMBOL_GPL(regulator_is_supported_voltage);
/**
* regulator_get_voltage_sel_regmap - standard get_voltage_sel for regmap users
*
* @rdev: regulator to operate on
*
* Regulators that use regmap for their register I/O can set the
* vsel_reg and vsel_mask fields in their descriptor and then use this
* as their get_voltage_vsel operation, saving some code.
*/
int regulator_get_voltage_sel_regmap(struct regulator_dev *rdev)
{
unsigned int val;
int ret;
ret = regmap_read(rdev->regmap, rdev->desc->vsel_reg, &val);
if (ret != 0)
return ret;
val &= rdev->desc->vsel_mask;
val >>= ffs(rdev->desc->vsel_mask) - 1;
return val;
}
EXPORT_SYMBOL_GPL(regulator_get_voltage_sel_regmap);
/**
* regulator_set_voltage_sel_regmap - standard set_voltage_sel for regmap users
*
* @rdev: regulator to operate on
* @sel: Selector to set
*
* Regulators that use regmap for their register I/O can set the
* vsel_reg and vsel_mask fields in their descriptor and then use this
* as their set_voltage_vsel operation, saving some code.
*/
int regulator_set_voltage_sel_regmap(struct regulator_dev *rdev, unsigned sel)
{
sel <<= ffs(rdev->desc->vsel_mask) - 1;
return regmap_update_bits(rdev->regmap, rdev->desc->vsel_reg,
rdev->desc->vsel_mask, sel);
}
EXPORT_SYMBOL_GPL(regulator_set_voltage_sel_regmap);
static int _regulator_do_set_voltage(struct regulator_dev *rdev,
int min_uV, int max_uV)
{
int ret;
int delay = 0;
unsigned int selector;
int old_selector = -1;
int best_val = INT_MAX;
trace_regulator_set_voltage(rdev_get_name(rdev), min_uV, max_uV);
min_uV += rdev->constraints->uV_offset;
max_uV += rdev->constraints->uV_offset;
/*
* If we can't obtain the old selector there is not enough
* info to call set_voltage_time_sel().
*/
if (rdev->desc->ops->set_voltage_time_sel &&
rdev->desc->ops->get_voltage_sel) {
old_selector = rdev->desc->ops->get_voltage_sel(rdev);
if (old_selector < 0)
return old_selector;
}
if (rdev->desc->ops->set_voltage) {
ret = rdev->desc->ops->set_voltage(rdev, min_uV, max_uV,
&selector);
if (rdev->desc->ops->list_voltage)
selector = rdev->desc->ops->list_voltage(rdev,
best_val = rdev->desc->ops->list_voltage(rdev,
selector);
else
selector = -1;
best_val = -1;
} else if (rdev->desc->ops->set_voltage_sel) {
int best_val = INT_MAX;
int i;
selector = 0;
@ -1878,36 +2020,27 @@ static int _regulator_do_set_voltage(struct regulator_dev *rdev,
}
}
/*
* If we can't obtain the old selector there is not enough
* info to call set_voltage_time_sel().
*/
if (rdev->desc->ops->set_voltage_time_sel &&
rdev->desc->ops->get_voltage_sel) {
unsigned int old_selector = 0;
ret = rdev->desc->ops->get_voltage_sel(rdev);
if (ret < 0)
return ret;
old_selector = ret;
ret = rdev->desc->ops->set_voltage_time_sel(rdev,
old_selector, selector);
if (ret < 0)
rdev_warn(rdev, "set_voltage_time_sel() failed: %d\n", ret);
else
delay = ret;
}
if (best_val != INT_MAX) {
if (best_val != INT_MAX)
ret = rdev->desc->ops->set_voltage_sel(rdev, selector);
selector = best_val;
} else {
else
ret = -EINVAL;
}
} else {
ret = -EINVAL;
}
/* Call set_voltage_time_sel if successfully obtained old_selector */
if (ret == 0 && old_selector >= 0 &&
rdev->desc->ops->set_voltage_time_sel) {
delay = rdev->desc->ops->set_voltage_time_sel(rdev,
old_selector, selector);
if (delay < 0) {
rdev_warn(rdev, "set_voltage_time_sel() failed: %d\n",
delay);
delay = 0;
}
}
/* Insert any necessary delays */
if (delay >= 1000) {
mdelay(delay / 1000);
@ -1920,7 +2053,7 @@ static int _regulator_do_set_voltage(struct regulator_dev *rdev,
_notifier_call_chain(rdev, REGULATOR_EVENT_VOLTAGE_CHANGE,
NULL);
trace_regulator_set_voltage_complete(rdev_get_name(rdev), selector);
trace_regulator_set_voltage_complete(rdev_get_name(rdev), best_val);
return ret;
}
@ -2324,6 +2457,9 @@ int regulator_set_optimum_mode(struct regulator *regulator, int uA_load)
*/
ret = -EINVAL;
if (!rdev->desc->ops->set_mode)
goto out;
/* get output voltage */
output_uV = _regulator_get_voltage(rdev);
if (output_uV <= 0) {
@ -2525,9 +2661,13 @@ int regulator_bulk_enable(int num_consumers,
int i;
int ret = 0;
for (i = 0; i < num_consumers; i++)
async_schedule_domain(regulator_bulk_enable_async,
&consumers[i], &async_domain);
for (i = 0; i < num_consumers; i++) {
if (consumers[i].consumer->always_on)
consumers[i].ret = 0;
else
async_schedule_domain(regulator_bulk_enable_async,
&consumers[i], &async_domain);
}
async_synchronize_full_domain(&async_domain);
@ -2566,7 +2706,7 @@ int regulator_bulk_disable(int num_consumers,
struct regulator_bulk_data *consumers)
{
int i;
int ret;
int ret, r;
for (i = num_consumers - 1; i >= 0; --i) {
ret = regulator_disable(consumers[i].consumer);
@ -2578,8 +2718,12 @@ int regulator_bulk_disable(int num_consumers,
err:
pr_err("Failed to disable %s: %d\n", consumers[i].supply, ret);
for (++i; i < num_consumers; ++i)
regulator_enable(consumers[i].consumer);
for (++i; i < num_consumers; ++i) {
r = regulator_enable(consumers[i].consumer);
if (r != 0)
pr_err("Failed to reename %s: %d\n",
consumers[i].supply, r);
}
return ret;
}
@ -2756,10 +2900,6 @@ static int add_regulator_attributes(struct regulator_dev *rdev)
return status;
}
/* suspend mode constraints need multiple supporting methods */
if (!(ops->set_suspend_enable && ops->set_suspend_disable))
return status;
status = device_create_file(dev, &dev_attr_suspend_standby_state);
if (status < 0)
return status;
@ -2820,28 +2960,29 @@ static void rdev_init_debugfs(struct regulator_dev *rdev)
/**
* regulator_register - register regulator
* @regulator_desc: regulator to register
* @dev: struct device for the regulator
* @init_data: platform provided init data, passed through by driver
* @driver_data: private regulator data
* @of_node: OpenFirmware node to parse for device tree bindings (may be
* NULL).
* @config: runtime configuration for regulator
*
* Called by regulator drivers to register a regulator.
* Returns 0 on success.
*/
struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,
struct device *dev, const struct regulator_init_data *init_data,
void *driver_data, struct device_node *of_node)
struct regulator_dev *
regulator_register(const struct regulator_desc *regulator_desc,
const struct regulator_config *config)
{
const struct regulation_constraints *constraints = NULL;
const struct regulator_init_data *init_data;
static atomic_t regulator_no = ATOMIC_INIT(0);
struct regulator_dev *rdev;
struct device *dev;
int ret, i;
const char *supply = NULL;
if (regulator_desc == NULL)
if (regulator_desc == NULL || config == NULL)
return ERR_PTR(-EINVAL);
dev = config->dev;
WARN_ON(!dev);
if (regulator_desc->name == NULL || regulator_desc->ops == NULL)
return ERR_PTR(-EINVAL);
@ -2865,6 +3006,8 @@ struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,
return ERR_PTR(-EINVAL);
}
init_data = config->init_data;
rdev = kzalloc(sizeof(struct regulator_dev), GFP_KERNEL);
if (rdev == NULL)
return ERR_PTR(-ENOMEM);
@ -2872,9 +3015,10 @@ struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,
mutex_lock(&regulator_list_mutex);
mutex_init(&rdev->mutex);
rdev->reg_data = driver_data;
rdev->reg_data = config->driver_data;
rdev->owner = regulator_desc->owner;
rdev->desc = regulator_desc;
rdev->regmap = config->regmap;
INIT_LIST_HEAD(&rdev->consumer_list);
INIT_LIST_HEAD(&rdev->list);
BLOCKING_INIT_NOTIFIER_HEAD(&rdev->notifier);
@ -2889,7 +3033,7 @@ struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,
/* register with sysfs */
rdev->dev.class = &regulator_class;
rdev->dev.of_node = of_node;
rdev->dev.of_node = config->of_node;
rdev->dev.parent = dev;
dev_set_name(&rdev->dev, "regulator.%d",
atomic_inc_return(&regulator_no) - 1);
@ -2922,7 +3066,7 @@ struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,
if (supply) {
struct regulator_dev *r;
r = regulator_dev_lookup(dev, supply);
r = regulator_dev_lookup(dev, supply, &ret);
if (!r) {
dev_err(dev, "Failed to find supply %s\n", supply);

View File

@ -517,6 +517,7 @@ static int __devinit da903x_regulator_probe(struct platform_device *pdev)
{
struct da903x_regulator_info *ri = NULL;
struct regulator_dev *rdev;
struct regulator_config config = { };
ri = find_regulator_info(pdev->id);
if (ri == NULL) {
@ -536,8 +537,11 @@ static int __devinit da903x_regulator_probe(struct platform_device *pdev)
if (ri->desc.id == DA9030_ID_LDO1 || ri->desc.id == DA9030_ID_LDO15)
ri->desc.ops = &da9030_regulator_ldo1_15_ops;
rdev = regulator_register(&ri->desc, &pdev->dev,
pdev->dev.platform_data, ri, NULL);
config.dev = &pdev->dev;
config.init_data = pdev->dev.platform_data;
config.driver_data = ri;
rdev = regulator_register(&ri->desc, &config);
if (IS_ERR(rdev)) {
dev_err(&pdev->dev, "failed to register regulator %s\n",
ri->desc.name);

View File

@ -19,6 +19,9 @@
#include <linux/platform_device.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
#ifdef CONFIG_OF
#include <linux/regulator/of_regulator.h>
#endif
#include <linux/mfd/da9052/da9052.h>
#include <linux/mfd/da9052/reg.h>
@ -37,6 +40,22 @@
#define DA9052_BUCK_ILIM_MASK_EVEN 0x0c
#define DA9052_BUCK_ILIM_MASK_ODD 0xc0
/* DA9052 REGULATOR IDs */
#define DA9052_ID_BUCK1 0
#define DA9052_ID_BUCK2 1
#define DA9052_ID_BUCK3 2
#define DA9052_ID_BUCK4 3
#define DA9052_ID_LDO1 4
#define DA9052_ID_LDO2 5
#define DA9052_ID_LDO3 6
#define DA9052_ID_LDO4 7
#define DA9052_ID_LDO5 8
#define DA9052_ID_LDO6 9
#define DA9052_ID_LDO7 10
#define DA9052_ID_LDO8 11
#define DA9052_ID_LDO9 12
#define DA9052_ID_LDO10 13
static const u32 da9052_current_limits[3][4] = {
{700000, 800000, 1000000, 1200000}, /* DA9052-BC BUCKs */
{1600000, 2000000, 2400000, 3000000}, /* DA9053-AA/Bx BUCK-CORE */
@ -50,8 +69,6 @@ struct da9052_regulator_info {
int step_uV;
int min_uV;
int max_uV;
unsigned char volt_shift;
unsigned char en_bit;
unsigned char activate_bit;
};
@ -70,42 +87,6 @@ static int verify_range(struct da9052_regulator_info *info,
return 0;
}
static int da9052_regulator_enable(struct regulator_dev *rdev)
{
struct da9052_regulator *regulator = rdev_get_drvdata(rdev);
struct da9052_regulator_info *info = regulator->info;
int offset = rdev_get_id(rdev);
return da9052_reg_update(regulator->da9052,
DA9052_BUCKCORE_REG + offset,
1 << info->en_bit, 1 << info->en_bit);
}
static int da9052_regulator_disable(struct regulator_dev *rdev)
{
struct da9052_regulator *regulator = rdev_get_drvdata(rdev);
struct da9052_regulator_info *info = regulator->info;
int offset = rdev_get_id(rdev);
return da9052_reg_update(regulator->da9052,
DA9052_BUCKCORE_REG + offset,
1 << info->en_bit, 0);
}
static int da9052_regulator_is_enabled(struct regulator_dev *rdev)
{
struct da9052_regulator *regulator = rdev_get_drvdata(rdev);
struct da9052_regulator_info *info = regulator->info;
int offset = rdev_get_id(rdev);
int ret;
ret = da9052_reg_read(regulator->da9052, DA9052_BUCKCORE_REG + offset);
if (ret < 0)
return ret;
return ret & (1 << info->en_bit);
}
static int da9052_dcdc_get_current_limit(struct regulator_dev *rdev)
{
struct da9052_regulator *regulator = rdev_get_drvdata(rdev);
@ -173,36 +154,23 @@ static int da9052_dcdc_set_current_limit(struct regulator_dev *rdev, int min_uA,
reg_val << 6);
}
static int da9052_list_buckperi_voltage(struct regulator_dev *rdev,
unsigned int selector)
{
struct da9052_regulator *regulator = rdev_get_drvdata(rdev);
struct da9052_regulator_info *info = regulator->info;
int volt_uV;
if ((regulator->da9052->chip_id == DA9052) &&
(selector >= DA9052_BUCK_PERI_REG_MAP_UPTO_3uV)) {
volt_uV = ((DA9052_BUCK_PERI_REG_MAP_UPTO_3uV * info->step_uV)
+ info->min_uV);
volt_uV += (selector - DA9052_BUCK_PERI_REG_MAP_UPTO_3uV)
* (DA9052_BUCK_PERI_3uV_STEP);
} else
volt_uV = (selector * info->step_uV) + info->min_uV;
if (volt_uV > info->max_uV)
return -EINVAL;
return volt_uV;
}
static int da9052_list_voltage(struct regulator_dev *rdev,
unsigned int selector)
{
struct da9052_regulator *regulator = rdev_get_drvdata(rdev);
struct da9052_regulator_info *info = regulator->info;
int id = rdev_get_id(rdev);
int volt_uV;
volt_uV = info->min_uV + info->step_uV * selector;
if ((id == DA9052_ID_BUCK4) && (regulator->da9052->chip_id == DA9052)
&& (selector >= DA9052_BUCK_PERI_REG_MAP_UPTO_3uV)) {
volt_uV = ((DA9052_BUCK_PERI_REG_MAP_UPTO_3uV * info->step_uV)
+ info->min_uV);
volt_uV += (selector - DA9052_BUCK_PERI_REG_MAP_UPTO_3uV)
* (DA9052_BUCK_PERI_3uV_STEP);
} else {
volt_uV = (selector * info->step_uV) + info->min_uV;
}
if (volt_uV > info->max_uV)
return -EINVAL;
@ -210,13 +178,13 @@ static int da9052_list_voltage(struct regulator_dev *rdev,
return volt_uV;
}
static int da9052_regulator_set_voltage_int(struct regulator_dev *rdev,
static int da9052_regulator_set_voltage(struct regulator_dev *rdev,
int min_uV, int max_uV,
unsigned int *selector)
{
struct da9052_regulator *regulator = rdev_get_drvdata(rdev);
struct da9052_regulator_info *info = regulator->info;
int offset = rdev_get_id(rdev);
int id = rdev_get_id(rdev);
int ret;
ret = verify_range(info, min_uV, max_uV);
@ -226,281 +194,135 @@ static int da9052_regulator_set_voltage_int(struct regulator_dev *rdev,
if (min_uV < info->min_uV)
min_uV = info->min_uV;
*selector = DIV_ROUND_UP(min_uV - info->min_uV, info->step_uV);
if ((id == DA9052_ID_BUCK4) && (regulator->da9052->chip_id == DA9052)
&& (min_uV >= DA9052_CONST_3uV)) {
*selector = DA9052_BUCK_PERI_REG_MAP_UPTO_3uV +
DIV_ROUND_UP(min_uV - DA9052_CONST_3uV,
DA9052_BUCK_PERI_3uV_STEP);
} else {
*selector = DIV_ROUND_UP(min_uV - info->min_uV, info->step_uV);
}
ret = da9052_list_voltage(rdev, *selector);
if (ret < 0)
return ret;
return da9052_reg_update(regulator->da9052,
DA9052_BUCKCORE_REG + offset,
(1 << info->volt_shift) - 1, *selector);
}
static int da9052_set_ldo_voltage(struct regulator_dev *rdev,
int min_uV, int max_uV,
unsigned int *selector)
{
return da9052_regulator_set_voltage_int(rdev, min_uV, max_uV, selector);
}
static int da9052_set_ldo5_6_voltage(struct regulator_dev *rdev,
int min_uV, int max_uV,
unsigned int *selector)
{
struct da9052_regulator *regulator = rdev_get_drvdata(rdev);
struct da9052_regulator_info *info = regulator->info;
int ret;
ret = da9052_regulator_set_voltage_int(rdev, min_uV, max_uV, selector);
ret = da9052_reg_update(regulator->da9052, rdev->desc->vsel_reg,
rdev->desc->vsel_mask, *selector);
if (ret < 0)
return ret;
/* Some LDOs are DVC controlled which requires enabling of
* the LDO activate bit to implment the changes on the
* LDO output.
*/
return da9052_reg_update(regulator->da9052, DA9052_SUPPLY_REG,
info->activate_bit, info->activate_bit);
}
static int da9052_set_dcdc_voltage(struct regulator_dev *rdev,
int min_uV, int max_uV,
unsigned int *selector)
{
struct da9052_regulator *regulator = rdev_get_drvdata(rdev);
struct da9052_regulator_info *info = regulator->info;
int ret;
ret = da9052_regulator_set_voltage_int(rdev, min_uV, max_uV, selector);
if (ret < 0)
return ret;
/* Some DCDCs are DVC controlled which requires enabling of
* the DCDC activate bit to implment the changes on the
* DCDC output.
*/
return da9052_reg_update(regulator->da9052, DA9052_SUPPLY_REG,
info->activate_bit, info->activate_bit);
}
static int da9052_get_regulator_voltage_sel(struct regulator_dev *rdev)
{
struct da9052_regulator *regulator = rdev_get_drvdata(rdev);
struct da9052_regulator_info *info = regulator->info;
int offset = rdev_get_id(rdev);
int ret;
ret = da9052_reg_read(regulator->da9052, DA9052_BUCKCORE_REG + offset);
if (ret < 0)
return ret;
ret &= ((1 << info->volt_shift) - 1);
/* Some LDOs and DCDCs are DVC controlled which requires enabling of
* the activate bit to implment the changes on the output.
*/
switch (id) {
case DA9052_ID_BUCK1:
case DA9052_ID_BUCK2:
case DA9052_ID_BUCK3:
case DA9052_ID_LDO2:
case DA9052_ID_LDO3:
ret = da9052_reg_update(regulator->da9052, DA9052_SUPPLY_REG,
info->activate_bit, info->activate_bit);
break;
}
return ret;
}
static int da9052_set_buckperi_voltage(struct regulator_dev *rdev, int min_uV,
int max_uV, unsigned int *selector)
{
struct da9052_regulator *regulator = rdev_get_drvdata(rdev);
struct da9052_regulator_info *info = regulator->info;
int offset = rdev_get_id(rdev);
int ret;
ret = verify_range(info, min_uV, max_uV);
if (ret < 0)
return ret;
if (min_uV < info->min_uV)
min_uV = info->min_uV;
if ((regulator->da9052->chip_id == DA9052) &&
(min_uV >= DA9052_CONST_3uV))
*selector = DA9052_BUCK_PERI_REG_MAP_UPTO_3uV +
DIV_ROUND_UP(min_uV - DA9052_CONST_3uV,
DA9052_BUCK_PERI_3uV_STEP);
else
*selector = DIV_ROUND_UP(min_uV - info->min_uV, info->step_uV);
ret = da9052_list_buckperi_voltage(rdev, *selector);
if (ret < 0)
return ret;
return da9052_reg_update(regulator->da9052,
DA9052_BUCKCORE_REG + offset,
(1 << info->volt_shift) - 1, *selector);
}
static int da9052_get_buckperi_voltage_sel(struct regulator_dev *rdev)
{
struct da9052_regulator *regulator = rdev_get_drvdata(rdev);
struct da9052_regulator_info *info = regulator->info;
int offset = rdev_get_id(rdev);
int ret;
ret = da9052_reg_read(regulator->da9052, DA9052_BUCKCORE_REG + offset);
if (ret < 0)
return ret;
ret &= ((1 << info->volt_shift) - 1);
return ret;
}
static struct regulator_ops da9052_buckperi_ops = {
.list_voltage = da9052_list_buckperi_voltage,
.get_voltage_sel = da9052_get_buckperi_voltage_sel,
.set_voltage = da9052_set_buckperi_voltage,
.get_current_limit = da9052_dcdc_get_current_limit,
.set_current_limit = da9052_dcdc_set_current_limit,
.is_enabled = da9052_regulator_is_enabled,
.enable = da9052_regulator_enable,
.disable = da9052_regulator_disable,
};
static struct regulator_ops da9052_dcdc_ops = {
.set_voltage = da9052_set_dcdc_voltage,
.set_voltage = da9052_regulator_set_voltage,
.get_current_limit = da9052_dcdc_get_current_limit,
.set_current_limit = da9052_dcdc_set_current_limit,
.list_voltage = da9052_list_voltage,
.get_voltage_sel = da9052_get_regulator_voltage_sel,
.is_enabled = da9052_regulator_is_enabled,
.enable = da9052_regulator_enable,
.disable = da9052_regulator_disable,
};
static struct regulator_ops da9052_ldo5_6_ops = {
.set_voltage = da9052_set_ldo5_6_voltage,
.list_voltage = da9052_list_voltage,
.get_voltage_sel = da9052_get_regulator_voltage_sel,
.is_enabled = da9052_regulator_is_enabled,
.enable = da9052_regulator_enable,
.disable = da9052_regulator_disable,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.is_enabled = regulator_is_enabled_regmap,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
};
static struct regulator_ops da9052_ldo_ops = {
.set_voltage = da9052_set_ldo_voltage,
.set_voltage = da9052_regulator_set_voltage,
.list_voltage = da9052_list_voltage,
.get_voltage_sel = da9052_get_regulator_voltage_sel,
.is_enabled = da9052_regulator_is_enabled,
.enable = da9052_regulator_enable,
.disable = da9052_regulator_disable,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.is_enabled = regulator_is_enabled_regmap,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
};
#define DA9052_LDO5_6(_id, step, min, max, sbits, ebits, abits) \
{\
.reg_desc = {\
.name = "LDO" #_id,\
.ops = &da9052_ldo5_6_ops,\
.type = REGULATOR_VOLTAGE,\
.id = _id,\
.n_voltages = (max - min) / step + 1, \
.owner = THIS_MODULE,\
},\
.min_uV = (min) * 1000,\
.max_uV = (max) * 1000,\
.step_uV = (step) * 1000,\
.volt_shift = (sbits),\
.en_bit = (ebits),\
.activate_bit = (abits),\
}
#define DA9052_LDO(_id, step, min, max, sbits, ebits, abits) \
{\
.reg_desc = {\
.name = "LDO" #_id,\
.name = #_id,\
.ops = &da9052_ldo_ops,\
.type = REGULATOR_VOLTAGE,\
.id = _id,\
.id = DA9052_ID_##_id,\
.n_voltages = (max - min) / step + 1, \
.owner = THIS_MODULE,\
.vsel_reg = DA9052_BUCKCORE_REG + DA9052_ID_##_id, \
.vsel_mask = (1 << (sbits)) - 1,\
.enable_reg = DA9052_BUCKCORE_REG + DA9052_ID_##_id, \
.enable_mask = 1 << (ebits),\
},\
.min_uV = (min) * 1000,\
.max_uV = (max) * 1000,\
.step_uV = (step) * 1000,\
.volt_shift = (sbits),\
.en_bit = (ebits),\
.activate_bit = (abits),\
}
#define DA9052_DCDC(_id, step, min, max, sbits, ebits, abits) \
{\
.reg_desc = {\
.name = "BUCK" #_id,\
.name = #_id,\
.ops = &da9052_dcdc_ops,\
.type = REGULATOR_VOLTAGE,\
.id = _id,\
.id = DA9052_ID_##_id,\
.n_voltages = (max - min) / step + 1, \
.owner = THIS_MODULE,\
.vsel_reg = DA9052_BUCKCORE_REG + DA9052_ID_##_id, \
.vsel_mask = (1 << (sbits)) - 1,\
.enable_reg = DA9052_BUCKCORE_REG + DA9052_ID_##_id, \
.enable_mask = 1 << (ebits),\
},\
.min_uV = (min) * 1000,\
.max_uV = (max) * 1000,\
.step_uV = (step) * 1000,\
.volt_shift = (sbits),\
.en_bit = (ebits),\
.activate_bit = (abits),\
}
#define DA9052_BUCKPERI(_id, step, min, max, sbits, ebits, abits) \
{\
.reg_desc = {\
.name = "BUCK" #_id,\
.ops = &da9052_buckperi_ops,\
.type = REGULATOR_VOLTAGE,\
.id = _id,\
.n_voltages = (max - min) / step + 1, \
.owner = THIS_MODULE,\
},\
.min_uV = (min) * 1000,\
.max_uV = (max) * 1000,\
.step_uV = (step) * 1000,\
.volt_shift = (sbits),\
.en_bit = (ebits),\
.activate_bit = (abits),\
}
static struct da9052_regulator_info da9052_regulator_info[] = {
/* Buck1 - 4 */
DA9052_DCDC(0, 25, 500, 2075, 6, 6, DA9052_SUPPLY_VBCOREGO),
DA9052_DCDC(1, 25, 500, 2075, 6, 6, DA9052_SUPPLY_VBPROGO),
DA9052_DCDC(2, 25, 925, 2500, 6, 6, DA9052_SUPPLY_VBMEMGO),
DA9052_BUCKPERI(3, 50, 1800, 3600, 5, 6, 0),
/* LD01 - LDO10 */
DA9052_LDO(4, 50, 600, 1800, 5, 6, 0),
DA9052_LDO5_6(5, 25, 600, 1800, 6, 6, DA9052_SUPPLY_VLDO2GO),
DA9052_LDO5_6(6, 25, 1725, 3300, 6, 6, DA9052_SUPPLY_VLDO3GO),
DA9052_LDO(7, 25, 1725, 3300, 6, 6, 0),
DA9052_LDO(8, 50, 1200, 3600, 6, 6, 0),
DA9052_LDO(9, 50, 1200, 3600, 6, 6, 0),
DA9052_LDO(10, 50, 1200, 3600, 6, 6, 0),
DA9052_LDO(11, 50, 1200, 3600, 6, 6, 0),
DA9052_LDO(12, 50, 1250, 3650, 6, 6, 0),
DA9052_LDO(13, 50, 1200, 3600, 6, 6, 0),
DA9052_DCDC(BUCK1, 25, 500, 2075, 6, 6, DA9052_SUPPLY_VBCOREGO),
DA9052_DCDC(BUCK2, 25, 500, 2075, 6, 6, DA9052_SUPPLY_VBPROGO),
DA9052_DCDC(BUCK3, 25, 925, 2500, 6, 6, DA9052_SUPPLY_VBMEMGO),
DA9052_DCDC(BUCK4, 50, 1800, 3600, 5, 6, 0),
DA9052_LDO(LDO1, 50, 600, 1800, 5, 6, 0),
DA9052_LDO(LDO2, 25, 600, 1800, 6, 6, DA9052_SUPPLY_VLDO2GO),
DA9052_LDO(LDO3, 25, 1725, 3300, 6, 6, DA9052_SUPPLY_VLDO3GO),
DA9052_LDO(LDO4, 25, 1725, 3300, 6, 6, 0),
DA9052_LDO(LDO5, 50, 1200, 3600, 6, 6, 0),
DA9052_LDO(LDO6, 50, 1200, 3600, 6, 6, 0),
DA9052_LDO(LDO7, 50, 1200, 3600, 6, 6, 0),
DA9052_LDO(LDO8, 50, 1200, 3600, 6, 6, 0),
DA9052_LDO(LDO9, 50, 1250, 3650, 6, 6, 0),
DA9052_LDO(LDO10, 50, 1200, 3600, 6, 6, 0),
};
static struct da9052_regulator_info da9053_regulator_info[] = {
/* Buck1 - 4 */
DA9052_DCDC(0, 25, 500, 2075, 6, 6, DA9052_SUPPLY_VBCOREGO),
DA9052_DCDC(1, 25, 500, 2075, 6, 6, DA9052_SUPPLY_VBPROGO),
DA9052_DCDC(2, 25, 925, 2500, 6, 6, DA9052_SUPPLY_VBMEMGO),
DA9052_BUCKPERI(3, 25, 925, 2500, 6, 6, 0),
/* LD01 - LDO10 */
DA9052_LDO(4, 50, 600, 1800, 5, 6, 0),
DA9052_LDO5_6(5, 25, 600, 1800, 6, 6, DA9052_SUPPLY_VLDO2GO),
DA9052_LDO5_6(6, 25, 1725, 3300, 6, 6, DA9052_SUPPLY_VLDO3GO),
DA9052_LDO(7, 25, 1725, 3300, 6, 6, 0),
DA9052_LDO(8, 50, 1200, 3600, 6, 6, 0),
DA9052_LDO(9, 50, 1200, 3600, 6, 6, 0),
DA9052_LDO(10, 50, 1200, 3600, 6, 6, 0),
DA9052_LDO(11, 50, 1200, 3600, 6, 6, 0),
DA9052_LDO(12, 50, 1250, 3650, 6, 6, 0),
DA9052_LDO(13, 50, 1200, 3600, 6, 6, 0),
DA9052_DCDC(BUCK1, 25, 500, 2075, 6, 6, DA9052_SUPPLY_VBCOREGO),
DA9052_DCDC(BUCK2, 25, 500, 2075, 6, 6, DA9052_SUPPLY_VBPROGO),
DA9052_DCDC(BUCK3, 25, 925, 2500, 6, 6, DA9052_SUPPLY_VBMEMGO),
DA9052_DCDC(BUCK4, 25, 925, 2500, 6, 6, 0),
DA9052_LDO(LDO1, 50, 600, 1800, 5, 6, 0),
DA9052_LDO(LDO2, 25, 600, 1800, 6, 6, DA9052_SUPPLY_VLDO2GO),
DA9052_LDO(LDO3, 25, 1725, 3300, 6, 6, DA9052_SUPPLY_VLDO3GO),
DA9052_LDO(LDO4, 25, 1725, 3300, 6, 6, 0),
DA9052_LDO(LDO5, 50, 1200, 3600, 6, 6, 0),
DA9052_LDO(LDO6, 50, 1200, 3600, 6, 6, 0),
DA9052_LDO(LDO7, 50, 1200, 3600, 6, 6, 0),
DA9052_LDO(LDO8, 50, 1200, 3600, 6, 6, 0),
DA9052_LDO(LDO9, 50, 1250, 3650, 6, 6, 0),
DA9052_LDO(LDO10, 50, 1200, 3600, 6, 6, 0),
};
static inline struct da9052_regulator_info *find_regulator_info(u8 chip_id,
@ -533,10 +355,10 @@ static inline struct da9052_regulator_info *find_regulator_info(u8 chip_id,
static int __devinit da9052_regulator_probe(struct platform_device *pdev)
{
struct regulator_config config = { };
struct da9052_regulator *regulator;
struct da9052 *da9052;
struct da9052_pdata *pdata;
int ret;
regulator = devm_kzalloc(&pdev->dev, sizeof(struct da9052_regulator),
GFP_KERNEL);
@ -551,26 +373,49 @@ static int __devinit da9052_regulator_probe(struct platform_device *pdev)
pdev->id);
if (regulator->info == NULL) {
dev_err(&pdev->dev, "invalid regulator ID specified\n");
ret = -EINVAL;
goto err;
return -EINVAL;
}
config.dev = &pdev->dev;
config.driver_data = regulator;
config.regmap = da9052->regmap;
if (pdata && pdata->regulators) {
config.init_data = pdata->regulators[pdev->id];
} else {
#ifdef CONFIG_OF
struct device_node *nproot = da9052->dev->of_node;
struct device_node *np;
if (!nproot)
return -ENODEV;
nproot = of_find_node_by_name(nproot, "regulators");
if (!nproot)
return -ENODEV;
for (np = of_get_next_child(nproot, NULL); !np;
np = of_get_next_child(nproot, np)) {
if (!of_node_cmp(np->name,
regulator->info->reg_desc.name)) {
config.init_data = of_get_regulator_init_data(
&pdev->dev, np);
break;
}
}
#endif
}
regulator->rdev = regulator_register(&regulator->info->reg_desc,
&pdev->dev,
pdata->regulators[pdev->id],
regulator, NULL);
&config);
if (IS_ERR(regulator->rdev)) {
dev_err(&pdev->dev, "failed to register regulator %s\n",
regulator->info->reg_desc.name);
ret = PTR_ERR(regulator->rdev);
goto err;
return PTR_ERR(regulator->rdev);
}
platform_set_drvdata(pdev, regulator);
return 0;
err:
devm_kfree(&pdev->dev, regulator);
return ret;
}
static int __devexit da9052_regulator_remove(struct platform_device *pdev)
@ -578,8 +423,6 @@ static int __devexit da9052_regulator_remove(struct platform_device *pdev)
struct da9052_regulator *regulator = platform_get_drvdata(pdev);
regulator_unregister(regulator->rdev);
devm_kfree(&pdev->dev, regulator);
return 0;
}

View File

@ -414,6 +414,7 @@ static int __devinit db8500_regulator_probe(struct platform_device *pdev)
{
struct regulator_init_data *db8500_init_data =
dev_get_platdata(&pdev->dev);
struct regulator_config config = { };
int i, err;
/* register all regulators */
@ -425,9 +426,12 @@ static int __devinit db8500_regulator_probe(struct platform_device *pdev)
info = &dbx500_regulator_info[i];
info->dev = &pdev->dev;
config.dev = &pdev->dev;
config.init_data = init_data;
config.driver_data = info;
/* register with the regulator framework */
info->rdev = regulator_register(&info->desc, &pdev->dev,
init_data, info, NULL);
info->rdev = regulator_register(&info->desc, &config);
if (IS_ERR(info->rdev)) {
err = PTR_ERR(info->rdev);
dev_err(&pdev->dev, "failed to register %s: err %i\n",

View File

@ -39,10 +39,13 @@ static struct regulator_desc dummy_desc = {
static int __devinit dummy_regulator_probe(struct platform_device *pdev)
{
struct regulator_config config = { };
int ret;
dummy_regulator_rdev = regulator_register(&dummy_desc, NULL,
&dummy_initdata, NULL, NULL);
config.dev = &pdev->dev;
config.init_data = &dummy_initdata;
dummy_regulator_rdev = regulator_register(&dummy_desc, &config);
if (IS_ERR(dummy_regulator_rdev)) {
ret = PTR_ERR(dummy_regulator_rdev);
pr_err("Failed to register regulator: %d\n", ret);

View File

@ -105,10 +105,8 @@ 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 = true;
}
gpio_set_value_cansleep(data->gpio, data->enable_high);
data->is_enabled = true;
return 0;
}
@ -117,10 +115,8 @@ 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 = false;
}
gpio_set_value_cansleep(data->gpio, !data->enable_high);
data->is_enabled = false;
return 0;
}
@ -153,7 +149,7 @@ static int fixed_voltage_list_voltage(struct regulator_dev *dev,
return data->microvolts;
}
static struct regulator_ops fixed_voltage_ops = {
static struct regulator_ops fixed_voltage_gpio_ops = {
.is_enabled = fixed_voltage_is_enabled,
.enable = fixed_voltage_enable,
.disable = fixed_voltage_disable,
@ -162,10 +158,16 @@ static struct regulator_ops fixed_voltage_ops = {
.list_voltage = fixed_voltage_list_voltage,
};
static struct regulator_ops fixed_voltage_ops = {
.get_voltage = fixed_voltage_get_voltage,
.list_voltage = fixed_voltage_list_voltage,
};
static int __devinit reg_fixed_voltage_probe(struct platform_device *pdev)
{
struct fixed_voltage_config *config;
struct fixed_voltage_data *drvdata;
struct regulator_config cfg = { };
int ret;
if (pdev->dev.of_node)
@ -176,7 +178,8 @@ static int __devinit reg_fixed_voltage_probe(struct platform_device *pdev)
if (!config)
return -ENOMEM;
drvdata = kzalloc(sizeof(struct fixed_voltage_data), GFP_KERNEL);
drvdata = devm_kzalloc(&pdev->dev, sizeof(struct fixed_voltage_data),
GFP_KERNEL);
if (drvdata == NULL) {
dev_err(&pdev->dev, "Failed to allocate device data\n");
ret = -ENOMEM;
@ -191,7 +194,6 @@ static int __devinit reg_fixed_voltage_probe(struct platform_device *pdev)
}
drvdata->desc.type = REGULATOR_VOLTAGE;
drvdata->desc.owner = THIS_MODULE;
drvdata->desc.ops = &fixed_voltage_ops;
if (config->microvolts)
drvdata->desc.n_voltages = 1;
@ -201,6 +203,7 @@ static int __devinit reg_fixed_voltage_probe(struct platform_device *pdev)
drvdata->startup_delay = config->startup_delay;
if (gpio_is_valid(config->gpio)) {
int gpio_flag;
drvdata->enable_high = config->enable_high;
/* FIXME: Remove below print warning
@ -218,7 +221,20 @@ static int __devinit reg_fixed_voltage_probe(struct platform_device *pdev)
dev_warn(&pdev->dev,
"using GPIO 0 for regulator enable control\n");
ret = gpio_request(config->gpio, config->supply_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;
gpio_flag = ret ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW;
if (config->gpio_is_open_drain)
gpio_flag |= GPIOF_OPEN_DRAIN;
ret = gpio_request_one(config->gpio, gpio_flag,
config->supply_name);
if (ret) {
dev_err(&pdev->dev,
"Could not obtain regulator enable GPIO %d: %d\n",
@ -226,31 +242,18 @@ static int __devinit reg_fixed_voltage_probe(struct platform_device *pdev)
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;
}
drvdata->desc.ops = &fixed_voltage_gpio_ops;
} else {
/* Regulator without GPIO control is considered
* always enabled
*/
drvdata->is_enabled = true;
drvdata->desc.ops = &fixed_voltage_ops;
}
drvdata->dev = regulator_register(&drvdata->desc, &pdev->dev,
config->init_data, drvdata,
pdev->dev.of_node);
cfg.dev = &pdev->dev;
cfg.init_data = config->init_data;
cfg.driver_data = drvdata;
cfg.of_node = pdev->dev.of_node;
drvdata->dev = regulator_register(&drvdata->desc, &cfg);
if (IS_ERR(drvdata->dev)) {
ret = PTR_ERR(drvdata->dev);
dev_err(&pdev->dev, "Failed to register regulator: %d\n", ret);
@ -270,7 +273,6 @@ err_gpio:
err_name:
kfree(drvdata->desc.name);
err:
kfree(drvdata);
return ret;
}
@ -282,7 +284,6 @@ static int __devexit reg_fixed_voltage_remove(struct platform_device *pdev)
if (gpio_is_valid(drvdata->gpio))
gpio_free(drvdata->gpio);
kfree(drvdata->desc.name);
kfree(drvdata);
return 0;
}

View File

@ -105,15 +105,15 @@ static int gpio_regulator_set_value(struct regulator_dev *dev,
int min, int max)
{
struct gpio_regulator_data *data = rdev_get_drvdata(dev);
int ptr, target, state;
int ptr, target, state, best_val = INT_MAX;
target = -1;
for (ptr = 0; ptr < data->nr_states; ptr++)
if (data->states[ptr].value >= min &&
if (data->states[ptr].value < best_val &&
data->states[ptr].value >= min &&
data->states[ptr].value <= max)
target = data->states[ptr].gpios;
if (target < 0)
if (best_val == INT_MAX)
return -EINVAL;
for (ptr = 0; ptr < data->nr_gpios; ptr++) {
@ -172,9 +172,11 @@ static int __devinit gpio_regulator_probe(struct platform_device *pdev)
{
struct gpio_regulator_config *config = pdev->dev.platform_data;
struct gpio_regulator_data *drvdata;
struct regulator_config cfg = { };
int ptr, ret, state;
drvdata = kzalloc(sizeof(struct gpio_regulator_data), GFP_KERNEL);
drvdata = devm_kzalloc(&pdev->dev, sizeof(struct gpio_regulator_data),
GFP_KERNEL);
if (drvdata == NULL) {
dev_err(&pdev->dev, "Failed to allocate device data\n");
return -ENOMEM;
@ -283,8 +285,11 @@ static int __devinit gpio_regulator_probe(struct platform_device *pdev)
}
drvdata->state = state;
drvdata->dev = regulator_register(&drvdata->desc, &pdev->dev,
config->init_data, drvdata, NULL);
cfg.dev = &pdev->dev;
cfg.init_data = config->init_data;
cfg.driver_data = &drvdata;
drvdata->dev = regulator_register(&drvdata->desc, &cfg);
if (IS_ERR(drvdata->dev)) {
ret = PTR_ERR(drvdata->dev);
dev_err(&pdev->dev, "Failed to register regulator: %d\n", ret);
@ -307,7 +312,6 @@ err_memgpio:
err_name:
kfree(drvdata->desc.name);
err:
kfree(drvdata);
return ret;
}
@ -326,7 +330,6 @@ static int __devexit gpio_regulator_remove(struct platform_device *pdev)
gpio_free(drvdata->enable_gpio);
kfree(drvdata->desc.name);
kfree(drvdata);
return 0;
}

View File

@ -112,7 +112,7 @@ static struct regulator_ops isl_fixed_ops = {
.list_voltage = isl6271a_list_fixed_voltage,
};
static struct regulator_desc isl_rd[] = {
static const struct regulator_desc isl_rd[] = {
{
.name = "Core Buck",
.id = 0,
@ -140,6 +140,7 @@ static struct regulator_desc isl_rd[] = {
static int __devinit isl6271a_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
struct regulator_config config = { };
struct regulator_init_data *init_data = i2c->dev.platform_data;
struct isl_pmic *pmic;
int err, i;
@ -147,12 +148,7 @@ static int __devinit isl6271a_probe(struct i2c_client *i2c,
if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
return -EIO;
if (!init_data) {
dev_err(&i2c->dev, "no platform data supplied\n");
return -EIO;
}
pmic = kzalloc(sizeof(struct isl_pmic), GFP_KERNEL);
pmic = devm_kzalloc(&i2c->dev, sizeof(struct isl_pmic), GFP_KERNEL);
if (!pmic)
return -ENOMEM;
@ -161,8 +157,14 @@ static int __devinit isl6271a_probe(struct i2c_client *i2c,
mutex_init(&pmic->mtx);
for (i = 0; i < 3; i++) {
pmic->rdev[i] = regulator_register(&isl_rd[i], &i2c->dev,
init_data, pmic, NULL);
config.dev = &i2c->dev;
if (i == 0)
config.init_data = init_data;
else
config.init_data = 0;
config.driver_data = pmic;
pmic->rdev[i] = regulator_register(&isl_rd[i], &config);
if (IS_ERR(pmic->rdev[i])) {
dev_err(&i2c->dev, "failed to register %s\n", id->name);
err = PTR_ERR(pmic->rdev[i]);
@ -177,8 +179,6 @@ static int __devinit isl6271a_probe(struct i2c_client *i2c,
error:
while (--i >= 0)
regulator_unregister(pmic->rdev[i]);
kfree(pmic);
return err;
}
@ -189,9 +189,6 @@ static int __devexit isl6271a_remove(struct i2c_client *i2c)
for (i = 0; i < 3; i++)
regulator_unregister(pmic->rdev[i]);
kfree(pmic);
return 0;
}

View File

@ -124,6 +124,10 @@ static const int *ldo_voltage_map[] = {
static int lp3971_ldo_list_voltage(struct regulator_dev *dev, unsigned index)
{
int ldo = rdev_get_id(dev) - LP3971_LDO1;
if (index > LDO_VOL_MAX_IDX)
return -EINVAL;
return 1000 * LDO_VOL_VALUE_MAP(ldo)[index];
}
@ -168,32 +172,15 @@ static int lp3971_ldo_get_voltage(struct regulator_dev *dev)
return 1000 * LDO_VOL_VALUE_MAP(ldo)[val];
}
static int lp3971_ldo_set_voltage(struct regulator_dev *dev,
int min_uV, int max_uV,
unsigned int *selector)
static int lp3971_ldo_set_voltage_sel(struct regulator_dev *dev,
unsigned int selector)
{
struct lp3971 *lp3971 = rdev_get_drvdata(dev);
int ldo = rdev_get_id(dev) - LP3971_LDO1;
int min_vol = min_uV / 1000, max_vol = max_uV / 1000;
const int *vol_map = LDO_VOL_VALUE_MAP(ldo);
u16 val;
if (min_vol < vol_map[LDO_VOL_MIN_IDX] ||
min_vol > vol_map[LDO_VOL_MAX_IDX])
return -EINVAL;
for (val = LDO_VOL_MIN_IDX; val <= LDO_VOL_MAX_IDX; val++)
if (vol_map[val] >= min_vol)
break;
if (val > LDO_VOL_MAX_IDX || vol_map[val] > max_vol)
return -EINVAL;
*selector = val;
return lp3971_set_bits(lp3971, LP3971_LDO_VOL_CONTR_REG(ldo),
LDO_VOL_CONTR_MASK << LDO_VOL_CONTR_SHIFT(ldo),
val << LDO_VOL_CONTR_SHIFT(ldo));
selector << LDO_VOL_CONTR_SHIFT(ldo));
}
static struct regulator_ops lp3971_ldo_ops = {
@ -202,11 +189,14 @@ static struct regulator_ops lp3971_ldo_ops = {
.enable = lp3971_ldo_enable,
.disable = lp3971_ldo_disable,
.get_voltage = lp3971_ldo_get_voltage,
.set_voltage = lp3971_ldo_set_voltage,
.set_voltage_sel = lp3971_ldo_set_voltage_sel,
};
static int lp3971_dcdc_list_voltage(struct regulator_dev *dev, unsigned index)
{
if (index < BUCK_TARGET_VOL_MIN_IDX || index > BUCK_TARGET_VOL_MAX_IDX)
return -EINVAL;
return 1000 * buck_voltage_map[index];
}
@ -259,33 +249,15 @@ static int lp3971_dcdc_get_voltage(struct regulator_dev *dev)
return val;
}
static int lp3971_dcdc_set_voltage(struct regulator_dev *dev,
int min_uV, int max_uV,
unsigned int *selector)
static int lp3971_dcdc_set_voltage_sel(struct regulator_dev *dev,
unsigned int selector)
{
struct lp3971 *lp3971 = rdev_get_drvdata(dev);
int buck = rdev_get_id(dev) - LP3971_DCDC1;
int min_vol = min_uV / 1000, max_vol = max_uV / 1000;
const int *vol_map = buck_voltage_map;
u16 val;
int ret;
if (min_vol < vol_map[BUCK_TARGET_VOL_MIN_IDX] ||
min_vol > vol_map[BUCK_TARGET_VOL_MAX_IDX])
return -EINVAL;
for (val = BUCK_TARGET_VOL_MIN_IDX; val <= BUCK_TARGET_VOL_MAX_IDX;
val++)
if (vol_map[val] >= min_vol)
break;
if (val > BUCK_TARGET_VOL_MAX_IDX || vol_map[val] > max_vol)
return -EINVAL;
*selector = val;
ret = lp3971_set_bits(lp3971, LP3971_BUCK_TARGET_VOL1_REG(buck),
BUCK_TARGET_VOL_MASK, val);
BUCK_TARGET_VOL_MASK, selector);
if (ret)
return ret;
@ -306,10 +278,10 @@ static struct regulator_ops lp3971_dcdc_ops = {
.enable = lp3971_dcdc_enable,
.disable = lp3971_dcdc_disable,
.get_voltage = lp3971_dcdc_get_voltage,
.set_voltage = lp3971_dcdc_set_voltage,
.set_voltage_sel = lp3971_dcdc_set_voltage_sel,
};
static struct regulator_desc regulators[] = {
static const struct regulator_desc regulators[] = {
{
.name = "LDO1",
.id = LP3971_LDO1,
@ -449,10 +421,15 @@ static int __devinit setup_regulators(struct lp3971 *lp3971,
/* Instantiate the regulators */
for (i = 0; i < pdata->num_regulators; i++) {
struct regulator_config config = { };
struct lp3971_regulator_subdev *reg = &pdata->regulators[i];
lp3971->rdev[i] = regulator_register(&regulators[reg->id],
lp3971->dev, reg->initdata, lp3971, NULL);
config.dev = lp3971->dev;
config.init_data = reg->initdata;
config.driver_data = lp3971;
lp3971->rdev[i] = regulator_register(&regulators[reg->id],
&config);
if (IS_ERR(lp3971->rdev[i])) {
err = PTR_ERR(lp3971->rdev[i]);
dev_err(lp3971->dev, "regulator init failed: %d\n",
@ -545,23 +522,7 @@ static struct i2c_driver lp3971_i2c_driver = {
.id_table = lp3971_i2c_id,
};
static int __init lp3971_module_init(void)
{
int ret;
ret = i2c_add_driver(&lp3971_i2c_driver);
if (ret != 0)
pr_err("Failed to register I2C driver: %d\n", ret);
return ret;
}
module_init(lp3971_module_init);
static void __exit lp3971_module_exit(void)
{
i2c_del_driver(&lp3971_i2c_driver);
}
module_exit(lp3971_module_exit);
module_i2c_driver(lp3971_i2c_driver);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Marek Szyprowski <m.szyprowski@samsung.com>");

View File

@ -245,6 +245,11 @@ static int lp3972_set_bits(struct lp3972 *lp3972, u8 reg, u16 mask, u16 val)
static int lp3972_ldo_list_voltage(struct regulator_dev *dev, unsigned index)
{
int ldo = rdev_get_id(dev) - LP3972_LDO1;
if (index < LP3972_LDO_VOL_MIN_IDX(ldo) ||
index > LP3972_LDO_VOL_MAX_IDX(ldo))
return -EINVAL;
return 1000 * LP3972_LDO_VOL_VALUE_MAP(ldo)[index];
}
@ -292,34 +297,16 @@ static int lp3972_ldo_get_voltage(struct regulator_dev *dev)
return 1000 * LP3972_LDO_VOL_VALUE_MAP(ldo)[val];
}
static int lp3972_ldo_set_voltage(struct regulator_dev *dev,
int min_uV, int max_uV,
unsigned int *selector)
static int lp3972_ldo_set_voltage_sel(struct regulator_dev *dev,
unsigned int selector)
{
struct lp3972 *lp3972 = rdev_get_drvdata(dev);
int ldo = rdev_get_id(dev) - LP3972_LDO1;
int min_vol = min_uV / 1000, max_vol = max_uV / 1000;
const int *vol_map = LP3972_LDO_VOL_VALUE_MAP(ldo);
u16 val;
int shift, ret;
if (min_vol < vol_map[LP3972_LDO_VOL_MIN_IDX(ldo)] ||
min_vol > vol_map[LP3972_LDO_VOL_MAX_IDX(ldo)])
return -EINVAL;
for (val = LP3972_LDO_VOL_MIN_IDX(ldo);
val <= LP3972_LDO_VOL_MAX_IDX(ldo); val++)
if (vol_map[val] >= min_vol)
break;
if (val > LP3972_LDO_VOL_MAX_IDX(ldo) || vol_map[val] > max_vol)
return -EINVAL;
*selector = val;
shift = LP3972_LDO_VOL_CONTR_SHIFT(ldo);
ret = lp3972_set_bits(lp3972, LP3972_LDO_VOL_CONTR_REG(ldo),
LP3972_LDO_VOL_MASK(ldo) << shift, val << shift);
LP3972_LDO_VOL_MASK(ldo) << shift, selector << shift);
if (ret)
return ret;
@ -355,12 +342,17 @@ static struct regulator_ops lp3972_ldo_ops = {
.enable = lp3972_ldo_enable,
.disable = lp3972_ldo_disable,
.get_voltage = lp3972_ldo_get_voltage,
.set_voltage = lp3972_ldo_set_voltage,
.set_voltage_sel = lp3972_ldo_set_voltage_sel,
};
static int lp3972_dcdc_list_voltage(struct regulator_dev *dev, unsigned index)
{
int buck = rdev_get_id(dev) - LP3972_DCDC1;
if (index < LP3972_BUCK_VOL_MIN_IDX(buck) ||
index > LP3972_BUCK_VOL_MAX_IDX(buck))
return -EINVAL;
return 1000 * buck_voltage_map[buck][index];
}
@ -419,34 +411,15 @@ static int lp3972_dcdc_get_voltage(struct regulator_dev *dev)
return val;
}
static int lp3972_dcdc_set_voltage(struct regulator_dev *dev,
int min_uV, int max_uV,
unsigned int *selector)
static int lp3972_dcdc_set_voltage_sel(struct regulator_dev *dev,
unsigned int selector)
{
struct lp3972 *lp3972 = rdev_get_drvdata(dev);
int buck = rdev_get_id(dev) - LP3972_DCDC1;
int min_vol = min_uV / 1000, max_vol = max_uV / 1000;
const int *vol_map = buck_voltage_map[buck];
u16 val;
int ret;
if (min_vol < vol_map[LP3972_BUCK_VOL_MIN_IDX(buck)] ||
min_vol > vol_map[LP3972_BUCK_VOL_MAX_IDX(buck)])
return -EINVAL;
for (val = LP3972_BUCK_VOL_MIN_IDX(buck);
val <= LP3972_BUCK_VOL_MAX_IDX(buck); val++)
if (vol_map[val] >= min_vol)
break;
if (val > LP3972_BUCK_VOL_MAX_IDX(buck) ||
vol_map[val] > max_vol)
return -EINVAL;
*selector = val;
ret = lp3972_set_bits(lp3972, LP3972_BUCK_VOL1_REG(buck),
LP3972_BUCK_VOL_MASK, val);
LP3972_BUCK_VOL_MASK, selector);
if (ret)
return ret;
@ -468,10 +441,10 @@ static struct regulator_ops lp3972_dcdc_ops = {
.enable = lp3972_dcdc_enable,
.disable = lp3972_dcdc_disable,
.get_voltage = lp3972_dcdc_get_voltage,
.set_voltage = lp3972_dcdc_set_voltage,
.set_voltage_sel = lp3972_dcdc_set_voltage_sel,
};
static struct regulator_desc regulators[] = {
static const struct regulator_desc regulators[] = {
{
.name = "LDO1",
.id = LP3972_LDO1,
@ -554,9 +527,14 @@ static int __devinit setup_regulators(struct lp3972 *lp3972,
/* Instantiate the regulators */
for (i = 0; i < pdata->num_regulators; i++) {
struct lp3972_regulator_subdev *reg = &pdata->regulators[i];
lp3972->rdev[i] = regulator_register(&regulators[reg->id],
lp3972->dev, reg->initdata, lp3972, NULL);
struct regulator_config config = { };
config.dev = lp3972->dev;
config.init_data = reg->initdata;
config.driver_data = lp3972;
lp3972->rdev[i] = regulator_register(&regulators[reg->id],
&config);
if (IS_ERR(lp3972->rdev[i])) {
err = PTR_ERR(lp3972->rdev[i]);
dev_err(lp3972->dev, "regulator init failed: %d\n",

View File

@ -161,7 +161,7 @@ static struct regulator_ops max1586_v6_ops = {
.list_voltage = max1586_v6_list,
};
static struct regulator_desc max1586_reg[] = {
static const struct regulator_desc max1586_reg[] = {
{
.name = "Output_V3",
.id = MAX1586_V3,
@ -185,21 +185,21 @@ static int __devinit max1586_pmic_probe(struct i2c_client *client,
{
struct regulator_dev **rdev;
struct max1586_platform_data *pdata = client->dev.platform_data;
struct regulator_config config = { };
struct max1586_data *max1586;
int i, id, ret = -ENOMEM;
max1586 = kzalloc(sizeof(struct max1586_data) +
max1586 = devm_kzalloc(&client->dev, sizeof(struct max1586_data) +
sizeof(struct regulator_dev *) * (MAX1586_V6 + 1),
GFP_KERNEL);
if (!max1586)
goto out;
return -ENOMEM;
max1586->client = client;
if (!pdata->v3_gain) {
ret = -EINVAL;
goto out_unmap;
}
if (!pdata->v3_gain)
return -EINVAL;
max1586->min_uV = MAX1586_V3_MIN_UV / 1000 * pdata->v3_gain / 1000;
max1586->max_uV = MAX1586_V3_MAX_UV / 1000 * pdata->v3_gain / 1000;
@ -212,9 +212,12 @@ static int __devinit max1586_pmic_probe(struct i2c_client *client,
dev_err(&client->dev, "invalid regulator id %d\n", id);
goto err;
}
rdev[i] = regulator_register(&max1586_reg[id], &client->dev,
pdata->subdevs[i].platform_data,
max1586, NULL);
config.dev = &client->dev;
config.init_data = pdata->subdevs[i].platform_data;
config.driver_data = max1586;
rdev[i] = regulator_register(&max1586_reg[id], &config);
if (IS_ERR(rdev[i])) {
ret = PTR_ERR(rdev[i]);
dev_err(&client->dev, "failed to register %s\n",
@ -230,9 +233,6 @@ static int __devinit max1586_pmic_probe(struct i2c_client *client,
err:
while (--i >= 0)
regulator_unregister(rdev[i]);
out_unmap:
kfree(max1586);
out:
return ret;
}
@ -244,8 +244,6 @@ static int __devexit max1586_pmic_remove(struct i2c_client *client)
for (i = 0; i <= MAX1586_V6; i++)
if (max1586->rdev[i])
regulator_unregister(max1586->rdev[i]);
kfree(max1586);
return 0;
}

View File

@ -207,7 +207,7 @@ static struct regulator_ops max8649_dcdc_ops = {
};
static struct regulator_desc dcdc_desc = {
static const struct regulator_desc dcdc_desc = {
.name = "max8649",
.ops = &max8649_dcdc_ops,
.type = REGULATOR_VOLTAGE,
@ -225,21 +225,23 @@ static int __devinit max8649_regulator_probe(struct i2c_client *client,
{
struct max8649_platform_data *pdata = client->dev.platform_data;
struct max8649_regulator_info *info = NULL;
struct regulator_config config = { };
unsigned int val;
unsigned char data;
int ret;
info = kzalloc(sizeof(struct max8649_regulator_info), GFP_KERNEL);
info = devm_kzalloc(&client->dev, sizeof(struct max8649_regulator_info),
GFP_KERNEL);
if (!info) {
dev_err(&client->dev, "No enough memory\n");
return -ENOMEM;
}
info->regmap = regmap_init_i2c(client, &max8649_regmap_config);
info->regmap = devm_regmap_init_i2c(client, &max8649_regmap_config);
if (IS_ERR(info->regmap)) {
ret = PTR_ERR(info->regmap);
dev_err(&client->dev, "Failed to allocate register map: %d\n", ret);
goto fail;
return ret;
}
info->dev = &client->dev;
@ -267,7 +269,7 @@ static int __devinit max8649_regulator_probe(struct i2c_client *client,
if (ret != 0) {
dev_err(info->dev, "Failed to detect ID of MAX8649:%d\n",
ret);
goto out;
return ret;
}
dev_info(info->dev, "Detected MAX8649 (ID:%x)\n", val);
@ -297,22 +299,18 @@ static int __devinit max8649_regulator_probe(struct i2c_client *client,
MAX8649_RAMP_DOWN);
}
info->regulator = regulator_register(&dcdc_desc, &client->dev,
pdata->regulator, info, NULL);
config.dev = &client->dev;
config.init_data = pdata->regulator;
config.driver_data = info;
info->regulator = regulator_register(&dcdc_desc, &config);
if (IS_ERR(info->regulator)) {
dev_err(info->dev, "failed to register regulator %s\n",
dcdc_desc.name);
ret = PTR_ERR(info->regulator);
goto out;
return PTR_ERR(info->regulator);
}
dev_info(info->dev, "Max8649 regulator device is detected.\n");
return 0;
out:
regmap_exit(info->regmap);
fail:
kfree(info);
return ret;
}
static int __devexit max8649_regulator_remove(struct i2c_client *client)
@ -322,8 +320,6 @@ static int __devexit max8649_regulator_remove(struct i2c_client *client)
if (info) {
if (info->regulator)
regulator_unregister(info->regulator);
regmap_exit(info->regmap);
kfree(info);
}
return 0;

View File

@ -313,7 +313,7 @@ static struct regulator_ops max8660_ldo67_ops = {
.set_voltage = max8660_ldo67_set,
};
static struct regulator_desc max8660_reg[] = {
static const struct regulator_desc max8660_reg[] = {
{
.name = "V3(DCDC)",
.id = MAX8660_V3,
@ -361,21 +361,20 @@ static int __devinit max8660_probe(struct i2c_client *client,
{
struct regulator_dev **rdev;
struct max8660_platform_data *pdata = client->dev.platform_data;
struct regulator_config config = { };
struct max8660 *max8660;
int boot_on, i, id, ret = -EINVAL;
if (pdata->num_subdevs > MAX8660_V_END) {
dev_err(&client->dev, "Too many regulators found!\n");
goto out;
return -EINVAL;
}
max8660 = kzalloc(sizeof(struct max8660) +
sizeof(struct regulator_dev *) * MAX8660_V_END,
GFP_KERNEL);
if (!max8660) {
ret = -ENOMEM;
goto out;
}
if (!max8660)
return -ENOMEM;
max8660->client = client;
rdev = max8660->rdev;
@ -404,7 +403,7 @@ static int __devinit max8660_probe(struct i2c_client *client,
for (i = 0; i < pdata->num_subdevs; i++) {
if (!pdata->subdevs[i].platform_data)
goto err_free;
goto err_out;
boot_on = pdata->subdevs[i].platform_data->constraints.boot_on;
@ -430,7 +429,7 @@ static int __devinit max8660_probe(struct i2c_client *client,
case MAX8660_V7:
if (!strcmp(i2c_id->name, "max8661")) {
dev_err(&client->dev, "Regulator not on this chip!\n");
goto err_free;
goto err_out;
}
if (boot_on)
@ -440,7 +439,7 @@ static int __devinit max8660_probe(struct i2c_client *client,
default:
dev_err(&client->dev, "invalid regulator %s\n",
pdata->subdevs[i].name);
goto err_free;
goto err_out;
}
}
@ -449,9 +448,11 @@ static int __devinit max8660_probe(struct i2c_client *client,
id = pdata->subdevs[i].id;
rdev[i] = regulator_register(&max8660_reg[id], &client->dev,
pdata->subdevs[i].platform_data,
max8660, NULL);
config.dev = &client->dev;
config.init_data = pdata->subdevs[i].platform_data;
config.driver_data = max8660;
rdev[i] = regulator_register(&max8660_reg[id], &config);
if (IS_ERR(rdev[i])) {
ret = PTR_ERR(rdev[i]);
dev_err(&client->dev, "failed to register %s\n",
@ -461,15 +462,12 @@ static int __devinit max8660_probe(struct i2c_client *client,
}
i2c_set_clientdata(client, max8660);
dev_info(&client->dev, "Maxim 8660/8661 regulator driver loaded\n");
return 0;
err_unregister:
while (--i >= 0)
regulator_unregister(rdev[i]);
err_free:
kfree(max8660);
out:
err_out:
return ret;
}
@ -481,8 +479,6 @@ static int __devexit max8660_remove(struct i2c_client *client)
for (i = 0; i < MAX8660_V_END; i++)
if (max8660->rdev[i])
regulator_unregister(max8660->rdev[i]);
kfree(max8660);
return 0;
}

View File

@ -42,8 +42,6 @@ struct max8925_regulator_info {
int max_uV;
int step_uV;
int vol_reg;
int vol_shift;
int vol_nbits;
int enable_reg;
};
@ -75,8 +73,7 @@ static int max8925_set_voltage(struct regulator_dev *rdev,
}
data = DIV_ROUND_UP(min_uV - info->min_uV, info->step_uV);
*selector = data;
data <<= info->vol_shift;
mask = ((1 << info->vol_nbits) - 1) << info->vol_shift;
mask = rdev->desc->n_voltages - 1;
return max8925_set_bits(info->i2c, info->vol_reg, mask, data);
}
@ -90,8 +87,8 @@ static int max8925_get_voltage(struct regulator_dev *rdev)
ret = max8925_reg_read(info->i2c, info->vol_reg);
if (ret < 0)
return ret;
mask = ((1 << info->vol_nbits) - 1) << info->vol_shift;
data = (ret & mask) >> info->vol_shift;
mask = rdev->desc->n_voltages - 1;
data = ret & mask;
return max8925_list_voltage(rdev, data);
}
@ -163,6 +160,7 @@ static int max8925_set_dvm_disable(struct regulator_dev *rdev)
}
static struct regulator_ops max8925_regulator_sdv_ops = {
.list_voltage = max8925_list_voltage,
.set_voltage = max8925_set_voltage,
.get_voltage = max8925_get_voltage,
.enable = max8925_enable,
@ -174,6 +172,7 @@ static struct regulator_ops max8925_regulator_sdv_ops = {
};
static struct regulator_ops max8925_regulator_ldo_ops = {
.list_voltage = max8925_list_voltage,
.set_voltage = max8925_set_voltage,
.get_voltage = max8925_get_voltage,
.enable = max8925_enable,
@ -189,13 +188,12 @@ static struct regulator_ops max8925_regulator_ldo_ops = {
.type = REGULATOR_VOLTAGE, \
.id = MAX8925_ID_SD##_id, \
.owner = THIS_MODULE, \
.n_voltages = 64, \
}, \
.min_uV = min * 1000, \
.max_uV = max * 1000, \
.step_uV = step * 1000, \
.vol_reg = MAX8925_SDV##_id, \
.vol_shift = 0, \
.vol_nbits = 6, \
.enable_reg = MAX8925_SDCTL##_id, \
}
@ -207,13 +205,12 @@ static struct regulator_ops max8925_regulator_ldo_ops = {
.type = REGULATOR_VOLTAGE, \
.id = MAX8925_ID_LDO##_id, \
.owner = THIS_MODULE, \
.n_voltages = 64, \
}, \
.min_uV = min * 1000, \
.max_uV = max * 1000, \
.step_uV = step * 1000, \
.vol_reg = MAX8925_LDOVOUT##_id, \
.vol_shift = 0, \
.vol_nbits = 6, \
.enable_reg = MAX8925_LDOCTL##_id, \
}
@ -261,6 +258,7 @@ static int __devinit max8925_regulator_probe(struct platform_device *pdev)
{
struct max8925_chip *chip = dev_get_drvdata(pdev->dev.parent);
struct max8925_platform_data *pdata = chip->dev->platform_data;
struct regulator_config config = { };
struct max8925_regulator_info *ri;
struct regulator_dev *rdev;
@ -272,8 +270,11 @@ static int __devinit max8925_regulator_probe(struct platform_device *pdev)
ri->i2c = chip->i2c;
ri->chip = chip;
rdev = regulator_register(&ri->desc, &pdev->dev,
pdata->regulator[pdev->id], ri, NULL);
config.dev = &pdev->dev;
config.init_data = pdata->regulator[pdev->id];
config.driver_data = ri;
rdev = regulator_register(&ri->desc, &config);
if (IS_ERR(rdev)) {
dev_err(&pdev->dev, "failed to register regulator %s\n",
ri->desc.name);

View File

@ -130,11 +130,10 @@ static int max8952_get_voltage(struct regulator_dev *rdev)
return max8952_voltage(max8952, vid);
}
static int max8952_set_voltage(struct regulator_dev *rdev,
int min_uV, int max_uV, unsigned *selector)
static int max8952_set_voltage_sel(struct regulator_dev *rdev,
unsigned selector)
{
struct max8952_data *max8952 = rdev_get_drvdata(rdev);
s8 vid = -1, i;
if (!gpio_is_valid(max8952->pdata->gpio_vid0) ||
!gpio_is_valid(max8952->pdata->gpio_vid1)) {
@ -142,23 +141,10 @@ static int max8952_set_voltage(struct regulator_dev *rdev,
return -EPERM;
}
for (i = 0; i < MAX8952_NUM_DVS_MODE; i++) {
int volt = max8952_voltage(max8952, i);
/* Set the voltage as low as possible within the range */
if (volt <= max_uV && volt >= min_uV)
if (vid == -1 || max8952_voltage(max8952, vid) > volt)
vid = i;
}
if (vid >= 0 && vid < MAX8952_NUM_DVS_MODE) {
max8952->vid0 = (vid % 2 == 1);
max8952->vid1 = (((vid >> 1) % 2) == 1);
*selector = vid;
gpio_set_value(max8952->pdata->gpio_vid0, max8952->vid0);
gpio_set_value(max8952->pdata->gpio_vid1, max8952->vid1);
} else
return -EINVAL;
max8952->vid0 = selector & 0x1;
max8952->vid1 = (selector >> 1) & 0x1;
gpio_set_value(max8952->pdata->gpio_vid0, max8952->vid0);
gpio_set_value(max8952->pdata->gpio_vid1, max8952->vid1);
return 0;
}
@ -169,11 +155,11 @@ static struct regulator_ops max8952_ops = {
.enable = max8952_enable,
.disable = max8952_disable,
.get_voltage = max8952_get_voltage,
.set_voltage = max8952_set_voltage,
.set_voltage_sel = max8952_set_voltage_sel,
.set_suspend_disable = max8952_disable,
};
static struct regulator_desc regulator = {
static const struct regulator_desc regulator = {
.name = "MAX8952_VOUT",
.id = 0,
.n_voltages = MAX8952_NUM_DVS_MODE,
@ -187,6 +173,7 @@ static int __devinit max8952_pmic_probe(struct i2c_client *client,
{
struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
struct max8952_platform_data *pdata = client->dev.platform_data;
struct regulator_config config = { };
struct max8952_data *max8952;
int ret = 0, err = 0;
@ -207,8 +194,11 @@ static int __devinit max8952_pmic_probe(struct i2c_client *client,
max8952->dev = &client->dev;
max8952->pdata = pdata;
max8952->rdev = regulator_register(&regulator, max8952->dev,
&pdata->reg_data, max8952, NULL);
config.dev = max8952->dev;
config.init_data = &pdata->reg_data;
config.driver_data = max8952;
max8952->rdev = regulator_register(&regulator, &config);
if (IS_ERR(max8952->rdev)) {
ret = PTR_ERR(max8952->rdev);
@ -217,8 +207,8 @@ static int __devinit max8952_pmic_probe(struct i2c_client *client,
}
max8952->en = !!(pdata->reg_data.constraints.boot_on);
max8952->vid0 = (pdata->default_mode % 2) == 1;
max8952->vid1 = ((pdata->default_mode >> 1) % 2) == 1;
max8952->vid0 = pdata->default_mode & 0x1;
max8952->vid1 = (pdata->default_mode >> 1) & 0x1;
if (gpio_is_valid(pdata->gpio_en)) {
if (!gpio_request(pdata->gpio_en, "MAX8952 EN"))
@ -241,13 +231,13 @@ static int __devinit max8952_pmic_probe(struct i2c_client *client,
gpio_is_valid(pdata->gpio_vid1)) {
if (!gpio_request(pdata->gpio_vid0, "MAX8952 VID0"))
gpio_direction_output(pdata->gpio_vid0,
(pdata->default_mode) % 2);
(pdata->default_mode) & 0x1);
else
err = 1;
if (!gpio_request(pdata->gpio_vid1, "MAX8952 VID1"))
gpio_direction_output(pdata->gpio_vid1,
(pdata->default_mode >> 1) % 2);
(pdata->default_mode >> 1) & 0x1);
else {
if (!err)
gpio_free(pdata->gpio_vid0);

View File

@ -68,29 +68,28 @@ struct voltage_map_desc {
int min;
int max;
int step;
unsigned int n_bits;
};
/* Voltage maps in mV */
static const struct voltage_map_desc ldo_voltage_map_desc = {
.min = 800, .max = 3950, .step = 50, .n_bits = 6,
.min = 800, .max = 3950, .step = 50,
}; /* LDO1 ~ 18, 21 all */
static const struct voltage_map_desc buck1245_voltage_map_desc = {
.min = 650, .max = 2225, .step = 25, .n_bits = 6,
.min = 650, .max = 2225, .step = 25,
}; /* Buck1, 2, 4, 5 */
static const struct voltage_map_desc buck37_voltage_map_desc = {
.min = 750, .max = 3900, .step = 50, .n_bits = 6,
.min = 750, .max = 3900, .step = 50,
}; /* Buck3, 7 */
/* current map in mA */
static const struct voltage_map_desc charger_current_map_desc = {
.min = 200, .max = 950, .step = 50, .n_bits = 4,
.min = 200, .max = 950, .step = 50,
};
static const struct voltage_map_desc topoff_current_map_desc = {
.min = 50, .max = 200, .step = 10, .n_bits = 4,
.min = 50, .max = 200, .step = 10,
};
static const struct voltage_map_desc *reg_voltage_map[] = {
@ -320,6 +319,7 @@ static int max8997_reg_disable(struct regulator_dev *rdev)
static int max8997_get_voltage_register(struct regulator_dev *rdev,
int *_reg, int *_shift, int *_mask)
{
struct max8997_data *max8997 = rdev_get_drvdata(rdev);
int rid = rdev_get_id(rdev);
int reg, shift = 0, mask = 0x3f;
@ -329,9 +329,13 @@ static int max8997_get_voltage_register(struct regulator_dev *rdev,
break;
case MAX8997_BUCK1:
reg = MAX8997_REG_BUCK1DVS1;
if (max8997->buck1_gpiodvs)
reg += max8997->buck125_gpioindex;
break;
case MAX8997_BUCK2:
reg = MAX8997_REG_BUCK2DVS1;
if (max8997->buck2_gpiodvs)
reg += max8997->buck125_gpioindex;
break;
case MAX8997_BUCK3:
reg = MAX8997_REG_BUCK3DVS;
@ -341,6 +345,8 @@ static int max8997_get_voltage_register(struct regulator_dev *rdev,
break;
case MAX8997_BUCK5:
reg = MAX8997_REG_BUCK5DVS1;
if (max8997->buck5_gpiodvs)
reg += max8997->buck125_gpioindex;
break;
case MAX8997_BUCK7:
reg = MAX8997_REG_BUCK7DVS;
@ -381,18 +387,12 @@ static int max8997_get_voltage(struct regulator_dev *rdev)
struct max8997_data *max8997 = rdev_get_drvdata(rdev);
struct i2c_client *i2c = max8997->iodev->i2c;
int reg, shift, mask, ret;
int rid = rdev_get_id(rdev);
u8 val;
ret = max8997_get_voltage_register(rdev, &reg, &shift, &mask);
if (ret)
return ret;
if ((rid == MAX8997_BUCK1 && max8997->buck1_gpiodvs) ||
(rid == MAX8997_BUCK2 && max8997->buck2_gpiodvs) ||
(rid == MAX8997_BUCK5 && max8997->buck5_gpiodvs))
reg += max8997->buck125_gpioindex;
ret = max8997_read_reg(i2c, reg, &val);
if (ret)
return ret;
@ -415,7 +415,7 @@ static inline int max8997_get_voltage_proper_val(
const struct voltage_map_desc *desc,
int min_vol, int max_vol)
{
int i = 0;
int i;
if (desc == NULL)
return -EINVAL;
@ -423,16 +423,14 @@ static inline int max8997_get_voltage_proper_val(
if (max_vol < desc->min || min_vol > desc->max)
return -EINVAL;
while (desc->min + desc->step * i < min_vol &&
desc->min + desc->step * i < desc->max)
i++;
if (min_vol < desc->min)
min_vol = desc->min;
i = DIV_ROUND_UP(min_vol - desc->min, desc->step);
if (desc->min + desc->step * i > max_vol)
return -EINVAL;
if (i >= (1 << desc->n_bits))
return -EINVAL;
return i;
}
@ -854,109 +852,65 @@ static struct regulator_ops max8997_charger_fixedstate_ops = {
.set_current_limit = max8997_set_voltage_ldobuck_wrap,
};
#define regulator_desc_ldo(num) { \
.name = "LDO"#num, \
.id = MAX8997_LDO##num, \
.ops = &max8997_ldo_ops, \
.type = REGULATOR_VOLTAGE, \
.owner = THIS_MODULE, \
}
#define regulator_desc_buck(num) { \
.name = "BUCK"#num, \
.id = MAX8997_BUCK##num, \
.ops = &max8997_buck_ops, \
#define MAX8997_VOLTAGE_REGULATOR(_name, _ops) {\
.name = #_name, \
.id = MAX8997_##_name, \
.ops = &_ops, \
.type = REGULATOR_VOLTAGE, \
.owner = THIS_MODULE, \
}
#define MAX8997_CURRENT_REGULATOR(_name, _ops) {\
.name = #_name, \
.id = MAX8997_##_name, \
.ops = &_ops, \
.type = REGULATOR_CURRENT, \
.owner = THIS_MODULE, \
}
static struct regulator_desc regulators[] = {
regulator_desc_ldo(1),
regulator_desc_ldo(2),
regulator_desc_ldo(3),
regulator_desc_ldo(4),
regulator_desc_ldo(5),
regulator_desc_ldo(6),
regulator_desc_ldo(7),
regulator_desc_ldo(8),
regulator_desc_ldo(9),
regulator_desc_ldo(10),
regulator_desc_ldo(11),
regulator_desc_ldo(12),
regulator_desc_ldo(13),
regulator_desc_ldo(14),
regulator_desc_ldo(15),
regulator_desc_ldo(16),
regulator_desc_ldo(17),
regulator_desc_ldo(18),
regulator_desc_ldo(21),
regulator_desc_buck(1),
regulator_desc_buck(2),
regulator_desc_buck(3),
regulator_desc_buck(4),
regulator_desc_buck(5),
{
.name = "BUCK6",
.id = MAX8997_BUCK6,
.ops = &max8997_fixedvolt_ops,
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
},
regulator_desc_buck(7),
{
.name = "EN32KHz_AP",
.id = MAX8997_EN32KHZ_AP,
.ops = &max8997_fixedvolt_ops,
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
}, {
.name = "EN32KHz_CP",
.id = MAX8997_EN32KHZ_CP,
.ops = &max8997_fixedvolt_ops,
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
}, {
.name = "ENVICHG",
.id = MAX8997_ENVICHG,
.ops = &max8997_fixedvolt_ops,
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
}, {
.name = "ESAFEOUT1",
.id = MAX8997_ESAFEOUT1,
.ops = &max8997_safeout_ops,
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
}, {
.name = "ESAFEOUT2",
.id = MAX8997_ESAFEOUT2,
.ops = &max8997_safeout_ops,
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
}, {
.name = "CHARGER_CV",
.id = MAX8997_CHARGER_CV,
.ops = &max8997_fixedstate_ops,
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
}, {
.name = "CHARGER",
.id = MAX8997_CHARGER,
.ops = &max8997_charger_ops,
.type = REGULATOR_CURRENT,
.owner = THIS_MODULE,
}, {
.name = "CHARGER_TOPOFF",
.id = MAX8997_CHARGER_TOPOFF,
.ops = &max8997_charger_fixedstate_ops,
.type = REGULATOR_CURRENT,
.owner = THIS_MODULE,
},
MAX8997_VOLTAGE_REGULATOR(LDO1, max8997_ldo_ops),
MAX8997_VOLTAGE_REGULATOR(LDO2, max8997_ldo_ops),
MAX8997_VOLTAGE_REGULATOR(LDO3, max8997_ldo_ops),
MAX8997_VOLTAGE_REGULATOR(LDO4, max8997_ldo_ops),
MAX8997_VOLTAGE_REGULATOR(LDO5, max8997_ldo_ops),
MAX8997_VOLTAGE_REGULATOR(LDO6, max8997_ldo_ops),
MAX8997_VOLTAGE_REGULATOR(LDO7, max8997_ldo_ops),
MAX8997_VOLTAGE_REGULATOR(LDO8, max8997_ldo_ops),
MAX8997_VOLTAGE_REGULATOR(LDO9, max8997_ldo_ops),
MAX8997_VOLTAGE_REGULATOR(LDO10, max8997_ldo_ops),
MAX8997_VOLTAGE_REGULATOR(LDO11, max8997_ldo_ops),
MAX8997_VOLTAGE_REGULATOR(LDO12, max8997_ldo_ops),
MAX8997_VOLTAGE_REGULATOR(LDO13, max8997_ldo_ops),
MAX8997_VOLTAGE_REGULATOR(LDO14, max8997_ldo_ops),
MAX8997_VOLTAGE_REGULATOR(LDO15, max8997_ldo_ops),
MAX8997_VOLTAGE_REGULATOR(LDO16, max8997_ldo_ops),
MAX8997_VOLTAGE_REGULATOR(LDO17, max8997_ldo_ops),
MAX8997_VOLTAGE_REGULATOR(LDO18, max8997_ldo_ops),
MAX8997_VOLTAGE_REGULATOR(LDO21, max8997_ldo_ops),
MAX8997_VOLTAGE_REGULATOR(BUCK1, max8997_buck_ops),
MAX8997_VOLTAGE_REGULATOR(BUCK2, max8997_buck_ops),
MAX8997_VOLTAGE_REGULATOR(BUCK3, max8997_buck_ops),
MAX8997_VOLTAGE_REGULATOR(BUCK4, max8997_buck_ops),
MAX8997_VOLTAGE_REGULATOR(BUCK5, max8997_buck_ops),
MAX8997_VOLTAGE_REGULATOR(BUCK6, max8997_fixedvolt_ops),
MAX8997_VOLTAGE_REGULATOR(BUCK7, max8997_buck_ops),
MAX8997_VOLTAGE_REGULATOR(EN32KHZ_AP, max8997_fixedvolt_ops),
MAX8997_VOLTAGE_REGULATOR(EN32KHZ_CP, max8997_fixedvolt_ops),
MAX8997_VOLTAGE_REGULATOR(ENVICHG, max8997_fixedvolt_ops),
MAX8997_VOLTAGE_REGULATOR(ESAFEOUT1, max8997_safeout_ops),
MAX8997_VOLTAGE_REGULATOR(ESAFEOUT2, max8997_safeout_ops),
MAX8997_VOLTAGE_REGULATOR(CHARGER_CV, max8997_fixedstate_ops),
MAX8997_CURRENT_REGULATOR(CHARGER, max8997_charger_ops),
MAX8997_CURRENT_REGULATOR(CHARGER_TOPOFF,
max8997_charger_fixedstate_ops),
};
static __devinit int max8997_pmic_probe(struct platform_device *pdev)
{
struct max8997_dev *iodev = dev_get_drvdata(pdev->dev.parent);
struct max8997_platform_data *pdata = dev_get_platdata(iodev->dev);
struct regulator_config config = { };
struct regulator_dev **rdev;
struct max8997_data *max8997;
struct i2c_client *i2c;
@ -1140,8 +1094,11 @@ static __devinit int max8997_pmic_probe(struct platform_device *pdev)
else if (id == MAX8997_CHARGER_CV)
regulators[id].n_voltages = 16;
rdev[i] = regulator_register(&regulators[id], max8997->dev,
pdata->regulators[i].initdata, max8997, NULL);
config.dev = max8997->dev;
config.init_data = pdata->regulators[i].initdata;
config.driver_data = max8997;
rdev[i] = regulator_register(&regulators[id], &config);
if (IS_ERR(rdev[i])) {
ret = PTR_ERR(rdev[i]);
dev_err(max8997->dev, "regulator init failed for %d\n",

View File

@ -277,7 +277,7 @@ static int max8998_get_voltage_register(struct regulator_dev *rdev,
return 0;
}
static int max8998_get_voltage(struct regulator_dev *rdev)
static int max8998_get_voltage_sel(struct regulator_dev *rdev)
{
struct max8998_data *max8998 = rdev_get_drvdata(rdev);
struct i2c_client *i2c = max8998->iodev->i2c;
@ -295,7 +295,7 @@ static int max8998_get_voltage(struct regulator_dev *rdev)
val >>= shift;
val &= mask;
return max8998_list_voltage(rdev, val);
return val;
}
static int max8998_set_voltage_ldo(struct regulator_dev *rdev,
@ -306,8 +306,7 @@ static int max8998_set_voltage_ldo(struct regulator_dev *rdev,
int min_vol = min_uV / 1000, max_vol = max_uV / 1000;
const struct voltage_map_desc *desc;
int ldo = rdev_get_id(rdev);
int reg, shift = 0, mask, ret;
int i = 0;
int reg, shift = 0, mask, ret, i;
if (ldo >= ARRAY_SIZE(ldo_voltage_map))
return -EINVAL;
@ -319,9 +318,10 @@ static int max8998_set_voltage_ldo(struct regulator_dev *rdev,
if (max_vol < desc->min || min_vol > desc->max)
return -EINVAL;
while (desc->min + desc->step*i < min_vol &&
desc->min + desc->step*i < desc->max)
i++;
if (min_vol < desc->min)
min_vol = desc->min;
i = DIV_ROUND_UP(min_vol - desc->min, desc->step);
if (desc->min + desc->step*i > max_vol)
return -EINVAL;
@ -359,8 +359,7 @@ static int max8998_set_voltage_buck(struct regulator_dev *rdev,
const struct voltage_map_desc *desc;
int buck = rdev_get_id(rdev);
int reg, shift = 0, mask, ret;
int difference = 0, i = 0, j = 0, previous_vol = 0;
u8 val = 0;
int i, j, previous_sel;
static u8 buck1_last_val;
if (buck >= ARRAY_SIZE(ldo_voltage_map))
@ -374,9 +373,10 @@ static int max8998_set_voltage_buck(struct regulator_dev *rdev,
if (max_vol < desc->min || min_vol > desc->max)
return -EINVAL;
while (desc->min + desc->step*i < min_vol &&
desc->min + desc->step*i < desc->max)
i++;
if (min_vol < desc->min)
min_vol = desc->min;
i = DIV_ROUND_UP(min_vol - desc->min, desc->step);
if (desc->min + desc->step*i > max_vol)
return -EINVAL;
@ -387,13 +387,14 @@ static int max8998_set_voltage_buck(struct regulator_dev *rdev,
if (ret)
return ret;
previous_vol = max8998_get_voltage(rdev);
previous_sel = max8998_get_voltage_sel(rdev);
/* Check if voltage needs to be changed */
/* if previous_voltage equal new voltage, return */
if (previous_vol == max8998_list_voltage(rdev, i)) {
if (previous_sel == i) {
dev_dbg(max8998->dev, "No voltage change, old:%d, new:%d\n",
previous_vol, max8998_list_voltage(rdev, i));
max8998_list_voltage(rdev, previous_sel),
max8998_list_voltage(rdev, i));
return ret;
}
@ -482,19 +483,40 @@ buck2_exit:
break;
}
return ret;
}
static int max8998_set_voltage_buck_time_sel(struct regulator_dev *rdev,
unsigned int old_selector,
unsigned int new_selector)
{
struct max8998_data *max8998 = rdev_get_drvdata(rdev);
struct i2c_client *i2c = max8998->iodev->i2c;
const struct voltage_map_desc *desc;
int buck = rdev_get_id(rdev);
u8 val = 0;
int difference, ret;
if (buck < MAX8998_BUCK1 || buck > MAX8998_BUCK4)
return -EINVAL;
desc = ldo_voltage_map[buck];
/* Voltage stabilization */
max8998_read_reg(i2c, MAX8998_REG_ONOFF4, &val);
ret = max8998_read_reg(i2c, MAX8998_REG_ONOFF4, &val);
if (ret)
return ret;
/* lp3974 hasn't got ENRAMP bit - ramp is assumed as true */
/* MAX8998 has ENRAMP bit implemented, so test it*/
if (max8998->iodev->type == TYPE_MAX8998 && !(val & MAX8998_ENRAMP))
return ret;
return 0;
difference = desc->min + desc->step*i - previous_vol/1000;
difference = (new_selector - old_selector) * desc->step;
if (difference > 0)
udelay(difference / ((val & 0x0f) + 1));
return difference / ((val & 0x0f) + 1);
return ret;
return 0;
}
static struct regulator_ops max8998_ldo_ops = {
@ -502,7 +524,7 @@ static struct regulator_ops max8998_ldo_ops = {
.is_enabled = max8998_ldo_is_enabled,
.enable = max8998_ldo_enable,
.disable = max8998_ldo_disable,
.get_voltage = max8998_get_voltage,
.get_voltage_sel = max8998_get_voltage_sel,
.set_voltage = max8998_set_voltage_ldo,
.set_suspend_enable = max8998_ldo_enable,
.set_suspend_disable = max8998_ldo_disable,
@ -513,8 +535,9 @@ static struct regulator_ops max8998_buck_ops = {
.is_enabled = max8998_ldo_is_enabled,
.enable = max8998_ldo_enable,
.disable = max8998_ldo_disable,
.get_voltage = max8998_get_voltage,
.get_voltage_sel = max8998_get_voltage_sel,
.set_voltage = max8998_set_voltage_buck,
.set_voltage_time_sel = max8998_set_voltage_buck_time_sel,
.set_suspend_enable = max8998_ldo_enable,
.set_suspend_disable = max8998_ldo_disable,
};
@ -685,6 +708,7 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev)
{
struct max8998_dev *iodev = dev_get_drvdata(pdev->dev.parent);
struct max8998_platform_data *pdata = dev_get_platdata(iodev->dev);
struct regulator_config config = { };
struct regulator_dev **rdev;
struct max8998_data *max8998;
struct i2c_client *i2c;
@ -840,8 +864,12 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev)
int count = (desc->max - desc->min) / desc->step + 1;
regulators[index].n_voltages = count;
}
rdev[i] = regulator_register(&regulators[index], max8998->dev,
pdata->regulators[i].initdata, max8998, NULL);
config.dev = max8998->dev;
config.init_data = pdata->regulators[i].initdata;
config.driver_data = max8998;
rdev[i] = regulator_register(&regulators[index], &config);
if (IS_ERR(rdev[i])) {
ret = PTR_ERR(rdev[i]);
dev_err(max8998->dev, "regulator init failed\n");

View File

@ -340,6 +340,7 @@ static int __devinit mc13783_regulator_probe(struct platform_device *pdev)
struct mc13xxx_regulator_platform_data *pdata =
dev_get_platdata(&pdev->dev);
struct mc13xxx_regulator_init_data *init_data;
struct regulator_config config = { };
int i, ret;
dev_dbg(&pdev->dev, "%s id %d\n", __func__, pdev->id);
@ -357,11 +358,16 @@ static int __devinit mc13783_regulator_probe(struct platform_device *pdev)
priv->mc13xxx = mc13783;
for (i = 0; i < pdata->num_regulators; i++) {
init_data = &pdata->regulators[i];
priv->regulators[i] = regulator_register(
&mc13783_regulators[init_data->id].desc,
&pdev->dev, init_data->init_data, priv, NULL);
struct regulator_desc *desc;
init_data = &pdata->regulators[i];
desc = &mc13783_regulators[init_data->id].desc;
config.dev = &pdev->dev;
config.init_data = init_data->init_data;
config.driver_data = priv;
priv->regulators[i] = regulator_register(desc, &config);
if (IS_ERR(priv->regulators[i])) {
dev_err(&pdev->dev, "failed to register regulator %s\n",
mc13783_regulators[i].desc.name);

View File

@ -428,24 +428,15 @@ static int mc13892_sw_regulator_get_voltage(struct regulator_dev *rdev)
return val;
}
static int mc13892_sw_regulator_set_voltage(struct regulator_dev *rdev,
int min_uV, int max_uV, unsigned *selector)
static int mc13892_sw_regulator_set_voltage_sel(struct regulator_dev *rdev,
unsigned selector)
{
struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev);
int hi, value, mask, id = rdev_get_id(rdev);
u32 valread;
int ret;
dev_dbg(rdev_get_dev(rdev), "%s id: %d min_uV: %d max_uV: %d\n",
__func__, id, min_uV, max_uV);
/* Find the best index */
value = mc13xxx_get_best_voltage_index(rdev, min_uV, max_uV);
dev_dbg(rdev_get_dev(rdev), "%s best value: %d\n", __func__, value);
if (value < 0)
return value;
value = mc13892_regulators[id].voltages[value];
value = mc13892_regulators[id].voltages[selector];
mc13xxx_lock(priv->mc13xxx);
ret = mc13xxx_reg_read(priv->mc13xxx,
@ -480,7 +471,7 @@ err:
static struct regulator_ops mc13892_sw_regulator_ops = {
.is_enabled = mc13xxx_sw_regulator_is_enabled,
.list_voltage = mc13xxx_regulator_list_voltage,
.set_voltage = mc13892_sw_regulator_set_voltage,
.set_voltage_sel = mc13892_sw_regulator_set_voltage_sel,
.get_voltage = mc13892_sw_regulator_get_voltage,
};
@ -528,6 +519,7 @@ static int __devinit mc13892_regulator_probe(struct platform_device *pdev)
struct mc13xxx_regulator_platform_data *pdata =
dev_get_platdata(&pdev->dev);
struct mc13xxx_regulator_init_data *mc13xxx_data;
struct regulator_config config = { };
int i, ret;
int num_regulators = 0;
u32 val;
@ -597,9 +589,12 @@ static int __devinit mc13892_regulator_probe(struct platform_device *pdev)
}
desc = &mc13892_regulators[id].desc;
priv->regulators[i] = regulator_register(
desc, &pdev->dev, init_data, priv, node);
config.dev = &pdev->dev;
config.init_data = init_data;
config.driver_data = priv;
config.of_node = node;
priv->regulators[i] = regulator_register(desc, &config);
if (IS_ERR(priv->regulators[i])) {
dev_err(&pdev->dev, "failed to register regulator %s\n",
mc13892_regulators[i].desc.name);

View File

@ -94,62 +94,18 @@ int mc13xxx_regulator_list_voltage(struct regulator_dev *rdev,
}
EXPORT_SYMBOL_GPL(mc13xxx_regulator_list_voltage);
int mc13xxx_get_best_voltage_index(struct regulator_dev *rdev,
int min_uV, int max_uV)
static int mc13xxx_regulator_set_voltage_sel(struct regulator_dev *rdev,
unsigned selector)
{
struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev);
struct mc13xxx_regulator *mc13xxx_regulators = priv->mc13xxx_regulators;
int reg_id = rdev_get_id(rdev);
int i;
int bestmatch;
int bestindex;
/*
* Locate the minimum voltage fitting the criteria on
* this regulator. The switchable voltages are not
* in strict falling order so we need to check them
* all for the best match.
*/
bestmatch = INT_MAX;
bestindex = -1;
for (i = 0; i < mc13xxx_regulators[reg_id].desc.n_voltages; i++) {
if (mc13xxx_regulators[reg_id].voltages[i] >= min_uV &&
mc13xxx_regulators[reg_id].voltages[i] < bestmatch) {
bestmatch = mc13xxx_regulators[reg_id].voltages[i];
bestindex = i;
}
}
if (bestindex < 0 || bestmatch > max_uV) {
dev_warn(&rdev->dev, "no possible value for %d<=x<=%d uV\n",
min_uV, max_uV);
return -EINVAL;
}
return bestindex;
}
EXPORT_SYMBOL_GPL(mc13xxx_get_best_voltage_index);
static int mc13xxx_regulator_set_voltage(struct regulator_dev *rdev, int min_uV,
int max_uV, unsigned *selector)
{
struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev);
struct mc13xxx_regulator *mc13xxx_regulators = priv->mc13xxx_regulators;
int value, id = rdev_get_id(rdev);
int id = rdev_get_id(rdev);
int ret;
dev_dbg(rdev_get_dev(rdev), "%s id: %d min_uV: %d max_uV: %d\n",
__func__, id, min_uV, max_uV);
/* Find the best index */
value = mc13xxx_get_best_voltage_index(rdev, min_uV, max_uV);
dev_dbg(rdev_get_dev(rdev), "%s best value: %d\n", __func__, value);
if (value < 0)
return value;
mc13xxx_lock(priv->mc13xxx);
ret = mc13xxx_reg_rmw(priv->mc13xxx, mc13xxx_regulators[id].vsel_reg,
mc13xxx_regulators[id].vsel_mask,
value << mc13xxx_regulators[id].vsel_shift);
selector << mc13xxx_regulators[id].vsel_shift);
mc13xxx_unlock(priv->mc13xxx);
return ret;
@ -187,7 +143,7 @@ struct regulator_ops mc13xxx_regulator_ops = {
.disable = mc13xxx_regulator_disable,
.is_enabled = mc13xxx_regulator_is_enabled,
.list_voltage = mc13xxx_regulator_list_voltage,
.set_voltage = mc13xxx_regulator_set_voltage,
.set_voltage_sel = mc13xxx_regulator_set_voltage_sel,
.get_voltage = mc13xxx_regulator_get_voltage,
};
EXPORT_SYMBOL_GPL(mc13xxx_regulator_ops);

View File

@ -35,8 +35,6 @@ struct mc13xxx_regulator_priv {
extern int mc13xxx_sw_regulator(struct regulator_dev *rdev);
extern int mc13xxx_sw_regulator_is_enabled(struct regulator_dev *rdev);
extern int mc13xxx_get_best_voltage_index(struct regulator_dev *rdev,
int min_uV, int max_uV);
extern int mc13xxx_regulator_list_voltage(struct regulator_dev *rdev,
unsigned selector);
extern int mc13xxx_fixed_regulator_set_voltage(struct regulator_dev *rdev,

View File

@ -150,57 +150,33 @@ static struct pcap_regulator vreg_table[] = {
VREG_INFO(SW2S, PCAP_REG_LOWPWR, NA, 20, NA, NA), */
};
static int pcap_regulator_set_voltage(struct regulator_dev *rdev,
int min_uV, int max_uV,
unsigned *selector)
static int pcap_regulator_set_voltage_sel(struct regulator_dev *rdev,
unsigned selector)
{
struct pcap_regulator *vreg = &vreg_table[rdev_get_id(rdev)];
void *pcap = rdev_get_drvdata(rdev);
int uV;
u8 i;
/* the regulator doesn't support voltage switching */
if (vreg->n_voltages == 1)
return -EINVAL;
for (i = 0; i < vreg->n_voltages; i++) {
/* For V1 the first is not the best match */
if (i == 0 && rdev_get_id(rdev) == V1)
i = 1;
else if (i + 1 == vreg->n_voltages && rdev_get_id(rdev) == V1)
i = 0;
uV = vreg->voltage_table[i] * 1000;
if (min_uV <= uV && uV <= max_uV) {
*selector = i;
return ezx_pcap_set_bits(pcap, vreg->reg,
(vreg->n_voltages - 1) << vreg->index,
i << vreg->index);
}
if (i == 0 && rdev_get_id(rdev) == V1)
i = vreg->n_voltages - 1;
}
/* the requested voltage range is not supported by this regulator */
return -EINVAL;
return ezx_pcap_set_bits(pcap, vreg->reg,
(vreg->n_voltages - 1) << vreg->index,
selector << vreg->index);
}
static int pcap_regulator_get_voltage(struct regulator_dev *rdev)
static int pcap_regulator_get_voltage_sel(struct regulator_dev *rdev)
{
struct pcap_regulator *vreg = &vreg_table[rdev_get_id(rdev)];
void *pcap = rdev_get_drvdata(rdev);
u32 tmp;
int mV;
if (vreg->n_voltages == 1)
return vreg->voltage_table[0] * 1000;
return 0;
ezx_pcap_read(pcap, vreg->reg, &tmp);
tmp = ((tmp >> vreg->index) & (vreg->n_voltages - 1));
mV = vreg->voltage_table[tmp];
return mV * 1000;
return tmp;
}
static int pcap_regulator_enable(struct regulator_dev *rdev)
@ -248,8 +224,8 @@ static int pcap_regulator_list_voltage(struct regulator_dev *rdev,
static struct regulator_ops pcap_regulator_ops = {
.list_voltage = pcap_regulator_list_voltage,
.set_voltage = pcap_regulator_set_voltage,
.get_voltage = pcap_regulator_get_voltage,
.set_voltage_sel = pcap_regulator_set_voltage_sel,
.get_voltage_sel = pcap_regulator_get_voltage_sel,
.enable = pcap_regulator_enable,
.disable = pcap_regulator_disable,
.is_enabled = pcap_regulator_is_enabled,
@ -265,7 +241,7 @@ static struct regulator_ops pcap_regulator_ops = {
.owner = THIS_MODULE, \
}
static struct regulator_desc pcap_regulators[] = {
static const struct regulator_desc pcap_regulators[] = {
VREG(V1), VREG(V2), VREG(V3), VREG(V4), VREG(V5), VREG(V6), VREG(V7),
VREG(V8), VREG(V9), VREG(V10), VREG(VAUX1), VREG(VAUX2), VREG(VAUX3),
VREG(VAUX4), VREG(VSIM), VREG(VSIM2), VREG(VVIB), VREG(SW1), VREG(SW2),
@ -275,9 +251,13 @@ static int __devinit pcap_regulator_probe(struct platform_device *pdev)
{
struct regulator_dev *rdev;
void *pcap = dev_get_drvdata(pdev->dev.parent);
struct regulator_config config = { };
rdev = regulator_register(&pcap_regulators[pdev->id], &pdev->dev,
pdev->dev.platform_data, pcap, NULL);
config.dev = &pdev->dev;
config.init_data = pdev->dev.platform_data;
config.driver_data = pcap;
rdev = regulator_register(&pcap_regulators[pdev->id], &config);
if (IS_ERR(rdev))
return PTR_ERR(rdev);

View File

@ -24,35 +24,25 @@
#include <linux/mfd/pcf50633/core.h>
#include <linux/mfd/pcf50633/pmic.h>
#define PCF50633_REGULATOR(_name, _id, _n) \
{ \
.name = _name, \
.id = _id, \
.ops = &pcf50633_regulator_ops, \
.n_voltages = _n, \
.type = REGULATOR_VOLTAGE, \
.owner = THIS_MODULE, \
#define PCF50633_REGULATOR(_name, _id, _n) \
{ \
.name = _name, \
.id = PCF50633_REGULATOR_##_id, \
.ops = &pcf50633_regulator_ops, \
.n_voltages = _n, \
.type = REGULATOR_VOLTAGE, \
.owner = THIS_MODULE, \
.vsel_reg = PCF50633_REG_##_id##OUT, \
.vsel_mask = 0xff, \
.enable_reg = PCF50633_REG_##_id##OUT + 1, \
.enable_mask = PCF50633_REGULATOR_ON, \
}
static const u8 pcf50633_regulator_registers[PCF50633_NUM_REGULATORS] = {
[PCF50633_REGULATOR_AUTO] = PCF50633_REG_AUTOOUT,
[PCF50633_REGULATOR_DOWN1] = PCF50633_REG_DOWN1OUT,
[PCF50633_REGULATOR_DOWN2] = PCF50633_REG_DOWN2OUT,
[PCF50633_REGULATOR_MEMLDO] = PCF50633_REG_MEMLDOOUT,
[PCF50633_REGULATOR_LDO1] = PCF50633_REG_LDO1OUT,
[PCF50633_REGULATOR_LDO2] = PCF50633_REG_LDO2OUT,
[PCF50633_REGULATOR_LDO3] = PCF50633_REG_LDO3OUT,
[PCF50633_REGULATOR_LDO4] = PCF50633_REG_LDO4OUT,
[PCF50633_REGULATOR_LDO5] = PCF50633_REG_LDO5OUT,
[PCF50633_REGULATOR_LDO6] = PCF50633_REG_LDO6OUT,
[PCF50633_REGULATOR_HCLDO] = PCF50633_REG_HCLDOOUT,
};
/* Bits from voltage value */
static u8 auto_voltage_bits(unsigned int millivolts)
{
if (millivolts < 1800)
return 0;
return 0x2f;
if (millivolts > 3800)
return 0xff;
@ -87,6 +77,9 @@ static u8 ldo_voltage_bits(unsigned int millivolts)
/* Obtain voltage value from bits */
static unsigned int auto_voltage_value(u8 bits)
{
/* AUTOOUT: 00000000 to 00101110 are reserved.
* Return 0 for bits in reserved range, which means this selector code
* can't be used on this system */
if (bits < 0x2f)
return 0;
@ -123,7 +116,7 @@ static int pcf50633_regulator_set_voltage(struct regulator_dev *rdev,
millivolts = min_uV / 1000;
regnr = pcf50633_regulator_registers[regulator_id];
regnr = rdev->desc->vsel_reg;
switch (regulator_id) {
case PCF50633_REGULATOR_AUTO:
@ -154,20 +147,22 @@ static int pcf50633_regulator_set_voltage(struct regulator_dev *rdev,
return pcf50633_reg_write(pcf, regnr, volt_bits);
}
static int pcf50633_regulator_voltage_value(enum pcf50633_regulator_id id,
u8 bits)
static int pcf50633_regulator_list_voltage(struct regulator_dev *rdev,
unsigned int index)
{
int regulator_id = rdev_get_id(rdev);
int millivolts;
switch (id) {
switch (regulator_id) {
case PCF50633_REGULATOR_AUTO:
millivolts = auto_voltage_value(bits);
millivolts = auto_voltage_value(index);
break;
case PCF50633_REGULATOR_DOWN1:
millivolts = down_voltage_value(bits);
millivolts = down_voltage_value(index);
break;
case PCF50633_REGULATOR_DOWN2:
millivolts = down_voltage_value(bits);
millivolts = down_voltage_value(index);
break;
case PCF50633_REGULATOR_LDO1:
case PCF50633_REGULATOR_LDO2:
@ -177,7 +172,7 @@ static int pcf50633_regulator_voltage_value(enum pcf50633_regulator_id id,
case PCF50633_REGULATOR_LDO6:
case PCF50633_REGULATOR_HCLDO:
case PCF50633_REGULATOR_MEMLDO:
millivolts = ldo_voltage_value(bits);
millivolts = ldo_voltage_value(index);
break;
default:
return -EINVAL;
@ -186,140 +181,44 @@ static int pcf50633_regulator_voltage_value(enum pcf50633_regulator_id id,
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;
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);
int regulator_id;
u8 regnr;
regulator_id = rdev_get_id(rdev);
if (regulator_id >= PCF50633_NUM_REGULATORS)
return -EINVAL;
/* The *ENA register is always one after the *OUT register */
regnr = pcf50633_regulator_registers[regulator_id] + 1;
return pcf50633_reg_set_bit_mask(pcf, regnr, PCF50633_REGULATOR_ON,
PCF50633_REGULATOR_ON);
}
static int pcf50633_regulator_disable(struct regulator_dev *rdev)
{
struct pcf50633 *pcf = rdev_get_drvdata(rdev);
int regulator_id;
u8 regnr;
regulator_id = rdev_get_id(rdev);
if (regulator_id >= PCF50633_NUM_REGULATORS)
return -EINVAL;
/* the *ENA register is always one after the *OUT register */
regnr = pcf50633_regulator_registers[regulator_id] + 1;
return pcf50633_reg_set_bit_mask(pcf, regnr,
PCF50633_REGULATOR_ON, 0);
}
static int pcf50633_regulator_is_enabled(struct regulator_dev *rdev)
{
struct pcf50633 *pcf = rdev_get_drvdata(rdev);
int regulator_id = rdev_get_id(rdev);
u8 regnr;
regulator_id = rdev_get_id(rdev);
if (regulator_id >= PCF50633_NUM_REGULATORS)
return -EINVAL;
/* the *ENA register is always one after the *OUT register */
regnr = pcf50633_regulator_registers[regulator_id] + 1;
return pcf50633_reg_read(pcf, regnr) & PCF50633_REGULATOR_ON;
}
static struct regulator_ops pcf50633_regulator_ops = {
.set_voltage = pcf50633_regulator_set_voltage,
.get_voltage = pcf50633_regulator_get_voltage,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.list_voltage = pcf50633_regulator_list_voltage,
.enable = pcf50633_regulator_enable,
.disable = pcf50633_regulator_disable,
.is_enabled = pcf50633_regulator_is_enabled,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,
};
static struct regulator_desc regulators[] = {
[PCF50633_REGULATOR_AUTO] =
PCF50633_REGULATOR("auto", PCF50633_REGULATOR_AUTO, 81),
[PCF50633_REGULATOR_DOWN1] =
PCF50633_REGULATOR("down1", PCF50633_REGULATOR_DOWN1, 96),
[PCF50633_REGULATOR_DOWN2] =
PCF50633_REGULATOR("down2", PCF50633_REGULATOR_DOWN2, 96),
[PCF50633_REGULATOR_LDO1] =
PCF50633_REGULATOR("ldo1", PCF50633_REGULATOR_LDO1, 28),
[PCF50633_REGULATOR_LDO2] =
PCF50633_REGULATOR("ldo2", PCF50633_REGULATOR_LDO2, 28),
[PCF50633_REGULATOR_LDO3] =
PCF50633_REGULATOR("ldo3", PCF50633_REGULATOR_LDO3, 28),
[PCF50633_REGULATOR_LDO4] =
PCF50633_REGULATOR("ldo4", PCF50633_REGULATOR_LDO4, 28),
[PCF50633_REGULATOR_LDO5] =
PCF50633_REGULATOR("ldo5", PCF50633_REGULATOR_LDO5, 28),
[PCF50633_REGULATOR_LDO6] =
PCF50633_REGULATOR("ldo6", PCF50633_REGULATOR_LDO6, 28),
[PCF50633_REGULATOR_HCLDO] =
PCF50633_REGULATOR("hcldo", PCF50633_REGULATOR_HCLDO, 28),
[PCF50633_REGULATOR_MEMLDO] =
PCF50633_REGULATOR("memldo", PCF50633_REGULATOR_MEMLDO, 28),
static const struct regulator_desc regulators[] = {
[PCF50633_REGULATOR_AUTO] = PCF50633_REGULATOR("auto", AUTO, 128),
[PCF50633_REGULATOR_DOWN1] = PCF50633_REGULATOR("down1", DOWN1, 96),
[PCF50633_REGULATOR_DOWN2] = PCF50633_REGULATOR("down2", DOWN2, 96),
[PCF50633_REGULATOR_LDO1] = PCF50633_REGULATOR("ldo1", LDO1, 28),
[PCF50633_REGULATOR_LDO2] = PCF50633_REGULATOR("ldo2", LDO2, 28),
[PCF50633_REGULATOR_LDO3] = PCF50633_REGULATOR("ldo3", LDO3, 28),
[PCF50633_REGULATOR_LDO4] = PCF50633_REGULATOR("ldo4", LDO4, 28),
[PCF50633_REGULATOR_LDO5] = PCF50633_REGULATOR("ldo5", LDO5, 28),
[PCF50633_REGULATOR_LDO6] = PCF50633_REGULATOR("ldo6", LDO6, 28),
[PCF50633_REGULATOR_HCLDO] = PCF50633_REGULATOR("hcldo", HCLDO, 28),
[PCF50633_REGULATOR_MEMLDO] = PCF50633_REGULATOR("memldo", MEMLDO, 28),
};
static int __devinit pcf50633_regulator_probe(struct platform_device *pdev)
{
struct regulator_dev *rdev;
struct pcf50633 *pcf;
struct regulator_config config = { };
/* Already set by core driver */
pcf = dev_to_pcf50633(pdev->dev.parent);
rdev = regulator_register(&regulators[pdev->id], &pdev->dev,
pdev->dev.platform_data, pcf, NULL);
config.dev = &pdev->dev;
config.init_data = pdev->dev.platform_data;
config.driver_data = pcf;
config.regmap = pcf->regmap;
rdev = regulator_register(&regulators[pdev->id], &config);
if (IS_ERR(rdev))
return PTR_ERR(rdev);

View File

@ -0,0 +1,295 @@
/*
* Regulator driver for RICOH RC5T583 power management chip.
*
* Copyright (c) 2011-2012, NVIDIA CORPORATION. All rights reserved.
* Author: Laxman dewangan <ldewangan@nvidia.com>
*
* based on code
* Copyright (C) 2011 RICOH COMPANY,LTD
*
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/err.h>
#include <linux/platform_device.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
#include <linux/gpio.h>
#include <linux/mfd/rc5t583.h>
struct rc5t583_regulator_info {
int deepsleep_id;
/* Regulator register address.*/
uint8_t reg_disc_reg;
uint8_t disc_bit;
uint8_t deepsleep_reg;
/* Chip constraints on regulator behavior */
int min_uV;
int max_uV;
int step_uV;
/* Regulator specific turn-on delay and voltage settling time*/
int enable_uv_per_us;
int change_uv_per_us;
/* Used by regulator core */
struct regulator_desc desc;
};
struct rc5t583_regulator {
struct rc5t583_regulator_info *reg_info;
/* Devices */
struct device *dev;
struct rc5t583 *mfd;
struct regulator_dev *rdev;
};
static int rc5t583_list_voltage(struct regulator_dev *rdev, unsigned selector)
{
struct rc5t583_regulator *reg = rdev_get_drvdata(rdev);
struct rc5t583_regulator_info *ri = reg->reg_info;
return ri->min_uV + (ri->step_uV * selector);
}
static int rc5t583_set_voltage(struct regulator_dev *rdev,
int min_uV, int max_uV, unsigned *selector)
{
struct rc5t583_regulator *reg = rdev_get_drvdata(rdev);
struct rc5t583_regulator_info *ri = reg->reg_info;
int sel, ret;
if (min_uV < ri->min_uV)
min_uV = ri->min_uV;
sel = DIV_ROUND_UP(min_uV - ri->min_uV, ri->step_uV);
if (sel >= rdev->desc->n_voltages) {
dev_err(&rdev->dev, "Invalid selector 0x%02x\n", sel);
return -EINVAL;
}
*selector = sel;
ret = rc5t583_update(reg->mfd->dev, rdev->desc->vsel_reg, sel,
rdev->desc->vsel_mask);
if (ret < 0)
dev_err(&rdev->dev, "Error in update voltage register 0x%02x\n",
rdev->desc->vsel_reg);
return ret;
}
static int rc5t583_regulator_enable_time(struct regulator_dev *rdev)
{
struct rc5t583_regulator *reg = rdev_get_drvdata(rdev);
int vsel = regulator_get_voltage_sel_regmap(rdev);
int curr_uV = rc5t583_list_voltage(rdev, vsel);
return DIV_ROUND_UP(curr_uV, reg->reg_info->enable_uv_per_us);
}
static int rc5t583_set_voltage_time_sel(struct regulator_dev *rdev,
unsigned int old_selector, unsigned int new_selector)
{
struct rc5t583_regulator *reg = rdev_get_drvdata(rdev);
int old_uV, new_uV;
old_uV = rc5t583_list_voltage(rdev, old_selector);
if (old_uV < 0)
return old_uV;
new_uV = rc5t583_list_voltage(rdev, new_selector);
if (new_uV < 0)
return new_uV;
return DIV_ROUND_UP(abs(old_uV - new_uV),
reg->reg_info->change_uv_per_us);
}
static struct regulator_ops rc5t583_ops = {
.is_enabled = regulator_is_enabled_regmap,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.enable_time = rc5t583_regulator_enable_time,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.set_voltage = rc5t583_set_voltage,
.list_voltage = rc5t583_list_voltage,
.set_voltage_time_sel = rc5t583_set_voltage_time_sel,
};
#define RC5T583_REG(_id, _en_reg, _en_bit, _disc_reg, _disc_bit, \
_vout_mask, _min_mv, _max_mv, _step_uV, _enable_mv) \
{ \
.reg_disc_reg = RC5T583_REG_##_disc_reg, \
.disc_bit = _disc_bit, \
.deepsleep_reg = RC5T583_REG_##_id##DAC_DS, \
.min_uV = _min_mv * 1000, \
.max_uV = _max_mv * 1000, \
.step_uV = _step_uV, \
.enable_uv_per_us = _enable_mv * 1000, \
.change_uv_per_us = 40 * 1000, \
.deepsleep_id = RC5T583_DS_##_id, \
.desc = { \
.name = "rc5t583-regulator-"#_id, \
.id = RC5T583_REGULATOR_##_id, \
.n_voltages = (_max_mv - _min_mv) * 1000 / _step_uV + 1, \
.ops = &rc5t583_ops, \
.type = REGULATOR_VOLTAGE, \
.owner = THIS_MODULE, \
.vsel_reg = RC5T583_REG_##_id##DAC, \
.vsel_mask = _vout_mask, \
.enable_reg = RC5T583_REG_##_en_reg, \
.enable_mask = BIT(_en_bit), \
}, \
}
static struct rc5t583_regulator_info rc5t583_reg_info[RC5T583_REGULATOR_MAX] = {
RC5T583_REG(DC0, DC0CTL, 0, DC0CTL, 1, 0x7F, 700, 1500, 12500, 4),
RC5T583_REG(DC1, DC1CTL, 0, DC1CTL, 1, 0x7F, 700, 1500, 12500, 14),
RC5T583_REG(DC2, DC2CTL, 0, DC2CTL, 1, 0x7F, 900, 2400, 12500, 14),
RC5T583_REG(DC3, DC3CTL, 0, DC3CTL, 1, 0x7F, 900, 2400, 12500, 14),
RC5T583_REG(LDO0, LDOEN2, 0, LDODIS2, 0, 0x7F, 900, 3400, 25000, 160),
RC5T583_REG(LDO1, LDOEN2, 1, LDODIS2, 1, 0x7F, 900, 3400, 25000, 160),
RC5T583_REG(LDO2, LDOEN2, 2, LDODIS2, 2, 0x7F, 900, 3400, 25000, 160),
RC5T583_REG(LDO3, LDOEN2, 3, LDODIS2, 3, 0x7F, 900, 3400, 25000, 160),
RC5T583_REG(LDO4, LDOEN2, 4, LDODIS2, 4, 0x3F, 750, 1500, 12500, 133),
RC5T583_REG(LDO5, LDOEN2, 5, LDODIS2, 5, 0x7F, 900, 3400, 25000, 267),
RC5T583_REG(LDO6, LDOEN2, 6, LDODIS2, 6, 0x7F, 900, 3400, 25000, 133),
RC5T583_REG(LDO7, LDOEN2, 7, LDODIS2, 7, 0x7F, 900, 3400, 25000, 233),
RC5T583_REG(LDO8, LDOEN1, 0, LDODIS1, 0, 0x7F, 900, 3400, 25000, 233),
RC5T583_REG(LDO9, LDOEN1, 1, LDODIS1, 1, 0x7F, 900, 3400, 25000, 133),
};
static int __devinit rc5t583_regulator_probe(struct platform_device *pdev)
{
struct rc5t583 *rc5t583 = dev_get_drvdata(pdev->dev.parent);
struct rc5t583_platform_data *pdata = dev_get_platdata(rc5t583->dev);
struct regulator_init_data *reg_data;
struct regulator_config config = { };
struct rc5t583_regulator *reg = NULL;
struct rc5t583_regulator *regs;
struct regulator_dev *rdev;
struct rc5t583_regulator_info *ri;
int ret;
int id;
if (!pdata) {
dev_err(&pdev->dev, "No platform data, exiting...\n");
return -ENODEV;
}
regs = devm_kzalloc(&pdev->dev, RC5T583_REGULATOR_MAX *
sizeof(struct rc5t583_regulator), GFP_KERNEL);
if (!regs) {
dev_err(&pdev->dev, "Memory allocation failed exiting..\n");
return -ENOMEM;
}
for (id = 0; id < RC5T583_REGULATOR_MAX; ++id) {
reg_data = pdata->reg_init_data[id];
/* No need to register if there is no regulator data */
if (!reg_data)
continue;
reg = &regs[id];
ri = &rc5t583_reg_info[id];
reg->reg_info = ri;
reg->mfd = rc5t583;
reg->dev = &pdev->dev;
if (ri->deepsleep_id == RC5T583_DS_NONE)
goto skip_ext_pwr_config;
ret = rc5t583_ext_power_req_config(rc5t583->dev,
ri->deepsleep_id,
pdata->regulator_ext_pwr_control[id],
pdata->regulator_deepsleep_slot[id]);
/*
* Configuring external control is not a major issue,
* just give warning.
*/
if (ret < 0)
dev_warn(&pdev->dev,
"Failed to configure ext control %d\n", id);
skip_ext_pwr_config:
config.dev = &pdev->dev;
config.init_data = reg_data;
config.driver_data = reg;
config.regmap = rc5t583->regmap;
rdev = regulator_register(&ri->desc, &config);
if (IS_ERR(rdev)) {
dev_err(&pdev->dev, "Failed to register regulator %s\n",
ri->desc.name);
ret = PTR_ERR(rdev);
goto clean_exit;
}
reg->rdev = rdev;
}
platform_set_drvdata(pdev, regs);
return 0;
clean_exit:
while (--id >= 0)
regulator_unregister(regs[id].rdev);
return ret;
}
static int __devexit rc5t583_regulator_remove(struct platform_device *pdev)
{
struct rc5t583_regulator *regs = platform_get_drvdata(pdev);
int id;
for (id = 0; id < RC5T583_REGULATOR_MAX; ++id)
regulator_unregister(regs[id].rdev);
return 0;
}
static struct platform_driver rc5t583_regulator_driver = {
.driver = {
.name = "rc5t583-regulator",
.owner = THIS_MODULE,
},
.probe = rc5t583_regulator_probe,
.remove = __devexit_p(rc5t583_regulator_remove),
};
static int __init rc5t583_regulator_init(void)
{
return platform_driver_register(&rc5t583_regulator_driver);
}
subsys_initcall(rc5t583_regulator_init);
static void __exit rc5t583_regulator_exit(void)
{
platform_driver_unregister(&rc5t583_regulator_driver);
}
module_exit(rc5t583_regulator_exit);
MODULE_AUTHOR("Laxman Dewangan <ldewangan@nvidia.com>");
MODULE_DESCRIPTION("RC5T583 regulator driver");
MODULE_ALIAS("platform:rc5t583-regulator");
MODULE_LICENSE("GPL v2");

View File

@ -28,6 +28,7 @@ struct s5m8767_info {
struct s5m87xx_dev *iodev;
int num_regulators;
struct regulator_dev **rdev;
struct s5m_opmode_data *opmode;
int ramp_delay;
bool buck2_ramp;
@ -141,9 +142,56 @@ static int s5m8767_list_voltage(struct regulator_dev *rdev,
return val;
}
static int s5m8767_get_register(struct regulator_dev *rdev, int *reg)
unsigned int s5m8767_opmode_reg[][4] = {
/* {OFF, ON, LOWPOWER, SUSPEND} */
/* LDO1 ... LDO28 */
{0x0, 0x3, 0x2, 0x1}, /* LDO1 */
{0x0, 0x3, 0x2, 0x1},
{0x0, 0x3, 0x2, 0x1},
{0x0, 0x0, 0x0, 0x0},
{0x0, 0x3, 0x2, 0x1}, /* LDO5 */
{0x0, 0x3, 0x2, 0x1},
{0x0, 0x3, 0x2, 0x1},
{0x0, 0x3, 0x2, 0x1},
{0x0, 0x3, 0x2, 0x1},
{0x0, 0x3, 0x2, 0x1}, /* LDO10 */
{0x0, 0x3, 0x2, 0x1},
{0x0, 0x3, 0x2, 0x1},
{0x0, 0x3, 0x2, 0x1},
{0x0, 0x3, 0x2, 0x1},
{0x0, 0x3, 0x2, 0x1}, /* LDO15 */
{0x0, 0x3, 0x2, 0x1},
{0x0, 0x3, 0x2, 0x1},
{0x0, 0x0, 0x0, 0x0},
{0x0, 0x3, 0x2, 0x1},
{0x0, 0x3, 0x2, 0x1}, /* LDO20 */
{0x0, 0x3, 0x2, 0x1},
{0x0, 0x3, 0x2, 0x1},
{0x0, 0x0, 0x0, 0x0},
{0x0, 0x3, 0x2, 0x1},
{0x0, 0x3, 0x2, 0x1}, /* LDO25 */
{0x0, 0x3, 0x2, 0x1},
{0x0, 0x3, 0x2, 0x1},
{0x0, 0x3, 0x2, 0x1}, /* LDO28 */
/* BUCK1 ... BUCK9 */
{0x0, 0x3, 0x1, 0x1}, /* BUCK1 */
{0x0, 0x3, 0x1, 0x1},
{0x0, 0x3, 0x1, 0x1},
{0x0, 0x3, 0x1, 0x1},
{0x0, 0x3, 0x2, 0x1}, /* BUCK5 */
{0x0, 0x3, 0x1, 0x1},
{0x0, 0x3, 0x1, 0x1},
{0x0, 0x3, 0x1, 0x1},
{0x0, 0x3, 0x1, 0x1}, /* BUCK9 */
};
static int s5m8767_get_register(struct regulator_dev *rdev, int *reg,
int *enable_ctrl)
{
int reg_id = rdev_get_id(rdev);
unsigned int mode;
struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev);
switch (reg_id) {
case S5M8767_LDO1 ... S5M8767_LDO2:
@ -168,6 +216,8 @@ static int s5m8767_get_register(struct regulator_dev *rdev, int *reg)
return -EINVAL;
}
mode = s5m8767->opmode[reg_id].mode;
*enable_ctrl = s5m8767_opmode_reg[reg_id][mode] << S5M8767_ENCTRL_SHIFT;
return 0;
}
@ -175,10 +225,10 @@ static int s5m8767_reg_is_enabled(struct regulator_dev *rdev)
{
struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev);
int ret, reg;
int mask = 0xc0, pattern = 0xc0;
int mask = 0xc0, enable_ctrl;
u8 val;
ret = s5m8767_get_register(rdev, &reg);
ret = s5m8767_get_register(rdev, &reg, &enable_ctrl);
if (ret == -EINVAL)
return 1;
else if (ret)
@ -188,33 +238,33 @@ static int s5m8767_reg_is_enabled(struct regulator_dev *rdev)
if (ret)
return ret;
return (val & mask) == pattern;
return (val & mask) == enable_ctrl;
}
static int s5m8767_reg_enable(struct regulator_dev *rdev)
{
struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev);
int ret, reg;
int mask = 0xc0, pattern = 0xc0;
int mask = 0xc0, enable_ctrl;
ret = s5m8767_get_register(rdev, &reg);
ret = s5m8767_get_register(rdev, &reg, &enable_ctrl);
if (ret)
return ret;
return s5m_reg_update(s5m8767->iodev, reg, pattern, mask);
return s5m_reg_update(s5m8767->iodev, reg, enable_ctrl, mask);
}
static int s5m8767_reg_disable(struct regulator_dev *rdev)
{
struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev);
int ret, reg;
int mask = 0xc0, pattern = 0xc0;
int mask = 0xc0, enable_ctrl;
ret = s5m8767_get_register(rdev, &reg);
ret = s5m8767_get_register(rdev, &reg, &enable_ctrl);
if (ret)
return ret;
return s5m_reg_update(s5m8767->iodev, reg, ~pattern, mask);
return s5m_reg_update(s5m8767->iodev, reg, ~mask, mask);
}
static int s5m8767_get_voltage_register(struct regulator_dev *rdev, int *_reg)
@ -305,51 +355,6 @@ static int s5m8767_convert_voltage_to_sel(
return selector;
}
static int s5m8767_set_voltage(struct regulator_dev *rdev,
int min_uV, int max_uV, unsigned *selector)
{
struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev);
const struct s5m_voltage_desc *desc;
int reg_id = rdev_get_id(rdev);
int sel, reg, mask, ret;
u8 val;
switch (reg_id) {
case S5M8767_LDO1 ... S5M8767_LDO28:
mask = 0x3f;
break;
case S5M8767_BUCK1 ... S5M8767_BUCK6:
mask = 0xff;
break;
case S5M8767_BUCK7 ... S5M8767_BUCK8:
return -EINVAL;
case S5M8767_BUCK9:
mask = 0xff;
break;
default:
return -EINVAL;
}
desc = reg_voltage_map[reg_id];
sel = s5m8767_convert_voltage_to_sel(desc, min_uV, max_uV);
if (sel < 0)
return sel;
ret = s5m8767_get_voltage_register(rdev, &reg);
if (ret)
return ret;
s5m_reg_read(s5m8767->iodev, reg, &val);
val &= ~mask;
val |= sel;
ret = s5m_reg_write(s5m8767->iodev, reg, val);
*selector = sel;
return ret;
}
static inline void s5m8767_set_high(struct s5m8767_info *s5m8767)
{
int temp_index = s5m8767->buck_gpioindex;
@ -368,70 +373,70 @@ static inline void s5m8767_set_low(struct s5m8767_info *s5m8767)
gpio_set_value(s5m8767->buck_gpios[0], (temp_index >> 2) & 0x1);
}
static int s5m8767_set_voltage_buck(struct regulator_dev *rdev,
int min_uV, int max_uV, unsigned *selector)
static int s5m8767_set_voltage(struct regulator_dev *rdev,
int min_uV, int max_uV, unsigned *selector)
{
struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev);
int reg_id = rdev_get_id(rdev);
const struct s5m_voltage_desc *desc;
int new_val, old_val, i = 0;
if (reg_id < S5M8767_BUCK1 || reg_id > S5M8767_BUCK6)
return -EINVAL;
int reg_id = rdev_get_id(rdev);
int sel, reg, mask, ret = 0, old_index, index = 0;
u8 val;
u8 *buck234_vol = NULL;
switch (reg_id) {
case S5M8767_BUCK1:
return s5m8767_set_voltage(rdev, min_uV, max_uV, selector);
case S5M8767_BUCK2 ... S5M8767_BUCK4:
case S5M8767_LDO1 ... S5M8767_LDO28:
mask = 0x3f;
break;
case S5M8767_BUCK5 ... S5M8767_BUCK6:
return s5m8767_set_voltage(rdev, min_uV, max_uV, selector);
case S5M8767_BUCK1 ... S5M8767_BUCK6:
mask = 0xff;
if (reg_id == S5M8767_BUCK2 && s5m8767->buck2_gpiodvs)
buck234_vol = &s5m8767->buck2_vol[0];
else if (reg_id == S5M8767_BUCK3 && s5m8767->buck3_gpiodvs)
buck234_vol = &s5m8767->buck3_vol[0];
else if (reg_id == S5M8767_BUCK4 && s5m8767->buck4_gpiodvs)
buck234_vol = &s5m8767->buck4_vol[0];
break;
case S5M8767_BUCK7 ... S5M8767_BUCK8:
return -EINVAL;
case S5M8767_BUCK9:
return s5m8767_set_voltage(rdev, min_uV, max_uV, selector);
mask = 0xff;
break;
default:
return -EINVAL;
}
desc = reg_voltage_map[reg_id];
new_val = s5m8767_convert_voltage_to_sel(desc, min_uV, max_uV);
if (new_val < 0)
return new_val;
switch (reg_id) {
case S5M8767_BUCK2:
if (s5m8767->buck2_gpiodvs) {
while (s5m8767->buck2_vol[i] != new_val)
i++;
} else
return s5m8767_set_voltage(rdev, min_uV,
max_uV, selector);
break;
case S5M8767_BUCK3:
if (s5m8767->buck3_gpiodvs) {
while (s5m8767->buck3_vol[i] != new_val)
i++;
} else
return s5m8767_set_voltage(rdev, min_uV,
max_uV, selector);
break;
case S5M8767_BUCK4:
if (s5m8767->buck3_gpiodvs) {
while (s5m8767->buck4_vol[i] != new_val)
i++;
} else
return s5m8767_set_voltage(rdev, min_uV,
max_uV, selector);
break;
sel = s5m8767_convert_voltage_to_sel(desc, min_uV, max_uV);
if (sel < 0)
return sel;
/* buck234_vol != NULL means to control buck234 voltage via DVS GPIO */
if (buck234_vol) {
while (*buck234_vol != sel) {
buck234_vol++;
index++;
}
old_index = s5m8767->buck_gpioindex;
s5m8767->buck_gpioindex = index;
if (index > old_index)
s5m8767_set_high(s5m8767);
else
s5m8767_set_low(s5m8767);
} else {
ret = s5m8767_get_voltage_register(rdev, &reg);
if (ret)
return ret;
s5m_reg_read(s5m8767->iodev, reg, &val);
val = (val & ~mask) | sel;
ret = s5m_reg_write(s5m8767->iodev, reg, val);
}
old_val = s5m8767->buck_gpioindex;
s5m8767->buck_gpioindex = i;
if (i > old_val)
s5m8767_set_high(s5m8767);
else
s5m8767_set_low(s5m8767);
*selector = new_val;
return 0;
*selector = sel;
return ret;
}
static int s5m8767_set_voltage_time_sel(struct regulator_dev *rdev,
@ -450,7 +455,7 @@ static int s5m8767_set_voltage_time_sel(struct regulator_dev *rdev,
return 0;
}
static struct regulator_ops s5m8767_ldo_ops = {
static struct regulator_ops s5m8767_ops = {
.list_voltage = s5m8767_list_voltage,
.is_enabled = s5m8767_reg_is_enabled,
.enable = s5m8767_reg_enable,
@ -460,75 +465,59 @@ static struct regulator_ops s5m8767_ldo_ops = {
.set_voltage_time_sel = s5m8767_set_voltage_time_sel,
};
static struct regulator_ops s5m8767_buck_ops = {
.list_voltage = s5m8767_list_voltage,
.is_enabled = s5m8767_reg_is_enabled,
.enable = s5m8767_reg_enable,
.disable = s5m8767_reg_disable,
.get_voltage_sel = s5m8767_get_voltage_sel,
.set_voltage = s5m8767_set_voltage_buck,
.set_voltage_time_sel = s5m8767_set_voltage_time_sel,
};
#define regulator_desc_ldo(num) { \
.name = "LDO"#num, \
.id = S5M8767_LDO##num, \
.ops = &s5m8767_ldo_ops, \
.type = REGULATOR_VOLTAGE, \
.owner = THIS_MODULE, \
}
#define regulator_desc_buck(num) { \
.name = "BUCK"#num, \
.id = S5M8767_BUCK##num, \
.ops = &s5m8767_buck_ops, \
#define s5m8767_regulator_desc(_name) { \
.name = #_name, \
.id = S5M8767_##_name, \
.ops = &s5m8767_ops, \
.type = REGULATOR_VOLTAGE, \
.owner = THIS_MODULE, \
}
static struct regulator_desc regulators[] = {
regulator_desc_ldo(1),
regulator_desc_ldo(2),
regulator_desc_ldo(3),
regulator_desc_ldo(4),
regulator_desc_ldo(5),
regulator_desc_ldo(6),
regulator_desc_ldo(7),
regulator_desc_ldo(8),
regulator_desc_ldo(9),
regulator_desc_ldo(10),
regulator_desc_ldo(11),
regulator_desc_ldo(12),
regulator_desc_ldo(13),
regulator_desc_ldo(14),
regulator_desc_ldo(15),
regulator_desc_ldo(16),
regulator_desc_ldo(17),
regulator_desc_ldo(18),
regulator_desc_ldo(19),
regulator_desc_ldo(20),
regulator_desc_ldo(21),
regulator_desc_ldo(22),
regulator_desc_ldo(23),
regulator_desc_ldo(24),
regulator_desc_ldo(25),
regulator_desc_ldo(26),
regulator_desc_ldo(27),
regulator_desc_ldo(28),
regulator_desc_buck(1),
regulator_desc_buck(2),
regulator_desc_buck(3),
regulator_desc_buck(4),
regulator_desc_buck(5),
regulator_desc_buck(6),
regulator_desc_buck(7),
regulator_desc_buck(8),
regulator_desc_buck(9),
s5m8767_regulator_desc(LDO1),
s5m8767_regulator_desc(LDO2),
s5m8767_regulator_desc(LDO3),
s5m8767_regulator_desc(LDO4),
s5m8767_regulator_desc(LDO5),
s5m8767_regulator_desc(LDO6),
s5m8767_regulator_desc(LDO7),
s5m8767_regulator_desc(LDO8),
s5m8767_regulator_desc(LDO9),
s5m8767_regulator_desc(LDO10),
s5m8767_regulator_desc(LDO11),
s5m8767_regulator_desc(LDO12),
s5m8767_regulator_desc(LDO13),
s5m8767_regulator_desc(LDO14),
s5m8767_regulator_desc(LDO15),
s5m8767_regulator_desc(LDO16),
s5m8767_regulator_desc(LDO17),
s5m8767_regulator_desc(LDO18),
s5m8767_regulator_desc(LDO19),
s5m8767_regulator_desc(LDO20),
s5m8767_regulator_desc(LDO21),
s5m8767_regulator_desc(LDO22),
s5m8767_regulator_desc(LDO23),
s5m8767_regulator_desc(LDO24),
s5m8767_regulator_desc(LDO25),
s5m8767_regulator_desc(LDO26),
s5m8767_regulator_desc(LDO27),
s5m8767_regulator_desc(LDO28),
s5m8767_regulator_desc(BUCK1),
s5m8767_regulator_desc(BUCK2),
s5m8767_regulator_desc(BUCK3),
s5m8767_regulator_desc(BUCK4),
s5m8767_regulator_desc(BUCK5),
s5m8767_regulator_desc(BUCK6),
s5m8767_regulator_desc(BUCK7),
s5m8767_regulator_desc(BUCK8),
s5m8767_regulator_desc(BUCK9),
};
static __devinit int s5m8767_pmic_probe(struct platform_device *pdev)
{
struct s5m87xx_dev *iodev = dev_get_drvdata(pdev->dev.parent);
struct s5m_platform_data *pdata = dev_get_platdata(iodev->dev);
struct regulator_config config = { };
struct regulator_dev **rdev;
struct s5m8767_info *s5m8767;
int i, ret, size;
@ -586,6 +575,7 @@ static __devinit int s5m8767_pmic_probe(struct platform_device *pdev)
s5m8767->buck2_ramp = pdata->buck2_ramp_enable;
s5m8767->buck3_ramp = pdata->buck3_ramp_enable;
s5m8767->buck4_ramp = pdata->buck4_ramp_enable;
s5m8767->opmode = pdata->opmode;
for (i = 0; i < 8; i++) {
if (s5m8767->buck2_gpiodvs) {
@ -723,8 +713,11 @@ static __devinit int s5m8767_pmic_probe(struct platform_device *pdev)
regulators[id].n_voltages =
(desc->max - desc->min) / desc->step + 1;
rdev[i] = regulator_register(&regulators[id], s5m8767->dev,
pdata->regulators[i].initdata, s5m8767, NULL);
config.dev = s5m8767->dev;
config.init_data = pdata->regulators[i].initdata;
config.driver_data = s5m8767;
rdev[i] = regulator_register(&regulators[id], &config);
if (IS_ERR(rdev[i])) {
ret = PTR_ERR(rdev[i]);
dev_err(s5m8767->dev, "regulator init failed for %d\n",

View File

@ -123,7 +123,7 @@ static struct regulator_ops tps6105x_regulator_ops = {
.list_voltage = tps6105x_regulator_list_voltage,
};
static struct regulator_desc tps6105x_regulator_desc = {
static const struct regulator_desc tps6105x_regulator_desc = {
.name = "tps6105x-boost",
.ops = &tps6105x_regulator_ops,
.type = REGULATOR_VOLTAGE,
@ -139,6 +139,7 @@ static int __devinit tps6105x_regulator_probe(struct platform_device *pdev)
{
struct tps6105x *tps6105x = dev_get_platdata(&pdev->dev);
struct tps6105x_platform_data *pdata = tps6105x->pdata;
struct regulator_config config = { };
int ret;
/* This instance is not set for regulator mode so bail out */
@ -148,11 +149,13 @@ static int __devinit tps6105x_regulator_probe(struct platform_device *pdev)
return 0;
}
config.dev = &tps6105x->client->dev;
config.init_data = pdata->regulator_data;
config.driver_data = tps6105x;
/* Register regulator with framework */
tps6105x->regulator = regulator_register(&tps6105x_regulator_desc,
&tps6105x->client->dev,
pdata->regulator_data, tps6105x,
NULL);
&config);
if (IS_ERR(tps6105x->regulator)) {
ret = PTR_ERR(tps6105x->regulator);
dev_err(&tps6105x->client->dev,

View File

@ -1,7 +1,7 @@
/*
* tps62360.c -- TI tps62360
*
* Driver for processor core supply tps62360 and tps62361B
* Driver for processor core supply tps62360, tps62361B, tps62362 and tps62363.
*
* Copyright (c) 2012, NVIDIA Corporation.
*
@ -46,7 +46,7 @@
#define REG_RAMPCTRL 6
#define REG_CHIPID 8
enum chips {TPS62360, TPS62361};
enum chips {TPS62360, TPS62361, TPS62362, TPS62363};
#define TPS62360_BASE_VOLTAGE 770
#define TPS62360_N_VOLTAGES 64
@ -56,10 +56,8 @@ enum chips {TPS62360, TPS62361};
/* tps 62360 chip information */
struct tps62360_chip {
const char *name;
struct device *dev;
struct regulator_desc desc;
struct i2c_client *client;
struct regulator_dev *rdev;
struct regmap *regmap;
int chip_id;
@ -272,6 +270,7 @@ static const struct regmap_config tps62360_regmap_config = {
static int __devinit tps62360_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct regulator_config config = { };
struct tps62360_regulator_platform_data *pdata;
struct regulator_dev *rdev;
struct tps62360_chip *tps;
@ -297,21 +296,31 @@ static int __devinit tps62360_probe(struct i2c_client *client,
tps->en_internal_pulldn = pdata->en_internal_pulldn;
tps->vsel0_gpio = pdata->vsel0_gpio;
tps->vsel1_gpio = pdata->vsel1_gpio;
tps->client = client;
tps->dev = &client->dev;
tps->name = id->name;
tps->voltage_base = (id->driver_data == TPS62360) ?
TPS62360_BASE_VOLTAGE : TPS62361_BASE_VOLTAGE;
tps->voltage_reg_mask = (id->driver_data == TPS62360) ? 0x3F : 0x7F;
switch (id->driver_data) {
case TPS62360:
case TPS62362:
tps->voltage_base = TPS62360_BASE_VOLTAGE;
tps->voltage_reg_mask = 0x3F;
tps->desc.n_voltages = TPS62360_N_VOLTAGES;
break;
case TPS62361:
case TPS62363:
tps->voltage_base = TPS62361_BASE_VOLTAGE;
tps->voltage_reg_mask = 0x7F;
tps->desc.n_voltages = TPS62361_N_VOLTAGES;
break;
default:
return -ENODEV;
}
tps->desc.name = id->name;
tps->desc.id = 0;
tps->desc.n_voltages = (id->driver_data == TPS62360) ?
TPS62360_N_VOLTAGES : TPS62361_N_VOLTAGES;
tps->desc.ops = &tps62360_dcdc_ops;
tps->desc.type = REGULATOR_VOLTAGE;
tps->desc.owner = THIS_MODULE;
tps->regmap = regmap_init_i2c(client, &tps62360_regmap_config);
tps->regmap = devm_regmap_init_i2c(client, &tps62360_regmap_config);
if (IS_ERR(tps->regmap)) {
ret = PTR_ERR(tps->regmap);
dev_err(&client->dev, "%s() Err: Failed to allocate register"
@ -376,9 +385,12 @@ static int __devinit tps62360_probe(struct i2c_client *client,
goto err_init;
}
config.dev = &client->dev;
config.init_data = &pdata->reg_init_data;
config.driver_data = tps;
/* Register the regulators */
rdev = regulator_register(&tps->desc, &client->dev,
&pdata->reg_init_data, tps, NULL);
rdev = regulator_register(&tps->desc, &config);
if (IS_ERR(rdev)) {
dev_err(tps->dev, "%s() Err: Failed to register %s\n",
__func__, id->name);
@ -396,7 +408,6 @@ err_gpio1:
if (gpio_is_valid(tps->vsel0_gpio))
gpio_free(tps->vsel0_gpio);
err_gpio0:
regmap_exit(tps->regmap);
return ret;
}
@ -417,7 +428,6 @@ static int __devexit tps62360_remove(struct i2c_client *client)
gpio_free(tps->vsel0_gpio);
regulator_unregister(tps->rdev);
regmap_exit(tps->regmap);
return 0;
}
@ -439,6 +449,8 @@ static void tps62360_shutdown(struct i2c_client *client)
static const struct i2c_device_id tps62360_id[] = {
{.name = "tps62360", .driver_data = TPS62360},
{.name = "tps62361", .driver_data = TPS62361},
{.name = "tps62362", .driver_data = TPS62362},
{.name = "tps62363", .driver_data = TPS62363},
{},
};
@ -468,5 +480,5 @@ static void __exit tps62360_cleanup(void)
module_exit(tps62360_cleanup);
MODULE_AUTHOR("Laxman Dewangan <ldewangan@nvidia.com>");
MODULE_DESCRIPTION("TPS62360 voltage regulator driver");
MODULE_DESCRIPTION("TPS6236x voltage regulator driver");
MODULE_LICENSE("GPL v2");

View File

@ -72,7 +72,7 @@
/* LDO_CTRL bitfields */
#define TPS65023_LDO_CTRL_LDOx_SHIFT(ldo_id) ((ldo_id)*4)
#define TPS65023_LDO_CTRL_LDOx_MASK(ldo_id) (0xF0 >> ((ldo_id)*4))
#define TPS65023_LDO_CTRL_LDOx_MASK(ldo_id) (0x0F << ((ldo_id)*4))
/* Number of step-down converters available */
#define TPS65023_NUM_DCDC 3
@ -139,7 +139,6 @@ struct tps_info {
/* PMIC details */
struct tps_pmic {
struct regulator_desc desc[TPS65023_NUM_REGULATOR];
struct i2c_client *client;
struct regulator_dev *rdev[TPS65023_NUM_REGULATOR];
const struct tps_info *info[TPS65023_NUM_REGULATOR];
struct regmap *regmap;
@ -152,96 +151,6 @@ struct tps_driver_data {
u8 core_regulator;
};
static int tps65023_dcdc_is_enabled(struct regulator_dev *dev)
{
struct tps_pmic *tps = rdev_get_drvdata(dev);
int data, dcdc = rdev_get_id(dev);
int ret;
u8 shift;
if (dcdc < TPS65023_DCDC_1 || dcdc > TPS65023_DCDC_3)
return -EINVAL;
shift = TPS65023_NUM_REGULATOR - dcdc;
ret = regmap_read(tps->regmap, TPS65023_REG_REG_CTRL, &data);
if (ret != 0)
return ret;
else
return (data & 1<<shift) ? 1 : 0;
}
static int tps65023_ldo_is_enabled(struct regulator_dev *dev)
{
struct tps_pmic *tps = rdev_get_drvdata(dev);
int data, ldo = rdev_get_id(dev);
int ret;
u8 shift;
if (ldo < TPS65023_LDO_1 || ldo > TPS65023_LDO_2)
return -EINVAL;
shift = (ldo == TPS65023_LDO_1 ? 1 : 2);
ret = regmap_read(tps->regmap, TPS65023_REG_REG_CTRL, &data);
if (ret != 0)
return ret;
else
return (data & 1<<shift) ? 1 : 0;
}
static int tps65023_dcdc_enable(struct regulator_dev *dev)
{
struct tps_pmic *tps = rdev_get_drvdata(dev);
int dcdc = rdev_get_id(dev);
u8 shift;
if (dcdc < TPS65023_DCDC_1 || dcdc > TPS65023_DCDC_3)
return -EINVAL;
shift = TPS65023_NUM_REGULATOR - dcdc;
return regmap_update_bits(tps->regmap, TPS65023_REG_REG_CTRL, 1 << shift, 1 << shift);
}
static int tps65023_dcdc_disable(struct regulator_dev *dev)
{
struct tps_pmic *tps = rdev_get_drvdata(dev);
int dcdc = rdev_get_id(dev);
u8 shift;
if (dcdc < TPS65023_DCDC_1 || dcdc > TPS65023_DCDC_3)
return -EINVAL;
shift = TPS65023_NUM_REGULATOR - dcdc;
return regmap_update_bits(tps->regmap, TPS65023_REG_REG_CTRL, 1 << shift, 0);
}
static int tps65023_ldo_enable(struct regulator_dev *dev)
{
struct tps_pmic *tps = rdev_get_drvdata(dev);
int ldo = rdev_get_id(dev);
u8 shift;
if (ldo < TPS65023_LDO_1 || ldo > TPS65023_LDO_2)
return -EINVAL;
shift = (ldo == TPS65023_LDO_1 ? 1 : 2);
return regmap_update_bits(tps->regmap, TPS65023_REG_REG_CTRL, 1 << shift, 1 << shift);
}
static int tps65023_ldo_disable(struct regulator_dev *dev)
{
struct tps_pmic *tps = rdev_get_drvdata(dev);
int ldo = rdev_get_id(dev);
u8 shift;
if (ldo < TPS65023_LDO_1 || ldo > TPS65023_LDO_2)
return -EINVAL;
shift = (ldo == TPS65023_LDO_1 ? 1 : 2);
return regmap_update_bits(tps->regmap, TPS65023_REG_REG_CTRL, 1 << shift, 0);
}
static int tps65023_dcdc_get_voltage(struct regulator_dev *dev)
{
struct tps_pmic *tps = rdev_get_drvdata(dev);
@ -261,50 +170,28 @@ static int tps65023_dcdc_get_voltage(struct regulator_dev *dev)
return tps->info[dcdc]->min_uV;
}
static int tps65023_dcdc_set_voltage(struct regulator_dev *dev,
int min_uV, int max_uV,
unsigned *selector)
static int tps65023_dcdc_set_voltage_sel(struct regulator_dev *dev,
unsigned selector)
{
struct tps_pmic *tps = rdev_get_drvdata(dev);
int dcdc = rdev_get_id(dev);
int vsel;
int ret;
if (dcdc != tps->core_regulator)
return -EINVAL;
if (min_uV < tps->info[dcdc]->min_uV
|| min_uV > tps->info[dcdc]->max_uV)
return -EINVAL;
if (max_uV < tps->info[dcdc]->min_uV
|| max_uV > tps->info[dcdc]->max_uV)
return -EINVAL;
for (vsel = 0; vsel < tps->info[dcdc]->table_len; vsel++) {
int mV = tps->info[dcdc]->table[vsel];
int uV = mV * 1000;
/* Break at the first in-range value */
if (min_uV <= uV && uV <= max_uV)
break;
}
*selector = vsel;
if (vsel == tps->info[dcdc]->table_len)
goto failed;
ret = regmap_write(tps->regmap, TPS65023_REG_DEF_CORE, vsel);
ret = regmap_write(tps->regmap, TPS65023_REG_DEF_CORE, selector);
if (ret)
goto out;
/* Tell the chip that we have changed the value in DEFCORE
* and its time to update the core voltage
*/
regmap_update_bits(tps->regmap, TPS65023_REG_CON_CTRL2,
TPS65023_REG_CTRL2_GO, TPS65023_REG_CTRL2_GO);
ret = regmap_update_bits(tps->regmap, TPS65023_REG_CON_CTRL2,
TPS65023_REG_CTRL2_GO, TPS65023_REG_CTRL2_GO);
out:
return ret;
failed:
return -EINVAL;
}
static int tps65023_ldo_get_voltage(struct regulator_dev *dev)
@ -325,42 +212,15 @@ static int tps65023_ldo_get_voltage(struct regulator_dev *dev)
return tps->info[ldo]->table[data] * 1000;
}
static int tps65023_ldo_set_voltage(struct regulator_dev *dev,
int min_uV, int max_uV, unsigned *selector)
static int tps65023_ldo_set_voltage_sel(struct regulator_dev *dev,
unsigned selector)
{
struct tps_pmic *tps = rdev_get_drvdata(dev);
int data, vsel, ldo = rdev_get_id(dev);
int ret;
int ldo_index = rdev_get_id(dev) - TPS65023_LDO_1;
if (ldo < TPS65023_LDO_1 || ldo > TPS65023_LDO_2)
return -EINVAL;
if (min_uV < tps->info[ldo]->min_uV || min_uV > tps->info[ldo]->max_uV)
return -EINVAL;
if (max_uV < tps->info[ldo]->min_uV || max_uV > tps->info[ldo]->max_uV)
return -EINVAL;
for (vsel = 0; vsel < tps->info[ldo]->table_len; vsel++) {
int mV = tps->info[ldo]->table[vsel];
int uV = mV * 1000;
/* Break at the first in-range value */
if (min_uV <= uV && uV <= max_uV)
break;
}
if (vsel == tps->info[ldo]->table_len)
return -EINVAL;
*selector = vsel;
ret = regmap_read(tps->regmap, TPS65023_REG_LDO_CTRL, &data);
if (ret != 0)
return ret;
data &= TPS65023_LDO_CTRL_LDOx_MASK(ldo - TPS65023_LDO_1);
data |= (vsel << (TPS65023_LDO_CTRL_LDOx_SHIFT(ldo - TPS65023_LDO_1)));
return regmap_write(tps->regmap, TPS65023_REG_LDO_CTRL, data);
return regmap_update_bits(tps->regmap, TPS65023_REG_LDO_CTRL,
TPS65023_LDO_CTRL_LDOx_MASK(ldo_index),
selector << TPS65023_LDO_CTRL_LDOx_SHIFT(ldo_index));
}
static int tps65023_dcdc_list_voltage(struct regulator_dev *dev,
@ -398,21 +258,21 @@ static int tps65023_ldo_list_voltage(struct regulator_dev *dev,
/* Operations permitted on VDCDCx */
static struct regulator_ops tps65023_dcdc_ops = {
.is_enabled = tps65023_dcdc_is_enabled,
.enable = tps65023_dcdc_enable,
.disable = tps65023_dcdc_disable,
.is_enabled = regulator_is_enabled_regmap,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.get_voltage = tps65023_dcdc_get_voltage,
.set_voltage = tps65023_dcdc_set_voltage,
.set_voltage_sel = tps65023_dcdc_set_voltage_sel,
.list_voltage = tps65023_dcdc_list_voltage,
};
/* Operations permitted on LDOx */
static struct regulator_ops tps65023_ldo_ops = {
.is_enabled = tps65023_ldo_is_enabled,
.enable = tps65023_ldo_enable,
.disable = tps65023_ldo_disable,
.is_enabled = regulator_is_enabled_regmap,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.get_voltage = tps65023_ldo_get_voltage,
.set_voltage = tps65023_ldo_set_voltage,
.set_voltage_sel = tps65023_ldo_set_voltage_sel,
.list_voltage = tps65023_ldo_list_voltage,
};
@ -426,6 +286,7 @@ static int __devinit tps_65023_probe(struct i2c_client *client,
{
const struct tps_driver_data *drv_data = (void *)id->driver_data;
const struct tps_info *info = drv_data->info;
struct regulator_config config = { };
struct regulator_init_data *init_data;
struct regulator_dev *rdev;
struct tps_pmic *tps;
@ -443,20 +304,19 @@ static int __devinit tps_65023_probe(struct i2c_client *client,
if (!init_data)
return -EIO;
tps = kzalloc(sizeof(*tps), GFP_KERNEL);
tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL);
if (!tps)
return -ENOMEM;
tps->regmap = regmap_init_i2c(client, &tps65023_regmap_config);
tps->regmap = devm_regmap_init_i2c(client, &tps65023_regmap_config);
if (IS_ERR(tps->regmap)) {
error = PTR_ERR(tps->regmap);
dev_err(&client->dev, "Failed to allocate register map: %d\n",
error);
goto fail_alloc;
return error;
}
/* common for all regulators */
tps->client = client;
tps->core_regulator = drv_data->core_regulator;
for (i = 0; i < TPS65023_NUM_REGULATOR; i++, info++, init_data++) {
@ -471,9 +331,22 @@ static int __devinit tps_65023_probe(struct i2c_client *client,
tps->desc[i].type = REGULATOR_VOLTAGE;
tps->desc[i].owner = THIS_MODULE;
tps->desc[i].enable_reg = TPS65023_REG_REG_CTRL;
if (i == TPS65023_LDO_1)
tps->desc[i].enable_mask = 1 << 1;
else if (i == TPS65023_LDO_2)
tps->desc[i].enable_mask = 1 << 2;
else /* DCDCx */
tps->desc[i].enable_mask =
1 << (TPS65023_NUM_REGULATOR - i);
config.dev = &client->dev;
config.init_data = init_data;
config.driver_data = tps;
config.regmap = tps->regmap;
/* Register the regulators */
rdev = regulator_register(&tps->desc[i], &client->dev,
init_data, tps, NULL);
rdev = regulator_register(&tps->desc[i], &config);
if (IS_ERR(rdev)) {
dev_err(&client->dev, "failed to register %s\n",
id->name);
@ -496,19 +369,9 @@ static int __devinit tps_65023_probe(struct i2c_client *client,
fail:
while (--i >= 0)
regulator_unregister(tps->rdev[i]);
regmap_exit(tps->regmap);
fail_alloc:
kfree(tps);
return error;
}
/**
* tps_65023_remove - TPS65023 driver i2c remove handler
* @client: i2c driver client device structure
*
* Unregister TPS driver as an i2c client device driver
*/
static int __devexit tps_65023_remove(struct i2c_client *client)
{
struct tps_pmic *tps = i2c_get_clientdata(client);
@ -516,10 +379,6 @@ static int __devexit tps_65023_remove(struct i2c_client *client)
for (i = 0; i < TPS65023_NUM_REGULATOR; i++)
regulator_unregister(tps->rdev[i]);
regmap_exit(tps->regmap);
kfree(tps);
return 0;
}
@ -638,13 +497,13 @@ static struct tps_driver_data tps65020_drv_data = {
};
static struct tps_driver_data tps65021_drv_data = {
.info = tps65021_regs,
.core_regulator = TPS65023_DCDC_3,
.info = tps65021_regs,
.core_regulator = TPS65023_DCDC_3,
};
static struct tps_driver_data tps65023_drv_data = {
.info = tps65023_regs,
.core_regulator = TPS65023_DCDC_1,
.info = tps65023_regs,
.core_regulator = TPS65023_DCDC_1,
};
static const struct i2c_device_id tps_65023_id[] = {
@ -669,22 +528,12 @@ static struct i2c_driver tps_65023_i2c_driver = {
.id_table = tps_65023_id,
};
/**
* tps_65023_init
*
* Module init function
*/
static int __init tps_65023_init(void)
{
return i2c_add_driver(&tps_65023_i2c_driver);
}
subsys_initcall(tps_65023_init);
/**
* tps_65023_cleanup
*
* Module exit function
*/
static void __exit tps_65023_cleanup(void)
{
i2c_del_driver(&tps_65023_i2c_driver);

View File

@ -404,6 +404,7 @@ static __devinit int tps6507x_pmic_probe(struct platform_device *pdev)
{
struct tps6507x_dev *tps6507x_dev = dev_get_drvdata(pdev->dev.parent);
struct tps_info *info = &tps6507x_pmic_regs[0];
struct regulator_config config = { };
struct regulator_init_data *init_data;
struct regulator_dev *rdev;
struct tps6507x_pmic *tps;
@ -428,7 +429,7 @@ static __devinit int tps6507x_pmic_probe(struct platform_device *pdev)
if (!init_data)
return -EINVAL;
tps = kzalloc(sizeof(*tps), GFP_KERNEL);
tps = devm_kzalloc(&pdev->dev, sizeof(*tps), GFP_KERNEL);
if (!tps)
return -ENOMEM;
@ -453,8 +454,11 @@ static __devinit int tps6507x_pmic_probe(struct platform_device *pdev)
tps->desc[i].type = REGULATOR_VOLTAGE;
tps->desc[i].owner = THIS_MODULE;
rdev = regulator_register(&tps->desc[i],
tps6507x_dev->dev, init_data, tps, NULL);
config.dev = tps6507x_dev->dev;
config.init_data = init_data;
config.driver_data = tps;
rdev = regulator_register(&tps->desc[i], &config);
if (IS_ERR(rdev)) {
dev_err(tps6507x_dev->dev,
"failed to register %s regulator\n",
@ -475,8 +479,6 @@ static __devinit int tps6507x_pmic_probe(struct platform_device *pdev)
fail:
while (--i >= 0)
regulator_unregister(tps->rdev[i]);
kfree(tps);
return error;
}
@ -488,9 +490,6 @@ static int __devexit tps6507x_pmic_remove(struct platform_device *pdev)
for (i = 0; i < TPS6507X_NUM_REGULATOR; i++)
regulator_unregister(tps->rdev[i]);
kfree(tps);
return 0;
}

View File

@ -0,0 +1,151 @@
/*
* Regulator driver for tps65090 power management chip.
*
* Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved.
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/err.h>
#include <linux/platform_device.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
#include <linux/mfd/tps65090.h>
#include <linux/regulator/tps65090-regulator.h>
struct tps65090_regulator {
int id;
/* used by regulator core */
struct regulator_desc desc;
/* Device */
struct device *dev;
};
static struct regulator_ops tps65090_ops = {
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,
};
#define tps65090_REG(_id) \
{ \
.id = TPS65090_ID_##_id, \
.desc = { \
.name = tps65090_rails(_id), \
.id = TPS65090_ID_##_id, \
.ops = &tps65090_ops, \
.type = REGULATOR_VOLTAGE, \
.owner = THIS_MODULE, \
.enable_reg = (TPS65090_ID_##_id) + 12, \
.enable_mask = BIT(0), \
}, \
}
static struct tps65090_regulator TPS65090_regulator[] = {
tps65090_REG(DCDC1),
tps65090_REG(DCDC2),
tps65090_REG(DCDC3),
tps65090_REG(FET1),
tps65090_REG(FET2),
tps65090_REG(FET3),
tps65090_REG(FET4),
tps65090_REG(FET5),
tps65090_REG(FET6),
tps65090_REG(FET7),
};
static inline struct tps65090_regulator *find_regulator_info(int id)
{
struct tps65090_regulator *ri;
int i;
for (i = 0; i < ARRAY_SIZE(TPS65090_regulator); i++) {
ri = &TPS65090_regulator[i];
if (ri->desc.id == id)
return ri;
}
return NULL;
}
static int __devinit tps65090_regulator_probe(struct platform_device *pdev)
{
struct tps65090 *tps65090_mfd = dev_get_drvdata(pdev->dev.parent);
struct tps65090_regulator *ri = NULL;
struct regulator_config config = { };
struct regulator_dev *rdev;
struct tps65090_regulator_platform_data *tps_pdata;
int id = pdev->id;
dev_dbg(&pdev->dev, "Probing regulator %d\n", id);
ri = find_regulator_info(id);
if (ri == NULL) {
dev_err(&pdev->dev, "invalid regulator ID specified\n");
return -EINVAL;
}
tps_pdata = pdev->dev.platform_data;
ri->dev = &pdev->dev;
config.dev = &pdev->dev;
config.init_data = &tps_pdata->regulator;
config.driver_data = ri;
config.regmap = tps65090_mfd->rmap;
rdev = regulator_register(&ri->desc, &config);
if (IS_ERR(rdev)) {
dev_err(&pdev->dev, "failed to register regulator %s\n",
ri->desc.name);
return PTR_ERR(rdev);
}
platform_set_drvdata(pdev, rdev);
return 0;
}
static int __devexit tps65090_regulator_remove(struct platform_device *pdev)
{
struct regulator_dev *rdev = platform_get_drvdata(pdev);
regulator_unregister(rdev);
return 0;
}
static struct platform_driver tps65090_regulator_driver = {
.driver = {
.name = "tps65090-regulator",
.owner = THIS_MODULE,
},
.probe = tps65090_regulator_probe,
.remove = __devexit_p(tps65090_regulator_remove),
};
static int __init tps65090_regulator_init(void)
{
return platform_driver_register(&tps65090_regulator_driver);
}
subsys_initcall(tps65090_regulator_init);
static void __exit tps65090_regulator_exit(void)
{
platform_driver_unregister(&tps65090_regulator_driver);
}
module_exit(tps65090_regulator_exit);
MODULE_DESCRIPTION("tps65090 regulator driver");
MODULE_AUTHOR("Venu Byravarasu <vbyravarasu@nvidia.com>");
MODULE_LICENSE("GPL v2");

View File

@ -312,7 +312,7 @@ static struct regulator_ops tps65217_pmic_ldo1_ops = {
.list_voltage = tps65217_pmic_list_voltage,
};
static struct regulator_desc regulators[] = {
static const struct regulator_desc regulators[] = {
TPS65217_REGULATOR("DCDC1", TPS65217_DCDC_1, tps65217_pmic_ops, 64),
TPS65217_REGULATOR("DCDC2", TPS65217_DCDC_2, tps65217_pmic_ops, 64),
TPS65217_REGULATOR("DCDC3", TPS65217_DCDC_3, tps65217_pmic_ops, 64),
@ -327,13 +327,17 @@ static int __devinit tps65217_regulator_probe(struct platform_device *pdev)
struct regulator_dev *rdev;
struct tps65217 *tps;
struct tps_info *info = &tps65217_pmic_regs[pdev->id];
struct regulator_config config = { };
/* Already set by core driver */
tps = dev_to_tps65217(pdev->dev.parent);
tps->info[pdev->id] = info;
rdev = regulator_register(&regulators[pdev->id], &pdev->dev,
pdev->dev.platform_data, tps, NULL);
config.dev = &pdev->dev;
config.init_data = pdev->dev.platform_data;
config.driver_data = tps;
rdev = regulator_register(&regulators[pdev->id], &config);
if (IS_ERR(rdev))
return PTR_ERR(rdev);

View File

@ -458,12 +458,10 @@ static int list_voltage(struct regulator_dev *rdev, unsigned selector)
info->voltages[selector] : -EINVAL);
}
static int set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV,
unsigned *selector)
static int set_voltage_sel(struct regulator_dev *rdev, unsigned selector)
{
const struct supply_info *info;
struct tps6524x *hw;
unsigned i;
hw = rdev_get_drvdata(rdev);
info = &supply_info[rdev_get_id(rdev)];
@ -471,20 +469,10 @@ static int set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV,
if (info->flags & FIXED_VOLTAGE)
return -EINVAL;
for (i = 0; i < info->n_voltages; i++)
if (min_uV <= info->voltages[i] &&
max_uV >= info->voltages[i])
break;
if (i >= info->n_voltages)
i = info->n_voltages - 1;
*selector = i;
return write_field(hw, &info->voltage, i);
return write_field(hw, &info->voltage, selector);
}
static int get_voltage(struct regulator_dev *rdev)
static int get_voltage_sel(struct regulator_dev *rdev)
{
const struct supply_info *info;
struct tps6524x *hw;
@ -502,7 +490,7 @@ static int get_voltage(struct regulator_dev *rdev)
if (WARN_ON(ret >= info->n_voltages))
return -EIO;
return info->voltages[ret];
return ret;
}
static int set_current_limit(struct regulator_dev *rdev, int min_uA,
@ -587,8 +575,8 @@ static struct regulator_ops regulator_ops = {
.is_enabled = is_supply_enabled,
.enable = enable_supply,
.disable = disable_supply,
.get_voltage = get_voltage,
.set_voltage = set_voltage,
.get_voltage_sel = get_voltage_sel,
.set_voltage_sel = set_voltage_sel,
.list_voltage = list_voltage,
.set_current_limit = set_current_limit,
.get_current_limit = get_current_limit,
@ -607,7 +595,6 @@ static int pmic_remove(struct spi_device *spi)
hw->rdev[i] = NULL;
}
spi_set_drvdata(spi, NULL);
kfree(hw);
return 0;
}
@ -617,6 +604,7 @@ static int __devinit pmic_probe(struct spi_device *spi)
struct device *dev = &spi->dev;
const struct supply_info *info = supply_info;
struct regulator_init_data *init_data;
struct regulator_config config = { };
int ret = 0, i;
init_data = dev->platform_data;
@ -625,7 +613,7 @@ static int __devinit pmic_probe(struct spi_device *spi)
return -EINVAL;
}
hw = kzalloc(sizeof(struct tps6524x), GFP_KERNEL);
hw = devm_kzalloc(&spi->dev, sizeof(struct tps6524x), GFP_KERNEL);
if (!hw) {
dev_err(dev, "cannot allocate regulator private data\n");
return -ENOMEM;
@ -648,8 +636,11 @@ static int __devinit pmic_probe(struct spi_device *spi)
if (info->flags & FIXED_VOLTAGE)
hw->desc[i].n_voltages = 1;
hw->rdev[i] = regulator_register(&hw->desc[i], dev,
init_data, hw, NULL);
config.dev = dev;
config.init_data = init_data;
config.driver_data = hw;
hw->rdev[i] = regulator_register(&hw->desc[i], &config);
if (IS_ERR(hw->rdev[i])) {
ret = PTR_ERR(hw->rdev[i]);
hw->rdev[i] = NULL;
@ -673,17 +664,7 @@ static struct spi_driver pmic_driver = {
},
};
static int __init pmic_driver_init(void)
{
return spi_register_driver(&pmic_driver);
}
module_init(pmic_driver_init);
static void __exit pmic_driver_exit(void)
{
spi_unregister_driver(&pmic_driver);
}
module_exit(pmic_driver_exit);
module_spi_driver(pmic_driver);
MODULE_DESCRIPTION("TPS6524X PMIC Driver");
MODULE_AUTHOR("Cyril Chemparathy");

View File

@ -75,8 +75,7 @@ static inline struct device *to_tps6586x_dev(struct regulator_dev *rdev)
return rdev_get_dev(rdev)->parent->parent;
}
static int tps6586x_ldo_list_voltage(struct regulator_dev *rdev,
unsigned selector)
static int tps6586x_list_voltage(struct regulator_dev *rdev, unsigned selector)
{
struct tps6586x_regulator *info = rdev_get_drvdata(rdev);
int rid = rdev_get_id(rdev);
@ -89,47 +88,34 @@ static int tps6586x_ldo_list_voltage(struct regulator_dev *rdev,
}
static int __tps6586x_ldo_set_voltage(struct device *parent,
struct tps6586x_regulator *ri,
int min_uV, int max_uV,
unsigned *selector)
{
int val, uV;
uint8_t mask;
for (val = 0; val < ri->desc.n_voltages; val++) {
uV = ri->voltages[val] * 1000;
/* LDO0 has minimal voltage 1.2 rather than 1.25 */
if (ri->desc.id == TPS6586X_ID_LDO_0 && val == 0)
uV -= 50 * 1000;
/* use the first in-range value */
if (min_uV <= uV && uV <= max_uV) {
*selector = val;
val <<= ri->volt_shift;
mask = ((1 << ri->volt_nbits) - 1) << ri->volt_shift;
return tps6586x_update(parent, ri->volt_reg, val, mask);
}
}
return -EINVAL;
}
static int tps6586x_ldo_set_voltage(struct regulator_dev *rdev,
int min_uV, int max_uV, unsigned *selector)
static int tps6586x_set_voltage_sel(struct regulator_dev *rdev,
unsigned selector)
{
struct tps6586x_regulator *ri = rdev_get_drvdata(rdev);
struct device *parent = to_tps6586x_dev(rdev);
int ret, val, rid = rdev_get_id(rdev);
uint8_t mask;
return __tps6586x_ldo_set_voltage(parent, ri, min_uV, max_uV,
selector);
val = selector << ri->volt_shift;
mask = ((1 << ri->volt_nbits) - 1) << ri->volt_shift;
ret = tps6586x_update(parent, ri->volt_reg, val, mask);
if (ret)
return ret;
/* Update go bit for DVM regulators */
switch (rid) {
case TPS6586X_ID_LDO_2:
case TPS6586X_ID_LDO_4:
case TPS6586X_ID_SM_0:
case TPS6586X_ID_SM_1:
ret = tps6586x_set_bits(parent, ri->go_reg, 1 << ri->go_bit);
break;
}
return ret;
}
static int tps6586x_ldo_get_voltage(struct regulator_dev *rdev)
static int tps6586x_get_voltage_sel(struct regulator_dev *rdev)
{
struct tps6586x_regulator *ri = rdev_get_drvdata(rdev);
struct device *parent = to_tps6586x_dev(rdev);
@ -146,22 +132,7 @@ static int tps6586x_ldo_get_voltage(struct regulator_dev *rdev)
if (val >= ri->desc.n_voltages)
BUG();
return ri->voltages[val] * 1000;
}
static int tps6586x_dvm_set_voltage(struct regulator_dev *rdev,
int min_uV, int max_uV, unsigned *selector)
{
struct tps6586x_regulator *ri = rdev_get_drvdata(rdev);
struct device *parent = to_tps6586x_dev(rdev);
int ret;
ret = __tps6586x_ldo_set_voltage(parent, ri, min_uV, max_uV,
selector);
if (ret)
return ret;
return tps6586x_set_bits(parent, ri->go_reg, 1 << ri->go_bit);
return val;
}
static int tps6586x_regulator_enable(struct regulator_dev *rdev)
@ -196,20 +167,10 @@ static int tps6586x_regulator_is_enabled(struct regulator_dev *rdev)
return !!(reg_val & (1 << ri->enable_bit[0]));
}
static struct regulator_ops tps6586x_regulator_ldo_ops = {
.list_voltage = tps6586x_ldo_list_voltage,
.get_voltage = tps6586x_ldo_get_voltage,
.set_voltage = tps6586x_ldo_set_voltage,
.is_enabled = tps6586x_regulator_is_enabled,
.enable = tps6586x_regulator_enable,
.disable = tps6586x_regulator_disable,
};
static struct regulator_ops tps6586x_regulator_dvm_ops = {
.list_voltage = tps6586x_ldo_list_voltage,
.get_voltage = tps6586x_ldo_get_voltage,
.set_voltage = tps6586x_dvm_set_voltage,
static struct regulator_ops tps6586x_regulator_ops = {
.list_voltage = tps6586x_list_voltage,
.get_voltage_sel = tps6586x_get_voltage_sel,
.set_voltage_sel = tps6586x_set_voltage_sel,
.is_enabled = tps6586x_regulator_is_enabled,
.enable = tps6586x_regulator_enable,
@ -241,11 +202,11 @@ static int tps6586x_dvm_voltages[] = {
1325, 1350, 1375, 1400, 1425, 1450, 1475, 1500,
};
#define TPS6586X_REGULATOR(_id, vdata, _ops, vreg, shift, nbits, \
#define TPS6586X_REGULATOR(_id, vdata, vreg, shift, nbits, \
ereg0, ebit0, ereg1, ebit1) \
.desc = { \
.name = "REG-" #_id, \
.ops = &tps6586x_regulator_##_ops, \
.ops = &tps6586x_regulator_ops, \
.type = REGULATOR_VOLTAGE, \
.id = TPS6586X_ID_##_id, \
.n_voltages = ARRAY_SIZE(tps6586x_##vdata##_voltages), \
@ -267,14 +228,14 @@ static int tps6586x_dvm_voltages[] = {
#define TPS6586X_LDO(_id, vdata, vreg, shift, nbits, \
ereg0, ebit0, ereg1, ebit1) \
{ \
TPS6586X_REGULATOR(_id, vdata, ldo_ops, vreg, shift, nbits, \
TPS6586X_REGULATOR(_id, vdata, vreg, shift, nbits, \
ereg0, ebit0, ereg1, ebit1) \
}
#define TPS6586X_DVM(_id, vdata, vreg, shift, nbits, \
ereg0, ebit0, ereg1, ebit1, goreg, gobit) \
{ \
TPS6586X_REGULATOR(_id, vdata, dvm_ops, vreg, shift, nbits, \
TPS6586X_REGULATOR(_id, vdata, vreg, shift, nbits, \
ereg0, ebit0, ereg1, ebit1) \
TPS6586X_REGULATOR_DVM_GOREG(goreg, gobit) \
}
@ -384,6 +345,7 @@ static inline struct tps6586x_regulator *find_regulator_info(int id)
static int __devinit tps6586x_regulator_probe(struct platform_device *pdev)
{
struct tps6586x_regulator *ri = NULL;
struct regulator_config config = { };
struct regulator_dev *rdev;
int id = pdev->id;
int err;
@ -400,8 +362,11 @@ static int __devinit tps6586x_regulator_probe(struct platform_device *pdev)
if (err)
return err;
rdev = regulator_register(&ri->desc, &pdev->dev,
pdev->dev.platform_data, ri, NULL);
config.dev = &pdev->dev;
config.init_data = pdev->dev.platform_data;
config.driver_data = ri;
rdev = regulator_register(&ri->desc, &config);
if (IS_ERR(rdev)) {
dev_err(&pdev->dev, "failed to register regulator %s\n",
ri->desc.name);

View File

@ -467,48 +467,6 @@ static int tps65911_get_ctrl_register(int id)
}
}
static int tps65910_is_enabled(struct regulator_dev *dev)
{
struct tps65910_reg *pmic = rdev_get_drvdata(dev);
int reg, value, id = rdev_get_id(dev);
reg = pmic->get_ctrl_reg(id);
if (reg < 0)
return reg;
value = tps65910_reg_read(pmic, reg);
if (value < 0)
return value;
return value & TPS65910_SUPPLY_STATE_ENABLED;
}
static int tps65910_enable(struct regulator_dev *dev)
{
struct tps65910_reg *pmic = rdev_get_drvdata(dev);
struct tps65910 *mfd = pmic->mfd;
int reg, id = rdev_get_id(dev);
reg = pmic->get_ctrl_reg(id);
if (reg < 0)
return reg;
return tps65910_set_bits(mfd, reg, TPS65910_SUPPLY_STATE_ENABLED);
}
static int tps65910_disable(struct regulator_dev *dev)
{
struct tps65910_reg *pmic = rdev_get_drvdata(dev);
struct tps65910 *mfd = pmic->mfd;
int reg, id = rdev_get_id(dev);
reg = pmic->get_ctrl_reg(id);
if (reg < 0)
return reg;
return tps65910_clear_bits(mfd, reg, TPS65910_SUPPLY_STATE_ENABLED);
}
static int tps65910_enable_time(struct regulator_dev *dev)
{
struct tps65910_reg *pmic = rdev_get_drvdata(dev);
@ -914,9 +872,9 @@ static int tps65910_set_voltage_dcdc_time_sel(struct regulator_dev *dev,
/* Regulator ops (except VRTC) */
static struct regulator_ops tps65910_ops_dcdc = {
.is_enabled = tps65910_is_enabled,
.enable = tps65910_enable,
.disable = tps65910_disable,
.is_enabled = regulator_is_enabled_regmap,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.enable_time = tps65910_enable_time,
.set_mode = tps65910_set_mode,
.get_mode = tps65910_get_mode,
@ -927,9 +885,9 @@ static struct regulator_ops tps65910_ops_dcdc = {
};
static struct regulator_ops tps65910_ops_vdd3 = {
.is_enabled = tps65910_is_enabled,
.enable = tps65910_enable,
.disable = tps65910_disable,
.is_enabled = regulator_is_enabled_regmap,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.enable_time = tps65910_enable_time,
.set_mode = tps65910_set_mode,
.get_mode = tps65910_get_mode,
@ -938,9 +896,9 @@ static struct regulator_ops tps65910_ops_vdd3 = {
};
static struct regulator_ops tps65910_ops = {
.is_enabled = tps65910_is_enabled,
.enable = tps65910_enable,
.disable = tps65910_disable,
.is_enabled = regulator_is_enabled_regmap,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.enable_time = tps65910_enable_time,
.set_mode = tps65910_set_mode,
.get_mode = tps65910_get_mode,
@ -950,9 +908,9 @@ static struct regulator_ops tps65910_ops = {
};
static struct regulator_ops tps65911_ops = {
.is_enabled = tps65910_is_enabled,
.enable = tps65910_enable,
.disable = tps65910_disable,
.is_enabled = regulator_is_enabled_regmap,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.enable_time = tps65910_enable_time,
.set_mode = tps65910_set_mode,
.get_mode = tps65910_get_mode,
@ -1097,6 +1055,7 @@ static int tps65910_set_ext_sleep_config(struct tps65910_reg *pmic,
static __devinit int tps65910_probe(struct platform_device *pdev)
{
struct tps65910 *tps65910 = dev_get_drvdata(pdev->dev.parent);
struct regulator_config config = { };
struct tps_info *info;
struct regulator_init_data *reg_data;
struct regulator_dev *rdev;
@ -1108,7 +1067,7 @@ static __devinit int tps65910_probe(struct platform_device *pdev)
if (!pmic_plat_data)
return -EINVAL;
pmic = kzalloc(sizeof(*pmic), GFP_KERNEL);
pmic = devm_kzalloc(&pdev->dev, sizeof(*pmic), GFP_KERNEL);
if (!pmic)
return -ENOMEM;
@ -1135,7 +1094,6 @@ static __devinit int tps65910_probe(struct platform_device *pdev)
break;
default:
pr_err("Invalid tps chip version\n");
kfree(pmic);
return -ENODEV;
}
@ -1143,7 +1101,7 @@ static __devinit int tps65910_probe(struct platform_device *pdev)
sizeof(struct regulator_desc), GFP_KERNEL);
if (!pmic->desc) {
err = -ENOMEM;
goto err_free_pmic;
goto err_out;
}
pmic->info = kcalloc(pmic->num_regulators,
@ -1205,9 +1163,15 @@ static __devinit int tps65910_probe(struct platform_device *pdev)
pmic->desc[i].type = REGULATOR_VOLTAGE;
pmic->desc[i].owner = THIS_MODULE;
pmic->desc[i].enable_reg = pmic->get_ctrl_reg(i);
pmic->desc[i].enable_mask = TPS65910_SUPPLY_STATE_ENABLED;
rdev = regulator_register(&pmic->desc[i],
tps65910->dev, reg_data, pmic, NULL);
config.dev = tps65910->dev;
config.init_data = reg_data;
config.driver_data = pmic;
config.regmap = tps65910->regmap;
rdev = regulator_register(&pmic->desc[i], &config);
if (IS_ERR(rdev)) {
dev_err(tps65910->dev,
"failed to register %s regulator\n",
@ -1229,8 +1193,7 @@ err_free_info:
kfree(pmic->info);
err_free_desc:
kfree(pmic->desc);
err_free_pmic:
kfree(pmic);
err_out:
return err;
}
@ -1245,7 +1208,6 @@ static int __devexit tps65910_remove(struct platform_device *pdev)
kfree(pmic->rdev);
kfree(pmic->info);
kfree(pmic->desc);
kfree(pmic);
return 0;
}

View File

@ -372,12 +372,14 @@ static unsigned int tps65912_get_mode(struct regulator_dev *dev)
return mode;
}
static int tps65912_list_voltage_dcdc(struct regulator_dev *dev,
unsigned selector)
static int tps65912_list_voltage(struct regulator_dev *dev, unsigned selector)
{
struct tps65912_reg *pmic = rdev_get_drvdata(dev);
int range, voltage = 0, id = rdev_get_id(dev);
if (id >= TPS65912_REG_LDO1 && id <= TPS65912_REG_LDO10)
return tps65912_vsel_to_uv_ldo(selector);
if (id > TPS65912_REG_DCDC4)
return -EINVAL;
@ -404,7 +406,7 @@ static int tps65912_list_voltage_dcdc(struct regulator_dev *dev,
return voltage;
}
static int tps65912_get_voltage_dcdc(struct regulator_dev *dev)
static int tps65912_get_voltage(struct regulator_dev *dev)
{
struct tps65912_reg *pmic = rdev_get_drvdata(dev);
struct tps65912 *mfd = pmic->mfd;
@ -418,7 +420,7 @@ static int tps65912_get_voltage_dcdc(struct regulator_dev *dev)
vsel = tps65912_reg_read(mfd, reg);
vsel &= 0x3F;
return tps65912_list_voltage_dcdc(dev, vsel);
return tps65912_list_voltage(dev, vsel);
}
static int tps65912_set_voltage_sel(struct regulator_dev *dev,
@ -436,32 +438,6 @@ static int tps65912_set_voltage_sel(struct regulator_dev *dev,
return tps65912_reg_write(mfd, reg, selector | value);
}
static int tps65912_get_voltage_ldo(struct regulator_dev *dev)
{
struct tps65912_reg *pmic = rdev_get_drvdata(dev);
struct tps65912 *mfd = pmic->mfd;
int id = rdev_get_id(dev);
int vsel = 0;
u8 reg;
reg = tps65912_get_sel_register(pmic, id);
vsel = tps65912_reg_read(mfd, reg);
vsel &= 0x3F;
return tps65912_vsel_to_uv_ldo(vsel);
}
static int tps65912_list_voltage_ldo(struct regulator_dev *dev,
unsigned selector)
{
int ldo = rdev_get_id(dev);
if (ldo < TPS65912_REG_LDO1 || ldo > TPS65912_REG_LDO10)
return -EINVAL;
return tps65912_vsel_to_uv_ldo(selector);
}
/* Operations permitted on DCDCx */
static struct regulator_ops tps65912_ops_dcdc = {
.is_enabled = tps65912_reg_is_enabled,
@ -469,9 +445,9 @@ static struct regulator_ops tps65912_ops_dcdc = {
.disable = tps65912_reg_disable,
.set_mode = tps65912_set_mode,
.get_mode = tps65912_get_mode,
.get_voltage = tps65912_get_voltage_dcdc,
.get_voltage = tps65912_get_voltage,
.set_voltage_sel = tps65912_set_voltage_sel,
.list_voltage = tps65912_list_voltage_dcdc,
.list_voltage = tps65912_list_voltage,
};
/* Operations permitted on LDOx */
@ -479,14 +455,15 @@ static struct regulator_ops tps65912_ops_ldo = {
.is_enabled = tps65912_reg_is_enabled,
.enable = tps65912_reg_enable,
.disable = tps65912_reg_disable,
.get_voltage = tps65912_get_voltage_ldo,
.get_voltage = tps65912_get_voltage,
.set_voltage_sel = tps65912_set_voltage_sel,
.list_voltage = tps65912_list_voltage_ldo,
.list_voltage = tps65912_list_voltage,
};
static __devinit int tps65912_probe(struct platform_device *pdev)
{
struct tps65912 *tps65912 = dev_get_drvdata(pdev->dev.parent);
struct regulator_config config = { };
struct tps_info *info;
struct regulator_init_data *reg_data;
struct regulator_dev *rdev;
@ -500,7 +477,7 @@ static __devinit int tps65912_probe(struct platform_device *pdev)
reg_data = pmic_plat_data->tps65912_pmic_init_data;
pmic = kzalloc(sizeof(*pmic), GFP_KERNEL);
pmic = devm_kzalloc(&pdev->dev, sizeof(*pmic), GFP_KERNEL);
if (!pmic)
return -ENOMEM;
@ -524,8 +501,12 @@ static __devinit int tps65912_probe(struct platform_device *pdev)
pmic->desc[i].type = REGULATOR_VOLTAGE;
pmic->desc[i].owner = THIS_MODULE;
range = tps65912_get_range(pmic, i);
rdev = regulator_register(&pmic->desc[i],
tps65912->dev, reg_data, pmic, NULL);
config.dev = tps65912->dev;
config.init_data = reg_data;
config.driver_data = pmic;
rdev = regulator_register(&pmic->desc[i], &config);
if (IS_ERR(rdev)) {
dev_err(tps65912->dev,
"failed to register %s regulator\n",
@ -542,8 +523,6 @@ static __devinit int tps65912_probe(struct platform_device *pdev)
err:
while (--i >= 0)
regulator_unregister(pmic->rdev[i]);
kfree(pmic);
return err;
}
@ -554,8 +533,6 @@ static int __devexit tps65912_remove(struct platform_device *pdev)
for (i = 0; i < TPS65912_NUM_REGULATOR; i++)
regulator_unregister(tps65912_reg->rdev[i]);
kfree(tps65912_reg);
return 0;
}

View File

@ -175,15 +175,14 @@ static int twl6030reg_is_enabled(struct regulator_dev *rdev)
struct twlreg_info *info = rdev_get_drvdata(rdev);
int grp = 0, val;
if (!(twl_class_is_6030() && (info->features & TWL6025_SUBCLASS)))
grp = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_GRP);
if (grp < 0)
return grp;
if (!(twl_class_is_6030() && (info->features & TWL6025_SUBCLASS)))
if (!(twl_class_is_6030() && (info->features & TWL6025_SUBCLASS))) {
grp = twlreg_grp(rdev);
if (grp < 0)
return grp;
grp &= P1_GRP_6030;
else
} else {
grp = 1;
}
val = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_STATE);
val = TWL6030_CFG_STATE_APP(val);
@ -197,7 +196,7 @@ static int twl4030reg_enable(struct regulator_dev *rdev)
int grp;
int ret;
grp = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_GRP);
grp = twlreg_grp(rdev);
if (grp < 0)
return grp;
@ -205,8 +204,6 @@ static int twl4030reg_enable(struct regulator_dev *rdev)
ret = twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_GRP, grp);
udelay(info->delay);
return ret;
}
@ -217,26 +214,37 @@ static int twl6030reg_enable(struct regulator_dev *rdev)
int ret;
if (!(twl_class_is_6030() && (info->features & TWL6025_SUBCLASS)))
grp = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_GRP);
grp = twlreg_grp(rdev);
if (grp < 0)
return grp;
ret = twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_STATE,
grp << TWL6030_CFG_STATE_GRP_SHIFT |
TWL6030_CFG_STATE_ON);
udelay(info->delay);
return ret;
}
static int twl4030reg_enable_time(struct regulator_dev *rdev)
{
struct twlreg_info *info = rdev_get_drvdata(rdev);
return info->delay;
}
static int twl6030reg_enable_time(struct regulator_dev *rdev)
{
struct twlreg_info *info = rdev_get_drvdata(rdev);
return info->delay;
}
static int twl4030reg_disable(struct regulator_dev *rdev)
{
struct twlreg_info *info = rdev_get_drvdata(rdev);
int grp;
int ret;
grp = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_GRP);
grp = twlreg_grp(rdev);
if (grp < 0)
return grp;
@ -348,7 +356,7 @@ static int twl6030reg_set_mode(struct regulator_dev *rdev, unsigned mode)
int val;
if (!(twl_class_is_6030() && (info->features & TWL6025_SUBCLASS)))
grp = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_GRP);
grp = twlreg_grp(rdev);
if (grp < 0)
return grp;
@ -473,31 +481,12 @@ static int twl4030ldo_list_voltage(struct regulator_dev *rdev, unsigned index)
}
static int
twl4030ldo_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV,
unsigned *selector)
twl4030ldo_set_voltage_sel(struct regulator_dev *rdev, unsigned selector)
{
struct twlreg_info *info = rdev_get_drvdata(rdev);
int vsel;
for (vsel = 0; vsel < info->table_len; vsel++) {
int mV = info->table[vsel];
int uV;
if (IS_UNSUP(mV))
continue;
uV = LDO_MV(mV) * 1000;
/* REVISIT for VAUX2, first match may not be best/lowest */
/* use the first in-range value */
if (min_uV <= uV && uV <= max_uV) {
*selector = vsel;
return twlreg_write(info, TWL_MODULE_PM_RECEIVER,
VREG_VOLTAGE, vsel);
}
}
return -EDOM;
return twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_VOLTAGE,
selector);
}
static int twl4030ldo_get_voltage(struct regulator_dev *rdev)
@ -516,12 +505,13 @@ static int twl4030ldo_get_voltage(struct regulator_dev *rdev)
static struct regulator_ops twl4030ldo_ops = {
.list_voltage = twl4030ldo_list_voltage,
.set_voltage = twl4030ldo_set_voltage,
.set_voltage_sel = twl4030ldo_set_voltage_sel,
.get_voltage = twl4030ldo_get_voltage,
.enable = twl4030reg_enable,
.disable = twl4030reg_disable,
.is_enabled = twl4030reg_is_enabled,
.enable_time = twl4030reg_enable_time,
.set_mode = twl4030reg_set_mode,
@ -642,6 +632,7 @@ static struct regulator_ops twl6030ldo_ops = {
.enable = twl6030reg_enable,
.disable = twl6030reg_disable,
.is_enabled = twl6030reg_is_enabled,
.enable_time = twl6030reg_enable_time,
.set_mode = twl6030reg_set_mode,
@ -675,6 +666,7 @@ static struct regulator_ops twl4030fixed_ops = {
.enable = twl4030reg_enable,
.disable = twl4030reg_disable,
.is_enabled = twl4030reg_is_enabled,
.enable_time = twl4030reg_enable_time,
.set_mode = twl4030reg_set_mode,
@ -689,6 +681,7 @@ static struct regulator_ops twl6030fixed_ops = {
.enable = twl6030reg_enable,
.disable = twl6030reg_disable,
.is_enabled = twl6030reg_is_enabled,
.enable_time = twl6030reg_enable_time,
.set_mode = twl6030reg_set_mode,
@ -699,6 +692,7 @@ static struct regulator_ops twl6030_fixed_resource = {
.enable = twl6030reg_enable,
.disable = twl6030reg_disable,
.is_enabled = twl6030reg_is_enabled,
.enable_time = twl6030reg_enable_time,
.get_status = twl6030reg_get_status,
};
@ -806,10 +800,7 @@ twl6030smps_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV,
vsel = 0;
else if ((min_uV >= 600000) && (min_uV <= 1300000)) {
int calc_uV;
vsel = (min_uV - 600000) / 125;
if (vsel % 100)
vsel += 100;
vsel /= 100;
vsel = DIV_ROUND_UP(min_uV - 600000, 12500);
vsel++;
calc_uV = twl6030smps_list_voltage(rdev, vsel);
if (calc_uV > max_uV)
@ -836,10 +827,7 @@ twl6030smps_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV,
vsel = 0;
else if ((min_uV >= 700000) && (min_uV <= 1420000)) {
int calc_uV;
vsel = (min_uV - 700000) / 125;
if (vsel % 100)
vsel += 100;
vsel /= 100;
vsel = DIV_ROUND_UP(min_uV - 700000, 12500);
vsel++;
calc_uV = twl6030smps_list_voltage(rdev, vsel);
if (calc_uV > max_uV)
@ -862,24 +850,18 @@ twl6030smps_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV,
return -EINVAL;
break;
case SMPS_EXTENDED_EN:
if (min_uV == 0)
if (min_uV == 0) {
vsel = 0;
else if ((min_uV >= 1852000) && (max_uV <= 4013600)) {
vsel = (min_uV - 1852000) / 386;
if (vsel % 100)
vsel += 100;
vsel /= 100;
} else if ((min_uV >= 1852000) && (max_uV <= 4013600)) {
vsel = DIV_ROUND_UP(min_uV - 1852000, 38600);
vsel++;
}
break;
case SMPS_OFFSET_EN|SMPS_EXTENDED_EN:
if (min_uV == 0)
if (min_uV == 0) {
vsel = 0;
else if ((min_uV >= 2161000) && (max_uV <= 4321000)) {
vsel = (min_uV - 2161000) / 386;
if (vsel % 100)
vsel += 100;
vsel /= 100;
} else if ((min_uV >= 2161000) && (max_uV <= 4321000)) {
vsel = DIV_ROUND_UP(min_uV - 2161000, 38600);
vsel++;
}
break;
@ -907,6 +889,7 @@ static struct regulator_ops twlsmps_ops = {
.enable = twl6030reg_enable,
.disable = twl6030reg_disable,
.is_enabled = twl6030reg_is_enabled,
.enable_time = twl6030reg_enable_time,
.set_mode = twl6030reg_set_mode,
@ -1194,6 +1177,7 @@ static int __devinit twlreg_probe(struct platform_device *pdev)
struct regulator_dev *rdev;
struct twl_regulator_driver_data *drvdata;
const struct of_device_id *match;
struct regulator_config config = { };
match = of_match_device(twl_of_match, &pdev->dev);
if (match) {
@ -1207,10 +1191,12 @@ static int __devinit twlreg_probe(struct platform_device *pdev)
initdata = pdev->dev.platform_data;
for (i = 0, info = NULL; i < ARRAY_SIZE(twl_of_match); i++) {
info = twl_of_match[i].data;
if (!info || info->desc.id != id)
continue;
break;
if (info && info->desc.id == id)
break;
}
if (i == ARRAY_SIZE(twl_of_match))
return -ENODEV;
drvdata = initdata->driver_data;
if (!drvdata)
return -EINVAL;
@ -1273,8 +1259,12 @@ static int __devinit twlreg_probe(struct platform_device *pdev)
break;
}
rdev = regulator_register(&info->desc, &pdev->dev, initdata, info,
pdev->dev.of_node);
config.dev = &pdev->dev;
config.init_data = initdata;
config.driver_data = info;
config.of_node = pdev->dev.of_node;
rdev = regulator_register(&info->desc, &config);
if (IS_ERR(rdev)) {
dev_err(&pdev->dev, "can't register %s, %ld\n",
info->desc.name, PTR_ERR(rdev));

View File

@ -60,41 +60,6 @@ struct wm831x_dcdc {
int dvs_vsel;
};
static int wm831x_dcdc_is_enabled(struct regulator_dev *rdev)
{
struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev);
struct wm831x *wm831x = dcdc->wm831x;
int mask = 1 << rdev_get_id(rdev);
int reg;
reg = wm831x_reg_read(wm831x, WM831X_DCDC_ENABLE);
if (reg < 0)
return reg;
if (reg & mask)
return 1;
else
return 0;
}
static int wm831x_dcdc_enable(struct regulator_dev *rdev)
{
struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev);
struct wm831x *wm831x = dcdc->wm831x;
int mask = 1 << rdev_get_id(rdev);
return wm831x_set_bits(wm831x, WM831X_DCDC_ENABLE, mask, mask);
}
static int wm831x_dcdc_disable(struct regulator_dev *rdev)
{
struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev);
struct wm831x *wm831x = dcdc->wm831x;
int mask = 1 << rdev_get_id(rdev);
return wm831x_set_bits(wm831x, WM831X_DCDC_ENABLE, mask, 0);
}
static unsigned int wm831x_dcdc_get_mode(struct regulator_dev *rdev)
{
@ -414,9 +379,9 @@ static struct regulator_ops wm831x_buckv_ops = {
.set_current_limit = wm831x_buckv_set_current_limit,
.get_current_limit = wm831x_buckv_get_current_limit,
.is_enabled = wm831x_dcdc_is_enabled,
.enable = wm831x_dcdc_enable,
.disable = wm831x_dcdc_disable,
.is_enabled = regulator_is_enabled_regmap,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.get_status = wm831x_dcdc_get_status,
.get_mode = wm831x_dcdc_get_mode,
.set_mode = wm831x_dcdc_set_mode,
@ -498,6 +463,7 @@ static __devinit int wm831x_buckv_probe(struct platform_device *pdev)
{
struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
struct wm831x_pdata *pdata = wm831x->dev->platform_data;
struct regulator_config config = { };
int id;
struct wm831x_dcdc *dcdc;
struct resource *res;
@ -511,9 +477,6 @@ static __devinit int wm831x_buckv_probe(struct platform_device *pdev)
dev_dbg(&pdev->dev, "Probing DCDC%d\n", id + 1);
if (pdata == NULL || pdata->dcdc[id] == NULL)
return -ENODEV;
dcdc = devm_kzalloc(&pdev->dev, sizeof(struct wm831x_dcdc),
GFP_KERNEL);
if (dcdc == NULL) {
@ -538,6 +501,8 @@ static __devinit int wm831x_buckv_probe(struct platform_device *pdev)
dcdc->desc.n_voltages = WM831X_BUCKV_MAX_SELECTOR + 1;
dcdc->desc.ops = &wm831x_buckv_ops;
dcdc->desc.owner = THIS_MODULE;
dcdc->desc.enable_reg = WM831X_DCDC_ENABLE;
dcdc->desc.enable_mask = 1 << id;
ret = wm831x_reg_read(wm831x, dcdc->base + WM831X_DCDC_ON_CONFIG);
if (ret < 0) {
@ -556,8 +521,13 @@ static __devinit int wm831x_buckv_probe(struct platform_device *pdev)
if (pdata->dcdc[id])
wm831x_buckv_dvs_init(dcdc, pdata->dcdc[id]->driver_data);
dcdc->regulator = regulator_register(&dcdc->desc, &pdev->dev,
pdata->dcdc[id], dcdc, NULL);
config.dev = pdev->dev.parent;
if (pdata)
config.init_data = pdata->dcdc[id];
config.driver_data = dcdc;
config.regmap = wm831x->regmap;
dcdc->regulator = regulator_register(&dcdc->desc, &config);
if (IS_ERR(dcdc->regulator)) {
ret = PTR_ERR(dcdc->regulator);
dev_err(wm831x->dev, "Failed to register DCDC%d: %d\n",
@ -675,29 +645,15 @@ static int wm831x_buckp_set_suspend_voltage(struct regulator_dev *rdev,
return wm831x_buckp_set_voltage_int(rdev, reg, uV, uV, &selector);
}
static int wm831x_buckp_get_voltage_sel(struct regulator_dev *rdev)
{
struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev);
struct wm831x *wm831x = dcdc->wm831x;
u16 reg = dcdc->base + WM831X_DCDC_ON_CONFIG;
int val;
val = wm831x_reg_read(wm831x, reg);
if (val < 0)
return val;
return val & WM831X_DC3_ON_VSEL_MASK;
}
static struct regulator_ops wm831x_buckp_ops = {
.set_voltage = wm831x_buckp_set_voltage,
.get_voltage_sel = wm831x_buckp_get_voltage_sel,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.list_voltage = wm831x_buckp_list_voltage,
.set_suspend_voltage = wm831x_buckp_set_suspend_voltage,
.is_enabled = wm831x_dcdc_is_enabled,
.enable = wm831x_dcdc_enable,
.disable = wm831x_dcdc_disable,
.is_enabled = regulator_is_enabled_regmap,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.get_status = wm831x_dcdc_get_status,
.get_mode = wm831x_dcdc_get_mode,
.set_mode = wm831x_dcdc_set_mode,
@ -708,6 +664,7 @@ static __devinit int wm831x_buckp_probe(struct platform_device *pdev)
{
struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
struct wm831x_pdata *pdata = wm831x->dev->platform_data;
struct regulator_config config = { };
int id;
struct wm831x_dcdc *dcdc;
struct resource *res;
@ -721,9 +678,6 @@ static __devinit int wm831x_buckp_probe(struct platform_device *pdev)
dev_dbg(&pdev->dev, "Probing DCDC%d\n", id + 1);
if (pdata == NULL || pdata->dcdc[id] == NULL)
return -ENODEV;
dcdc = devm_kzalloc(&pdev->dev, sizeof(struct wm831x_dcdc),
GFP_KERNEL);
if (dcdc == NULL) {
@ -748,9 +702,18 @@ static __devinit int wm831x_buckp_probe(struct platform_device *pdev)
dcdc->desc.n_voltages = WM831X_BUCKP_MAX_SELECTOR + 1;
dcdc->desc.ops = &wm831x_buckp_ops;
dcdc->desc.owner = THIS_MODULE;
dcdc->desc.vsel_reg = dcdc->base + WM831X_DCDC_ON_CONFIG;
dcdc->desc.vsel_mask = WM831X_DC3_ON_VSEL_MASK;
dcdc->desc.enable_reg = WM831X_DCDC_ENABLE;
dcdc->desc.enable_mask = 1 << id;
dcdc->regulator = regulator_register(&dcdc->desc, &pdev->dev,
pdata->dcdc[id], dcdc, NULL);
config.dev = pdev->dev.parent;
if (pdata)
config.init_data = pdata->dcdc[id];
config.driver_data = dcdc;
config.regmap = wm831x->regmap;
dcdc->regulator = regulator_register(&dcdc->desc, &config);
if (IS_ERR(dcdc->regulator)) {
ret = PTR_ERR(dcdc->regulator);
dev_err(wm831x->dev, "Failed to register DCDC%d: %d\n",
@ -832,15 +795,16 @@ static int wm831x_boostp_get_status(struct regulator_dev *rdev)
static struct regulator_ops wm831x_boostp_ops = {
.get_status = wm831x_boostp_get_status,
.is_enabled = wm831x_dcdc_is_enabled,
.enable = wm831x_dcdc_enable,
.disable = wm831x_dcdc_disable,
.is_enabled = regulator_is_enabled_regmap,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
};
static __devinit int wm831x_boostp_probe(struct platform_device *pdev)
{
struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
struct wm831x_pdata *pdata = wm831x->dev->platform_data;
struct regulator_config config = { };
int id = pdev->id % ARRAY_SIZE(pdata->dcdc);
struct wm831x_dcdc *dcdc;
struct resource *res;
@ -851,7 +815,7 @@ static __devinit int wm831x_boostp_probe(struct platform_device *pdev)
if (pdata == NULL || pdata->dcdc[id] == NULL)
return -ENODEV;
dcdc = kzalloc(sizeof(struct wm831x_dcdc), GFP_KERNEL);
dcdc = devm_kzalloc(&pdev->dev, sizeof(struct wm831x_dcdc), GFP_KERNEL);
if (dcdc == NULL) {
dev_err(&pdev->dev, "Unable to allocate private data\n");
return -ENOMEM;
@ -873,9 +837,15 @@ static __devinit int wm831x_boostp_probe(struct platform_device *pdev)
dcdc->desc.type = REGULATOR_VOLTAGE;
dcdc->desc.ops = &wm831x_boostp_ops;
dcdc->desc.owner = THIS_MODULE;
dcdc->desc.enable_reg = WM831X_DCDC_ENABLE;
dcdc->desc.enable_mask = 1 << id;
dcdc->regulator = regulator_register(&dcdc->desc, &pdev->dev,
pdata->dcdc[id], dcdc, NULL);
config.dev = pdev->dev.parent;
config.init_data = pdata->dcdc[id];
config.driver_data = dcdc;
config.regmap = wm831x->regmap;
dcdc->regulator = regulator_register(&dcdc->desc, &config);
if (IS_ERR(dcdc->regulator)) {
ret = PTR_ERR(dcdc->regulator);
dev_err(wm831x->dev, "Failed to register DCDC%d: %d\n",
@ -900,7 +870,6 @@ static __devinit int wm831x_boostp_probe(struct platform_device *pdev)
err_regulator:
regulator_unregister(dcdc->regulator);
err:
kfree(dcdc);
return ret;
}
@ -912,7 +881,6 @@ static __devexit int wm831x_boostp_remove(struct platform_device *pdev)
free_irq(platform_get_irq_byname(pdev, "UV"), dcdc);
regulator_unregister(dcdc->regulator);
kfree(dcdc);
return 0;
}
@ -936,9 +904,9 @@ static struct platform_driver wm831x_boostp_driver = {
#define WM831X_EPE_BASE 6
static struct regulator_ops wm831x_epe_ops = {
.is_enabled = wm831x_dcdc_is_enabled,
.enable = wm831x_dcdc_enable,
.disable = wm831x_dcdc_disable,
.is_enabled = regulator_is_enabled_regmap,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.get_status = wm831x_dcdc_get_status,
};
@ -946,16 +914,14 @@ static __devinit int wm831x_epe_probe(struct platform_device *pdev)
{
struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
struct wm831x_pdata *pdata = wm831x->dev->platform_data;
struct regulator_config config = { };
int id = pdev->id % ARRAY_SIZE(pdata->epe);
struct wm831x_dcdc *dcdc;
int ret;
dev_dbg(&pdev->dev, "Probing EPE%d\n", id + 1);
if (pdata == NULL || pdata->epe[id] == NULL)
return -ENODEV;
dcdc = kzalloc(sizeof(struct wm831x_dcdc), GFP_KERNEL);
dcdc = devm_kzalloc(&pdev->dev, sizeof(struct wm831x_dcdc), GFP_KERNEL);
if (dcdc == NULL) {
dev_err(&pdev->dev, "Unable to allocate private data\n");
return -ENOMEM;
@ -972,9 +938,16 @@ static __devinit int wm831x_epe_probe(struct platform_device *pdev)
dcdc->desc.ops = &wm831x_epe_ops;
dcdc->desc.type = REGULATOR_VOLTAGE;
dcdc->desc.owner = THIS_MODULE;
dcdc->desc.enable_reg = WM831X_DCDC_ENABLE;
dcdc->desc.enable_mask = 1 << dcdc->desc.id;
dcdc->regulator = regulator_register(&dcdc->desc, &pdev->dev,
pdata->epe[id], dcdc, NULL);
config.dev = pdev->dev.parent;
if (pdata)
config.init_data = pdata->epe[id];
config.driver_data = dcdc;
config.regmap = wm831x->regmap;
dcdc->regulator = regulator_register(&dcdc->desc, &config);
if (IS_ERR(dcdc->regulator)) {
ret = PTR_ERR(dcdc->regulator);
dev_err(wm831x->dev, "Failed to register EPE%d: %d\n",
@ -987,7 +960,6 @@ static __devinit int wm831x_epe_probe(struct platform_device *pdev)
return 0;
err:
kfree(dcdc);
return ret;
}
@ -996,9 +968,7 @@ static __devexit int wm831x_epe_remove(struct platform_device *pdev)
struct wm831x_dcdc *dcdc = platform_get_drvdata(pdev);
platform_set_drvdata(pdev, NULL);
regulator_unregister(dcdc->regulator);
kfree(dcdc);
return 0;
}

View File

@ -154,6 +154,7 @@ static __devinit int wm831x_isink_probe(struct platform_device *pdev)
struct wm831x_pdata *pdata = wm831x->dev->platform_data;
struct wm831x_isink *isink;
int id = pdev->id % ARRAY_SIZE(pdata->isink);
struct regulator_config config = { };
struct resource *res;
int ret, irq;
@ -189,8 +190,11 @@ static __devinit int wm831x_isink_probe(struct platform_device *pdev)
isink->desc.type = REGULATOR_CURRENT;
isink->desc.owner = THIS_MODULE;
isink->regulator = regulator_register(&isink->desc, &pdev->dev,
pdata->isink[id], isink, NULL);
config.dev = pdev->dev.parent;
config.init_data = pdata->isink[id];
config.driver_data = isink;
isink->regulator = regulator_register(&isink->desc, &config);
if (IS_ERR(isink->regulator)) {
ret = PTR_ERR(isink->regulator);
dev_err(wm831x->dev, "Failed to register ISINK%d: %d\n",

View File

@ -46,41 +46,6 @@ struct wm831x_ldo {
* Shared
*/
static int wm831x_ldo_is_enabled(struct regulator_dev *rdev)
{
struct wm831x_ldo *ldo = rdev_get_drvdata(rdev);
struct wm831x *wm831x = ldo->wm831x;
int mask = 1 << rdev_get_id(rdev);
int reg;
reg = wm831x_reg_read(wm831x, WM831X_LDO_ENABLE);
if (reg < 0)
return reg;
if (reg & mask)
return 1;
else
return 0;
}
static int wm831x_ldo_enable(struct regulator_dev *rdev)
{
struct wm831x_ldo *ldo = rdev_get_drvdata(rdev);
struct wm831x *wm831x = ldo->wm831x;
int mask = 1 << rdev_get_id(rdev);
return wm831x_set_bits(wm831x, WM831X_LDO_ENABLE, mask, mask);
}
static int wm831x_ldo_disable(struct regulator_dev *rdev)
{
struct wm831x_ldo *ldo = rdev_get_drvdata(rdev);
struct wm831x *wm831x = ldo->wm831x;
int mask = 1 << rdev_get_id(rdev);
return wm831x_set_bits(wm831x, WM831X_LDO_ENABLE, mask, 0);
}
static irqreturn_t wm831x_ldo_uv_irq(int irq, void *data)
{
struct wm831x_ldo *ldo = data;
@ -105,7 +70,7 @@ static int wm831x_gp_ldo_list_voltage(struct regulator_dev *rdev,
/* 0.9-1.6V in 50mV steps */
if (selector <= WM831X_GP_LDO_SELECTOR_LOW)
return 900000 + (selector * 50000);
/* 1.7-3.3V in 50mV steps */
/* 1.7-3.3V in 100mV steps */
if (selector <= WM831X_GP_LDO_MAX_SELECTOR)
return 1600000 + ((selector - WM831X_GP_LDO_SELECTOR_LOW)
* 100000);
@ -160,22 +125,6 @@ static int wm831x_gp_ldo_set_suspend_voltage(struct regulator_dev *rdev,
return wm831x_gp_ldo_set_voltage_int(rdev, reg, uV, uV, &selector);
}
static int wm831x_gp_ldo_get_voltage_sel(struct regulator_dev *rdev)
{
struct wm831x_ldo *ldo = rdev_get_drvdata(rdev);
struct wm831x *wm831x = ldo->wm831x;
int reg = ldo->base + WM831X_LDO_ON_CONTROL;
int ret;
ret = wm831x_reg_read(wm831x, reg);
if (ret < 0)
return ret;
ret &= WM831X_LDO1_ON_VSEL_MASK;
return ret;
}
static unsigned int wm831x_gp_ldo_get_mode(struct regulator_dev *rdev)
{
struct wm831x_ldo *ldo = rdev_get_drvdata(rdev);
@ -293,7 +242,7 @@ static unsigned int wm831x_gp_ldo_get_optimum_mode(struct regulator_dev *rdev,
static struct regulator_ops wm831x_gp_ldo_ops = {
.list_voltage = wm831x_gp_ldo_list_voltage,
.get_voltage_sel = wm831x_gp_ldo_get_voltage_sel,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.set_voltage = wm831x_gp_ldo_set_voltage,
.set_suspend_voltage = wm831x_gp_ldo_set_suspend_voltage,
.get_mode = wm831x_gp_ldo_get_mode,
@ -301,15 +250,16 @@ static struct regulator_ops wm831x_gp_ldo_ops = {
.get_status = wm831x_gp_ldo_get_status,
.get_optimum_mode = wm831x_gp_ldo_get_optimum_mode,
.is_enabled = wm831x_ldo_is_enabled,
.enable = wm831x_ldo_enable,
.disable = wm831x_ldo_disable,
.is_enabled = regulator_is_enabled_regmap,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
};
static __devinit int wm831x_gp_ldo_probe(struct platform_device *pdev)
{
struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
struct wm831x_pdata *pdata = wm831x->dev->platform_data;
struct regulator_config config = { };
int id;
struct wm831x_ldo *ldo;
struct resource *res;
@ -323,9 +273,6 @@ static __devinit int wm831x_gp_ldo_probe(struct platform_device *pdev)
dev_dbg(&pdev->dev, "Probing LDO%d\n", id + 1);
if (pdata == NULL || pdata->ldo[id] == NULL)
return -ENODEV;
ldo = devm_kzalloc(&pdev->dev, sizeof(struct wm831x_ldo), GFP_KERNEL);
if (ldo == NULL) {
dev_err(&pdev->dev, "Unable to allocate private data\n");
@ -349,9 +296,18 @@ static __devinit int wm831x_gp_ldo_probe(struct platform_device *pdev)
ldo->desc.n_voltages = WM831X_GP_LDO_MAX_SELECTOR + 1;
ldo->desc.ops = &wm831x_gp_ldo_ops;
ldo->desc.owner = THIS_MODULE;
ldo->desc.vsel_reg = ldo->base + WM831X_LDO_ON_CONTROL;
ldo->desc.vsel_mask = WM831X_LDO1_ON_VSEL_MASK;
ldo->desc.enable_reg = WM831X_LDO_ENABLE;
ldo->desc.enable_mask = 1 << id;
ldo->regulator = regulator_register(&ldo->desc, &pdev->dev,
pdata->ldo[id], ldo, NULL);
config.dev = pdev->dev.parent;
if (pdata)
config.init_data = pdata->ldo[id];
config.driver_data = ldo;
config.regmap = wm831x->regmap;
ldo->regulator = regulator_register(&ldo->desc, &config);
if (IS_ERR(ldo->regulator)) {
ret = PTR_ERR(ldo->regulator);
dev_err(wm831x->dev, "Failed to register LDO%d: %d\n",
@ -414,7 +370,7 @@ static int wm831x_aldo_list_voltage(struct regulator_dev *rdev,
/* 1-1.6V in 50mV steps */
if (selector <= WM831X_ALDO_SELECTOR_LOW)
return 1000000 + (selector * 50000);
/* 1.7-3.5V in 50mV steps */
/* 1.7-3.5V in 100mV steps */
if (selector <= WM831X_ALDO_MAX_SELECTOR)
return 1600000 + ((selector - WM831X_ALDO_SELECTOR_LOW)
* 100000);
@ -468,22 +424,6 @@ static int wm831x_aldo_set_suspend_voltage(struct regulator_dev *rdev,
return wm831x_aldo_set_voltage_int(rdev, reg, uV, uV, &selector);
}
static int wm831x_aldo_get_voltage_sel(struct regulator_dev *rdev)
{
struct wm831x_ldo *ldo = rdev_get_drvdata(rdev);
struct wm831x *wm831x = ldo->wm831x;
int reg = ldo->base + WM831X_LDO_ON_CONTROL;
int ret;
ret = wm831x_reg_read(wm831x, reg);
if (ret < 0)
return ret;
ret &= WM831X_LDO7_ON_VSEL_MASK;
return ret;
}
static unsigned int wm831x_aldo_get_mode(struct regulator_dev *rdev)
{
struct wm831x_ldo *ldo = rdev_get_drvdata(rdev);
@ -559,22 +499,23 @@ static int wm831x_aldo_get_status(struct regulator_dev *rdev)
static struct regulator_ops wm831x_aldo_ops = {
.list_voltage = wm831x_aldo_list_voltage,
.get_voltage_sel = wm831x_aldo_get_voltage_sel,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.set_voltage = wm831x_aldo_set_voltage,
.set_suspend_voltage = wm831x_aldo_set_suspend_voltage,
.get_mode = wm831x_aldo_get_mode,
.set_mode = wm831x_aldo_set_mode,
.get_status = wm831x_aldo_get_status,
.is_enabled = wm831x_ldo_is_enabled,
.enable = wm831x_ldo_enable,
.disable = wm831x_ldo_disable,
.is_enabled = regulator_is_enabled_regmap,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
};
static __devinit int wm831x_aldo_probe(struct platform_device *pdev)
{
struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
struct wm831x_pdata *pdata = wm831x->dev->platform_data;
struct regulator_config config = { };
int id;
struct wm831x_ldo *ldo;
struct resource *res;
@ -588,9 +529,6 @@ static __devinit int wm831x_aldo_probe(struct platform_device *pdev)
dev_dbg(&pdev->dev, "Probing LDO%d\n", id + 1);
if (pdata == NULL || pdata->ldo[id] == NULL)
return -ENODEV;
ldo = devm_kzalloc(&pdev->dev, sizeof(struct wm831x_ldo), GFP_KERNEL);
if (ldo == NULL) {
dev_err(&pdev->dev, "Unable to allocate private data\n");
@ -614,9 +552,18 @@ static __devinit int wm831x_aldo_probe(struct platform_device *pdev)
ldo->desc.n_voltages = WM831X_ALDO_MAX_SELECTOR + 1;
ldo->desc.ops = &wm831x_aldo_ops;
ldo->desc.owner = THIS_MODULE;
ldo->desc.vsel_reg = ldo->base + WM831X_LDO_ON_CONTROL;
ldo->desc.vsel_mask = WM831X_LDO7_ON_VSEL_MASK;
ldo->desc.enable_reg = WM831X_LDO_ENABLE;
ldo->desc.enable_mask = 1 << id;
ldo->regulator = regulator_register(&ldo->desc, &pdev->dev,
pdata->ldo[id], ldo, NULL);
config.dev = pdev->dev.parent;
if (pdata)
config.init_data = pdata->ldo[id];
config.driver_data = ldo;
config.regmap = wm831x->regmap;
ldo->regulator = regulator_register(&ldo->desc, &config);
if (IS_ERR(ldo->regulator)) {
ret = PTR_ERR(ldo->regulator);
dev_err(wm831x->dev, "Failed to register LDO%d: %d\n",
@ -720,22 +667,6 @@ static int wm831x_alive_ldo_set_suspend_voltage(struct regulator_dev *rdev,
return wm831x_alive_ldo_set_voltage_int(rdev, reg, uV, uV, &selector);
}
static int wm831x_alive_ldo_get_voltage_sel(struct regulator_dev *rdev)
{
struct wm831x_ldo *ldo = rdev_get_drvdata(rdev);
struct wm831x *wm831x = ldo->wm831x;
int reg = ldo->base + WM831X_ALIVE_LDO_ON_CONTROL;
int ret;
ret = wm831x_reg_read(wm831x, reg);
if (ret < 0)
return ret;
ret &= WM831X_LDO11_ON_VSEL_MASK;
return ret;
}
static int wm831x_alive_ldo_get_status(struct regulator_dev *rdev)
{
struct wm831x_ldo *ldo = rdev_get_drvdata(rdev);
@ -755,20 +686,21 @@ static int wm831x_alive_ldo_get_status(struct regulator_dev *rdev)
static struct regulator_ops wm831x_alive_ldo_ops = {
.list_voltage = wm831x_alive_ldo_list_voltage,
.get_voltage_sel = wm831x_alive_ldo_get_voltage_sel,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.set_voltage = wm831x_alive_ldo_set_voltage,
.set_suspend_voltage = wm831x_alive_ldo_set_suspend_voltage,
.get_status = wm831x_alive_ldo_get_status,
.is_enabled = wm831x_ldo_is_enabled,
.enable = wm831x_ldo_enable,
.disable = wm831x_ldo_disable,
.is_enabled = regulator_is_enabled_regmap,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
};
static __devinit int wm831x_alive_ldo_probe(struct platform_device *pdev)
{
struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
struct wm831x_pdata *pdata = wm831x->dev->platform_data;
struct regulator_config config = { };
int id;
struct wm831x_ldo *ldo;
struct resource *res;
@ -783,9 +715,6 @@ static __devinit int wm831x_alive_ldo_probe(struct platform_device *pdev)
dev_dbg(&pdev->dev, "Probing LDO%d\n", id + 1);
if (pdata == NULL || pdata->ldo[id] == NULL)
return -ENODEV;
ldo = devm_kzalloc(&pdev->dev, sizeof(struct wm831x_ldo), GFP_KERNEL);
if (ldo == NULL) {
dev_err(&pdev->dev, "Unable to allocate private data\n");
@ -809,9 +738,18 @@ static __devinit int wm831x_alive_ldo_probe(struct platform_device *pdev)
ldo->desc.n_voltages = WM831X_ALIVE_LDO_MAX_SELECTOR + 1;
ldo->desc.ops = &wm831x_alive_ldo_ops;
ldo->desc.owner = THIS_MODULE;
ldo->desc.vsel_reg = ldo->base + WM831X_ALIVE_LDO_ON_CONTROL;
ldo->desc.vsel_mask = WM831X_LDO11_ON_VSEL_MASK;
ldo->desc.enable_reg = WM831X_LDO_ENABLE;
ldo->desc.enable_mask = 1 << id;
ldo->regulator = regulator_register(&ldo->desc, &pdev->dev,
pdata->ldo[id], ldo, NULL);
config.dev = pdev->dev.parent;
if (pdata)
config.init_data = pdata->ldo[id];
config.driver_data = ldo;
config.regmap = wm831x->regmap;
ldo->regulator = regulator_register(&ldo->desc, &config);
if (IS_ERR(ldo->regulator)) {
ret = PTR_ERR(ldo->regulator);
dev_err(wm831x->dev, "Failed to register LDO%d: %d\n",

View File

@ -1269,7 +1269,7 @@ static struct regulator_ops wm8350_isink_ops = {
.enable_time = wm8350_isink_enable_time,
};
static struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = {
static const struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = {
{
.name = "DCDC1",
.id = WM8350_DCDC_1,
@ -1398,6 +1398,7 @@ static irqreturn_t pmic_uv_handler(int irq, void *data)
static int wm8350_regulator_probe(struct platform_device *pdev)
{
struct wm8350 *wm8350 = dev_get_drvdata(&pdev->dev);
struct regulator_config config = { };
struct regulator_dev *rdev;
int ret;
u16 val;
@ -1425,10 +1426,12 @@ static int wm8350_regulator_probe(struct platform_device *pdev)
break;
}
config.dev = &pdev->dev;
config.init_data = pdev->dev.platform_data;
config.driver_data = dev_get_drvdata(&pdev->dev);
/* register regulator */
rdev = regulator_register(&wm8350_reg[pdev->id], &pdev->dev,
pdev->dev.platform_data,
dev_get_drvdata(&pdev->dev), NULL);
rdev = regulator_register(&wm8350_reg[pdev->id], &config);
if (IS_ERR(rdev)) {
dev_err(&pdev->dev, "failed to register %s\n",
wm8350_reg[pdev->id].name);

View File

@ -323,11 +323,14 @@ static struct regulator_desc regulators[] = {
static int __devinit wm8400_regulator_probe(struct platform_device *pdev)
{
struct wm8400 *wm8400 = container_of(pdev, struct wm8400, regulators[pdev->id]);
struct regulator_config config = { };
struct regulator_dev *rdev;
rdev = regulator_register(&regulators[pdev->id], &pdev->dev,
pdev->dev.platform_data, wm8400, NULL);
config.dev = &pdev->dev;
config.init_data = pdev->dev.platform_data;
config.driver_data = wm8400;
rdev = regulator_register(&regulators[pdev->id], &config);
if (IS_ERR(rdev))
return PTR_ERR(rdev);

View File

@ -86,36 +86,6 @@ static int wm8994_ldo1_list_voltage(struct regulator_dev *rdev,
return (selector * 100000) + 2400000;
}
static int wm8994_ldo1_get_voltage_sel(struct regulator_dev *rdev)
{
struct wm8994_ldo *ldo = rdev_get_drvdata(rdev);
int val;
val = wm8994_reg_read(ldo->wm8994, WM8994_LDO_1);
if (val < 0)
return val;
return (val & WM8994_LDO1_VSEL_MASK) >> WM8994_LDO1_VSEL_SHIFT;
}
static int wm8994_ldo1_set_voltage(struct regulator_dev *rdev,
int min_uV, int max_uV, unsigned *s)
{
struct wm8994_ldo *ldo = rdev_get_drvdata(rdev);
int selector, v;
selector = (min_uV - 2400000) / 100000;
v = wm8994_ldo1_list_voltage(rdev, selector);
if (v < 0 || v > max_uV)
return -EINVAL;
*s = selector;
selector <<= WM8994_LDO1_VSEL_SHIFT;
return wm8994_set_bits(ldo->wm8994, WM8994_LDO_1,
WM8994_LDO1_VSEL_MASK, selector);
}
static struct regulator_ops wm8994_ldo1_ops = {
.enable = wm8994_ldo_enable,
.disable = wm8994_ldo_disable,
@ -123,8 +93,8 @@ static struct regulator_ops wm8994_ldo1_ops = {
.enable_time = wm8994_ldo_enable_time,
.list_voltage = wm8994_ldo1_list_voltage,
.get_voltage_sel = wm8994_ldo1_get_voltage_sel,
.set_voltage = wm8994_ldo1_set_voltage,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
};
static int wm8994_ldo2_list_voltage(struct regulator_dev *rdev,
@ -153,51 +123,6 @@ static int wm8994_ldo2_list_voltage(struct regulator_dev *rdev,
}
}
static int wm8994_ldo2_get_voltage_sel(struct regulator_dev *rdev)
{
struct wm8994_ldo *ldo = rdev_get_drvdata(rdev);
int val;
val = wm8994_reg_read(ldo->wm8994, WM8994_LDO_2);
if (val < 0)
return val;
return (val & WM8994_LDO2_VSEL_MASK) >> WM8994_LDO2_VSEL_SHIFT;
}
static int wm8994_ldo2_set_voltage(struct regulator_dev *rdev,
int min_uV, int max_uV, unsigned *s)
{
struct wm8994_ldo *ldo = rdev_get_drvdata(rdev);
int selector, v;
switch (ldo->wm8994->type) {
case WM8994:
selector = (min_uV - 900000) / 100000;
break;
case WM8958:
selector = (min_uV - 1000000) / 100000;
break;
case WM1811:
selector = (min_uV - 950000) / 100000;
if (selector == 0)
selector = 1;
break;
default:
return -EINVAL;
}
v = wm8994_ldo2_list_voltage(rdev, selector);
if (v < 0 || v > max_uV)
return -EINVAL;
*s = selector;
selector <<= WM8994_LDO2_VSEL_SHIFT;
return wm8994_set_bits(ldo->wm8994, WM8994_LDO_2,
WM8994_LDO2_VSEL_MASK, selector);
}
static struct regulator_ops wm8994_ldo2_ops = {
.enable = wm8994_ldo_enable,
.disable = wm8994_ldo_disable,
@ -205,16 +130,18 @@ static struct regulator_ops wm8994_ldo2_ops = {
.enable_time = wm8994_ldo_enable_time,
.list_voltage = wm8994_ldo2_list_voltage,
.get_voltage_sel = wm8994_ldo2_get_voltage_sel,
.set_voltage = wm8994_ldo2_set_voltage,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
};
static struct regulator_desc wm8994_ldo_desc[] = {
static const struct regulator_desc wm8994_ldo_desc[] = {
{
.name = "LDO1",
.id = 1,
.type = REGULATOR_VOLTAGE,
.n_voltages = WM8994_LDO1_MAX_SELECTOR + 1,
.vsel_reg = WM8994_LDO_1,
.vsel_mask = WM8994_LDO1_VSEL_MASK,
.ops = &wm8994_ldo1_ops,
.owner = THIS_MODULE,
},
@ -223,6 +150,8 @@ static struct regulator_desc wm8994_ldo_desc[] = {
.id = 2,
.type = REGULATOR_VOLTAGE,
.n_voltages = WM8994_LDO2_MAX_SELECTOR + 1,
.vsel_reg = WM8994_LDO_2,
.vsel_mask = WM8994_LDO2_VSEL_MASK,
.ops = &wm8994_ldo2_ops,
.owner = THIS_MODULE,
},
@ -233,6 +162,7 @@ static __devinit int wm8994_ldo_probe(struct platform_device *pdev)
struct wm8994 *wm8994 = dev_get_drvdata(pdev->dev.parent);
struct wm8994_pdata *pdata = wm8994->dev->platform_data;
int id = pdev->id % ARRAY_SIZE(pdata->ldo);
struct regulator_config config = { };
struct wm8994_ldo *ldo;
int ret;
@ -268,8 +198,12 @@ static __devinit int wm8994_ldo_probe(struct platform_device *pdev)
} else
ldo->is_enabled = true;
ldo->regulator = regulator_register(&wm8994_ldo_desc[id], &pdev->dev,
pdata->ldo[id].init_data, ldo, NULL);
config.dev = &pdev->dev;
config.init_data = pdata->ldo[id].init_data;
config.driver_data = ldo;
config.regmap = wm8994->regmap;
ldo->regulator = regulator_register(&wm8994_ldo_desc[id], &config);
if (IS_ERR(ldo->regulator)) {
ret = PTR_ERR(ldo->regulator);
dev_err(wm8994->dev, "Failed to register LDO%d: %d\n",

View File

@ -250,6 +250,26 @@ enum {
RC5T583_EXT_PWRREQ2_CONTROL = 0x2,
};
enum {
RC5T583_REGULATOR_DC0,
RC5T583_REGULATOR_DC1,
RC5T583_REGULATOR_DC2,
RC5T583_REGULATOR_DC3,
RC5T583_REGULATOR_LDO0,
RC5T583_REGULATOR_LDO1,
RC5T583_REGULATOR_LDO2,
RC5T583_REGULATOR_LDO3,
RC5T583_REGULATOR_LDO4,
RC5T583_REGULATOR_LDO5,
RC5T583_REGULATOR_LDO6,
RC5T583_REGULATOR_LDO7,
RC5T583_REGULATOR_LDO8,
RC5T583_REGULATOR_LDO9,
/* Should be last entry */
RC5T583_REGULATOR_MAX,
};
struct rc5t583 {
struct device *dev;
struct regmap *regmap;
@ -273,11 +293,20 @@ struct rc5t583 {
* The board specific data is provided through this structure.
* @irq_base: Irq base number on which this device registers their interrupts.
* @enable_shutdown: Enable shutdown through the input pin "shutdown".
* @regulator_deepsleep_slot: The slot number on which device goes to sleep
* in device sleep mode.
* @regulator_ext_pwr_control: External power request regulator control. The
* regulator output enable/disable is controlled by the external
* power request input state.
* @reg_init_data: Regulator init data.
*/
struct rc5t583_platform_data {
int irq_base;
bool enable_shutdown;
int regulator_deepsleep_slot[RC5T583_REGULATOR_MAX];
unsigned long regulator_ext_pwr_control[RC5T583_REGULATOR_MAX];
struct regulator_init_data *reg_init_data[RC5T583_REGULATOR_MAX];
};
static inline int rc5t583_write(struct device *dev, uint8_t reg, uint8_t val)

View File

@ -335,6 +335,7 @@ extern int s5m_reg_update(struct s5m87xx_dev *s5m87xx, u8 reg, u8 val, u8 mask);
struct s5m_platform_data {
struct s5m_regulator_data *regulators;
struct s5m_opmode_data *opmode;
int device_type;
int num_regulators;

View File

@ -58,6 +58,8 @@ enum s5m8767_regulators {
S5M8767_REG_MAX,
};
#define S5M8767_ENCTRL_SHIFT 6
/* S5M8763 regulator ids */
enum s5m8763_regulators {
S5M8763_LDO1,
@ -97,4 +99,31 @@ struct s5m_regulator_data {
struct regulator_init_data *initdata;
};
/*
* s5m_opmode_data - regulator operation mode data
* @id: regulator id
* @mode: regulator operation mode
*/
struct s5m_opmode_data {
int id;
int mode;
};
/*
* s5m regulator operation mode
* S5M_OPMODE_OFF Regulator always OFF
* S5M_OPMODE_ON Regulator always ON
* S5M_OPMODE_LOWPOWER Regulator is on in low-power mode
* S5M_OPMODE_SUSPEND Regulator is changed by PWREN pin
* If PWREN is high, regulator is on
* If PWREN is low, regulator is off
*/
enum s5m_opmode {
S5M_OPMODE_OFF,
S5M_OPMODE_ON,
S5M_OPMODE_LOWPOWER,
S5M_OPMODE_SUSPEND,
};
#endif /* __LINUX_MFD_S5M_PMIC_H */

View File

@ -22,6 +22,19 @@
#ifndef __LINUX_MFD_TPS65090_H
#define __LINUX_MFD_TPS65090_H
#include <linux/irq.h>
struct tps65090 {
struct mutex lock;
struct device *dev;
struct i2c_client *client;
struct regmap *rmap;
struct irq_chip irq_chip;
struct mutex irq_lock;
int irq_base;
unsigned int id;
};
struct tps65090_subdev_info {
int id;
const char *name;

View File

@ -19,6 +19,7 @@
#include <linux/notifier.h>
#include <linux/regulator/consumer.h>
struct regmap;
struct regulator_dev;
struct regulator_init_data;
@ -148,10 +149,12 @@ enum regulator_type {
};
/**
* struct regulator_desc - Regulator descriptor
* struct regulator_desc - Static regulator descriptor
*
* Each regulator registered with the core is described with a structure of
* this type.
* Each regulator registered with the core is described with a
* structure of this type and a struct regulator_config. This
* structure contains the non-varying parts of the regulator
* description.
*
* @name: Identifying name for the regulator.
* @supply_name: Identifying the regulator supply
@ -161,6 +164,11 @@ enum regulator_type {
* @irq: Interrupt number for the regulator.
* @type: Indicates if the regulator is a voltage or current regulator.
* @owner: Module providing the regulator, used for refcounting.
* @vsel_reg: Register for selector when using regulator_regmap_X_voltage_
* @vsel_mask: Mask for register bitfield used for selector
* @enable_reg: Register for control when using regmap enable/disable ops
* @enable_mask: Mask for control when using regmap enable/disable ops
*/
struct regulator_desc {
const char *name;
@ -171,6 +179,33 @@ struct regulator_desc {
int irq;
enum regulator_type type;
struct module *owner;
unsigned int vsel_reg;
unsigned int vsel_mask;
unsigned int enable_reg;
unsigned int enable_mask;
};
/**
* struct regulator_config - Dynamic regulator descriptor
*
* Each regulator registered with the core is described with a
* structure of this type and a struct regulator_desc. This structure
* contains the runtime variable parts of the regulator description.
*
* @dev: struct device for the regulator
* @init_data: platform provided init data, passed through by driver
* @driver_data: private regulator data
* @of_node: OpenFirmware node to parse for device tree bindings (may be
* NULL).
* @regmap: regmap to use for core regmap helpers
*/
struct regulator_config {
struct device *dev;
const struct regulator_init_data *init_data;
void *driver_data;
struct device_node *of_node;
struct regmap *regmap;
};
/*
@ -184,7 +219,7 @@ struct regulator_desc {
* no other direct access).
*/
struct regulator_dev {
struct regulator_desc *desc;
const struct regulator_desc *desc;
int exclusive;
u32 use_count;
u32 open_count;
@ -201,6 +236,7 @@ struct regulator_dev {
struct device dev;
struct regulation_constraints *constraints;
struct regulator *supply; /* for tree */
struct regmap *regmap;
struct delayed_work disable_work;
int deferred_disables;
@ -210,9 +246,9 @@ struct regulator_dev {
struct dentry *debugfs;
};
struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,
struct device *dev, const struct regulator_init_data *init_data,
void *driver_data, struct device_node *of_node);
struct regulator_dev *
regulator_register(const struct regulator_desc *regulator_desc,
const struct regulator_config *config);
void regulator_unregister(struct regulator_dev *rdev);
int regulator_notifier_call_chain(struct regulator_dev *rdev,
@ -224,6 +260,12 @@ int rdev_get_id(struct regulator_dev *rdev);
int regulator_mode_to_status(unsigned int);
int regulator_get_voltage_sel_regmap(struct regulator_dev *rdev);
int regulator_set_voltage_sel_regmap(struct regulator_dev *rdev, unsigned sel);
int regulator_is_enabled_regmap(struct regulator_dev *rdev);
int regulator_enable_regmap(struct regulator_dev *rdev);
int regulator_disable_regmap(struct regulator_dev *rdev);
void *regulator_get_init_drvdata(struct regulator_init_data *reg_init_data);
#endif

View File

@ -26,6 +26,12 @@ struct regulator_init_data;
* @gpio: GPIO to use for enable control
* set to -EINVAL if not used
* @startup_delay: Start-up time in microseconds
* @gpio_is_open_drain: Gpio pin is open drain or normal type.
* If it is open drain type then HIGH will be set
* through PULL-UP with setting gpio as input
* and low will be set as gpio-output with driven
* to low. For non-open-drain case, the gpio will
* will be in output and drive to low/high accordingly.
* @enable_high: Polarity of enable GPIO
* 1 = Active high, 0 = Active low
* @enabled_at_boot: Whether regulator has been enabled at
@ -43,6 +49,7 @@ struct fixed_voltage_config {
int microvolts;
int gpio;
unsigned startup_delay;
unsigned gpio_is_open_drain:1;
unsigned enable_high:1;
unsigned enabled_at_boot:1;
struct regulator_init_data *init_data;

View File

@ -0,0 +1,50 @@
/*
* Regulator driver interface for TI TPS65090 PMIC family
*
* Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved.
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __REGULATOR_TPS65090_H
#define __REGULATOR_TPS65090_H
#include <linux/regulator/machine.h>
#define tps65090_rails(_name) "tps65090_"#_name
enum {
TPS65090_ID_DCDC1,
TPS65090_ID_DCDC2,
TPS65090_ID_DCDC3,
TPS65090_ID_FET1,
TPS65090_ID_FET2,
TPS65090_ID_FET3,
TPS65090_ID_FET4,
TPS65090_ID_FET5,
TPS65090_ID_FET6,
TPS65090_ID_FET7,
};
/*
* struct tps65090_regulator_platform_data
*
* @regulator: The regulator init data.
* @slew_rate_uV_per_us: Slew rate microvolt per microsec.
*/
struct tps65090_regulator_platform_data {
struct regulator_init_data regulator;
};
#endif /* __REGULATOR_TPS65090_H */

View File

@ -809,6 +809,7 @@ static int ldo_regulator_register(struct snd_soc_codec *codec,
{
struct ldo_regulator *ldo;
struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
struct regulator_config config = { };
ldo = kzalloc(sizeof(struct ldo_regulator), GFP_KERNEL);
@ -832,8 +833,11 @@ static int ldo_regulator_register(struct snd_soc_codec *codec,
ldo->codec_data = codec;
ldo->voltage = voltage;
ldo->dev = regulator_register(&ldo->desc, codec->dev,
init_data, ldo, NULL);
config.dev = codec->dev;
config.driver_data = ldo;
config.init_data = init_data;
ldo->dev = regulator_register(&ldo->desc, &config);
if (IS_ERR(ldo->dev)) {
int ret = PTR_ERR(ldo->dev);