diff options
Diffstat (limited to 'drivers/gpio/gpiolib.c')
-rw-r--r-- | drivers/gpio/gpiolib.c | 83 |
1 files changed, 81 insertions, 2 deletions
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index a971e3d043b..a0fa0b25d21 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c | |||
@@ -58,6 +58,8 @@ 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 */ | ||
62 | #define FLAG_OPEN_SOURCE 9 /* Gpio is open source type */ | ||
61 | 63 | ||
62 | #define ID_SHIFT 16 /* add new flags before this one */ | 64 | #define ID_SHIFT 16 /* add new flags before this one */ |
63 | 65 | ||
@@ -1257,6 +1259,8 @@ void gpio_free(unsigned gpio) | |||
1257 | module_put(desc->chip->owner); | 1259 | module_put(desc->chip->owner); |
1258 | clear_bit(FLAG_ACTIVE_LOW, &desc->flags); | 1260 | clear_bit(FLAG_ACTIVE_LOW, &desc->flags); |
1259 | clear_bit(FLAG_REQUESTED, &desc->flags); | 1261 | clear_bit(FLAG_REQUESTED, &desc->flags); |
1262 | clear_bit(FLAG_OPEN_DRAIN, &desc->flags); | ||
1263 | clear_bit(FLAG_OPEN_SOURCE, &desc->flags); | ||
1260 | } else | 1264 | } else |
1261 | WARN_ON(extra_checks); | 1265 | WARN_ON(extra_checks); |
1262 | 1266 | ||
@@ -1278,6 +1282,12 @@ int gpio_request_one(unsigned gpio, unsigned long flags, const char *label) | |||
1278 | if (err) | 1282 | if (err) |
1279 | return err; | 1283 | return err; |
1280 | 1284 | ||
1285 | if (flags & GPIOF_OPEN_DRAIN) | ||
1286 | set_bit(FLAG_OPEN_DRAIN, &gpio_desc[gpio].flags); | ||
1287 | |||
1288 | if (flags & GPIOF_OPEN_SOURCE) | ||
1289 | set_bit(FLAG_OPEN_SOURCE, &gpio_desc[gpio].flags); | ||
1290 | |||
1281 | if (flags & GPIOF_DIR_IN) | 1291 | if (flags & GPIOF_DIR_IN) |
1282 | err = gpio_direction_input(gpio); | 1292 | err = gpio_direction_input(gpio); |
1283 | else | 1293 | else |
@@ -1427,6 +1437,14 @@ int gpio_direction_output(unsigned gpio, int value) | |||
1427 | struct gpio_desc *desc = &gpio_desc[gpio]; | 1437 | struct gpio_desc *desc = &gpio_desc[gpio]; |
1428 | int status = -EINVAL; | 1438 | int status = -EINVAL; |
1429 | 1439 | ||
1440 | /* Open drain pin should not be driven to 1 */ | ||
1441 | if (value && test_bit(FLAG_OPEN_DRAIN, &desc->flags)) | ||
1442 | return gpio_direction_input(gpio); | ||
1443 | |||
1444 | /* Open source pin should not be driven to 0 */ | ||
1445 | if (!value && test_bit(FLAG_OPEN_SOURCE, &desc->flags)) | ||
1446 | return gpio_direction_input(gpio); | ||
1447 | |||
1430 | spin_lock_irqsave(&gpio_lock, flags); | 1448 | spin_lock_irqsave(&gpio_lock, flags); |
1431 | 1449 | ||
1432 | if (!gpio_is_valid(gpio)) | 1450 | if (!gpio_is_valid(gpio)) |
@@ -1563,6 +1581,57 @@ int __gpio_get_value(unsigned gpio) | |||
1563 | } | 1581 | } |
1564 | EXPORT_SYMBOL_GPL(__gpio_get_value); | 1582 | EXPORT_SYMBOL_GPL(__gpio_get_value); |
1565 | 1583 | ||
1584 | /* | ||
1585 | * _gpio_set_open_drain_value() - Set the open drain gpio's value. | ||
1586 | * @gpio: Gpio whose state need to be set. | ||
1587 | * @chip: Gpio chip. | ||
1588 | * @value: Non-zero for setting it HIGH otherise it will set to LOW. | ||
1589 | */ | ||
1590 | static void _gpio_set_open_drain_value(unsigned gpio, | ||
1591 | struct gpio_chip *chip, int value) | ||
1592 | { | ||
1593 | int err = 0; | ||
1594 | if (value) { | ||
1595 | err = chip->direction_input(chip, gpio - chip->base); | ||
1596 | if (!err) | ||
1597 | clear_bit(FLAG_IS_OUT, &gpio_desc[gpio].flags); | ||
1598 | } else { | ||
1599 | err = chip->direction_output(chip, gpio - chip->base, 0); | ||
1600 | if (!err) | ||
1601 | set_bit(FLAG_IS_OUT, &gpio_desc[gpio].flags); | ||
1602 | } | ||
1603 | trace_gpio_direction(gpio, value, err); | ||
1604 | if (err < 0) | ||
1605 | pr_err("%s: Error in set_value for open drain gpio%d err %d\n", | ||
1606 | __func__, gpio, err); | ||
1607 | } | ||
1608 | |||
1609 | /* | ||
1610 | * _gpio_set_open_source() - Set the open source gpio's value. | ||
1611 | * @gpio: Gpio whose state need to be set. | ||
1612 | * @chip: Gpio chip. | ||
1613 | * @value: Non-zero for setting it HIGH otherise it will set to LOW. | ||
1614 | */ | ||
1615 | static void _gpio_set_open_source_value(unsigned gpio, | ||
1616 | struct gpio_chip *chip, int value) | ||
1617 | { | ||
1618 | int err = 0; | ||
1619 | if (value) { | ||
1620 | err = chip->direction_output(chip, gpio - chip->base, 1); | ||
1621 | if (!err) | ||
1622 | set_bit(FLAG_IS_OUT, &gpio_desc[gpio].flags); | ||
1623 | } else { | ||
1624 | err = chip->direction_input(chip, gpio - chip->base); | ||
1625 | if (!err) | ||
1626 | clear_bit(FLAG_IS_OUT, &gpio_desc[gpio].flags); | ||
1627 | } | ||
1628 | trace_gpio_direction(gpio, !value, err); | ||
1629 | if (err < 0) | ||
1630 | pr_err("%s: Error in set_value for open source gpio%d err %d\n", | ||
1631 | __func__, gpio, err); | ||
1632 | } | ||
1633 | |||
1634 | |||
1566 | /** | 1635 | /** |
1567 | * __gpio_set_value() - assign a gpio's value | 1636 | * __gpio_set_value() - assign a gpio's value |
1568 | * @gpio: gpio whose value will be assigned | 1637 | * @gpio: gpio whose value will be assigned |
@@ -1579,7 +1648,12 @@ void __gpio_set_value(unsigned gpio, int value) | |||
1579 | chip = gpio_to_chip(gpio); | 1648 | chip = gpio_to_chip(gpio); |
1580 | WARN_ON(chip->can_sleep); | 1649 | WARN_ON(chip->can_sleep); |
1581 | trace_gpio_value(gpio, 0, value); | 1650 | trace_gpio_value(gpio, 0, value); |
1582 | chip->set(chip, gpio - chip->base, value); | 1651 | if (test_bit(FLAG_OPEN_DRAIN, &gpio_desc[gpio].flags)) |
1652 | _gpio_set_open_drain_value(gpio, chip, value); | ||
1653 | else if (test_bit(FLAG_OPEN_SOURCE, &gpio_desc[gpio].flags)) | ||
1654 | _gpio_set_open_source_value(gpio, chip, value); | ||
1655 | else | ||
1656 | chip->set(chip, gpio - chip->base, value); | ||
1583 | } | 1657 | } |
1584 | EXPORT_SYMBOL_GPL(__gpio_set_value); | 1658 | EXPORT_SYMBOL_GPL(__gpio_set_value); |
1585 | 1659 | ||
@@ -1646,7 +1720,12 @@ void gpio_set_value_cansleep(unsigned gpio, int value) | |||
1646 | might_sleep_if(extra_checks); | 1720 | might_sleep_if(extra_checks); |
1647 | chip = gpio_to_chip(gpio); | 1721 | chip = gpio_to_chip(gpio); |
1648 | trace_gpio_value(gpio, 0, value); | 1722 | trace_gpio_value(gpio, 0, value); |
1649 | chip->set(chip, gpio - chip->base, value); | 1723 | if (test_bit(FLAG_OPEN_DRAIN, &gpio_desc[gpio].flags)) |
1724 | _gpio_set_open_drain_value(gpio, chip, value); | ||
1725 | else if (test_bit(FLAG_OPEN_SOURCE, &gpio_desc[gpio].flags)) | ||
1726 | _gpio_set_open_source_value(gpio, chip, value); | ||
1727 | else | ||
1728 | chip->set(chip, gpio - chip->base, value); | ||
1650 | } | 1729 | } |
1651 | EXPORT_SYMBOL_GPL(gpio_set_value_cansleep); | 1730 | EXPORT_SYMBOL_GPL(gpio_set_value_cansleep); |
1652 | 1731 | ||