in char/bbc_i2c.c [181:228]
int bbc_i2c_readb(struct bbc_i2c_client *client, unsigned char *byte, int off)
{
struct bbc_i2c_bus *bp = client->bp;
unsigned char address = client->address, status;
int ret = -1;
if (bp->i2c_bussel_reg != NULL)
writeb(client->bus, bp->i2c_bussel_reg);
writeb(address, bp->i2c_control_regs + 0x1);
writeb(I2C_PCF_START, bp->i2c_control_regs + 0x0);
if (wait_for_pin(bp, &status))
goto out;
writeb(off, bp->i2c_control_regs + 0x1);
if (wait_for_pin(bp, &status) ||
(status & I2C_PCF_LRB) != 0)
goto out;
writeb(I2C_PCF_STOP, bp->i2c_control_regs + 0x0);
address |= 0x1; /* READ */
writeb(address, bp->i2c_control_regs + 0x1);
writeb(I2C_PCF_START, bp->i2c_control_regs + 0x0);
if (wait_for_pin(bp, &status))
goto out;
/* Set PIN back to one so the device sends the first
* byte.
*/
(void) readb(bp->i2c_control_regs + 0x1);
if (wait_for_pin(bp, &status))
goto out;
writeb(I2C_PCF_ESO | I2C_PCF_ENI, bp->i2c_control_regs + 0x0);
*byte = readb(bp->i2c_control_regs + 0x1);
if (wait_for_pin(bp, &status))
goto out;
ret = 0;
out:
writeb(I2C_PCF_STOP, bp->i2c_control_regs + 0x0);
(void) readb(bp->i2c_control_regs + 0x1);
return ret;
}