regulator: twl4030: add support for external voltage get/set
[pandora-kernel.git] / drivers / regulator / twl-regulator.c
index 11cc308..f6918bf 100644 (file)
@@ -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;
@@ -1052,6 +1072,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)
@@ -1066,8 +1087,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.