regulator: tps65910: Add backup battery regulator
authorMarkus Pargmann <mpa@pengutronix.de>
Fri, 20 Dec 2013 11:43:27 +0000 (12:43 +0100)
committerMark Brown <broonie@linaro.org>
Sat, 21 Dec 2013 14:49:19 +0000 (14:49 +0000)
tps65910 has a backup battery charger with a configurable voltage. This
patch adds a regulator for the backup battery.

Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
Signed-off-by: Mark Brown <broonie@linaro.org>
Documentation/devicetree/bindings/mfd/tps65910.txt
drivers/regulator/tps65910-regulator.c
include/linux/mfd/tps65910.h

index 2e3304888ffc1c10e07b83fcec088d61dce6004d..b4bd98af1cc7979ec1f6c7c6645173cd5c8b2d35 100644 (file)
@@ -21,7 +21,7 @@ Required properties:
 
   The valid regulator-compatible values are:
   tps65910: vrtc, vio, vdd1, vdd2, vdd3, vdig1, vdig2, vpll, vdac, vaux1,
-            vaux2, vaux33, vmmc
+            vaux2, vaux33, vmmc, vbb
   tps65911: vrtc, vio, vdd1, vdd3, vddctrl, ldo1, ldo2, ldo3, ldo4, ldo5,
             ldo6, ldo7, ldo8
 
@@ -38,7 +38,7 @@ Required properties:
        vcc4-supply: VAUX1 and VAUX2 input.
        vcc5-supply: VPLL and VDAC input.
        vcc6-supply: VDIG1 and VDIG2 input.
-       vcc7-supply: VRTC input.
+       vcc7-supply: VRTC and VBB input.
        vccio-supply: VIO input.
   tps65911:
        vcc1-supply: VDD1 input.
index a00132e31ec7ab245f2017f13e110c6730c906fd..979ea0a99a79503e4f4a3f59bd8a1adac9d6d7dd 100644 (file)
@@ -88,6 +88,11 @@ static const unsigned int VMMC_VSEL_table[] = {
        1800000, 2800000, 3000000, 3300000,
 };
 
+/* supported BBCH voltages in microvolts */
+static const unsigned int VBB_VSEL_table[] = {
+       3000000, 2520000, 3150000, 5000000,
+};
+
 struct tps_info {
        const char *name;
        const char *vin_name;
@@ -183,6 +188,12 @@ static struct tps_info tps65910_regs[] = {
                .voltage_table = VMMC_VSEL_table,
                .enable_time_us = 100,
        },
+       {
+               .name = "vbb",
+               .vin_name = "vcc7",
+               .n_voltages = ARRAY_SIZE(VBB_VSEL_table),
+               .voltage_table = VBB_VSEL_table,
+       },
 };
 
 static struct tps_info tps65911_regs[] = {
@@ -339,6 +350,8 @@ static int tps65910_get_ctrl_register(int id)
                return TPS65910_VAUX33;
        case TPS65910_REG_VMMC:
                return TPS65910_VMMC;
+       case TPS65910_REG_VBB:
+               return TPS65910_BBCH;
        default:
                return -EINVAL;
        }
@@ -528,6 +541,10 @@ static int tps65910_get_voltage_sel(struct regulator_dev *dev)
                value &= LDO_SEL_MASK;
                value >>= LDO_SEL_SHIFT;
                break;
+       case TPS65910_REG_VBB:
+               value &= BBCH_BBSEL_MASK;
+               value >>= BBCH_BBSEL_SHIFT;
+               break;
        default:
                return -EINVAL;
        }
@@ -638,6 +655,9 @@ static int tps65910_set_voltage_sel(struct regulator_dev *dev,
        case TPS65910_REG_VMMC:
                return tps65910_reg_update_bits(pmic->mfd, reg, LDO_SEL_MASK,
                                                selector << LDO_SEL_SHIFT);
+       case TPS65910_REG_VBB:
+               return tps65910_reg_update_bits(pmic->mfd, reg, BBCH_BBSEL_MASK,
+                                               selector << BBCH_BBSEL_SHIFT);
        }
 
        return -EINVAL;
