Merge remote-tracking branch 'regulator/topic/drivers' into regulator-next

Conflicts:
	drivers/regulator/88pm8607.c (simple overlap with a bugfix in v3.4)
This commit is contained in:
Mark Brown
2012-05-12 11:10:25 +01:00
33 changed files with 559 additions and 304 deletions
@@ -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:
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;
}; };
@@ -0,0 +1,97 @@
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>;
};
};
};
+86
View File
@@ -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,
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 @@ failed:
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,
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 = {
.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),
-7
View File
@@ -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? */
-1
View File
@@ -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>
-1
View File
@@ -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>
+2 -1
View File
@@ -20,6 +20,7 @@
#include <linux/regulator/driver.h> #include <linux/regulator/driver.h>
#include <linux/regulator/machine.h> #include <linux/regulator/machine.h>
#ifdef CONFIG_OF #ifdef CONFIG_OF
#include <linux/of.h>
#include <linux/regulator/of_regulator.h> #include <linux/regulator/of_regulator.h>
#endif #endif
@@ -393,7 +394,7 @@ static int __devinit da9052_regulator_probe(struct platform_device *pdev)
if (!nproot) if (!nproot)
return -ENODEV; return -ENODEV;
for (np = of_get_next_child(nproot, NULL); !np; for (np = of_get_next_child(nproot, NULL); np;
np = of_get_next_child(nproot, np)) { np = of_get_next_child(nproot, np)) {
if (!of_node_cmp(np->name, if (!of_node_cmp(np->name,
regulator->info->reg_desc.name)) { regulator->info->reg_desc.name)) {
+3 -1
View File
@@ -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)
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;
} }
-1
View File
@@ -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 {
-1
View File
@@ -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
+1 -1
View File
@@ -370,7 +370,7 @@ static int __devinit max8660_probe(struct i2c_client *client,
return -EINVAL; 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)
+4 -9
View File
@@ -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,
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)
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,7 +122,7 @@ 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_sel(struct regulator_dev *rdev, static int max8952_set_voltage_sel(struct regulator_dev *rdev,
@@ -154,7 +149,7 @@ 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_sel = max8952_set_voltage_sel, .set_voltage_sel = max8952_set_voltage_sel,
.set_suspend_disable = max8952_disable, .set_suspend_disable = max8952_disable,
}; };
+88 -71
View File
@@ -22,7 +22,6 @@
*/ */
#include <linux/bug.h> #include <linux/bug.h>
#include <linux/delay.h>
#include <linux/err.h> #include <linux/err.h>
#include <linux/gpio.h> #include <linux/gpio.h>
#include <linux/slab.h> #include <linux/slab.h>
@@ -278,9 +277,7 @@ static int max8997_reg_is_enabled(struct regulator_dev *rdev)
u8 val; u8 val;
ret = max8997_get_enable_register(rdev, &reg, &mask, &pattern); ret = max8997_get_enable_register(rdev, &reg, &mask, &pattern);
if (ret == -EINVAL) if (ret)
return 1; /* "not controllable" */
else if (ret)
return ret; return ret;
ret = max8997_read_reg(i2c, reg, &val); ret = max8997_read_reg(i2c, reg, &val);
@@ -382,7 +379,7 @@ static int max8997_get_voltage_register(struct regulator_dev *rdev,
return 0; return 0;
} }
static int max8997_get_voltage(struct regulator_dev *rdev) static int max8997_get_voltage_sel(struct regulator_dev *rdev)
{ {
struct max8997_data *max8997 = rdev_get_drvdata(rdev); struct max8997_data *max8997 = rdev_get_drvdata(rdev);
struct i2c_client *i2c = max8997->iodev->i2c; struct i2c_client *i2c = max8997->iodev->i2c;
@@ -400,15 +397,7 @@ static int max8997_get_voltage(struct regulator_dev *rdev)
val >>= shift; val >>= shift;
val &= mask; val &= mask;
if (rdev->desc && rdev->desc->ops && rdev->desc->ops->list_voltage) return val;
return rdev->desc->ops->list_voltage(rdev, val);
/*
* max8997_list_voltage returns value for any rdev with voltage_map,
* which works for "CHARGER" and "CHARGER TOPOFF" that do not have
* list_voltage ops (they are current regulators).
*/
return max8997_list_voltage(rdev, val);
} }
static inline int max8997_get_voltage_proper_val( static inline int max8997_get_voltage_proper_val(
@@ -497,9 +486,7 @@ static int max8997_set_voltage_ldobuck(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 rid = rdev_get_id(rdev); int rid = rdev_get_id(rdev);
int reg, shift = 0, mask, ret; int i, reg, shift, mask, ret;
int i;
u8 org;
switch (rid) { switch (rid) {
case MAX8997_LDO1 ... MAX8997_LDO21: case MAX8997_LDO1 ... MAX8997_LDO21:
@@ -528,21 +515,50 @@ static int max8997_set_voltage_ldobuck(struct regulator_dev *rdev,
if (ret) if (ret)
return ret; return ret;
max8997_read_reg(i2c, reg, &org);
org = (org & mask) >> shift;
ret = max8997_update_reg(i2c, reg, i << shift, mask << shift); ret = max8997_update_reg(i2c, reg, i << shift, mask << shift);
*selector = i; *selector = i;
if (rid == MAX8997_BUCK1 || rid == MAX8997_BUCK2 || return ret;
rid == MAX8997_BUCK4 || rid == MAX8997_BUCK5) {
/* If the voltage is increasing */
if (org < i)
udelay(DIV_ROUND_UP(desc->step * (i - org),
max8997->ramp_delay));
} }
return ret; static int max8997_set_voltage_ldobuck_time_sel(struct regulator_dev *rdev,
unsigned int old_selector,
unsigned int new_selector)
{
struct max8997_data *max8997 = rdev_get_drvdata(rdev);
int rid = rdev_get_id(rdev);
const struct voltage_map_desc *desc = reg_voltage_map[rid];
/* Delay is required only if the voltage is increasing */
if (old_selector >= new_selector)
return 0;
/* No need to delay if gpio_dvs_mode */
switch (rid) {
case MAX8997_BUCK1:
if (max8997->buck1_gpiodvs)
return 0;
break;
case MAX8997_BUCK2:
if (max8997->buck2_gpiodvs)
return 0;
break;
case MAX8997_BUCK5:
if (max8997->buck5_gpiodvs)
return 0;
break;
}
switch (rid) {
case MAX8997_BUCK1:
case MAX8997_BUCK2:
case MAX8997_BUCK4:
case MAX8997_BUCK5:
return DIV_ROUND_UP(desc->step * (new_selector - old_selector),
max8997->ramp_delay);
}
return 0;
} }
/* /*
@@ -749,11 +765,6 @@ static int max8997_set_voltage_safeout(struct regulator_dev *rdev,
return ret; return ret;
} }
static int max8997_reg_enable_suspend(struct regulator_dev *rdev)
{
return 0;
}
static int max8997_reg_disable_suspend(struct regulator_dev *rdev) static int max8997_reg_disable_suspend(struct regulator_dev *rdev)
{ {
struct max8997_data *max8997 = rdev_get_drvdata(rdev); struct max8997_data *max8997 = rdev_get_drvdata(rdev);
@@ -786,9 +797,9 @@ static struct regulator_ops max8997_ldo_ops = {
.is_enabled = max8997_reg_is_enabled, .is_enabled = max8997_reg_is_enabled,
.enable = max8997_reg_enable, .enable = max8997_reg_enable,
.disable = max8997_reg_disable, .disable = max8997_reg_disable,
.get_voltage = max8997_get_voltage, .get_voltage_sel = max8997_get_voltage_sel,
.set_voltage = max8997_set_voltage_ldobuck, .set_voltage = max8997_set_voltage_ldobuck,
.set_suspend_enable = max8997_reg_enable_suspend, .set_voltage_time_sel = max8997_set_voltage_ldobuck_time_sel,
.set_suspend_disable = max8997_reg_disable_suspend, .set_suspend_disable = max8997_reg_disable_suspend,
}; };
@@ -797,9 +808,9 @@ static struct regulator_ops max8997_buck_ops = {
.is_enabled = max8997_reg_is_enabled, .is_enabled = max8997_reg_is_enabled,
.enable = max8997_reg_enable, .enable = max8997_reg_enable,
.disable = max8997_reg_disable, .disable = max8997_reg_disable,
.get_voltage = max8997_get_voltage, .get_voltage_sel = max8997_get_voltage_sel,
.set_voltage = max8997_set_voltage_buck, .set_voltage = max8997_set_voltage_buck,
.set_suspend_enable = max8997_reg_enable_suspend, .set_voltage_time_sel = max8997_set_voltage_ldobuck_time_sel,
.set_suspend_disable = max8997_reg_disable_suspend, .set_suspend_disable = max8997_reg_disable_suspend,
}; };
@@ -808,7 +819,6 @@ static struct regulator_ops max8997_fixedvolt_ops = {
.is_enabled = max8997_reg_is_enabled, .is_enabled = max8997_reg_is_enabled,
.enable = max8997_reg_enable, .enable = max8997_reg_enable,
.disable = max8997_reg_disable, .disable = max8997_reg_disable,
.set_suspend_enable = max8997_reg_enable_suspend,
.set_suspend_disable = max8997_reg_disable_suspend, .set_suspend_disable = max8997_reg_disable_suspend,
}; };
@@ -817,39 +827,56 @@ static struct regulator_ops max8997_safeout_ops = {
.is_enabled = max8997_reg_is_enabled, .is_enabled = max8997_reg_is_enabled,
.enable = max8997_reg_enable, .enable = max8997_reg_enable,
.disable = max8997_reg_disable, .disable = max8997_reg_disable,
.get_voltage = max8997_get_voltage, .get_voltage_sel = max8997_get_voltage_sel,
.set_voltage = max8997_set_voltage_safeout, .set_voltage = max8997_set_voltage_safeout,
.set_suspend_enable = max8997_reg_enable_suspend,
.set_suspend_disable = max8997_reg_disable_suspend, .set_suspend_disable = max8997_reg_disable_suspend,
}; };
static struct regulator_ops max8997_fixedstate_ops = { static struct regulator_ops max8997_fixedstate_ops = {
.list_voltage = max8997_list_voltage_charger_cv, .list_voltage = max8997_list_voltage_charger_cv,
.get_voltage = max8997_get_voltage, .get_voltage_sel = max8997_get_voltage_sel,
.set_voltage = max8997_set_voltage_charger_cv, .set_voltage = max8997_set_voltage_charger_cv,
}; };
static int max8997_set_voltage_ldobuck_wrap(struct regulator_dev *rdev, static int max8997_set_current_limit(struct regulator_dev *rdev,
int min_uV, int max_uV) int min_uA, int max_uA)
{ {
unsigned dummy; unsigned dummy;
int rid = rdev_get_id(rdev);
return max8997_set_voltage_ldobuck(rdev, min_uV, max_uV, &dummy); if (rid != MAX8997_CHARGER && rid != MAX8997_CHARGER_TOPOFF)
return -EINVAL;
/* Reuse max8997_set_voltage_ldobuck to set current_limit. */
return max8997_set_voltage_ldobuck(rdev, min_uA, max_uA, &dummy);
} }
static int max8997_get_current_limit(struct regulator_dev *rdev)
{
int sel, rid = rdev_get_id(rdev);
if (rid != MAX8997_CHARGER && rid != MAX8997_CHARGER_TOPOFF)
return -EINVAL;
sel = max8997_get_voltage_sel(rdev);
if (sel < 0)
return sel;
/* Reuse max8997_list_voltage to get current_limit. */
return max8997_list_voltage(rdev, sel);
}
static struct regulator_ops max8997_charger_ops = { static struct regulator_ops max8997_charger_ops = {
.is_enabled = max8997_reg_is_enabled, .is_enabled = max8997_reg_is_enabled,
.enable = max8997_reg_enable, .enable = max8997_reg_enable,
.disable = max8997_reg_disable, .disable = max8997_reg_disable,
.get_current_limit = max8997_get_voltage, .get_current_limit = max8997_get_current_limit,
.set_current_limit = max8997_set_voltage_ldobuck_wrap, .set_current_limit = max8997_set_current_limit,
}; };
static struct regulator_ops max8997_charger_fixedstate_ops = { static struct regulator_ops max8997_charger_fixedstate_ops = {
.is_enabled = max8997_reg_is_enabled, .get_current_limit = max8997_get_current_limit,
.get_current_limit = max8997_get_voltage, .set_current_limit = max8997_set_current_limit,
.set_current_limit = max8997_set_voltage_ldobuck_wrap,
}; };
#define MAX8997_VOLTAGE_REGULATOR(_name, _ops) {\ #define MAX8997_VOLTAGE_REGULATOR(_name, _ops) {\
@@ -922,16 +949,15 @@ static __devinit int max8997_pmic_probe(struct platform_device *pdev)
return -ENODEV; return -ENODEV;
} }
max8997 = kzalloc(sizeof(struct max8997_data), GFP_KERNEL); max8997 = devm_kzalloc(&pdev->dev, sizeof(struct max8997_data),
GFP_KERNEL);
if (!max8997) if (!max8997)
return -ENOMEM; return -ENOMEM;
size = sizeof(struct regulator_dev *) * pdata->num_regulators; size = sizeof(struct regulator_dev *) * pdata->num_regulators;
max8997->rdev = kzalloc(size, GFP_KERNEL); max8997->rdev = devm_kzalloc(&pdev->dev, size, GFP_KERNEL);
if (!max8997->rdev) { if (!max8997->rdev)
kfree(max8997);
return -ENOMEM; return -ENOMEM;
}
rdev = max8997->rdev; rdev = max8997->rdev;
max8997->dev = &pdev->dev; max8997->dev = &pdev->dev;
@@ -955,7 +981,7 @@ static __devinit int max8997_pmic_probe(struct platform_device *pdev)
pdata->buck1_voltage[i] / 1000 + pdata->buck1_voltage[i] / 1000 +
buck1245_voltage_map_desc.step); buck1245_voltage_map_desc.step);
if (ret < 0) if (ret < 0)
goto err_alloc; goto err_out;
max8997->buck2_vol[i] = ret = max8997->buck2_vol[i] = ret =
max8997_get_voltage_proper_val( max8997_get_voltage_proper_val(
@@ -964,7 +990,7 @@ static __devinit int max8997_pmic_probe(struct platform_device *pdev)
pdata->buck2_voltage[i] / 1000 + pdata->buck2_voltage[i] / 1000 +
buck1245_voltage_map_desc.step); buck1245_voltage_map_desc.step);
if (ret < 0) if (ret < 0)
goto err_alloc; goto err_out;
max8997->buck5_vol[i] = ret = max8997->buck5_vol[i] = ret =
max8997_get_voltage_proper_val( max8997_get_voltage_proper_val(
@@ -973,7 +999,7 @@ static __devinit int max8997_pmic_probe(struct platform_device *pdev)
pdata->buck5_voltage[i] / 1000 + pdata->buck5_voltage[i] / 1000 +
buck1245_voltage_map_desc.step); buck1245_voltage_map_desc.step);
if (ret < 0) if (ret < 0)
goto err_alloc; goto err_out;
if (max_buck1 < max8997->buck1_vol[i]) if (max_buck1 < max8997->buck1_vol[i])
max_buck1 = max8997->buck1_vol[i]; max_buck1 = max8997->buck1_vol[i];
@@ -1006,7 +1032,7 @@ static __devinit int max8997_pmic_probe(struct platform_device *pdev)
!gpio_is_valid(pdata->buck125_gpios[2])) { !gpio_is_valid(pdata->buck125_gpios[2])) {
dev_err(&pdev->dev, "GPIO NOT VALID\n"); dev_err(&pdev->dev, "GPIO NOT VALID\n");
ret = -EINVAL; ret = -EINVAL;
goto err_alloc; goto err_out;
} }
ret = gpio_request(pdata->buck125_gpios[0], ret = gpio_request(pdata->buck125_gpios[0],
@@ -1015,7 +1041,7 @@ static __devinit int max8997_pmic_probe(struct platform_device *pdev)
dev_warn(&pdev->dev, "Duplicated gpio request" dev_warn(&pdev->dev, "Duplicated gpio request"
" on SET1\n"); " on SET1\n");
else if (ret) else if (ret)
goto err_alloc; goto err_out;
else else
gpio1set = true; gpio1set = true;
@@ -1027,7 +1053,7 @@ static __devinit int max8997_pmic_probe(struct platform_device *pdev)
else if (ret) { else if (ret) {
if (gpio1set) if (gpio1set)
gpio_free(pdata->buck125_gpios[0]); gpio_free(pdata->buck125_gpios[0]);
goto err_alloc; goto err_out;
} else } else
gpio2set = true; gpio2set = true;
@@ -1041,7 +1067,7 @@ static __devinit int max8997_pmic_probe(struct platform_device *pdev)
gpio_free(pdata->buck125_gpios[0]); gpio_free(pdata->buck125_gpios[0]);
if (gpio2set) if (gpio2set)
gpio_free(pdata->buck125_gpios[1]); gpio_free(pdata->buck125_gpios[1]);
goto err_alloc; goto err_out;
} }
gpio_direction_output(pdata->buck125_gpios[0], gpio_direction_output(pdata->buck125_gpios[0],
@@ -1110,13 +1136,9 @@ static __devinit int max8997_pmic_probe(struct platform_device *pdev)
return 0; return 0;
err: err:
for (i = 0; i < max8997->num_regulators; i++) while (--i >= 0)
if (rdev[i])
regulator_unregister(rdev[i]); regulator_unregister(rdev[i]);
err_alloc: err_out:
kfree(max8997->rdev);
kfree(max8997);
return ret; return ret;
} }
@@ -1127,12 +1149,7 @@ static int __devexit max8997_pmic_remove(struct platform_device *pdev)
int i; int i;
for (i = 0; i < max8997->num_regulators; i++) for (i = 0; i < max8997->num_regulators; i++)
if (rdev[i])
regulator_unregister(rdev[i]); regulator_unregister(rdev[i]);
kfree(max8997->rdev);
kfree(max8997);
return 0; return 0;
} }
+15 -27
View File
@@ -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>
@@ -719,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;
@@ -752,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");
@@ -779,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;
@@ -791,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;
@@ -803,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;
@@ -815,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;
} }
@@ -825,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,
@@ -840,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;
@@ -851,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++) {
@@ -881,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;
} }
@@ -899,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;
} }
+47
View File
@@ -14,6 +14,7 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/regulator/machine.h> #include <linux/regulator/machine.h>
#include <linux/regulator/of_regulator.h>
static void of_get_regulation_constraints(struct device_node *np, static void of_get_regulation_constraints(struct device_node *np,
struct regulator_init_data **init_data) struct regulator_init_data **init_data)
@@ -85,3 +86,49 @@ struct regulator_init_data *of_get_regulator_init_data(struct device *dev,
return init_data; return init_data;
} }
EXPORT_SYMBOL_GPL(of_get_regulator_init_data); EXPORT_SYMBOL_GPL(of_get_regulator_init_data);
/**
* of_regulator_match - extract regulator init data
* @dev: device requesting the data
* @node: parent device node of the regulators
* @matches: match table for the regulators
* @num_matches: number of entries in match table
*
* This function uses a match table specified by the regulator driver and
* looks up the corresponding init data in the device tree. Note that the
* match table is modified in place.
*
* Returns the number of matches found or a negative error code on failure.
*/
int of_regulator_match(struct device *dev, struct device_node *node,
struct of_regulator_match *matches,
unsigned int num_matches)
{
unsigned int count = 0;
unsigned int i;
if (!dev || !node)
return -EINVAL;
for (i = 0; i < num_matches; i++) {
struct of_regulator_match *match = &matches[i];
struct device_node *child;
child = of_find_node_by_name(node, match->name);
if (!child)
continue;
match->init_data = of_get_regulator_init_data(dev, child);
if (!match->init_data) {
dev_err(dev, "failed to parse DT for regulator %s\n",
child->name);
return -EINVAL;
}
match->of_node = child;
count++;
}
return count;
}
EXPORT_SYMBOL_GPL(of_regulator_match);
-1
View File
@@ -23,7 +23,6 @@
*/ */
#include <linux/module.h> #include <linux/module.h>
#include <linux/delay.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/err.h> #include <linux/err.h>
+4 -2
View File
@@ -12,7 +12,6 @@
*/ */
#include <linux/bug.h> #include <linux/bug.h>
#include <linux/delay.h>
#include <linux/err.h> #include <linux/err.h>
#include <linux/gpio.h> #include <linux/gpio.h>
#include <linux/slab.h> #include <linux/slab.h>
@@ -347,7 +346,10 @@ static int s5m8767_convert_voltage_to_sel(
if (max_vol < desc->min || min_vol > desc->max) if (max_vol < desc->min || min_vol > desc->max)
return -EINVAL; return -EINVAL;
selector = (min_vol - desc->min) / desc->step; if (min_vol < desc->min)
min_vol = desc->min;
selector = DIV_ROUND_UP(min_vol - desc->min, desc->step);
if (desc->min + desc->step * selector > max_vol) if (desc->min + desc->step * selector > max_vol)
return -EINVAL; return -EINVAL;
+97 -73
View File
@@ -32,7 +32,6 @@
#include <linux/regulator/tps62360.h> #include <linux/regulator/tps62360.h>
#include <linux/gpio.h> #include <linux/gpio.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/delay.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/regmap.h> #include <linux/regmap.h>
@@ -48,10 +47,10 @@
enum chips {TPS62360, TPS62361, TPS62362, TPS62363}; enum chips {TPS62360, TPS62361, TPS62362, TPS62363};
#define TPS62360_BASE_VOLTAGE 770 #define TPS62360_BASE_VOLTAGE 770000
#define TPS62360_N_VOLTAGES 64 #define TPS62360_N_VOLTAGES 64
#define TPS62361_BASE_VOLTAGE 500 #define TPS62361_BASE_VOLTAGE 500000
#define TPS62361_N_VOLTAGES 128 #define TPS62361_N_VOLTAGES 128
/* tps 62360 chip information */ /* tps 62360 chip information */
@@ -72,6 +71,7 @@ struct tps62360_chip {
int lru_index[4]; int lru_index[4];
int curr_vset_vsel[4]; int curr_vset_vsel[4];
int curr_vset_id; int curr_vset_id;
int change_uv_per_us;
}; };
/* /*
@@ -97,6 +97,7 @@ static bool find_voltage_set_register(struct tps62360_chip *tps,
bool found = false; bool found = false;
int new_vset_reg = tps->lru_index[3]; int new_vset_reg = tps->lru_index[3];
int found_index = 3; int found_index = 3;
for (i = 0; i < 4; ++i) { for (i = 0; i < 4; ++i) {
if (tps->curr_vset_vsel[tps->lru_index[i]] == req_vsel) { if (tps->curr_vset_vsel[tps->lru_index[i]] == req_vsel) {
new_vset_reg = tps->lru_index[i]; new_vset_reg = tps->lru_index[i];
@@ -115,7 +116,7 @@ update_lru_index:
return found; return found;
} }
static int tps62360_dcdc_get_voltage(struct regulator_dev *dev) static int tps62360_dcdc_get_voltage_sel(struct regulator_dev *dev)
{ {
struct tps62360_chip *tps = rdev_get_drvdata(dev); struct tps62360_chip *tps = rdev_get_drvdata(dev);
int vsel; int vsel;
@@ -124,12 +125,12 @@ static int tps62360_dcdc_get_voltage(struct regulator_dev *dev)
ret = regmap_read(tps->regmap, REG_VSET0 + tps->curr_vset_id, &data); ret = regmap_read(tps->regmap, REG_VSET0 + tps->curr_vset_id, &data);
if (ret < 0) { if (ret < 0) {
dev_err(tps->dev, "%s: Error in reading register %d\n", dev_err(tps->dev, "%s(): register %d read failed with err %d\n",
__func__, REG_VSET0 + tps->curr_vset_id); __func__, REG_VSET0 + tps->curr_vset_id, ret);
return ret; return ret;
} }
vsel = (int)data & tps->voltage_reg_mask; vsel = (int)data & tps->voltage_reg_mask;
return (tps->voltage_base + vsel * 10) * 1000; return vsel;
} }
static int tps62360_dcdc_set_voltage(struct regulator_dev *dev, static int tps62360_dcdc_set_voltage(struct regulator_dev *dev,
@@ -141,17 +142,13 @@ static int tps62360_dcdc_set_voltage(struct regulator_dev *dev,
bool found = false; bool found = false;
int new_vset_id = tps->curr_vset_id; int new_vset_id = tps->curr_vset_id;
if (max_uV < min_uV) if ((max_uV < min_uV) || (max_uV < tps->voltage_base))
return -EINVAL; return -EINVAL;
if (min_uV > if (min_uV > (tps->voltage_base + (tps->desc.n_voltages - 1) * 10000))
((tps->voltage_base + (tps->desc.n_voltages - 1) * 10) * 1000))
return -EINVAL; return -EINVAL;
if (max_uV < tps->voltage_base * 1000) vsel = DIV_ROUND_UP(min_uV - tps->voltage_base, 10000);
return -EINVAL;
vsel = DIV_ROUND_UP(min_uV - (tps->voltage_base * 1000), 10000);
if (selector) if (selector)
*selector = (vsel & tps->voltage_reg_mask); *selector = (vsel & tps->voltage_reg_mask);
@@ -166,8 +163,9 @@ static int tps62360_dcdc_set_voltage(struct regulator_dev *dev,
ret = regmap_update_bits(tps->regmap, REG_VSET0 + new_vset_id, ret = regmap_update_bits(tps->regmap, REG_VSET0 + new_vset_id,
tps->voltage_reg_mask, vsel); tps->voltage_reg_mask, vsel);
if (ret < 0) { if (ret < 0) {
dev_err(tps->dev, "%s: Error in updating register %d\n", dev_err(tps->dev,
__func__, REG_VSET0 + new_vset_id); "%s(): register %d update failed with err %d\n",
__func__, REG_VSET0 + new_vset_id, ret);
return ret; return ret;
} }
tps->curr_vset_id = new_vset_id; tps->curr_vset_id = new_vset_id;
@@ -176,8 +174,7 @@ static int tps62360_dcdc_set_voltage(struct regulator_dev *dev,
/* Select proper VSET register vio gpios */ /* Select proper VSET register vio gpios */
if (tps->valid_gpios) { if (tps->valid_gpios) {
gpio_set_value_cansleep(tps->vsel0_gpio, gpio_set_value_cansleep(tps->vsel0_gpio, new_vset_id & 0x1);
new_vset_id & 0x1);
gpio_set_value_cansleep(tps->vsel1_gpio, gpio_set_value_cansleep(tps->vsel1_gpio,
(new_vset_id >> 1) & 0x1); (new_vset_id >> 1) & 0x1);
} }
@@ -191,57 +188,72 @@ static int tps62360_dcdc_list_voltage(struct regulator_dev *dev,
if (selector >= tps->desc.n_voltages) if (selector >= tps->desc.n_voltages)
return -EINVAL; return -EINVAL;
return (tps->voltage_base + selector * 10) * 1000;
return tps->voltage_base + selector * 10000;
}
static int tps62360_set_voltage_time_sel(struct regulator_dev *rdev,
unsigned int old_selector, unsigned int new_selector)
{
struct tps62360_chip *tps = rdev_get_drvdata(rdev);
int old_uV, new_uV;
old_uV = tps62360_dcdc_list_voltage(rdev, old_selector);
if (old_uV < 0)
return old_uV;
new_uV = tps62360_dcdc_list_voltage(rdev, new_selector);
if (new_uV < 0)
return new_uV;
return DIV_ROUND_UP(abs(old_uV - new_uV), tps->change_uv_per_us);
} }
static struct regulator_ops tps62360_dcdc_ops = { static struct regulator_ops tps62360_dcdc_ops = {
.get_voltage = tps62360_dcdc_get_voltage, .get_voltage_sel = tps62360_dcdc_get_voltage_sel,
.set_voltage = tps62360_dcdc_set_voltage, .set_voltage = tps62360_dcdc_set_voltage,
.list_voltage = tps62360_dcdc_list_voltage, .list_voltage = tps62360_dcdc_list_voltage,
.set_voltage_time_sel = tps62360_set_voltage_time_sel,
}; };
static int tps62360_init_force_pwm(struct tps62360_chip *tps, static int __devinit tps62360_init_force_pwm(struct tps62360_chip *tps,
struct tps62360_regulator_platform_data *pdata, struct tps62360_regulator_platform_data *pdata,
int vset_id) int vset_id)
{ {
unsigned int data;
int ret; int ret;
ret = regmap_read(tps->regmap, REG_VSET0 + vset_id, &data); int bit = 0;
if (ret < 0) {
dev_err(tps->dev, "%s() fails in writing reg %d\n",
__func__, REG_VSET0 + vset_id);
return ret;
}
tps->curr_vset_vsel[vset_id] = data & tps->voltage_reg_mask;
if (pdata->en_force_pwm) if (pdata->en_force_pwm)
data |= BIT(7); bit = BIT(7);
else
data &= ~BIT(7); ret = regmap_update_bits(tps->regmap, REG_VSET0 + vset_id, BIT(7), bit);
ret = regmap_write(tps->regmap, REG_VSET0 + vset_id, data);
if (ret < 0) if (ret < 0)
dev_err(tps->dev, "%s() fails in writing reg %d\n", dev_err(tps->dev,
__func__, REG_VSET0 + vset_id); "%s(): register %d update failed with err %d\n",
__func__, REG_VSET0 + vset_id, ret);
return ret; return ret;
} }
static int tps62360_init_dcdc(struct tps62360_chip *tps, static int __devinit tps62360_init_dcdc(struct tps62360_chip *tps,
struct tps62360_regulator_platform_data *pdata) struct tps62360_regulator_platform_data *pdata)
{ {
int ret; int ret;
int i; int i;
unsigned int ramp_ctrl;
/* Initailize internal pull up/down control */ /* Initialize internal pull up/down control */
if (tps->en_internal_pulldn) if (tps->en_internal_pulldn)
ret = regmap_write(tps->regmap, REG_CONTROL, 0xE0); ret = regmap_write(tps->regmap, REG_CONTROL, 0xE0);
else else
ret = regmap_write(tps->regmap, REG_CONTROL, 0x0); ret = regmap_write(tps->regmap, REG_CONTROL, 0x0);
if (ret < 0) { if (ret < 0) {
dev_err(tps->dev, "%s() fails in writing reg %d\n", dev_err(tps->dev,
__func__, REG_CONTROL); "%s(): register %d write failed with err %d\n",
__func__, REG_CONTROL, ret);
return ret; return ret;
} }
/* Initailize force PWM mode */ /* Initialize force PWM mode */
if (tps->valid_gpios) { if (tps->valid_gpios) {
for (i = 0; i < 4; ++i) { for (i = 0; i < 4; ++i) {
ret = tps62360_init_force_pwm(tps, pdata, i); ret = tps62360_init_force_pwm(tps, pdata, i);
@@ -256,15 +268,33 @@ static int tps62360_init_dcdc(struct tps62360_chip *tps,
/* Reset output discharge path to reduce power consumption */ /* Reset output discharge path to reduce power consumption */
ret = regmap_update_bits(tps->regmap, REG_RAMPCTRL, BIT(2), 0); ret = regmap_update_bits(tps->regmap, REG_RAMPCTRL, BIT(2), 0);
if (ret < 0) if (ret < 0) {
dev_err(tps->dev, "%s() fails in updating reg %d\n", dev_err(tps->dev,
__func__, REG_RAMPCTRL); "%s(): register %d update failed with err %d\n",
__func__, REG_RAMPCTRL, ret);
return ret;
}
/* Get ramp value from ramp control register */
ret = regmap_read(tps->regmap, REG_RAMPCTRL, &ramp_ctrl);
if (ret < 0) {
dev_err(tps->dev,
"%s(): register %d read failed with err %d\n",
__func__, REG_RAMPCTRL, ret);
return ret;
}
ramp_ctrl = (ramp_ctrl >> 4) & 0x7;
/* ramp mV/us = 32/(2^ramp_ctrl) */
tps->change_uv_per_us = DIV_ROUND_UP(32000, BIT(ramp_ctrl));
return ret; return ret;
} }
static const struct regmap_config tps62360_regmap_config = { static const struct regmap_config tps62360_regmap_config = {
.reg_bits = 8, .reg_bits = 8,
.val_bits = 8, .val_bits = 8,
.max_register = REG_CHIPID,
.cache_type = REGCACHE_RBTREE,
}; };
static int __devinit tps62360_probe(struct i2c_client *client, static int __devinit tps62360_probe(struct i2c_client *client,
@@ -279,14 +309,14 @@ static int __devinit tps62360_probe(struct i2c_client *client,
pdata = client->dev.platform_data; pdata = client->dev.platform_data;
if (!pdata) { if (!pdata) {
dev_err(&client->dev, "%s() Err: Platform data not found\n", dev_err(&client->dev, "%s(): Platform data not found\n",
__func__); __func__);
return -EIO; return -EIO;
} }
tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL); tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL);
if (!tps) { if (!tps) {
dev_err(&client->dev, "%s() Err: Memory allocation fails\n", dev_err(&client->dev, "%s(): Memory allocation failed\n",
__func__); __func__);
return -ENOMEM; return -ENOMEM;
} }
@@ -323,8 +353,9 @@ static int __devinit tps62360_probe(struct i2c_client *client,
tps->regmap = devm_regmap_init_i2c(client, &tps62360_regmap_config); tps->regmap = devm_regmap_init_i2c(client, &tps62360_regmap_config);
if (IS_ERR(tps->regmap)) { if (IS_ERR(tps->regmap)) {
ret = PTR_ERR(tps->regmap); ret = PTR_ERR(tps->regmap);
dev_err(&client->dev, "%s() Err: Failed to allocate register" dev_err(&client->dev,
"map: %d\n", __func__, ret); "%s(): regmap allocation failed with err %d\n",
__func__, ret);
return ret; return ret;
} }
i2c_set_clientdata(client, tps); i2c_set_clientdata(client, tps);
@@ -335,35 +366,26 @@ static int __devinit tps62360_probe(struct i2c_client *client,
tps->valid_gpios = false; tps->valid_gpios = false;
if (gpio_is_valid(tps->vsel0_gpio) && gpio_is_valid(tps->vsel1_gpio)) { if (gpio_is_valid(tps->vsel0_gpio) && gpio_is_valid(tps->vsel1_gpio)) {
ret = gpio_request(tps->vsel0_gpio, "tps62360-vsel0"); int gpio_flags;
gpio_flags = (pdata->vsel0_def_state) ?
GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW;
ret = gpio_request_one(tps->vsel0_gpio,
gpio_flags, "tps62360-vsel0");
if (ret) { if (ret) {
dev_err(&client->dev, dev_err(&client->dev,
"Err: Could not obtain vsel0 GPIO %d: %d\n", "%s(): Could not obtain vsel0 GPIO %d: %d\n",
tps->vsel0_gpio, ret); __func__, tps->vsel0_gpio, ret);
goto err_gpio0;
}
ret = gpio_direction_output(tps->vsel0_gpio,
pdata->vsel0_def_state);
if (ret) {
dev_err(&client->dev, "Err: Could not set direction of"
"vsel0 GPIO %d: %d\n", tps->vsel0_gpio, ret);
gpio_free(tps->vsel0_gpio);
goto err_gpio0; goto err_gpio0;
} }
ret = gpio_request(tps->vsel1_gpio, "tps62360-vsel1"); gpio_flags = (pdata->vsel1_def_state) ?
GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW;
ret = gpio_request_one(tps->vsel1_gpio,
gpio_flags, "tps62360-vsel1");
if (ret) { if (ret) {
dev_err(&client->dev, dev_err(&client->dev,
"Err: Could not obtain vsel1 GPIO %d: %d\n", "%s(): Could not obtain vsel1 GPIO %d: %d\n",
tps->vsel1_gpio, ret); __func__, tps->vsel1_gpio, ret);
goto err_gpio1;
}
ret = gpio_direction_output(tps->vsel1_gpio,
pdata->vsel1_def_state);
if (ret) {
dev_err(&client->dev, "Err: Could not set direction of"
"vsel1 GPIO %d: %d\n", tps->vsel1_gpio, ret);
gpio_free(tps->vsel1_gpio);
goto err_gpio1; goto err_gpio1;
} }
tps->valid_gpios = true; tps->valid_gpios = true;
@@ -380,7 +402,7 @@ static int __devinit tps62360_probe(struct i2c_client *client,
ret = tps62360_init_dcdc(tps, pdata); ret = tps62360_init_dcdc(tps, pdata);
if (ret < 0) { if (ret < 0) {
dev_err(tps->dev, "%s() Err: Init fails with = %d\n", dev_err(tps->dev, "%s(): Init failed with err = %d\n",
__func__, ret); __func__, ret);
goto err_init; goto err_init;
} }
@@ -392,7 +414,8 @@ static int __devinit tps62360_probe(struct i2c_client *client,
/* Register the regulators */ /* Register the regulators */
rdev = regulator_register(&tps->desc, &config); rdev = regulator_register(&tps->desc, &config);
if (IS_ERR(rdev)) { if (IS_ERR(rdev)) {
dev_err(tps->dev, "%s() Err: Failed to register %s\n", dev_err(tps->dev,
"%s(): regulator register failed with err %s\n",
__func__, id->name); __func__, id->name);
ret = PTR_ERR(rdev); ret = PTR_ERR(rdev);
goto err_init; goto err_init;
@@ -442,8 +465,9 @@ static void tps62360_shutdown(struct i2c_client *client)
/* Configure the output discharge path */ /* Configure the output discharge path */
st = regmap_update_bits(tps->regmap, REG_RAMPCTRL, BIT(2), BIT(2)); st = regmap_update_bits(tps->regmap, REG_RAMPCTRL, BIT(2), BIT(2));
if (st < 0) if (st < 0)
dev_err(tps->dev, "%s() fails in updating reg %d\n", dev_err(tps->dev,
__func__, REG_RAMPCTRL); "%s(): register %d update failed with err %d\n",
__func__, REG_RAMPCTRL, st);
} }
static const struct i2c_device_id tps62360_id[] = { static const struct i2c_device_id tps62360_id[] = {
-1
View File
@@ -23,7 +23,6 @@
#include <linux/regulator/driver.h> #include <linux/regulator/driver.h>
#include <linux/regulator/machine.h> #include <linux/regulator/machine.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/delay.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/regmap.h> #include <linux/regmap.h>
+3 -4
View File
@@ -23,7 +23,6 @@
#include <linux/regulator/driver.h> #include <linux/regulator/driver.h>
#include <linux/regulator/machine.h> #include <linux/regulator/machine.h>
#include <linux/regulator/tps6507x.h> #include <linux/regulator/tps6507x.h>
#include <linux/delay.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/mfd/tps6507x.h> #include <linux/mfd/tps6507x.h>
@@ -283,7 +282,7 @@ static int tps6507x_pmic_disable(struct regulator_dev *dev)
1 << shift); 1 << shift);
} }
static int tps6507x_pmic_get_voltage(struct regulator_dev *dev) static int tps6507x_pmic_get_voltage_sel(struct regulator_dev *dev)
{ {
struct tps6507x_pmic *tps = rdev_get_drvdata(dev); struct tps6507x_pmic *tps = rdev_get_drvdata(dev);
int data, rid = rdev_get_id(dev); int data, rid = rdev_get_id(dev);
@@ -325,7 +324,7 @@ static int tps6507x_pmic_get_voltage(struct regulator_dev *dev)
return data; return data;
data &= mask; data &= mask;
return tps->info[rid]->table[data] * 1000; return data;
} }
static int tps6507x_pmic_set_voltage_sel(struct regulator_dev *dev, static int tps6507x_pmic_set_voltage_sel(struct regulator_dev *dev,
@@ -395,7 +394,7 @@ static struct regulator_ops tps6507x_pmic_ops = {
.is_enabled = tps6507x_pmic_is_enabled, .is_enabled = tps6507x_pmic_is_enabled,
.enable = tps6507x_pmic_enable, .enable = tps6507x_pmic_enable,
.disable = tps6507x_pmic_disable, .disable = tps6507x_pmic_disable,
.get_voltage = tps6507x_pmic_get_voltage, .get_voltage_sel = tps6507x_pmic_get_voltage_sel,
.set_voltage_sel = tps6507x_pmic_set_voltage_sel, .set_voltage_sel = tps6507x_pmic_set_voltage_sel,
.list_voltage = tps6507x_pmic_list_voltage, .list_voltage = tps6507x_pmic_list_voltage,
}; };

Some files were not shown because too many files have changed in this diff Show More