aboutsummaryrefslogtreecommitdiff
path: root/drivers/regulator/twl-regulator.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/regulator/twl-regulator.c')
-rw-r--r--drivers/regulator/twl-regulator.c335
1 files changed, 133 insertions, 202 deletions
diff --git a/drivers/regulator/twl-regulator.c b/drivers/regulator/twl-regulator.c
index c7390711d95..fed28abef41 100644
--- a/drivers/regulator/twl-regulator.c
+++ b/drivers/regulator/twl-regulator.c
@@ -10,6 +10,8 @@
*/
#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/slab.h>
#include <linux/init.h>
#include <linux/err.h>
#include <linux/platform_device.h>
@@ -43,9 +45,6 @@ struct twlreg_info {
u8 table_len;
const u16 *table;
- /* regulator specific turn-on delay */
- u16 delay;
-
/* State REMAP default configuration */
u8 remap;
@@ -59,7 +58,7 @@ struct twlreg_info {
struct regulator_desc desc;
/* chip specific features */
- unsigned long features;
+ unsigned long features;
/*
* optional override functions for voltage set/get
@@ -110,7 +109,7 @@ struct twlreg_info {
#define SMPS_OFFSET_EN BIT(0)
#define SMPS_EXTENDED_EN BIT(1)
-/* twl6025 SMPS EPROM values */
+/* twl6032 SMPS EPROM values */
#define TWL6030_SMPS_OFFSET 0xB0
#define TWL6030_SMPS_MULT 0xB3
#define SMPS_MULTOFFSET_SMPS4 BIT(0)
@@ -174,7 +173,7 @@ static int twl6030reg_is_enabled(struct regulator_dev *rdev)
struct twlreg_info *info = rdev_get_drvdata(rdev);
int grp = 0, val;
- if (!(twl_class_is_6030() && (info->features & TWL6025_SUBCLASS))) {
+ if (!(twl_class_is_6030() && (info->features & TWL6032_SUBCLASS))) {
grp = twlreg_grp(rdev);
if (grp < 0)
return grp;
@@ -212,7 +211,7 @@ static int twl6030reg_enable(struct regulator_dev *rdev)
int grp = 0;
int ret;
- if (!(twl_class_is_6030() && (info->features & TWL6025_SUBCLASS)))
+ if (!(twl_class_is_6030() && (info->features & TWL6032_SUBCLASS)))
grp = twlreg_grp(rdev);
if (grp < 0)
return grp;
@@ -223,20 +222,6 @@ static int twl6030reg_enable(struct regulator_dev *rdev)
return ret;
}
-static int twl4030reg_enable_time(struct regulator_dev *rdev)
-{
- struct twlreg_info *info = rdev_get_drvdata(rdev);
-
- return info->delay;
-}
-
-static int twl6030reg_enable_time(struct regulator_dev *rdev)
-{
- struct twlreg_info *info = rdev_get_drvdata(rdev);
-
- return info->delay;
-}
-
static int twl4030reg_disable(struct regulator_dev *rdev)
{
struct twlreg_info *info = rdev_get_drvdata(rdev);
@@ -260,7 +245,7 @@ static int twl6030reg_disable(struct regulator_dev *rdev)
int grp = 0;
int ret;
- if (!(twl_class_is_6030() && (info->features & TWL6025_SUBCLASS)))
+ if (!(twl_class_is_6030() && (info->features & TWL6032_SUBCLASS)))
grp = P1_GRP_6030 | P2_GRP_6030 | P3_GRP_6030;
/* For 6030, set the off state for all grps enabled */
@@ -354,7 +339,7 @@ static int twl6030reg_set_mode(struct regulator_dev *rdev, unsigned mode)
int grp = 0;
int val;
- if (!(twl_class_is_6030() && (info->features & TWL6025_SUBCLASS)))
+ if (!(twl_class_is_6030() && (info->features & TWL6032_SUBCLASS)))
grp = twlreg_grp(rdev);
if (grp < 0)
@@ -456,12 +441,6 @@ static const u16 VSIM_VSEL_table[] = {
static const u16 VDAC_VSEL_table[] = {
1200, 1300, 1800, 1800,
};
-static const u16 VDD1_VSEL_table[] = {
- 800, 1450,
-};
-static const u16 VDD2_VSEL_table[] = {
- 800, 1450, 1500,
-};
static const u16 VIO_VSEL_table[] = {
1800, 1850,
};
@@ -486,29 +465,27 @@ twl4030ldo_set_voltage_sel(struct regulator_dev *rdev, unsigned selector)
selector);
}
-static int twl4030ldo_get_voltage(struct regulator_dev *rdev)
+static int twl4030ldo_get_voltage_sel(struct regulator_dev *rdev)
{
struct twlreg_info *info = rdev_get_drvdata(rdev);
- int vsel = twlreg_read(info, TWL_MODULE_PM_RECEIVER,
- VREG_VOLTAGE);
+ int vsel = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_VOLTAGE);
if (vsel < 0)
return vsel;
vsel &= info->table_len - 1;
- return LDO_MV(info->table[vsel]) * 1000;
+ return vsel;
}
static struct regulator_ops twl4030ldo_ops = {
.list_voltage = twl4030ldo_list_voltage,
.set_voltage_sel = twl4030ldo_set_voltage_sel,
- .get_voltage = twl4030ldo_get_voltage,
+ .get_voltage_sel = twl4030ldo_get_voltage_sel,
.enable = twl4030reg_enable,
.disable = twl4030reg_disable,
.is_enabled = twl4030reg_is_enabled,
- .enable_time = twl4030reg_enable_time,
.set_mode = twl4030reg_set_mode,
@@ -577,59 +554,53 @@ static struct regulator_ops twl6030coresmps_ops = {
.get_voltage = twl6030coresmps_get_voltage,
};
-static int twl6030ldo_list_voltage(struct regulator_dev *rdev, unsigned index)
+static int twl6030ldo_list_voltage(struct regulator_dev *rdev, unsigned sel)
{
- struct twlreg_info *info = rdev_get_drvdata(rdev);
+ struct twlreg_info *info = rdev_get_drvdata(rdev);
- return ((info->min_mV + (index * 100)) * 1000);
+ switch (sel) {
+ case 0:
+ return 0;
+ case 1 ... 24:
+ /* Linear mapping from 00000001 to 00011000:
+ * Absolute voltage value = 1.0 V + 0.1 V × (sel – 00000001)
+ */
+ return (info->min_mV + 100 * (sel - 1)) * 1000;
+ case 25 ... 30:
+ return -EINVAL;
+ case 31:
+ return 2750000;
+ default:
+ return -EINVAL;
+ }
}
static int
-twl6030ldo_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV,
- unsigned *selector)
+twl6030ldo_set_voltage_sel(struct regulator_dev *rdev, unsigned selector)
{
struct twlreg_info *info = rdev_get_drvdata(rdev);
- int vsel;
-
- if ((min_uV/1000 < info->min_mV) || (max_uV/1000 > info->max_mV))
- return -EDOM;
-
- /*
- * Use the below formula to calculate vsel
- * mV = 1000mv + 100mv * (vsel - 1)
- */
- vsel = (min_uV/1000 - 1000)/100 + 1;
- *selector = vsel;
- return twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_VOLTAGE, vsel);
+ return twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_VOLTAGE,
+ selector);
}
-static int twl6030ldo_get_voltage(struct regulator_dev *rdev)
+static int twl6030ldo_get_voltage_sel(struct regulator_dev *rdev)
{
struct twlreg_info *info = rdev_get_drvdata(rdev);
- int vsel = twlreg_read(info, TWL_MODULE_PM_RECEIVER,
- VREG_VOLTAGE);
-
- if (vsel < 0)
- return vsel;
+ int vsel = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_VOLTAGE);
- /*
- * Use the below formula to calculate vsel
- * mV = 1000mv + 100mv * (vsel - 1)
- */
- return (1000 + (100 * (vsel - 1))) * 1000;
+ return vsel;
}
static struct regulator_ops twl6030ldo_ops = {
.list_voltage = twl6030ldo_list_voltage,
- .set_voltage = twl6030ldo_set_voltage,
- .get_voltage = twl6030ldo_get_voltage,
+ .set_voltage_sel = twl6030ldo_set_voltage_sel,
+ .get_voltage_sel = twl6030ldo_get_voltage_sel,
.enable = twl6030reg_enable,
.disable = twl6030reg_disable,
.is_enabled = twl6030reg_is_enabled,
- .enable_time = twl6030reg_enable_time,
.set_mode = twl6030reg_set_mode,
@@ -638,32 +609,12 @@ static struct regulator_ops twl6030ldo_ops = {
/*----------------------------------------------------------------------*/
-/*
- * Fixed voltage LDOs don't have a VSEL field to update.
- */
-static int twlfixed_list_voltage(struct regulator_dev *rdev, unsigned index)
-{
- struct twlreg_info *info = rdev_get_drvdata(rdev);
-
- return info->min_mV * 1000;
-}
-
-static int twlfixed_get_voltage(struct regulator_dev *rdev)
-{
- struct twlreg_info *info = rdev_get_drvdata(rdev);
-
- return info->min_mV * 1000;
-}
-
static struct regulator_ops twl4030fixed_ops = {
- .list_voltage = twlfixed_list_voltage,
-
- .get_voltage = twlfixed_get_voltage,
+ .list_voltage = regulator_list_voltage_linear,
.enable = twl4030reg_enable,
.disable = twl4030reg_disable,
.is_enabled = twl4030reg_is_enabled,
- .enable_time = twl4030reg_enable_time,
.set_mode = twl4030reg_set_mode,
@@ -671,28 +622,17 @@ static struct regulator_ops twl4030fixed_ops = {
};
static struct regulator_ops twl6030fixed_ops = {
- .list_voltage = twlfixed_list_voltage,
-
- .get_voltage = twlfixed_get_voltage,
+ .list_voltage = regulator_list_voltage_linear,
.enable = twl6030reg_enable,
.disable = twl6030reg_disable,
.is_enabled = twl6030reg_is_enabled,
- .enable_time = twl6030reg_enable_time,
.set_mode = twl6030reg_set_mode,
.get_status = twl6030reg_get_status,
};
-static struct regulator_ops twl6030_fixed_resource = {
- .enable = twl6030reg_enable,
- .disable = twl6030reg_disable,
- .is_enabled = twl6030reg_is_enabled,
- .enable_time = twl6030reg_enable_time,
- .get_status = twl6030reg_get_status,
-};
-
/*
* SMPS status and control
*/
@@ -784,37 +724,32 @@ static int twl6030smps_list_voltage(struct regulator_dev *rdev, unsigned index)
return voltage;
}
-static int
-twl6030smps_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV,
- unsigned int *selector)
+static int twl6030smps_map_voltage(struct regulator_dev *rdev, int min_uV,
+ int max_uV)
{
- struct twlreg_info *info = rdev_get_drvdata(rdev);
- int vsel = 0;
+ struct twlreg_info *info = rdev_get_drvdata(rdev);
+ int vsel = 0;
switch (info->flags) {
case 0:
if (min_uV == 0)
vsel = 0;
else if ((min_uV >= 600000) && (min_uV <= 1300000)) {
- int calc_uV;
vsel = DIV_ROUND_UP(min_uV - 600000, 12500);
vsel++;
- calc_uV = twl6030smps_list_voltage(rdev, vsel);
- if (calc_uV > max_uV)
- return -EINVAL;
}
/* Values 1..57 for vsel are linear and can be calculated
* values 58..62 are non linear.
*/
- else if ((min_uV > 1900000) && (max_uV >= 2100000))
+ else if ((min_uV > 1900000) && (min_uV <= 2100000))
vsel = 62;
- else if ((min_uV > 1800000) && (max_uV >= 1900000))
+ else if ((min_uV > 1800000) && (min_uV <= 1900000))
vsel = 61;
- else if ((min_uV > 1500000) && (max_uV >= 1800000))
+ else if ((min_uV > 1500000) && (min_uV <= 1800000))
vsel = 60;
- else if ((min_uV > 1350000) && (max_uV >= 1500000))
+ else if ((min_uV > 1350000) && (min_uV <= 1500000))
vsel = 59;
- else if ((min_uV > 1300000) && (max_uV >= 1350000))
+ else if ((min_uV > 1300000) && (min_uV <= 1350000))
vsel = 58;
else
return -EINVAL;
@@ -823,25 +758,21 @@ twl6030smps_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV,
if (min_uV == 0)
vsel = 0;
else if ((min_uV >= 700000) && (min_uV <= 1420000)) {
- int calc_uV;
vsel = DIV_ROUND_UP(min_uV - 700000, 12500);
vsel++;
- calc_uV = twl6030smps_list_voltage(rdev, vsel);
- if (calc_uV > max_uV)
- return -EINVAL;
}
/* Values 1..57 for vsel are linear and can be calculated
* values 58..62 are non linear.
*/
- else if ((min_uV > 1900000) && (max_uV >= 2100000))
+ else if ((min_uV > 1900000) && (min_uV <= 2100000))
vsel = 62;
- else if ((min_uV > 1800000) && (max_uV >= 1900000))
+ else if ((min_uV > 1800000) && (min_uV <= 1900000))
vsel = 61;
- else if ((min_uV > 1350000) && (max_uV >= 1800000))
+ else if ((min_uV > 1350000) && (min_uV <= 1800000))
vsel = 60;
- else if ((min_uV > 1350000) && (max_uV >= 1500000))
+ else if ((min_uV > 1350000) && (min_uV <= 1500000))
vsel = 59;
- else if ((min_uV > 1300000) && (max_uV >= 1350000))
+ else if ((min_uV > 1300000) && (min_uV <= 1350000))
vsel = 58;
else
return -EINVAL;
@@ -857,17 +788,23 @@ twl6030smps_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV,
case SMPS_OFFSET_EN|SMPS_EXTENDED_EN:
if (min_uV == 0) {
vsel = 0;
- } else if ((min_uV >= 2161000) && (max_uV <= 4321000)) {
+ } else if ((min_uV >= 2161000) && (min_uV <= 4321000)) {
vsel = DIV_ROUND_UP(min_uV - 2161000, 38600);
vsel++;
}
break;
}
- *selector = vsel;
+ return vsel;
+}
+
+static int twl6030smps_set_voltage_sel(struct regulator_dev *rdev,
+ unsigned int selector)
+{
+ struct twlreg_info *info = rdev_get_drvdata(rdev);
return twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_VOLTAGE_SMPS,
- vsel);
+ selector);
}
static int twl6030smps_get_voltage_sel(struct regulator_dev *rdev)
@@ -879,14 +816,14 @@ static int twl6030smps_get_voltage_sel(struct regulator_dev *rdev)
static struct regulator_ops twlsmps_ops = {
.list_voltage = twl6030smps_list_voltage,
+ .map_voltage = twl6030smps_map_voltage,
- .set_voltage = twl6030smps_set_voltage,
+ .set_voltage_sel = twl6030smps_set_voltage_sel,
.get_voltage_sel = twl6030smps_get_voltage_sel,
.enable = twl6030reg_enable,
.disable = twl6030reg_disable,
.is_enabled = twl6030reg_is_enabled,
- .enable_time = twl6030reg_enable_time,
.set_mode = twl6030reg_set_mode,
@@ -904,12 +841,11 @@ static struct regulator_ops twlsmps_ops = {
0x0, TWL6030, twl6030fixed_ops)
#define TWL4030_ADJUSTABLE_LDO(label, offset, num, turnon_delay, remap_conf) \
-static struct twlreg_info TWL4030_INFO_##label = { \
+static const struct twlreg_info TWL4030_INFO_##label = { \
.base = offset, \
.id = num, \
.table_len = ARRAY_SIZE(label##_VSEL_table), \
.table = label##_VSEL_table, \
- .delay = turnon_delay, \
.remap = remap_conf, \
.desc = { \
.name = #label, \
@@ -918,14 +854,14 @@ static struct twlreg_info TWL4030_INFO_##label = { \
.ops = &twl4030ldo_ops, \
.type = REGULATOR_VOLTAGE, \
.owner = THIS_MODULE, \
+ .enable_time = turnon_delay, \
}, \
}
#define TWL4030_ADJUSTABLE_SMPS(label, offset, num, turnon_delay, remap_conf) \
-static struct twlreg_info TWL4030_INFO_##label = { \
+static const struct twlreg_info TWL4030_INFO_##label = { \
.base = offset, \
.id = num, \
- .delay = turnon_delay, \
.remap = remap_conf, \
.desc = { \
.name = #label, \
@@ -933,11 +869,12 @@ static struct twlreg_info TWL4030_INFO_##label = { \
.ops = &twl4030smps_ops, \
.type = REGULATOR_VOLTAGE, \
.owner = THIS_MODULE, \
+ .enable_time = turnon_delay, \
}, \
}
#define TWL6030_ADJUSTABLE_SMPS(label) \
-static struct twlreg_info TWL6030_INFO_##label = { \
+static const struct twlreg_info TWL6030_INFO_##label = { \
.desc = { \
.name = #label, \
.id = TWL6030_REG_##label, \
@@ -948,29 +885,29 @@ static struct twlreg_info TWL6030_INFO_##label = { \
}
#define TWL6030_ADJUSTABLE_LDO(label, offset, min_mVolts, max_mVolts) \
-static struct twlreg_info TWL6030_INFO_##label = { \
+static const struct twlreg_info TWL6030_INFO_##label = { \
.base = offset, \
.min_mV = min_mVolts, \
.max_mV = max_mVolts, \
.desc = { \
.name = #label, \
.id = TWL6030_REG_##label, \
- .n_voltages = (max_mVolts - min_mVolts)/100 + 1, \
+ .n_voltages = 32, \
.ops = &twl6030ldo_ops, \
.type = REGULATOR_VOLTAGE, \
.owner = THIS_MODULE, \
}, \
}
-#define TWL6025_ADJUSTABLE_LDO(label, offset, min_mVolts, max_mVolts) \
-static struct twlreg_info TWL6025_INFO_##label = { \
+#define TWL6032_ADJUSTABLE_LDO(label, offset, min_mVolts, max_mVolts) \
+static const struct twlreg_info TWL6032_INFO_##label = { \
.base = offset, \
.min_mV = min_mVolts, \
.max_mV = max_mVolts, \
.desc = { \
.name = #label, \
- .id = TWL6025_REG_##label, \
- .n_voltages = ((max_mVolts - min_mVolts)/100) + 1, \
+ .id = TWL6032_REG_##label, \
+ .n_voltages = 32, \
.ops = &twl6030ldo_ops, \
.type = REGULATOR_VOLTAGE, \
.owner = THIS_MODULE, \
@@ -979,11 +916,10 @@ static struct twlreg_info TWL6025_INFO_##label = { \
#define TWL_FIXED_LDO(label, offset, mVolts, num, turnon_delay, remap_conf, \
family, operations) \
-static struct twlreg_info TWLFIXED_INFO_##label = { \
+static const struct twlreg_info TWLFIXED_INFO_##label = { \
.base = offset, \
.id = num, \
.min_mV = mVolts, \
- .delay = turnon_delay, \
.remap = remap_conf, \
.desc = { \
.name = #label, \
@@ -992,30 +928,19 @@ static struct twlreg_info TWLFIXED_INFO_##label = { \
.ops = &operations, \
.type = REGULATOR_VOLTAGE, \
.owner = THIS_MODULE, \
+ .min_uV = mVolts * 1000, \
+ .enable_time = turnon_delay, \
}, \
}
-#define TWL6030_FIXED_RESOURCE(label, offset, turnon_delay) \
-static struct twlreg_info TWLRES_INFO_##label = { \
- .base = offset, \
- .delay = turnon_delay, \
- .desc = { \
- .name = #label, \
- .id = TWL6030_REG_##label, \
- .ops = &twl6030_fixed_resource, \
- .type = REGULATOR_VOLTAGE, \
- .owner = THIS_MODULE, \
- }, \
- }
-
-#define TWL6025_ADJUSTABLE_SMPS(label, offset) \
-static struct twlreg_info TWLSMPS_INFO_##label = { \
+#define TWL6032_ADJUSTABLE_SMPS(label, offset) \
+static const struct twlreg_info TWLSMPS_INFO_##label = { \
.base = offset, \
.min_mV = 600, \
.max_mV = 2100, \
.desc = { \
.name = #label, \
- .id = TWL6025_REG_##label, \
+ .id = TWL6032_REG_##label, \
.n_voltages = 63, \
.ops = &twlsmps_ops, \
.type = REGULATOR_VOLTAGE, \
@@ -1056,16 +981,16 @@ TWL6030_ADJUSTABLE_LDO(VMMC, 0x68, 1000, 3300);
TWL6030_ADJUSTABLE_LDO(VPP, 0x6c, 1000, 3300);
TWL6030_ADJUSTABLE_LDO(VUSIM, 0x74, 1000, 3300);
/* 6025 are renamed compared to 6030 versions */
-TWL6025_ADJUSTABLE_LDO(LDO2, 0x54, 1000, 3300);
-TWL6025_ADJUSTABLE_LDO(LDO4, 0x58, 1000, 3300);
-TWL6025_ADJUSTABLE_LDO(LDO3, 0x5c, 1000, 3300);
-TWL6025_ADJUSTABLE_LDO(LDO5, 0x68, 1000, 3300);
-TWL6025_ADJUSTABLE_LDO(LDO1, 0x6c, 1000, 3300);
-TWL6025_ADJUSTABLE_LDO(LDO7, 0x74, 1000, 3300);
-TWL6025_ADJUSTABLE_LDO(LDO6, 0x60, 1000, 3300);
-TWL6025_ADJUSTABLE_LDO(LDOLN, 0x64, 1000, 3300);
-TWL6025_ADJUSTABLE_LDO(LDOUSB, 0x70, 1000, 3300);
-TWL4030_FIXED_LDO(VINTANA2, 0x3f, 1500, 11, 100, 0x08);
+TWL6032_ADJUSTABLE_LDO(LDO2, 0x54, 1000, 3300);
+TWL6032_ADJUSTABLE_LDO(LDO4, 0x58, 1000, 3300);
+TWL6032_ADJUSTABLE_LDO(LDO3, 0x5c, 1000, 3300);
+TWL6032_ADJUSTABLE_LDO(LDO5, 0x68, 1000, 3300);
+TWL6032_ADJUSTABLE_LDO(LDO1, 0x6c, 1000, 3300);
+TWL6032_ADJUSTABLE_LDO(LDO7, 0x74, 1000, 3300);
+TWL6032_ADJUSTABLE_LDO(LDO6, 0x60, 1000, 3300);
+TWL6032_ADJUSTABLE_LDO(LDOLN, 0x64, 1000, 3300);
+TWL6032_ADJUSTABLE_LDO(LDOUSB, 0x70, 1000, 3300);
+TWL4030_FIXED_LDO(VINTANA1, 0x3f, 1500, 11, 100, 0x08);
TWL4030_FIXED_LDO(VINTDIG, 0x47, 1500, 13, 100, 0x08);
TWL4030_FIXED_LDO(VUSB1V5, 0x71, 1500, 17, 100, 0x08);
TWL4030_FIXED_LDO(VUSB1V8, 0x74, 1800, 18, 100, 0x08);
@@ -1076,10 +1001,9 @@ TWL6030_FIXED_LDO(VDAC, 0x64, 1800, 0);
TWL6030_FIXED_LDO(VUSB, 0x70, 3300, 0);
TWL6030_FIXED_LDO(V1V8, 0x16, 1800, 0);
TWL6030_FIXED_LDO(V2V1, 0x1c, 2100, 0);
-TWL6030_FIXED_RESOURCE(CLK32KG, 0x8C, 0);
-TWL6025_ADJUSTABLE_SMPS(SMPS3, 0x34);
-TWL6025_ADJUSTABLE_SMPS(SMPS4, 0x10);
-TWL6025_ADJUSTABLE_SMPS(VIO, 0x16);
+TWL6032_ADJUSTABLE_SMPS(SMPS3, 0x34);
+TWL6032_ADJUSTABLE_SMPS(SMPS4, 0x10);
+TWL6032_ADJUSTABLE_SMPS(VIO, 0x16);
static u8 twl_get_smps_offset(void)
{
@@ -1107,12 +1031,11 @@ static u8 twl_get_smps_mult(void)
#define TWL4030_OF_MATCH(comp, label) TWL_OF_MATCH(comp, TWL4030, label)
#define TWL6030_OF_MATCH(comp, label) TWL_OF_MATCH(comp, TWL6030, label)
-#define TWL6025_OF_MATCH(comp, label) TWL_OF_MATCH(comp, TWL6025, label)
+#define TWL6032_OF_MATCH(comp, label) TWL_OF_MATCH(comp, TWL6032, label)
#define TWLFIXED_OF_MATCH(comp, label) TWL_OF_MATCH(comp, TWLFIXED, label)
-#define TWLRES_OF_MATCH(comp, label) TWL_OF_MATCH(comp, TWLRES, label)
#define TWLSMPS_OF_MATCH(comp, label) TWL_OF_MATCH(comp, TWLSMPS, label)
-static const struct of_device_id twl_of_match[] __devinitconst = {
+static const struct of_device_id twl_of_match[] = {
TWL4030_OF_MATCH("ti,twl4030-vaux1", VAUX1),
TWL4030_OF_MATCH("ti,twl4030-vaux2", VAUX2_4030),
TWL4030_OF_MATCH("ti,twl5030-vaux2", VAUX2),
@@ -1137,16 +1060,16 @@ static const struct of_device_id twl_of_match[] __devinitconst = {
TWL6030_OF_MATCH("ti,twl6030-vmmc", VMMC),
TWL6030_OF_MATCH("ti,twl6030-vpp", VPP),
TWL6030_OF_MATCH("ti,twl6030-vusim", VUSIM),
- TWL6025_OF_MATCH("ti,twl6025-ldo2", LDO2),
- TWL6025_OF_MATCH("ti,twl6025-ldo4", LDO4),
- TWL6025_OF_MATCH("ti,twl6025-ldo3", LDO3),
- TWL6025_OF_MATCH("ti,twl6025-ldo5", LDO5),
- TWL6025_OF_MATCH("ti,twl6025-ldo1", LDO1),
- TWL6025_OF_MATCH("ti,twl6025-ldo7", LDO7),
- TWL6025_OF_MATCH("ti,twl6025-ldo6", LDO6),
- TWL6025_OF_MATCH("ti,twl6025-ldoln", LDOLN),
- TWL6025_OF_MATCH("ti,twl6025-ldousb", LDOUSB),
- TWLFIXED_OF_MATCH("ti,twl4030-vintana2", VINTANA2),
+ TWL6032_OF_MATCH("ti,twl6032-ldo2", LDO2),
+ TWL6032_OF_MATCH("ti,twl6032-ldo4", LDO4),
+ TWL6032_OF_MATCH("ti,twl6032-ldo3", LDO3),
+ TWL6032_OF_MATCH("ti,twl6032-ldo5", LDO5),
+ TWL6032_OF_MATCH("ti,twl6032-ldo1", LDO1),
+ TWL6032_OF_MATCH("ti,twl6032-ldo7", LDO7),
+ TWL6032_OF_MATCH("ti,twl6032-ldo6", LDO6),
+ TWL6032_OF_MATCH("ti,twl6032-ldoln", LDOLN),
+ TWL6032_OF_MATCH("ti,twl6032-ldousb", LDOUSB),
+ TWLFIXED_OF_MATCH("ti,twl4030-vintana1", VINTANA1),
TWLFIXED_OF_MATCH("ti,twl4030-vintdig", VINTDIG),
TWLFIXED_OF_MATCH("ti,twl4030-vusb1v5", VUSB1V5),
TWLFIXED_OF_MATCH("ti,twl4030-vusb1v8", VUSB1V8),
@@ -1157,18 +1080,18 @@ static const struct of_device_id twl_of_match[] __devinitconst = {
TWLFIXED_OF_MATCH("ti,twl6030-vusb", VUSB),
TWLFIXED_OF_MATCH("ti,twl6030-v1v8", V1V8),
TWLFIXED_OF_MATCH("ti,twl6030-v2v1", V2V1),
- TWLRES_OF_MATCH("ti,twl6030-clk32kg", CLK32KG),
- TWLSMPS_OF_MATCH("ti,twl6025-smps3", SMPS3),
- TWLSMPS_OF_MATCH("ti,twl6025-smps4", SMPS4),
- TWLSMPS_OF_MATCH("ti,twl6025-vio", VIO),
+ TWLSMPS_OF_MATCH("ti,twl6032-smps3", SMPS3),
+ TWLSMPS_OF_MATCH("ti,twl6032-smps4", SMPS4),
+ TWLSMPS_OF_MATCH("ti,twl6032-vio", VIO),
{},
};
MODULE_DEVICE_TABLE(of, twl_of_match);
-static int __devinit twlreg_probe(struct platform_device *pdev)
+static int twlreg_probe(struct platform_device *pdev)
{
int i, id;
struct twlreg_info *info;
+ const struct twlreg_info *template;
struct regulator_init_data *initdata;
struct regulation_constraints *c;
struct regulator_dev *rdev;
@@ -1178,17 +1101,17 @@ static int __devinit twlreg_probe(struct platform_device *pdev)
match = of_match_device(twl_of_match, &pdev->dev);
if (match) {
- info = match->data;
- id = info->desc.id;
+ template = match->data;
+ id = template->desc.id;
initdata = of_get_regulator_init_data(&pdev->dev,
pdev->dev.of_node);
drvdata = NULL;
} else {
id = pdev->id;
- initdata = pdev->dev.platform_data;
- for (i = 0, info = NULL; i < ARRAY_SIZE(twl_of_match); i++) {
- info = twl_of_match[i].data;
- if (info && info->desc.id == id)
+ initdata = dev_get_platdata(&pdev->dev);
+ for (i = 0, template = NULL; i < ARRAY_SIZE(twl_of_match); i++) {
+ template = twl_of_match[i].data;
+ if (template && template->desc.id == id)
break;
}
if (i == ARRAY_SIZE(twl_of_match))
@@ -1199,12 +1122,16 @@ static int __devinit twlreg_probe(struct platform_device *pdev)
return -EINVAL;
}
- if (!info)
+ if (!template)
return -ENODEV;
if (!initdata)
return -EINVAL;
+ info = kmemdup(template, sizeof(*info), GFP_KERNEL);
+ if (!info)
+ return -ENOMEM;
+
if (drvdata) {
/* copy the driver data into regulator data */
info->features = drvdata->features;
@@ -1236,19 +1163,19 @@ static int __devinit twlreg_probe(struct platform_device *pdev)
}
switch (id) {
- case TWL6025_REG_SMPS3:
+ case TWL6032_REG_SMPS3:
if (twl_get_smps_mult() & SMPS_MULTOFFSET_SMPS3)
info->flags |= SMPS_EXTENDED_EN;
if (twl_get_smps_offset() & SMPS_MULTOFFSET_SMPS3)
info->flags |= SMPS_OFFSET_EN;
break;
- case TWL6025_REG_SMPS4:
+ case TWL6032_REG_SMPS4:
if (twl_get_smps_mult() & SMPS_MULTOFFSET_SMPS4)
info->flags |= SMPS_EXTENDED_EN;
if (twl_get_smps_offset() & SMPS_MULTOFFSET_SMPS4)
info->flags |= SMPS_OFFSET_EN;
break;
- case TWL6025_REG_VIO:
+ case TWL6032_REG_VIO:
if (twl_get_smps_mult() & SMPS_MULTOFFSET_VIO)
info->flags |= SMPS_EXTENDED_EN;
if (twl_get_smps_offset() & SMPS_MULTOFFSET_VIO)
@@ -1261,10 +1188,11 @@ static int __devinit twlreg_probe(struct platform_device *pdev)
config.driver_data = info;
config.of_node = pdev->dev.of_node;
- rdev = regulator_register(&info->desc, &config);
+ rdev = devm_regulator_register(&pdev->dev, &info->desc, &config);
if (IS_ERR(rdev)) {
dev_err(&pdev->dev, "can't register %s, %ld\n",
info->desc.name, PTR_ERR(rdev));
+ kfree(info);
return PTR_ERR(rdev);
}
platform_set_drvdata(pdev, rdev);
@@ -1284,9 +1212,12 @@ static int __devinit twlreg_probe(struct platform_device *pdev)
return 0;
}
-static int __devexit twlreg_remove(struct platform_device *pdev)
+static int twlreg_remove(struct platform_device *pdev)
{
- regulator_unregister(platform_get_drvdata(pdev));
+ struct regulator_dev *rdev = platform_get_drvdata(pdev);
+ struct twlreg_info *info = rdev->reg_data;
+
+ kfree(info);
return 0;
}
@@ -1294,7 +1225,7 @@ MODULE_ALIAS("platform:twl_reg");
static struct platform_driver twlreg_driver = {
.probe = twlreg_probe,
- .remove = __devexit_p(twlreg_remove),
+ .remove = twlreg_remove,
/* NOTE: short name, to work around driver model truncation of
* "twl_regulator.12" (and friends) to "twl_regulator.1".
*/