You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
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:
@@ -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>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
@@ -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),
|
||||||
|
|||||||
@@ -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? */
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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)) {
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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,
|
||||||
};
|
};
|
||||||
|
|||||||
+90
-73
@@ -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, ®, &mask, &pattern);
|
ret = max8997_get_enable_register(rdev, ®, &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)
|
static int max8997_set_voltage_ldobuck_time_sel(struct regulator_dev *rdev,
|
||||||
udelay(DIV_ROUND_UP(desc->step * (i - org),
|
unsigned int old_selector,
|
||||||
max8997->ramp_delay));
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
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_out:
|
||||||
err_alloc:
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+17
-29
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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,8 +414,9 @@ 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,
|
||||||
__func__, id->name);
|
"%s(): regulator register failed with err %s\n",
|
||||||
|
__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[] = {
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|
||||||
|
|||||||
@@ -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
Reference in New Issue
Block a user