Commit bd63ace4 authored by Chew, Chiau Ee's avatar Chew, Chiau Ee Committed by Wolfram Sang

i2c: designware: 10-bit addressing mode enabling if I2C_DYNAMIC_TAR_UPDATE is set

According to Designware I2C spec, if I2C_DYNAMIC_TAR_UPDATE is set to 1,
the 10-bit addressing mode is controlled by IC_10BITADDR_MASTER bit of
IC_TAR register instead of IC_CON register. The IC_10BITADDR_MASTER
in IC_CON register becomes read-only copy. Since I2C_DYNAMIC_TAR_UPDATE
value can't be detected from hardware register, so we will always set the
IC_10BITADDR_MASTER bit in both IC_CON and IC_TAR register whenever 10-bit
addresing mode is requested by user application.
Signed-off-by: default avatarChew, Chiau Ee <chiau.ee.chew@intel.com>
Reviewed-by: default avatarMika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: default avatarWolfram Sang <wsa@the-dreams.de>
parent 85b3a935
...@@ -98,6 +98,8 @@ ...@@ -98,6 +98,8 @@
#define DW_IC_ERR_TX_ABRT 0x1 #define DW_IC_ERR_TX_ABRT 0x1
#define DW_IC_TAR_10BITADDR_MASTER BIT(12)
/* /*
* status codes * status codes
*/ */
...@@ -388,22 +390,34 @@ static int i2c_dw_wait_bus_not_busy(struct dw_i2c_dev *dev) ...@@ -388,22 +390,34 @@ static int i2c_dw_wait_bus_not_busy(struct dw_i2c_dev *dev)
static void i2c_dw_xfer_init(struct dw_i2c_dev *dev) static void i2c_dw_xfer_init(struct dw_i2c_dev *dev)
{ {
struct i2c_msg *msgs = dev->msgs; struct i2c_msg *msgs = dev->msgs;
u32 ic_con; u32 ic_con, ic_tar = 0;
/* Disable the adapter */ /* Disable the adapter */
__i2c_dw_enable(dev, false); __i2c_dw_enable(dev, false);
/* set the slave (target) address */
dw_writel(dev, msgs[dev->msg_write_idx].addr, DW_IC_TAR);
/* if the slave address is ten bit address, enable 10BITADDR */ /* if the slave address is ten bit address, enable 10BITADDR */
ic_con = dw_readl(dev, DW_IC_CON); ic_con = dw_readl(dev, DW_IC_CON);
if (msgs[dev->msg_write_idx].flags & I2C_M_TEN) if (msgs[dev->msg_write_idx].flags & I2C_M_TEN) {
ic_con |= DW_IC_CON_10BITADDR_MASTER; ic_con |= DW_IC_CON_10BITADDR_MASTER;
else /*
* If I2C_DYNAMIC_TAR_UPDATE is set, the 10-bit addressing
* mode has to be enabled via bit 12 of IC_TAR register.
* We set it always as I2C_DYNAMIC_TAR_UPDATE can't be
* detected from registers.
*/
ic_tar = DW_IC_TAR_10BITADDR_MASTER;
} else {
ic_con &= ~DW_IC_CON_10BITADDR_MASTER; ic_con &= ~DW_IC_CON_10BITADDR_MASTER;
}
dw_writel(dev, ic_con, DW_IC_CON); dw_writel(dev, ic_con, DW_IC_CON);
/*
* Set the slave (target) address and enable 10-bit addressing mode
* if applicable.
*/
dw_writel(dev, msgs[dev->msg_write_idx].addr | ic_tar, DW_IC_TAR);
/* Enable the adapter */ /* Enable the adapter */
__i2c_dw_enable(dev, true); __i2c_dw_enable(dev, true);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment