diff options
Diffstat (limited to 'sys/dev/pcf')
-rw-r--r-- | sys/dev/pcf/pcf.c | 26 | ||||
-rw-r--r-- | sys/dev/pcf/pcf_isa.c | 44 |
2 files changed, 55 insertions, 15 deletions
diff --git a/sys/dev/pcf/pcf.c b/sys/dev/pcf/pcf.c index 08b088f..0320958 100644 --- a/sys/dev/pcf/pcf.c +++ b/sys/dev/pcf/pcf.c @@ -64,6 +64,10 @@ pcf_wait_byte(struct pcf_softc *sc) return (0); } +#ifdef PCFDEBUG + printf("pcf: timeout!\n"); +#endif + return (IIC_ETIMEOUT); } @@ -132,6 +136,9 @@ pcf_repeated_start(device_t dev, u_char slave, int timeout) /* check for ack */ if (pcf_noack(sc, timeout)) { error = IIC_ENOACK; +#ifdef PCFDEBUG + printf("pcf: no ack on repeated_start!\n"); +#endif goto error; } @@ -151,8 +158,12 @@ pcf_start(device_t dev, u_char slave, int timeout) #ifdef PCFDEBUG device_printf(dev, " >> start for slave %#x\n", (unsigned)slave); #endif - if ((pcf_get_S1(sc) & nBB) == 0) + if ((pcf_get_S1(sc) & nBB) == 0) { +#ifdef PCFDEBUG + printf("pcf: busy!\n"); +#endif return (IIC_EBUSBSY); + } /* set slave address to PCF. Last bit (LSB) must be set correctly * according to transfer direction */ @@ -170,6 +181,9 @@ pcf_start(device_t dev, u_char slave, int timeout) /* check for ACK */ if (pcf_noack(sc, timeout)) { error = IIC_ENOACK; +#ifdef PCFDEBUG + printf("pcf: no ack on start!\n"); +#endif goto error; } @@ -183,23 +197,21 @@ error: void pcf_intr(void *arg) { - device_t dev = (device_t)arg; - struct pcf_softc *sc = DEVTOSOFTC(dev); - + struct pcf_softc *sc = arg; char data, status, addr; char error = 0; status = pcf_get_S1(sc); if (status & PIN) { - device_printf(dev, "spurious interrupt, status=0x%x\n", - status & 0xff); + printf("pcf: spurious interrupt, status=0x%x\n", + status & 0xff); goto error; } if (status & LAB) - device_printf(dev, "bus arbitration lost!\n"); + printf("pcf: bus arbitration lost!\n"); if (status & BER) { error = IIC_EBUSERR; diff --git a/sys/dev/pcf/pcf_isa.c b/sys/dev/pcf/pcf_isa.c index 0b0968a..b4a99e8 100644 --- a/sys/dev/pcf/pcf_isa.c +++ b/sys/dev/pcf/pcf_isa.c @@ -53,12 +53,16 @@ __FBSDID("$FreeBSD$"); #include <dev/pcf/pcfvar.h> #include "iicbus_if.h" +#define PCF_NAME "pcf" + +static void pcf_identify(driver_t *, device_t); static int pcf_probe(device_t); static int pcf_attach(device_t); static int pcf_detach(device_t); static device_method_t pcf_methods[] = { /* device interface */ + DEVMETHOD(device_identify, pcf_identify), DEVMETHOD(device_probe, pcf_probe), DEVMETHOD(device_attach, pcf_attach), DEVMETHOD(device_detach, pcf_detach), @@ -77,16 +81,37 @@ static device_method_t pcf_methods[] = { static devclass_t pcf_devclass; static driver_t pcf_driver = { - "pcf", + PCF_NAME, pcf_methods, sizeof(struct pcf_softc), }; +static void +pcf_identify(driver_t *driver, device_t parent) +{ + BUS_ADD_CHILD(parent, ISA_ORDER_SPECULATIVE, PCF_NAME, 0); + + return; +} + static int pcf_probe(device_t dev) { + u_long start, count; + u_int rid = 0, port, error; + + bus_get_resource(dev, SYS_RES_IOPORT, rid, &start, &count); + + /* The port address must be explicitly specified */ + if ((error = resource_int_value(PCF_NAME, 0, "port", &port) != 0)) + return (error); + + /* Probe is only successfull for the specified base io */ + if (port != (u_int)start) + return (ENXIO); device_set_desc(dev, "PCF8584 I2C bus controller"); + return (0); } @@ -121,14 +146,16 @@ pcf_attach(device_t dev) /* reset the chip */ pcf_rst_card(dev, IIC_FASTEST, PCF_DEFAULT_ADDR, NULL); - rv = BUS_SETUP_INTR(device_get_parent(dev), dev, sc->res_irq, - INTR_TYPE_NET /* | INTR_ENTROPY */, - pcf_intr, sc, &sc->intr_cookie); - if (rv) { - device_printf(dev, "could not setup IRQ\n"); - goto error; + if (sc->res_irq) { + rv = BUS_SETUP_INTR(device_get_parent(dev), dev, sc->res_irq, + INTR_TYPE_NET /* | INTR_ENTROPY */, + pcf_intr, sc, &sc->intr_cookie); + if (rv) { + device_printf(dev, "could not setup IRQ\n"); + goto error; + } } - + if ((sc->iicbus = device_add_child(dev, "iicbus", -1)) == NULL) device_printf(dev, "could not allocate iicbus instance\n"); @@ -181,5 +208,6 @@ pcf_detach(device_t dev) } DRIVER_MODULE(pcf, ebus, pcf_driver, pcf_devclass, 0, 0); +DRIVER_MODULE(pcf, isa, pcf_driver, pcf_devclass, 0, 0); MODULE_DEPEND(pcf, iicbus, PCF_MINVER, PCF_PREFVER, PCF_MAXVER); MODULE_VERSION(pcf, PCF_MODVER); |