[U-Boot] [PATCH 4/4 V5] I2C: mxc_i2c rework

Anatolij Gustschin
2011-10-14T16:28:55Z

Hi Marek,

On Thu, 22 Sep 2011 21:22:12 +0200
Marek Vasut <marek.vasut@gmail.com> wrote:

> Rewrite the mxc_i2c driver.
> * This version is much closer to Linux implementation.
> * Fixes IPG_PERCLK being incorrectly used as clock source
> * Fixes behaviour of the driver on iMX51
> * Clean up coding style a bit ;-)
>
> Signed-off-by: Marek Vasut <marek.vasut@gmail.com>
> Cc: Stefano Babic <sbabic@denx.de>
> Cc: Heiko Schocher <hs@denx.de>
> Cc: Jason Hui <jason.hui@linaro.org>
> ---
> drivers/i2c/mxc_i2c.c | 422 +++++++++++++++++++++++++++++++++----------------
> 1 files changed, 289 insertions(+), 133 deletions(-)

Unfortunately this patch breaks accessing the I2C EEPROM on
imx31_phycore board. On this board the U-Boot environment
is stored in the I2C EEPROM. With this patch applied reading
the environment doesn't work correctly, I always get "bad CRC"
warning and fall back to default environment. Some EEPROM data
dumps using i2c commands reveal that the EEPROM data addressing
is broken, this is due to the wrong swapping of address bytes
in the code below:

> +/*
> + * Write register address
> + */
> +int i2c_imx_set_reg_addr(uint addr, int alen)
> {
> - int i, retry = 0;
> - for (retry = 0; retry < 3; retry++) {
> - if (wait_idle())
> + struct mxc_i2c_regs *i2c_regs = (struct mxc_i2c_regs *)I2C_BASE;
> + int ret;
> + int i;
> +
> + for (i = 0; i < (8 * alen); i += 8) {
> + writeb((addr >> i) & 0xff, &i2c_regs->i2dr);
> +
> + ret = i2c_imx_trx_complete();
> + if (ret)
> break;

Applying the patch below fixes the EEPROM addressing issue,
i2c commands seem to work correctly:
dumping the EEPROM data to memory by

uboot> i2c read 0x52 0.2 1000 80000000
uboot> md 80000000 1
80000000: cf6bcdbd ..k.

and calculating the checksum by

uboot> crc 80000004 ffc
CRC32 for 80000004 ... 80000fff ==> cf6bcdbd

shows that it works, but when the board boots, the
reading of the environment still doesn't work. Bad CRC
is always reported, even with the below patch applied.
Reverting this driver rework commit fixes the issue.

Any idea where the problem could be?

Thanks,
Anatolij

diff --git a/drivers/i2c/mxc_i2c.c b/drivers/i2c/mxc_i2c.c
index a805bf6..9984c2a 100644
--- a/drivers/i2c/mxc_i2c.c
+++ b/drivers/i2c/mxc_i2c.c
@@ -291,11 +291,10 @@ int i2c_imx_set_chip_addr(uchar chip, int read)
int i2c_imx_set_reg_addr(uint addr, int alen)
{
struct mxc_i2c_regs *i2c_regs = (struct mxc_i2c_regs *)I2C_BASE;
- int ret;
- int i;
+ int ret = 0;

- for (i = 0; i < (8 * alen); i += 8) {
- writeb((addr >> i) & 0xff, &i2c_regs->i2dr);
+ while (alen--) {
+ writeb((addr >> (alen * 8)) & 0xff, &i2c_regs->i2dr);

ret = i2c_imx_trx_complete();
if (ret)