int vfc_i2c_wait_for_bus(struct vfc_dev *dev) { int timeout = 1000; while(!(sbus_readl(&dev->regs->i2c_s1) & BB)) { if(!(timeout--)) return -ETIMEDOUT; vfc_i2c_delay(dev); } return 0; }
int vfc_i2c_recvbuf(struct vfc_dev *dev, unsigned char addr, char *buf, int count) { int ret, last; if(!(count && buf && dev && dev->regs) ) return -EINVAL; if ((ret = vfc_i2c_wait_for_bus(dev))) { printk(KERN_ERR "vfc%d: VFC I2C bus busy\n", dev->instance); return ret; } if ((ret = vfc_i2c_xmit_addr(dev, addr, VFC_I2C_READ))) { WRITE_S1(SEND_I2C_STOP); vfc_i2c_delay(dev); return ret; } last = 0; while (count--) { if (!count) last = 1; if ((ret = vfc_i2c_recv_byte(dev, buf, last))) { printk(KERN_ERR "vfc%d: " "VFC error while receiving byte\n", dev->instance); WRITE_S1(SEND_I2C_STOP); ret = -EINVAL; } buf++; } WRITE_S1(SEND_I2C_STOP | ACK); vfc_i2c_delay(dev); return ret; }
int vfc_i2c_wait_for_pin(struct vfc_dev *dev, int ack) { int timeout = 1000; int s1; while ((s1 = sbus_readl(&dev->regs->i2c_s1)) & PIN) { if (!(timeout--)) return -ETIMEDOUT; vfc_i2c_delay(dev); } if (ack == VFC_I2C_ACK_CHECK) { if(s1 & LRB) return -EIO; } return 0; }
int vfc_i2c_reset_bus(struct vfc_dev *dev) { VFC_I2C_DEBUG_PRINTK((KERN_DEBUG "vfc%d: Resetting the i2c bus\n", dev->instance)); if(dev == NULL) return -EINVAL; if(dev->regs == NULL) return -EINVAL; WRITE_S1(SEND_I2C_STOP); WRITE_S1(SEND_I2C_STOP | ACK); vfc_i2c_delay(dev); WRITE_S1(CLEAR_I2C_BUS); VFC_I2C_DEBUG_PRINTK((KERN_DEBUG "vfc%d: I2C status %x\n", dev->instance, sbus_readl(&dev->regs->i2c_s1))); return 0; }