aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorTero Kristo <t-kristo@ti.com>2012-02-16 05:27:52 -0500
committerMark Brown <broonie@opensource.wolfsonmicro.com>2012-03-11 16:08:45 -0400
commit63bfff4e20211b464cbea6e79e5fd36df227c154 (patch)
tree4ea7a62c37820578be7ecbc943f6e62a017c64e4 /drivers
parenta33b6e5a8fb5fadeef206bacef13117e8a3080c4 (diff)
regulator: twl4030: add support for external voltage get/set
This is needed for SMPS regulators, which use the OMAP voltage processor for voltage get/set functions instead of the normal I2C channel. For this purpose, regulator_init_data->driver_data contents are expanded, it is now a struct which contains function pointers for the set/get voltage operations, a data pointer for these, and the previously used features bitmask. Signed-off-by: Tero Kristo <t-kristo@ti.com> Acked-by: Samuel Ortiz <sameo@linux.intel.com> [for the MFD part] Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mfd/twl-core.c16
-rw-r--r--drivers/regulator/twl-regulator.c39
2 files changed, 49 insertions, 6 deletions
diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c
index e04e04ddc15e..fae5f76d6ccb 100644
--- a/drivers/mfd/twl-core.c
+++ b/drivers/mfd/twl-core.c
@@ -619,6 +619,8 @@ add_regulator_linked(int num, struct regulator_init_data *pdata,
619 unsigned num_consumers, unsigned long features) 619 unsigned num_consumers, unsigned long features)
620{ 620{
621 unsigned sub_chip_id; 621 unsigned sub_chip_id;
622 struct twl_regulator_driver_data drv_data;
623
622 /* regulator framework demands init_data ... */ 624 /* regulator framework demands init_data ... */
623 if (!pdata) 625 if (!pdata)
624 return NULL; 626 return NULL;
@@ -628,7 +630,19 @@ add_regulator_linked(int num, struct regulator_init_data *pdata,
628 pdata->num_consumer_supplies = num_consumers; 630 pdata->num_consumer_supplies = num_consumers;
629 } 631 }
630 632
631 pdata->driver_data = (void *)features; 633 if (pdata->driver_data) {
634 /* If we have existing drv_data, just add the flags */
635 struct twl_regulator_driver_data *tmp;
636 tmp = pdata->driver_data;
637 tmp->features |= features;
638 } else {
639 /* add new driver data struct, used only during init */
640 drv_data.features = features;
641 drv_data.set_voltage = NULL;
642 drv_data.get_voltage = NULL;
643 drv_data.data = NULL;
644 pdata->driver_data = &drv_data;
645 }
632 646
633 /* NOTE: we currently ignore regulator IRQs, e.g. for short circuits */ 647 /* NOTE: we currently ignore regulator IRQs, e.g. for short circuits */
634 sub_chip_id = twl_map[TWL_MODULE_PM_MASTER].sid; 648 sub_chip_id = twl_map[TWL_MODULE_PM_MASTER].sid;
diff --git a/drivers/regulator/twl-regulator.c b/drivers/regulator/twl-regulator.c
index e5d222342157..7ff8bb22d569 100644
--- a/drivers/regulator/twl-regulator.c
+++ b/drivers/regulator/twl-regulator.c
@@ -58,6 +58,16 @@ struct twlreg_info {
58 58
59 /* chip specific features */ 59 /* chip specific features */
60 unsigned long features; 60 unsigned long features;
61
62 /*
63 * optional override functions for voltage set/get
64 * these are currently only used for SMPS regulators
65 */
66 int (*get_voltage)(void *data);
67 int (*set_voltage)(void *data, int target_uV);
68
69 /* data passed from board for external get/set voltage */
70 void *data;
61}; 71};
62 72
63 73
@@ -522,15 +532,25 @@ twl4030smps_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV,
522 struct twlreg_info *info = rdev_get_drvdata(rdev); 532 struct twlreg_info *info = rdev_get_drvdata(rdev);
523 int vsel = DIV_ROUND_UP(min_uV - 600000, 12500); 533 int vsel = DIV_ROUND_UP(min_uV - 600000, 12500);
524 534
525 twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_VOLTAGE_SMPS_4030, 535 if (info->set_voltage) {
526 vsel); 536 return info->set_voltage(info->data, min_uV);
537 } else {
538 twlreg_write(info, TWL_MODULE_PM_RECEIVER,
539 VREG_VOLTAGE_SMPS_4030, vsel);
540 }
541
527 return 0; 542 return 0;
528} 543}
529 544
530static int twl4030smps_get_voltage(struct regulator_dev *rdev) 545static int twl4030smps_get_voltage(struct regulator_dev *rdev)
531{ 546{
532 struct twlreg_info *info = rdev_get_drvdata(rdev); 547 struct twlreg_info *info = rdev_get_drvdata(rdev);
533 int vsel = twlreg_read(info, TWL_MODULE_PM_RECEIVER, 548 int vsel;
549
550 if (info->get_voltage)
551 return info->get_voltage(info->data);
552
553 vsel = twlreg_read(info, TWL_MODULE_PM_RECEIVER,
534 VREG_VOLTAGE_SMPS_4030); 554 VREG_VOLTAGE_SMPS_4030);
535 555
536 return vsel * 12500 + 600000; 556 return vsel * 12500 + 600000;
@@ -1060,6 +1080,7 @@ static int __devinit twlreg_probe(struct platform_device *pdev)
1060 struct regulator_init_data *initdata; 1080 struct regulator_init_data *initdata;
1061 struct regulation_constraints *c; 1081 struct regulation_constraints *c;
1062 struct regulator_dev *rdev; 1082 struct regulator_dev *rdev;
1083 struct twl_regulator_driver_data *drvdata;
1063 1084
1064 for (i = 0, info = NULL; i < ARRAY_SIZE(twl_regs); i++) { 1085 for (i = 0, info = NULL; i < ARRAY_SIZE(twl_regs); i++) {
1065 if (twl_regs[i].desc.id != pdev->id) 1086 if (twl_regs[i].desc.id != pdev->id)
@@ -1074,8 +1095,16 @@ static int __devinit twlreg_probe(struct platform_device *pdev)
1074 if (!initdata) 1095 if (!initdata)
1075 return -EINVAL; 1096 return -EINVAL;
1076 1097
1077 /* copy the features into regulator data */ 1098 drvdata = initdata->driver_data;
1078 info->features = (unsigned long)initdata->driver_data; 1099
1100 if (!drvdata)
1101 return -EINVAL;
1102
1103 /* copy the driver data into regulator data */
1104 info->features = drvdata->features;
1105 info->data = drvdata->data;
1106 info->set_voltage = drvdata->set_voltage;
1107 info->get_voltage = drvdata->get_voltage;
1079 1108
1080 /* Constrain board-specific capabilities according to what 1109 /* Constrain board-specific capabilities according to what
1081 * this driver and the chip itself can actually do. 1110 * this driver and the chip itself can actually do.