Message ID | OF3CD158BA.04CCFBB5-ONC12575B6.005911D5-C12575B6.005CAFC2@transmode.se (mailing list archive) |
---|---|
State | Superseded, archived |
Delegated to: | Kumar Gala |
Headers | show |
Hi Your patch (and the small addition to mpc_i2c_start) does not work for me. [ 35.765803] mpc_xfer() [ 35.785480] writeccr 0 [ 35.785505] writeccr 80 [ 35.785523] mpc_xfer: 1 bytes to 2c:W - 1 of 2 messages [ 35.798817] mpc_write addr=2c len=1 restart=0 [ 35.815327] writeccr f0 [ 35.815503] I2C: SR=a2 [ 35.818675] I2C: SR=a6 [ 35.821450] mpc_xfer: 1 bytes to 2c:R - 2 of 2 messages [ 35.827119] mpc_read addr=2c len=1 restart=1 [ 35.837463] writeccr f4 [ 35.837641] I2C: SR=a6 [ 35.840011] writeccr e8 [ 35.840133] I2C: SR=a3 [ 35.843596] writeccr 80 [ 35.843632] mpc_xfer() [ 35.855068] writeccr 0 [ 35.855093] writeccr 80 [ 35.855111] mpc_xfer: 1 bytes to 2c:W - 1 of 2 messages [ 35.865346] mpc_write addr=2c len=1 restart=0 [ 35.870109] writeccr f0 [ 35.870272] I2C: SR=a2 [ 35.873372] I2C: SR=a6 [ 35.875757] mpc_xfer: 1 bytes to 2c:R - 2 of 2 messages [ 35.881606] mpc_read addr=2c len=1 restart=1 [ 35.886290] writeccr f4 [ 35.886463] I2C: SR=a6 [ 35.889425] writeccr e8 [ 35.889575] I2C: SR=a7 [ 35.891944] writeccr 80 [ 35.961177] mpc_xfer() [ 35.972517] writeccr 0 [ 35.972541] writeccr 80 [ 35.972559] mpc_xfer: 1 bytes to 4e:W - 1 of 20 messages [ 35.982628] mpc_write addr=4e len=1 restart=0 [ 35.987389] writeccr f0 [ 35.987424] I2C: SR=b3 [ 35.990386] I2C: MAL [ 35.992971] i2c_wait(address) error: -5 [ 35.997215] writeccr 80 [ 35.997241] Error: i2c_transfer failed: -5 I have now spent a few hours trying a lot of different paths to fix this approach, but I simply cannot find a way to get i2c read to work without a trailing STOP condition with this controller. Is there a problem in applying my patch, as it should be "clean" improvement over the current implementation, which uses STOP condition, but does not work. Until Isomeone finds a way to get it to work without STOP, we will have a working driver, which I assume is what we want. Best regards, Esben Haabendal
diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c index 6c1cddd..d7edcd2 100644 --- a/drivers/i2c/busses/i2c-mpc.c +++ b/drivers/i2c/busses/i2c-mpc.c @@ -189,9 +189,6 @@ static int mpc_write(struct mpc_i2c *i2c, int target, unsigned timeout = i2c->adap.timeout; u32 flags = restart ? CCR_RSTA : 0; - /* Start with MEN */ - if (!restart) - writeccr(i2c, CCR_MEN); /* Start as master */ writeccr(i2c, CCR_MIEN | CCR_MEN | CCR_MSTA | CCR_MTX | flags); /* Write target byte */ @@ -220,9 +217,6 @@ static int mpc_read(struct mpc_i2c *i2c, int target, int i, result; u32 flags = restart ? CCR_RSTA : 0; - /* Start with MEN */ - if (!restart) - writeccr(i2c, CCR_MEN); /* Switch to read - restart */ writeccr(i2c, CCR_MIEN | CCR_MEN | CCR_MSTA | CCR_MTX | flags); /* Write target address byte - this time with the read flag set */ @@ -241,18 +235,15 @@ static int mpc_read(struct mpc_i2c *i2c, int target, readb(i2c->base + MPC_I2C_DR); } - for (i = 0; i < length; i++) { + for (i = length; i ; --i) { result = i2c_wait(i2c, timeout, 0); if (result < 0) return result; - /* Generate txack on next to last byte */ - if (i == length - 2) + /* Generate txack on next to last byte(s) */ + if (i <= 2) writeccr(i2c, CCR_MIEN | CCR_MEN | CCR_MSTA | CCR_TXAK); - /* Generate stop on last byte */ - if (i == length - 1) - writeccr(i2c, CCR_MIEN | CCR_MEN | CCR_TXAK); - data[i] = readb(i2c->base + MPC_I2C_DR); + data[length-i] = readb(i2c->base + MPC_I2C_DR); } return length;