Logo Search packages:      
Sourcecode: linux-fsl-imx51 version File versions  Download package

static int mxc_i2c_readbytes ( mxc_i2c_device dev,
struct i2c_msg *  msg,
int  last,
int  addr_comp 
) [static]

Read the received data. The function waits till data is available or times out. Generates a stop signal if this is the last message to be received. Sends an ack for all the bytes received except the last byte.

Parameters:
dev the mxc i2c structure used to get to the right i2c device
*msg pointer to a message structure that contains the slave address and a pointer to the receive buffer
last indicates that this is the last message to be received
addr_comp flag indicates that we just finished the address cycle
Returns:
The function returns the number of bytes read or -1 on time out.

Definition at line 283 of file mxc_i2c.c.

References mxc_i2c_device::membase, mxc_i2c_stop(), and mxc_i2c_wait_for_tc().

Referenced by mxc_i2c_xfer().

{
      int i;
      char *buf = msg->buf;
      int len = msg->len;
      volatile unsigned int cr;

      cr = readw(dev->membase + MXC_I2CR);
      /*
       * Clear MTX to switch to receive mode.
       */
      cr &= ~MXC_I2CR_MTX;
      /*
       * Clear the TXAK bit to gen an ack when receiving only one byte.
       */
      if (len == 1) {
            cr |= MXC_I2CR_TXAK;
      } else {
            cr &= ~MXC_I2CR_TXAK;
      }
      writew(cr, dev->membase + MXC_I2CR);
      /*
       * Dummy read only at the end of an address cycle
       */
      if (addr_comp > 0) {
            readw(dev->membase + MXC_I2DR);
      }

      for (i = 0; i < len; i++) {
            /*
             * Wait for data transmission to complete
             */
            if (mxc_i2c_wait_for_tc(dev, msg->flags)) {
                  mxc_i2c_stop(dev);
                  return -1;
            }
            /*
             * Do not generate an ACK for the last byte
             */
            if (i == (len - 2)) {
                  cr = readw(dev->membase + MXC_I2CR);
                  cr |= MXC_I2CR_TXAK;
                  writew(cr, dev->membase + MXC_I2CR);
            } else if (i == (len - 1)) {
                  if (last) {
                        mxc_i2c_stop(dev);
                  }
            }
            /* Read the data */
            *buf++ = readw(dev->membase + MXC_I2DR);
      }

      return i;
}


Generated by  Doxygen 1.6.0   Back to index