Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/i2c Add sanity, flexibility and readability to TPS65...



details:   https://anonhg.NetBSD.org/src/rev/88178bd0bcf5
branches:  trunk
changeset: 786320:88178bd0bcf5
user:      rkujawa <rkujawa%NetBSD.org@localhost>
date:      Fri Apr 26 15:31:03 2013 +0000

description:
Add sanity, flexibility and readability to TPS65217 driver. In preparation to
add envsys support.

diffstat:

 sys/dev/i2c/tps65217pmic.c    |  372 ++++++++++++++++++++++++++++++-----------
 sys/dev/i2c/tps65217pmicreg.h |   28 +-
 2 files changed, 280 insertions(+), 120 deletions(-)

diffs (truncated from 497 to 300 lines):

diff -r 650c61bde574 -r 88178bd0bcf5 sys/dev/i2c/tps65217pmic.c
--- a/sys/dev/i2c/tps65217pmic.c        Fri Apr 26 11:01:28 2013 +0000
+++ b/sys/dev/i2c/tps65217pmic.c        Fri Apr 26 15:31:03 2013 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: tps65217pmic.c,v 1.1 2013/04/25 20:55:34 rkujawa Exp $ */
+/*     $NetBSD: tps65217pmic.c,v 1.2 2013/04/26 15:31:03 rkujawa Exp $ */
 
 /*-
  * Copyright (c) 2013 The NetBSD Foundation, Inc.
@@ -29,8 +29,13 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
+/* 
+ * Texas Instruments TPS65217 Power Management IC driver. 
+ * TODO: battery, sequencer
+ */
+
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tps65217pmic.c,v 1.1 2013/04/25 20:55:34 rkujawa Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tps65217pmic.c,v 1.2 2013/04/26 15:31:03 rkujawa Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -52,23 +57,10 @@
        uint8_t         sc_revision;
 };
 
-static int tps65217pmic_match(device_t, cfdata_t, void *);
-static void tps65217pmic_attach(device_t, device_t, void *);
 
-static uint8_t tps65217pmic_reg_read(struct tps65217pmic_softc *sc, 
-    uint8_t reg);
-
-static uint16_t tps65217pmic_ppath_max_usb_current(uint8_t ppath);
-static uint16_t tps65217pmic_ppath_max_ac_current(uint8_t ppath);
-
-static void tps65217pmic_print_status(struct tps65217pmic_softc *sc);
-static void tps65217pmic_version(struct tps65217pmic_softc *sc);
-
-CFATTACH_DECL_NEW(tps65217pmic, sizeof (struct tps65217pmic_softc),
-    tps65217pmic_match, tps65217pmic_attach, NULL, NULL);
-
+#define NTPS_REG       7
 /* Voltage regulators */
