Module Name:    src
Committed By:   jmcneill
Date:           Sat Oct  7 18:22:06 UTC 2017

Modified Files:
        src/sys/dev/i2c: axp20x.c axp20xvar.h files.i2c

Log Message:
Hook axp20x into fdt regulator api


To generate a diff of this commit:
cvs rdiff -u -r1.7 -r1.8 src/sys/dev/i2c/axp20x.c
cvs rdiff -u -r1.2 -r1.3 src/sys/dev/i2c/axp20xvar.h
cvs rdiff -u -r1.77 -r1.78 src/sys/dev/i2c/files.i2c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/i2c/axp20x.c
diff -u src/sys/dev/i2c/axp20x.c:1.7 src/sys/dev/i2c/axp20x.c:1.8
--- src/sys/dev/i2c/axp20x.c:1.7	Tue Aug 29 10:10:54 2017
+++ src/sys/dev/i2c/axp20x.c	Sat Oct  7 18:22:06 2017
@@ -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 <jmcne...@invisible.ca>
@@ -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 @@ axp20x_set_dcdc(device_t dev, int dcdc, 
 	}
 }
 
+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, &reg, 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, &reg, 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 @@ axp20x_poweroff(device_t dev)
 }
 
 #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 struct fdtbus_power_controller_fu
 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, &reg, NULL);
+	}
 }
 #endif /* FDT */

Index: src/sys/dev/i2c/axp20xvar.h
diff -u src/sys/dev/i2c/axp20xvar.h:1.2 src/sys/dev/i2c/axp20xvar.h:1.3
--- src/sys/dev/i2c/axp20xvar.h:1.2	Tue Aug 29 10:10:54 2017
+++ src/sys/dev/i2c/axp20xvar.h	Sat Oct  7 18:22:06 2017
@@ -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_ */

Index: src/sys/dev/i2c/files.i2c
diff -u src/sys/dev/i2c/files.i2c:1.77 src/sys/dev/i2c/files.i2c:1.78
--- src/sys/dev/i2c/files.i2c:1.77	Mon Oct  2 22:48:02 2017
+++ src/sys/dev/i2c/files.i2c	Sat Oct  7 18:22:06 2017
@@ -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 @@ attach  mpl115a at iic
 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

Reply via email to