summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcel Ziswiler <marcel.ziswiler@toradex.com>2012-07-17 16:45:14 +0200
committerMarcel Ziswiler <marcel.ziswiler@toradex.com>2012-07-17 16:45:14 +0200
commit3a008052e87426fdf3b29752432470a648453d69 (patch)
tree0c0fcd3c7ae3eec717caf3f9ba7452b7f1831a3f
parent4f48c4961b86b4df1bcb4b1b535bc1c3d158b5af (diff)
regulator: tps6586x support for tps658623 and tps658643
From a regulator point of view those PMICs differentiate in their SM2 voltage tables. While the older tps658621a and tps658621d as utilised on Harmony resp. Ventana have a range from 3000 to 4550 mV the tps658623 goes from 1700 to 2475 mV and the tps658643 just from 1025 to 1800 mV. Using its VERSIONCRC register the type of PMIC is queried and the right ranges applied.
-rw-r--r--arch/arm/configs/colibri_t20_defconfig1
-rw-r--r--drivers/mfd/tps6586x.c40
-rw-r--r--drivers/regulator/Kconfig5
-rw-r--r--drivers/regulator/tps6586x-regulator.c88
-rw-r--r--include/linux/mfd/tps6586x.h10
5 files changed, 98 insertions, 46 deletions
diff --git a/arch/arm/configs/colibri_t20_defconfig b/arch/arm/configs/colibri_t20_defconfig
index b77bbe272bb9..175df0e21637 100644
--- a/arch/arm/configs/colibri_t20_defconfig
+++ b/arch/arm/configs/colibri_t20_defconfig
@@ -303,7 +303,6 @@ CONFIG_REGULATOR_FIXED_VOLTAGE=y
CONFIG_REGULATOR_VIRTUAL_CONSUMER=y
CONFIG_REGULATOR_MAX8907C=y
CONFIG_REGULATOR_TPS6586X=y
-CONFIG_REGULATOR_TPS658623=y
CONFIG_MEDIA_SUPPORT=y
CONFIG_VIDEO_DEV=y
CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
diff --git a/drivers/mfd/tps6586x.c b/drivers/mfd/tps6586x.c
index 9a146c8bba92..1c140e5ace4f 100644
--- a/drivers/mfd/tps6586x.c
+++ b/drivers/mfd/tps6586x.c
@@ -96,6 +96,7 @@ struct tps6586x {
struct mutex lock;
struct device *dev;
struct i2c_client *client;
+ enum tps6586x_type type;
struct gpio_chip gpio;
struct irq_chip irq_chip;
@@ -255,6 +256,14 @@ out:
}
EXPORT_SYMBOL_GPL(tps6586x_update);
+enum tps6586x_type tps6586x_gettype(struct device *dev)
+{
+ struct tps6586x *tps6586x = dev_get_drvdata(dev);
+
+ return tps6586x->type;
+}
+EXPORT_SYMBOL_GPL(tps6586x_gettype);
+
static struct i2c_client *tps6586x_i2c_client = NULL;
static void tps6586x_power_off(void)
{
@@ -517,17 +526,36 @@ static int __devinit tps6586x_i2c_probe(struct i2c_client *client,
return -ENOTSUPP;
}
+ tps6586x = kzalloc(sizeof(struct tps6586x), GFP_KERNEL);
+ if (tps6586x == NULL)
+ return -ENOMEM;
+
ret = i2c_smbus_read_byte_data(client, TPS6586X_VERSIONCRC);
if (ret < 0) {
dev_err(&client->dev, "Chip ID read failed: %d\n", ret);
- return -EIO;
+ ret = -EIO;
+ goto err_irq_init;
+ }
+ tps6586x->type = (enum tps6586x_type)ret;
+ switch (ret) {
+ case TPS658621A:
+ dev_info(&client->dev, "found TPS658621A, ");
+ break;
+ case TPS658621D:
+ dev_info(&client->dev, "found TPS658621D, ");
+ break;
+ case TPS658623:
+ dev_info(&client->dev, "found TPS658623, ");
+ break;
+ case TPS658643:
+ dev_info(&client->dev, "found TPS658643, ");
+ break;
+ default:
+ dev_info(&client->dev, "unknown TPS6586X found, ");
+ tps6586x->type = TPS6586X_ANY;
}
- dev_info(&client->dev, "VERSIONCRC is %02x\n", ret);
-
- tps6586x = kzalloc(sizeof(struct tps6586x), GFP_KERNEL);
- if (tps6586x == NULL)
- return -ENOMEM;
+ printk("VERSIONCRC is %02x\n", ret);
tps6586x->client = client;
tps6586x->dev = &client->dev;
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index c3b94771d451..d3cb8e6ff099 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -319,11 +319,6 @@ config REGULATOR_TPS6586X
help
This driver supports TPS6586X voltage regulator chips.
-config REGULATOR_TPS658623
- depends on REGULATOR_TPS6586X
- default n
- bool "Use voltage tables suitable for TPS658623."
-
config REGULATOR_TPS6524X
tristate "TI TPS6524X Power regulators"
depends on SPI
diff --git a/drivers/regulator/tps6586x-regulator.c b/drivers/regulator/tps6586x-regulator.c
index acef70550c7e..43a3a11db46c 100644
--- a/drivers/regulator/tps6586x-regulator.c
+++ b/drivers/regulator/tps6586x-regulator.c
@@ -64,6 +64,7 @@ struct tps6586x_regulator {
int enable_reg[2];
int *voltages;
int delay; /* delay in us for regulator to stabilize */
+ enum tps6586x_type type;
/* for DVM regulators */
int go_reg;
@@ -229,14 +230,19 @@ static int tps6586x_ldo4_voltages[] = {
2300, 2325, 2350, 2375, 2400, 2425, 2450, 2475,
};
-#ifndef CONFIG_REGULATOR_TPS658623
static int tps6586x_sm2_voltages[] = {
3000, 3050, 3100, 3150, 3200, 3250, 3300, 3350,
3400, 3450, 3500, 3550, 3600, 3650, 3700, 3750,
3800, 3850, 3900, 3950, 4000, 4050, 4100, 4150,
4200, 4250, 4300, 4350, 4400, 4450, 4500, 4550,
};
-#endif /* !CONFIG_REGULATOR_TPS658623 */
+
+static int tps6586x_sm2fortythree_voltages[] = {
+ 1025, 1225, 1425, 1625, 1050, 1250, 1450, 1650,
+ 1075, 1275, 1475, 1675, 1100, 1300, 1500, 1700,
+ 1125, 1325, 1525, 1725, 1150, 1350, 1550, 1750,
+ 1175, 1375, 1575, 1775, 1200, 1400, 1600, 1800,
+};
static int tps6586x_dvm_voltages[] = {
725, 750, 775, 800, 825, 850, 875, 900,
@@ -245,7 +251,7 @@ static int tps6586x_dvm_voltages[] = {
1325, 1350, 1375, 1400, 1425, 1450, 1475, 1500,
};
-#define TPS6586X_REGULATOR(_id, vdata, _ops, vreg, shift, nbits, \
+#define TPS6586X_REGULATOR(_id, _type, vdata, _ops, vreg, shift, nbits, \
ereg0, ebit0, ereg1, ebit1, en_time) \
.desc = { \
.name = "REG-" #_id, \
@@ -263,48 +269,62 @@ static int tps6586x_dvm_voltages[] = {
.enable_reg[1] = TPS6586X_SUPPLY##ereg1, \
.enable_bit[1] = (ebit1), \
.voltages = tps6586x_##vdata##_voltages, \
- .delay = en_time,
+ .delay = en_time, \
+ .type = (_type),
#define TPS6586X_REGULATOR_DVM_GOREG(goreg, gobit) \
.go_reg = TPS6586X_##goreg, \
.go_bit = (gobit),
-#define TPS6586X_LDO(_id, vdata, vreg, shift, nbits, \
+#define TPS6586X_LDO(_id, type, vdata, vreg, shift, nbits, \
ereg0, ebit0, ereg1, ebit1, en_time) \
{ \
- TPS6586X_REGULATOR(_id, vdata, ldo_ops, vreg, shift, nbits, \
- ereg0, ebit0, ereg1, ebit1, en_time) \
+ TPS6586X_REGULATOR(_id, type, vdata, ldo_ops, vreg, shift, \
+ nbits, ereg0, ebit0, ereg1, ebit1, en_time) \
}
-#define TPS6586X_DVM(_id, vdata, vreg, shift, nbits, \
+#define TPS6586X_DVM(_id, type, vdata, vreg, shift, nbits, \
ereg0, ebit0, ereg1, ebit1, goreg, gobit, en_time) \
{ \
- TPS6586X_REGULATOR(_id, vdata, dvm_ops, vreg, shift, nbits, \
- ereg0, ebit0, ereg1, ebit1, en_time) \
+ TPS6586X_REGULATOR(_id, type, vdata, dvm_ops, vreg, shift, \
+ nbits, ereg0, ebit0, ereg1, ebit1, en_time) \
TPS6586X_REGULATOR_DVM_GOREG(goreg, gobit) \
}
+/* Note: type ANY means universal, search order matters, place ANY last */
static struct tps6586x_regulator tps6586x_regulator[] = {
- TPS6586X_LDO(LDO_0, ldo0, SUPPLYV1, 5, 3, ENC, 0, END, 0, 4000),
- TPS6586X_LDO(LDO_1, dvm, SUPPLYV1, 0, 5, ENC, 1, END, 1, 4000),
- TPS6586X_LDO(LDO_3, ldo, SUPPLYV4, 0, 3, ENC, 2, END, 2, 3000),
- TPS6586X_LDO(LDO_5, ldo, SUPPLYV6, 0, 3, ENE, 6, ENE, 6, 3000),
- TPS6586X_LDO(LDO_6, ldo, SUPPLYV3, 0, 3, ENC, 4, END, 4, 15000),
- TPS6586X_LDO(LDO_7, ldo, SUPPLYV3, 3, 3, ENC, 5, END, 5, 15000),
- TPS6586X_LDO(LDO_8, ldo, SUPPLYV2, 5, 3, ENC, 6, END, 6, 15000),
- TPS6586X_LDO(LDO_9, ldo, SUPPLYV6, 3, 3, ENE, 7, ENE, 7, 3000),
- TPS6586X_LDO(LDO_RTC, ldo, SUPPLYV4, 3, 3, V4, 7, V4, 7, 0),
-#ifndef CONFIG_REGULATOR_TPS658623
- TPS6586X_LDO(SM_2, sm2, SUPPLYV2, 0, 5, ENC, 7, END, 7, 0),
-#endif
-
- TPS6586X_DVM(LDO_2, dvm, LDO2BV1, 0, 5, ENA, 3, ENB, 3, VCC2, 6, 3000),
- TPS6586X_DVM(SM_0, dvm, SM0V1, 0, 5, ENA, 1, ENB, 1, VCC1, 2, 4000),
- TPS6586X_DVM(SM_1, dvm, SM1V1, 0, 5, ENA, 0, ENB, 0, VCC1, 0, 4000),
-#ifdef CONFIG_REGULATOR_TPS658623
- TPS6586X_DVM(SM_2, ldo4, SUPPLYV2, 0, 5, ENC, 3, END, 3, VCC1, 6, 15000),
-#endif
- TPS6586X_DVM(LDO_4, ldo4, LDO4V1, 0, 5, ENC, 3, END, 3, VCC1, 6, 15000),
+ TPS6586X_LDO(LDO_0, TPS6586X_ANY, ldo0, SUPPLYV1, 5, 3, ENC, 0, END, 0,
+ 4000),
+ TPS6586X_LDO(LDO_1, TPS6586X_ANY, dvm, SUPPLYV1, 0, 5, ENC, 1, END, 1,
+ 4000),
+ TPS6586X_DVM(LDO_2, TPS6586X_ANY, dvm, LDO2BV1, 0, 5, ENA, 3, ENB, 3,
+ VCC2, 6, 3000),
+ TPS6586X_LDO(LDO_3, TPS6586X_ANY, ldo, SUPPLYV4, 0, 3, ENC, 2, END, 2,
+ 3000),
+ TPS6586X_DVM(LDO_4, TPS6586X_ANY, ldo4, LDO4V1, 0, 5, ENC, 3, END, 3,
+ VCC1, 6, 15000),
+ TPS6586X_LDO(LDO_5, TPS6586X_ANY, ldo, SUPPLYV6, 0, 3, ENE, 6, ENE, 6,
+ 3000),
+ TPS6586X_LDO(LDO_6, TPS6586X_ANY, ldo, SUPPLYV3, 0, 3, ENC, 4, END, 4,
+ 15000),
+ TPS6586X_LDO(LDO_7, TPS6586X_ANY, ldo, SUPPLYV3, 3, 3, ENC, 5, END, 5,
+ 15000),
+ TPS6586X_LDO(LDO_8, TPS6586X_ANY, ldo, SUPPLYV2, 5, 3, ENC, 6, END, 6,
+ 15000),
+ TPS6586X_LDO(LDO_9, TPS6586X_ANY, ldo, SUPPLYV6, 3, 3, ENE, 7, ENE, 7,
+ 3000),
+ TPS6586X_LDO(LDO_RTC, TPS6586X_ANY, ldo, SUPPLYV4, 3, 3, V4, 7, V4, 7,
+ 0),
+ TPS6586X_DVM(SM_0, TPS6586X_ANY, dvm, SM0V1, 0, 5, ENA, 1, ENB, 1,
+ VCC1, 2, 4000),
+ TPS6586X_DVM(SM_1, TPS6586X_ANY, dvm, SM1V1, 0, 5, ENA, 0, ENB, 0,
+ VCC1, 0, 4000),
+ TPS6586X_DVM(SM_2, TPS658623, ldo4, SUPPLYV2, 0, 5, ENC, 3, END, 3,
+ VCC1, 6, 15000),
+ TPS6586X_DVM(SM_2, TPS658643, sm2fortythree, SUPPLYV2, 0, 5, ENC, 3,
+ END, 3, VCC1, 6, 15000),
+ TPS6586X_LDO(SM_2, TPS6586X_ANY, sm2, SUPPLYV2, 0, 5, ENC, 7, END, 7,
+ 0),
};
/*
@@ -406,14 +426,16 @@ static inline int tps6586x_regulator_set_slew_rate(struct platform_device *pdev)
return tps6586x_write(parent, reg, setting->slew_rate);
}
-static inline struct tps6586x_regulator *find_regulator_info(int id)
+static inline struct tps6586x_regulator *find_regulator_info(int id,
+ enum tps6586x_type type)
{
struct tps6586x_regulator *ri;
int i;
for (i = 0; i < ARRAY_SIZE(tps6586x_regulator); i++) {
ri = &tps6586x_regulator[i];
- if (ri->desc.id == id)
+ if ((ri->desc.id == id) && ((ri->type == type) ||
+ (ri->type == TPS6586X_ANY)))
return ri;
}
return NULL;
@@ -428,7 +450,7 @@ static int __devinit tps6586x_regulator_probe(struct platform_device *pdev)
dev_dbg(&pdev->dev, "Probing reulator %d\n", id);
- ri = find_regulator_info(id);
+ ri = find_regulator_info(id, tps6586x_gettype(pdev->dev.parent));
if (ri == NULL) {
dev_err(&pdev->dev, "invalid regulator ID specified\n");
return -EINVAL;
diff --git a/include/linux/mfd/tps6586x.h b/include/linux/mfd/tps6586x.h
index 702cee59cc7b..b5e990e9f6ee 100644
--- a/include/linux/mfd/tps6586x.h
+++ b/include/linux/mfd/tps6586x.h
@@ -56,7 +56,6 @@ enum pwm_pfm_mode {
PWM_ONLY,
AUTO_PWM_PFM,
PWM_DEFAULT_VALUE,
-
};
enum slew_rate_settings {
@@ -71,6 +70,14 @@ enum slew_rate_settings {
SLEW_RATE_DEFAULT_VALUE,
};
+enum tps6586x_type {
+ TPS658621A = 0x15,
+ TPS658621D = 0x2c,
+ TPS658623 = 0x1b,
+ TPS658643 = 0x03,
+ TPS6586X_ANY = -1,
+};
+
struct tps6586x_settings {
/* SM0, SM1 and SM2 have PWM-only and auto PWM/PFM mode */
enum pwm_pfm_mode sm_pwm_mode;
@@ -128,5 +135,6 @@ extern int tps6586x_set_bits(struct device *dev, int reg, uint8_t bit_mask);
extern int tps6586x_clr_bits(struct device *dev, int reg, uint8_t bit_mask);
extern int tps6586x_update(struct device *dev, int reg, uint8_t val,
uint8_t mask);
+extern enum tps6586x_type tps6586x_gettype(struct device *dev);
#endif /*__LINUX_MFD_TPS6586X_H */