-enum tpsreg {
+enum tps_reg_num {
        TPS65217PMIC_LDO1,
        TPS65217PMIC_LDO2,
        TPS65217PMIC_LDO3LS,
@@ -78,6 +70,62 @@
        TPS65217PMIC_DCDC3
 }; 
 
+struct tps_reg_param {
+       /* parameters configured statically */
+
+       const char* name;
+       uint16_t voltage_min;           /* in mV */
+       uint16_t voltage_max;           /* in mV */
+       const uint16_t *voltages;       /* all possible voltage settings */
+       uint8_t nvoltages;              /* number of voltage settings */
+
+       bool can_track;                 /* regulator can track U of other r. */
+       struct tps_reg_param *tracked_reg; /* ptr to tracked regulator */
+       bool can_xadj;                  /* voltage can be adjusted externally */
+       bool can_ls;                    /* can be a load switch instead of r. */
+
+       uint8_t defreg_num;             /* DEF register */
+       uint8_t enable_bit;             /* position in ENABLE register */
+       
+       /*
+        * Run-time parameters configured during attachment and later, these
+        * probably should be split into separate struct that would be a part
+        * of softc. But since we can have only one TPS chip, that should be
+        * okay for now.
+        */
+
+       bool is_enabled;                /* regulator is enabled */
+       bool is_pg;                     /* regulator is "power good" */
+       bool is_tracking;               /* voltage is tracking other reg. */
+       bool is_ls;                     /* is a load switch */
+       bool is_xadj;                   /* voltage is adjusted externally */
+
+       uint16_t current_voltage;       /* in mV */
+
+};
+
+static int tps65217pmic_match(device_t, cfdata_t, void *);
+static void tps65217pmic_attach(device_t, device_t, void *);
+
+static uint8_t tps65217pmic_reg_read(struct tps65217pmic_softc *sc, 
+    uint8_t regno);
+
+static void tps65217pmic_refresh(struct tps65217pmic_softc *sc);
+
+static uint16_t tps65217pmic_ppath_max_usb_current(uint8_t ppath);
+static uint16_t tps65217pmic_ppath_max_ac_current(uint8_t ppath);
+
+static void tps65217pmic_regulator_read_config(struct tps65217pmic_softc 
+    *sc, struct tps_reg_param *regulator);
+
+static void tps65217pmic_print_ppath(struct tps65217pmic_softc *sc);
+static void tps65217pmic_print_ldos(struct tps65217pmic_softc *sc);
+
+static void tps65217pmic_version(struct tps65217pmic_softc *sc);
+
+CFATTACH_DECL_NEW(tps65217pmic, sizeof (struct tps65217pmic_softc),
+    tps65217pmic_match, tps65217pmic_attach, NULL, NULL);
+
 /* Possible settings of LDO1 in mV. */
 static const uint16_t ldo1voltages[] = { 1000, 1100, 1200, 1250, 1300, 1350, 
     1400, 1500, 1600, 1800, 2500, 2750, 2800, 3000, 3100, 3300 };
@@ -90,17 +138,120 @@
     3200, 3300, 3300, 3300, 3300, 3300, 3300, 3300, 3300 };
 /* Possible settings of LDO3, LDO4 in mV. */
 static const uint16_t ldo3voltages[] = { 1500, 1550, 1600, 1650, 1700, 1750, 
-    1800, 1850,1900, 2000, 2100, 2200, 2300, 2400, 2450, 2500,2550, 2600, 
+    1800, 1850, 1900, 2000, 2100, 2200, 2300, 2400, 2450, 2500, 2550, 2600, 
     2650, 2700, 2750, 2800, 2850, 2900,2950, 3000, 3050, 3100, 3150, 3200, 
     3250, 3300 };
 
+static struct tps_reg_param tps_regulators[] = {
+       { 
+               .name = "LDO1", 
+               .voltage_min = 1000, 
+               .voltage_max = 3300, 
+               .voltages = ldo1voltages,
+               .nvoltages = 16,
+               .can_track = false,
+               .tracked_reg = NULL,
+               .can_xadj =  false,
+               .can_ls = false,
+               .defreg_num = TPS65217PMIC_DEFLDO1,
+               .enable_bit = TPS65217PMIC_ENABLE_LDO1
+       },
+       { 
+               .name = "LDO2",
+               .voltage_min = 900, 
+               .voltage_max = 3300,
+               .voltages = ldo2voltages,
+               .nvoltages = 64,
+               .can_track = true,
+               .tracked_reg = &(tps_regulators[TPS65217PMIC_DCDC3]), 
+               .can_xadj = false,
+               .can_ls = false,
+               .defreg_num = TPS65217PMIC_DEFLDO2,
+               .enable_bit = TPS65217PMIC_ENABLE_LDO2
+       },
+       { 
+               .name = "LDO3",
+               .voltage_min = 1500, 
+               .voltage_max = 3300,
+               .voltages = ldo3voltages,
+               .nvoltages = 32,
+               .can_track = false,
+               .tracked_reg = NULL, 
+               .can_xadj = false,
+               .can_ls = true,
+               .defreg_num = TPS65217PMIC_DEFLDO3,
+               .enable_bit = TPS65217PMIC_ENABLE_LDO3
+       },
+       { 
+               .name = "LDO4",
+               .voltage_min = 1500, 
+               .voltage_max = 3300,
+               .voltages = ldo3voltages,
+               .nvoltages = 32,
+               .can_track = false,
+               .tracked_reg = NULL, 
+               .can_xadj = false,
+               .can_ls = true,
+               .defreg_num = TPS65217PMIC_DEFLDO4,
+               .enable_bit = TPS65217PMIC_ENABLE_LDO4
+       },
+       { 
+               .name = "DCDC1",
+               .voltage_min = 900, 
+               .voltage_max = 3300,
+               .voltages = ldo2voltages,
+               .nvoltages = 64,
+               .can_track = false,
+               .tracked_reg = NULL, 
+               .can_xadj = true,
+               .can_ls = false,
+               .defreg_num = TPS65217PMIC_DEFDCDC1,
+               .enable_bit = TPS65217PMIC_ENABLE_DCDC1
+       },
+       { 
+               .name = "DCDC2",
+               .voltage_min = 900, 
+               .voltage_max = 3300,
+               .voltages = ldo2voltages,
+               .nvoltages = 64,
+               .can_track = false,
+               .tracked_reg = NULL, 
+               .can_xadj = true,
+               .can_ls = false,
+               .defreg_num = TPS65217PMIC_DEFDCDC2,
+               .enable_bit = TPS65217PMIC_ENABLE_DCDC2 
+       },
+       { 
+               .name = "DCDC3",
+               .voltage_min = 900, 
+               .voltage_max = 3300,
+               .voltages = ldo2voltages,
+               .nvoltages = 64,
+               .can_track = false,
+               .tracked_reg = NULL, 
+               .can_xadj = true,
+               .can_ls = false,
+               .defreg_num = TPS65217PMIC_DEFDCDC3,
+               .enable_bit = TPS65217PMIC_ENABLE_DCDC3
+       }
+};
+
+static bool matched = false;
+
 static int
 tps65217pmic_match(device_t parent, cfdata_t cf, void *aux)
 {
        struct i2c_attach_args *ia = aux;
 
-       if (ia->ia_addr == TPS65217PMIC_ADDR)
+       if (ia->ia_addr == TPS65217PMIC_ADDR) {
+               /* we can only have one */
+               if (matched)
+                       return 0;
+               else
+                       matched = true;
+
                return 1;
+       }
        return 0;
 }
 
