Module Name:    src
Committed By:   jmcneill
Date:           Sun Oct 27 20:11:13 UTC 2019

Modified Files:
        src/sys/dev/i2c: files.i2c tps65217pmic.c

Log Message:
Add FDT support


To generate a diff of this commit:
cvs rdiff -u -r1.100 -r1.101 src/sys/dev/i2c/files.i2c
cvs rdiff -u -r1.12 -r1.13 src/sys/dev/i2c/tps65217pmic.c

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/files.i2c
diff -u src/sys/dev/i2c/files.i2c:1.100 src/sys/dev/i2c/files.i2c:1.101
--- src/sys/dev/i2c/files.i2c:1.100	Wed Jul 24 05:25:32 2019
+++ src/sys/dev/i2c/files.i2c	Sun Oct 27 20:11:13 2019
@@ -1,4 +1,4 @@
-#	$NetBSD: files.i2c,v 1.100 2019/07/24 05:25:32 thorpej Exp $
+#	$NetBSD: files.i2c,v 1.101 2019/10/27 20:11:13 jmcneill Exp $
 
 obsolete defflag	opt_i2cbus.h		I2C_SCAN
 define	i2cbus { }
@@ -202,8 +202,10 @@ attach	tps65950pm at iic
 file	dev/i2c/tps65950.c		tps65950pm
 
 # TI TPS65217
-device	tps65217pmic: sysmon_envsys
+device	tps65217pmic { }: sysmon_envsys
+device	tps65217reg: tps65217pmic
 attach	tps65217pmic at iic
+attach	tps65217reg at tps65217pmic
 file	dev/i2c/tps65217pmic.c 		tps65217pmic	needs-flag
 
 # Microchip MCP980x

Index: src/sys/dev/i2c/tps65217pmic.c
diff -u src/sys/dev/i2c/tps65217pmic.c:1.12 src/sys/dev/i2c/tps65217pmic.c:1.13
--- src/sys/dev/i2c/tps65217pmic.c:1.12	Sat Jun 16 21:22:13 2018
+++ src/sys/dev/i2c/tps65217pmic.c	Sun Oct 27 20:11:13 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: tps65217pmic.c,v 1.12 2018/06/16 21:22:13 thorpej Exp $ */
+/*	$NetBSD: tps65217pmic.c,v 1.13 2019/10/27 20:11:13 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2013 The NetBSD Foundation, Inc.
@@ -34,8 +34,10 @@
  * TODO: battery, sequencer, pgood
  */
 
