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 /* 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(dev); goto error; } if (len == 1 && last) /* ok, last data byte already in S0, no I2C activity * on next pcf_get_S0() */ pcf_stop(dev); 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; #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_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); }
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); }
int pcf_start(device_t dev, u_char slave, int timeout) { struct pcf_softc *sc = DEVTOSOFTC(dev); int error = 0; #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 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; } return (0); error: pcf_stop(dev); return (error); }
int pcf_repeated_start(device_t dev, u_char slave, int timeout) { struct pcf_softc *sc = DEVTOSOFTC(dev); int error = 0; #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; } return (0); error: pcf_stop(dev); return (error); }