
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)