regulator: palmas: fix build warnings
[linux-2.6.git] / drivers / regulator / pcf50633-regulator.c
index 70ba775..6db46c6 100644 (file)
 #include <linux/mfd/pcf50633/core.h>
 #include <linux/mfd/pcf50633/pmic.h>
 
-#define PCF50633_REGULATOR(_name, _id)                 \
+#define PCF50633_REGULATOR(_name, _id, _n)             \
        {                                       \
                .name = _name,                  \
                .id = _id,                      \
                .ops = &pcf50633_regulator_ops, \
+               .n_voltages = _n, \
                .type = REGULATOR_VOLTAGE,      \
                .owner = THIS_MODULE,           \
        }
@@ -107,7 +108,8 @@ static unsigned int ldo_voltage_value(u8 bits)
 }
 
 static int pcf50633_regulator_set_voltage(struct regulator_dev *rdev,
-                                               int min_uV, int max_uV)
+                                         int min_uV, int max_uV,
+                                         unsigned *selector)
 {
        struct pcf50633 *pcf;
        int regulator_id, millivolts;
@@ -140,42 +142,32 @@ static int pcf50633_regulator_set_voltage(struct regulator_dev *rdev,
        case PCF50633_REGULATOR_LDO5:
        case PCF50633_REGULATOR_LDO6:
        case PCF50633_REGULATOR_HCLDO:
+       case PCF50633_REGULATOR_MEMLDO:
                volt_bits = ldo_voltage_bits(millivolts);
                break;
        default:
                return -EINVAL;
        }
 
+       *selector = volt_bits;
+
        return pcf50633_reg_write(pcf, regnr, volt_bits);
 }
 
