diff options
author | Nitin Kumbhar <nkumbhar@nvidia.com> | 2011-03-24 16:21:21 +0530 |
---|---|---|
committer | Varun Colbert <vcolbert@nvidia.com> | 2011-03-25 17:08:59 -0700 |
commit | 93da32d7e16da64d6d4dd37fb18125ad0be8aa63 (patch) | |
tree | 678ba046dc69078ab55a5f4685862b82442f0bb9 /drivers | |
parent | a6064a56e19c9b808d0512499c3d13a88f9cd178 (diff) |
i2c: buses: tegra: use new i2c slave controller
tegra2 has an improved new i2c slave controller. This should be
used instead of the old i2c slave controller. With old i2c slave
controller, occasionally it generates spurious slave interrupts
causing disruptions in master i2c transfers.
BUG 788286
BUG 804545
Reviewed-on: http://git-master/r/24107
(cherry picked from commit 64a6e1d5a555be1c330de80cfb477563ae061452)
Change-Id: Id5d5bd809df4a583a743d84a91aecbb78889a3c6
Reviewed-on: http://git-master/r/24246
Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com>
Tested-by: Bharat Nihalani <bnihalani@nvidia.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/i2c/busses/i2c-tegra.c | 15 |
1 files changed, 15 insertions, 0 deletions
diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c index 49880008d5b5..30ffa65671dd 100644 --- a/drivers/i2c/busses/i2c-tegra.c +++ b/drivers/i2c/busses/i2c-tegra.c @@ -42,6 +42,7 @@ #define I2C_STATUS 0x01C #define I2C_STATUS_BUSY (1<<8) #define I2C_SL_CNFG 0x020 +#define I2C_SL_CNFG_NACK (1<<1) #define I2C_SL_CNFG_NEWSL (1<<2) #define I2C_SL_ADDR1 0x02c #define I2C_TX_FIFO 0x050 @@ -120,6 +121,7 @@ struct tegra_i2c_dev { int irq; bool irq_disabled; int is_dvc; + bool is_slave; struct completion msg_complete; int msg_err; u8 *msg_buf; @@ -307,6 +309,13 @@ static void tegra_dvc_init(struct tegra_i2c_dev *i2c_dev) dvc_writel(i2c_dev, val, DVC_CTRL_REG1); } +static void tegra_i2c_slave_init(struct tegra_i2c_dev *i2c_dev) +{ + u32 val = I2C_SL_CNFG_NEWSL | I2C_SL_CNFG_NACK; + + i2c_writel(i2c_dev, val, I2C_SL_CNFG); +} + static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev) { u32 val; @@ -330,6 +339,9 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev) 0 << I2C_FIFO_CONTROL_RX_TRIG_SHIFT; i2c_writel(i2c_dev, val, I2C_FIFO_CONTROL); + if (i2c_dev->is_slave) + tegra_i2c_slave_init(i2c_dev); + if (tegra_i2c_flush_fifos(i2c_dev)) err = -ETIMEDOUT; @@ -688,6 +700,9 @@ static int tegra_i2c_probe(struct platform_device *pdev) i2c_dev->is_dvc = plat->is_dvc; init_completion(&i2c_dev->msg_complete); + if (irq == INT_I2C || irq == INT_I2C3) + i2c_dev->is_slave = true; + platform_set_drvdata(pdev, i2c_dev); ret = tegra_i2c_init(i2c_dev); |