TWL specific changes, cross-merged with OMAP due to arch/arm wanting to
use the new ability to override the voltage set and get operations to support the in-CPU voltage management. The other changes are minor fixes, the addition of a few new regulators and device tree support. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (GNU/Linux) iQIcBAABAgAGBQJPXQiBAAoJEBus8iNuMP3dhiMP/2z1ImskdfEg+nT43nX4qjge MFiHzynz13X4VvOB3+rE0OsBmTjRdjpZzsND3g673D6RuT2mfSAj270AbsJ9bZNR Fz8c/RAv2LWG5GKNCB8cWFoxVxk7xhrpE31a6JYV10HBhxmg/6ESaKs63W6MKWQk NSfQdE2PujrCIYBwqCYP4knk+Gx4R5GBMol8hXjIkmcSPCnZ71/o6UMu0OsJ6e37 LKwkBT8zY72HhmBrWNmHXrH94dCYv9XjTtOfjhF97+UAFAuVcztXUq4ZKFNUPuNN QLAftkoKPXbSUpqvmmMCJQcNUMvpEGFh42JLZO1S8HN5Mb5+CPE2oS62QNtbrbrV cwxpWUse823qJSHXwCWS4ai9M3fO/1tWEfo4nWauKyAgXLV/udF0nBVnSjv72Agg cJsmVNOdwLUb89izD2Q05gvObfzPLxjFrGMTHZ1p+h5rgIdQq6ttx4yoZIlmUMqy eBFWofYRbxS3UDVteBNZGuAb5AMFuMPrlmluTGWftY41d8mgFLyreNoFReEbeiDP ZRpulqoOll1KYdTwg3BbgfS/x8FsSdtH8LBP2BIsmZ6q7hG7CEoG/OOk4ex4vuMx AgUV8uRfQ7HjW5NkAX6kOvm3IH6yUOq7uysifKvs+iBRjT2kP0iw3OThdImHDetq kjIFEOq+og9NNJ7fLFAB =EHNp -----END PGP SIGNATURE----- Merge tag 'topic/twl' into regulator-next TWL specific changes, cross-merged with OMAP due to arch/arm wanting to use the new ability to override the voltage set and get operations to support the in-CPU voltage management. The other changes are minor fixes, the addition of a few new regulators and device tree support.
This commit is contained in:
commit
4992fa1fd4
|
@ -0,0 +1,68 @@
|
|||
TWL family of regulators
|
||||
|
||||
Required properties:
|
||||
For twl6030 regulators/LDOs
|
||||
- compatible:
|
||||
- "ti,twl6030-vaux1" for VAUX1 LDO
|
||||
- "ti,twl6030-vaux2" for VAUX2 LDO
|
||||
- "ti,twl6030-vaux3" for VAUX3 LDO
|
||||
- "ti,twl6030-vmmc" for VMMC LDO
|
||||
- "ti,twl6030-vpp" for VPP LDO
|
||||
- "ti,twl6030-vusim" for VUSIM LDO
|
||||
- "ti,twl6030-vana" for VANA LDO
|
||||
- "ti,twl6030-vcxio" for VCXIO LDO
|
||||
- "ti,twl6030-vdac" for VDAC LDO
|
||||
- "ti,twl6030-vusb" for VUSB LDO
|
||||
- "ti,twl6030-v1v8" for V1V8 LDO
|
||||
- "ti,twl6030-v2v1" for V2V1 LDO
|
||||
- "ti,twl6030-clk32kg" for CLK32KG RESOURCE
|
||||
- "ti,twl6030-vdd1" for VDD1 SMPS
|
||||
- "ti,twl6030-vdd2" for VDD2 SMPS
|
||||
- "ti,twl6030-vdd3" for VDD3 SMPS
|
||||
For twl6025 regulators/LDOs
|
||||
- compatible:
|
||||
- "ti,twl6025-ldo1" for LDO1 LDO
|
||||
- "ti,twl6025-ldo2" for LDO2 LDO
|
||||
- "ti,twl6025-ldo3" for LDO3 LDO
|
||||
- "ti,twl6025-ldo4" for LDO4 LDO
|
||||
- "ti,twl6025-ldo5" for LDO5 LDO
|
||||
- "ti,twl6025-ldo6" for LDO6 LDO
|
||||
- "ti,twl6025-ldo7" for LDO7 LDO
|
||||
- "ti,twl6025-ldoln" for LDOLN LDO
|
||||
- "ti,twl6025-ldousb" for LDOUSB LDO
|
||||
- "ti,twl6025-smps3" for SMPS3 SMPS
|
||||
- "ti,twl6025-smps4" for SMPS4 SMPS
|
||||
- "ti,twl6025-vio" for VIO SMPS
|
||||
For twl4030 regulators/LDOs
|
||||
- compatible:
|
||||
- "ti,twl4030-vaux1" for VAUX1 LDO
|
||||
- "ti,twl4030-vaux2" for VAUX2 LDO
|
||||
- "ti,twl5030-vaux2" for VAUX2 LDO
|
||||
- "ti,twl4030-vaux3" for VAUX3 LDO
|
||||
- "ti,twl4030-vaux4" for VAUX4 LDO
|
||||
- "ti,twl4030-vmmc1" for VMMC1 LDO
|
||||
- "ti,twl4030-vmmc2" for VMMC2 LDO
|
||||
- "ti,twl4030-vpll1" for VPLL1 LDO
|
||||
- "ti,twl4030-vpll2" for VPLL2 LDO
|
||||
- "ti,twl4030-vsim" for VSIM LDO
|
||||
- "ti,twl4030-vdac" for VDAC LDO
|
||||
- "ti,twl4030-vintana2" for VINTANA2 LDO
|
||||
- "ti,twl4030-vio" for VIO LDO
|
||||
- "ti,twl4030-vdd1" for VDD1 SMPS
|
||||
- "ti,twl4030-vdd2" for VDD2 SMPS
|
||||
- "ti,twl4030-vintana1" for VINTANA1 LDO
|
||||
- "ti,twl4030-vintdig" for VINTDIG LDO
|
||||
- "ti,twl4030-vusb1v5" for VUSB1V5 LDO
|
||||
- "ti,twl4030-vusb1v8" for VUSB1V8 LDO
|
||||
- "ti,twl4030-vusb3v1" for VUSB3V1 LDO
|
||||
|
||||
Optional properties:
|
||||
- Any optional property defined in bindings/regulator/regulator.txt
|
||||
|
||||
Example:
|
||||
|
||||
xyz: regulator@0 {
|
||||
compatible = "ti,twl6030-vaux1";
|
||||
regulator-min-microvolt = <1000000>;
|
||||
regulator-max-microvolt = <3000000>;
|
||||
};
|
|
@ -621,6 +621,8 @@ add_regulator_linked(int num, struct regulator_init_data *pdata,
|
|||
unsigned num_consumers, unsigned long features)
|
||||
{
|
||||
unsigned sub_chip_id;
|
||||
struct twl_regulator_driver_data drv_data;
|
||||
|
||||
/* regulator framework demands init_data ... */
|
||||
if (!pdata)
|
||||
return NULL;
|
||||
|
@ -630,7 +632,19 @@ add_regulator_linked(int num, struct regulator_init_data *pdata,
|
|||
pdata->num_consumer_supplies = num_consumers;
|
||||
}
|
||||
|
||||
pdata->driver_data = (void *)features;
|
||||
if (pdata->driver_data) {
|
||||
/* If we have existing drv_data, just add the flags */
|
||||
struct twl_regulator_driver_data *tmp;
|
||||
tmp = pdata->driver_data;
|
||||
tmp->features |= features;
|
||||
} else {
|
||||
/* add new driver data struct, used only during init */
|
||||
drv_data.features = features;
|
||||
drv_data.set_voltage = NULL;
|
||||
drv_data.get_voltage = NULL;
|
||||
drv_data.data = NULL;
|
||||
pdata->driver_data = &drv_data;
|
||||
}
|
||||
|
||||
/* NOTE: we currently ignore regulator IRQs, e.g. for short circuits */
|
||||
sub_chip_id = twl_map[TWL_MODULE_PM_MASTER].sid;
|
||||
|
@ -937,6 +951,31 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features)
|
|||
/* twl6030 regulators */
|
||||
if (twl_has_regulator() && twl_class_is_6030() &&
|
||||
!(features & TWL6025_SUBCLASS)) {
|
||||
child = add_regulator(TWL6030_REG_VDD1, pdata->vdd1,
|
||||
features);
|
||||
if (IS_ERR(child))
|
||||
return PTR_ERR(child);
|
||||
|
||||
child = add_regulator(TWL6030_REG_VDD2, pdata->vdd2,
|
||||
features);
|
||||
if (IS_ERR(child))
|
||||
return PTR_ERR(child);
|
||||
|
||||
child = add_regulator(TWL6030_REG_VDD3, pdata->vdd3,
|
||||
features);
|
||||
if (IS_ERR(child))
|
||||
return PTR_ERR(child);
|
||||
|
||||
child = add_regulator(TWL6030_REG_V1V8, pdata->v1v8,
|
||||
features);
|
||||
if (IS_ERR(child))
|
||||
return PTR_ERR(child);
|
||||
|
||||
child = add_regulator(TWL6030_REG_V2V1, pdata->v2v1,
|
||||
features);
|
||||
if (IS_ERR(child))
|
||||
return PTR_ERR(child);
|
||||
|
||||
child = add_regulator(TWL6030_REG_VMMC, pdata->vmmc,
|
||||
features);
|
||||
if (IS_ERR(child))
|
||||
|
|
|
@ -14,8 +14,11 @@
|
|||
#include <linux/err.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/regulator/driver.h>
|
||||
#include <linux/regulator/machine.h>
|
||||
#include <linux/regulator/of_regulator.h>
|
||||
#include <linux/i2c/twl.h>
|
||||
|
||||
|
||||
|
@ -58,6 +61,16 @@ struct twlreg_info {
|
|||
|
||||
/* chip specific features */
|
||||
unsigned long features;
|
||||
|
||||
/*
|
||||
* optional override functions for voltage set/get
|
||||
* these are currently only used for SMPS regulators
|
||||
*/
|
||||
int (*get_voltage)(void *data);
|
||||
int (*set_voltage)(void *data, int target_uV);
|
||||
|
||||
/* data passed from board for external get/set voltage */
|
||||
void *data;
|
||||
};
|
||||
|
||||
|
||||
|
@ -522,15 +535,25 @@ twl4030smps_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV,
|
|||
struct twlreg_info *info = rdev_get_drvdata(rdev);
|
||||
int vsel = DIV_ROUND_UP(min_uV - 600000, 12500);
|
||||
|
||||
twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_VOLTAGE_SMPS_4030,
|
||||
vsel);
|
||||
if (info->set_voltage) {
|
||||
return info->set_voltage(info->data, min_uV);
|
||||
} else {
|
||||
twlreg_write(info, TWL_MODULE_PM_RECEIVER,
|
||||
VREG_VOLTAGE_SMPS_4030, vsel);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int twl4030smps_get_voltage(struct regulator_dev *rdev)
|
||||
{
|
||||
struct twlreg_info *info = rdev_get_drvdata(rdev);
|
||||
int vsel = twlreg_read(info, TWL_MODULE_PM_RECEIVER,
|
||||
int vsel;
|
||||
|
||||
if (info->get_voltage)
|
||||
return info->get_voltage(info->data);
|
||||
|
||||
vsel = twlreg_read(info, TWL_MODULE_PM_RECEIVER,
|
||||
VREG_VOLTAGE_SMPS_4030);
|
||||
|
||||
return vsel * 12500 + 600000;
|
||||
|
@ -541,6 +564,32 @@ static struct regulator_ops twl4030smps_ops = {
|
|||
.get_voltage = twl4030smps_get_voltage,
|
||||
};
|
||||
|
||||
static int twl6030coresmps_set_voltage(struct regulator_dev *rdev, int min_uV,
|
||||
int max_uV, unsigned *selector)
|
||||
{
|
||||
struct twlreg_info *info = rdev_get_drvdata(rdev);
|
||||
|
||||
if (info->set_voltage)
|
||||
return info->set_voltage(info->data, min_uV);
|
||||
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static int twl6030coresmps_get_voltage(struct regulator_dev *rdev)
|
||||
{
|
||||
struct twlreg_info *info = rdev_get_drvdata(rdev);
|
||||
|
||||
if (info->get_voltage)
|
||||
return info->get_voltage(info->data);
|
||||
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static struct regulator_ops twl6030coresmps_ops = {
|
||||
.set_voltage = twl6030coresmps_set_voltage,
|
||||
.get_voltage = twl6030coresmps_get_voltage,
|
||||
};
|
||||
|
||||
static int twl6030ldo_list_voltage(struct regulator_dev *rdev, unsigned index)
|
||||
{
|
||||
struct twlreg_info *info = rdev_get_drvdata(rdev);
|
||||
|
@ -755,12 +804,16 @@ twl6030smps_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV,
|
|||
case 0:
|
||||
if (min_uV == 0)
|
||||
vsel = 0;
|
||||
else if ((min_uV >= 600000) && (max_uV <= 1300000)) {
|
||||
else if ((min_uV >= 600000) && (min_uV <= 1300000)) {
|
||||
int calc_uV;
|
||||
vsel = (min_uV - 600000) / 125;
|
||||
if (vsel % 100)
|
||||
vsel += 100;
|
||||
vsel /= 100;
|
||||
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.
|
||||
|
@ -781,12 +834,16 @@ twl6030smps_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV,
|
|||
case SMPS_OFFSET_EN:
|
||||
if (min_uV == 0)
|
||||
vsel = 0;
|
||||
else if ((min_uV >= 700000) && (max_uV <= 1420000)) {
|
||||
else if ((min_uV >= 700000) && (min_uV <= 1420000)) {
|
||||
int calc_uV;
|
||||
vsel = (min_uV - 700000) / 125;
|
||||
if (vsel % 100)
|
||||
vsel += 100;
|
||||
vsel /= 100;
|
||||
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.
|
||||
|
@ -819,7 +876,7 @@ twl6030smps_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV,
|
|||
if (min_uV == 0)
|
||||
vsel = 0;
|
||||
else if ((min_uV >= 2161000) && (max_uV <= 4321000)) {
|
||||
vsel = (min_uV - 1852000) / 386;
|
||||
vsel = (min_uV - 2161000) / 386;
|
||||
if (vsel % 100)
|
||||
vsel += 100;
|
||||
vsel /= 100;
|
||||
|
@ -866,7 +923,8 @@ static struct regulator_ops twlsmps_ops = {
|
|||
TWL_FIXED_LDO(label, offset, mVolts, 0x0, turnon_delay, \
|
||||
0x0, TWL6030, twl6030fixed_ops)
|
||||
|
||||
#define TWL4030_ADJUSTABLE_LDO(label, offset, num, turnon_delay, remap_conf) { \
|
||||
#define TWL4030_ADJUSTABLE_LDO(label, offset, num, turnon_delay, remap_conf) \
|
||||
static struct twlreg_info TWL4030_INFO_##label = { \
|
||||
.base = offset, \
|
||||
.id = num, \
|
||||
.table_len = ARRAY_SIZE(label##_VSEL_table), \
|
||||
|
@ -884,7 +942,7 @@ static struct regulator_ops twlsmps_ops = {
|
|||
}
|
||||
|
||||
#define TWL4030_ADJUSTABLE_SMPS(label, offset, num, turnon_delay, remap_conf) \
|
||||
{ \
|
||||
static struct twlreg_info TWL4030_INFO_##label = { \
|
||||
.base = offset, \
|
||||
.id = num, \
|
||||
.delay = turnon_delay, \
|
||||
|
@ -898,7 +956,19 @@ static struct regulator_ops twlsmps_ops = {
|
|||
}, \
|
||||
}
|
||||
|
||||
#define TWL6030_ADJUSTABLE_LDO(label, offset, min_mVolts, max_mVolts) { \
|
||||
#define TWL6030_ADJUSTABLE_SMPS(label) \
|
||||
static struct twlreg_info TWL6030_INFO_##label = { \
|
||||
.desc = { \
|
||||
.name = #label, \
|
||||
.id = TWL6030_REG_##label, \
|
||||
.ops = &twl6030coresmps_ops, \
|
||||
.type = REGULATOR_VOLTAGE, \
|
||||
.owner = THIS_MODULE, \
|
||||
}, \
|
||||
}
|
||||
|
||||
#define TWL6030_ADJUSTABLE_LDO(label, offset, min_mVolts, max_mVolts) \
|
||||
static struct twlreg_info TWL6030_INFO_##label = { \
|
||||
.base = offset, \
|
||||
.min_mV = min_mVolts, \
|
||||
.max_mV = max_mVolts, \
|
||||
|
@ -912,7 +982,8 @@ static struct regulator_ops twlsmps_ops = {
|
|||
}, \
|
||||
}
|
||||
|
||||
#define TWL6025_ADJUSTABLE_LDO(label, offset, min_mVolts, max_mVolts) { \
|
||||
#define TWL6025_ADJUSTABLE_LDO(label, offset, min_mVolts, max_mVolts) \
|
||||
static struct twlreg_info TWL6025_INFO_##label = { \
|
||||
.base = offset, \
|
||||
.min_mV = min_mVolts, \
|
||||
.max_mV = max_mVolts, \
|
||||
|
@ -927,7 +998,8 @@ static struct regulator_ops twlsmps_ops = {
|
|||
}
|
||||
|
||||
#define TWL_FIXED_LDO(label, offset, mVolts, num, turnon_delay, remap_conf, \
|
||||
family, operations) { \
|
||||
family, operations) \
|
||||
static struct twlreg_info TWLFIXED_INFO_##label = { \
|
||||
.base = offset, \
|
||||
.id = num, \
|
||||
.min_mV = mVolts, \
|
||||
|
@ -943,7 +1015,8 @@ static struct regulator_ops twlsmps_ops = {
|
|||
}, \
|
||||
}
|
||||
|
||||
#define TWL6030_FIXED_RESOURCE(label, offset, turnon_delay) { \
|
||||
#define TWL6030_FIXED_RESOURCE(label, offset, turnon_delay) \
|
||||
static struct twlreg_info TWLRES_INFO_##label = { \
|
||||
.base = offset, \
|
||||
.delay = turnon_delay, \
|
||||
.desc = { \
|
||||
|
@ -955,7 +1028,8 @@ static struct regulator_ops twlsmps_ops = {
|
|||
}, \
|
||||
}
|
||||
|
||||
#define TWL6025_ADJUSTABLE_SMPS(label, offset) { \
|
||||
#define TWL6025_ADJUSTABLE_SMPS(label, offset) \
|
||||
static struct twlreg_info TWLSMPS_INFO_##label = { \
|
||||
.base = offset, \
|
||||
.min_mV = 600, \
|
||||
.max_mV = 2100, \
|
||||
|
@ -973,59 +1047,59 @@ static struct regulator_ops twlsmps_ops = {
|
|||
* We list regulators here if systems need some level of
|
||||
* software control over them after boot.
|
||||
*/
|
||||
static struct twlreg_info twl_regs[] = {
|
||||
TWL4030_ADJUSTABLE_LDO(VAUX1, 0x17, 1, 100, 0x08),
|
||||
TWL4030_ADJUSTABLE_LDO(VAUX2_4030, 0x1b, 2, 100, 0x08),
|
||||
TWL4030_ADJUSTABLE_LDO(VAUX2, 0x1b, 2, 100, 0x08),
|
||||
TWL4030_ADJUSTABLE_LDO(VAUX3, 0x1f, 3, 100, 0x08),
|
||||
TWL4030_ADJUSTABLE_LDO(VAUX4, 0x23, 4, 100, 0x08),
|
||||
TWL4030_ADJUSTABLE_LDO(VMMC1, 0x27, 5, 100, 0x08),
|
||||
TWL4030_ADJUSTABLE_LDO(VMMC2, 0x2b, 6, 100, 0x08),
|
||||
TWL4030_ADJUSTABLE_LDO(VPLL1, 0x2f, 7, 100, 0x00),
|
||||
TWL4030_ADJUSTABLE_LDO(VPLL2, 0x33, 8, 100, 0x08),
|
||||
TWL4030_ADJUSTABLE_LDO(VSIM, 0x37, 9, 100, 0x00),
|
||||
TWL4030_ADJUSTABLE_LDO(VDAC, 0x3b, 10, 100, 0x08),
|
||||
TWL4030_FIXED_LDO(VINTANA1, 0x3f, 1500, 11, 100, 0x08),
|
||||
TWL4030_ADJUSTABLE_LDO(VINTANA2, 0x43, 12, 100, 0x08),
|
||||
TWL4030_FIXED_LDO(VINTDIG, 0x47, 1500, 13, 100, 0x08),
|
||||
TWL4030_ADJUSTABLE_LDO(VIO, 0x4b, 14, 1000, 0x08),
|
||||
TWL4030_ADJUSTABLE_SMPS(VDD1, 0x55, 15, 1000, 0x08),
|
||||
TWL4030_ADJUSTABLE_SMPS(VDD2, 0x63, 16, 1000, 0x08),
|
||||
TWL4030_FIXED_LDO(VUSB1V5, 0x71, 1500, 17, 100, 0x08),
|
||||
TWL4030_FIXED_LDO(VUSB1V8, 0x74, 1800, 18, 100, 0x08),
|
||||
TWL4030_FIXED_LDO(VUSB3V1, 0x77, 3100, 19, 150, 0x08),
|
||||
/* VUSBCP is managed *only* by the USB subchip */
|
||||
|
||||
/* 6030 REG with base as PMC Slave Misc : 0x0030 */
|
||||
/* Turnon-delay and remap configuration values for 6030 are not
|
||||
verified since the specification is not public */
|
||||
TWL6030_ADJUSTABLE_LDO(VAUX1_6030, 0x54, 1000, 3300),
|
||||
TWL6030_ADJUSTABLE_LDO(VAUX2_6030, 0x58, 1000, 3300),
|
||||
TWL6030_ADJUSTABLE_LDO(VAUX3_6030, 0x5c, 1000, 3300),
|
||||
TWL6030_ADJUSTABLE_LDO(VMMC, 0x68, 1000, 3300),
|
||||
TWL6030_ADJUSTABLE_LDO(VPP, 0x6c, 1000, 3300),
|
||||
TWL6030_ADJUSTABLE_LDO(VUSIM, 0x74, 1000, 3300),
|
||||
TWL6030_FIXED_LDO(VANA, 0x50, 2100, 0),
|
||||
TWL6030_FIXED_LDO(VCXIO, 0x60, 1800, 0),
|
||||
TWL6030_FIXED_LDO(VDAC, 0x64, 1800, 0),
|
||||
TWL6030_FIXED_LDO(VUSB, 0x70, 3300, 0),
|
||||
TWL6030_FIXED_RESOURCE(CLK32KG, 0x8C, 0),
|
||||
|
||||
/* 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),
|
||||
|
||||
TWL6025_ADJUSTABLE_SMPS(SMPS3, 0x34),
|
||||
TWL6025_ADJUSTABLE_SMPS(SMPS4, 0x10),
|
||||
TWL6025_ADJUSTABLE_SMPS(VIO, 0x16),
|
||||
};
|
||||
TWL4030_ADJUSTABLE_LDO(VAUX1, 0x17, 1, 100, 0x08);
|
||||
TWL4030_ADJUSTABLE_LDO(VAUX2_4030, 0x1b, 2, 100, 0x08);
|
||||
TWL4030_ADJUSTABLE_LDO(VAUX2, 0x1b, 2, 100, 0x08);
|
||||
TWL4030_ADJUSTABLE_LDO(VAUX3, 0x1f, 3, 100, 0x08);
|
||||
TWL4030_ADJUSTABLE_LDO(VAUX4, 0x23, 4, 100, 0x08);
|
||||
TWL4030_ADJUSTABLE_LDO(VMMC1, 0x27, 5, 100, 0x08);
|
||||
TWL4030_ADJUSTABLE_LDO(VMMC2, 0x2b, 6, 100, 0x08);
|
||||
TWL4030_ADJUSTABLE_LDO(VPLL1, 0x2f, 7, 100, 0x00);
|
||||
TWL4030_ADJUSTABLE_LDO(VPLL2, 0x33, 8, 100, 0x08);
|
||||
TWL4030_ADJUSTABLE_LDO(VSIM, 0x37, 9, 100, 0x00);
|
||||
TWL4030_ADJUSTABLE_LDO(VDAC, 0x3b, 10, 100, 0x08);
|
||||
TWL4030_ADJUSTABLE_LDO(VINTANA2, 0x43, 12, 100, 0x08);
|
||||
TWL4030_ADJUSTABLE_LDO(VIO, 0x4b, 14, 1000, 0x08);
|
||||
TWL4030_ADJUSTABLE_SMPS(VDD1, 0x55, 15, 1000, 0x08);
|
||||
TWL4030_ADJUSTABLE_SMPS(VDD2, 0x63, 16, 1000, 0x08);
|
||||
/* VUSBCP is managed *only* by the USB subchip */
|
||||
/* 6030 REG with base as PMC Slave Misc : 0x0030 */
|
||||
/* Turnon-delay and remap configuration values for 6030 are not
|
||||
verified since the specification is not public */
|
||||
TWL6030_ADJUSTABLE_SMPS(VDD1);
|
||||
TWL6030_ADJUSTABLE_SMPS(VDD2);
|
||||
TWL6030_ADJUSTABLE_SMPS(VDD3);
|
||||
TWL6030_ADJUSTABLE_LDO(VAUX1_6030, 0x54, 1000, 3300);
|
||||
TWL6030_ADJUSTABLE_LDO(VAUX2_6030, 0x58, 1000, 3300);
|
||||
TWL6030_ADJUSTABLE_LDO(VAUX3_6030, 0x5c, 1000, 3300);
|
||||
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);
|
||||
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);
|
||||
TWL4030_FIXED_LDO(VUSB3V1, 0x77, 3100, 19, 150, 0x08);
|
||||
TWL6030_FIXED_LDO(VANA, 0x50, 2100, 0);
|
||||
TWL6030_FIXED_LDO(VCXIO, 0x60, 1800, 0);
|
||||
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);
|
||||
|
||||
static u8 twl_get_smps_offset(void)
|
||||
{
|
||||
|
@ -1045,29 +1119,116 @@ static u8 twl_get_smps_mult(void)
|
|||
return value;
|
||||
}
|
||||
|
||||
#define TWL_OF_MATCH(comp, family, label) \
|
||||
{ \
|
||||
.compatible = comp, \
|
||||
.data = &family##_INFO_##label, \
|
||||
}
|
||||
|
||||
#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 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 = {
|
||||
TWL4030_OF_MATCH("ti,twl4030-vaux1", VAUX1),
|
||||
TWL4030_OF_MATCH("ti,twl4030-vaux2", VAUX2_4030),
|
||||
TWL4030_OF_MATCH("ti,twl5030-vaux2", VAUX2),
|
||||
TWL4030_OF_MATCH("ti,twl4030-vaux3", VAUX3),
|
||||
TWL4030_OF_MATCH("ti,twl4030-vaux4", VAUX4),
|
||||
TWL4030_OF_MATCH("ti,twl4030-vmmc1", VMMC1),
|
||||
TWL4030_OF_MATCH("ti,twl4030-vmmc2", VMMC2),
|
||||
TWL4030_OF_MATCH("ti,twl4030-vpll1", VPLL1),
|
||||
TWL4030_OF_MATCH("ti,twl4030-vpll2", VPLL2),
|
||||
TWL4030_OF_MATCH("ti,twl4030-vsim", VSIM),
|
||||
TWL4030_OF_MATCH("ti,twl4030-vdac", VDAC),
|
||||
TWL4030_OF_MATCH("ti,twl4030-vintana2", VINTANA2),
|
||||
TWL4030_OF_MATCH("ti,twl4030-vio", VIO),
|
||||
TWL4030_OF_MATCH("ti,twl4030-vdd1", VDD1),
|
||||
TWL4030_OF_MATCH("ti,twl4030-vdd2", VDD2),
|
||||
TWL6030_OF_MATCH("ti,twl6030-vdd1", VDD1),
|
||||
TWL6030_OF_MATCH("ti,twl6030-vdd2", VDD2),
|
||||
TWL6030_OF_MATCH("ti,twl6030-vdd3", VDD3),
|
||||
TWL6030_OF_MATCH("ti,twl6030-vaux1", VAUX1_6030),
|
||||
TWL6030_OF_MATCH("ti,twl6030-vaux2", VAUX2_6030),
|
||||
TWL6030_OF_MATCH("ti,twl6030-vaux3", VAUX3_6030),
|
||||
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),
|
||||
TWLFIXED_OF_MATCH("ti,twl4030-vintdig", VINTDIG),
|
||||
TWLFIXED_OF_MATCH("ti,twl4030-vusb1v5", VUSB1V5),
|
||||
TWLFIXED_OF_MATCH("ti,twl4030-vusb1v8", VUSB1V8),
|
||||
TWLFIXED_OF_MATCH("ti,twl4030-vusb3v1", VUSB3V1),
|
||||
TWLFIXED_OF_MATCH("ti,twl6030-vana", VANA),
|
||||
TWLFIXED_OF_MATCH("ti,twl6030-vcxio", VCXIO),
|
||||
TWLFIXED_OF_MATCH("ti,twl6030-vdac", VDAC),
|
||||
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),
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, twl_of_match);
|
||||
|
||||
static int __devinit twlreg_probe(struct platform_device *pdev)
|
||||
{
|
||||
int i;
|
||||
int i, id;
|
||||
struct twlreg_info *info;
|
||||
struct regulator_init_data *initdata;
|
||||
struct regulation_constraints *c;
|
||||
struct regulator_dev *rdev;
|
||||
struct twl_regulator_driver_data *drvdata;
|
||||
const struct of_device_id *match;
|
||||
|
||||
for (i = 0, info = NULL; i < ARRAY_SIZE(twl_regs); i++) {
|
||||
if (twl_regs[i].desc.id != pdev->id)
|
||||
continue;
|
||||
info = twl_regs + i;
|
||||
break;
|
||||
match = of_match_device(twl_of_match, &pdev->dev);
|
||||
if (match) {
|
||||
info = match->data;
|
||||
id = info->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)
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
drvdata = initdata->driver_data;
|
||||
if (!drvdata)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!info)
|
||||
return -ENODEV;
|
||||
|
||||
initdata = pdev->dev.platform_data;
|
||||
if (!initdata)
|
||||
return -EINVAL;
|
||||
|
||||
/* copy the features into regulator data */
|
||||
info->features = (unsigned long)initdata->driver_data;
|
||||
if (drvdata) {
|
||||
/* copy the driver data into regulator data */
|
||||
info->features = drvdata->features;
|
||||
info->data = drvdata->data;
|
||||
info->set_voltage = drvdata->set_voltage;
|
||||
info->get_voltage = drvdata->get_voltage;
|
||||
}
|
||||
|
||||
/* Constrain board-specific capabilities according to what
|
||||
* this driver and the chip itself can actually do.
|
||||
|
@ -1077,7 +1238,7 @@ static int __devinit twlreg_probe(struct platform_device *pdev)
|
|||
c->valid_ops_mask &= REGULATOR_CHANGE_VOLTAGE
|
||||
| REGULATOR_CHANGE_MODE
|
||||
| REGULATOR_CHANGE_STATUS;
|
||||
switch (pdev->id) {
|
||||
switch (id) {
|
||||
case TWL4030_REG_VIO:
|
||||
case TWL4030_REG_VDD1:
|
||||
case TWL4030_REG_VDD2:
|
||||
|
@ -1091,7 +1252,7 @@ static int __devinit twlreg_probe(struct platform_device *pdev)
|
|||
break;
|
||||
}
|
||||
|
||||
switch (pdev->id) {
|
||||
switch (id) {
|
||||
case TWL6025_REG_SMPS3:
|
||||
if (twl_get_smps_mult() & SMPS_MULTOFFSET_SMPS3)
|
||||
info->flags |= SMPS_EXTENDED_EN;
|
||||
|
@ -1112,7 +1273,8 @@ static int __devinit twlreg_probe(struct platform_device *pdev)
|
|||
break;
|
||||
}
|
||||
|
||||
rdev = regulator_register(&info->desc, &pdev->dev, initdata, info, NULL);
|
||||
rdev = regulator_register(&info->desc, &pdev->dev, initdata, info,
|
||||
pdev->dev.of_node);
|
||||
if (IS_ERR(rdev)) {
|
||||
dev_err(&pdev->dev, "can't register %s, %ld\n",
|
||||
info->desc.name, PTR_ERR(rdev));
|
||||
|
@ -1149,8 +1311,11 @@ static struct platform_driver twlreg_driver = {
|
|||
/* NOTE: short name, to work around driver model truncation of
|
||||
* "twl_regulator.12" (and friends) to "twl_regulator.1".
|
||||
*/
|
||||
.driver.name = "twl_reg",
|
||||
.driver.owner = THIS_MODULE,
|
||||
.driver = {
|
||||
.name = "twl_reg",
|
||||
.owner = THIS_MODULE,
|
||||
.of_match_table = of_match_ptr(twl_of_match),
|
||||
},
|
||||
};
|
||||
|
||||
static int __init twlreg_init(void)
|
||||
|
|
|
@ -712,6 +712,9 @@ struct twl4030_platform_data {
|
|||
struct regulator_init_data *vaux1;
|
||||
struct regulator_init_data *vaux2;
|
||||
struct regulator_init_data *vaux3;
|
||||
struct regulator_init_data *vdd1;
|
||||
struct regulator_init_data *vdd2;
|
||||
struct regulator_init_data *vdd3;
|
||||
/* TWL4030 LDO regulators */
|
||||
struct regulator_init_data *vpll1;
|
||||
struct regulator_init_data *vpll2;
|
||||
|
@ -720,8 +723,6 @@ struct twl4030_platform_data {
|
|||
struct regulator_init_data *vsim;
|
||||
struct regulator_init_data *vaux4;
|
||||
struct regulator_init_data *vio;
|
||||
struct regulator_init_data *vdd1;
|
||||
struct regulator_init_data *vdd2;
|
||||
struct regulator_init_data *vintana1;
|
||||
struct regulator_init_data *vintana2;
|
||||
struct regulator_init_data *vintdig;
|
||||
|
@ -733,6 +734,8 @@ struct twl4030_platform_data {
|
|||
struct regulator_init_data *vcxio;
|
||||
struct regulator_init_data *vusb;
|
||||
struct regulator_init_data *clk32kg;
|
||||
struct regulator_init_data *v1v8;
|
||||
struct regulator_init_data *v2v1;
|
||||
/* TWL6025 LDO regulators */
|
||||
struct regulator_init_data *ldo1;
|
||||
struct regulator_init_data *ldo2;
|
||||
|
@ -749,6 +752,13 @@ struct twl4030_platform_data {
|
|||
struct regulator_init_data *vio6025;
|
||||
};
|
||||
|
||||
struct twl_regulator_driver_data {
|
||||
int (*set_voltage)(void *data, int target_uV);
|
||||
int (*get_voltage)(void *data);
|
||||
void *data;
|
||||
unsigned long features;
|
||||
};
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
int twl4030_sih_setup(int module);
|
||||
|
|
Loading…
Reference in New Issue