@@ -669,6 +689,9 @@ static int tps65911_set_voltage_sel(struct regulator_dev *dev,
        case TPS65910_REG_VIO:
                return tps65910_reg_update_bits(pmic->mfd, reg, LDO_SEL_MASK,
                                                selector << LDO_SEL_SHIFT);
+       case TPS65910_REG_VBB:
+               return tps65910_reg_update_bits(pmic->mfd, reg, BBCH_BBSEL_MASK,
+                                               selector << BBCH_BBSEL_SHIFT);
        }
 
        return -EINVAL;
@@ -762,6 +785,18 @@ static struct regulator_ops tps65910_ops_vdd3 = {
        .map_voltage            = regulator_map_voltage_ascend,
 };
 
+static struct regulator_ops tps65910_ops_vbb = {
+       .is_enabled             = regulator_is_enabled_regmap,
+       .enable                 = regulator_enable_regmap,
+       .disable                = regulator_disable_regmap,
+       .set_mode               = tps65910_set_mode,
+       .get_mode               = tps65910_get_mode,
+       .get_voltage_sel        = tps65910_get_voltage_sel,
+       .set_voltage_sel        = tps65910_set_voltage_sel,
+       .list_voltage           = regulator_list_voltage_table,
+       .map_voltage            = regulator_map_voltage_iterate,
+};
+
 static struct regulator_ops tps65910_ops = {
        .is_enabled             = regulator_is_enabled_regmap,
        .enable                 = regulator_enable_regmap,
@@ -944,6 +979,7 @@ static struct of_regulator_match tps65910_matches[] = {
        { .name = "vaux2",      .driver_data = (void *) &tps65910_regs[10] },
        { .name = "vaux33",     .driver_data = (void *) &tps65910_regs[11] },
        { .name = "vmmc",       .driver_data = (void *) &tps65910_regs[12] },
+       { .name = "vbb",        .driver_data = (void *) &tps65910_regs[13] },
 };
 
 static struct of_regulator_match tps65911_matches[] = {
@@ -1145,6 +1181,10 @@ static int tps65910_probe(struct platform_device *pdev)
                                pmic->desc[i].ops = &tps65910_ops_dcdc;
                                pmic->desc[i].ramp_delay = 5000;
                        }
+               } else if (i == TPS65910_REG_VBB &&
+                               tps65910_chip_id(tps65910) == TPS65910) {
+                       pmic->desc[i].ops = &tps65910_ops_vbb;
+                       pmic->desc[i].volt_table = info->voltage_table;
                } else {
                        if (tps65910_chip_id(tps65910) == TPS65910) {
                                pmic->desc[i].ops = &tps65910_ops;
@@ -1167,7 +1207,21 @@ static int tps65910_probe(struct platform_device *pdev)
                pmic->desc[i].type = REGULATOR_VOLTAGE;
                pmic->desc[i].owner = THIS_MODULE;
                pmic->desc[i].enable_reg = pmic->get_ctrl_reg(i);
-               pmic->desc[i].enable_mask = TPS65910_SUPPLY_STATE_ENABLED;
+
+               switch (i) {
+               case TPS65910_REG_VBB:
+                       if (tps65910_chip_id(tps65910) == TPS65910)
+                               pmic->desc[i].enable_mask = BBCH_BBCHEN_MASK;
+                       else
+                               pmic->desc[i].enable_mask =
+                                       TPS65910_SUPPLY_STATE_ENABLED;
+                       break;
+
+               default:
+                       pmic->desc[i].enable_mask =
+                               TPS65910_SUPPLY_STATE_ENABLED;
+                       break;
+               }
 
                config.dev = tps65910->dev;
                config.init_data = reg_data;
index 20e433e551e3b75d6849c0ed900a14bd4438c401..1adeee1861949626521f550ae06763665c0ce9d4 100644 (file)
 #define TPS65910_REG_VAUX2                             10
 #define TPS65910_REG_VAUX33                            11
 #define TPS65910_REG_VMMC                              12
+#define TPS65910_REG_VBB                               13
 
 #define TPS65911_REG_VDDCTRL                           4
 #define TPS65911_REG_LDO1                              5
 #define TPS65911_REG_LDO8                              12
 
 /* Max number of TPS65910/11 regulators */
-#define TPS65910_NUM_REGS                              13
+#define TPS65910_NUM_REGS                              14
 
 /* External sleep controls through EN1/EN2/EN3/SLEEP inputs */
 #define TPS65910_SLEEP_CONTROL_EXT_INPUT_EN1           0x1