diff options
author | Nitin Kumbhar <nkumbhar@nvidia.com> | 2011-03-24 16:21:21 +0530 |
---|---|---|
committer | Dan Willemsen <dwillemsen@nvidia.com> | 2011-11-30 21:41:50 -0800 |
commit | 1828bd6171fbc8f02c6cc1bb21b7bfe920a5d090 (patch) | |
tree | 64b87b5f1419ab0fc5e933996247da1fdea3956b /drivers/i2c | |
parent | 7b62b15d270e0327cc9ea49f527e197e3f56a713 (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)
Original-Change-Id: Id5d5bd809df4a583a743d84a91aecbb78889a3c6
Reviewed-on: http://git-master/r/24246
Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com>
Tested-by: Bharat Nihalani <bnihalani@nvidia.com>
Rebase-Id: Re4b74bb7df316c939cb619da87d2f6fd1ccb35dc
Diffstat (limited to 'drivers/i2c')
-rw-r--r-- | drivers/i2c/busses/i2c-tegra.c | 14 |
1 files changed, 14 insertions, 0 deletions
diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c index 4bc4f0174c28..87bee539f1a0 100644 --- a/drivers/i2c/busses/i2c-tegra.c +++ b/drivers/i2c/busses/i2c-tegra.c @@ -143,6 +143,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; @@ -358,6 +359,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; @@ -391,6 +399,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; @@ -758,6 +769,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); |