Commit c413767e authored by Chaithrika U S's avatar Chaithrika U S Committed by Kevin Hilman

i2c: davinci: Add helper functions for power management

Add i2c reset control and clock divider calculation functions
which will be useful for power management features.
Signed-off-by: default avatarChaithrika U S <chaithrika@ti.com>
Acked-by: default avatarKevin Hilman <khilman@deeprootsystems.com>
parent 36f78aaa
...@@ -126,12 +126,21 @@ static inline u16 davinci_i2c_read_reg(struct davinci_i2c_dev *i2c_dev, int reg) ...@@ -126,12 +126,21 @@ static inline u16 davinci_i2c_read_reg(struct davinci_i2c_dev *i2c_dev, int reg)
return __raw_readw(i2c_dev->base + reg); return __raw_readw(i2c_dev->base + reg);
} }
/* static inline void davinci_i2c_reset_ctrl(struct davinci_i2c_dev *i2c_dev,
* This functions configures I2C and brings I2C out of reset. int val)
* This function is called during I2C init function. This function {
* also gets called if I2C encounters any errors. u16 w;
*/
static int i2c_davinci_init(struct davinci_i2c_dev *dev) w = davinci_i2c_read_reg(i2c_dev, DAVINCI_I2C_MDR_REG);
if (!val) /* put I2C into reset */
w &= ~DAVINCI_I2C_MDR_IRS;
else /* take I2C out of reset */
w |= DAVINCI_I2C_MDR_IRS;
davinci_i2c_write_reg(i2c_dev, DAVINCI_I2C_MDR_REG, w);
}
static void i2c_davinci_calc_clk_dividers(struct davinci_i2c_dev *dev)
{ {
struct davinci_i2c_platform_data *pdata = dev->dev->platform_data; struct davinci_i2c_platform_data *pdata = dev->dev->platform_data;
u16 psc; u16 psc;
...@@ -140,15 +149,6 @@ static int i2c_davinci_init(struct davinci_i2c_dev *dev) ...@@ -140,15 +149,6 @@ static int i2c_davinci_init(struct davinci_i2c_dev *dev)
u32 clkh; u32 clkh;
u32 clkl; u32 clkl;
u32 input_clock = clk_get_rate(dev->clk); u32 input_clock = clk_get_rate(dev->clk);
u16 w;
if (!pdata)
pdata = &davinci_i2c_platform_data_default;
/* put I2C into reset */
w = davinci_i2c_read_reg(dev, DAVINCI_I2C_MDR_REG);
w &= ~DAVINCI_I2C_MDR_IRS;
davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, w);
/* NOTE: I2C Clock divider programming info /* NOTE: I2C Clock divider programming info
* As per I2C specs the following formulas provide prescaler * As per I2C specs the following formulas provide prescaler
...@@ -180,12 +180,32 @@ static int i2c_davinci_init(struct davinci_i2c_dev *dev) ...@@ -180,12 +180,32 @@ static int i2c_davinci_init(struct davinci_i2c_dev *dev)
davinci_i2c_write_reg(dev, DAVINCI_I2C_CLKH_REG, clkh); davinci_i2c_write_reg(dev, DAVINCI_I2C_CLKH_REG, clkh);
davinci_i2c_write_reg(dev, DAVINCI_I2C_CLKL_REG, clkl); davinci_i2c_write_reg(dev, DAVINCI_I2C_CLKL_REG, clkl);
dev_dbg(dev->dev, "input_clock = %d, CLK = %d\n", input_clock, clk);
}
/*
* This function configures I2C and brings I2C out of reset.
* This function is called during I2C init function. This function
* also gets called if I2C encounters any errors.
*/
static int i2c_davinci_init(struct davinci_i2c_dev *dev)
{
struct davinci_i2c_platform_data *pdata = dev->dev->platform_data;
if (!pdata)
pdata = &davinci_i2c_platform_data_default;
/* put I2C into reset */
davinci_i2c_reset_ctrl(dev, 0);
/* compute clock dividers */
i2c_davinci_calc_clk_dividers(dev);
/* Respond at reserved "SMBus Host" slave address" (and zero); /* Respond at reserved "SMBus Host" slave address" (and zero);
* we seem to have no option to not respond... * we seem to have no option to not respond...
*/ */
davinci_i2c_write_reg(dev, DAVINCI_I2C_OAR_REG, 0x08); davinci_i2c_write_reg(dev, DAVINCI_I2C_OAR_REG, 0x08);
dev_dbg(dev->dev, "input_clock = %d, CLK = %d\n", input_clock, clk);
dev_dbg(dev->dev, "PSC = %d\n", dev_dbg(dev->dev, "PSC = %d\n",
davinci_i2c_read_reg(dev, DAVINCI_I2C_PSC_REG)); davinci_i2c_read_reg(dev, DAVINCI_I2C_PSC_REG));
dev_dbg(dev->dev, "CLKL = %d\n", dev_dbg(dev->dev, "CLKL = %d\n",
...@@ -196,9 +216,7 @@ static int i2c_davinci_init(struct davinci_i2c_dev *dev) ...@@ -196,9 +216,7 @@ static int i2c_davinci_init(struct davinci_i2c_dev *dev)
pdata->bus_freq, pdata->bus_delay); pdata->bus_freq, pdata->bus_delay);
/* Take the I2C module out of reset: */ /* Take the I2C module out of reset: */
w = davinci_i2c_read_reg(dev, DAVINCI_I2C_MDR_REG); davinci_i2c_reset_ctrl(dev, 1);
w |= DAVINCI_I2C_MDR_IRS;
davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, w);
/* Enable interrupts */ /* Enable interrupts */
davinci_i2c_write_reg(dev, DAVINCI_I2C_IMR_REG, I2C_DAVINCI_INTR_ALL); davinci_i2c_write_reg(dev, DAVINCI_I2C_IMR_REG, I2C_DAVINCI_INTR_ALL);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment