diff options
Diffstat (limited to 'drivers/regulator')
-rw-r--r-- | drivers/regulator/twl-regulator.c | 39 |
1 files changed, 34 insertions, 5 deletions
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 { /* 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 +532,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; @@ -1060,6 +1080,7 @@ static int __devinit twlreg_probe(struct platform_device *pdev) struct regulator_init_data *initdata; struct regulation_constraints *c; struct regulator_dev *rdev; + struct twl_regulator_driver_data *drvdata; for (i = 0, info = NULL; i < ARRAY_SIZE(twl_regs); i++) { if (twl_regs[i].desc.id != pdev->id) @@ -1074,8 +1095,16 @@ static int __devinit twlreg_probe(struct platform_device *pdev) if (!initdata) return -EINVAL; - /* copy the features into regulator data */ - info->features = (unsigned long)initdata->driver_data; + drvdata = initdata->driver_data; + + if (!drvdata) + return -EINVAL; + + /* 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. |