- int i2c_error = 0;
- u16 status;
- int i = 2 - alen;
- u8 tmpbuf[2] = {(regoffset) >> 8, regoffset & 0xff};
- u16 w;
-
- /* wait until bus not busy */
- wait_for_bb();
-
- /* one byte only */
- writew(alen, &i2c_base->cnt);
- /* set slave address */
- writew(devaddr, &i2c_base->sa);
- /* no stop bit needed here */
- writew(I2C_CON_EN | I2C_CON_MST | I2C_CON_STT |
- I2C_CON_TRX, &i2c_base->con);
-
- /* send register offset */
- while (1) {
- status = wait_for_pin();
- if (status == 0 || status & I2C_STAT_NACK) {
- i2c_error = 1;
- goto read_exit;
- }
- if (status & I2C_STAT_XRDY) {
- w = tmpbuf[i++];
-#if !(defined(CONFIG_OMAP243X) || defined(CONFIG_OMAP34XX) || \
- defined(CONFIG_OMAP44XX) || defined(CONFIG_AM33XX))
- w |= tmpbuf[i++] << 8;
-#endif
- writew(w, &i2c_base->data);
- writew(I2C_STAT_XRDY, &i2c_base->stat);
- }
- if (status & I2C_STAT_ARDY) {
- writew(I2C_STAT_ARDY, &i2c_base->stat);
- break;
- }
- }
-
- /* set slave address */
- writew(devaddr, &i2c_base->sa);
- /* read one byte from slave */
- writew(1, &i2c_base->cnt);
- /* need stop bit here */
- writew(I2C_CON_EN | I2C_CON_MST |
- I2C_CON_STT | I2C_CON_STP,
- &i2c_base->con);
-
- /* receive data */
- while (1) {
- status = wait_for_pin();
- if (status == 0 || status & I2C_STAT_NACK) {
- i2c_error = 1;
- goto read_exit;
- }
- if (status & I2C_STAT_RRDY) {
-#if defined(CONFIG_OMAP243X) || defined(CONFIG_OMAP34XX) || \
- defined(CONFIG_OMAP44XX) || defined(CONFIG_AM33XX)
- *value = readb(&i2c_base->data);
-#else
- *value = readw(&i2c_base->data);
-#endif
- writew(I2C_STAT_RRDY, &i2c_base->stat);
- }
- if (status & I2C_STAT_ARDY) {
- writew(I2C_STAT_ARDY, &i2c_base->stat);
- break;
- }
- }
-
-read_exit:
- flush_fifo();
- writew(0xFFFF, &i2c_base->stat);
- writew(0, &i2c_base->cnt);
- return i2c_error;
-}
-
-static void flush_fifo(void)
-{ u16 stat;