diff options
author | Grygorii Strashko <grygorii.strashko@ti.com> | 2015-04-06 08:38:40 -0400 |
---|---|---|
committer | Wolfram Sang <wsa@the-dreams.de> | 2015-04-10 11:56:27 -0400 |
commit | 2e65676f710e8feb9f76a7beee649b0e5ff95ca3 (patch) | |
tree | 502ff002d2d97ad799d0eb443fe0c52130e36fb8 /drivers/i2c/busses | |
parent | 2b2190a375d796a5ad9ec557cb51269f36b264d4 (diff) |
i2c: davinci: use bus recovery infrastructure
This patch converts Davinci I2C driver to use I2C bus recovery
infrastructure, introduced by commit 5f9296ba21b3 ("i2c: Add
bus recovery infrastructure").
The i2c_bus_recovery_info is configured for Davinci I2C adapter
only in case scl_pin is provided in platform data.
As the controller must be held in reset while doing so, the
recovery routine must re-init the controller. Since this was already
being done after each call to i2c_recover_bus, move those calls into
the recovery_prepare/unprepare routines and as well.
Acked-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
Diffstat (limited to 'drivers/i2c/busses')
-rw-r--r-- | drivers/i2c/busses/i2c-davinci.c | 77 |
1 files changed, 36 insertions, 41 deletions
diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c index 120a4ef36ef5..54819fb4f82e 100644 --- a/drivers/i2c/busses/i2c-davinci.c +++ b/drivers/i2c/busses/i2c-davinci.c | |||
@@ -129,43 +129,6 @@ static inline u16 davinci_i2c_read_reg(struct davinci_i2c_dev *i2c_dev, int reg) | |||
129 | return readw_relaxed(i2c_dev->base + reg); | 129 | return readw_relaxed(i2c_dev->base + reg); |
130 | } | 130 | } |
131 | 131 | ||
132 | /* Generate a pulse on the i2c clock pin. */ | ||
133 | static void davinci_i2c_clock_pulse(unsigned int scl_pin) | ||
134 | { | ||
135 | u16 i; | ||
136 | |||
137 | if (scl_pin) { | ||
138 | /* Send high and low on the SCL line */ | ||
139 | for (i = 0; i < 9; i++) { | ||
140 | gpio_set_value(scl_pin, 0); | ||
141 | udelay(20); | ||
142 | gpio_set_value(scl_pin, 1); | ||
143 | udelay(20); | ||
144 | } | ||
145 | } | ||
146 | } | ||
147 | |||
148 | /* This routine does i2c bus recovery as specified in the | ||
149 | * i2c protocol Rev. 03 section 3.16 titled "Bus clear" | ||
150 | */ | ||
151 | static void davinci_i2c_recover_bus(struct davinci_i2c_dev *dev) | ||
152 | { | ||
153 | u32 flag = 0; | ||
154 | struct davinci_i2c_platform_data *pdata = dev->pdata; | ||
155 | |||
156 | dev_err(dev->dev, "initiating i2c bus recovery\n"); | ||
157 | /* Send NACK to the slave */ | ||
158 | flag = davinci_i2c_read_reg(dev, DAVINCI_I2C_MDR_REG); | ||
159 | flag |= DAVINCI_I2C_MDR_NACK; | ||
160 | /* write the data into mode register */ | ||
161 | davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag); | ||
162 | davinci_i2c_clock_pulse(pdata->scl_pin); | ||
163 | /* Send STOP */ | ||
164 | flag = davinci_i2c_read_reg(dev, DAVINCI_I2C_MDR_REG); | ||
165 | flag |= DAVINCI_I2C_MDR_STP; | ||
166 | davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag); | ||
167 | } | ||
168 | |||
169 | static inline void davinci_i2c_reset_ctrl(struct davinci_i2c_dev *i2c_dev, | 132 | static inline void davinci_i2c_reset_ctrl(struct davinci_i2c_dev *i2c_dev, |
170 | int val) | 133 | int val) |
171 | { | 134 | { |
@@ -263,6 +226,34 @@ static int i2c_davinci_init(struct davinci_i2c_dev *dev) | |||
263 | } | 226 | } |
264 | 227 | ||
265 | /* | 228 | /* |
229 | * This routine does i2c bus recovery by using i2c_generic_gpio_recovery | ||
230 | * which is provided by I2C Bus recovery infrastructure. | ||
231 | */ | ||
232 | static void davinci_i2c_prepare_recovery(struct i2c_adapter *adap) | ||
233 | { | ||
234 | struct davinci_i2c_dev *dev = i2c_get_adapdata(adap); | ||
235 | |||
236 | /* Disable interrupts */ | ||
237 | davinci_i2c_write_reg(dev, DAVINCI_I2C_IMR_REG, 0); | ||
238 | |||
239 | /* put I2C into reset */ | ||
240 | davinci_i2c_reset_ctrl(dev, 0); | ||
241 | } | ||
242 | |||
243 | static void davinci_i2c_unprepare_recovery(struct i2c_adapter *adap) | ||
244 | { | ||
245 | struct davinci_i2c_dev *dev = i2c_get_adapdata(adap); | ||
246 | |||
247 | i2c_davinci_init(dev); | ||
248 | } | ||
249 | |||
250 | static struct i2c_bus_recovery_info davinci_i2c_gpio_recovery_info = { | ||
251 | .recover_bus = i2c_generic_gpio_recovery, | ||
252 | .prepare_recovery = davinci_i2c_prepare_recovery, | ||
253 | .unprepare_recovery = davinci_i2c_unprepare_recovery, | ||
254 | }; | ||
255 | |||
256 | /* | ||
266 | * Waiting for bus not busy | 257 | * Waiting for bus not busy |
267 | */ | 258 | */ |
268 | static int i2c_davinci_wait_bus_not_busy(struct davinci_i2c_dev *dev, | 259 | static int i2c_davinci_wait_bus_not_busy(struct davinci_i2c_dev *dev, |
@@ -282,8 +273,7 @@ static int i2c_davinci_wait_bus_not_busy(struct davinci_i2c_dev *dev, | |||
282 | return -ETIMEDOUT; | 273 | return -ETIMEDOUT; |
283 | } else { | 274 | } else { |
284 | to_cnt = 0; | 275 | to_cnt = 0; |
285 | davinci_i2c_recover_bus(dev); | 276 | i2c_recover_bus(&dev->adapter); |
286 | i2c_davinci_init(dev); | ||
287 | } | 277 | } |
288 | } | 278 | } |
289 | if (allow_sleep) | 279 | if (allow_sleep) |
@@ -372,8 +362,7 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop) | |||
372 | dev->adapter.timeout); | 362 | dev->adapter.timeout); |
373 | if (!time_left) { | 363 | if (!time_left) { |
374 | dev_err(dev->dev, "controller timed out\n"); | 364 | dev_err(dev->dev, "controller timed out\n"); |
375 | davinci_i2c_recover_bus(dev); | 365 | i2c_recover_bus(adap); |
376 | i2c_davinci_init(dev); | ||
377 | dev->buf_len = 0; | 366 | dev->buf_len = 0; |
378 | return -ETIMEDOUT; | 367 | return -ETIMEDOUT; |
379 | } | 368 | } |
@@ -712,6 +701,12 @@ static int davinci_i2c_probe(struct platform_device *pdev) | |||
712 | adap->timeout = DAVINCI_I2C_TIMEOUT; | 701 | adap->timeout = DAVINCI_I2C_TIMEOUT; |
713 | adap->dev.of_node = pdev->dev.of_node; | 702 | adap->dev.of_node = pdev->dev.of_node; |
714 | 703 | ||
704 | if (dev->pdata->scl_pin) { | ||
705 | adap->bus_recovery_info = &davinci_i2c_gpio_recovery_info; | ||
706 | adap->bus_recovery_info->scl_gpio = dev->pdata->scl_pin; | ||
707 | adap->bus_recovery_info->sda_gpio = dev->pdata->sda_pin; | ||
708 | } | ||
709 | |||
715 | adap->nr = pdev->id; | 710 | adap->nr = pdev->id; |
716 | r = i2c_add_numbered_adapter(adap); | 711 | r = i2c_add_numbered_adapter(adap); |
717 | if (r) { | 712 | if (r) { |