int pcf_read(device_t dev, char *buf, int len, int *read, int last, int delay /* us */) { struct pcf_softc *sc = DEVTOSOFTC(dev); int bytes, error = 0; #ifdef PCFDEBUG char *obuf = buf; device_printf(dev, " << reading %d bytes\n", len); #endif PCF_LOCK(sc); /* trig the bus to get the first data byte in S0 */ if (len) { if (len == 1 && last) /* just one byte to read */ pcf_set_S1(sc, ESO); /* no ack */ dummy_read(sc); } bytes = 0; while (len) { /* XXX delay needed here */ /* wait for trigged byte */ if ((error = pcf_wait_byte(sc))) { pcf_stop_locked(sc); goto error; } if (len == 1 && last) /* ok, last data byte already in S0, no I2C activity * on next pcf_get_S0() */ pcf_stop_locked(sc); else if (len == 2 && last) /* next trigged byte with no ack */ pcf_set_S1(sc, ESO); /* receive byte, trig next byte */ *buf++ = pcf_get_S0(sc); len --; bytes ++; }; error: *read = bytes; PCF_UNLOCK(sc); #ifdef PCFDEBUG device_printf(dev, " << %d bytes read (%d): %#x%s\n", bytes, error, (unsigned)obuf[0], bytes > 1? "...": ""); #endif return (error); }
static int pcf_start(device_t pcfdev, u_char slave, int timeout) { struct pcf_softc *pcf = DEVTOSOFTC(pcfdev); int error = 0; if ((PCF_GET_S1(pcf) & nBB) == 0) return (IIC_EBUSBSY); /* set slave address to PCF. Last bit (LSB) must be set correctly * according to transfer direction */ PCF_SET_S0(pcf, slave); /* START only */ PCF_SET_S1(pcf, PIN|ES0|STA|ACK); pcf->pcf_started = 1; /* wait for address sent, polling */ if ((error = pcf_wait_byte(pcf))) goto error; /* check for ACK */ if (pcf_noack(pcf, timeout)) { error = IIC_ENOACK; goto error; } return (0); error: pcf_stop(pcfdev); return (error); }
static int pcf_repeated_start(device_t pcfdev, u_char slave, int timeout) { struct pcf_softc *pcf = DEVTOSOFTC(pcfdev); int error = 0; /* repeated start */ PCF_SET_S1(pcf, ES0|STA|STO|ACK); /* set slave address to PCF. Last bit (LSB) must be set correctly * according to transfer direction */ PCF_SET_S0(pcf, slave); /* wait for address sent, polling */ if ((error = pcf_wait_byte(pcf))) goto error; /* check for ack */ if (pcf_noack(pcf, timeout)) { error = IIC_ENOACK; goto error; } return (0); error: pcf_stop(pcfdev); return (error); }
static int pcf_read(device_t pcfdev, char *buf, int len, int *read, int last, int delay /* us */) { struct pcf_softc *pcf = DEVTOSOFTC(pcfdev); int bytes, error = 0; #ifdef PCFDEBUG kprintf("pcf%d: << reading %d bytes\n", device_get_unit(pcfdev), len); #endif /* trig the bus to get the first data byte in S0 */ if (len) { if (len == 1 && last) /* just one byte to read */ PCF_SET_S1(pcf, ES0); /* no ack */ dummy_read(pcf); } bytes = 0; while (len) { /* XXX delay needed here */ /* wait for trigged byte */ if ((error = pcf_wait_byte(pcf))) { pcf_stop(pcfdev); goto error; } if (len == 1 && last) /* ok, last data byte already in S0, no I2C activity * on next PCF_GET_S0() */ pcf_stop(pcfdev); else if (len == 2 && last) /* next trigged byte with no ack */ PCF_SET_S1(pcf, ES0); /* receive byte, trig next byte */ *buf++ = PCF_GET_S0(pcf); len --; bytes ++; } error: *read = bytes; #ifdef PCFDEBUG kprintf("pcf%d: << %d bytes read (%d)\n", device_get_unit(pcfdev), bytes, error); #endif return (error); }
int pcf_start(device_t dev, u_char slave, int timeout) { struct pcf_softc *sc = DEVTOSOFTC(dev); int error = 0; PCF_LOCK(sc); #ifdef PCFDEBUG device_printf(dev, " >> start for slave %#x\n", (unsigned)slave); #endif if ((pcf_get_S1(sc) & nBB) == 0) { #ifdef PCFDEBUG printf("pcf: busy!\n"); #endif PCF_UNLOCK(sc); return (IIC_EBUSBSY); } /* set slave address to PCF. Last bit (LSB) must be set correctly * according to transfer direction */ pcf_set_S0(sc, slave); /* START only */ pcf_set_S1(sc, PIN|ESO|STA|ACK); sc->pcf_started = 1; /* wait for address sent, polling */ if ((error = pcf_wait_byte(sc))) goto error; /* check for ACK */ if (pcf_noack(sc, timeout)) { error = IIC_ENOACK; #ifdef PCFDEBUG printf("pcf: no ack on start!\n"); #endif goto error; } PCF_UNLOCK(sc); return (0); error: pcf_stop_locked(sc); PCF_UNLOCK(sc); return (error); }
int pcf_write(device_t dev, const char *buf, int len, int *sent, int timeout /* us */) { struct pcf_softc *sc = DEVTOSOFTC(dev); int bytes, error = 0; #ifdef PCFDEBUG device_printf(dev, " >> writing %d bytes: %#x%s\n", len, (unsigned)buf[0], len > 1? "...": ""); #endif bytes = 0; PCF_LOCK(sc); while (len) { pcf_set_S0(sc, *buf++); /* wait for the byte to be send */ if ((error = pcf_wait_byte(sc))) goto error; /* check if ack received */ if (pcf_noack(sc, timeout)) { error = IIC_ENOACK; goto error; } len --; bytes ++; } error: *sent = bytes; PCF_UNLOCK(sc); #ifdef PCFDEBUG device_printf(dev, " >> %d bytes written (%d)\n", bytes, error); #endif return (error); }
static int pcf_write(device_t pcfdev, const char *buf, int len, int *sent, int timeout /* us */) { struct pcf_softc *pcf = DEVTOSOFTC(pcfdev); int bytes, error = 0; #ifdef PCFDEBUG kprintf("pcf%d: >> writing %d bytes\n", device_get_unit(pcfdev), len); #endif bytes = 0; while (len) { PCF_SET_S0(pcf, *buf++); /* wait for the byte to be send */ if ((error = pcf_wait_byte(pcf))) goto error; /* check if ack received */ if (pcf_noack(pcf, timeout)) { error = IIC_ENOACK; goto error; } len --; bytes ++; } error: *sent = bytes; #ifdef PCFDEBUG kprintf("pcf%d: >> %d bytes written (%d)\n", device_get_unit(pcfdev), bytes, error); #endif return (error); }
int pcf_repeated_start(device_t dev, u_char slave, int timeout) { struct pcf_softc *sc = DEVTOSOFTC(dev); int error = 0; PCF_LOCK(sc); #ifdef PCFDEBUG device_printf(dev, " >> repeated start for slave %#x\n", (unsigned)slave); #endif /* repeated start */ pcf_set_S1(sc, ESO|STA|STO|ACK); /* set slave address to PCF. Last bit (LSB) must be set correctly * according to transfer direction */ pcf_set_S0(sc, slave); /* wait for address sent, polling */ if ((error = pcf_wait_byte(sc))) goto error; /* check for ack */ if (pcf_noack(sc, timeout)) { error = IIC_ENOACK; #ifdef PCFDEBUG printf("pcf: no ack on repeated_start!\n"); #endif goto error; } PCF_UNLOCK(sc); return (0); error: pcf_stop_locked(sc); PCF_UNLOCK(sc); return (error); }