|
@@ -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.
|