summaryrefslogtreecommitdiffstats
path: root/sys/dev/pcf
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/pcf')
-rw-r--r--sys/dev/pcf/pcf.c26
-rw-r--r--sys/dev/pcf/pcf_isa.c44
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);
OpenPOWER on IntegriCloud