static int i2c_pxa_do_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[], int num) { struct i2c_algo_pxa_data * adap; struct i2c_msg *pmsg=NULL; int i; int ret=0, timeout; adap = i2c_adap->algo_data; timeout = adap->wait_bus_not_busy(adap); if (timeout) { return I2C_RETRY; } for (i = 0;ret >= 0 && i < num; i++) { int last = i + 1 == num; pmsg = &msgs[i]; ret = i2c_pxa_set_ctrl_byte(adap,pmsg); /* Send START */ if (i == 0) { adap->start(adap); }else{ adap->repeat_start(adap); } adap->transfer(adap, 0, I2C_TRANSMIT, 0); /* Wait for ITE (transmit empty) */ timeout = adap->wait_for_interrupt(adap, I2C_TRANSMIT); #ifdef DEBUG /* Check for ACK (bus error) */ if (timeout==BUS_ERROR){ printk(KERN_INFO "i2c_pxa_do_xfer: bus error -> forcing reset\n"); adap->reset(adap); return I2C_RETRY; } #endif if (timeout) { adap->abort(adap); adap->reset(adap); return I2C_RETRY; } /* FIXME: handle arbitration... */ #if 0 /* Check for bus arbitration loss */ if (adap->arbitration_loss(adap)){ printk("Arbitration loss detected \n"); adap->reset(adap); return I2C_RETRY; } #endif /* Read */ if (pmsg->flags & I2C_M_RD) { /* read bytes into buffer*/ ret = i2c_pxa_readbytes(i2c_adap, pmsg->buf, pmsg->len, last); #if DEBUG > 2 if (ret != pmsg->len) { printk(KERN_INFO"i2c_pxa_do_xfer: read %d/%d bytes.\n", ret, pmsg->len); } else { printk(KERN_INFO"i2c_pxa_do_xfer: read %d bytes.\n",ret); } #endif } else { /* Write */ ret = i2c_pxa_sendbytes(i2c_adap, pmsg->buf, pmsg->len, last); #if DEBUG > 2 if (ret != pmsg->len) { printk(KERN_INFO"i2c_pxa_do_xfer: wrote %d/%d bytes.\n", ret, pmsg->len); } else { printk(KERN_INFO"i2c_pxa_do_xfer: wrote %d bytes.\n",ret); } #endif } } if (ret<0){ return ret; }else{ return i; } }
static int i2c_pxa_do_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[], int num) { struct i2c_algo_pxa_data * adap; struct i2c_msg *pmsg=NULL; int i; int ret=0, timeout; adap = i2c_adap->algo_data; timeout = adap->wait_bus_not_busy(); if (timeout) { return I2C_RETRY; } #if 0 /* If only i2c ack polling the SCL remains low: so I reset the i2c controller This works but it's not so nice to do run-time: its better don't arrive here with 0 length writes */ if (msgs[0].len == 0) { #ifdef DEBUG printk("i2c_pxa_do_xfer: ctrl-byte\n"); #endif pmsg = &msgs[0]; ret = i2c_pxa_set_ctrl_byte(adap,pmsg); adap->start(); adap->transfer(0, I2C_TRANSMIT, 0); if ((adap->wait_for_interrupt(I2C_TRANSMIT) != BUS_ERROR)) { #ifdef DEBUG printk("OK"); #endif adap->reset(); /* in scannig is abort, but here leaves SCL down */ return 0; } else { #ifdef DEBUG printk("ERR\n"); adap->reset(); /* in scannig is stop, but I don't believe that it works */ return -EIO; #endif } udelay(100); } #endif for (i = 0;ret >= 0 && i < num; i++) { int last = i + 1 == num; pmsg = &msgs[i]; ret = i2c_pxa_set_ctrl_byte(adap,pmsg); /* Send START */ if (i == 0) { adap->start(); }else{ adap->repeat_start(); } adap->transfer(0, I2C_TRANSMIT, 0); /* Wait for ITE (transmit empty) */ timeout = adap->wait_for_interrupt(I2C_TRANSMIT); #ifdef DEBUG /* Check for ACK (bus error) */ if (timeout==BUS_ERROR){ printk(KERN_INFO "i2c_pxa_do_xfer: bus error -> forcing reset\n"); adap->reset(); return I2C_RETRY; } else #endif if (timeout == -ERESTARTSYS) { adap->abort(); return timeout; } else if (timeout) { #ifdef DEBUG printk(KERN_INFO "i2c_pxa_do_xfer: timeout -> forcing reset\n"); #endif adap->reset(); return I2C_RETRY; } /* FIXME: handle arbitration... */ #if 0 /* Check for bus arbitration loss */ if (adap->arbitration_loss()){ printk("Arbitration loss detected \n"); adap->reset(); return I2C_RETRY; } #endif /* Read */ if (pmsg->flags & I2C_M_RD) { /* read bytes into buffer*/ ret = i2c_pxa_readbytes(i2c_adap, pmsg->buf, pmsg->len, last); #if DEBUG > 2 if (ret != pmsg->len) { printk(KERN_INFO"i2c_pxa_do_xfer: read %d/%d bytes.\n", ret, pmsg->len); } else { printk(KERN_INFO"i2c_pxa_do_xfer: read %d bytes.\n",ret); } #endif } else { /* Write */ ret = i2c_pxa_sendbytes(i2c_adap, pmsg->buf, pmsg->len, last); #if DEBUG > 2 if (ret != pmsg->len) { printk(KERN_INFO"i2c_pxa_do_xfer: wrote %d/%d bytes.\n", ret, pmsg->len); } else { printk(KERN_INFO"i2c_pxa_do_xfer: wrote %d bytes.\n",ret); } #endif } #if DEBUG > 3 { int idx; for(idx=0;idx<ret;idx++){ printk(KERN_INFO"%02x ",pmsg->buf[idx]); } printk(KERN_INFO"\n"); } #endif } if (ret<0){ return ret; }else{ return i; } }