svn commit: r353643 - head/sys/dev/nctgpio

Andriy Gapon avg at FreeBSD.org
Wed Oct 16 14:42:49 UTC 2019


Author: avg
Date: Wed Oct 16 14:42:49 2019
New Revision: 353643
URL: https://svnweb.freebsd.org/changeset/base/353643

Log:
  move nctgpio to superio(4) bus
  
  This is where it logically belongs.
  The change allows to drop a bunch of low lewel code.
  
  Reviewed by:	gonzo
  MFC after:	19 days
  Differential Revision: https://reviews.freebsd.org/D21980

Modified:
  head/sys/dev/nctgpio/nctgpio.c

Modified: head/sys/dev/nctgpio/nctgpio.c
==============================================================================
--- head/sys/dev/nctgpio/nctgpio.c	Wed Oct 16 13:53:53 2019	(r353642)
+++ head/sys/dev/nctgpio/nctgpio.c	Wed Oct 16 14:42:49 2019	(r353643)
@@ -42,34 +42,20 @@
 #include <sys/lock.h>
 
 #include <sys/module.h>
-#include <sys/rman.h>
 #include <sys/gpio.h>
 
-#include <isa/isavar.h>
-
 #include <machine/bus.h>
-#include <machine/resource.h>
 
 #include <dev/gpio/gpiobusvar.h>
+#include <dev/superio/superio.h>
 
 #include "gpio_if.h"
 
-/*
- * Global configuration registers (CR).
- */
-#define NCT_CR_LDN			0x07	/* Logical Device Number */
-#define NCT_CR_CHIP_ID			0x20 	/* Chip ID */
-#define NCT_CR_CHIP_ID_H		0x20 	/* Chip ID (high byte) */
-#define NCT_CR_CHIP_ID_L		0x21 	/* Chip ID (low byte) */
-#define NCT_CR_OPT_1			0x26	/* Global Options (1) */
-
 /* Logical Device Numbers. */
 #define NCT_LDN_GPIO			0x07
-#define NCT_LDN_GPIO_CFG		0x08
 #define NCT_LDN_GPIO_MODE		0x0f
 
 /* Logical Device 7 */
-#define NCT_LD7_GPIO_ENABLE		0x30
 #define NCT_LD7_GPIO0_IOR		0xe0
 #define NCT_LD7_GPIO0_DAT		0xe1
 #define NCT_LD7_GPIO0_INV		0xe2
@@ -83,8 +69,6 @@
 #define NCT_LDF_GPIO0_OUTCFG		0xe0
 #define NCT_LDF_GPIO1_OUTCFG		0xe1
 
-#define NCT_EXTFUNC_ENTER		0x87
-#define NCT_EXTFUNC_EXIT		0xaa
 
 #define NCT_MAX_PIN			15
 #define NCT_IS_VALID_PIN(_p)	((_p) >= 0 && (_p) <= NCT_MAX_PIN)
@@ -97,10 +81,9 @@
 
 struct nct_softc {
 	device_t			dev;
+	device_t			dev_f;
 	device_t			busdev;
 	struct mtx			mtx;
-	struct resource			*portres;
-	int				rid;
 	struct gpio_pin			pins[NCT_MAX_PIN + 1];
 };
 
