diff options
author | Laxman Dewangan <ldewangan@nvidia.com> | 2012-02-17 09:56:21 -0500 |
---|---|---|
committer | Grant Likely <grant.likely@secretlab.ca> | 2012-03-05 09:49:44 -0500 |
commit | aca5ce14eb773a75e5d935968b2e390dc5bd29c3 (patch) | |
tree | 7da20e783f03b076d41163aad82dfb6878964ff9 /drivers/gpio | |
parent | 3d2ddfdcf05f5f816f829f81858c54827d7be5b4 (diff) |
gpio: gpiolib: Support for open drain/collector gpios
Adding support for the open drain gpio on which client
can specify the open drain property through GPIO flag
GPIOF_OPEN_DRAIN at the time of gpio request.
The open drain pins are normally pulled high and it
cannot be driven to output with value of 1 and so
when client request for setting the pin to HIGH, the
gpio will be set to input direction to make pin in tristate
and hence PULL-UP on pins will make the state to HIGH.
The open drain pin can be driven to LOW by setting output
with value of 0.
Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com>
Reviwed-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Acked-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Diffstat (limited to 'drivers/gpio')
-rw-r--r-- | drivers/gpio/gpiolib.c | 44 |
1 files changed, 42 insertions, 2 deletions
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index e633a2afbe90..5d25a33d5359 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c | |||
@@ -58,6 +58,7 @@ struct gpio_desc { | |||
58 | #define FLAG_TRIG_FALL 5 /* trigger on falling edge */ | 58 | #define FLAG_TRIG_FALL 5 /* trigger on falling edge */ |
59 | #define FLAG_TRIG_RISE 6 /* trigger on rising edge */ | 59 | #define FLAG_TRIG_RISE 6 /* trigger on rising edge */ |
60 | #define FLAG_ACTIVE_LOW 7 /* sysfs value has active low */ | 60 | #define FLAG_ACTIVE_LOW 7 /* sysfs value has active low */ |
61 | #define FLAG_OPEN_DRAIN 8 /* Gpio is open drain type */ | ||
61 | 62 | ||
62 | #define ID_SHIFT 16 /* add new flags before this one */ | 63 | #define ID_SHIFT 16 /* add new flags before this one */ |
63 | 64 | ||
@@ -1264,6 +1265,7 @@ void gpio_free(unsigned gpio) | |||
1264 | module_put(desc->chip->owner); | 1265 | module_put(desc->chip->owner); |
1265 | clear_bit(FLAG_ACTIVE_LOW, &desc->flags); | 1266 | clear_bit(FLAG_ACTIVE_LOW, &desc->flags); |
1266 | clear_bit(FLAG_REQUESTED, &desc->flags); | 1267 | clear_bit(FLAG_REQUESTED, &desc->flags); |
1268 | clear_bit(FLAG_OPEN_DRAIN, &desc->flags); | ||
1267 | } else | 1269 | } else |
1268 | WARN_ON(extra_checks); | 1270 | WARN_ON(extra_checks); |
1269 | 1271 | ||
@@ -1285,6 +1287,9 @@ int gpio_request_one(unsigned gpio, unsigned long flags, const char *label) | |||
1285 | if (err) | 1287 | if (err) |
1286 | return err; | 1288 | return err; |
1287 | 1289 | ||
1290 | if (flags & GPIOF_OPEN_DRAIN) | ||
1291 | set_bit(FLAG_OPEN_DRAIN, &gpio_desc[gpio].flags); | ||
1292 | |||
1288 | if (flags & GPIOF_DIR_IN) | 1293 | if (flags & GPIOF_DIR_IN) |
1289 | err = gpio_direction_input(gpio); | 1294 | err = gpio_direction_input(gpio); |
1290 | else | 1295 | else |
@@ -1434,6 +1439,10 @@ int gpio_direction_output(unsigned gpio, int value) | |||
1434 | struct gpio_desc *desc = &gpio_desc[gpio]; | 1439 | struct gpio_desc *desc = &gpio_desc[gpio]; |
1435 | int status = -EINVAL; | 1440 | int status = -EINVAL; |
1436 | 1441 | ||
1442 | /* Open drain pin should not be driven to 1 */ | ||
1443 | if (value && test_bit(FLAG_OPEN_DRAIN, &desc->flags)) | ||
1444 | return gpio_direction_input(gpio); | ||
1445 | |||
1437 | spin_lock_irqsave(&gpio_lock, flags); | 1446 | spin_lock_irqsave(&gpio_lock, flags); |
1438 | 1447 | ||
1439 | if (!gpio_is_valid(gpio)) | 1448 | if (!gpio_is_valid(gpio)) |
@@ -1570,6 +1579,31 @@ int __gpio_get_value(unsigned gpio) | |||
1570 | } | 1579 | } |
1571 | EXPORT_SYMBOL_GPL(__gpio_get_value); | 1580 | EXPORT_SYMBOL_GPL(__gpio_get_value); |
1572 | 1581 | ||
1582 | /* | ||
1583 | * _gpio_set_open_drain_value() - Set the open drain gpio's value. | ||
1584 | * @gpio: Gpio whose state need to be set. | ||
1585 | * @chip: Gpio chip. | ||
1586 | * @value: Non-zero for setting it HIGH otherise it will set to LOW. | ||
1587 | */ | ||
1588 | static void _gpio_set_open_drain_value(unsigned gpio, | ||
1589 | struct gpio_chip *chip, int value) | ||
1590 | { | ||
1591 | int err = 0; | ||
1592 | if (value) { | ||
1593 | err = chip->direction_input(chip, gpio - chip->base); | ||
1594 | if (!err) | ||
1595 | clear_bit(FLAG_IS_OUT, &gpio_desc[gpio].flags); | ||
1596 | } else { | ||
1597 | err = chip->direction_output(chip, gpio - chip->base, 0); | ||
1598 | if (!err) | ||
1599 | set_bit(FLAG_IS_OUT, &gpio_desc[gpio].flags); | ||
1600 | } | ||
1601 | trace_gpio_direction(gpio, value, err); | ||
1602 | if (err < 0) | ||
1603 | pr_err("%s: Error in set_value for open drain gpio%d err %d\n", | ||
1604 | __func__, gpio, err); | ||
1605 | } | ||
1606 | |||
1573 | /** | 1607 | /** |
1574 | * __gpio_set_value() - assign a gpio's value | 1608 | * __gpio_set_value() - assign a gpio's value |
1575 | * @gpio: gpio whose value will be assigned | 1609 | * @gpio: gpio whose value will be assigned |
@@ -1586,7 +1620,10 @@ void __gpio_set_value(unsigned gpio, int value) | |||
1586 | chip = gpio_to_chip(gpio); | 1620 | chip = gpio_to_chip(gpio); |
1587 | WARN_ON(chip->can_sleep); | 1621 | WARN_ON(chip->can_sleep); |
1588 | trace_gpio_value(gpio, 0, value); | 1622 | trace_gpio_value(gpio, 0, value); |
1589 | chip->set(chip, gpio - chip->base, value); | 1623 | if (test_bit(FLAG_OPEN_DRAIN, &gpio_desc[gpio].flags)) |
1624 | _gpio_set_open_drain_value(gpio, chip, value); | ||
1625 | else | ||
1626 | chip->set(chip, gpio - chip->base, value); | ||
1590 | } | 1627 | } |
1591 | EXPORT_SYMBOL_GPL(__gpio_set_value); | 1628 | EXPORT_SYMBOL_GPL(__gpio_set_value); |
1592 | 1629 | ||
@@ -1653,7 +1690,10 @@ void gpio_set_value_cansleep(unsigned gpio, int value) | |||
1653 | might_sleep_if(extra_checks); | 1690 | might_sleep_if(extra_checks); |
1654 | chip = gpio_to_chip(gpio); | 1691 | chip = gpio_to_chip(gpio); |
1655 | trace_gpio_value(gpio, 0, value); | 1692 | trace_gpio_value(gpio, 0, value); |
1656 | chip->set(chip, gpio - chip->base, value); | 1693 | if (test_bit(FLAG_OPEN_DRAIN, &gpio_desc[gpio].flags)) |
1694 | _gpio_set_open_drain_value(gpio, chip, value); | ||
1695 | else | ||
1696 | chip->set(chip, gpio - chip->base, value); | ||
1657 | } | 1697 | } |
1658 | EXPORT_SYMBOL_GPL(gpio_set_value_cansleep); | 1698 | EXPORT_SYMBOL_GPL(gpio_set_value_cansleep); |
1659 | 1699 | ||