+#include "opt_fdt.h"
+
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tps65217pmic.c,v 1.12 2018/06/16 21:22:13 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tps65217pmic.c,v 1.13 2019/10/27 20:11:13 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -51,16 +53,23 @@ __KERNEL_RCSID(0, "$NetBSD: tps65217pmic
 #include <dev/i2c/tps65217pmicreg.h>
 #include <dev/i2c/tps65217pmicvar.h>
 
+#ifdef FDT
+#include <dev/fdt/fdtvar.h>
+#endif
+
 #define NTPS_REG	7
 #define SNUM_REGS	NTPS_REG-1
 #define SNUM_USBSTATUS	NTPS_REG
 #define SNUM_ACSTATUS	NTPS_REG+1
 
+struct tps_reg_param;
+
 struct tps65217pmic_softc {
 	device_t		sc_dev;
 
 	i2c_tag_t		sc_tag;
 	i2c_addr_t		sc_addr;
+	int			sc_phandle;
 
 	uint8_t			sc_version;
 	uint8_t			sc_revision;
@@ -83,6 +92,17 @@ struct tps65217pmic_softc {
 	struct sysmon_pswitch	sc_smpsw;
 };
 
+struct tps65217reg_softc {
+	device_t		sc_dev;
+	int			sc_phandle;
+	struct tps_reg_param	*sc_param;
+};
+
+struct tps65217reg_attach_args {
+	struct tps_reg_param	*reg_param;
+	int			reg_phandle;
+};
+
 /* Voltage regulators */
 enum tps_reg_num {
 	TPS65217PMIC_LDO1,
@@ -159,6 +179,10 @@ static void tps65217pmic_wled_init(struc
 CFATTACH_DECL_NEW(tps65217pmic, sizeof (struct tps65217pmic_softc),
     tps65217pmic_match, tps65217pmic_attach, NULL, NULL);
 
+#ifdef FDT
+static void tps65217pmic_regulator_attach(struct tps65217pmic_softc *);
+#endif
+
 /* 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 };
@@ -177,7 +201,7 @@ static const uint16_t ldo3voltages[] = {
 
 static struct tps_reg_param tps_regulators[] = {
 	{
-		.name = "LDO1",
+		.name = "ldo1",
 		.voltage_min = 1000,
 		.voltage_max = 3300,
 		.voltages = ldo1voltages,
@@ -190,7 +214,7 @@ static struct tps_reg_param tps_regulato
 		.enable_bit = TPS65217PMIC_ENABLE_LDO1
 	},
 	{
-		.name = "LDO2",
+		.name = "ldo2",
 		.voltage_min = 900,
 		.voltage_max = 3300,
 		.voltages = ldo2voltages,
@@ -203,7 +227,7 @@ static struct tps_reg_param tps_regulato
 		.enable_bit = TPS65217PMIC_ENABLE_LDO2
 	},
 	{
-		.name = "LDO3",
+		.name = "ldo3",
 		.voltage_min = 1500,
 		.voltage_max = 3300,
 		.voltages = ldo3voltages,
@@ -216,7 +240,7 @@ static struct tps_reg_param tps_regulato
 		.enable_bit = TPS65217PMIC_ENABLE_LDO3
 	},
 	{
-		.name = "LDO4",
+		.name = "ldo4",
 		.voltage_min = 1500,
 		.voltage_max = 3300,
 		.voltages = ldo3voltages,
@@ -229,7 +253,7 @@ static struct tps_reg_param tps_regulato
 		.enable_bit = TPS65217PMIC_ENABLE_LDO4
 	},
 	{
-		.name = "DCDC1",
+		.name = "dcdc1",
 		.voltage_min = 900,
 		.voltage_max = 3300,
 		.voltages = ldo2voltages,
@@ -242,7 +266,7 @@ static struct tps_reg_param tps_regulato
 		.enable_bit = TPS65217PMIC_ENABLE_DCDC1
 	},
 	{
-		.name = "DCDC2",
+		.name = "dcdc2",
 		.voltage_min = 900,
 		.voltage_max = 3300,
 		.voltages = ldo2voltages,
@@ -255,7 +279,7 @@ static struct tps_reg_param tps_regulato
 		.enable_bit = TPS65217PMIC_ENABLE_DCDC2
 	},
 	{
-		.name = "DCDC3",
+		.name = "dcdc3",
 		.voltage_min = 900,
 		.voltage_max = 3300,
 		.voltages = ldo2voltages,
@@ -271,10 +295,19 @@ static struct tps_reg_param tps_regulato
 
 static bool matched = false;
 
+static const struct device_compatible_entry compat_data[] = {
+	{ "ti,tps65217",			0 },
+	{ NULL }
+};
+
 static int
 tps65217pmic_match(device_t parent, cfdata_t cf, void *aux)
 {
 	struct i2c_attach_args *ia = aux;
+	int match_result;
+
+	if (iic_use_direct_match(ia, cf, compat_data, &match_result))
+		return match_result;
 
 	if (ia->ia_addr == TPS65217PMIC_ADDR) {
 		/* we can only have one */
@@ -299,6 +332,7 @@ tps65217pmic_attach(device_t parent, dev
 
 	sc->sc_dev = self;
 	sc->sc_addr = ia->ia_addr;
+	sc->sc_phandle = ia->ia_cookie;
 	sc->sc_tag = ia->ia_tag;
 
 	dict = device_properties(self);
@@ -349,6 +383,10 @@ tps65217pmic_attach(device_t parent, dev
 		tps65217pmic_wled_init(sc, isel, fdim, brightness);
 
 	tps65217pmic_envsys_register(sc);
+
+#ifdef FDT
+	tps65217pmic_regulator_attach(sc);
+#endif
 }
 
 static void
@@ -835,5 +873,160 @@ tps65217pmic_set_volt(device_t self, con
 	while (val & TPS65217PMIC_DEFSLEW_GO) {
 		val = tps65217pmic_reg_read(sc, TPS65217PMIC_DEFSLEW);
 	}
+
+	regulator->current_voltage = regulator->voltages[i];
+
 	return 0;
 }
+
+#ifdef FDT
+static struct tps_reg_param *
+tps65217pmic_get_params(const char *name)
+{
+	int i;
+
+	for (i = 0; i < __arraycount(tps_regulators); i++) {
+		if (strcmp(name, tps_regulators[i].name) == 0)
+			return &tps_regulators[i];
+	}
+
+	return NULL;
+}
+
+static void
+tps65217pmic_regulator_attach(struct tps65217pmic_softc *sc)
+{
+	struct tps65217reg_attach_args raa;
+	struct tps_reg_param *param;
+	const char *compat_name;
+	int phandle, child;
+
+	phandle = of_find_firstchild_byname(sc->sc_phandle, "regulators");
+	if (phandle <= 0)
+		return;
+
+	for (child = OF_child(phandle); child; child = OF_peer(child)) {
+		compat_name = fdtbus_get_string(child, "regulator-compatible");
+		if (compat_name == NULL)
+			continue;
+		param = tps65217pmic_get_params(compat_name);
+		if (param == NULL)
+			continue;
+
+		raa.reg_param = param;
+		raa.reg_phandle = child;
+		config_found(sc->sc_dev, &raa, NULL);
+	}
+}
+
+static int
+tps65217reg_acquire(device_t dev)
+{
+	return 0;
+}
+
+static void
+tps65217reg_release(device_t dev)
+{
+}
+
+static int
+tps65217reg_enable(device_t dev, bool enable)
+{
+	struct tps65217reg_softc *sc = device_private(dev);
+	struct tps65217pmic_softc *pmic_sc = device_private(device_parent(dev));
+	struct tps_reg_param *regulator = sc->sc_param;
+	uint8_t val;
+	int error;
+
+	error = iic_acquire_bus(pmic_sc->sc_tag, I2C_F_POLL);
+	if (error != 0)
+		return error;
+
+	val = tps65217pmic_reg_read(pmic_sc, TPS65217PMIC_ENABLE);
+	if (enable)
+		val |= regulator->enable_bit;
+	else
+		val &= ~regulator->enable_bit;
+	tps65217pmic_reg_write(pmic_sc, TPS65217PMIC_ENABLE, val);
+
+	regulator->is_enabled = enable;
+
+	iic_release_bus(pmic_sc->sc_tag, I2C_F_POLL);
+
+	return 0;
+}
+
+static int
+tps65217reg_set_voltage(device_t dev, u_int min_uvol, u_int max_uvol)
+{
+	struct tps65217reg_softc *sc = device_private(dev);
+	struct tps65217pmic_softc *pmic_sc = device_private(device_parent(dev));
+	struct tps_reg_param *regulator = sc->sc_param;
+	int error;
+
+	error = iic_acquire_bus(pmic_sc->sc_tag, I2C_F_POLL);
+	if (error != 0)
+		return error;
+
+	error = tps65217pmic_set_volt(pmic_sc->sc_dev, regulator->name, min_uvol / 1000);
+
+	iic_release_bus(pmic_sc->sc_tag, I2C_F_POLL);
+
+	return error;
+}
+
+static int
+tps65217reg_get_voltage(device_t dev, u_int *puvol)
+{
+	struct tps65217reg_softc *sc = device_private(dev);
+	struct tps_reg_param *regulator = sc->sc_param;
+
+	*puvol = (u_int)regulator->current_voltage * 1000;
+
+	return 0;
+}
+
+static struct fdtbus_regulator_controller_func tps65217reg_funcs = {
+	.acquire = tps65217reg_acquire,
+	.release = tps65217reg_release,
+	.enable = tps65217reg_enable,
+	.set_voltage = tps65217reg_set_voltage,
+	.get_voltage = tps65217reg_get_voltage,
+};
+
+static int
+tps65217reg_match(device_t parent, cfdata_t match, void *aux)
+{
+	return 1;
+}
+
+static void
+tps65217reg_attach(device_t parent, device_t self, void *aux)
+{
+	struct tps65217reg_softc *sc = device_private(self);
+	struct tps65217reg_attach_args *raa = aux;
+	const char *regname;
+
+	sc->sc_dev = self;
+	sc->sc_phandle = raa->reg_phandle;
+	sc->sc_param = raa->reg_param;
+
+	fdtbus_register_regulator_controller(self, sc->sc_phandle,
+	    &tps65217reg_funcs);
+
+	regname = fdtbus_get_string(sc->sc_phandle, "regulator-name");
+	if (regname == NULL)
+		regname = fdtbus_get_string(sc->sc_phandle, "regulator-compatible");
+
+	aprint_naive("\n");
+	if (regname != NULL)
+		aprint_normal(": %s\n", regname);
+	else
+		aprint_normal("\n");
+}
+
+CFATTACH_DECL_NEW(tps65217reg, sizeof (struct tps65217reg_softc),
+    tps65217reg_match, tps65217reg_attach, NULL, NULL);
+
+#endif

Reply via email to