summaryrefslogtreecommitdiff
path: root/drivers/i2c
diff options
context:
space:
mode:
authorChaitanya Bandi <bandik@nvidia.com>2012-08-17 21:07:06 +0530
committerVarun Colbert <vcolbert@nvidia.com>2012-08-22 17:33:32 -0700
commit2925aeea0965d77e2eb0dd9044a315ef12cb0747 (patch)
tree57971f9b8b66fdf4e1b61588942ff034784adfd5 /drivers/i2c
parent1ee27d967c401fb0241bd412d98f140ea4f8bc3a (diff)
i2c: tegra: Add support for clk divisor in standard/fast mode
Added support for clk divisor in standard/fast mode. Change-Id: I2cd8a6ee80979a4967d032d064babaea2978aab3 Signed-off-by: Chaitanya Bandi <bandik@nvidia.com> Reviewed-on: http://git-master/r/124399 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Laxman Dewangan <ldewangan@nvidia.com>
Diffstat (limited to 'drivers/i2c')
-rw-r--r--drivers/i2c/busses/i2c-tegra.c46
1 files changed, 37 insertions, 9 deletions
diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index 7dc9fa17a862..be2cfa407a6b 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -80,7 +80,10 @@
#define I2C_INT_ARBITRATION_LOST (1<<2)
#define I2C_INT_TX_FIFO_DATA_REQ (1<<1)
#define I2C_INT_RX_FIFO_DATA_REQ (1<<0)
+
#define I2C_CLK_DIVISOR 0x06c
+#define I2C_CLK_DIVISOR_STD_FAST_MODE_SHIFT 16
+#define I2C_CLK_MULTIPLIER_STD_FAST_MODE 8
#define DVC_CTRL_REG1 0x000
#define DVC_CTRL_REG1_INTR_EN (1<<10)
@@ -139,9 +142,12 @@ enum msg_end_type {
struct tegra_i2c_chipdata {
bool timeout_irq_occurs_before_bus_inactive;
bool has_xfer_complete_interrupt;
- u16 i2c_clock_multiplier;
bool has_hw_arb_support;
bool has_fast_clock;
+ bool has_clk_divisor_std_fast_mode;
+ u16 clk_divisor_std_fast_mode;
+ u16 clk_divisor_hs_mode;
+ int clk_multiplier_hs_mode;
};
struct tegra_i2c_dev;
@@ -485,10 +491,25 @@ static inline void tegra_i2c_clock_disable(struct tegra_i2c_dev *i2c_dev)
clk_disable(i2c_dev->fast_clk);
}
+static void tegra_i2c_set_clk_rate(struct tegra_i2c_dev *i2c_dev)
+{
+ u32 clk_multiplier;
+ if (i2c_dev->is_high_speed_enable)
+ clk_multiplier = i2c_dev->chipdata->clk_multiplier_hs_mode
+ * (i2c_dev->chipdata->clk_divisor_hs_mode + 1);
+ else
+ clk_multiplier = I2C_CLK_MULTIPLIER_STD_FAST_MODE
+ * (i2c_dev->chipdata->clk_divisor_std_fast_mode + 1);
+
+ clk_set_rate(i2c_dev->div_clk, i2c_dev->last_bus_clk_rate
+ * clk_multiplier);
+}
+
static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev)
{
u32 val;
int err = 0;
+ u32 clk_divisor = 0;
tegra_i2c_clock_enable(i2c_dev);
@@ -504,10 +525,13 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev)
i2c_writel(i2c_dev, val, I2C_CNFG);
i2c_writel(i2c_dev, 0, I2C_INT_MASK);
- clk_set_rate(i2c_dev->div_clk, i2c_dev->last_bus_clk_rate
- * i2c_dev->chipdata->i2c_clock_multiplier);
+ tegra_i2c_set_clk_rate(i2c_dev);
- i2c_writel(i2c_dev, 0x3, I2C_CLK_DIVISOR);
+ clk_divisor |= i2c_dev->chipdata->clk_divisor_hs_mode;
+ if (i2c_dev->chipdata->has_clk_divisor_std_fast_mode)
+ clk_divisor |= i2c_dev->chipdata->clk_divisor_std_fast_mode
+ << I2C_CLK_DIVISOR_STD_FAST_MODE_SHIFT;
+ i2c_writel(i2c_dev, clk_divisor, I2C_CLK_DIVISOR);
if (!i2c_dev->is_dvc) {
u32 sl_cfg = i2c_readl(i2c_dev, I2C_SL_CNFG);
@@ -853,9 +877,7 @@ static int tegra_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[],
}
if (i2c_dev->last_bus_clk_rate != i2c_bus->bus_clk_rate) {
- clk_set_rate(i2c_dev->div_clk, i2c_dev->last_bus_clk_rate
- * i2c_dev->chipdata->i2c_clock_multiplier);
-
+ tegra_i2c_set_clk_rate(i2c_dev);
i2c_dev->last_bus_clk_rate = i2c_bus->bus_clk_rate;
}
@@ -901,17 +923,23 @@ static const struct i2c_algorithm tegra_i2c_algo = {
static struct tegra_i2c_chipdata tegra20_i2c_chipdata = {
.timeout_irq_occurs_before_bus_inactive = true,
.has_xfer_complete_interrupt = false,
- .i2c_clock_multiplier = 8,
.has_hw_arb_support = false,
.has_fast_clock = true,
+ .has_clk_divisor_std_fast_mode = false,
+ .clk_divisor_std_fast_mode = 0,
+ .clk_divisor_hs_mode = 3,
+ .clk_multiplier_hs_mode = 12,
};
static struct tegra_i2c_chipdata tegra11_i2c_chipdata = {
.timeout_irq_occurs_before_bus_inactive = false,
.has_xfer_complete_interrupt = true,
- .i2c_clock_multiplier = 200,
.has_hw_arb_support = true,
.has_fast_clock = false,
+ .has_clk_divisor_std_fast_mode = true,
+ .clk_divisor_std_fast_mode = 0x19,
+ .clk_divisor_hs_mode = 1,
+ .clk_multiplier_hs_mode = 3,
};
/* Match table for of_platform binding */