summaryrefslogtreecommitdiff
path: root/drivers/i2c
diff options
context:
space:
mode:
authorNitin Kumbhar <nkumbhar@nvidia.com>2011-03-24 16:21:21 +0530
committerDan Willemsen <dwillemsen@nvidia.com>2011-11-30 21:41:50 -0800
commit1828bd6171fbc8f02c6cc1bb21b7bfe920a5d090 (patch)
tree64b87b5f1419ab0fc5e933996247da1fdea3956b /drivers/i2c
parent7b62b15d270e0327cc9ea49f527e197e3f56a713 (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.c14
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);