@@ -138,7 +289,22 @@
        aprint_normal(" Power Management Multi-Channel IC (rev 1.%d)\n", 
            sc->sc_revision);
 
-       tps65217pmic_print_status(sc);
+       tps65217pmic_refresh(sc);
+
+       tps65217pmic_print_ppath(sc);
+       tps65217pmic_print_ldos(sc);
+}
+
+static void
+tps65217pmic_refresh(struct tps65217pmic_softc *sc)
+{
+       int i;
+       struct tps_reg_param *c_reg;
+
+       for (i = 0; i < NTPS_REG; i++) {
+               c_reg = &tps_regulators[i];
+               tps65217pmic_regulator_read_config(sc, c_reg); 
+       }
 }
 
 /* Get version and revision of the chip. */
@@ -186,56 +352,100 @@
        return 0;
 }
 
-static uint16_t
-tps65217pmic_regulator_voltage(struct tps65217pmic_softc *sc, uint8_t regulator)
+/* Read regulator state and save it to tps_reg_param. */
+static void 
+tps65217pmic_regulator_read_config(struct tps65217pmic_softc *sc, struct 
+    tps_reg_param *regulator)
 {
-       uint8_t defreg;
+       uint8_t defreg, regenable;
+       uint16_t voltage;
+
+       regenable = tps65217pmic_reg_read(sc, TPS65217PMIC_ENABLE);
+
+       if (regenable & (regulator->enable_bit))
+               regulator->is_enabled = true;
+       else {
+               regulator->is_enabled = false;
+               return;
+       }
 
-       switch (regulator) {
-       case TPS65217PMIC_LDO1:
-               defreg = tps65217pmic_reg_read(sc, TPS65217PMIC_DEFLDO1);
-               return ldo1voltages[defreg];
-       case TPS65217PMIC_LDO2:
-               defreg = tps65217pmic_reg_read(sc, TPS65217PMIC_DEFLDO2);
-               if (defreg & TPS65217PMIC_DEFLDO2_TRACKING)
-                       return tps65217pmic_regulator_voltage(sc, 
-                           TPS65217PMIC_DCDC3);
-               return ldo2voltages[defreg & TPS65217PMIC_DEFLDO2_VOLTAGE];
-       case TPS65217PMIC_LDO3LS:
-               defreg = tps65217pmic_reg_read(sc, TPS65217PMIC_DEFLDO3);
-               if (!(defreg & TPS65217PMIC_DEFLDOX_LS))
-                       return 0;
-               return ldo3voltages[defreg & TPS65217PMIC_DEFLDO3_VOLTAGE];
-       case TPS65217PMIC_LDO4LS:



Home | Main Index | Thread Index | Old Index