Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/i2c Hook axp20x into fdt regulator api
details: https://anonhg.NetBSD.org/src/rev/30e1a9af3c12
branches: trunk
changeset: 356658:30e1a9af3c12
user: jmcneill <jmcneill%NetBSD.org@localhost>
date: Sat Oct 07 18:22:06 2017 +0000
description:
Hook axp20x into fdt regulator api
diffstat:
sys/dev/i2c/axp20x.c | 156 +++++++++++++++++++++++++++++++++++++++++++++++-
sys/dev/i2c/axp20xvar.h | 3 +-
sys/dev/i2c/files.i2c | 6 +-
3 files changed, 160 insertions(+), 5 deletions(-)
diffs (230 lines):
diff -r 7ad44e4c9662 -r 30e1a9af3c12 sys/dev/i2c/axp20x.c
--- a/sys/dev/i2c/axp20x.c Sat Oct 07 17:42:43 2017 +0000
+++ b/sys/dev/i2c/axp20x.c Sat Oct 07 18:22:06 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: axp20x.c,v 1.7 2017/08/29 10:10:54 jmcneill Exp $ */
+/* $NetBSD: axp20x.c,v 1.8 2017/10/07 18:22:06 jmcneill Exp $ */
/*-
* Copyright (c) 2014-2017 Jared McNeill <jmcneill%invisible.ca@localhost>
@@ -29,7 +29,7 @@
#include "opt_fdt.h"
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: axp20x.c,v 1.7 2017/08/29 10:10:54 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: axp20x.c,v 1.8 2017/10/07 18:22:06 jmcneill Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -632,6 +632,31 @@
}
}
+int
+axp20x_get_dcdc(device_t dev, int dcdc, int *pmvolt, bool poll)
+{
+ struct axp20x_softc *sc = device_private(dev);
+ uint8_t reg;
+ int error;
+
+ switch (dcdc) {
+ case AXP20X_DCDC2:
+ error = axp20x_read(sc, AXP_DCDC2, ®, 1, poll ? I2C_F_POLL : 0);
+ if (error != 0)
+ return error;
+ *pmvolt = __SHIFTOUT(reg, AXP_DCDC2_VOLT_MASK) * 25 + 700;
+ return 0;
+ case AXP20X_DCDC3:
+ error = axp20x_read(sc, AXP_DCDC3, ®, 1, poll ? I2C_F_POLL : 0);
+ if (error != 0)
+ return error;
+ *pmvolt = __SHIFTOUT(reg, AXP_DCDC3_VOLT_MASK) * 25 + 700;
+ return 0;
+ default:
+ return EINVAL;
+ }
+}
+
void
axp20x_poweroff(device_t dev)
{
@@ -643,6 +668,122 @@
}
#ifdef FDT
+static const struct axp20xregdef {
+ const char *name;
+ int dcdc;
+} axp20x_regdefs[] = {
+ { "dcdc2", AXP20X_DCDC2 },
+ { "dcdc3", AXP20X_DCDC3 },
+};
+
+struct axp20xreg_softc {
+ device_t sc_dev;
+ int sc_phandle;
+ const struct axp20xregdef *sc_regdef;
+};
+
+struct axp20xreg_attach_args {
+ int reg_phandle;
+};
+
+static int
+axp20xreg_acquire(device_t dev)
+{
+ return 0;
+}
+
+static void
+axp20xreg_release(device_t dev)
+{
+}
+
+static int
+axp20xreg_enable(device_t dev, bool enable)
+{
+ /* TODO */
+ return enable ? 0 : EINVAL;
+}
+
+static int
+axp20xreg_set_voltage(device_t dev, u_int min_uvol, u_int max_uvol)
+{
+ struct axp20xreg_softc * const sc = device_private(dev);
+
+ return axp20x_set_dcdc(device_parent(dev), sc->sc_regdef->dcdc, min_uvol / 1000, true);
+}
+
+static int
+axp20xreg_get_voltage(device_t dev, u_int *puvol)
+{
+ struct axp20xreg_softc * const sc = device_private(dev);
+ int mvol, error;
+
+ error = axp20x_get_dcdc(device_parent(dev), sc->sc_regdef->dcdc, &mvol, true);
+ if (error != 0)
+ return error;
+
+ *puvol = mvol * 1000;
+ return 0;
+}
+
+static struct fdtbus_regulator_controller_func axp20xreg_funcs = {
+ .acquire = axp20xreg_acquire,
+ .release = axp20xreg_release,
+ .enable = axp20xreg_enable,
+ .set_voltage = axp20xreg_set_voltage,
+ .get_voltage = axp20xreg_get_voltage,
+};
+
+static const struct axp20xregdef *
+axp20xreg_lookup(int phandle)
+{
+ const char *name;
+ int n;
+
+ name = fdtbus_get_string(phandle, "name");
+ if (name == NULL)
+ return NULL;
+
+ for (n = 0; n < __arraycount(axp20x_regdefs); n++)
+ if (strcmp(name, axp20x_regdefs[n].name) == 0)
+ return &axp20x_regdefs[n];
+
+ return NULL;
+}
+
+static int
+axp20xreg_match(device_t parent, cfdata_t match, void *aux)
+{
+ const struct axp20xreg_attach_args *reg = aux;
+
+ return axp20xreg_lookup(reg->reg_phandle) != NULL;
+}
+
+static void
+axp20xreg_attach(device_t parent, device_t self, void *aux)
+{
+ struct axp20xreg_softc * const sc = device_private(self);
+ const struct axp20xreg_attach_args *reg = aux;
+ const char *regulator_name;
+
+ sc->sc_dev = self;
+ sc->sc_phandle = reg->reg_phandle;
+ sc->sc_regdef = axp20xreg_lookup(reg->reg_phandle);
+
+ regulator_name = fdtbus_get_string(reg->reg_phandle, "regulator-name");
+
+ aprint_naive("\n");
+ if (regulator_name)
+ aprint_normal(": %s (%s)\n", sc->sc_regdef->name, regulator_name);
+ else
+ aprint_normal(": %s\n", sc->sc_regdef->name);
+
+ fdtbus_register_regulator_controller(self, sc->sc_phandle, &axp20xreg_funcs);
+}
+
+CFATTACH_DECL_NEW(axp20xreg, sizeof(struct axp20xreg_softc),
+ axp20xreg_match, axp20xreg_attach, NULL, NULL);
+
static void
axp20x_fdt_poweroff(device_t dev)
{
@@ -657,7 +798,18 @@
static void
axp20x_fdt_attach(struct axp20x_softc *sc)
{
+ int regulators_phandle, child;
+
fdtbus_register_power_controller(sc->sc_dev, sc->sc_phandle,
&axp20x_fdt_power_funcs);
+
+ regulators_phandle = of_find_firstchild_byname(sc->sc_phandle, "regulators");
+ if (regulators_phandle == -1)
+ return;
+
+ for (child = OF_child(regulators_phandle); child; child = OF_peer(child)) {
+ struct axp20xreg_attach_args reg = { .reg_phandle = child };
+ config_found(sc->sc_dev, ®, NULL);
+ }
}
#endif /* FDT */
diff -r 7ad44e4c9662 -r 30e1a9af3c12 sys/dev/i2c/axp20xvar.h
--- a/sys/dev/i2c/axp20xvar.h Sat Oct 07 17:42:43 2017 +0000
+++ b/sys/dev/i2c/axp20xvar.h Sat Oct 07 18:22:06 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: axp20xvar.h,v 1.2 2017/08/29 10:10:54 jmcneill Exp $ */
+/* $NetBSD: axp20xvar.h,v 1.3 2017/10/07 18:22:06 jmcneill Exp $ */
/*
* Copyright (c) 1998, 2001 Manuel Bouyer.
@@ -31,6 +31,7 @@
#define AXP20X_DCDC3 3
int axp20x_set_dcdc(device_t, int, int, bool);
+int axp20x_get_dcdc(device_t, int, int *, bool);
void axp20x_poweroff(device_t);
#endif /* _DEV_I2C_AXP20XVAR_H_ */
diff -r 7ad44e4c9662 -r 30e1a9af3c12 sys/dev/i2c/files.i2c
--- a/sys/dev/i2c/files.i2c Sat Oct 07 17:42:43 2017 +0000
+++ b/sys/dev/i2c/files.i2c Sat Oct 07 18:22:06 2017 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: files.i2c,v 1.77 2017/10/02 22:48:02 jmcneill Exp $
+# $NetBSD: files.i2c,v 1.78 2017/10/07 18:22:06 jmcneill Exp $
obsolete defflag opt_i2cbus.h I2C_SCAN
define i2cbus { }
@@ -222,8 +222,10 @@
file dev/i2c/mpl115a.c mpl115a
# AXP20x Power Management Unit
-device axp20x: sysmon_envsys
+device axp20x { }: sysmon_envsys
+device axp20xreg: axp20x
attach axp20x at iic
+attach axp20xreg at axp20x
file dev/i2c/axp20x.c axp20x needs-flag
# AXP22x Power Management Unit
Home |
Main Index |
Thread Index |
Old Index