@@ -112,22 +95,6 @@ struct nct_softc {
 #define GPIO_ASSERT_LOCKED(_sc)	mtx_assert(&(_sc)->mtx, MA_OWNED)
 #define GPIO_ASSERT_UNLOCKED(_sc)	mtx_assert(&(_sc)->mtx, MA_NOTOWNED)
 
-#define NCT_BARRIER_WRITE(_sc)	\
-	bus_barrier((_sc)->portres, 0, 2, BUS_SPACE_BARRIER_WRITE)
-
-#define NCT_BARRIER_READ_WRITE(_sc)	\
-	bus_barrier((_sc)->portres, 0, 2, \
-		BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE)
-
-static void	ext_cfg_enter(struct nct_softc *);
-static void	ext_cfg_exit(struct nct_softc *);
-
-/*
- * Potential Extended Function Enable Register addresses.
- * Same address as EFIR.
- */
-uint8_t probe_addrs[] = {0x2e, 0x4e};
-
 struct nuvoton_vendor_device_id {
 	uint16_t		chip_id;
 	const char *		descr;
@@ -146,77 +113,7 @@ struct nuvoton_vendor_device_id {
 	},
 };
 
-static void
-write_cfg_reg_1(struct nct_softc *sc, uint8_t reg, uint8_t value)
-{
-	GPIO_ASSERT_LOCKED(sc);
-	bus_write_1(sc->portres, 0, reg);
-	NCT_BARRIER_WRITE(sc);
-	bus_write_1(sc->portres, 1, value);
-	NCT_BARRIER_WRITE(sc);
-}
-
-static uint8_t
-read_cfg_reg_1(struct nct_softc *sc, uint8_t reg)
-{
-	uint8_t value;
-
-	GPIO_ASSERT_LOCKED(sc);
-	bus_write_1(sc->portres, 0, reg);
-	NCT_BARRIER_READ_WRITE(sc);
-	value = bus_read_1(sc->portres, 1);
-	NCT_BARRIER_READ_WRITE(sc);
-	
-	return (value);
-}
-
-static uint16_t
-read_cfg_reg_2(struct nct_softc *sc, uint8_t reg)
-{
-	uint16_t value;
-
-	value = read_cfg_reg_1(sc, reg) << 8;
-	value |= read_cfg_reg_1(sc, reg + 1);
-
-	return (value);
-}
-
 /*
- * Enable extended function mode.
- *
- */
-static void
-ext_cfg_enter(struct nct_softc *sc)
-{
-	GPIO_ASSERT_LOCKED(sc);
-	bus_write_1(sc->portres, 0, NCT_EXTFUNC_ENTER);
-	NCT_BARRIER_WRITE(sc);
-	bus_write_1(sc->portres, 0, NCT_EXTFUNC_ENTER);
-	NCT_BARRIER_WRITE(sc);
-}
-
-/*
- * Disable extended function mode.
- *
- */
-static void
-ext_cfg_exit(struct nct_softc *sc)
-{
-	GPIO_ASSERT_LOCKED(sc);
-	bus_write_1(sc->portres, 0, NCT_EXTFUNC_EXIT);
-	NCT_BARRIER_WRITE(sc);
-}
-
-/*
- * Select a Logical Device.
- */
-static void
-select_ldn(struct nct_softc *sc, uint8_t ldn)
-{
-	write_cfg_reg_1(sc, NCT_CR_LDN, ldn);
-}
-
-/*
  * Get the GPIO Input/Output register address
  * for a pin.
  */
@@ -289,10 +186,9 @@ nct_set_pin_is_output(struct nct_softc *sc, uint32_t p
 	uint8_t ior;
 
 	reg = nct_ior_addr(pin_num);
-	select_ldn(sc, NCT_LDN_GPIO);
-	ior = read_cfg_reg_1(sc, reg);
+	ior = superio_read(sc->dev, reg);
 	ior &= ~(NCT_PIN_BIT(pin_num));
-	write_cfg_reg_1(sc, reg, ior);
+	superio_write(sc->dev, reg, ior);
 }
 
 /*
@@ -305,10 +201,9 @@ nct_set_pin_is_input(struct nct_softc *sc, uint32_t pi
 	uint8_t ior;
 
 	reg = nct_ior_addr(pin_num);
-	select_ldn(sc, NCT_LDN_GPIO);
-	ior = read_cfg_reg_1(sc, reg);
+	ior = superio_read(sc->dev, reg);
 	ior |= NCT_PIN_BIT(pin_num);
-	write_cfg_reg_1(sc, reg, ior);
+	superio_write(sc->dev, reg, ior);
 }
 
 /*
@@ -321,8 +216,7 @@ nct_pin_is_input(struct nct_softc *sc, uint32_t pin_nu
 	uint8_t ior;
 
 	reg = nct_ior_addr(pin_num);
-	select_ldn(sc, NCT_LDN_GPIO);
-	ior = read_cfg_reg_1(sc, reg);
+	ior = superio_read(sc->dev, reg);
 
 	return (ior & NCT_PIN_BIT(pin_num));
 }
@@ -337,14 +231,13 @@ nct_write_pin(struct nct_softc *sc, uint32_t pin_num, 
 	uint8_t value;
 
 	reg = nct_dat_addr(pin_num);
-	select_ldn(sc, NCT_LDN_GPIO);
-	value = read_cfg_reg_1(sc, reg);
+	value = superio_read(sc->dev, reg);
 	if (data)
 		value |= NCT_PIN_BIT(pin_num);
 	else
 		value &= ~(NCT_PIN_BIT(pin_num));
 
-	write_cfg_reg_1(sc, reg, value);
+	superio_write(sc->dev, reg, value);
 }
 
 static bool
@@ -353,9 +246,8 @@ nct_read_pin(struct nct_softc *sc, uint32_t pin_num)
 	uint8_t reg;
 
 	reg = nct_dat_addr(pin_num);
-	select_ldn(sc, NCT_LDN_GPIO);
 
-	return (read_cfg_reg_1(sc, reg) & NCT_PIN_BIT(pin_num));
+	return (superio_read(sc->dev, reg) & NCT_PIN_BIT(pin_num));
 }
 
 static void
@@ -365,10 +257,9 @@ nct_set_pin_is_inverted(struct nct_softc *sc, uint32_t
 	uint8_t inv;
 
 	reg = nct_inv_addr(pin_num);
-	select_ldn(sc, NCT_LDN_GPIO);
-	inv = read_cfg_reg_1(sc, reg);
+	inv = superio_read(sc->dev, reg);
 	inv |= (NCT_PIN_BIT(pin_num));
-	write_cfg_reg_1(sc, reg, inv);
+	superio_write(sc->dev, reg, inv);
 }
 
 static void
@@ -378,10 +269,9 @@ nct_set_pin_not_inverted(struct nct_softc *sc, uint32_
 	uint8_t inv;
 
 	reg = nct_inv_addr(pin_num);
-	select_ldn(sc, NCT_LDN_GPIO);
-	inv = read_cfg_reg_1(sc, reg);
+	inv = superio_read(sc->dev, reg);
 	inv &= ~(NCT_PIN_BIT(pin_num));
-	write_cfg_reg_1(sc, reg, inv);
+	superio_write(sc->dev, reg, inv);
 }
 
 static bool
@@ -391,8 +281,7 @@ nct_pin_is_inverted(struct nct_softc *sc, uint32_t pin
 	uint8_t inv;
 
 	reg = nct_inv_addr(pin_num);
-	select_ldn(sc, NCT_LDN_GPIO);
-	inv = read_cfg_reg_1(sc, reg);
+	inv = superio_read(sc->dev, reg);
 
 	return (inv & NCT_PIN_BIT(pin_num));
 }
@@ -404,10 +293,9 @@ nct_set_pin_opendrain(struct nct_softc *sc, uint32_t p
 	uint8_t outcfg;
 
 	reg = nct_outcfg_addr(pin_num);
-	select_ldn(sc, NCT_LDN_GPIO_MODE);
-	outcfg = read_cfg_reg_1(sc, reg);
-	outcfg |= (NCT_PIN_BIT(pin_num));
-	write_cfg_reg_1(sc, reg, outcfg);
+	outcfg = superio_read(sc->dev_f, reg);
+	outcfg |= NCT_PIN_BIT(pin_num);
+	superio_write(sc->dev_f, reg, outcfg);
 }
 
 static void
@@ -417,10 +305,9 @@ nct_set_pin_pushpull(struct nct_softc *sc, uint32_t pi
 	uint8_t outcfg;
 
 	reg = nct_outcfg_addr(pin_num);
-	select_ldn(sc, NCT_LDN_GPIO_MODE);
-	outcfg = read_cfg_reg_1(sc, reg);
-	outcfg &= ~(NCT_PIN_BIT(pin_num));
-	write_cfg_reg_1(sc, reg, outcfg);
+	outcfg = superio_read(sc->dev_f, reg);
+	outcfg &= ~NCT_PIN_BIT(pin_num);
+	superio_write(sc->dev_f, reg, outcfg);
 }
 
 static bool
@@ -430,66 +317,33 @@ nct_pin_is_opendrain(struct nct_softc *sc, uint32_t pi
 	uint8_t outcfg;
 
 	reg = nct_outcfg_addr(pin_num);
-	select_ldn(sc, NCT_LDN_GPIO_MODE);
-	outcfg = read_cfg_reg_1(sc, reg);
-
+	outcfg = superio_read(sc->dev_f, reg);
 	return (outcfg & NCT_PIN_BIT(pin_num));
 }
 
-static void
-nct_identify(driver_t *driver, device_t parent)
-{
-	if (device_find_child(parent, driver->name, 0) != NULL)
-		return;
-
-	BUS_ADD_CHILD(parent, 0, driver->name, 0);
-}
-
 static int
 nct_probe(device_t dev)
 {
-	int i, j;
-	int rc;
-	struct nct_softc *sc;
+	int j;
 	uint16_t chipid;
 
-	/* Make sure we do not claim some ISA PNP device. */
-	if (isa_get_logicalid(dev) != 0)
+	if (superio_vendor(dev) != SUPERIO_VENDOR_NUVOTON)
 		return (ENXIO);
+	if (superio_get_type(dev) != SUPERIO_DEV_GPIO)
+		return (ENXIO);
 
-	sc = device_get_softc(dev);
+	/*
+	 * There are several GPIO devices, we attach only to one of them
+	 * and use the rest without attaching.
+	 */
+	if (superio_get_ldn(dev) != NCT_LDN_GPIO)
+		return (ENXIO);
 
-	for (i = 0; i < nitems(probe_addrs); i++) {
-		sc->rid = 0;
-		sc->portres = bus_alloc_resource(dev, SYS_RES_IOPORT, &sc->rid,
-			probe_addrs[i], probe_addrs[i] + 1, 2, RF_ACTIVE);
-		if (sc->portres == NULL)
-			continue;
-
-		GPIO_LOCK_INIT(sc);
-
-		GPIO_ASSERT_UNLOCKED(sc);
-		GPIO_LOCK(sc);
-		ext_cfg_enter(sc);
-		chipid = read_cfg_reg_2(sc, NCT_CR_CHIP_ID);
-		ext_cfg_exit(sc);
-		GPIO_UNLOCK(sc);
-
-		GPIO_LOCK_DESTROY(sc);
-
-		bus_release_resource(dev, SYS_RES_IOPORT, sc->rid, sc->portres);
-		bus_delete_resource(dev, SYS_RES_IOPORT, sc->rid);
-
-		for (j = 0; j < nitems(nct_devs); j++) {
-			if (chipid == nct_devs[j].chip_id) {
-				rc = bus_set_resource(dev, SYS_RES_IOPORT, 0, probe_addrs[i], 2);
-				if (rc != 0) {
-					device_printf(dev, "bus_set_resource failed for address 0x%02X\n", probe_addrs[i]);
-					continue;
-				}
-				device_set_desc(dev, nct_devs[j].descr);
-				return (BUS_PROBE_DEFAULT);
-			}
+	chipid = superio_devid(dev);
+	for (j = 0; j < nitems(nct_devs); j++) {
+		if (chipid == nct_devs[j].chip_id) {
+			device_set_desc(dev, "Nuvoton GPIO controller");
+			return (BUS_PROBE_DEFAULT);
 		}
 	}
 	return (ENXIO);
@@ -502,24 +356,19 @@ nct_attach(device_t dev)
 	int i;
 
 	sc = device_get_softc(dev);
-
-	sc->rid = 0;
-	sc->portres = bus_alloc_resource(dev, SYS_RES_IOPORT, &sc->rid,
-		0ul, ~0ul, 2, RF_ACTIVE);
-	if (sc->portres == NULL) {
-		device_printf(dev, "cannot allocate ioport\n");
+	sc->dev = dev;
+	sc->dev_f = superio_find_dev(device_get_parent(dev), SUPERIO_DEV_GPIO,
+	    NCT_LDN_GPIO_MODE);
+	if (sc->dev_f == NULL) {
+		device_printf(dev, "failed to find LDN F\n");
 		return (ENXIO);
 	}
 
-	GPIO_LOCK_INIT(sc);
+	/* Enable gpio0 and gpio1. */
+	superio_dev_enable(dev, 0x03);
 
-	GPIO_ASSERT_UNLOCKED(sc);
+	GPIO_LOCK_INIT(sc);
 	GPIO_LOCK(sc);
-	ext_cfg_enter(sc);
-	select_ldn(sc, NCT_LDN_GPIO);
-	/* Enable gpio0 and gpio1. */
-	write_cfg_reg_1(sc, NCT_LD7_GPIO_ENABLE,
-		read_cfg_reg_1(sc, NCT_LD7_GPIO_ENABLE) | 0x03);
 
 	for (i = 0; i <= NCT_MAX_PIN; i++) {
 		struct gpio_pin *pin;
@@ -550,12 +399,7 @@ nct_attach(device_t dev)
 	sc->busdev = gpiobus_attach_bus(dev);
 	if (sc->busdev == NULL) {
 		GPIO_ASSERT_UNLOCKED(sc);
-		GPIO_LOCK(sc);
-		ext_cfg_exit(sc);
-		GPIO_UNLOCK(sc);
-		bus_release_resource(dev, SYS_RES_IOPORT, sc->rid, sc->portres);
 		GPIO_LOCK_DESTROY(sc);
-
 		return (ENXIO);
 	}
 
@@ -571,13 +415,6 @@ nct_detach(device_t dev)
 	gpiobus_detach_bus(dev);
 
 	GPIO_ASSERT_UNLOCKED(sc);
-	GPIO_LOCK(sc);
-	ext_cfg_exit(sc);
-	GPIO_UNLOCK(sc);
-
-	/* Cleanup resources. */
-	bus_release_resource(dev, SYS_RES_IOPORT, sc->rid, sc->portres);
-
 	GPIO_LOCK_DESTROY(sc);
 
 	return (0);
@@ -775,26 +612,25 @@ nct_gpio_pin_setflags(device_t dev, uint32_t pin_num, 
 
 static device_method_t nct_methods[] = {
 	/* Device interface */
-	DEVMETHOD(device_identify,	nct_identify),
 	DEVMETHOD(device_probe,		nct_probe),
 	DEVMETHOD(device_attach,	nct_attach),
 	DEVMETHOD(device_detach,	nct_detach),
 
 	/* GPIO */
-	DEVMETHOD(gpio_get_bus,			nct_gpio_get_bus),
-	DEVMETHOD(gpio_pin_max,			nct_gpio_pin_max),
-	DEVMETHOD(gpio_pin_get,			nct_gpio_pin_get),
-	DEVMETHOD(gpio_pin_set,			nct_gpio_pin_set),
-	DEVMETHOD(gpio_pin_toggle,		nct_gpio_pin_toggle),
-	DEVMETHOD(gpio_pin_getname,		nct_gpio_pin_getname),
-	DEVMETHOD(gpio_pin_getcaps,		nct_gpio_pin_getcaps),
+	DEVMETHOD(gpio_get_bus,		nct_gpio_get_bus),
+	DEVMETHOD(gpio_pin_max,		nct_gpio_pin_max),
+	DEVMETHOD(gpio_pin_get,		nct_gpio_pin_get),
+	DEVMETHOD(gpio_pin_set,		nct_gpio_pin_set),
+	DEVMETHOD(gpio_pin_toggle,	nct_gpio_pin_toggle),
+	DEVMETHOD(gpio_pin_getname,	nct_gpio_pin_getname),
+	DEVMETHOD(gpio_pin_getcaps,	nct_gpio_pin_getcaps),
 	DEVMETHOD(gpio_pin_getflags,	nct_gpio_pin_getflags),
 	DEVMETHOD(gpio_pin_setflags,	nct_gpio_pin_setflags),
 
 	DEVMETHOD_END
 };
 
-static driver_t nct_isa_driver = {
+static driver_t nct_driver = {
 	"gpio",
 	nct_methods,
 	sizeof(struct nct_softc)
@@ -802,5 +638,8 @@ static driver_t nct_isa_driver = {
 
 static devclass_t nct_devclass;
 
-DRIVER_MODULE(nctgpio, isa, nct_isa_driver, nct_devclass, NULL, NULL);
+DRIVER_MODULE(nctgpio, superio, nct_driver, nct_devclass, NULL, NULL);
 MODULE_DEPEND(nctgpio, gpiobus, 1, 1, 1);
+MODULE_DEPEND(nctgpio, superio, 1, 1, 1);
+MODULE_VERSION(nctgpio, 1);
+


More information about the svn-src-all mailing list