summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorNitin Kumbhar <nkumbhar@nvidia.com>2011-03-24 16:21:21 +0530
committerVarun Colbert <vcolbert@nvidia.com>2011-03-25 17:08:59 -0700
commit93da32d7e16da64d6d4dd37fb18125ad0be8aa63 (patch)
tree678ba046dc69078ab55a5f4685862b82442f0bb9 /drivers
parenta6064a56e19c9b808d0512499c3d13a88f9cd178 (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.c15
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);