Adding Mangling capability to i2c imx bus controller. Signed-off-by: Fabien Marteau <fabien.marteau@xxxxxxxxxxxx> --- Index: linux-2.6.36/drivers/i2c/busses/i2c-imx.c =================================================================== --- linux-2.6.36.orig/drivers/i2c/busses/i2c-imx.c 2010-10-20 22:30:22.000000000 +0200 +++ linux-2.6.36/drivers/i2c/busses/i2c-imx.c 2011-01-31 16:23:34.000000000 +0100 @@ -300,17 +300,28 @@ { int i, result; - dev_dbg(&i2c_imx->adapter.dev, "<%s> write slave address: addr=0x%x\n", - __func__, msgs->addr << 1); + if ((msgs->flags & I2C_M_NOSTART) == 0) { + /* write slave address */ + if (msgs->flags & I2C_M_REV_DIR_ADDR) { + dev_dbg(&i2c_imx->adapter.dev, + "<%s> write slave address: addr=0x%x\n", + __func__, msgs->addr << 1 | 0x01); + writeb((msgs->addr << 1) | 0x01, + i2c_imx->base + IMX_I2C_I2DR); + } else { + dev_dbg(&i2c_imx->adapter.dev, + "<%s> write slave address: addr=0x%x\n", + __func__, msgs->addr << 1); + writeb((msgs->addr << 1), i2c_imx->base + IMX_I2C_I2DR); + } + result = i2c_imx_trx_complete(i2c_imx); + if (result) + return result; + result = i2c_imx_acked(i2c_imx); + if (result != 0) + return result; + } - /* write slave address */ - writeb(msgs->addr << 1, i2c_imx->base + IMX_I2C_I2DR); - result = i2c_imx_trx_complete(i2c_imx); - if (result) - return result; - result = i2c_imx_acked(i2c_imx); - if (result) - return result; dev_dbg(&i2c_imx->adapter.dev, "<%s> write data\n", __func__); /* write data */ @@ -323,7 +334,7 @@ if (result) return result; result = i2c_imx_acked(i2c_imx); - if (result) + if ((result != 0) && ((msgs[0].flags & I2C_M_IGNORE_NAK) == 0)) return result; } return 0; @@ -334,18 +345,27 @@ int i, result; unsigned int temp; - dev_dbg(&i2c_imx->adapter.dev, - "<%s> write slave address: addr=0x%x\n", - __func__, (msgs->addr << 1) | 0x01); - - /* write slave address */ - writeb((msgs->addr << 1) | 0x01, i2c_imx->base + IMX_I2C_I2DR); - result = i2c_imx_trx_complete(i2c_imx); - if (result) - return result; - result = i2c_imx_acked(i2c_imx); - if (result) - return result; + if ((msgs->flags & I2C_M_NOSTART) == 0) { + /* write slave address */ + if (msgs->flags & I2C_M_REV_DIR_ADDR) { + dev_dbg(&i2c_imx->adapter.dev, + "<%s> write slave address: addr=0x%x\n", + __func__, (msgs->addr << 1)); + writeb((msgs->addr << 1), i2c_imx->base + IMX_I2C_I2DR); + } else { + dev_dbg(&i2c_imx->adapter.dev, + "<%s> write slave address: addr=0x%x\n", + __func__, (msgs->addr << 1) | 0x01); + writeb((msgs->addr << 1) | 0x01, + i2c_imx->base + IMX_I2C_I2DR); + } + result = i2c_imx_trx_complete(i2c_imx); + if (result) + return result; + result = i2c_imx_acked(i2c_imx); + if (result != 0) + return result; + } dev_dbg(&i2c_imx->adapter.dev, "<%s> setup bus\n", __func__); @@ -405,7 +425,7 @@ /* read/write data */ for (i = 0; i < num; i++) { - if (i) { + if (i && ((msgs[i].flags & I2C_M_NOSTART) == 0)) { dev_dbg(&i2c_imx->adapter.dev, "<%s> repeated start\n", __func__); temp = readb(i2c_imx->base + IMX_I2C_I2CR); @@ -454,7 +474,7 @@ static u32 i2c_imx_func(struct i2c_adapter *adapter) { - return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; + return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_PROTOCOL_MANGLING; } static struct i2c_algorithm i2c_imx_algo = { -- To unsubscribe from this list: send the line "unsubscribe linux-i2c" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html