diff options
Diffstat (limited to 'drivers/gpio')
-rw-r--r-- | drivers/gpio/twl4030-gpio.c | 54 |
1 files changed, 23 insertions, 31 deletions
diff --git a/drivers/gpio/twl4030-gpio.c b/drivers/gpio/twl4030-gpio.c index 37d3eec8730a..afad14792141 100644 --- a/drivers/gpio/twl4030-gpio.c +++ b/drivers/gpio/twl4030-gpio.c | |||
@@ -202,37 +202,6 @@ static int twl4030_get_gpio_datain(int gpio) | |||
202 | return ret; | 202 | return ret; |
203 | } | 203 | } |
204 | 204 | ||
205 | /* | ||
206 | * Configure debounce timing value for a GPIO pin on TWL4030 | ||
207 | */ | ||
208 | int twl4030_set_gpio_debounce(int gpio, int enable) | ||
209 | { | ||
210 | u8 d_bnk = gpio >> 3; | ||
211 | u8 d_msk = BIT(gpio & 0x7); | ||
212 | u8 reg = 0; | ||
213 | u8 base = 0; | ||
214 | int ret = 0; | ||
215 | |||
216 | if (unlikely((gpio >= TWL4030_GPIO_MAX) | ||
217 | || !(gpio_usage_count & BIT(gpio)))) | ||
218 | return -EPERM; | ||
219 | |||
220 | base = REG_GPIO_DEBEN1 + d_bnk; | ||
221 | mutex_lock(&gpio_lock); | ||
222 | ret = gpio_twl4030_read(base); | ||
223 | if (ret >= 0) { | ||
224 | if (enable) | ||
225 | reg = ret | d_msk; | ||
226 | else | ||
227 | reg = ret & ~d_msk; | ||
228 | |||
229 | ret = gpio_twl4030_write(base, reg); | ||
230 | } | ||
231 | mutex_unlock(&gpio_lock); | ||
232 | return ret; | ||
233 | } | ||
234 | EXPORT_SYMBOL(twl4030_set_gpio_debounce); | ||
235 | |||
236 | /*----------------------------------------------------------------------*/ | 205 | /*----------------------------------------------------------------------*/ |
237 | 206 | ||
238 | static int twl_request(struct gpio_chip *chip, unsigned offset) | 207 | static int twl_request(struct gpio_chip *chip, unsigned offset) |
@@ -405,6 +374,23 @@ static int __devinit gpio_twl4030_pulls(u32 ups, u32 downs) | |||
405 | REG_GPIOPUPDCTR1, 5); | 374 | REG_GPIOPUPDCTR1, 5); |
406 | } | 375 | } |
407 | 376 | ||
377 | static int __devinit gpio_twl4030_debounce(u32 debounce, u8 mmc_cd) | ||
378 | { | ||
379 | u8 message[4]; | ||
380 | |||
381 | /* 30 msec of debouncing is always used for MMC card detect, | ||
382 | * and is optional for everything else. | ||
383 | */ | ||
384 | message[1] = (debounce & 0xff) | (mmc_cd & 0x03); | ||
385 | debounce >>= 8; | ||
386 | message[2] = (debounce & 0xff); | ||
387 | debounce >>= 8; | ||
388 | message[3] = (debounce & 0x03); | ||
389 | |||
390 | return twl4030_i2c_write(TWL4030_MODULE_GPIO, message, | ||
391 | REG_GPIO_DEBEN1, 3); | ||
392 | } | ||
393 | |||
408 | static int gpio_twl4030_remove(struct platform_device *pdev); | 394 | static int gpio_twl4030_remove(struct platform_device *pdev); |
409 | 395 | ||
410 | static int __devinit gpio_twl4030_probe(struct platform_device *pdev) | 396 | static int __devinit gpio_twl4030_probe(struct platform_device *pdev) |
@@ -439,6 +425,12 @@ no_irqs: | |||
439 | pdata->pullups, pdata->pulldowns, | 425 | pdata->pullups, pdata->pulldowns, |
440 | ret); | 426 | ret); |
441 | 427 | ||
428 | ret = gpio_twl4030_debounce(pdata->debounce, pdata->mmc_cd); | ||
429 | if (ret) | ||
430 | dev_dbg(&pdev->dev, "debounce %.03x %.01x --> %d\n", | ||
431 | pdata->debounce, pdata->mmc_cd, | ||
432 | ret); | ||
433 | |||
442 | twl_gpiochip.base = pdata->gpio_base; | 434 | twl_gpiochip.base = pdata->gpio_base; |
443 | twl_gpiochip.ngpio = TWL4030_GPIO_MAX; | 435 | twl_gpiochip.ngpio = TWL4030_GPIO_MAX; |
444 | twl_gpiochip.dev = &pdev->dev; | 436 | twl_gpiochip.dev = &pdev->dev; |