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 AS3722 SD4 regulator frobbing bits.



details:   https://anonhg.NetBSD.org/src/rev/49dc4b248b5c
branches:  trunk
changeset: 823632:49dc4b248b5c
user:      jakllsch <jakllsch%NetBSD.org@localhost>
date:      Sat Apr 29 19:56:59 2017 +0000

description:
Add AS3722 SD4 regulator frobbing bits.

Reduces aprint_error counter with TEGRA kernel on Jetson TK1 to 1 from 3.

diffstat:

 sys/dev/i2c/as3722.c |  95 ++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 93 insertions(+), 2 deletions(-)

diffs (144 lines):

diff -r 0431a9c4de29 -r 49dc4b248b5c sys/dev/i2c/as3722.c
--- a/sys/dev/i2c/as3722.c      Sat Apr 29 18:31:43 2017 +0000
+++ b/sys/dev/i2c/as3722.c      Sat Apr 29 19:56:59 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: as3722.c,v 1.9 2017/04/22 23:50:13 jmcneill Exp $ */
+/* $NetBSD: as3722.c,v 1.10 2017/04/29 19:56:59 jakllsch Exp $ */
 
 /*-
  * Copyright (c) 2015 Jared D. McNeill <jmcneill%invisible.ca@localhost>
@@ -29,7 +29,7 @@
 #include "opt_fdt.h"
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: as3722.c,v 1.9 2017/04/22 23:50:13 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: as3722.c,v 1.10 2017/04/29 19:56:59 jakllsch Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -55,6 +55,8 @@
 
 #define AS3722_SD0_VOLTAGE_REG         0x00
 
+#define AS3722_SD4_VOLTAGE_REG         0x04
+
 #define AS3722_GPIO0_CTRL_REG          0x08
 #define AS3722_GPIO0_CTRL_INVERT       __BIT(7)
 #define AS3722_GPIO0_CTRL_IOSF         __BITS(6,3)
@@ -80,6 +82,9 @@
 #define AS3722_WATCHDOG_SIGNAL_PWM_DIV __BITS(7,6)
 #define AS3722_WATCHDOG_SIGNAL_SW_SIG  __BIT(0)
 
+#define AS3722_SDCONTROL_REG           0x4d
+#define AS3722_SDCONTROL_SD4_ENABLE    __BIT(4)
+
 #define AS3722_LDOCONTROL0_REG         0x4e
 
 #define AS3722_RTC_CONTROL_REG         0x60
@@ -109,6 +114,8 @@
 #ifdef FDT
 static int     as3722reg_set_voltage_sd0(device_t, u_int, u_int);
 static int     as3722reg_get_voltage_sd0(device_t, u_int *);
+static int     as3722reg_set_voltage_sd4(device_t, u_int, u_int);
+static int     as3722reg_get_voltage_sd4(device_t, u_int *);
 static int     as3722reg_set_voltage_ldo(device_t, u_int, u_int);
 static int     as3722reg_get_voltage_ldo(device_t, u_int *);
 
@@ -126,6 +133,13 @@
          .vsel_mask = 0x7f,
          .set = as3722reg_set_voltage_sd0,
          .get = as3722reg_get_voltage_sd0 },
+       { .name = "sd4",
+         .vsel_reg = AS3722_SD4_VOLTAGE_REG,
+         .vsel_mask = 0x7f,
+         .enable_reg = AS3722_SDCONTROL_REG,
+         .enable_mask = AS3722_SDCONTROL_SD4_ENABLE,
+         .set = as3722reg_set_voltage_sd4,
+         .get = as3722reg_get_voltage_sd4 },
        { .name = "ldo6",
          .vsel_reg = AS3722_LDO6_VOLTAGE_REG,
          .vsel_mask = 0x7f,
@@ -668,6 +682,83 @@
 }
 
 static int
+as3722reg_set_voltage_sd4(device_t dev, u_int min_uvol, u_int max_uvol)
+{
+       struct as3722reg_softc *sc = device_private(dev);
+       struct as3722_softc *asc = device_private(device_parent(dev));
+       const struct as3722regdef *regdef = sc->sc_regdef;
+       const int flags = (cold ? I2C_F_POLL : 0);
+       uint8_t set_v = 0x00;
+       u_int uvol;
+       int error;
+
+
+       for (uint8_t v = 0x01; v <= 0x40; v++) {
+               uvol = 600000 + (v * 12500);
+               if (uvol >= min_uvol && uvol <= max_uvol) {
+                       set_v = v;
+                       goto done;
+               }
+       }
+       for (uint8_t v = 0x41; v <= 0x70; v++) {
+               uvol = 1400000 + ((v - 0x40) * 25000);
+               if (uvol >= min_uvol && uvol <= max_uvol) {
+                       set_v = v;
+                       goto done;
+               }
+       }
+       for (uint8_t v = 0x71; v <= 0x7f; v++) {
+               uvol = 2600000 + ((v - 0x70) * 50000);
+               if (uvol >= min_uvol && uvol <= max_uvol) {
+                       set_v = v;
+                       goto done;
+               }
+       }
+       if (set_v == 0)
+               return ERANGE;
+
+done:
+       iic_acquire_bus(asc->sc_i2c, flags);
+       error = as3722_set_clear(asc, regdef->vsel_reg, set_v,
+           regdef->vsel_mask, flags);
+       iic_release_bus(asc->sc_i2c, flags);
+
+       return error;
+}
+
+static int
+as3722reg_get_voltage_sd4(device_t dev, u_int *puvol)
+{
+       struct as3722reg_softc *sc = device_private(dev);
+       struct as3722_softc *asc = device_private(device_parent(dev));
+       const struct as3722regdef *regdef = sc->sc_regdef;
+       const int flags = (cold ? I2C_F_POLL : 0);
+       uint8_t v;
+       int error;
+
+       iic_acquire_bus(asc->sc_i2c, flags);
+       error = as3722_read(asc, regdef->vsel_reg, &v, flags);
+       iic_release_bus(asc->sc_i2c, flags);
+       if (error != 0)
+               return error;
+
+       v &= regdef->vsel_mask;
+
+       if (v == 0)
+               *puvol = 0;     /* DC/DC powered down */
+       else if (v >= 0x01 && v <= 0x40)
+               *puvol = 600000 + (v * 12500);
+       else if (v >= 0x41 && v <= 0x70)
+               *puvol = 1400000 + (v - 0x40) * 25000;
+       else if (v >= 0x71 && v <= 0x7f)
+               *puvol = 2600000 + (v - 0x70) * 50000;
+       else
+               return EINVAL;
+
+       return 0;
+}
+
+static int
 as3722reg_set_voltage(device_t dev, u_int min_uvol, u_int max_uvol)
 {
        struct as3722reg_softc *sc = device_private(dev);



Home | Main Index | Thread Index | Old Index