Commit ac180657 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'regulator-3.5' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator

Pull regulator updates from Mark Brown:
 "The major thing here is the addition of some helpers to factor code
  out of drivers, making a fair proportion of regulators much more just
  data rather than code which is nice.

  - Helpers in the core for regulators using regmap, providing generic
    implementations of the enable and voltage selection operations which
    just need data to describe them in the drivers.
  - Split out voltage mapping and voltage setting, allowing many more
    drivers to take advantage of the infrastructure for selectors.
  - Loads and loads of cleanups from Axel Lin once again, including many
    changes to take advantage of the above new framework features
  - New drivers for Ricoh RC5T583, TI TPS62362, TI TPS62363, TI
    TPS65913, TI TWL6035 and TI TWL6037.

  Some of the registration changes to support the core refactoring
  caused so many conflicts that eventually topic branches were abandoned
  for this release."

* tag 'regulator-3.5' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator: (227 commits)
  regulator: tps65910: use of_node of matched regulator being register
  regulator: tps65910: dt: support when "regulators" node found
  regulator: tps65910: add error message in case of failure
  regulator: tps62360: dt: initialize of_node param for regulator register.
  regulator: tps65910: use devm_* for memory allocation
  regulator: tps65910: use small letter for regulator names
  mfd: tpx6586x:  Depend on regulator
  regulator: regulator for Palmas Kconfig
  regulator: regulator driver for Palmas series chips
  regulator: Enable Device Tree for the db8500-prcmu regulator driver
  regulator: db8500-prcmu: Separate regulator registration from probe
  regulator: ab3100: Use regulator_map_voltage_iterate()
  regulator: tps65217: Convert to set_voltage_sel and map_voltage
  regulator: Enable the ab8500 for Device Tree
  regulator: ab8500: Split up probe() into manageable pieces
  regulator: max8925: Remove check_range function and max_uV from struct rc5t583_regulator_info
  regulator: max8649: Remove unused check_range() function
  regulator: rc5t583: Remove max_uV from struct rc5t583_regulator_info
  regulator: da9052: Convert to set_voltage_sel and map_voltage
  regulator: max8952: Use devm_kzalloc
  ...
