Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F148311162
D21980.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
11 KB
Referenced Files
None
Subscribers
None
D21980.diff
View Options
Index: head/sys/dev/nctgpio/nctgpio.c
===================================================================
--- head/sys/dev/nctgpio/nctgpio.c
+++ head/sys/dev/nctgpio/nctgpio.c
@@ -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 @@
#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 @@
},
};
-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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 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);
+
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Mar 18, 2:57 AM (16 h, 14 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29872409
Default Alt Text
D21980.diff (11 KB)
Attached To
Mode
D21980: move nctgpio to superio(4) bus
Attached
Detach File
Event Timeline
Log In to Comment