diff options
author | Chaitanya Bandi <bandik@nvidia.com> | 2013-01-28 19:18:16 +0530 |
---|---|---|
committer | Dan Willemsen <dwillemsen@nvidia.com> | 2013-09-14 12:58:48 -0700 |
commit | 5aa48105f13266b2ec58d3761df3312ffc8882ad (patch) | |
tree | 00be369c2bf0bd3a994afa20976ffa03196b0c94 /drivers/i2c | |
parent | 662c97036f0aeb7e36df92e8c84360950f05b095 (diff) |
i2c: tegra: Add CONFIG_LOAD register setting for T14x
Added CONFIG_LOAD register setting for T14x.
Change-Id: Ib667362cd8881d50f24c0942d3acbb40f7fbf9c5
Signed-off-by: Chaitanya Bandi <bandik@nvidia.com>
Reviewed-on: http://git-master/r/194696
GVS: Gerrit_Virtual_Submit
Reviewed-by: Laxman Dewangan <ldewangan@nvidia.com>
Diffstat (limited to 'drivers/i2c')
-rw-r--r-- | drivers/i2c/busses/i2c-tegra.c | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c index bdb1399fd157..324fbd397211 100644 --- a/drivers/i2c/busses/i2c-tegra.c +++ b/drivers/i2c/busses/i2c-tegra.c @@ -123,6 +123,11 @@ #define I2C_BUS_CLEAR_STATUS 0x088 #define I2C_BC_STATUS (1<<0) +#define I2C_CONFIG_LOAD 0x08C +#define I2C_MSTR_CONFIG_LOAD (1 << 0) +#define I2C_SLV_CONFIG_LOAD (1 << 1) +#define I2C_TIMEOUT_CONFIG_LOAD (1 << 2) + #define SL_ADDR1(addr) (addr & 0xff) #define SL_ADDR2(addr) ((addr >> 8) & 0xff) @@ -150,6 +155,7 @@ struct tegra_i2c_chipdata { u16 clk_divisor_std_fast_mode; u16 clk_divisor_hs_mode; int clk_multiplier_hs_mode; + bool has_config_load_reg; }; /** @@ -496,6 +502,7 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev) u32 val; int err = 0; u32 clk_divisor = 0; + unsigned long timeout = jiffies + HZ; err = tegra_i2c_clock_enable(i2c_dev); if (err < 0) { @@ -542,6 +549,17 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev) if (tegra_i2c_flush_fifos(i2c_dev)) err = -ETIMEDOUT; + if (i2c_dev->chipdata->has_config_load_reg) { + i2c_writel(i2c_dev, I2C_MSTR_CONFIG_LOAD, I2C_CONFIG_LOAD); + while (i2c_readl(i2c_dev, I2C_CONFIG_LOAD) != 0) { + if (time_after(jiffies, timeout)) { + dev_warn(i2c_dev->dev, "timeout waiting for config load\n"); + return -ETIMEDOUT; + } + msleep(1); + } + } + tegra_i2c_clock_disable(i2c_dev); if (i2c_dev->irq_disabled) { @@ -776,6 +794,7 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev, u32 int_mask; int ret; unsigned long flags = 0; + unsigned long timeout = jiffies + HZ; if (msg->len == 0) return -EINVAL; @@ -908,6 +927,20 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev, | I2C_BC_STOP_COND | I2C_BC_TERMINATE , I2C_BUS_CLEAR_CNFG); + + if (i2c_dev->chipdata->has_config_load_reg) { + i2c_writel(i2c_dev, I2C_MSTR_CONFIG_LOAD, + I2C_CONFIG_LOAD); + while (i2c_readl(i2c_dev, I2C_CONFIG_LOAD) != 0) { + if (time_after(jiffies, timeout)) { + dev_warn(i2c_dev->dev, + "timeout config_load"); + return -ETIMEDOUT; + } + msleep(1); + } + } + tegra_i2c_unmask_irq(i2c_dev, I2C_INT_BUS_CLEAR_DONE); wait_for_completion_timeout(&i2c_dev->msg_complete, @@ -1055,6 +1088,7 @@ static struct tegra_i2c_chipdata tegra20_i2c_chipdata = { .clk_divisor_std_fast_mode = 0, .clk_divisor_hs_mode = 3, .clk_multiplier_hs_mode = 12, + .has_config_load_reg = false, }; static struct tegra_i2c_chipdata tegra30_i2c_chipdata = { @@ -1067,6 +1101,7 @@ static struct tegra_i2c_chipdata tegra30_i2c_chipdata = { .clk_divisor_std_fast_mode = 0, .clk_divisor_hs_mode = 3, .clk_multiplier_hs_mode = 12, + .has_config_load_reg = false, }; static struct tegra_i2c_chipdata tegra114_i2c_chipdata = { @@ -1079,6 +1114,7 @@ static struct tegra_i2c_chipdata tegra114_i2c_chipdata = { .clk_divisor_std_fast_mode = 0x19, .clk_divisor_hs_mode = 1, .clk_multiplier_hs_mode = 3, + .has_config_load_reg = false, }; static struct tegra_i2c_chipdata tegra148_i2c_chipdata = { @@ -1091,6 +1127,7 @@ static struct tegra_i2c_chipdata tegra148_i2c_chipdata = { .clk_divisor_std_fast_mode = 0x19, .clk_divisor_hs_mode = 1, .clk_multiplier_hs_mode = 3, + .has_config_load_reg = true, }; /* Match table for of_platform binding */ |