aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c/busses
diff options
context:
space:
mode:
authorChaithrika U S <chaithrika@ti.com>2010-01-06 04:24:58 -0500
committerKevin Hilman <khilman@deeprootsystems.com>2010-08-05 12:38:32 -0400
commit5ae5b1136e0c434b076ab1f9cb39deebf6187f55 (patch)
treec9d9f9b0f7f6ef6528e537c20d963738dd712775 /drivers/i2c/busses
parentc062a2518d35a76e7db8519b2292191a47e3ab79 (diff)
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: Chaithrika U S <chaithrika@ti.com> Acked-by: Kevin Hilman <khilman@deeprootsystems.com>
Diffstat (limited to 'drivers/i2c/busses')
-rw-r--r--drivers/i2c/busses/i2c-davinci.c56
1 files changed, 37 insertions, 19 deletions
diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c
index 4e33909dd3f0..9afd9af4f550 100644
--- a/drivers/i2c/busses/i2c-davinci.c
+++ b/drivers/i2c/busses/i2c-davinci.c
@@ -126,12 +126,21 @@ static inline u16 davinci_i2c_read_reg(struct davinci_i2c_dev *i2c_dev, int reg)
126 return __raw_readw(i2c_dev->base + reg); 126 return __raw_readw(i2c_dev->base + reg);
127} 127}
128 128
129/* 129static inline void davinci_i2c_reset_ctrl(struct davinci_i2c_dev *i2c_dev,
130 * This functions configures I2C and brings I2C out of reset. 130 int val)
131 * This function is called during I2C init function. This function 131{
132 * also gets called if I2C encounters any errors. 132 u16 w;
133 */ 133
134static int i2c_davinci_init(struct davinci_i2c_dev *dev) 134 w = davinci_i2c_read_reg(i2c_dev, DAVINCI_I2C_MDR_REG);
135 if (!val) /* put I2C into reset */
136 w &= ~DAVINCI_I2C_MDR_IRS;
137 else /* take I2C out of reset */
138 w |= DAVINCI_I2C_MDR_IRS;
139
140 davinci_i2c_write_reg(i2c_dev, DAVINCI_I2C_MDR_REG, w);
141}
142
143static void i2c_davinci_calc_clk_dividers(struct davinci_i2c_dev *dev)
135{ 144{
136 struct davinci_i2c_platform_data *pdata = dev->dev->platform_data; 145 struct davinci_i2c_platform_data *pdata = dev->dev->platform_data;
137 u16 psc; 146 u16 psc;
@@ -140,15 +149,6 @@ static int i2c_davinci_init(struct davinci_i2c_dev *dev)
140 u32 clkh; 149 u32 clkh;
141 u32 clkl; 150 u32 clkl;
142 u32 input_clock = clk_get_rate(dev->clk); 151 u32 input_clock = clk_get_rate(dev->clk);
143 u16 w;
144
145 if (!pdata)
146 pdata = &davinci_i2c_platform_data_default;
147
148 /* put I2C into reset */
149 w = davinci_i2c_read_reg(dev, DAVINCI_I2C_MDR_REG);
150 w &= ~DAVINCI_I2C_MDR_IRS;
151 davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, w);
152 152
153 /* NOTE: I2C Clock divider programming info 153 /* NOTE: I2C Clock divider programming info
154 * As per I2C specs the following formulas provide prescaler 154 * As per I2C specs the following formulas provide prescaler
@@ -180,12 +180,32 @@ static int i2c_davinci_init(struct davinci_i2c_dev *dev)
180 davinci_i2c_write_reg(dev, DAVINCI_I2C_CLKH_REG, clkh); 180 davinci_i2c_write_reg(dev, DAVINCI_I2C_CLKH_REG, clkh);
181 davinci_i2c_write_reg(dev, DAVINCI_I2C_CLKL_REG, clkl); 181 davinci_i2c_write_reg(dev, DAVINCI_I2C_CLKL_REG, clkl);
182 182
183 dev_dbg(dev->dev, "input_clock = %d, CLK = %d\n", input_clock, clk);
184}
185
186/*
187 * This function configures I2C and brings I2C out of reset.
188 * This function is called during I2C init function. This function
189 * also gets called if I2C encounters any errors.
190 */
191static int i2c_davinci_init(struct davinci_i2c_dev *dev)
192{
193 struct davinci_i2c_platform_data *pdata = dev->dev->platform_data;
194
195 if (!pdata)
196 pdata = &davinci_i2c_platform_data_default;
197
198 /* put I2C into reset */
199 davinci_i2c_reset_ctrl(dev, 0);
200
201 /* compute clock dividers */
202 i2c_davinci_calc_clk_dividers(dev);
203
183 /* Respond at reserved "SMBus Host" slave address" (and zero); 204 /* Respond at reserved "SMBus Host" slave address" (and zero);
184 * we seem to have no option to not respond... 205 * we seem to have no option to not respond...
185 */ 206 */
186 davinci_i2c_write_reg(dev, DAVINCI_I2C_OAR_REG, 0x08); 207 davinci_i2c_write_reg(dev, DAVINCI_I2C_OAR_REG, 0x08);
187 208
188 dev_dbg(dev->dev, "input_clock = %d, CLK = %d\n", input_clock, clk);
189 dev_dbg(dev->dev, "PSC = %d\n", 209 dev_dbg(dev->dev, "PSC = %d\n",
190 davinci_i2c_read_reg(dev, DAVINCI_I2C_PSC_REG)); 210 davinci_i2c_read_reg(dev, DAVINCI_I2C_PSC_REG));
191 dev_dbg(dev->dev, "CLKL = %d\n", 211 dev_dbg(dev->dev, "CLKL = %d\n",
@@ -196,9 +216,7 @@ static int i2c_davinci_init(struct davinci_i2c_dev *dev)
196 pdata->bus_freq, pdata->bus_delay); 216 pdata->bus_freq, pdata->bus_delay);
197 217
198 /* Take the I2C module out of reset: */ 218 /* Take the I2C module out of reset: */
199 w = davinci_i2c_read_reg(dev, DAVINCI_I2C_MDR_REG); 219 davinci_i2c_reset_ctrl(dev, 1);
200 w |= DAVINCI_I2C_MDR_IRS;
201 davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, w);
202 220
203 /* Enable interrupts */ 221 /* Enable interrupts */
204 davinci_i2c_write_reg(dev, DAVINCI_I2C_IMR_REG, I2C_DAVINCI_INTR_ALL); 222 davinci_i2c_write_reg(dev, DAVINCI_I2C_IMR_REG, I2C_DAVINCI_INTR_ALL);