parents ae82a828 84df8c12
...@@ -8,6 +8,8 @@ Optional properties: ...@@ -8,6 +8,8 @@ Optional properties:
- startup-delay-us: startup time in microseconds - startup-delay-us: startup time in microseconds
- enable-active-high: Polarity of GPIO is Active high - enable-active-high: Polarity of GPIO is Active high
If this property is missing, the default assumed is Active low. If this property is missing, the default assumed is Active low.
- gpio-open-drain: GPIO is open drain type.
If this property is missing then default assumption is false.
Any property defined as part of the core regulator Any property defined as part of the core regulator
binding, defined in regulator.txt, can also be used. binding, defined in regulator.txt, can also be used.
...@@ -25,5 +27,6 @@ Example: ...@@ -25,5 +27,6 @@ Example:
gpio = <&gpio1 16 0>; gpio = <&gpio1 16 0>;
startup-delay-us = <70000>; startup-delay-us = <70000>;
enable-active-high; enable-active-high;
regulator-boot-on regulator-boot-on;
gpio-open-drain;
}; };
TPS62360 Voltage regulators
Required properties:
- compatible: Must be one of the following.
"ti,tps62360"
"ti,tps62361",
"ti,tps62362",
"ti,tps62363",
- reg: I2C slave address
Optional properties:
- ti,enable-vout-discharge: Enable output discharge. This is boolean value.
- ti,enable-pull-down: Enable pull down. This is boolean value.
- ti,vsel0-gpio: GPIO for controlling VSEL0 line.
If this property is missing, then assume that there is no GPIO
for vsel0 control.
- ti,vsel1-gpio: Gpio for controlling VSEL1 line.
If this property is missing, then assume that there is no GPIO
for vsel1 control.
- ti,vsel0-state-high: Inital state of vsel0 input is high.
If this property is missing, then assume the state as low (0).
- ti,vsel1-state-high: Inital state of vsel1 input is high.
If this property is missing, then assume the state as low (0).
Any property defined as part of the core regulator binding, defined in
regulator.txt, can also be used.
Example:
abc: tps62360 {
compatible = "ti,tps62361";
reg = <0x60>;
regulator-name = "tps62361-vout";
regulator-min-microvolt = <500000>;
regulator-max-microvolt = <1500000>;
regulator-boot-on
ti,vsel0-gpio = <&gpio1 16 0>;
ti,vsel1-gpio = <&gpio1 17 0>;
ti,vsel0-state-high;
ti,vsel1-state-high;
ti,enable-pull-down;
ti,enable-force-pwm;
ti,enable-vout-discharge;
};
TPS6586x family of regulators
Required properties:
- compatible: "ti,tps6586x"
- reg: I2C slave address
- interrupts: the interrupt outputs of the controller
- #gpio-cells: number of cells to describe a GPIO
- gpio-controller: mark the device as a GPIO controller
- regulators: list of regulators provided by this controller, must be named
after their hardware counterparts: sm[0-2], ldo[0-9] and ldo_rtc
Each regulator is defined using the standard binding for regulators.
Example:
pmu: tps6586x@34 {
compatible = "ti,tps6586x";
reg = <0x34>;
interrupts = <0 88 0x4>;
#gpio-cells = <2>;
gpio-controller;
regulators {
sm0_reg: sm0 {
regulator-min-microvolt = < 725000>;
regulator-max-microvolt = <1500000>;
regulator-boot-on;
regulator-always-on;
};
sm1_reg: sm1 {
regulator-min-microvolt = < 725000>;
regulator-max-microvolt = <1500000>;
regulator-boot-on;
regulator-always-on;
};
sm2_reg: sm2 {
regulator-min-microvolt = <3000000>;
regulator-max-microvolt = <4550000>;
regulator-boot-on;
regulator-always-on;
};
ldo0_reg: ldo0 {
regulator-name = "PCIE CLK";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
};
ldo1_reg: ldo1 {
regulator-min-microvolt = < 725000>;
regulator-max-microvolt = <1500000>;
};
ldo2_reg: ldo2 {
regulator-min-microvolt = < 725000>;
regulator-max-microvolt = <1500000>;
};
ldo3_reg: ldo3 {
regulator-min-microvolt = <1250000>;
regulator-max-microvolt = <3300000>;
};
ldo4_reg: ldo4 {
regulator-min-microvolt = <1700000>;
regulator-max-microvolt = <2475000>;
};
ldo5_reg: ldo5 {
regulator-min-microvolt = <1250000>;
regulator-max-microvolt = <3300000>;
};
ldo6_reg: ldo6 {
regulator-min-microvolt = <1250000>;
regulator-max-microvolt = <3300000>;
};
ldo7_reg: ldo7 {
regulator-min-microvolt = <1250000>;
regulator-max-microvolt = <3300000>;
};
ldo8_reg: ldo8 {
regulator-min-microvolt = <1250000>;
regulator-max-microvolt = <3300000>;
};
ldo9_reg: ldo9 {
regulator-min-microvolt = <1250000>;
regulator-max-microvolt = <3300000>;
};
};
};
...@@ -11,8 +11,7 @@ Registration ...@@ -11,8 +11,7 @@ Registration
Drivers can register a regulator by calling :- Drivers can register a regulator by calling :-
struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc, struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,
struct device *dev, struct regulator_init_data *init_data, const struct regulator_config *config);
void *driver_data, struct device_node *of_node);
This will register the regulators capabilities and operations to the regulator This will register the regulators capabilities and operations to the regulator
core. core.
......
...@@ -162,6 +162,7 @@ config MFD_TPS6586X ...@@ -162,6 +162,7 @@ config MFD_TPS6586X
bool "TPS6586x Power Management chips" bool "TPS6586x Power Management chips"
depends on I2C=y && GPIOLIB && GENERIC_HARDIRQS depends on I2C=y && GPIOLIB && GENERIC_HARDIRQS
select MFD_CORE select MFD_CORE
depends on REGULATOR
help help
If you say yes here you get support for the TPS6586X series of If you say yes here you get support for the TPS6586X series of
Power Management chips. Power Management chips.
......
...@@ -78,17 +78,6 @@ static struct mfd_cell tps65090s[] = { ...@@ -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) int tps65090_write(struct device *dev, int reg, uint8_t val)
{ {
struct tps65090 *tps = dev_get_drvdata(dev); struct tps65090 *tps = dev_get_drvdata(dev);
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/gpio.h> #include <linux/gpio.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/regulator/of_regulator.h>
#include <linux/mfd/core.h> #include <linux/mfd/core.h>
#include <linux/mfd/tps6586x.h> #include <linux/mfd/tps6586x.h>
...@@ -460,6 +461,7 @@ static int __devinit tps6586x_add_subdevs(struct tps6586x *tps6586x, ...@@ -460,6 +461,7 @@ static int __devinit tps6586x_add_subdevs(struct tps6586x *tps6586x,
pdev->dev.parent = tps6586x->dev; pdev->dev.parent = tps6586x->dev;
pdev->dev.platform_data = subdev->platform_data; pdev->dev.platform_data = subdev->platform_data;
pdev->dev.of_node = subdev->of_node;
ret = platform_device_add(pdev); ret = platform_device_add(pdev);
if (ret) { if (ret) {
...@@ -474,6 +476,86 @@ static int __devinit tps6586x_add_subdevs(struct tps6586x *tps6586x, ...@@ -474,6 +476,86 @@ static int __devinit tps6586x_add_subdevs(struct tps6586x *tps6586x,
return ret; return ret;
} }
#ifdef CONFIG_OF
static struct of_regulator_match tps6586x_matches[] = {
{ .name = "sm0", .driver_data = (void *)TPS6586X_ID_SM_0 },
{ .name = "sm1", .driver_data = (void *)TPS6586X_ID_SM_1 },
{ .name = "sm2", .driver_data = (void *)TPS6586X_ID_SM_2 },
{ .name = "ldo0", .driver_data = (void *)TPS6586X_ID_LDO_0 },
{ .name = "ldo1", .driver_data = (void *)TPS6586X_ID_LDO_1 },
{ .name = "ldo2", .driver_data = (void *)TPS6586X_ID_LDO_2 },
{ .name = "ldo3", .driver_data = (void *)TPS6586X_ID_LDO_3 },
{ .name = "ldo4", .driver_data = (void *)TPS6586X_ID_LDO_4 },
{ .name = "ldo5", .driver_data = (void *)TPS6586X_ID_LDO_5 },
{ .name = "ldo6", .driver_data = (void *)TPS6586X_ID_LDO_6 },
{ .name = "ldo7", .driver_data = (void *)TPS6586X_ID_LDO_7 },
{ .name = "ldo8", .driver_data = (void *)TPS6586X_ID_LDO_8 },
{ .name = "ldo9", .driver_data = (void *)TPS6586X_ID_LDO_9 },
{ .name = "ldo_rtc", .driver_data = (void *)TPS6586X_ID_LDO_RTC },
};
static struct tps6586x_platform_data *tps6586x_parse_dt(struct i2c_client *client)
{
const unsigned int num = ARRAY_SIZE(tps6586x_matches);
struct device_node *np = client->dev.of_node;
struct tps6586x_platform_data *pdata;
struct tps6586x_subdev_info *devs;
struct device_node *regs;
unsigned int count;
unsigned int i, j;
int err;
regs = of_find_node_by_name(np, "regulators");
if (!regs)
return NULL;
err = of_regulator_match(&client->dev, regs, tps6586x_matches, num);
if (err < 0) {
of_node_put(regs);
return NULL;
}
of_node_put(regs);
count = err;
devs = devm_kzalloc(&client->dev, count * sizeof(*devs), GFP_KERNEL);
if (!devs)
return NULL;
for (i = 0, j = 0; i < num && j < count; i++) {
if (!tps6586x_matches[i].init_data)
continue;
devs[j].name = "tps6586x-regulator";
devs[j].platform_data = tps6586x_matches[i].init_data;
devs[j].id = (int)tps6586x_matches[i].driver_data;
devs[j].of_node = tps6586x_matches[i].of_node;
j++;
}
pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL);
if (!pdata)
return NULL;
pdata->num_subdevs = count;
pdata->subdevs = devs;
pdata->gpio_base = -1;
pdata->irq_base = -1;
return pdata;
}
static struct of_device_id tps6586x_of_match[] = {
{ .compatible = "ti,tps6586x", },
{ },
};
#else
static struct tps6586x_platform_data *tps6586x_parse_dt(struct i2c_client *client)
{
return NULL;
}
#endif
static int __devinit tps6586x_i2c_probe(struct i2c_client *client, static int __devinit tps6586x_i2c_probe(struct i2c_client *client,
const struct i2c_device_id *id) const struct i2c_device_id *id)
{ {
...@@ -481,6 +563,9 @@ static int __devinit tps6586x_i2c_probe(struct i2c_client *client, ...@@ -481,6 +563,9 @@ static int __devinit tps6586x_i2c_probe(struct i2c_client *client,
struct tps6586x *tps6586x; struct tps6586x *tps6586x;
int ret; int ret;
if (!pdata && client->dev.of_node)
pdata = tps6586x_parse_dt(client);
if (!pdata) { if (!pdata) {
dev_err(&client->dev, "tps6586x requires platform data\n"); dev_err(&client->dev, "tps6586x requires platform data\n");
return -ENOTSUPP; return -ENOTSUPP;
...@@ -573,6 +658,7 @@ static struct i2c_driver tps6586x_driver = { ...@@ -573,6 +658,7 @@ static struct i2c_driver tps6586x_driver = {
.driver = { .driver = {
.name = "tps6586x", .name = "tps6586x",
.owner = THIS_MODULE, .owner = THIS_MODULE,
.of_match_table = of_match_ptr(tps6586x_of_match),
}, },
.probe = tps6586x_i2c_probe, .probe = tps6586x_i2c_probe,
.remove = __devexit_p(tps6586x_i2c_remove), .remove = __devexit_p(tps6586x_i2c_remove),
......
...@@ -224,13 +224,6 @@ ...@@ -224,13 +224,6 @@
#define HIGH_PERF_SQ (1 << 3) #define HIGH_PERF_SQ (1 << 3)
#define CK32K_LOWPWR_EN (1 << 7) #define CK32K_LOWPWR_EN (1 << 7)
/* chip-specific feature flags, for i2c_device_id.driver_data */
#define TWL4030_VAUX2 BIT(0) /* pre-5030 voltage ranges */
#define TPS_SUBSET BIT(1) /* tps659[23]0 have fewer LDOs */
#define TWL5031 BIT(2) /* twl5031 has different registers */
#define TWL6030_CLASS BIT(3) /* TWL6030 class */
/*----------------------------------------------------------------------*/ /*----------------------------------------------------------------------*/
/* is driver active, bound to a chip? */ /* is driver active, bound to a chip? */
......
...@@ -27,13 +27,8 @@ struct pm8607_regulator_info { ...@@ -27,13 +27,8 @@ struct pm8607_regulator_info {
unsigned int *vol_table; unsigned int *vol_table;
unsigned int *vol_suspend; unsigned int *vol_suspend;
int vol_reg;
int vol_shift;
int vol_nbits;
int update_reg; int update_reg;
int update_bit; int update_bit;
int enable_reg;
int enable_bit;
int slope_double; int slope_double;
}; };
...@@ -216,7 +211,7 @@ static int pm8607_list_voltage(struct regulator_dev *rdev, unsigned index) ...@@ -216,7 +211,7 @@ static int pm8607_list_voltage(struct regulator_dev *rdev, unsigned index)
struct pm8607_regulator_info *info = rdev_get_drvdata(rdev); struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
int ret = -EINVAL; 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]; ret = info->vol_table[index];
if (info->slope_double) if (info->slope_double)
ret <<= 1; ret <<= 1;
...@@ -224,51 +219,16 @@ static int pm8607_list_voltage(struct regulator_dev *rdev, unsigned index) ...@@ -224,51 +219,16 @@ static int pm8607_list_voltage(struct regulator_dev *rdev, unsigned index)
return ret; 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); struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
int i, ret = -ENOENT; uint8_t val;
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;
int ret; int ret;
if (min_uV > max_uV) { val = (uint8_t)(selector << (ffs(rdev->desc->vsel_mask) - 1));
pr_err("invalid voltage range (%d, %d) uV\n", min_uV, max_uV);
return -EINVAL;
}
ret = choose_voltage(rdev, min_uV, max_uV); ret = pm860x_set_bits(info->i2c, rdev->desc->vsel_reg,
if (ret < 0) rdev->desc->vsel_mask, val);
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);
if (ret) if (ret)
return ret; return ret;
switch (info->desc.id) { switch (info->desc.id) {
...@@ -282,60 +242,16 @@ static int pm8607_set_voltage(struct regulator_dev *rdev, ...@@ -282,60 +242,16 @@ static int pm8607_set_voltage(struct regulator_dev *rdev,
return ret; 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 = { static struct regulator_ops pm8607_regulator_ops = {
.set_voltage = pm8607_set_voltage, .list_voltage = pm8607_list_voltage,
.get_voltage = pm8607_get_voltage, .set_voltage_sel = pm8607_set_voltage_sel,
.enable = pm8607_enable, .get_voltage_sel = regulator_get_voltage_sel_regmap,
.disable = pm8607_disable, .enable = regulator_enable_regmap,
.is_enabled = pm8607_is_enabled, .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 = { \ .desc = { \
.name = #vreg, \ .name = #vreg, \
...@@ -343,20 +259,20 @@ static struct regulator_ops pm8607_regulator_ops = { ...@@ -343,20 +259,20 @@ static struct regulator_ops pm8607_regulator_ops = {
.type = REGULATOR_VOLTAGE, \ .type = REGULATOR_VOLTAGE, \
.id = PM8607_ID_##vreg, \ .id = PM8607_ID_##vreg, \
.owner = THIS_MODULE, \ .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_reg = PM8607_##ureg, \
.update_bit = (ubit), \ .update_bit = (ubit), \
.enable_reg = PM8607_##ereg, \
.enable_bit = (ebit), \
.slope_double = (0), \ .slope_double = (0), \
.vol_table = (unsigned int *)&vreg##_table, \ .vol_table = (unsigned int *)&vreg##_table, \
.vol_suspend = (unsigned int *)&vreg##_suspend_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 = { \ .desc = { \
.name = "LDO" #_id, \ .name = "LDO" #_id, \
...@@ -364,35 +280,35 @@ static struct regulator_ops pm8607_regulator_ops = { ...@@ -364,35 +280,35 @@ static struct regulator_ops pm8607_regulator_ops = {
.type = REGULATOR_VOLTAGE, \ .type = REGULATOR_VOLTAGE, \
.id = PM8607_ID_LDO##_id, \ .id = PM8607_ID_LDO##_id, \
.owner = THIS_MODULE, \ .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), \ .slope_double = (0), \
.vol_table = (unsigned int *)&LDO##_id##_table, \ .vol_table = (unsigned int *)&LDO##_id##_table, \
.vol_suspend = (unsigned int *)&LDO##_id##_suspend_table, \ .vol_suspend = (unsigned int *)&LDO##_id##_suspend_table, \
} }
static struct pm8607_regulator_info pm8607_regulator_info[] = { static struct pm8607_regulator_info pm8607_regulator_info[] = {
PM8607_DVC(BUCK1, 6, GO, 0, SUPPLIES_EN11, 0), PM8607_DVC(BUCK1, GO, 0, SUPPLIES_EN11, 0),
PM8607_DVC(BUCK2, 6, GO, 1, SUPPLIES_EN11, 1), PM8607_DVC(BUCK2, GO, 1, SUPPLIES_EN11, 1),
PM8607_DVC(BUCK3, 6, GO, 2, SUPPLIES_EN11, 2), PM8607_DVC(BUCK3, GO, 2, SUPPLIES_EN11, 2),
PM8607_LDO( 1, LDO1, 0, 2, SUPPLIES_EN11, 3), PM8607_LDO(1, LDO1, 0, SUPPLIES_EN11, 3),
PM8607_LDO( 2, LDO2, 0, 3, SUPPLIES_EN11, 4), PM8607_LDO(2, LDO2, 0, SUPPLIES_EN11, 4),
PM8607_LDO( 3, LDO3, 0, 3, SUPPLIES_EN11, 5), PM8607_LDO(3, LDO3, 0, SUPPLIES_EN11, 5),
PM8607_LDO( 4, LDO4, 0, 3, SUPPLIES_EN11, 6), PM8607_LDO(4, LDO4, 0, SUPPLIES_EN11, 6),
PM8607_LDO( 5, LDO5, 0, 2, SUPPLIES_EN11, 7), PM8607_LDO(5, LDO5, 0, SUPPLIES_EN11, 7),
PM8607_LDO( 6, LDO6, 0, 3, SUPPLIES_EN12, 0), PM8607_LDO(6, LDO6, 0, SUPPLIES_EN12, 0),
PM8607_LDO( 7, LDO7, 0, 3, SUPPLIES_EN12, 1), PM8607_LDO(7, LDO7, 0, SUPPLIES_EN12, 1),
PM8607_LDO( 8, LDO8, 0, 3, SUPPLIES_EN12, 2), PM8607_LDO(8, LDO8, 0, SUPPLIES_EN12, 2),
PM8607_LDO( 9, LDO9, 0, 3, SUPPLIES_EN12, 3), PM8607_LDO(9, LDO9, 0, SUPPLIES_EN12, 3),
PM8607_LDO(10, LDO10, 0, 4, SUPPLIES_EN12, 4), PM8607_LDO(10, LDO10, 0, SUPPLIES_EN12, 4),
PM8607_LDO(12, LDO12, 0, 4, SUPPLIES_EN12, 5), PM8607_LDO(12, LDO12, 0, SUPPLIES_EN12, 5),
PM8607_LDO(13, VIBRATOR_SET, 1, 3, VIBRATOR_SET, 0), PM8607_LDO(13, VIBRATOR_SET, 1, VIBRATOR_SET, 0),
PM8607_LDO(14, LDO14, 0, 3, SUPPLIES_EN12, 6), PM8607_LDO(14, LDO14, 0, SUPPLIES_EN12, 6),
}; };
static int __devinit pm8607_regulator_probe(struct platform_device *pdev) static int __devinit pm8607_regulator_probe(struct platform_device *pdev)
...@@ -400,6 +316,7 @@ 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 pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
struct pm8607_regulator_info *info = NULL; struct pm8607_regulator_info *info = NULL;
struct regulator_init_data *pdata = pdev->dev.platform_data; struct regulator_init_data *pdata = pdev->dev.platform_data;
struct regulator_config config = { };
struct resource *res; struct resource *res;
int i; int i;
...@@ -425,9 +342,17 @@ static int __devinit pm8607_regulator_probe(struct platform_device *pdev) ...@@ -425,9 +342,17 @@ static int __devinit pm8607_regulator_probe(struct platform_device *pdev)
if ((i == PM8607_ID_BUCK3) && info->chip->buck3_double) if ((i == PM8607_ID_BUCK3) && info->chip->buck3_double)
info->slope_double = 1; 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 */ /* replace driver_data with info */
info->regulator = regulator_register(&info->desc, &pdev->dev, info->regulator = regulator_register(&info->desc, &config);
pdata, info, NULL);
if (IS_ERR(info->regulator)) { if (IS_ERR(info->regulator)) {
dev_err(&pdev->dev, "failed to register regulator %s\n", dev_err(&pdev->dev, "failed to register regulator %s\n",
info->desc.name); info->desc.name);
......
...@@ -223,6 +223,16 @@ config REGULATOR_PCF50633 ...@@ -223,6 +223,16 @@ config REGULATOR_PCF50633
Say Y here to support the voltage regulators and convertors Say Y here to support the voltage regulators and convertors
on PCF50633 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 config REGULATOR_S5M8767
tristate "Samsung S5M8767A voltage regulator" tristate "Samsung S5M8767A voltage regulator"
depends on MFD_S5M_CORE depends on MFD_S5M_CORE
...@@ -258,6 +268,18 @@ config REGULATOR_DB8500_PRCMU ...@@ -258,6 +268,18 @@ config REGULATOR_DB8500_PRCMU
This driver supports the voltage domain regulators controlled by the This driver supports the voltage domain regulators controlled by the
DB8500 PRCMU DB8500 PRCMU
config REGULATOR_PALMAS
tristate "TI Palmas PMIC Regulators"
depends on MFD_PALMAS
help
If you wish to control the regulators on the Palmas series of
chips say Y here. This will enable support for all the software
controllable SMPS/LDO regulators.
The regulators available on Palmas series chips vary depending
on the muxing. This is handled automatically in the driver by
reading the mux info from OTP.
config REGULATOR_TPS6105X config REGULATOR_TPS6105X
tristate "TI TPS6105X Power regulators" tristate "TI TPS6105X Power regulators"
depends on TPS6105X depends on TPS6105X
...@@ -268,11 +290,11 @@ config REGULATOR_TPS6105X ...@@ -268,11 +290,11 @@ config REGULATOR_TPS6105X
audio amplifiers. audio amplifiers.
config REGULATOR_TPS62360 config REGULATOR_TPS62360
tristate "TI TPS62360 Power Regulator" tristate "TI TPS6236x Power Regulator"
depends on I2C depends on I2C
select REGMAP_I2C select REGMAP_I2C
help 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 regulator is meant for processor core supply. This chip is
high-frequency synchronous step down dc-dc converter optimized high-frequency synchronous step down dc-dc converter optimized
for battery-powered portable applications. for battery-powered portable applications.
...@@ -294,6 +316,13 @@ config REGULATOR_TPS6507X ...@@ -294,6 +316,13 @@ config REGULATOR_TPS6507X
three step-down converters and two general-purpose LDO voltage regulators. three step-down converters and two general-purpose LDO voltage regulators.
It supports TI's software based Class-2 SmartReflex implementation. 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 config REGULATOR_TPS65217
tristate "TI TPS65217 Power regulators" tristate "TI TPS65217 Power regulators"
depends on MFD_TPS65217 depends on MFD_TPS65217
......
...@@ -9,7 +9,6 @@ obj-$(CONFIG_REGULATOR_FIXED_VOLTAGE) += fixed.o ...@@ -9,7 +9,6 @@ obj-$(CONFIG_REGULATOR_FIXED_VOLTAGE) += fixed.o
obj-$(CONFIG_REGULATOR_VIRTUAL_CONSUMER) += virtual.o obj-$(CONFIG_REGULATOR_VIRTUAL_CONSUMER) += virtual.o
obj-$(CONFIG_REGULATOR_USERSPACE_CONSUMER) += userspace-consumer.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_88PM8607) += 88pm8607.o
obj-$(CONFIG_REGULATOR_AAT2870) += aat2870-regulator.o obj-$(CONFIG_REGULATOR_AAT2870) += aat2870-regulator.o
obj-$(CONFIG_REGULATOR_AB3100) += ab3100.o obj-$(CONFIG_REGULATOR_AB3100) += ab3100.o
...@@ -20,6 +19,7 @@ obj-$(CONFIG_REGULATOR_DA903X) += da903x.o ...@@ -20,6 +19,7 @@ obj-$(CONFIG_REGULATOR_DA903X) += da903x.o
obj-$(CONFIG_REGULATOR_DA9052) += da9052-regulator.o obj-$(CONFIG_REGULATOR_DA9052) += da9052-regulator.o
obj-$(CONFIG_REGULATOR_DBX500_PRCMU) += dbx500-prcmu.o obj-$(CONFIG_REGULATOR_DBX500_PRCMU) += dbx500-prcmu.o
obj-$(CONFIG_REGULATOR_DB8500_PRCMU) += db8500-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_ISL6271A) += isl6271a-regulator.o
obj-$(CONFIG_REGULATOR_LP3971) += lp3971.o obj-$(CONFIG_REGULATOR_LP3971) += lp3971.o
obj-$(CONFIG_REGULATOR_LP3972) += lp3972.o obj-$(CONFIG_REGULATOR_LP3972) += lp3972.o
...@@ -33,13 +33,16 @@ obj-$(CONFIG_REGULATOR_MAX8998) += max8998.o ...@@ -33,13 +33,16 @@ obj-$(CONFIG_REGULATOR_MAX8998) += max8998.o
obj-$(CONFIG_REGULATOR_MC13783) += mc13783-regulator.o obj-$(CONFIG_REGULATOR_MC13783) += mc13783-regulator.o
obj-$(CONFIG_REGULATOR_MC13892) += mc13892-regulator.o obj-$(CONFIG_REGULATOR_MC13892) += mc13892-regulator.o
obj-$(CONFIG_REGULATOR_MC13XXX_CORE) += mc13xxx-regulator-core.o obj-$(CONFIG_REGULATOR_MC13XXX_CORE) += mc13xxx-regulator-core.o
obj-$(CONFIG_REGULATOR_PALMAS) += palmas-regulator.o
obj-$(CONFIG_REGULATOR_PCAP) += pcap-regulator.o obj-$(CONFIG_REGULATOR_PCAP) += pcap-regulator.o
obj-$(CONFIG_REGULATOR_PCF50633) += pcf50633-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_S5M8767) += s5m8767.o
obj-$(CONFIG_REGULATOR_TPS6105X) += tps6105x-regulator.o obj-$(CONFIG_REGULATOR_TPS6105X) += tps6105x-regulator.o
obj-$(CONFIG_REGULATOR_TPS62360) += tps62360-regulator.o obj-$(CONFIG_REGULATOR_TPS62360) += tps62360-regulator.o
obj-$(CONFIG_REGULATOR_TPS65023) += tps65023-regulator.o obj-$(CONFIG_REGULATOR_TPS65023) += tps65023-regulator.o
obj-$(CONFIG_REGULATOR_TPS6507X) += tps6507x-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_TPS65217) += tps65217-regulator.o
obj-$(CONFIG_REGULATOR_TPS6524X) += tps6524x-regulator.o obj-$(CONFIG_REGULATOR_TPS6524X) += tps6524x-regulator.o
obj-$(CONFIG_REGULATOR_TPS6586X) += tps6586x-regulator.o obj-$(CONFIG_REGULATOR_TPS6586X) += tps6586x-regulator.o
......
...@@ -24,7 +24,6 @@ ...@@ -24,7 +24,6 @@
#include <linux/err.h> #include <linux/err.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/delay.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/regulator/driver.h> #include <linux/regulator/driver.h>
#include <linux/regulator/machine.h> #include <linux/regulator/machine.h>
...@@ -178,6 +177,7 @@ static struct aat2870_regulator *aat2870_get_regulator(int id) ...@@ -178,6 +177,7 @@ static struct aat2870_regulator *aat2870_get_regulator(int id)
static int aat2870_regulator_probe(struct platform_device *pdev) static int aat2870_regulator_probe(struct platform_device *pdev)
{ {
struct aat2870_regulator *ri; struct aat2870_regulator *ri;
struct regulator_config config = { 0 };
struct regulator_dev *rdev; struct regulator_dev *rdev;
ri = aat2870_get_regulator(pdev->id); ri = aat2870_get_regulator(pdev->id);
...@@ -187,8 +187,11 @@ static int aat2870_regulator_probe(struct platform_device *pdev) ...@@ -187,8 +187,11 @@ static int aat2870_regulator_probe(struct platform_device *pdev)
} }
ri->aat2870 = dev_get_drvdata(pdev->dev.parent); ri->aat2870 = dev_get_drvdata(pdev->dev.parent);
rdev = regulator_register(&ri->desc, &pdev->dev, config.dev = &pdev->dev;
pdev->dev.platform_data, ri, NULL); config.driver_data = ri;
config.init_data = pdev->dev.platform_data;
rdev = regulator_register(&ri->desc, &config);
if (IS_ERR(rdev)) { if (IS_ERR(rdev)) {
dev_err(&pdev->dev, "Failed to register regulator %s\n", dev_err(&pdev->dev, "Failed to register regulator %s\n",
ri->desc.name); ri->desc.name);
...@@ -231,3 +234,4 @@ module_exit(aat2870_regulator_exit); ...@@ -231,3 +234,4 @@ module_exit(aat2870_regulator_exit);
MODULE_DESCRIPTION("AnalogicTech AAT2870 Regulator"); MODULE_DESCRIPTION("AnalogicTech AAT2870 Regulator");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_AUTHOR("Jin Park <jinyoungp@nvidia.com>"); MODULE_AUTHOR("Jin Park <jinyoungp@nvidia.com>");
MODULE_ALIAS("platform:aat2870-regulator");
...@@ -13,7 +13,6 @@ ...@@ -13,7 +13,6 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/err.h> #include <linux/err.h>
#include <linux/delay.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/regulator/driver.h> #include <linux/regulator/driver.h>
#include <linux/mfd/abx500.h> #include <linux/mfd/abx500.h>
...@@ -305,53 +304,12 @@ static int ab3100_get_voltage_regulator(struct regulator_dev *reg) ...@@ -305,53 +304,12 @@ static int ab3100_get_voltage_regulator(struct regulator_dev *reg)
return abreg->typ_voltages[regval]; return abreg->typ_voltages[regval];
} }
static int ab3100_get_best_voltage_index(struct regulator_dev *reg, static int ab3100_set_voltage_regulator_sel(struct regulator_dev *reg,
int min_uV, int max_uV) unsigned selector)
{
struct ab3100_regulator *abreg = reg->reg_data;
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 < abreg->voltages_len; i++) {
if (abreg->typ_voltages[i] <= max_uV &&
abreg->typ_voltages[i] >= min_uV &&
abreg->typ_voltages[i] < bestmatch) {
bestmatch = abreg->typ_voltages[i];
bestindex = i;
}
}
if (bestindex < 0) {
dev_warn(&reg->dev, "requested %d<=x<=%d uV, out of range!\n",
min_uV, max_uV);
return -EINVAL;
}
return bestindex;
}
static int ab3100_set_voltage_regulator(struct regulator_dev *reg,
int min_uV, int max_uV,
unsigned *selector)
{ {
struct ab3100_regulator *abreg = reg->reg_data; struct ab3100_regulator *abreg = reg->reg_data;
u8 regval; u8 regval;
int err; 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, err = abx500_get_register_interruptible(abreg->dev, 0,
abreg->regreg, &regval); abreg->regreg, &regval);
...@@ -364,7 +322,7 @@ static int ab3100_set_voltage_regulator(struct regulator_dev *reg, ...@@ -364,7 +322,7 @@ static int ab3100_set_voltage_regulator(struct regulator_dev *reg,
/* The highest three bits control the variable regulators */ /* The highest three bits control the variable regulators */
regval &= ~0xE0; regval &= ~0xE0;
regval |= (bestindex << 5); regval |= (selector << 5);
err = abx500_set_register_interruptible(abreg->dev, 0, err = abx500_set_register_interruptible(abreg->dev, 0,
abreg->regreg, regval); abreg->regreg, regval);
...@@ -392,7 +350,7 @@ static int ab3100_set_suspend_voltage_regulator(struct regulator_dev *reg, ...@@ -392,7 +350,7 @@ static int ab3100_set_suspend_voltage_regulator(struct regulator_dev *reg,
return -EINVAL; return -EINVAL;
/* LDO E and BUCK have special suspend voltages you can set */ /* LDO E and BUCK have special suspend voltages you can set */
bestindex = ab3100_get_best_voltage_index(reg, uV, uV); bestindex = regulator_map_voltage_iterate(reg, uV, uV);
err = abx500_get_register_interruptible(abreg->dev, 0, err = abx500_get_register_interruptible(abreg->dev, 0,
targetreg, &regval); targetreg, &regval);
...@@ -464,7 +422,7 @@ static struct regulator_ops regulator_ops_variable = { ...@@ -464,7 +422,7 @@ static struct regulator_ops regulator_ops_variable = {
.disable = ab3100_disable_regulator, .disable = ab3100_disable_regulator,
.is_enabled = ab3100_is_enabled_regulator, .is_enabled = ab3100_is_enabled_regulator,
.get_voltage = ab3100_get_voltage_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, .list_voltage = ab3100_list_voltage_regulator,
.enable_time = ab3100_enable_time_regulator, .enable_time = ab3100_enable_time_regulator,
}; };
...@@ -474,7 +432,7 @@ static struct regulator_ops regulator_ops_variable_sleepable = { ...@@ -474,7 +432,7 @@ static struct regulator_ops regulator_ops_variable_sleepable = {
.disable = ab3100_disable_regulator, .disable = ab3100_disable_regulator,
.is_enabled = ab3100_is_enabled_regulator, .is_enabled = ab3100_is_enabled_regulator,
.get_voltage = ab3100_get_voltage_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, .set_suspend_voltage = ab3100_set_suspend_voltage_regulator,
.list_voltage = ab3100_list_voltage_regulator, .list_voltage = ab3100_list_voltage_regulator,
.enable_time = ab3100_enable_time_regulator, .enable_time = ab3100_enable_time_regulator,
...@@ -582,6 +540,7 @@ ab3100_regulator_desc[AB3100_NUM_REGULATORS] = { ...@@ -582,6 +540,7 @@ ab3100_regulator_desc[AB3100_NUM_REGULATORS] = {
static int __devinit ab3100_regulators_probe(struct platform_device *pdev) static int __devinit ab3100_regulators_probe(struct platform_device *pdev)
{ {
struct ab3100_platform_data *plfdata = pdev->dev.platform_data; struct ab3100_platform_data *plfdata = pdev->dev.platform_data;
struct regulator_config config = { };
int err = 0; int err = 0;
u8 data; u8 data;
int i; int i;
...@@ -627,15 +586,15 @@ static int __devinit ab3100_regulators_probe(struct platform_device *pdev) ...@@ -627,15 +586,15 @@ static int __devinit ab3100_regulators_probe(struct platform_device *pdev)
reg->dev = &pdev->dev; reg->dev = &pdev->dev;
reg->plfdata = plfdata; reg->plfdata = plfdata;
config.dev = &pdev->dev;
config.driver_data = reg;
config.init_data = &plfdata->reg_constraints[i];
/* /*
* Register the regulator, pass around * Register the regulator, pass around
* the ab3100_regulator struct * the ab3100_regulator struct
*/ */
rdev = regulator_register(&ab3100_regulator_desc[i], rdev = regulator_register(&ab3100_regulator_desc[i], &config);
&pdev->dev,
&plfdata->reg_constraints[i],
reg, NULL);
if (IS_ERR(rdev)) { if (IS_ERR(rdev)) {
err = PTR_ERR(rdev); err = PTR_ERR(rdev);
dev_err(&pdev->dev, dev_err(&pdev->dev,
......
...@@ -18,9 +18,12 @@ ...@@ -18,9 +18,12 @@
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/mfd/abx500.h> #include <linux/mfd/abx500.h>
#include <linux/mfd/abx500/ab8500.h> #include <linux/mfd/abx500/ab8500.h>
#include <linux/of.h>
#include <linux/regulator/of_regulator.h>
#include <linux/regulator/driver.h> #include <linux/regulator/driver.h>
#include <linux/regulator/machine.h> #include <linux/regulator/machine.h>
#include <linux/regulator/ab8500.h> #include <linux/regulator/ab8500.h>
#include <linux/slab.h>
/** /**
* struct ab8500_regulator_info - ab8500 regulator information * struct ab8500_regulator_info - ab8500 regulator information
...@@ -234,25 +237,8 @@ static int ab8500_regulator_get_voltage_sel(struct regulator_dev *rdev) ...@@ -234,25 +237,8 @@ static int ab8500_regulator_get_voltage_sel(struct regulator_dev *rdev)
return val; return val;
} }
static int ab8500_get_best_voltage_index(struct regulator_dev *rdev, static int ab8500_regulator_set_voltage_sel(struct regulator_dev *rdev,
int min_uV, int max_uV) unsigned selector)
{
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)
{ {
int ret; int ret;
struct ab8500_regulator_info *info = rdev_get_drvdata(rdev); struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
...@@ -263,18 +249,8 @@ static int ab8500_regulator_set_voltage(struct regulator_dev *rdev, ...@@ -263,18 +249,8 @@ static int ab8500_regulator_set_voltage(struct regulator_dev *rdev,
return -EINVAL; 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 */ /* set the registers for the request */
regval = (u8)ret; regval = (u8)selector;
ret = abx500_mask_and_set_register_interruptible(info->dev, ret = abx500_mask_and_set_register_interruptible(info->dev,
info->voltage_bank, info->voltage_reg, info->voltage_bank, info->voltage_reg,
info->voltage_mask, regval); info->voltage_mask, regval);
...@@ -319,7 +295,7 @@ static struct regulator_ops ab8500_regulator_ops = { ...@@ -319,7 +295,7 @@ static struct regulator_ops ab8500_regulator_ops = {
.disable = ab8500_regulator_disable, .disable = ab8500_regulator_disable,
.is_enabled = ab8500_regulator_is_enabled, .is_enabled = ab8500_regulator_is_enabled,
.get_voltage_sel = ab8500_regulator_get_voltage_sel, .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, .list_voltage = ab8500_list_voltage,
.enable_time = ab8500_regulator_enable_time, .enable_time = ab8500_regulator_enable_time,
.set_voltage_time_sel = ab8500_regulator_set_voltage_time_sel, .set_voltage_time_sel = ab8500_regulator_set_voltage_time_sel,
...@@ -735,12 +711,139 @@ static struct ab8500_reg_init ab8500_reg_init[] = { ...@@ -735,12 +711,139 @@ static struct ab8500_reg_init ab8500_reg_init[] = {
REG_INIT(AB8500_REGUCTRLDISCH2, 0x04, 0x44, 0x16), REG_INIT(AB8500_REGUCTRLDISCH2, 0x04, 0x44, 0x16),
}; };
static __devinit int
ab8500_regulator_init_registers(struct platform_device *pdev, int id, int value)
{
int err;
if (value & ~ab8500_reg_init[id].mask) {
dev_err(&pdev->dev,
"Configuration error: value outside mask.\n");
return -EINVAL;
}
err = abx500_mask_and_set_register_interruptible(
&pdev->dev,
ab8500_reg_init[id].bank,
ab8500_reg_init[id].addr,
ab8500_reg_init[id].mask,
value);
if (err < 0) {
dev_err(&pdev->dev,
"Failed to initialize 0x%02x, 0x%02x.\n",
ab8500_reg_init[id].bank,
ab8500_reg_init[id].addr);
return err;
}
dev_vdbg(&pdev->dev,
"init: 0x%02x, 0x%02x, 0x%02x, 0x%02x\n",
ab8500_reg_init[id].bank,
ab8500_reg_init[id].addr,
ab8500_reg_init[id].mask,
value);
return 0;
}
static __devinit int ab8500_regulator_register(struct platform_device *pdev,
struct regulator_init_data *init_data,
int id,
struct device_node *np)
{
struct ab8500_regulator_info *info = NULL;
struct regulator_config config = { };
int err;
/* assign per-regulator data */
info = &ab8500_regulator_info[id];
info->dev = &pdev->dev;
config.dev = &pdev->dev;
config.init_data = init_data;
config.driver_data = info;
config.of_node = np;
/* fix for hardware before ab8500v2.0 */
if (abx500_get_chip_id(info->dev) < 0x20) {
if (info->desc.id == AB8500_LDO_AUX3) {
info->desc.n_voltages =
ARRAY_SIZE(ldo_vauxn_voltages);
info->voltages = ldo_vauxn_voltages;
info->voltages_len =
ARRAY_SIZE(ldo_vauxn_voltages);
info->voltage_mask = 0xf;
}
}
/* register regulator with framework */
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",
info->desc.name);
/* when we fail, un-register all earlier regulators */
while (--id >= 0) {
info = &ab8500_regulator_info[id];
regulator_unregister(info->regulator);
}
return err;
}
return 0;
}
static struct of_regulator_match ab8500_regulator_matches[] = {
{ .name = "LDO-AUX1", .driver_data = (void *) AB8500_LDO_AUX1, },
{ .name = "LDO-AUX2", .driver_data = (void *) AB8500_LDO_AUX2, },
{ .name = "LDO-AUX3", .driver_data = (void *) AB8500_LDO_AUX3, },
{ .name = "LDO-INTCORE", .driver_data = (void *) AB8500_LDO_INTCORE, },
{ .name = "LDO-TVOUT", .driver_data = (void *) AB8500_LDO_TVOUT, },
{ .name = "LDO-USB", .driver_data = (void *) AB8500_LDO_USB, },
{ .name = "LDO-AUDIO", .driver_data = (void *) AB8500_LDO_AUDIO, },
{ .name = "LDO-ANAMIC1", .driver_data = (void *) AB8500_LDO_ANAMIC1, },
{ .name = "LDO-ANAMIC2", .driver_data = (void *) AB8500_LDO_ANAMIC2, },
{ .name = "LDO-DMIC", .driver_data = (void *) AB8500_LDO_DMIC, },
{ .name = "LDO-ANA", .driver_data = (void *) AB8500_LDO_ANA, },
};
static __devinit int
ab8500_regulator_of_probe(struct platform_device *pdev, struct device_node *np)
{
int err, i;
for (i = 0; i < ARRAY_SIZE(ab8500_regulator_info); i++) {
err = ab8500_regulator_register(
pdev, ab8500_regulator_matches[i].init_data,
i, ab8500_regulator_matches[i].of_node);
if (err)
return err;
}
return 0;
}
static __devinit int ab8500_regulator_probe(struct platform_device *pdev) static __devinit int ab8500_regulator_probe(struct platform_device *pdev)
{ {
struct ab8500 *ab8500 = dev_get_drvdata(pdev->dev.parent); struct ab8500 *ab8500 = dev_get_drvdata(pdev->dev.parent);
struct ab8500_platform_data *pdata; struct ab8500_platform_data *pdata;
struct device_node *np = pdev->dev.of_node;
int i, err; int i, err;
if (np) {
err = of_regulator_match(&pdev->dev, np,
ab8500_regulator_matches,
ARRAY_SIZE(ab8500_regulator_matches));
if (err < 0) {
dev_err(&pdev->dev,
"Error parsing regulator init data: %d\n", err);
return err;
}
err = ab8500_regulator_of_probe(pdev, np);
return err;
}
if (!ab8500) { if (!ab8500) {
dev_err(&pdev->dev, "null mfd parent\n"); dev_err(&pdev->dev, "null mfd parent\n");
return -EINVAL; return -EINVAL;
...@@ -759,8 +862,7 @@ static __devinit int ab8500_regulator_probe(struct platform_device *pdev) ...@@ -759,8 +862,7 @@ static __devinit int ab8500_regulator_probe(struct platform_device *pdev)
/* initialize registers */ /* initialize registers */
for (i = 0; i < pdata->num_regulator_reg_init; i++) { for (i = 0; i < pdata->num_regulator_reg_init; i++) {
int id; int id, value;
u8 value;
id = pdata->regulator_reg_init[i].id; id = pdata->regulator_reg_init[i].id;
value = pdata->regulator_reg_init[i].value; value = pdata->regulator_reg_init[i].value;
...@@ -771,70 +873,17 @@ static __devinit int ab8500_regulator_probe(struct platform_device *pdev) ...@@ -771,70 +873,17 @@ static __devinit int ab8500_regulator_probe(struct platform_device *pdev)
"Configuration error: id outside range.\n"); "Configuration error: id outside range.\n");
return -EINVAL; return -EINVAL;
} }
if (value & ~ab8500_reg_init[id].mask) {
dev_err(&pdev->dev,
"Configuration error: value outside mask.\n");
return -EINVAL;
}
/* initialize register */ err = ab8500_regulator_init_registers(pdev, id, value);
err = abx500_mask_and_set_register_interruptible(&pdev->dev, if (err < 0)
ab8500_reg_init[id].bank,
ab8500_reg_init[id].addr,
ab8500_reg_init[id].mask,
value);
if (err < 0) {
dev_err(&pdev->dev,
"Failed to initialize 0x%02x, 0x%02x.\n",
ab8500_reg_init[id].bank,
ab8500_reg_init[id].addr);
return err; return err;
}
dev_vdbg(&pdev->dev,
" init: 0x%02x, 0x%02x, 0x%02x, 0x%02x\n",
ab8500_reg_init[id].bank,
ab8500_reg_init[id].addr,
ab8500_reg_init[id].mask,
value);
} }
/* register all regulators */ /* register all regulators */
for (i = 0; i < ARRAY_SIZE(ab8500_regulator_info); i++) { for (i = 0; i < ARRAY_SIZE(ab8500_regulator_info); i++) {
struct ab8500_regulator_info *info = NULL; err = ab8500_regulator_register(pdev, &pdata->regulator[i], i, NULL);
if (err < 0)
/* assign per-regulator data */
info = &ab8500_regulator_info[i];
info->dev = &pdev->dev;
/* fix for hardware before ab8500v2.0 */
if (abx500_get_chip_id(info->dev) < 0x20) {
if (info->desc.id == AB8500_LDO_AUX3) {
info->desc.n_voltages =
ARRAY_SIZE(ldo_vauxn_voltages);
info->voltages = ldo_vauxn_voltages;
info->voltages_len =
ARRAY_SIZE(ldo_vauxn_voltages);
info->voltage_mask = 0xf;
}
}
/* register regulator with framework */
info->regulator = regulator_register(&info->desc, &pdev->dev,
&pdata->regulator[i], info, NULL);
if (IS_ERR(info->regulator)) {
err = PTR_ERR(info->regulator);
dev_err(&pdev->dev, "failed to register regulator %s\n",
info->desc.name);
/* when we fail, un-register all earlier regulators */
while (--i >= 0) {
info = &ab8500_regulator_info[i];
regulator_unregister(info->regulator);
}
return err; return err;
}
dev_vdbg(rdev_get_dev(info->regulator),
"%s-probed\n", info->desc.name);
} }
return 0; return 0;
...@@ -857,12 +906,18 @@ static __devexit int ab8500_regulator_remove(struct platform_device *pdev) ...@@ -857,12 +906,18 @@ static __devexit int ab8500_regulator_remove(struct platform_device *pdev)
return 0; return 0;
} }
static const struct of_device_id ab8500_regulator_match[] = {
{ .compatible = "stericsson,ab8500-regulator", },
{}
};
static struct platform_driver ab8500_regulator_driver = { static struct platform_driver ab8500_regulator_driver = {
.probe = ab8500_regulator_probe, .probe = ab8500_regulator_probe,
.remove = __devexit_p(ab8500_regulator_remove), .remove = __devexit_p(ab8500_regulator_remove),
.driver = { .driver = {
.name = "ab8500-regulator", .name = "ab8500-regulator",
.owner = THIS_MODULE, .owner = THIS_MODULE,
.of_match_table = ab8500_regulator_match,
}, },
}; };
......
...@@ -99,8 +99,8 @@ static int ad5398_set_current_limit(struct regulator_dev *rdev, int min_uA, int ...@@ -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) if (ad5398_calc_current(chip, selector) > max_uA)
return -EINVAL; return -EINVAL;
dev_dbg(&client->dev, "changing current %dmA\n", dev_dbg(&client->dev, "changing current %duA\n",
ad5398_calc_current(chip, selector) / 1000); ad5398_calc_current(chip, selector));
/* read chip enable bit */ /* read chip enable bit */
ret = ad5398_read_reg(client, &data); ret = ad5398_read_reg(client, &data);
...@@ -184,7 +184,7 @@ static struct regulator_ops ad5398_ops = { ...@@ -184,7 +184,7 @@ static struct regulator_ops ad5398_ops = {
.is_enabled = ad5398_is_enabled, .is_enabled = ad5398_is_enabled,
}; };
static struct regulator_desc ad5398_reg = { static const struct regulator_desc ad5398_reg = {
.name = "isink", .name = "isink",
.id = 0, .id = 0,
.ops = &ad5398_ops, .ops = &ad5398_ops,
...@@ -212,6 +212,7 @@ static int __devinit ad5398_probe(struct i2c_client *client, ...@@ -212,6 +212,7 @@ static int __devinit ad5398_probe(struct i2c_client *client,
const struct i2c_device_id *id) const struct i2c_device_id *id)
{ {
struct regulator_init_data *init_data = client->dev.platform_data; struct regulator_init_data *init_data = client->dev.platform_data;
struct regulator_config config = { };
struct ad5398_chip_info *chip; struct ad5398_chip_info *chip;
const struct ad5398_current_data_format *df = const struct ad5398_current_data_format *df =
(struct ad5398_current_data_format *)id->driver_data; (struct ad5398_current_data_format *)id->driver_data;
...@@ -220,10 +221,14 @@ static int __devinit ad5398_probe(struct i2c_client *client, ...@@ -220,10 +221,14 @@ static int __devinit ad5398_probe(struct i2c_client *client,
if (!init_data) if (!init_data)
return -EINVAL; return -EINVAL;
chip = kzalloc(sizeof(*chip), GFP_KERNEL); chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL);
if (!chip) if (!chip)
return -ENOMEM; return -ENOMEM;
config.dev = &client->dev;
config.init_data = init_data;
config.driver_data = chip;
chip->client = client; chip->client = client;
chip->min_uA = df->min_uA; chip->min_uA = df->min_uA;
...@@ -232,8 +237,7 @@ static int __devinit ad5398_probe(struct i2c_client *client, ...@@ -232,8 +237,7 @@ static int __devinit ad5398_probe(struct i2c_client *client,
chip->current_offset = df->current_offset; chip->current_offset = df->current_offset;
chip->current_mask = (chip->current_level - 1) << chip->current_offset; chip->current_mask = (chip->current_level - 1) << chip->current_offset;
chip->rdev = regulator_register(&ad5398_reg, &client->dev, chip->rdev = regulator_register(&ad5398_reg, &config);
init_data, chip, NULL);
if (IS_ERR(chip->rdev)) { if (IS_ERR(chip->rdev)) {
ret = PTR_ERR(chip->rdev); ret = PTR_ERR(chip->rdev);
dev_err(&client->dev, "failed to register %s %s\n", dev_err(&client->dev, "failed to register %s %s\n",
...@@ -246,7 +250,6 @@ static int __devinit ad5398_probe(struct i2c_client *client, ...@@ -246,7 +250,6 @@ static int __devinit ad5398_probe(struct i2c_client *client,
return 0; return 0;
err: err:
kfree(chip);
return ret; return ret;
} }
...@@ -255,8 +258,6 @@ static int __devexit ad5398_remove(struct i2c_client *client) ...@@ -255,8 +258,6 @@ static int __devexit ad5398_remove(struct i2c_client *client)
struct ad5398_chip_info *chip = i2c_get_clientdata(client); struct ad5398_chip_info *chip = i2c_get_clientdata(client);
regulator_unregister(chip->rdev); regulator_unregister(chip->rdev);
kfree(chip);
return 0; return 0;
} }
......
...@@ -122,6 +122,7 @@ static int __devinit anatop_regulator_probe(struct platform_device *pdev) ...@@ -122,6 +122,7 @@ static int __devinit anatop_regulator_probe(struct platform_device *pdev)
struct anatop_regulator *sreg; struct anatop_regulator *sreg;
struct regulator_init_data *initdata; struct regulator_init_data *initdata;
struct anatop *anatopmfd = dev_get_drvdata(pdev->dev.parent); struct anatop *anatopmfd = dev_get_drvdata(pdev->dev.parent);
struct regulator_config config = { };
int ret = 0; int ret = 0;
initdata = of_get_regulator_init_data(dev, np); initdata = of_get_regulator_init_data(dev, np);
...@@ -178,9 +179,13 @@ static int __devinit anatop_regulator_probe(struct platform_device *pdev) ...@@ -178,9 +179,13 @@ static int __devinit anatop_regulator_probe(struct platform_device *pdev)
rdesc->n_voltages = (sreg->max_voltage - sreg->min_voltage) rdesc->n_voltages = (sreg->max_voltage - sreg->min_voltage)
/ 25000 + 1; / 25000 + 1;
config.dev = &pdev->dev;
config.init_data = initdata;
config.driver_data = sreg;
config.of_node = pdev->dev.of_node;
/* register regulator */ /* register regulator */
rdev = regulator_register(rdesc, dev, rdev = regulator_register(rdesc, &config);
initdata, sreg, pdev->dev.of_node);
if (IS_ERR(rdev)) { if (IS_ERR(rdev)) {
dev_err(dev, "failed to register %s\n", dev_err(dev, "failed to register %s\n",
rdesc->name); rdesc->name);
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -17,6 +17,8 @@ ...@@ -17,6 +17,8 @@
#include <linux/regulator/driver.h> #include <linux/regulator/driver.h>
#include <linux/regulator/machine.h> #include <linux/regulator/machine.h>
#include <linux/regulator/db8500-prcmu.h> #include <linux/regulator/db8500-prcmu.h>
#include <linux/regulator/of_regulator.h>
#include <linux/of.h>
#include <linux/module.h> #include <linux/module.h>
#include "dbx500-prcmu.h" #include "dbx500-prcmu.h"
...@@ -410,45 +412,120 @@ dbx500_regulator_info[DB8500_NUM_REGULATORS] = { ...@@ -410,45 +412,120 @@ dbx500_regulator_info[DB8500_NUM_REGULATORS] = {
}, },
}; };
static __devinit int db8500_regulator_register(struct platform_device *pdev,
struct regulator_init_data *init_data,
int id,
struct device_node *np)
{
struct dbx500_regulator_info *info;
struct regulator_config config = { };
int err;
/* assign per-regulator data */
info = &dbx500_regulator_info[id];
info->dev = &pdev->dev;
config.dev = &pdev->dev;
config.init_data = init_data;
config.driver_data = info;
config.of_node = np;
/* register with the regulator framework */
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",
info->desc.name, err);
/* if failing, unregister all earlier regulators */
while (--id >= 0) {
info = &dbx500_regulator_info[id];
regulator_unregister(info->rdev);
}
return err;
}
dev_dbg(rdev_get_dev(info->rdev),
"regulator-%s-probed\n", info->desc.name);
return 0;
}
static struct of_regulator_match db8500_regulator_matches[] = {
{ .name = "db8500-vape", .driver_data = (void *) DB8500_REGULATOR_VAPE, },
{ .name = "db8500-varm", .driver_data = (void *) DB8500_REGULATOR_VARM, },
{ .name = "db8500-vmodem", .driver_data = (void *) DB8500_REGULATOR_VMODEM, },
{ .name = "db8500-vpll", .driver_data = (void *) DB8500_REGULATOR_VPLL, },
{ .name = "db8500-vsmps1", .driver_data = (void *) DB8500_REGULATOR_VSMPS1, },
{ .name = "db8500-vsmps2", .driver_data = (void *) DB8500_REGULATOR_VSMPS2, },
{ .name = "db8500-vsmps3", .driver_data = (void *) DB8500_REGULATOR_VSMPS3, },
{ .name = "db8500-vrf1", .driver_data = (void *) DB8500_REGULATOR_VRF1, },
{ .name = "db8500-sva-mmdsp", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SVAMMDSP, },
{ .name = "db8500-sva-mmdsp-ret", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SVAMMDSPRET, },
{ .name = "db8500-sva-pipe", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SVAPIPE, },
{ .name = "db8500-sia-mmdsp", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SIAMMDSP, },
{ .name = "db8500-sia-mmdsp-ret", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SIAMMDSPRET, },
{ .name = "db8500-sia-pipe", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SIAPIPE, },
{ .name = "db8500-sga", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SGA, },
{ .name = "db8500-b2r2-mcde", .driver_data = (void *) DB8500_REGULATOR_SWITCH_B2R2_MCDE, },
{ .name = "db8500-esram12", .driver_data = (void *) DB8500_REGULATOR_SWITCH_ESRAM12, },
{ .name = "db8500-esram12-ret", .driver_data = (void *) DB8500_REGULATOR_SWITCH_ESRAM12RET, },
{ .name = "db8500-esram34", .driver_data = (void *) DB8500_REGULATOR_SWITCH_ESRAM34, },
{ .name = "db8500-esram34-ret", .driver_data = (void *) DB8500_REGULATOR_SWITCH_ESRAM34RET, },
};
static __devinit int
db8500_regulator_of_probe(struct platform_device *pdev,
struct device_node *np)
{
int i, err;
for (i = 0; i < ARRAY_SIZE(dbx500_regulator_info); i++) {
err = db8500_regulator_register(
pdev, db8500_regulator_matches[i].init_data,
i, db8500_regulator_matches[i].of_node);
if (err)
return err;
}
return 0;
}
static int __devinit db8500_regulator_probe(struct platform_device *pdev) static int __devinit db8500_regulator_probe(struct platform_device *pdev)
{ {
struct regulator_init_data *db8500_init_data = struct regulator_init_data *db8500_init_data =
dev_get_platdata(&pdev->dev); dev_get_platdata(&pdev->dev);
struct device_node *np = pdev->dev.of_node;
int i, err; int i, err;
/* register all regulators */ /* register all regulators */
for (i = 0; i < ARRAY_SIZE(dbx500_regulator_info); i++) { if (np) {
struct dbx500_regulator_info *info; err = of_regulator_match(&pdev->dev, np,
struct regulator_init_data *init_data = &db8500_init_data[i]; db8500_regulator_matches,
ARRAY_SIZE(db8500_regulator_matches));
/* assign per-regulator data */ if (err < 0) {
info = &dbx500_regulator_info[i]; dev_err(&pdev->dev,
info->dev = &pdev->dev; "Error parsing regulator init data: %d\n", err);
/* register with the regulator framework */
info->rdev = regulator_register(&info->desc, &pdev->dev,
init_data, info, NULL);
if (IS_ERR(info->rdev)) {
err = PTR_ERR(info->rdev);
dev_err(&pdev->dev, "failed to register %s: err %i\n",
info->desc.name, err);
/* if failing, unregister all earlier regulators */
while (--i >= 0) {
info = &dbx500_regulator_info[i];
regulator_unregister(info->rdev);
}
return err; return err;
} }
dev_dbg(rdev_get_dev(info->rdev), err = db8500_regulator_of_probe(pdev, np);
"regulator-%s-probed\n", info->desc.name); if (err)
return err;
} else {
for (i = 0; i < ARRAY_SIZE(dbx500_regulator_info); i++) {
err = db8500_regulator_register(pdev,
&db8500_init_data[i],
i, NULL);
if (err)
return err;
}
} }
err = ux500_regulator_debug_init(pdev, err = ux500_regulator_debug_init(pdev,
dbx500_regulator_info, dbx500_regulator_info,
ARRAY_SIZE(dbx500_regulator_info)); ARRAY_SIZE(dbx500_regulator_info));
return 0;
return err;
} }
static int __exit db8500_regulator_remove(struct platform_device *pdev) static int __exit db8500_regulator_remove(struct platform_device *pdev)
...@@ -470,10 +547,16 @@ static int __exit db8500_regulator_remove(struct platform_device *pdev) ...@@ -470,10 +547,16 @@ static int __exit db8500_regulator_remove(struct platform_device *pdev)
return 0; return 0;
} }
static const struct of_device_id db8500_prcmu_regulator_match[] = {
{ .compatible = "stericsson,db8500-prcmu-regulator", },
{}
};
static struct platform_driver db8500_regulator_driver = { static struct platform_driver db8500_regulator_driver = {
.driver = { .driver = {
.name = "db8500-prcmu-regulators", .name = "db8500-prcmu-regulators",
.owner = THIS_MODULE, .owner = THIS_MODULE,
.of_match_table = db8500_prcmu_regulator_match,
}, },
.probe = db8500_regulator_probe, .probe = db8500_regulator_probe,
.remove = __exit_p(db8500_regulator_remove), .remove = __exit_p(db8500_regulator_remove),
......
...@@ -39,10 +39,13 @@ static struct regulator_desc dummy_desc = { ...@@ -39,10 +39,13 @@ static struct regulator_desc dummy_desc = {
static int __devinit dummy_regulator_probe(struct platform_device *pdev) static int __devinit dummy_regulator_probe(struct platform_device *pdev)
{ {
struct regulator_config config = { };
int ret; int ret;
dummy_regulator_rdev = regulator_register(&dummy_desc, NULL, config.dev = &pdev->dev;
&dummy_initdata, NULL, NULL); config.init_data = &dummy_initdata;
dummy_regulator_rdev = regulator_register(&dummy_desc, &config);
if (IS_ERR(dummy_regulator_rdev)) { if (IS_ERR(dummy_regulator_rdev)) {
ret = PTR_ERR(dummy_regulator_rdev); ret = PTR_ERR(dummy_regulator_rdev);
pr_err("Failed to register regulator: %d\n", ret); pr_err("Failed to register regulator: %d\n", ret);
......
...@@ -25,7 +25,6 @@ ...@@ -25,7 +25,6 @@
#include <linux/regulator/driver.h> #include <linux/regulator/driver.h>
#include <linux/regulator/fixed.h> #include <linux/regulator/fixed.h>
#include <linux/gpio.h> #include <linux/gpio.h>
#include <linux/delay.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_gpio.h> #include <linux/of_gpio.h>
...@@ -91,6 +90,9 @@ of_get_fixed_voltage_config(struct device *dev) ...@@ -91,6 +90,9 @@ of_get_fixed_voltage_config(struct device *dev)
if (of_find_property(np, "enable-active-high", NULL)) if (of_find_property(np, "enable-active-high", NULL))
config->enable_high = true; config->enable_high = true;
if (of_find_property(np, "gpio-open-drain", NULL))
config->gpio_is_open_drain = true;
return config; return config;
} }
...@@ -105,10 +107,8 @@ static int fixed_voltage_enable(struct regulator_dev *dev) ...@@ -105,10 +107,8 @@ static int fixed_voltage_enable(struct regulator_dev *dev)
{ {
struct fixed_voltage_data *data = rdev_get_drvdata(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);
gpio_set_value_cansleep(data->gpio, data->enable_high); data->is_enabled = true;
data->is_enabled = true;
}
return 0; return 0;
} }
...@@ -117,10 +117,8 @@ static int fixed_voltage_disable(struct regulator_dev *dev) ...@@ -117,10 +117,8 @@ static int fixed_voltage_disable(struct regulator_dev *dev)
{ {
struct fixed_voltage_data *data = rdev_get_drvdata(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);
gpio_set_value_cansleep(data->gpio, !data->enable_high); data->is_enabled = false;
data->is_enabled = false;
}
return 0; return 0;
} }
...@@ -153,7 +151,7 @@ static int fixed_voltage_list_voltage(struct regulator_dev *dev, ...@@ -153,7 +151,7 @@ static int fixed_voltage_list_voltage(struct regulator_dev *dev,
return data->microvolts; return data->microvolts;
} }
static struct regulator_ops fixed_voltage_ops = { static struct regulator_ops fixed_voltage_gpio_ops = {
.is_enabled = fixed_voltage_is_enabled, .is_enabled = fixed_voltage_is_enabled,
.enable = fixed_voltage_enable, .enable = fixed_voltage_enable,
.disable = fixed_voltage_disable, .disable = fixed_voltage_disable,
...@@ -162,10 +160,16 @@ static struct regulator_ops fixed_voltage_ops = { ...@@ -162,10 +160,16 @@ static struct regulator_ops fixed_voltage_ops = {
.list_voltage = fixed_voltage_list_voltage, .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) static int __devinit reg_fixed_voltage_probe(struct platform_device *pdev)
{ {
struct fixed_voltage_config *config; struct fixed_voltage_config *config;
struct fixed_voltage_data *drvdata; struct fixed_voltage_data *drvdata;
struct regulator_config cfg = { };
int ret; int ret;
if (pdev->dev.of_node) if (pdev->dev.of_node)
...@@ -176,7 +180,8 @@ static int __devinit reg_fixed_voltage_probe(struct platform_device *pdev) ...@@ -176,7 +180,8 @@ static int __devinit reg_fixed_voltage_probe(struct platform_device *pdev)
if (!config) if (!config)
return -ENOMEM; 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) { if (drvdata == NULL) {
dev_err(&pdev->dev, "Failed to allocate device data\n"); dev_err(&pdev->dev, "Failed to allocate device data\n");
ret = -ENOMEM; ret = -ENOMEM;
...@@ -191,7 +196,6 @@ static int __devinit reg_fixed_voltage_probe(struct platform_device *pdev) ...@@ -191,7 +196,6 @@ static int __devinit reg_fixed_voltage_probe(struct platform_device *pdev)
} }
drvdata->desc.type = REGULATOR_VOLTAGE; drvdata->desc.type = REGULATOR_VOLTAGE;
drvdata->desc.owner = THIS_MODULE; drvdata->desc.owner = THIS_MODULE;
drvdata->desc.ops = &fixed_voltage_ops;
if (config->microvolts) if (config->microvolts)
drvdata->desc.n_voltages = 1; drvdata->desc.n_voltages = 1;
...@@ -201,6 +205,7 @@ static int __devinit reg_fixed_voltage_probe(struct platform_device *pdev) ...@@ -201,6 +205,7 @@ static int __devinit reg_fixed_voltage_probe(struct platform_device *pdev)
drvdata->startup_delay = config->startup_delay; drvdata->startup_delay = config->startup_delay;
if (gpio_is_valid(config->gpio)) { if (gpio_is_valid(config->gpio)) {
int gpio_flag;
drvdata->enable_high = config->enable_high; drvdata->enable_high = config->enable_high;
/* FIXME: Remove below print warning /* FIXME: Remove below print warning
...@@ -218,39 +223,39 @@ static int __devinit reg_fixed_voltage_probe(struct platform_device *pdev) ...@@ -218,39 +223,39 @@ static int __devinit reg_fixed_voltage_probe(struct platform_device *pdev)
dev_warn(&pdev->dev, dev_warn(&pdev->dev,
"using GPIO 0 for regulator enable control\n"); "using GPIO 0 for regulator enable control\n");
ret = gpio_request(config->gpio, config->supply_name); /*
if (ret) { * set output direction without changing state
dev_err(&pdev->dev,
"Could not obtain regulator enable GPIO %d: %d\n",
config->gpio, ret);
goto err_name;
}
/* set output direction without changing state
* to prevent glitch * to prevent glitch
*/ */
drvdata->is_enabled = config->enabled_at_boot; drvdata->is_enabled = config->enabled_at_boot;
ret = drvdata->is_enabled ? ret = drvdata->is_enabled ?
config->enable_high : !config->enable_high; 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_direction_output(config->gpio, ret); ret = gpio_request_one(config->gpio, gpio_flag,
config->supply_name);
if (ret) { if (ret) {
dev_err(&pdev->dev, dev_err(&pdev->dev,
"Could not configure regulator enable GPIO %d direction: %d\n", "Could not obtain regulator enable GPIO %d: %d\n",
config->gpio, ret); config->gpio, ret);
goto err_gpio; goto err_name;
} }
drvdata->desc.ops = &fixed_voltage_gpio_ops;
} else { } else {
/* Regulator without GPIO control is considered drvdata->desc.ops = &fixed_voltage_ops;
* always enabled
*/
drvdata->is_enabled = true;
} }
drvdata->dev = regulator_register(&drvdata->desc, &pdev->dev, cfg.dev = &pdev->dev;
config->init_data, drvdata, cfg.init_data = config->init_data;
pdev->dev.of_node); cfg.driver_data = drvdata;
cfg.of_node = pdev->dev.of_node;
drvdata->dev = regulator_register(&drvdata->desc, &cfg);
if (IS_ERR(drvdata->dev)) { if (IS_ERR(drvdata->dev)) {
ret = PTR_ERR(drvdata->dev); ret = PTR_ERR(drvdata->dev);
dev_err(&pdev->dev, "Failed to register regulator: %d\n", ret); dev_err(&pdev->dev, "Failed to register regulator: %d\n", ret);
...@@ -270,7 +275,6 @@ static int __devinit reg_fixed_voltage_probe(struct platform_device *pdev) ...@@ -270,7 +275,6 @@ static int __devinit reg_fixed_voltage_probe(struct platform_device *pdev)
err_name: err_name:
kfree(drvdata->desc.name); kfree(drvdata->desc.name);
err: err:
kfree(drvdata);
return ret; return ret;
} }
...@@ -282,7 +286,6 @@ static int __devexit reg_fixed_voltage_remove(struct platform_device *pdev) ...@@ -282,7 +286,6 @@ static int __devexit reg_fixed_voltage_remove(struct platform_device *pdev)
if (gpio_is_valid(drvdata->gpio)) if (gpio_is_valid(drvdata->gpio))
gpio_free(drvdata->gpio); gpio_free(drvdata->gpio);
kfree(drvdata->desc.name); kfree(drvdata->desc.name);
kfree(drvdata);
return 0; return 0;
} }
......
...@@ -30,7 +30,6 @@ ...@@ -30,7 +30,6 @@
#include <linux/regulator/machine.h> #include <linux/regulator/machine.h>
#include <linux/regulator/gpio-regulator.h> #include <linux/regulator/gpio-regulator.h>
#include <linux/gpio.h> #include <linux/gpio.h>
#include <linux/delay.h>
#include <linux/slab.h> #include <linux/slab.h>
struct gpio_regulator_data { struct gpio_regulator_data {
...@@ -105,15 +104,15 @@ static int gpio_regulator_set_value(struct regulator_dev *dev, ...@@ -105,15 +104,15 @@ static int gpio_regulator_set_value(struct regulator_dev *dev,
int min, int max) int min, int max)
{ {
struct gpio_regulator_data *data = rdev_get_drvdata(dev); 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++) 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) data->states[ptr].value <= max)
target = data->states[ptr].gpios; target = data->states[ptr].gpios;
if (target < 0) if (best_val == INT_MAX)
return -EINVAL; return -EINVAL;
for (ptr = 0; ptr < data->nr_gpios; ptr++) { for (ptr = 0; ptr < data->nr_gpios; ptr++) {
...@@ -172,9 +171,11 @@ static int __devinit gpio_regulator_probe(struct platform_device *pdev) ...@@ -172,9 +171,11 @@ static int __devinit gpio_regulator_probe(struct platform_device *pdev)
{ {
struct gpio_regulator_config *config = pdev->dev.platform_data; struct gpio_regulator_config *config = pdev->dev.platform_data;
struct gpio_regulator_data *drvdata; struct gpio_regulator_data *drvdata;
struct regulator_config cfg = { };
int ptr, ret, state; 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) { if (drvdata == NULL) {
dev_err(&pdev->dev, "Failed to allocate device data\n"); dev_err(&pdev->dev, "Failed to allocate device data\n");
return -ENOMEM; return -ENOMEM;
...@@ -283,8 +284,11 @@ static int __devinit gpio_regulator_probe(struct platform_device *pdev) ...@@ -283,8 +284,11 @@ static int __devinit gpio_regulator_probe(struct platform_device *pdev)
} }
drvdata->state = state; drvdata->state = state;
drvdata->dev = regulator_register(&drvdata->desc, &pdev->dev, cfg.dev = &pdev->dev;
config->init_data, drvdata, NULL); cfg.init_data = config->init_data;
cfg.driver_data = &drvdata;
drvdata->dev = regulator_register(&drvdata->desc, &cfg);
if (IS_ERR(drvdata->dev)) { if (IS_ERR(drvdata->dev)) {
ret = PTR_ERR(drvdata->dev); ret = PTR_ERR(drvdata->dev);
dev_err(&pdev->dev, "Failed to register regulator: %d\n", ret); dev_err(&pdev->dev, "Failed to register regulator: %d\n", ret);
...@@ -307,7 +311,6 @@ static int __devinit gpio_regulator_probe(struct platform_device *pdev) ...@@ -307,7 +311,6 @@ static int __devinit gpio_regulator_probe(struct platform_device *pdev)
err_name: err_name:
kfree(drvdata->desc.name); kfree(drvdata->desc.name);
err: err:
kfree(drvdata);
return ret; return ret;
} }
...@@ -326,7 +329,6 @@ static int __devexit gpio_regulator_remove(struct platform_device *pdev) ...@@ -326,7 +329,6 @@ static int __devexit gpio_regulator_remove(struct platform_device *pdev)
gpio_free(drvdata->enable_gpio); gpio_free(drvdata->enable_gpio);
kfree(drvdata->desc.name); kfree(drvdata->desc.name);
kfree(drvdata);
return 0; return 0;
} }
......
...@@ -22,7 +22,6 @@ ...@@ -22,7 +22,6 @@
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/regulator/driver.h> #include <linux/regulator/driver.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/delay.h>
#include <linux/slab.h> #include <linux/slab.h>
#define ISL6271A_VOLTAGE_MIN 850000 #define ISL6271A_VOLTAGE_MIN 850000
...@@ -36,47 +35,30 @@ struct isl_pmic { ...@@ -36,47 +35,30 @@ struct isl_pmic {
struct mutex mtx; struct mutex mtx;
}; };
static int isl6271a_get_voltage(struct regulator_dev *dev) static int isl6271a_get_voltage_sel(struct regulator_dev *dev)
{ {
struct isl_pmic *pmic = rdev_get_drvdata(dev); struct isl_pmic *pmic = rdev_get_drvdata(dev);
int idx, data; int idx;
mutex_lock(&pmic->mtx); mutex_lock(&pmic->mtx);
idx = i2c_smbus_read_byte(pmic->client); idx = i2c_smbus_read_byte(pmic->client);
if (idx < 0) { if (idx < 0)
dev_err(&pmic->client->dev, "Error getting voltage\n"); dev_err(&pmic->client->dev, "Error getting voltage\n");
data = idx;
goto out;
}
/* Convert the data from chip to microvolts */
data = ISL6271A_VOLTAGE_MIN + (ISL6271A_VOLTAGE_STEP * (idx & 0xf));
out:
mutex_unlock(&pmic->mtx); mutex_unlock(&pmic->mtx);
return data; return idx;
} }
static int isl6271a_set_voltage(struct regulator_dev *dev, static int isl6271a_set_voltage_sel(struct regulator_dev *dev,
int minuV, int maxuV, unsigned selector)
unsigned *selector)
{ {
struct isl_pmic *pmic = rdev_get_drvdata(dev); struct isl_pmic *pmic = rdev_get_drvdata(dev);
int err, data; int err;
if (minuV < ISL6271A_VOLTAGE_MIN || minuV > ISL6271A_VOLTAGE_MAX)
return -EINVAL;
if (maxuV < ISL6271A_VOLTAGE_MIN || maxuV > ISL6271A_VOLTAGE_MAX)
return -EINVAL;
data = DIV_ROUND_UP(minuV - ISL6271A_VOLTAGE_MIN,
ISL6271A_VOLTAGE_STEP);
*selector = data;
mutex_lock(&pmic->mtx); mutex_lock(&pmic->mtx);
err = i2c_smbus_write_byte(pmic->client, data); err = i2c_smbus_write_byte(pmic->client, selector);
if (err < 0) if (err < 0)
dev_err(&pmic->client->dev, "Error setting voltage\n"); dev_err(&pmic->client->dev, "Error setting voltage\n");
...@@ -84,15 +66,11 @@ static int isl6271a_set_voltage(struct regulator_dev *dev, ...@@ -84,15 +66,11 @@ static int isl6271a_set_voltage(struct regulator_dev *dev,
return err; return err;
} }
static int isl6271a_list_voltage(struct regulator_dev *dev, unsigned selector)
{
return ISL6271A_VOLTAGE_MIN + (ISL6271A_VOLTAGE_STEP * selector);
}
static struct regulator_ops isl_core_ops = { static struct regulator_ops isl_core_ops = {
.get_voltage = isl6271a_get_voltage, .get_voltage_sel = isl6271a_get_voltage_sel,
.set_voltage = isl6271a_set_voltage, .set_voltage_sel = isl6271a_set_voltage_sel,
.list_voltage = isl6271a_list_voltage, .list_voltage = regulator_list_voltage_linear,
.map_voltage = regulator_map_voltage_linear,
}; };
static int isl6271a_get_fixed_voltage(struct regulator_dev *dev) static int isl6271a_get_fixed_voltage(struct regulator_dev *dev)
...@@ -112,7 +90,7 @@ static struct regulator_ops isl_fixed_ops = { ...@@ -112,7 +90,7 @@ static struct regulator_ops isl_fixed_ops = {
.list_voltage = isl6271a_list_fixed_voltage, .list_voltage = isl6271a_list_fixed_voltage,
}; };
static struct regulator_desc isl_rd[] = { static const struct regulator_desc isl_rd[] = {
{ {
.name = "Core Buck", .name = "Core Buck",
.id = 0, .id = 0,
...@@ -120,6 +98,8 @@ static struct regulator_desc isl_rd[] = { ...@@ -120,6 +98,8 @@ static struct regulator_desc isl_rd[] = {
.ops = &isl_core_ops, .ops = &isl_core_ops,
.type = REGULATOR_VOLTAGE, .type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE, .owner = THIS_MODULE,
.min_uV = ISL6271A_VOLTAGE_MIN,
.uV_step = ISL6271A_VOLTAGE_STEP,
}, { }, {
.name = "LDO1", .name = "LDO1",
.id = 1, .id = 1,
...@@ -140,6 +120,7 @@ static struct regulator_desc isl_rd[] = { ...@@ -140,6 +120,7 @@ static struct regulator_desc isl_rd[] = {
static int __devinit isl6271a_probe(struct i2c_client *i2c, static int __devinit isl6271a_probe(struct i2c_client *i2c,
const struct i2c_device_id *id) const struct i2c_device_id *id)
{ {
struct regulator_config config = { };
struct regulator_init_data *init_data = i2c->dev.platform_data; struct regulator_init_data *init_data = i2c->dev.platform_data;
struct isl_pmic *pmic; struct isl_pmic *pmic;
int err, i; int err, i;
...@@ -147,12 +128,7 @@ static int __devinit isl6271a_probe(struct i2c_client *i2c, ...@@ -147,12 +128,7 @@ static int __devinit isl6271a_probe(struct i2c_client *i2c,
if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
return -EIO; return -EIO;
if (!init_data) { pmic = devm_kzalloc(&i2c->dev, sizeof(struct isl_pmic), GFP_KERNEL);
dev_err(&i2c->dev, "no platform data supplied\n");
return -EIO;
}
pmic = kzalloc(sizeof(struct isl_pmic), GFP_KERNEL);
if (!pmic) if (!pmic)
return -ENOMEM; return -ENOMEM;
...@@ -161,8 +137,14 @@ static int __devinit isl6271a_probe(struct i2c_client *i2c, ...@@ -161,8 +137,14 @@ static int __devinit isl6271a_probe(struct i2c_client *i2c,
mutex_init(&pmic->mtx); mutex_init(&pmic->mtx);
for (i = 0; i < 3; i++) { for (i = 0; i < 3; i++) {
pmic->rdev[i] = regulator_register(&isl_rd[i], &i2c->dev, config.dev = &i2c->dev;
init_data, pmic, NULL); 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])) { if (IS_ERR(pmic->rdev[i])) {
dev_err(&i2c->dev, "failed to register %s\n", id->name); dev_err(&i2c->dev, "failed to register %s\n", id->name);
err = PTR_ERR(pmic->rdev[i]); err = PTR_ERR(pmic->rdev[i]);
...@@ -177,8 +159,6 @@ static int __devinit isl6271a_probe(struct i2c_client *i2c, ...@@ -177,8 +159,6 @@ static int __devinit isl6271a_probe(struct i2c_client *i2c,
error: error:
while (--i >= 0) while (--i >= 0)
regulator_unregister(pmic->rdev[i]); regulator_unregister(pmic->rdev[i]);
kfree(pmic);
return err; return err;
} }
...@@ -189,9 +169,6 @@ static int __devexit isl6271a_remove(struct i2c_client *i2c) ...@@ -189,9 +169,6 @@ static int __devexit isl6271a_remove(struct i2c_client *i2c)
for (i = 0; i < 3; i++) for (i = 0; i < 3; i++)
regulator_unregister(pmic->rdev[i]); regulator_unregister(pmic->rdev[i]);
kfree(pmic);
return 0; return 0;
} }
......
...@@ -124,6 +124,10 @@ static const int *ldo_voltage_map[] = { ...@@ -124,6 +124,10 @@ static const int *ldo_voltage_map[] = {
static int lp3971_ldo_list_voltage(struct regulator_dev *dev, unsigned index) static int lp3971_ldo_list_voltage(struct regulator_dev *dev, unsigned index)
{ {
int ldo = rdev_get_id(dev) - LP3971_LDO1; int ldo = rdev_get_id(dev) - LP3971_LDO1;
if (index > LDO_VOL_MAX_IDX)
return -EINVAL;
return 1000 * LDO_VOL_VALUE_MAP(ldo)[index]; return 1000 * LDO_VOL_VALUE_MAP(ldo)[index];
} }
...@@ -168,32 +172,15 @@ static int lp3971_ldo_get_voltage(struct regulator_dev *dev) ...@@ -168,32 +172,15 @@ static int lp3971_ldo_get_voltage(struct regulator_dev *dev)
return 1000 * LDO_VOL_VALUE_MAP(ldo)[val]; return 1000 * LDO_VOL_VALUE_MAP(ldo)[val];
} }
static int lp3971_ldo_set_voltage(struct regulator_dev *dev, static int lp3971_ldo_set_voltage_sel(struct regulator_dev *dev,
int min_uV, int max_uV, unsigned int selector)
unsigned int *selector)
{ {
struct lp3971 *lp3971 = rdev_get_drvdata(dev); struct lp3971 *lp3971 = rdev_get_drvdata(dev);
int ldo = rdev_get_id(dev) - LP3971_LDO1; 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), return lp3971_set_bits(lp3971, LP3971_LDO_VOL_CONTR_REG(ldo),
LDO_VOL_CONTR_MASK << LDO_VOL_CONTR_SHIFT(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 = { static struct regulator_ops lp3971_ldo_ops = {
...@@ -202,11 +189,14 @@ static struct regulator_ops lp3971_ldo_ops = { ...@@ -202,11 +189,14 @@ static struct regulator_ops lp3971_ldo_ops = {
.enable = lp3971_ldo_enable, .enable = lp3971_ldo_enable,
.disable = lp3971_ldo_disable, .disable = lp3971_ldo_disable,
.get_voltage = lp3971_ldo_get_voltage, .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) 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]; return 1000 * buck_voltage_map[index];
} }
...@@ -259,33 +249,15 @@ static int lp3971_dcdc_get_voltage(struct regulator_dev *dev) ...@@ -259,33 +249,15 @@ static int lp3971_dcdc_get_voltage(struct regulator_dev *dev)
return val; return val;
} }
static int lp3971_dcdc_set_voltage(struct regulator_dev *dev, static int lp3971_dcdc_set_voltage_sel(struct regulator_dev *dev,
int min_uV, int max_uV, unsigned int selector)
unsigned int *selector)
{ {
struct lp3971 *lp3971 = rdev_get_drvdata(dev); struct lp3971 *lp3971 = rdev_get_drvdata(dev);
int buck = rdev_get_id(dev) - LP3971_DCDC1; 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; 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), ret = lp3971_set_bits(lp3971, LP3971_BUCK_TARGET_VOL1_REG(buck),
BUCK_TARGET_VOL_MASK, val); BUCK_TARGET_VOL_MASK, selector);
if (ret) if (ret)
return ret; return ret;
...@@ -306,10 +278,10 @@ static struct regulator_ops lp3971_dcdc_ops = { ...@@ -306,10 +278,10 @@ static struct regulator_ops lp3971_dcdc_ops = {
.enable = lp3971_dcdc_enable, .enable = lp3971_dcdc_enable,
.disable = lp3971_dcdc_disable, .disable = lp3971_dcdc_disable,
.get_voltage = lp3971_dcdc_get_voltage, .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", .name = "LDO1",
.id = LP3971_LDO1, .id = LP3971_LDO1,
...@@ -449,10 +421,15 @@ static int __devinit setup_regulators(struct lp3971 *lp3971, ...@@ -449,10 +421,15 @@ static int __devinit setup_regulators(struct lp3971 *lp3971,
/* Instantiate the regulators */ /* Instantiate the regulators */
for (i = 0; i < pdata->num_regulators; i++) { for (i = 0; i < pdata->num_regulators; i++) {
struct regulator_config config = { };
struct lp3971_regulator_subdev *reg = &pdata->regulators[i]; 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])) { if (IS_ERR(lp3971->rdev[i])) {
err = PTR_ERR(lp3971->rdev[i]); err = PTR_ERR(lp3971->rdev[i]);
dev_err(lp3971->dev, "regulator init failed: %d\n", dev_err(lp3971->dev, "regulator init failed: %d\n",
...@@ -545,23 +522,7 @@ static struct i2c_driver lp3971_i2c_driver = { ...@@ -545,23 +522,7 @@ static struct i2c_driver lp3971_i2c_driver = {
.id_table = lp3971_i2c_id, .id_table = lp3971_i2c_id,
}; };
static int __init lp3971_module_init(void) module_i2c_driver(lp3971_i2c_driver);
{
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_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_AUTHOR("Marek Szyprowski <m.szyprowski@samsung.com>"); MODULE_AUTHOR("Marek Szyprowski <m.szyprowski@samsung.com>");
......
...@@ -245,6 +245,11 @@ static int lp3972_set_bits(struct lp3972 *lp3972, u8 reg, u16 mask, u16 val) ...@@ -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) static int lp3972_ldo_list_voltage(struct regulator_dev *dev, unsigned index)
{ {
int ldo = rdev_get_id(dev) - LP3972_LDO1; 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]; return 1000 * LP3972_LDO_VOL_VALUE_MAP(ldo)[index];
} }
...@@ -292,34 +297,16 @@ static int lp3972_ldo_get_voltage(struct regulator_dev *dev) ...@@ -292,34 +297,16 @@ static int lp3972_ldo_get_voltage(struct regulator_dev *dev)
return 1000 * LP3972_LDO_VOL_VALUE_MAP(ldo)[val]; return 1000 * LP3972_LDO_VOL_VALUE_MAP(ldo)[val];
} }
static int lp3972_ldo_set_voltage(struct regulator_dev *dev, static int lp3972_ldo_set_voltage_sel(struct regulator_dev *dev,
int min_uV, int max_uV, unsigned int selector)
unsigned int *selector)
{ {
struct lp3972 *lp3972 = rdev_get_drvdata(dev); struct lp3972 *lp3972 = rdev_get_drvdata(dev);
int ldo = rdev_get_id(dev) - LP3972_LDO1; 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; 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); shift = LP3972_LDO_VOL_CONTR_SHIFT(ldo);
ret = lp3972_set_bits(lp3972, LP3972_LDO_VOL_CONTR_REG(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) if (ret)
return ret; return ret;
...@@ -355,12 +342,17 @@ static struct regulator_ops lp3972_ldo_ops = { ...@@ -355,12 +342,17 @@ static struct regulator_ops lp3972_ldo_ops = {
.enable = lp3972_ldo_enable, .enable = lp3972_ldo_enable,
.disable = lp3972_ldo_disable, .disable = lp3972_ldo_disable,
.get_voltage = lp3972_ldo_get_voltage, .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) static int lp3972_dcdc_list_voltage(struct regulator_dev *dev, unsigned index)
{ {
int buck = rdev_get_id(dev) - LP3972_DCDC1; 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]; return 1000 * buck_voltage_map[buck][index];
} }
...@@ -419,34 +411,15 @@ static int lp3972_dcdc_get_voltage(struct regulator_dev *dev) ...@@ -419,34 +411,15 @@ static int lp3972_dcdc_get_voltage(struct regulator_dev *dev)
return val; return val;
} }
static int lp3972_dcdc_set_voltage(struct regulator_dev *dev, static int lp3972_dcdc_set_voltage_sel(struct regulator_dev *dev,
int min_uV, int max_uV, unsigned int selector)
unsigned int *selector)
{ {
struct lp3972 *lp3972 = rdev_get_drvdata(dev); struct lp3972 *lp3972 = rdev_get_drvdata(dev);
int buck = rdev_get_id(dev) - LP3972_DCDC1; 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; 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), ret = lp3972_set_bits(lp3972, LP3972_BUCK_VOL1_REG(buck),
LP3972_BUCK_VOL_MASK, val); LP3972_BUCK_VOL_MASK, selector);
if (ret) if (ret)
return ret; return ret;
...@@ -468,10 +441,10 @@ static struct regulator_ops lp3972_dcdc_ops = { ...@@ -468,10 +441,10 @@ static struct regulator_ops lp3972_dcdc_ops = {
.enable = lp3972_dcdc_enable, .enable = lp3972_dcdc_enable,
.disable = lp3972_dcdc_disable, .disable = lp3972_dcdc_disable,
.get_voltage = lp3972_dcdc_get_voltage, .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", .name = "LDO1",
.id = LP3972_LDO1, .id = LP3972_LDO1,
...@@ -554,9 +527,14 @@ static int __devinit setup_regulators(struct lp3972 *lp3972, ...@@ -554,9 +527,14 @@ static int __devinit setup_regulators(struct lp3972 *lp3972,
/* Instantiate the regulators */ /* Instantiate the regulators */
for (i = 0; i < pdata->num_regulators; i++) { for (i = 0; i < pdata->num_regulators; i++) {
struct lp3972_regulator_subdev *reg = &pdata->regulators[i]; struct lp3972_regulator_subdev *reg = &pdata->regulators[i];
lp3972->rdev[i] = regulator_register(&regulators[reg->id], struct regulator_config config = { };
lp3972->dev, reg->initdata, lp3972, NULL);
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])) { if (IS_ERR(lp3972->rdev[i])) {
err = PTR_ERR(lp3972->rdev[i]); err = PTR_ERR(lp3972->rdev[i]);
dev_err(lp3972->dev, "regulator init failed: %d\n", dev_err(lp3972->dev, "regulator init failed: %d\n",
......
...@@ -161,7 +161,7 @@ static struct regulator_ops max1586_v6_ops = { ...@@ -161,7 +161,7 @@ static struct regulator_ops max1586_v6_ops = {
.list_voltage = max1586_v6_list, .list_voltage = max1586_v6_list,
}; };
static struct regulator_desc max1586_reg[] = { static const struct regulator_desc max1586_reg[] = {
{ {
.name = "Output_V3", .name = "Output_V3",
.id = MAX1586_V3, .id = MAX1586_V3,
...@@ -185,21 +185,21 @@ static int __devinit max1586_pmic_probe(struct i2c_client *client, ...@@ -185,21 +185,21 @@ static int __devinit max1586_pmic_probe(struct i2c_client *client,
{ {
struct regulator_dev **rdev; struct regulator_dev **rdev;
struct max1586_platform_data *pdata = client->dev.platform_data; struct max1586_platform_data *pdata = client->dev.platform_data;
struct regulator_config config = { };
struct max1586_data *max1586; struct max1586_data *max1586;
int i, id, ret = -ENOMEM; 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), sizeof(struct regulator_dev *) * (MAX1586_V6 + 1),
GFP_KERNEL); GFP_KERNEL);
if (!max1586) if (!max1586)
goto out; return -ENOMEM;
max1586->client = client; max1586->client = client;
if (!pdata->v3_gain) { if (!pdata->v3_gain)
ret = -EINVAL; return -EINVAL;
goto out_unmap;
}
max1586->min_uV = MAX1586_V3_MIN_UV / 1000 * pdata->v3_gain / 1000; max1586->min_uV = MAX1586_V3_MIN_UV / 1000 * pdata->v3_gain / 1000;
max1586->max_uV = MAX1586_V3_MAX_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, ...@@ -212,9 +212,12 @@ static int __devinit max1586_pmic_probe(struct i2c_client *client,
dev_err(&client->dev, "invalid regulator id %d\n", id); dev_err(&client->dev, "invalid regulator id %d\n", id);
goto err; goto err;
} }
rdev[i] = regulator_register(&max1586_reg[id], &client->dev,
pdata->subdevs[i].platform_data, config.dev = &client->dev;
max1586, NULL); 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])) { if (IS_ERR(rdev[i])) {
ret = PTR_ERR(rdev[i]); ret = PTR_ERR(rdev[i]);
dev_err(&client->dev, "failed to register %s\n", dev_err(&client->dev, "failed to register %s\n",
...@@ -230,9 +233,6 @@ static int __devinit max1586_pmic_probe(struct i2c_client *client, ...@@ -230,9 +233,6 @@ static int __devinit max1586_pmic_probe(struct i2c_client *client,
err: err:
while (--i >= 0) while (--i >= 0)
regulator_unregister(rdev[i]); regulator_unregister(rdev[i]);
out_unmap:
kfree(max1586);
out:
return ret; return ret;
} }
...@@ -244,8 +244,6 @@ static int __devexit max1586_pmic_remove(struct i2c_client *client) ...@@ -244,8 +244,6 @@ static int __devexit max1586_pmic_remove(struct i2c_client *client)
for (i = 0; i <= MAX1586_V6; i++) for (i = 0; i <= MAX1586_V6; i++)
if (max1586->rdev[i]) if (max1586->rdev[i])
regulator_unregister(max1586->rdev[i]); regulator_unregister(max1586->rdev[i]);
kfree(max1586);
return 0; return 0;
} }
......
...@@ -53,7 +53,6 @@ struct max8649_regulator_info { ...@@ -53,7 +53,6 @@ struct max8649_regulator_info {
struct device *dev; struct device *dev;
struct regmap *regmap; struct regmap *regmap;
int vol_reg;
unsigned mode:2; /* bit[1:0] = VID1, VID0 */ unsigned mode:2; /* bit[1:0] = VID1, VID0 */
unsigned extclk_freq:2; unsigned extclk_freq:2;
unsigned extclk:1; unsigned extclk:1;
...@@ -61,53 +60,6 @@ struct max8649_regulator_info { ...@@ -61,53 +60,6 @@ struct max8649_regulator_info {
unsigned ramp_down:1; unsigned ramp_down:1;
}; };
/* I2C operations */
static inline int check_range(int min_uV, int max_uV)
{
if ((min_uV < MAX8649_DCDC_VMIN) || (max_uV > MAX8649_DCDC_VMAX)
|| (min_uV > max_uV))
return -EINVAL;
return 0;
}
static int max8649_list_voltage(struct regulator_dev *rdev, unsigned index)
{
return (MAX8649_DCDC_VMIN + index * MAX8649_DCDC_STEP);
}
static int max8649_get_voltage(struct regulator_dev *rdev)
{
struct max8649_regulator_info *info = rdev_get_drvdata(rdev);
unsigned int val;
unsigned char data;
int ret;
ret = regmap_read(info->regmap, info->vol_reg, &val);
if (ret != 0)
return ret;
data = (unsigned char)val & MAX8649_VOL_MASK;
return max8649_list_voltage(rdev, data);
}
static int max8649_set_voltage(struct regulator_dev *rdev,
int min_uV, int max_uV, unsigned *selector)
{
struct max8649_regulator_info *info = rdev_get_drvdata(rdev);
unsigned char data, mask;
if (check_range(min_uV, max_uV)) {
dev_err(info->dev, "invalid voltage range (%d, %d) uV\n",
min_uV, max_uV);
return -EINVAL;
}
data = DIV_ROUND_UP(min_uV - MAX8649_DCDC_VMIN, MAX8649_DCDC_STEP);
mask = MAX8649_VOL_MASK;
*selector = data & mask;
return regmap_update_bits(info->regmap, info->vol_reg, mask, data);
}
/* EN_PD means pulldown on EN input */ /* EN_PD means pulldown on EN input */
static int max8649_enable(struct regulator_dev *rdev) static int max8649_enable(struct regulator_dev *rdev)
{ {
...@@ -145,11 +97,11 @@ static int max8649_enable_time(struct regulator_dev *rdev) ...@@ -145,11 +97,11 @@ static int max8649_enable_time(struct regulator_dev *rdev)
unsigned int val; unsigned int val;
/* get voltage */ /* get voltage */
ret = regmap_read(info->regmap, info->vol_reg, &val); ret = regmap_read(info->regmap, rdev->desc->vsel_reg, &val);
if (ret != 0) if (ret != 0)
return ret; return ret;
val &= MAX8649_VOL_MASK; val &= MAX8649_VOL_MASK;
voltage = max8649_list_voltage(rdev, (unsigned char)val); /* uV */ voltage = regulator_list_voltage_linear(rdev, (unsigned char)val);
/* get rate */ /* get rate */
ret = regmap_read(info->regmap, MAX8649_RAMP, &val); ret = regmap_read(info->regmap, MAX8649_RAMP, &val);
...@@ -167,11 +119,11 @@ static int max8649_set_mode(struct regulator_dev *rdev, unsigned int mode) ...@@ -167,11 +119,11 @@ static int max8649_set_mode(struct regulator_dev *rdev, unsigned int mode)
switch (mode) { switch (mode) {
case REGULATOR_MODE_FAST: case REGULATOR_MODE_FAST:
regmap_update_bits(info->regmap, info->vol_reg, MAX8649_FORCE_PWM, regmap_update_bits(info->regmap, rdev->desc->vsel_reg,
MAX8649_FORCE_PWM); MAX8649_FORCE_PWM, MAX8649_FORCE_PWM);
break; break;
case REGULATOR_MODE_NORMAL: case REGULATOR_MODE_NORMAL:
regmap_update_bits(info->regmap, info->vol_reg, regmap_update_bits(info->regmap, rdev->desc->vsel_reg,
MAX8649_FORCE_PWM, 0); MAX8649_FORCE_PWM, 0);
break; break;
default: default:
...@@ -186,7 +138,7 @@ static unsigned int max8649_get_mode(struct regulator_dev *rdev) ...@@ -186,7 +138,7 @@ static unsigned int max8649_get_mode(struct regulator_dev *rdev)
unsigned int val; unsigned int val;
int ret; int ret;
ret = regmap_read(info->regmap, info->vol_reg, &val); ret = regmap_read(info->regmap, rdev->desc->vsel_reg, &val);
if (ret != 0) if (ret != 0)
return ret; return ret;
if (val & MAX8649_FORCE_PWM) if (val & MAX8649_FORCE_PWM)
...@@ -195,9 +147,10 @@ static unsigned int max8649_get_mode(struct regulator_dev *rdev) ...@@ -195,9 +147,10 @@ static unsigned int max8649_get_mode(struct regulator_dev *rdev)
} }
static struct regulator_ops max8649_dcdc_ops = { static struct regulator_ops max8649_dcdc_ops = {
.set_voltage = max8649_set_voltage, .set_voltage_sel = regulator_set_voltage_sel_regmap,
.get_voltage = max8649_get_voltage, .get_voltage_sel = regulator_get_voltage_sel_regmap,
.list_voltage = max8649_list_voltage, .list_voltage = regulator_list_voltage_linear,
.map_voltage = regulator_map_voltage_linear,
.enable = max8649_enable, .enable = max8649_enable,
.disable = max8649_disable, .disable = max8649_disable,
.is_enabled = max8649_is_enabled, .is_enabled = max8649_is_enabled,
...@@ -213,6 +166,9 @@ static struct regulator_desc dcdc_desc = { ...@@ -213,6 +166,9 @@ static struct regulator_desc dcdc_desc = {
.type = REGULATOR_VOLTAGE, .type = REGULATOR_VOLTAGE,
.n_voltages = 1 << 6, .n_voltages = 1 << 6,
.owner = THIS_MODULE, .owner = THIS_MODULE,
.vsel_mask = MAX8649_VOL_MASK,
.min_uV = MAX8649_DCDC_VMIN,
.uV_step = MAX8649_DCDC_STEP,
}; };
static struct regmap_config max8649_regmap_config = { static struct regmap_config max8649_regmap_config = {
...@@ -225,21 +181,23 @@ static int __devinit max8649_regulator_probe(struct i2c_client *client, ...@@ -225,21 +181,23 @@ static int __devinit max8649_regulator_probe(struct i2c_client *client,
{ {
struct max8649_platform_data *pdata = client->dev.platform_data; struct max8649_platform_data *pdata = client->dev.platform_data;
struct max8649_regulator_info *info = NULL; struct max8649_regulator_info *info = NULL;
struct regulator_config config = { };
unsigned int val; unsigned int val;
unsigned char data; unsigned char data;
int ret; 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) { if (!info) {
dev_err(&client->dev, "No enough memory\n"); dev_err(&client->dev, "No enough memory\n");
return -ENOMEM; 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)) { if (IS_ERR(info->regmap)) {
ret = PTR_ERR(info->regmap); ret = PTR_ERR(info->regmap);
dev_err(&client->dev, "Failed to allocate register map: %d\n", ret); dev_err(&client->dev, "Failed to allocate register map: %d\n", ret);
goto fail; return ret;
} }
info->dev = &client->dev; info->dev = &client->dev;
...@@ -248,16 +206,16 @@ static int __devinit max8649_regulator_probe(struct i2c_client *client, ...@@ -248,16 +206,16 @@ static int __devinit max8649_regulator_probe(struct i2c_client *client,
info->mode = pdata->mode; info->mode = pdata->mode;
switch (info->mode) { switch (info->mode) {
case 0: case 0:
info->vol_reg = MAX8649_MODE0; dcdc_desc.vsel_reg = MAX8649_MODE0;
break; break;
case 1: case 1:
info->vol_reg = MAX8649_MODE1; dcdc_desc.vsel_reg = MAX8649_MODE1;
break; break;
case 2: case 2:
info->vol_reg = MAX8649_MODE2; dcdc_desc.vsel_reg = MAX8649_MODE2;
break; break;
case 3: case 3:
info->vol_reg = MAX8649_MODE3; dcdc_desc.vsel_reg = MAX8649_MODE3;
break; break;
default: default:
break; break;
...@@ -267,7 +225,7 @@ static int __devinit max8649_regulator_probe(struct i2c_client *client, ...@@ -267,7 +225,7 @@ static int __devinit max8649_regulator_probe(struct i2c_client *client,
if (ret != 0) { if (ret != 0) {
dev_err(info->dev, "Failed to detect ID of MAX8649:%d\n", dev_err(info->dev, "Failed to detect ID of MAX8649:%d\n",
ret); ret);
goto out; return ret;
} }
dev_info(info->dev, "Detected MAX8649 (ID:%x)\n", val); dev_info(info->dev, "Detected MAX8649 (ID:%x)\n", val);
...@@ -277,7 +235,8 @@ static int __devinit max8649_regulator_probe(struct i2c_client *client, ...@@ -277,7 +235,8 @@ static int __devinit max8649_regulator_probe(struct i2c_client *client,
/* enable/disable external clock synchronization */ /* enable/disable external clock synchronization */
info->extclk = pdata->extclk; info->extclk = pdata->extclk;
data = (info->extclk) ? MAX8649_SYNC_EXTCLK : 0; data = (info->extclk) ? MAX8649_SYNC_EXTCLK : 0;
regmap_update_bits(info->regmap, info->vol_reg, MAX8649_SYNC_EXTCLK, data); regmap_update_bits(info->regmap, dcdc_desc.vsel_reg,
MAX8649_SYNC_EXTCLK, data);
if (info->extclk) { if (info->extclk) {
/* set external clock frequency */ /* set external clock frequency */
info->extclk_freq = pdata->extclk_freq; info->extclk_freq = pdata->extclk_freq;
...@@ -297,22 +256,18 @@ static int __devinit max8649_regulator_probe(struct i2c_client *client, ...@@ -297,22 +256,18 @@ static int __devinit max8649_regulator_probe(struct i2c_client *client,
MAX8649_RAMP_DOWN); MAX8649_RAMP_DOWN);
} }
info->regulator = regulator_register(&dcdc_desc, &client->dev, config.dev = &client->dev;
pdata->regulator, info, NULL); config.init_data = pdata->regulator;
config.driver_data = info;
info->regulator = regulator_register(&dcdc_desc, &config);
if (IS_ERR(info->regulator)) { if (IS_ERR(info->regulator)) {
dev_err(info->dev, "failed to register regulator %s\n", dev_err(info->dev, "failed to register regulator %s\n",
dcdc_desc.name); dcdc_desc.name);
ret = PTR_ERR(info->regulator); return PTR_ERR(info->regulator);
goto out;
} }
dev_info(info->dev, "Max8649 regulator device is detected.\n");
return 0; return 0;
out:
regmap_exit(info->regmap);
fail:
kfree(info);
return ret;
} }
static int __devexit max8649_regulator_remove(struct i2c_client *client) static int __devexit max8649_regulator_remove(struct i2c_client *client)
...@@ -322,8 +277,6 @@ static int __devexit max8649_regulator_remove(struct i2c_client *client) ...@@ -322,8 +277,6 @@ static int __devexit max8649_regulator_remove(struct i2c_client *client)
if (info) { if (info) {
if (info->regulator) if (info->regulator)
regulator_unregister(info->regulator); regulator_unregister(info->regulator);
regmap_exit(info->regmap);
kfree(info);
} }
return 0; return 0;
...@@ -360,4 +313,3 @@ module_exit(max8649_exit); ...@@ -360,4 +313,3 @@ module_exit(max8649_exit);
MODULE_DESCRIPTION("MAXIM 8649 voltage regulator driver"); MODULE_DESCRIPTION("MAXIM 8649 voltage regulator driver");
MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>"); MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
...@@ -126,42 +126,22 @@ static int max8660_dcdc_disable(struct regulator_dev *rdev) ...@@ -126,42 +126,22 @@ static int max8660_dcdc_disable(struct regulator_dev *rdev)
return max8660_write(max8660, MAX8660_OVER1, mask, 0); return max8660_write(max8660, MAX8660_OVER1, mask, 0);
} }
static int max8660_dcdc_list(struct regulator_dev *rdev, unsigned selector) static int max8660_dcdc_get_voltage_sel(struct regulator_dev *rdev)
{
if (selector > MAX8660_DCDC_MAX_SEL)
return -EINVAL;
return MAX8660_DCDC_MIN_UV + selector * MAX8660_DCDC_STEP;
}
static int max8660_dcdc_get(struct regulator_dev *rdev)
{ {
struct max8660 *max8660 = rdev_get_drvdata(rdev); struct max8660 *max8660 = rdev_get_drvdata(rdev);
u8 reg = (rdev_get_id(rdev) == MAX8660_V3) ? MAX8660_ADTV2 : MAX8660_SDTV2; u8 reg = (rdev_get_id(rdev) == MAX8660_V3) ? MAX8660_ADTV2 : MAX8660_SDTV2;
u8 selector = max8660->shadow_regs[reg]; u8 selector = max8660->shadow_regs[reg];
return MAX8660_DCDC_MIN_UV + selector * MAX8660_DCDC_STEP; return selector;
} }
static int max8660_dcdc_set(struct regulator_dev *rdev, int min_uV, int max_uV, static int max8660_dcdc_set_voltage_sel(struct regulator_dev *rdev,
unsigned int *s) unsigned int selector)
{ {
struct max8660 *max8660 = rdev_get_drvdata(rdev); struct max8660 *max8660 = rdev_get_drvdata(rdev);
u8 reg, selector, bits; u8 reg, bits;
int ret; int ret;
if (min_uV < MAX8660_DCDC_MIN_UV || min_uV > MAX8660_DCDC_MAX_UV)
return -EINVAL;
if (max_uV < MAX8660_DCDC_MIN_UV || max_uV > MAX8660_DCDC_MAX_UV)
return -EINVAL;
selector = DIV_ROUND_UP(min_uV - MAX8660_DCDC_MIN_UV,
MAX8660_DCDC_STEP);
ret = max8660_dcdc_list(rdev, selector);
if (ret < 0 || ret > max_uV)
return -EINVAL;
*s = selector;
reg = (rdev_get_id(rdev) == MAX8660_V3) ? MAX8660_ADTV2 : MAX8660_SDTV2; reg = (rdev_get_id(rdev) == MAX8660_V3) ? MAX8660_ADTV2 : MAX8660_SDTV2;
ret = max8660_write(max8660, reg, 0, selector); ret = max8660_write(max8660, reg, 0, selector);
if (ret) if (ret)
...@@ -174,9 +154,10 @@ static int max8660_dcdc_set(struct regulator_dev *rdev, int min_uV, int max_uV, ...@@ -174,9 +154,10 @@ static int max8660_dcdc_set(struct regulator_dev *rdev, int min_uV, int max_uV,
static struct regulator_ops max8660_dcdc_ops = { static struct regulator_ops max8660_dcdc_ops = {
.is_enabled = max8660_dcdc_is_enabled, .is_enabled = max8660_dcdc_is_enabled,
.list_voltage = max8660_dcdc_list, .list_voltage = regulator_list_voltage_linear,
.set_voltage = max8660_dcdc_set, .map_voltage = regulator_map_voltage_linear,
.get_voltage = max8660_dcdc_get, .set_voltage_sel = max8660_dcdc_set_voltage_sel,
.get_voltage_sel = max8660_dcdc_get_voltage_sel,
}; };
...@@ -184,42 +165,20 @@ static struct regulator_ops max8660_dcdc_ops = { ...@@ -184,42 +165,20 @@ static struct regulator_ops max8660_dcdc_ops = {
* LDO5 functions * LDO5 functions
*/ */
static int max8660_ldo5_list(struct regulator_dev *rdev, unsigned selector) static int max8660_ldo5_get_voltage_sel(struct regulator_dev *rdev)
{
if (selector > MAX8660_LDO5_MAX_SEL)
return -EINVAL;
return MAX8660_LDO5_MIN_UV + selector * MAX8660_LDO5_STEP;
}
static int max8660_ldo5_get(struct regulator_dev *rdev)
{ {
struct max8660 *max8660 = rdev_get_drvdata(rdev); struct max8660 *max8660 = rdev_get_drvdata(rdev);
u8 selector = max8660->shadow_regs[MAX8660_MDTV2];
return MAX8660_LDO5_MIN_UV + selector * MAX8660_LDO5_STEP; u8 selector = max8660->shadow_regs[MAX8660_MDTV2];
return selector;
} }
static int max8660_ldo5_set(struct regulator_dev *rdev, int min_uV, int max_uV, static int max8660_ldo5_set_voltage_sel(struct regulator_dev *rdev,
unsigned int *s) unsigned int selector)
{ {
struct max8660 *max8660 = rdev_get_drvdata(rdev); struct max8660 *max8660 = rdev_get_drvdata(rdev);
u8 selector;
int ret; int ret;
if (min_uV < MAX8660_LDO5_MIN_UV || min_uV > MAX8660_LDO5_MAX_UV)
return -EINVAL;
if (max_uV < MAX8660_LDO5_MIN_UV || max_uV > MAX8660_LDO5_MAX_UV)
return -EINVAL;
selector = DIV_ROUND_UP(min_uV - MAX8660_LDO5_MIN_UV,
MAX8660_LDO5_STEP);
ret = max8660_ldo5_list(rdev, selector);
if (ret < 0 || ret > max_uV)
return -EINVAL;
*s = selector;
ret = max8660_write(max8660, MAX8660_MDTV2, 0, selector); ret = max8660_write(max8660, MAX8660_MDTV2, 0, selector);
if (ret) if (ret)
return ret; return ret;
...@@ -229,9 +188,10 @@ static int max8660_ldo5_set(struct regulator_dev *rdev, int min_uV, int max_uV, ...@@ -229,9 +188,10 @@ static int max8660_ldo5_set(struct regulator_dev *rdev, int min_uV, int max_uV,
} }
static struct regulator_ops max8660_ldo5_ops = { static struct regulator_ops max8660_ldo5_ops = {
.list_voltage = max8660_ldo5_list, .list_voltage = regulator_list_voltage_linear,
.set_voltage = max8660_ldo5_set, .map_voltage = regulator_map_voltage_linear,
.get_voltage = max8660_ldo5_get, .set_voltage_sel = max8660_ldo5_set_voltage_sel,
.get_voltage_sel = max8660_ldo5_get_voltage_sel,
}; };
...@@ -261,59 +221,38 @@ static int max8660_ldo67_disable(struct regulator_dev *rdev) ...@@ -261,59 +221,38 @@ static int max8660_ldo67_disable(struct regulator_dev *rdev)
return max8660_write(max8660, MAX8660_OVER2, mask, 0); return max8660_write(max8660, MAX8660_OVER2, mask, 0);
} }
static int max8660_ldo67_list(struct regulator_dev *rdev, unsigned selector) static int max8660_ldo67_get_voltage_sel(struct regulator_dev *rdev)
{
if (selector > MAX8660_LDO67_MAX_SEL)
return -EINVAL;
return MAX8660_LDO67_MIN_UV + selector * MAX8660_LDO67_STEP;
}
static int max8660_ldo67_get(struct regulator_dev *rdev)
{ {
struct max8660 *max8660 = rdev_get_drvdata(rdev); struct max8660 *max8660 = rdev_get_drvdata(rdev);
u8 shift = (rdev_get_id(rdev) == MAX8660_V6) ? 0 : 4; u8 shift = (rdev_get_id(rdev) == MAX8660_V6) ? 0 : 4;
u8 selector = (max8660->shadow_regs[MAX8660_L12VCR] >> shift) & 0xf; u8 selector = (max8660->shadow_regs[MAX8660_L12VCR] >> shift) & 0xf;
return selector;
return MAX8660_LDO67_MIN_UV + selector * MAX8660_LDO67_STEP;
} }
static int max8660_ldo67_set(struct regulator_dev *rdev, int min_uV, static int max8660_ldo67_set_voltage_sel(struct regulator_dev *rdev,
int max_uV, unsigned int *s) unsigned int selector)
{ {
struct max8660 *max8660 = rdev_get_drvdata(rdev); struct max8660 *max8660 = rdev_get_drvdata(rdev);
u8 selector;
int ret;
if (min_uV < MAX8660_LDO67_MIN_UV || min_uV > MAX8660_LDO67_MAX_UV)
return -EINVAL;
if (max_uV < MAX8660_LDO67_MIN_UV || max_uV > MAX8660_LDO67_MAX_UV)
return -EINVAL;
selector = DIV_ROUND_UP(min_uV - MAX8660_LDO67_MIN_UV,
MAX8660_LDO67_STEP);
ret = max8660_ldo67_list(rdev, selector);
if (ret < 0 || ret > max_uV)
return -EINVAL;
*s = selector;
if (rdev_get_id(rdev) == MAX8660_V6) if (rdev_get_id(rdev) == MAX8660_V6)
return max8660_write(max8660, MAX8660_L12VCR, 0xf0, selector); return max8660_write(max8660, MAX8660_L12VCR, 0xf0, selector);
else else
return max8660_write(max8660, MAX8660_L12VCR, 0x0f, selector << 4); return max8660_write(max8660, MAX8660_L12VCR, 0x0f,
selector << 4);
} }
static struct regulator_ops max8660_ldo67_ops = { static struct regulator_ops max8660_ldo67_ops = {
.is_enabled = max8660_ldo67_is_enabled, .is_enabled = max8660_ldo67_is_enabled,
.enable = max8660_ldo67_enable, .enable = max8660_ldo67_enable,
.disable = max8660_ldo67_disable, .disable = max8660_ldo67_disable,
.list_voltage = max8660_ldo67_list, .list_voltage = regulator_list_voltage_linear,
.get_voltage = max8660_ldo67_get, .map_voltage = regulator_map_voltage_linear,
.set_voltage = max8660_ldo67_set, .get_voltage_sel = max8660_ldo67_get_voltage_sel,
.set_voltage_sel = max8660_ldo67_set_voltage_sel,
}; };
static struct regulator_desc max8660_reg[] = { static const struct regulator_desc max8660_reg[] = {
{ {
.name = "V3(DCDC)", .name = "V3(DCDC)",
.id = MAX8660_V3, .id = MAX8660_V3,
...@@ -321,6 +260,8 @@ static struct regulator_desc max8660_reg[] = { ...@@ -321,6 +260,8 @@ static struct regulator_desc max8660_reg[] = {
.type = REGULATOR_VOLTAGE, .type = REGULATOR_VOLTAGE,
.n_voltages = MAX8660_DCDC_MAX_SEL + 1, .n_voltages = MAX8660_DCDC_MAX_SEL + 1,
.owner = THIS_MODULE, .owner = THIS_MODULE,
.min_uV = MAX8660_DCDC_MIN_UV,
.uV_step = MAX8660_DCDC_STEP,
}, },
{ {
.name = "V4(DCDC)", .name = "V4(DCDC)",
...@@ -329,6 +270,8 @@ static struct regulator_desc max8660_reg[] = { ...@@ -329,6 +270,8 @@ static struct regulator_desc max8660_reg[] = {
.type = REGULATOR_VOLTAGE, .type = REGULATOR_VOLTAGE,
.n_voltages = MAX8660_DCDC_MAX_SEL + 1, .n_voltages = MAX8660_DCDC_MAX_SEL + 1,
.owner = THIS_MODULE, .owner = THIS_MODULE,
.min_uV = MAX8660_DCDC_MIN_UV,
.uV_step = MAX8660_DCDC_STEP,
}, },
{ {
.name = "V5(LDO)", .name = "V5(LDO)",
...@@ -337,6 +280,8 @@ static struct regulator_desc max8660_reg[] = { ...@@ -337,6 +280,8 @@ static struct regulator_desc max8660_reg[] = {
.type = REGULATOR_VOLTAGE, .type = REGULATOR_VOLTAGE,
.n_voltages = MAX8660_LDO5_MAX_SEL + 1, .n_voltages = MAX8660_LDO5_MAX_SEL + 1,
.owner = THIS_MODULE, .owner = THIS_MODULE,
.min_uV = MAX8660_LDO5_MIN_UV,
.uV_step = MAX8660_LDO5_STEP,
}, },
{ {
.name = "V6(LDO)", .name = "V6(LDO)",
...@@ -345,6 +290,8 @@ static struct regulator_desc max8660_reg[] = { ...@@ -345,6 +290,8 @@ static struct regulator_desc max8660_reg[] = {
.type = REGULATOR_VOLTAGE, .type = REGULATOR_VOLTAGE,
.n_voltages = MAX8660_LDO67_MAX_SEL + 1, .n_voltages = MAX8660_LDO67_MAX_SEL + 1,
.owner = THIS_MODULE, .owner = THIS_MODULE,
.min_uV = MAX8660_LDO67_MIN_UV,
.uV_step = MAX8660_LDO67_STEP,
}, },
{ {
.name = "V7(LDO)", .name = "V7(LDO)",
...@@ -353,6 +300,8 @@ static struct regulator_desc max8660_reg[] = { ...@@ -353,6 +300,8 @@ static struct regulator_desc max8660_reg[] = {
.type = REGULATOR_VOLTAGE, .type = REGULATOR_VOLTAGE,
.n_voltages = MAX8660_LDO67_MAX_SEL + 1, .n_voltages = MAX8660_LDO67_MAX_SEL + 1,
.owner = THIS_MODULE, .owner = THIS_MODULE,
.min_uV = MAX8660_LDO67_MIN_UV,
.uV_step = MAX8660_LDO67_STEP,
}, },
}; };
...@@ -361,21 +310,20 @@ static int __devinit max8660_probe(struct i2c_client *client, ...@@ -361,21 +310,20 @@ static int __devinit max8660_probe(struct i2c_client *client,
{ {
struct regulator_dev **rdev; struct regulator_dev **rdev;
struct max8660_platform_data *pdata = client->dev.platform_data; struct max8660_platform_data *pdata = client->dev.platform_data;
struct regulator_config config = { };
struct max8660 *max8660; struct max8660 *max8660;
int boot_on, i, id, ret = -EINVAL; int boot_on, i, id, ret = -EINVAL;
if (pdata->num_subdevs > MAX8660_V_END) { if (pdata->num_subdevs > MAX8660_V_END) {
dev_err(&client->dev, "Too many regulators found!\n"); dev_err(&client->dev, "Too many regulators found!\n");
goto out; return -EINVAL;
} }
max8660 = kzalloc(sizeof(struct max8660) + max8660 = devm_kzalloc(&client->dev, sizeof(struct max8660) +
sizeof(struct regulator_dev *) * MAX8660_V_END, sizeof(struct regulator_dev *) * MAX8660_V_END,
GFP_KERNEL); GFP_KERNEL);
if (!max8660) { if (!max8660)
ret = -ENOMEM; return -ENOMEM;
goto out;
}
max8660->client = client; max8660->client = client;
rdev = max8660->rdev; rdev = max8660->rdev;
...@@ -404,7 +352,7 @@ static int __devinit max8660_probe(struct i2c_client *client, ...@@ -404,7 +352,7 @@ static int __devinit max8660_probe(struct i2c_client *client,
for (i = 0; i < pdata->num_subdevs; i++) { for (i = 0; i < pdata->num_subdevs; i++) {
if (!pdata->subdevs[i].platform_data) if (!pdata->subdevs[i].platform_data)
goto err_free; goto err_out;
boot_on = pdata->subdevs[i].platform_data->constraints.boot_on; boot_on = pdata->subdevs[i].platform_data->constraints.boot_on;
...@@ -430,7 +378,7 @@ static int __devinit max8660_probe(struct i2c_client *client, ...@@ -430,7 +378,7 @@ static int __devinit max8660_probe(struct i2c_client *client,
case MAX8660_V7: case MAX8660_V7:
if (!strcmp(i2c_id->name, "max8661")) { if (!strcmp(i2c_id->name, "max8661")) {
dev_err(&client->dev, "Regulator not on this chip!\n"); dev_err(&client->dev, "Regulator not on this chip!\n");
goto err_free; goto err_out;
} }
if (boot_on) if (boot_on)
...@@ -440,7 +388,7 @@ static int __devinit max8660_probe(struct i2c_client *client, ...@@ -440,7 +388,7 @@ static int __devinit max8660_probe(struct i2c_client *client,
default: default:
dev_err(&client->dev, "invalid regulator %s\n", dev_err(&client->dev, "invalid regulator %s\n",
pdata->subdevs[i].name); pdata->subdevs[i].name);
goto err_free; goto err_out;
} }
} }
...@@ -449,9 +397,11 @@ static int __devinit max8660_probe(struct i2c_client *client, ...@@ -449,9 +397,11 @@ static int __devinit max8660_probe(struct i2c_client *client,
id = pdata->subdevs[i].id; id = pdata->subdevs[i].id;
rdev[i] = regulator_register(&max8660_reg[id], &client->dev, config.dev = &client->dev;
pdata->subdevs[i].platform_data, config.init_data = pdata->subdevs[i].platform_data;
max8660, NULL); config.driver_data = max8660;
rdev[i] = regulator_register(&max8660_reg[id], &config);
if (IS_ERR(rdev[i])) { if (IS_ERR(rdev[i])) {
ret = PTR_ERR(rdev[i]); ret = PTR_ERR(rdev[i]);
dev_err(&client->dev, "failed to register %s\n", dev_err(&client->dev, "failed to register %s\n",
...@@ -461,15 +411,12 @@ static int __devinit max8660_probe(struct i2c_client *client, ...@@ -461,15 +411,12 @@ static int __devinit max8660_probe(struct i2c_client *client,
} }
i2c_set_clientdata(client, max8660); i2c_set_clientdata(client, max8660);
dev_info(&client->dev, "Maxim 8660/8661 regulator driver loaded\n");
return 0; return 0;
err_unregister: err_unregister:
while (--i >= 0) while (--i >= 0)
regulator_unregister(rdev[i]); regulator_unregister(rdev[i]);
err_free: err_out:
kfree(max8660);
out:
return ret; return ret;
} }
...@@ -481,8 +428,6 @@ static int __devexit max8660_remove(struct i2c_client *client) ...@@ -481,8 +428,6 @@ static int __devexit max8660_remove(struct i2c_client *client)
for (i = 0; i < MAX8660_V_END; i++) for (i = 0; i < MAX8660_V_END; i++)
if (max8660->rdev[i]) if (max8660->rdev[i])
regulator_unregister(max8660->rdev[i]); regulator_unregister(max8660->rdev[i]);
kfree(max8660);
return 0; return 0;
} }
......
...@@ -38,50 +38,20 @@ struct max8925_regulator_info { ...@@ -38,50 +38,20 @@ struct max8925_regulator_info {
struct i2c_client *i2c; struct i2c_client *i2c;
struct max8925_chip *chip; struct max8925_chip *chip;
int min_uV;
int max_uV;
int step_uV;
int vol_reg; int vol_reg;
int vol_shift;
int vol_nbits;
int enable_reg; int enable_reg;
}; };
static inline int check_range(struct max8925_regulator_info *info, static int max8925_set_voltage_sel(struct regulator_dev *rdev,
int min_uV, int max_uV) unsigned int selector)
{
if (min_uV < info->min_uV || min_uV > info->max_uV)
return -EINVAL;
return 0;
}
static int max8925_list_voltage(struct regulator_dev *rdev, unsigned index)
{
struct max8925_regulator_info *info = rdev_get_drvdata(rdev);
return info->min_uV + index * info->step_uV;
}
static int max8925_set_voltage(struct regulator_dev *rdev,
int min_uV, int max_uV, unsigned int *selector)
{ {
struct max8925_regulator_info *info = rdev_get_drvdata(rdev); struct max8925_regulator_info *info = rdev_get_drvdata(rdev);
unsigned char data, mask; unsigned char mask = rdev->desc->n_voltages - 1;
if (check_range(info, min_uV, max_uV)) {
dev_err(info->chip->dev, "invalid voltage range (%d, %d) uV\n",
min_uV, max_uV);
return -EINVAL;
}
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;
return max8925_set_bits(info->i2c, info->vol_reg, mask, data); return max8925_set_bits(info->i2c, info->vol_reg, mask, selector);
} }
static int max8925_get_voltage(struct regulator_dev *rdev) static int max8925_get_voltage_sel(struct regulator_dev *rdev)
{ {
struct max8925_regulator_info *info = rdev_get_drvdata(rdev); struct max8925_regulator_info *info = rdev_get_drvdata(rdev);
unsigned char data, mask; unsigned char data, mask;
...@@ -90,10 +60,10 @@ static int max8925_get_voltage(struct regulator_dev *rdev) ...@@ -90,10 +60,10 @@ static int max8925_get_voltage(struct regulator_dev *rdev)
ret = max8925_reg_read(info->i2c, info->vol_reg); ret = max8925_reg_read(info->i2c, info->vol_reg);
if (ret < 0) if (ret < 0)
return ret; return ret;
mask = ((1 << info->vol_nbits) - 1) << info->vol_shift; mask = rdev->desc->n_voltages - 1;
data = (ret & mask) >> info->vol_shift; data = ret & mask;
return max8925_list_voltage(rdev, data); return data;
} }
static int max8925_enable(struct regulator_dev *rdev) static int max8925_enable(struct regulator_dev *rdev)
...@@ -163,8 +133,10 @@ static int max8925_set_dvm_disable(struct regulator_dev *rdev) ...@@ -163,8 +133,10 @@ static int max8925_set_dvm_disable(struct regulator_dev *rdev)
} }
static struct regulator_ops max8925_regulator_sdv_ops = { static struct regulator_ops max8925_regulator_sdv_ops = {
.set_voltage = max8925_set_voltage, .map_voltage = regulator_map_voltage_linear,
.get_voltage = max8925_get_voltage, .list_voltage = regulator_list_voltage_linear,
.set_voltage_sel = max8925_set_voltage_sel,
.get_voltage_sel = max8925_get_voltage_sel,
.enable = max8925_enable, .enable = max8925_enable,
.disable = max8925_disable, .disable = max8925_disable,
.is_enabled = max8925_is_enabled, .is_enabled = max8925_is_enabled,
...@@ -174,8 +146,10 @@ static struct regulator_ops max8925_regulator_sdv_ops = { ...@@ -174,8 +146,10 @@ static struct regulator_ops max8925_regulator_sdv_ops = {
}; };
static struct regulator_ops max8925_regulator_ldo_ops = { static struct regulator_ops max8925_regulator_ldo_ops = {
.set_voltage = max8925_set_voltage, .map_voltage = regulator_map_voltage_linear,
.get_voltage = max8925_get_voltage, .list_voltage = regulator_list_voltage_linear,
.set_voltage_sel = max8925_set_voltage_sel,
.get_voltage_sel = max8925_get_voltage_sel,
.enable = max8925_enable, .enable = max8925_enable,
.disable = max8925_disable, .disable = max8925_disable,
.is_enabled = max8925_is_enabled, .is_enabled = max8925_is_enabled,
...@@ -189,13 +163,11 @@ static struct regulator_ops max8925_regulator_ldo_ops = { ...@@ -189,13 +163,11 @@ static struct regulator_ops max8925_regulator_ldo_ops = {
.type = REGULATOR_VOLTAGE, \ .type = REGULATOR_VOLTAGE, \
.id = MAX8925_ID_SD##_id, \ .id = MAX8925_ID_SD##_id, \
.owner = THIS_MODULE, \ .owner = THIS_MODULE, \
.n_voltages = 64, \
.min_uV = min * 1000, \
.uV_step = step * 1000, \
}, \ }, \
.min_uV = min * 1000, \
.max_uV = max * 1000, \
.step_uV = step * 1000, \
.vol_reg = MAX8925_SDV##_id, \ .vol_reg = MAX8925_SDV##_id, \
.vol_shift = 0, \
.vol_nbits = 6, \
.enable_reg = MAX8925_SDCTL##_id, \ .enable_reg = MAX8925_SDCTL##_id, \
} }
...@@ -207,13 +179,11 @@ static struct regulator_ops max8925_regulator_ldo_ops = { ...@@ -207,13 +179,11 @@ static struct regulator_ops max8925_regulator_ldo_ops = {
.type = REGULATOR_VOLTAGE, \ .type = REGULATOR_VOLTAGE, \
.id = MAX8925_ID_LDO##_id, \ .id = MAX8925_ID_LDO##_id, \
.owner = THIS_MODULE, \ .owner = THIS_MODULE, \
.n_voltages = 64, \
.min_uV = min * 1000, \
.uV_step = step * 1000, \
}, \ }, \
.min_uV = min * 1000, \
.max_uV = max * 1000, \
.step_uV = step * 1000, \
.vol_reg = MAX8925_LDOVOUT##_id, \ .vol_reg = MAX8925_LDOVOUT##_id, \
.vol_shift = 0, \
.vol_nbits = 6, \
.enable_reg = MAX8925_LDOCTL##_id, \ .enable_reg = MAX8925_LDOCTL##_id, \
} }
...@@ -261,6 +231,7 @@ static int __devinit max8925_regulator_probe(struct platform_device *pdev) ...@@ -261,6 +231,7 @@ static int __devinit max8925_regulator_probe(struct platform_device *pdev)
{ {
struct max8925_chip *chip = dev_get_drvdata(pdev->dev.parent); struct max8925_chip *chip = dev_get_drvdata(pdev->dev.parent);
struct max8925_platform_data *pdata = chip->dev->platform_data; struct max8925_platform_data *pdata = chip->dev->platform_data;
struct regulator_config config = { };
struct max8925_regulator_info *ri; struct max8925_regulator_info *ri;
struct regulator_dev *rdev; struct regulator_dev *rdev;
...@@ -272,8 +243,11 @@ static int __devinit max8925_regulator_probe(struct platform_device *pdev) ...@@ -272,8 +243,11 @@ static int __devinit max8925_regulator_probe(struct platform_device *pdev)
ri->i2c = chip->i2c; ri->i2c = chip->i2c;
ri->chip = chip; ri->chip = chip;
rdev = regulator_register(&ri->desc, &pdev->dev, config.dev = &pdev->dev;
pdata->regulator[pdev->id], ri, NULL); config.init_data = pdata->regulator[pdev->id];
config.driver_data = ri;
rdev = regulator_register(&ri->desc, &config);
if (IS_ERR(rdev)) { if (IS_ERR(rdev)) {
dev_err(&pdev->dev, "failed to register regulator %s\n", dev_err(&pdev->dev, "failed to register regulator %s\n",
ri->desc.name); ri->desc.name);
...@@ -319,4 +293,3 @@ MODULE_LICENSE("GPL"); ...@@ -319,4 +293,3 @@ MODULE_LICENSE("GPL");
MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>"); MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
MODULE_DESCRIPTION("Regulator Driver for Maxim 8925 PMIC"); MODULE_DESCRIPTION("Regulator Driver for Maxim 8925 PMIC");
MODULE_ALIAS("platform:max8925-regulator"); MODULE_ALIAS("platform:max8925-regulator");
...@@ -69,11 +69,6 @@ static int max8952_write_reg(struct max8952_data *max8952, ...@@ -69,11 +69,6 @@ static int max8952_write_reg(struct max8952_data *max8952,
return i2c_smbus_write_byte_data(max8952->client, reg, value); return i2c_smbus_write_byte_data(max8952->client, reg, value);
} }
static int max8952_voltage(struct max8952_data *max8952, u8 mode)
{
return (max8952->pdata->dvs_mode[mode] * 10 + 770) * 1000;
}
static int max8952_list_voltage(struct regulator_dev *rdev, static int max8952_list_voltage(struct regulator_dev *rdev,
unsigned int selector) unsigned int selector)
{ {
...@@ -82,7 +77,7 @@ static int max8952_list_voltage(struct regulator_dev *rdev, ...@@ -82,7 +77,7 @@ static int max8952_list_voltage(struct regulator_dev *rdev,
if (rdev_get_id(rdev) != 0) if (rdev_get_id(rdev) != 0)
return -EINVAL; return -EINVAL;
return max8952_voltage(max8952, selector); return (max8952->pdata->dvs_mode[selector] * 10 + 770) * 1000;
} }
static int max8952_is_enabled(struct regulator_dev *rdev) static int max8952_is_enabled(struct regulator_dev *rdev)
...@@ -117,7 +112,7 @@ static int max8952_disable(struct regulator_dev *rdev) ...@@ -117,7 +112,7 @@ static int max8952_disable(struct regulator_dev *rdev)
return 0; return 0;
} }
static int max8952_get_voltage(struct regulator_dev *rdev) static int max8952_get_voltage_sel(struct regulator_dev *rdev)
{ {
struct max8952_data *max8952 = rdev_get_drvdata(rdev); struct max8952_data *max8952 = rdev_get_drvdata(rdev);
u8 vid = 0; u8 vid = 0;
...@@ -127,14 +122,13 @@ static int max8952_get_voltage(struct regulator_dev *rdev) ...@@ -127,14 +122,13 @@ static int max8952_get_voltage(struct regulator_dev *rdev)
if (max8952->vid1) if (max8952->vid1)
vid += 2; vid += 2;
return max8952_voltage(max8952, vid); return vid;
} }
static int max8952_set_voltage(struct regulator_dev *rdev, static int max8952_set_voltage_sel(struct regulator_dev *rdev,
int min_uV, int max_uV, unsigned *selector) unsigned selector)
{ {
struct max8952_data *max8952 = rdev_get_drvdata(rdev); struct max8952_data *max8952 = rdev_get_drvdata(rdev);
s8 vid = -1, i;
if (!gpio_is_valid(max8952->pdata->gpio_vid0) || if (!gpio_is_valid(max8952->pdata->gpio_vid0) ||
!gpio_is_valid(max8952->pdata->gpio_vid1)) { !gpio_is_valid(max8952->pdata->gpio_vid1)) {
...@@ -142,23 +136,10 @@ static int max8952_set_voltage(struct regulator_dev *rdev, ...@@ -142,23 +136,10 @@ static int max8952_set_voltage(struct regulator_dev *rdev,
return -EPERM; return -EPERM;
} }
for (i = 0; i < MAX8952_NUM_DVS_MODE; i++) { max8952->vid0 = selector & 0x1;
int volt = max8952_voltage(max8952, i); max8952->vid1 = (selector >> 1) & 0x1;
gpio_set_value(max8952->pdata->gpio_vid0, max8952->vid0);
/* Set the voltage as low as possible within the range */ gpio_set_value(max8952->pdata->gpio_vid1, max8952->vid1);
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;
return 0; return 0;
} }
...@@ -168,12 +149,12 @@ static struct regulator_ops max8952_ops = { ...@@ -168,12 +149,12 @@ static struct regulator_ops max8952_ops = {
.is_enabled = max8952_is_enabled, .is_enabled = max8952_is_enabled,
.enable = max8952_enable, .enable = max8952_enable,
.disable = max8952_disable, .disable = max8952_disable,
.get_voltage = max8952_get_voltage, .get_voltage_sel = max8952_get_voltage_sel,
.set_voltage = max8952_set_voltage, .set_voltage_sel = max8952_set_voltage_sel,
.set_suspend_disable = max8952_disable, .set_suspend_disable = max8952_disable,
}; };
static struct regulator_desc regulator = { static const struct regulator_desc regulator = {
.name = "MAX8952_VOUT", .name = "MAX8952_VOUT",
.id = 0, .id = 0,
.n_voltages = MAX8952_NUM_DVS_MODE, .n_voltages = MAX8952_NUM_DVS_MODE,
...@@ -187,6 +168,7 @@ static int __devinit max8952_pmic_probe(struct i2c_client *client, ...@@ -187,6 +168,7 @@ static int __devinit max8952_pmic_probe(struct i2c_client *client,
{ {
struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
struct max8952_platform_data *pdata = client->dev.platform_data; struct max8952_platform_data *pdata = client->dev.platform_data;
struct regulator_config config = { };
struct max8952_data *max8952; struct max8952_data *max8952;
int ret = 0, err = 0; int ret = 0, err = 0;
...@@ -199,7 +181,8 @@ static int __devinit max8952_pmic_probe(struct i2c_client *client, ...@@ -199,7 +181,8 @@ static int __devinit max8952_pmic_probe(struct i2c_client *client,
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE)) if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE))
return -EIO; return -EIO;
max8952 = kzalloc(sizeof(struct max8952_data), GFP_KERNEL); max8952 = devm_kzalloc(&client->dev, sizeof(struct max8952_data),
GFP_KERNEL);
if (!max8952) if (!max8952)
return -ENOMEM; return -ENOMEM;
...@@ -207,18 +190,21 @@ static int __devinit max8952_pmic_probe(struct i2c_client *client, ...@@ -207,18 +190,21 @@ static int __devinit max8952_pmic_probe(struct i2c_client *client,
max8952->dev = &client->dev; max8952->dev = &client->dev;
max8952->pdata = pdata; max8952->pdata = pdata;
max8952->rdev = regulator_register(&regulator, max8952->dev, config.dev = max8952->dev;
&pdata->reg_data, max8952, NULL); config.init_data = &pdata->reg_data;
config.driver_data = max8952;
max8952->rdev = regulator_register(&regulator, &config);
if (IS_ERR(max8952->rdev)) { if (IS_ERR(max8952->rdev)) {
ret = PTR_ERR(max8952->rdev); ret = PTR_ERR(max8952->rdev);
dev_err(max8952->dev, "regulator init failed (%d)\n", ret); dev_err(max8952->dev, "regulator init failed (%d)\n", ret);
goto err_reg; return ret;
} }
max8952->en = !!(pdata->reg_data.constraints.boot_on); max8952->en = !!(pdata->reg_data.constraints.boot_on);
max8952->vid0 = (pdata->default_mode % 2) == 1; max8952->vid0 = pdata->default_mode & 0x1;
max8952->vid1 = ((pdata->default_mode >> 1) % 2) == 1; max8952->vid1 = (pdata->default_mode >> 1) & 0x1;
if (gpio_is_valid(pdata->gpio_en)) { if (gpio_is_valid(pdata->gpio_en)) {
if (!gpio_request(pdata->gpio_en, "MAX8952 EN")) if (!gpio_request(pdata->gpio_en, "MAX8952 EN"))
...@@ -241,13 +227,13 @@ static int __devinit max8952_pmic_probe(struct i2c_client *client, ...@@ -241,13 +227,13 @@ static int __devinit max8952_pmic_probe(struct i2c_client *client,
gpio_is_valid(pdata->gpio_vid1)) { gpio_is_valid(pdata->gpio_vid1)) {
if (!gpio_request(pdata->gpio_vid0, "MAX8952 VID0")) if (!gpio_request(pdata->gpio_vid0, "MAX8952 VID0"))
gpio_direction_output(pdata->gpio_vid0, gpio_direction_output(pdata->gpio_vid0,
(pdata->default_mode) % 2); (pdata->default_mode) & 0x1);
else else
err = 1; err = 1;
if (!gpio_request(pdata->gpio_vid1, "MAX8952 VID1")) if (!gpio_request(pdata->gpio_vid1, "MAX8952 VID1"))
gpio_direction_output(pdata->gpio_vid1, gpio_direction_output(pdata->gpio_vid1,
(pdata->default_mode >> 1) % 2); (pdata->default_mode >> 1) & 0x1);
else { else {
if (!err) if (!err)
gpio_free(pdata->gpio_vid0); gpio_free(pdata->gpio_vid0);
...@@ -310,10 +296,6 @@ static int __devinit max8952_pmic_probe(struct i2c_client *client, ...@@ -310,10 +296,6 @@ static int __devinit max8952_pmic_probe(struct i2c_client *client,
i2c_set_clientdata(client, max8952); i2c_set_clientdata(client, max8952);
return 0; return 0;
err_reg:
kfree(max8952);
return ret;
} }
static int __devexit max8952_pmic_remove(struct i2c_client *client) static int __devexit max8952_pmic_remove(struct i2c_client *client)
...@@ -327,8 +309,6 @@ static int __devexit max8952_pmic_remove(struct i2c_client *client) ...@@ -327,8 +309,6 @@ static int __devexit max8952_pmic_remove(struct i2c_client *client)
gpio_free(pdata->gpio_vid0); gpio_free(pdata->gpio_vid0);
gpio_free(pdata->gpio_vid1); gpio_free(pdata->gpio_vid1);
gpio_free(pdata->gpio_en); gpio_free(pdata->gpio_en);
kfree(max8952);
return 0; return 0;
} }
......
This diff is collapsed.
...@@ -28,7 +28,6 @@ ...@@ -28,7 +28,6 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/mutex.h> #include <linux/mutex.h>
#include <linux/delay.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/regulator/driver.h> #include <linux/regulator/driver.h>
#include <linux/mfd/max8998.h> #include <linux/mfd/max8998.h>
...@@ -277,7 +276,7 @@ static int max8998_get_voltage_register(struct regulator_dev *rdev, ...@@ -277,7 +276,7 @@ static int max8998_get_voltage_register(struct regulator_dev *rdev,
return 0; 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 max8998_data *max8998 = rdev_get_drvdata(rdev);
struct i2c_client *i2c = max8998->iodev->i2c; struct i2c_client *i2c = max8998->iodev->i2c;
...@@ -295,7 +294,7 @@ static int max8998_get_voltage(struct regulator_dev *rdev) ...@@ -295,7 +294,7 @@ static int max8998_get_voltage(struct regulator_dev *rdev)
val >>= shift; val >>= shift;
val &= mask; val &= mask;
return max8998_list_voltage(rdev, val); return val;
} }
static int max8998_set_voltage_ldo(struct regulator_dev *rdev, static int max8998_set_voltage_ldo(struct regulator_dev *rdev,
...@@ -306,8 +305,7 @@ static int max8998_set_voltage_ldo(struct regulator_dev *rdev, ...@@ -306,8 +305,7 @@ static int max8998_set_voltage_ldo(struct regulator_dev *rdev,
int min_vol = min_uV / 1000, max_vol = max_uV / 1000; int min_vol = min_uV / 1000, max_vol = max_uV / 1000;
const struct voltage_map_desc *desc; const struct voltage_map_desc *desc;
int ldo = rdev_get_id(rdev); int ldo = rdev_get_id(rdev);
int reg, shift = 0, mask, ret; int reg, shift = 0, mask, ret, i;
int i = 0;
if (ldo >= ARRAY_SIZE(ldo_voltage_map)) if (ldo >= ARRAY_SIZE(ldo_voltage_map))
return -EINVAL; return -EINVAL;
...@@ -319,9 +317,10 @@ static int max8998_set_voltage_ldo(struct regulator_dev *rdev, ...@@ -319,9 +317,10 @@ static int max8998_set_voltage_ldo(struct regulator_dev *rdev,
if (max_vol < desc->min || min_vol > desc->max) if (max_vol < desc->min || min_vol > desc->max)
return -EINVAL; return -EINVAL;
while (desc->min + desc->step*i < min_vol && if (min_vol < desc->min)
desc->min + desc->step*i < desc->max) min_vol = desc->min;
i++;
i = DIV_ROUND_UP(min_vol - desc->min, desc->step);
if (desc->min + desc->step*i > max_vol) if (desc->min + desc->step*i > max_vol)
return -EINVAL; return -EINVAL;
...@@ -359,8 +358,7 @@ static int max8998_set_voltage_buck(struct regulator_dev *rdev, ...@@ -359,8 +358,7 @@ static int max8998_set_voltage_buck(struct regulator_dev *rdev,
const struct voltage_map_desc *desc; const struct voltage_map_desc *desc;
int buck = rdev_get_id(rdev); int buck = rdev_get_id(rdev);
int reg, shift = 0, mask, ret; int reg, shift = 0, mask, ret;
int difference = 0, i = 0, j = 0, previous_vol = 0; int i, j, previous_sel;
u8 val = 0;
static u8 buck1_last_val; static u8 buck1_last_val;
if (buck >= ARRAY_SIZE(ldo_voltage_map)) if (buck >= ARRAY_SIZE(ldo_voltage_map))
...@@ -374,9 +372,10 @@ static int max8998_set_voltage_buck(struct regulator_dev *rdev, ...@@ -374,9 +372,10 @@ static int max8998_set_voltage_buck(struct regulator_dev *rdev,
if (max_vol < desc->min || min_vol > desc->max) if (max_vol < desc->min || min_vol > desc->max)
return -EINVAL; return -EINVAL;
while (desc->min + desc->step*i < min_vol && if (min_vol < desc->min)
desc->min + desc->step*i < desc->max) min_vol = desc->min;
i++;
i = DIV_ROUND_UP(min_vol - desc->min, desc->step);
if (desc->min + desc->step*i > max_vol) if (desc->min + desc->step*i > max_vol)
return -EINVAL; return -EINVAL;
...@@ -387,13 +386,14 @@ static int max8998_set_voltage_buck(struct regulator_dev *rdev, ...@@ -387,13 +386,14 @@ static int max8998_set_voltage_buck(struct regulator_dev *rdev,
if (ret) if (ret)
return ret; return ret;
previous_vol = max8998_get_voltage(rdev); previous_sel = max8998_get_voltage_sel(rdev);
/* Check if voltage needs to be changed */ /* Check if voltage needs to be changed */
/* if previous_voltage equal new voltage, return */ /* 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", 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; return ret;
} }
...@@ -482,19 +482,40 @@ static int max8998_set_voltage_buck(struct regulator_dev *rdev, ...@@ -482,19 +482,40 @@ static int max8998_set_voltage_buck(struct regulator_dev *rdev,
break; 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 */ /* 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 */ /* lp3974 hasn't got ENRAMP bit - ramp is assumed as true */
/* MAX8998 has ENRAMP bit implemented, so test it*/ /* MAX8998 has ENRAMP bit implemented, so test it*/
if (max8998->iodev->type == TYPE_MAX8998 && !(val & MAX8998_ENRAMP)) 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) if (difference > 0)
udelay(difference / ((val & 0x0f) + 1)); return difference / ((val & 0x0f) + 1);
return ret; return 0;
} }
static struct regulator_ops max8998_ldo_ops = { static struct regulator_ops max8998_ldo_ops = {
...@@ -502,7 +523,7 @@ static struct regulator_ops max8998_ldo_ops = { ...@@ -502,7 +523,7 @@ static struct regulator_ops max8998_ldo_ops = {
.is_enabled = max8998_ldo_is_enabled, .is_enabled = max8998_ldo_is_enabled,
.enable = max8998_ldo_enable, .enable = max8998_ldo_enable,
.disable = max8998_ldo_disable, .disable = max8998_ldo_disable,
.get_voltage = max8998_get_voltage, .get_voltage_sel = max8998_get_voltage_sel,
.set_voltage = max8998_set_voltage_ldo, .set_voltage = max8998_set_voltage_ldo,
.set_suspend_enable = max8998_ldo_enable, .set_suspend_enable = max8998_ldo_enable,
.set_suspend_disable = max8998_ldo_disable, .set_suspend_disable = max8998_ldo_disable,
...@@ -513,8 +534,9 @@ static struct regulator_ops max8998_buck_ops = { ...@@ -513,8 +534,9 @@ static struct regulator_ops max8998_buck_ops = {
.is_enabled = max8998_ldo_is_enabled, .is_enabled = max8998_ldo_is_enabled,
.enable = max8998_ldo_enable, .enable = max8998_ldo_enable,
.disable = max8998_ldo_disable, .disable = max8998_ldo_disable,
.get_voltage = max8998_get_voltage, .get_voltage_sel = max8998_get_voltage_sel,
.set_voltage = max8998_set_voltage_buck, .set_voltage = max8998_set_voltage_buck,
.set_voltage_time_sel = max8998_set_voltage_buck_time_sel,
.set_suspend_enable = max8998_ldo_enable, .set_suspend_enable = max8998_ldo_enable,
.set_suspend_disable = max8998_ldo_disable, .set_suspend_disable = max8998_ldo_disable,
}; };
...@@ -685,6 +707,7 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev) ...@@ -685,6 +707,7 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev)
{ {
struct max8998_dev *iodev = dev_get_drvdata(pdev->dev.parent); struct max8998_dev *iodev = dev_get_drvdata(pdev->dev.parent);
struct max8998_platform_data *pdata = dev_get_platdata(iodev->dev); struct max8998_platform_data *pdata = dev_get_platdata(iodev->dev);
struct regulator_config config = { };
struct regulator_dev **rdev; struct regulator_dev **rdev;
struct max8998_data *max8998; struct max8998_data *max8998;
struct i2c_client *i2c; struct i2c_client *i2c;
...@@ -695,16 +718,15 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev) ...@@ -695,16 +718,15 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev)
return -ENODEV; return -ENODEV;
} }
max8998 = kzalloc(sizeof(struct max8998_data), GFP_KERNEL); max8998 = devm_kzalloc(&pdev->dev, sizeof(struct max8998_data),
GFP_KERNEL);
if (!max8998) if (!max8998)
return -ENOMEM; return -ENOMEM;
size = sizeof(struct regulator_dev *) * pdata->num_regulators; size = sizeof(struct regulator_dev *) * pdata->num_regulators;
max8998->rdev = kzalloc(size, GFP_KERNEL); max8998->rdev = devm_kzalloc(&pdev->dev, size, GFP_KERNEL);
if (!max8998->rdev) { if (!max8998->rdev)
kfree(max8998);
return -ENOMEM; return -ENOMEM;
}
rdev = max8998->rdev; rdev = max8998->rdev;
max8998->dev = &pdev->dev; max8998->dev = &pdev->dev;
...@@ -728,14 +750,14 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev) ...@@ -728,14 +750,14 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev)
printk(KERN_ERR "MAX8998 SET1 GPIO defined as 0 !\n"); printk(KERN_ERR "MAX8998 SET1 GPIO defined as 0 !\n");
WARN_ON(!pdata->buck1_set1); WARN_ON(!pdata->buck1_set1);
ret = -EIO; ret = -EIO;
goto err_free_mem; goto err_out;
} }
/* Check if SET2 is not equal to 0 */ /* Check if SET2 is not equal to 0 */
if (!pdata->buck1_set2) { if (!pdata->buck1_set2) {
printk(KERN_ERR "MAX8998 SET2 GPIO defined as 0 !\n"); printk(KERN_ERR "MAX8998 SET2 GPIO defined as 0 !\n");
WARN_ON(!pdata->buck1_set2); WARN_ON(!pdata->buck1_set2);
ret = -EIO; ret = -EIO;
goto err_free_mem; goto err_out;
} }
gpio_request(pdata->buck1_set1, "MAX8998 BUCK1_SET1"); gpio_request(pdata->buck1_set1, "MAX8998 BUCK1_SET1");
...@@ -755,7 +777,7 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev) ...@@ -755,7 +777,7 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev)
max8998->buck1_vol[0] = i; max8998->buck1_vol[0] = i;
ret = max8998_write_reg(i2c, MAX8998_REG_BUCK1_VOLTAGE1, i); ret = max8998_write_reg(i2c, MAX8998_REG_BUCK1_VOLTAGE1, i);
if (ret) if (ret)
goto err_free_mem; goto err_out;
/* Set predefined value for BUCK1 register 2 */ /* Set predefined value for BUCK1 register 2 */
i = 0; i = 0;
...@@ -767,7 +789,7 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev) ...@@ -767,7 +789,7 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev)
max8998->buck1_vol[1] = i; max8998->buck1_vol[1] = i;
ret = max8998_write_reg(i2c, MAX8998_REG_BUCK1_VOLTAGE2, i); ret = max8998_write_reg(i2c, MAX8998_REG_BUCK1_VOLTAGE2, i);
if (ret) if (ret)
goto err_free_mem; goto err_out;
/* Set predefined value for BUCK1 register 3 */ /* Set predefined value for BUCK1 register 3 */
i = 0; i = 0;
...@@ -779,7 +801,7 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev) ...@@ -779,7 +801,7 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev)
max8998->buck1_vol[2] = i; max8998->buck1_vol[2] = i;
ret = max8998_write_reg(i2c, MAX8998_REG_BUCK1_VOLTAGE3, i); ret = max8998_write_reg(i2c, MAX8998_REG_BUCK1_VOLTAGE3, i);
if (ret) if (ret)
goto err_free_mem; goto err_out;
/* Set predefined value for BUCK1 register 4 */ /* Set predefined value for BUCK1 register 4 */
i = 0; i = 0;
...@@ -791,7 +813,7 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev) ...@@ -791,7 +813,7 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev)
max8998->buck1_vol[3] = i; max8998->buck1_vol[3] = i;
ret = max8998_write_reg(i2c, MAX8998_REG_BUCK1_VOLTAGE4, i); ret = max8998_write_reg(i2c, MAX8998_REG_BUCK1_VOLTAGE4, i);
if (ret) if (ret)
goto err_free_mem; goto err_out;
} }
...@@ -801,7 +823,7 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev) ...@@ -801,7 +823,7 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev)
printk(KERN_ERR "MAX8998 SET3 GPIO defined as 0 !\n"); printk(KERN_ERR "MAX8998 SET3 GPIO defined as 0 !\n");
WARN_ON(!pdata->buck2_set3); WARN_ON(!pdata->buck2_set3);
ret = -EIO; ret = -EIO;
goto err_free_mem; goto err_out;
} }
gpio_request(pdata->buck2_set3, "MAX8998 BUCK2_SET3"); gpio_request(pdata->buck2_set3, "MAX8998 BUCK2_SET3");
gpio_direction_output(pdata->buck2_set3, gpio_direction_output(pdata->buck2_set3,
...@@ -816,7 +838,7 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev) ...@@ -816,7 +838,7 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev)
max8998->buck2_vol[0] = i; max8998->buck2_vol[0] = i;
ret = max8998_write_reg(i2c, MAX8998_REG_BUCK2_VOLTAGE1, i); ret = max8998_write_reg(i2c, MAX8998_REG_BUCK2_VOLTAGE1, i);
if (ret) if (ret)
goto err_free_mem; goto err_out;
/* BUCK2 register 2 */ /* BUCK2 register 2 */
i = 0; i = 0;
...@@ -827,7 +849,7 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev) ...@@ -827,7 +849,7 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev)
max8998->buck2_vol[1] = i; max8998->buck2_vol[1] = i;
ret = max8998_write_reg(i2c, MAX8998_REG_BUCK2_VOLTAGE2, i); ret = max8998_write_reg(i2c, MAX8998_REG_BUCK2_VOLTAGE2, i);
if (ret) if (ret)
goto err_free_mem; goto err_out;
} }
for (i = 0; i < pdata->num_regulators; i++) { for (i = 0; i < pdata->num_regulators; i++) {
...@@ -840,8 +862,12 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev) ...@@ -840,8 +862,12 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev)
int count = (desc->max - desc->min) / desc->step + 1; int count = (desc->max - desc->min) / desc->step + 1;
regulators[index].n_voltages = count; 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])) { if (IS_ERR(rdev[i])) {
ret = PTR_ERR(rdev[i]); ret = PTR_ERR(rdev[i]);
dev_err(max8998->dev, "regulator init failed\n"); dev_err(max8998->dev, "regulator init failed\n");
...@@ -853,14 +879,9 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev) ...@@ -853,14 +879,9 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev)
return 0; return 0;
err: err:
for (i = 0; i < max8998->num_regulators; i++) while (--i >= 0)
if (rdev[i]) regulator_unregister(rdev[i]);
regulator_unregister(rdev[i]); err_out:
err_free_mem:
kfree(max8998->rdev);
kfree(max8998);
return ret; return ret;
} }
...@@ -871,12 +892,7 @@ static int __devexit max8998_pmic_remove(struct platform_device *pdev) ...@@ -871,12 +892,7 @@ static int __devexit max8998_pmic_remove(struct platform_device *pdev)
int i; int i;
for (i = 0; i < max8998->num_regulators; i++) for (i = 0; i < max8998->num_regulators; i++)
if (rdev[i]) regulator_unregister(rdev[i]);
regulator_unregister(rdev[i]);
kfree(max8998->rdev);
kfree(max8998);
return 0; return 0;
} }
......
...@@ -340,6 +340,7 @@ static int __devinit mc13783_regulator_probe(struct platform_device *pdev) ...@@ -340,6 +340,7 @@ static int __devinit mc13783_regulator_probe(struct platform_device *pdev)
struct mc13xxx_regulator_platform_data *pdata = struct mc13xxx_regulator_platform_data *pdata =
dev_get_platdata(&pdev->dev); dev_get_platdata(&pdev->dev);
struct mc13xxx_regulator_init_data *init_data; struct mc13xxx_regulator_init_data *init_data;
struct regulator_config config = { };
int i, ret; int i, ret;
dev_dbg(&pdev->dev, "%s id %d\n", __func__, pdev->id); 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) ...@@ -357,11 +358,16 @@ static int __devinit mc13783_regulator_probe(struct platform_device *pdev)
priv->mc13xxx = mc13783; priv->mc13xxx = mc13783;
for (i = 0; i < pdata->num_regulators; i++) { for (i = 0; i < pdata->num_regulators; i++) {
struct regulator_desc *desc;
init_data = &pdata->regulators[i]; init_data = &pdata->regulators[i];
priv->regulators[i] = regulator_register( desc = &mc13783_regulators[init_data->id].desc;
&mc13783_regulators[init_data->id].desc,
&pdev->dev, init_data->init_data, priv, NULL); 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])) { if (IS_ERR(priv->regulators[i])) {
dev_err(&pdev->dev, "failed to register regulator %s\n", dev_err(&pdev->dev, "failed to register regulator %s\n",
mc13783_regulators[i].desc.name); mc13783_regulators[i].desc.name);
......
This diff is collapsed.
This diff is collapsed.
...@@ -35,8 +35,6 @@ struct mc13xxx_regulator_priv { ...@@ -35,8 +35,6 @@ struct mc13xxx_regulator_priv {
extern int mc13xxx_sw_regulator(struct regulator_dev *rdev); extern int mc13xxx_sw_regulator(struct regulator_dev *rdev);
extern int mc13xxx_sw_regulator_is_enabled(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, extern int mc13xxx_regulator_list_voltage(struct regulator_dev *rdev,
unsigned selector); unsigned selector);
extern int mc13xxx_fixed_regulator_set_voltage(struct regulator_dev *rdev, extern int mc13xxx_fixed_regulator_set_voltage(struct regulator_dev *rdev,
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -123,7 +123,7 @@ static struct regulator_ops tps6105x_regulator_ops = { ...@@ -123,7 +123,7 @@ static struct regulator_ops tps6105x_regulator_ops = {
.list_voltage = tps6105x_regulator_list_voltage, .list_voltage = tps6105x_regulator_list_voltage,
}; };
static struct regulator_desc tps6105x_regulator_desc = { static const struct regulator_desc tps6105x_regulator_desc = {
.name = "tps6105x-boost", .name = "tps6105x-boost",
.ops = &tps6105x_regulator_ops, .ops = &tps6105x_regulator_ops,
.type = REGULATOR_VOLTAGE, .type = REGULATOR_VOLTAGE,
...@@ -139,6 +139,7 @@ static int __devinit tps6105x_regulator_probe(struct platform_device *pdev) ...@@ -139,6 +139,7 @@ static int __devinit tps6105x_regulator_probe(struct platform_device *pdev)
{ {
struct tps6105x *tps6105x = dev_get_platdata(&pdev->dev); struct tps6105x *tps6105x = dev_get_platdata(&pdev->dev);
struct tps6105x_platform_data *pdata = tps6105x->pdata; struct tps6105x_platform_data *pdata = tps6105x->pdata;
struct regulator_config config = { };
int ret; int ret;
/* This instance is not set for regulator mode so bail out */ /* 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) ...@@ -148,11 +149,13 @@ static int __devinit tps6105x_regulator_probe(struct platform_device *pdev)
return 0; return 0;
} }
config.dev = &tps6105x->client->dev;
config.init_data = pdata->regulator_data;
config.driver_data = tps6105x;
/* Register regulator with framework */ /* Register regulator with framework */
tps6105x->regulator = regulator_register(&tps6105x_regulator_desc, tps6105x->regulator = regulator_register(&tps6105x_regulator_desc,
&tps6105x->client->dev, &config);
pdata->regulator_data, tps6105x,
NULL);
if (IS_ERR(tps6105x->regulator)) { if (IS_ERR(tps6105x->regulator)) {
ret = PTR_ERR(tps6105x->regulator); ret = PTR_ERR(tps6105x->regulator);
dev_err(&tps6105x->client->dev, dev_err(&tps6105x->client->dev,
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -335,6 +335,7 @@ extern int s5m_reg_update(struct s5m87xx_dev *s5m87xx, u8 reg, u8 val, u8 mask); ...@@ -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_platform_data {
struct s5m_regulator_data *regulators; struct s5m_regulator_data *regulators;
struct s5m_opmode_data *opmode;
int device_type; int device_type;
int num_regulators; int num_regulators;
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment