AnsweredAssumed Answered

mx28 I2C support for RESTART operation

Question asked by Matthew Hilder on Dec 11, 2012
Latest reply on Dec 17, 2012 by Matthew Hilder

   Some I2C peripherals require a RESTART sequence to read registers, e.g.

START, I2C address+WR, write register number, RESTART, I2C address+RD, read register value, STOP

 

Previous Freescale I2C drivers handled this OK but the mx28 driver linux-2.6.35.3/drivers/i2c/busses/i2c-mxs.c has a couple of bugs that prevent this from working.

In DMA mode, the function hw_i2c_dma_setup_write has line desc[2]->cmd.pio_words[0] |= BM_I2C_CTRL0_POST_SEND_STOP; which forces a STOP operation on the bus instead of allowing a possible RESTART.

This line can be safely deleted as the very next line ORs in "flags" which will assert STOP only when necessary.

 

In PIOQUEUE mode as it stands the I2C operation times out as the isr never sees the bus go idle after the I2C write sequence - we are correctly holding the bus for a RESTART.  One way to make it work is to queue up both the I2C write and I2C read commands before looking for command completion.  This way both commands run and the isr correctly completes after the read portion.
i.e. in mxs_i2c_xfer_msg

hw_i2c_pioq_setup_write(dev,

                        msg->addr,

                        msg->buf, msg->len, flags);

hw_i2c_pioq_run(dev);

---becomes---

hw_i2c_pioq_setup_write(dev,

                        msg->addr,

                        msg->buf, msg->len, flags);

 

if (!stop)

                return dev->cmd_err;

hw_i2c_pioq_run(dev);

 

In keeping with the rest of the file there is no error checking on FIFO space available.

 

It would also be nice to be able to specify the I2C clock speed in the platform data and have the module calculate values for the TIMING registers.  At present I've just hard coded these into the i2c-mxs.c file and apply them anytime the I2C module is reset.

 

Hope this helps some-one.

 

Matt.

 

Outcomes