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 | |
| 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>
| -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) { |