-static int pcf50633_regulator_get_voltage(struct regulator_dev *rdev)
+static int pcf50633_regulator_voltage_value(enum pcf50633_regulator_id id,
+                                               u8 bits)
 {
-       struct pcf50633 *pcf;
-       int regulator_id, millivolts, volt_bits;
-       u8 regnr;
-
-       pcf = rdev_get_drvdata(rdev);
-
-       regulator_id = rdev_get_id(rdev);
-       if (regulator_id >= PCF50633_NUM_REGULATORS)
-               return -EINVAL;
-
-       regnr = pcf50633_regulator_registers[regulator_id];
-
-       volt_bits = pcf50633_reg_read(pcf, regnr);
-       if (volt_bits < 0)
-               return -1;
+       int millivolts;
 
-       switch (regulator_id) {
+       switch (id) {
        case PCF50633_REGULATOR_AUTO:
-               millivolts = auto_voltage_value(volt_bits);
+               millivolts = auto_voltage_value(bits);
                break;
        case PCF50633_REGULATOR_DOWN1:
-               millivolts = down_voltage_value(volt_bits);
+               millivolts = down_voltage_value(bits);
                break;
        case PCF50633_REGULATOR_DOWN2:
-               millivolts = down_voltage_value(volt_bits);
+               millivolts = down_voltage_value(bits);
                break;
        case PCF50633_REGULATOR_LDO1:
        case PCF50633_REGULATOR_LDO2:
@@ -184,7 +176,8 @@ static int pcf50633_regulator_get_voltage(struct regulator_dev *rdev)
        case PCF50633_REGULATOR_LDO5:
        case PCF50633_REGULATOR_LDO6:
        case PCF50633_REGULATOR_HCLDO:
-               millivolts = ldo_voltage_value(volt_bits);
+       case PCF50633_REGULATOR_MEMLDO:
+               millivolts = ldo_voltage_value(bits);
                break;
        default:
                return -EINVAL;
@@ -193,6 +186,46 @@ static int pcf50633_regulator_get_voltage(struct regulator_dev *rdev)
        return millivolts * 1000;
 }
 
+static int pcf50633_regulator_get_voltage(struct regulator_dev *rdev)
+{
+       struct pcf50633 *pcf;
+       int regulator_id;
+       u8 volt_bits, regnr;
+
+       pcf = rdev_get_drvdata(rdev);
+
+       regulator_id = rdev_get_id(rdev);
+       if (regulator_id >= PCF50633_NUM_REGULATORS)
+               return -EINVAL;
+
+       regnr = pcf50633_regulator_registers[regulator_id];
+
+       volt_bits = pcf50633_reg_read(pcf, regnr);
+
+       return pcf50633_regulator_voltage_value(regulator_id, volt_bits);
+}
+
+static int pcf50633_regulator_list_voltage(struct regulator_dev *rdev,
+                                               unsigned int index)
+{
+       struct pcf50633 *pcf;
+       int regulator_id;
+
+       pcf = rdev_get_drvdata(rdev);
+
+       regulator_id = rdev_get_id(rdev);
+
+       switch (regulator_id) {
+       case PCF50633_REGULATOR_AUTO:
+               index += 0x2f;
+               break;
+       default:
+               break;
+       }
+
+       return pcf50633_regulator_voltage_value(regulator_id, index);
+}
+
 static int pcf50633_regulator_enable(struct regulator_dev *rdev)
 {
        struct pcf50633 *pcf = rdev_get_drvdata(rdev);
@@ -246,6 +279,7 @@ static int pcf50633_regulator_is_enabled(struct regulator_dev *rdev)
 static struct regulator_ops pcf50633_regulator_ops = {
        .set_voltage = pcf50633_regulator_set_voltage,
        .get_voltage = pcf50633_regulator_get_voltage,
+       .list_voltage = pcf50633_regulator_list_voltage,
        .enable = pcf50633_regulator_enable,
        .disable = pcf50633_regulator_disable,
        .is_enabled = pcf50633_regulator_is_enabled,
@@ -253,27 +287,27 @@ static struct regulator_ops pcf50633_regulator_ops = {
 
 static struct regulator_desc regulators[] = {
        [PCF50633_REGULATOR_AUTO] =
-               PCF50633_REGULATOR("auto", PCF50633_REGULATOR_AUTO),
+               PCF50633_REGULATOR("auto", PCF50633_REGULATOR_AUTO, 81),
        [PCF50633_REGULATOR_DOWN1] =
-               PCF50633_REGULATOR("down1", PCF50633_REGULATOR_DOWN1),
+               PCF50633_REGULATOR("down1", PCF50633_REGULATOR_DOWN1, 96),
        [PCF50633_REGULATOR_DOWN2] =
-               PCF50633_REGULATOR("down2", PCF50633_REGULATOR_DOWN2),
+               PCF50633_REGULATOR("down2", PCF50633_REGULATOR_DOWN2, 96),
        [PCF50633_REGULATOR_LDO1] =
-               PCF50633_REGULATOR("ldo1", PCF50633_REGULATOR_LDO1),
+               PCF50633_REGULATOR("ldo1", PCF50633_REGULATOR_LDO1, 28),
        [PCF50633_REGULATOR_LDO2] =
-               PCF50633_REGULATOR("ldo2", PCF50633_REGULATOR_LDO2),
+               PCF50633_REGULATOR("ldo2", PCF50633_REGULATOR_LDO2, 28),
        [PCF50633_REGULATOR_LDO3] =
-               PCF50633_REGULATOR("ldo3", PCF50633_REGULATOR_LDO3),
+               PCF50633_REGULATOR("ldo3", PCF50633_REGULATOR_LDO3, 28),
        [PCF50633_REGULATOR_LDO4] =
-               PCF50633_REGULATOR("ldo4", PCF50633_REGULATOR_LDO4),
+               PCF50633_REGULATOR("ldo4", PCF50633_REGULATOR_LDO4, 28),
        [PCF50633_REGULATOR_LDO5] =
-               PCF50633_REGULATOR("ldo5", PCF50633_REGULATOR_LDO5),
+               PCF50633_REGULATOR("ldo5", PCF50633_REGULATOR_LDO5, 28),
        [PCF50633_REGULATOR_LDO6] =
-               PCF50633_REGULATOR("ldo6", PCF50633_REGULATOR_LDO6),
+               PCF50633_REGULATOR("ldo6", PCF50633_REGULATOR_LDO6, 28),
        [PCF50633_REGULATOR_HCLDO] =
-               PCF50633_REGULATOR("hcldo", PCF50633_REGULATOR_HCLDO),
+               PCF50633_REGULATOR("hcldo", PCF50633_REGULATOR_HCLDO, 28),
        [PCF50633_REGULATOR_MEMLDO] =
-               PCF50633_REGULATOR("memldo", PCF50633_REGULATOR_MEMLDO),
+               PCF50633_REGULATOR("memldo", PCF50633_REGULATOR_MEMLDO, 28),
 };
 
 static int __devinit pcf50633_regulator_probe(struct platform_device *pdev)
@@ -282,13 +316,15 @@ static int __devinit pcf50633_regulator_probe(struct platform_device *pdev)
        struct pcf50633 *pcf;
 
        /* Already set by core driver */
-       pcf = platform_get_drvdata(pdev);
+       pcf = dev_to_pcf50633(pdev->dev.parent);
 
        rdev = regulator_register(&regulators[pdev->id], &pdev->dev,
-                                 pdev->dev.platform_data, pcf);
+                                 pdev->dev.platform_data, pcf, NULL);
        if (IS_ERR(rdev))
                return PTR_ERR(rdev);
 
+       platform_set_drvdata(pdev, rdev);
+
        if (pcf->pdata->regulator_registered)
                pcf->pdata->regulator_registered(pcf, pdev->id);
 
@@ -299,6 +335,7 @@ static int __devexit pcf50633_regulator_remove(struct platform_device *pdev)
 {
        struct regulator_dev *rdev = platform_get_drvdata(pdev);
 
+       platform_set_drvdata(pdev, NULL);
        regulator_unregister(rdev);
 
        return 0;