diff options
| author | Philipp Zabel <p.zabel@pengutronix.de> | 2014-01-07 06:34:11 -0500 |
|---|---|---|
| committer | Linus Walleij <linus.walleij@linaro.org> | 2014-02-07 03:47:02 -0500 |
| commit | ef70bbe1aaa612f75360e5df5952fddec50b7ca9 (patch) | |
| tree | 2f80756c83780e9ed9c67401af16022a749543c0 | |
| parent | 25b35da7f4cce82271859f1b6eabd9f3bd41a2bb (diff) | |
gpio: make gpiod_direction_output take a logical value
The documentation was not clear about whether
gpio_direction_output should take a logical value or the physical
level on the output line, i.e. whether the ACTIVE_LOW status
would be taken into account.
This converts gpiod_direction_output to use the logical level
and adds a new gpiod_direction_output_raw for the raw value.
Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
Reviewed-by: Alexandre Courbot <acourbot@nvidia.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
| -rw-r--r-- | Documentation/gpio/consumer.txt | 1 | ||||
| -rw-r--r-- | drivers/gpio/gpiolib.c | 67 | ||||
| -rw-r--r-- | include/asm-generic/gpio.h | 2 | ||||
| -rw-r--r-- | include/linux/gpio/consumer.h | 7 |
4 files changed, 57 insertions, 20 deletions
diff --git a/Documentation/gpio/consumer.txt b/Documentation/gpio/consumer.txt index e42f77d8d4ca..09854fe59307 100644 --- a/Documentation/gpio/consumer.txt +++ b/Documentation/gpio/consumer.txt | |||
| @@ -154,6 +154,7 @@ raw line value: | |||
| 154 | void gpiod_set_raw_value(struct gpio_desc *desc, int value) | 154 | void gpiod_set_raw_value(struct gpio_desc *desc, int value) |
| 155 | int gpiod_get_raw_value_cansleep(const struct gpio_desc *desc) | 155 | int gpiod_get_raw_value_cansleep(const struct gpio_desc *desc) |
| 156 | void gpiod_set_raw_value_cansleep(struct gpio_desc *desc, int value) | 156 | void gpiod_set_raw_value_cansleep(struct gpio_desc *desc, int value) |
| 157 | int gpiod_direction_output_raw(struct gpio_desc *desc, int value) | ||
| 157 | 158 | ||
| 158 | The active-low state of a GPIO can also be queried using the following call: | 159 | The active-low state of a GPIO can also be queried using the following call: |
| 159 | 160 | ||
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 50c4922fe53a..80da9f1940c9 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c | |||
| @@ -350,9 +350,9 @@ static ssize_t gpio_direction_store(struct device *dev, | |||
| 350 | if (!test_bit(FLAG_EXPORT, &desc->flags)) | 350 | if (!test_bit(FLAG_EXPORT, &desc->flags)) |
| 351 | status = -EIO; | 351 | status = -EIO; |
| 352 | else if (sysfs_streq(buf, "high")) | 352 | else if (sysfs_streq(buf, "high")) |
| 353 | status = gpiod_direction_output(desc, 1); | 353 | status = gpiod_direction_output_raw(desc, 1); |
| 354 | else if (sysfs_streq(buf, "out") || sysfs_streq(buf, "low")) | 354 | else if (sysfs_streq(buf, "out") || sysfs_streq(buf, "low")) |
| 355 | status = gpiod_direction_output(desc, 0); | 355 | status = gpiod_direction_output_raw(desc, 0); |
| 356 | else if (sysfs_streq(buf, "in")) | 356 | else if (sysfs_streq(buf, "in")) |
| 357 | status = gpiod_direction_input(desc); | 357 | status = gpiod_direction_input(desc); |
| 358 | else | 358 | else |
| @@ -1590,7 +1590,7 @@ int gpio_request_one(unsigned gpio, unsigned long flags, const char *label) | |||
| 1590 | if (flags & GPIOF_DIR_IN) | 1590 | if (flags & GPIOF_DIR_IN) |
| 1591 | err = gpiod_direction_input(desc); | 1591 | err = gpiod_direction_input(desc); |
| 1592 | else | 1592 | else |
| 1593 | err = gpiod_direction_output(desc, | 1593 | err = gpiod_direction_output_raw(desc, |
| 1594 | (flags & GPIOF_INIT_HIGH) ? 1 : 0); | 1594 | (flags & GPIOF_INIT_HIGH) ? 1 : 0); |
| 1595 | 1595 | ||
| 1596 | if (err) | 1596 | if (err) |
| @@ -1756,28 +1756,13 @@ fail: | |||
| 1756 | } | 1756 | } |
| 1757 | EXPORT_SYMBOL_GPL(gpiod_direction_input); | 1757 | EXPORT_SYMBOL_GPL(gpiod_direction_input); |
| 1758 | 1758 | ||
| 1759 | /** | 1759 | static int _gpiod_direction_output_raw(struct gpio_desc *desc, int value) |
| 1760 | * gpiod_direction_output - set the GPIO direction to input | ||
| 1761 | * @desc: GPIO to set to output | ||
| 1762 | * @value: initial output value of the GPIO | ||
| 1763 | * | ||
| 1764 | * Set the direction of the passed GPIO to output, such as gpiod_set_value() can | ||
| 1765 | * be called safely on it. The initial value of the output must be specified. | ||
| 1766 | * | ||
| 1767 | * Return 0 in case of success, else an error code. | ||
| 1768 | */ | ||
| 1769 | int gpiod_direction_output(struct gpio_desc *desc, int value) | ||
| 1770 | { | 1760 | { |
| 1771 | unsigned long flags; | 1761 | unsigned long flags; |
| 1772 | struct gpio_chip *chip; | 1762 | struct gpio_chip *chip; |
| 1773 | int status = -EINVAL; | 1763 | int status = -EINVAL; |
| 1774 | int offset; | 1764 | int offset; |
| 1775 | 1765 | ||
| 1776 | if (!desc || !desc->chip) { | ||
| 1777 | pr_warn("%s: invalid GPIO\n", __func__); | ||
| 1778 | return -EINVAL; | ||
| 1779 | } | ||
| 1780 | |||
| 1781 | /* GPIOs used for IRQs shall not be set as output */ | 1766 | /* GPIOs used for IRQs shall not be set as output */ |
| 1782 | if (test_bit(FLAG_USED_AS_IRQ, &desc->flags)) { | 1767 | if (test_bit(FLAG_USED_AS_IRQ, &desc->flags)) { |
| 1783 | gpiod_err(desc, | 1768 | gpiod_err(desc, |
| @@ -1840,6 +1825,50 @@ fail: | |||
| 1840 | gpiod_dbg(desc, "%s: gpio status %d\n", __func__, status); | 1825 | gpiod_dbg(desc, "%s: gpio status %d\n", __func__, status); |
| 1841 | return status; | 1826 | return status; |
| 1842 | } | 1827 | } |
| 1828 | |||
| 1829 | /** | ||
| 1830 | * gpiod_direction_output_raw - set the GPIO direction to output | ||
| 1831 | * @desc: GPIO to set to output | ||
| 1832 | * @value: initial output value of the GPIO | ||
| 1833 | * | ||
| 1834 | * Set the direction of the passed GPIO to output, such as gpiod_set_value() can | ||
| 1835 | * be called safely on it. The initial value of the output must be specified | ||
| 1836 | * as raw value on the physical line without regard for the ACTIVE_LOW status. | ||
| 1837 | * | ||
| 1838 | * Return 0 in case of success, else an error code. | ||
| 1839 | */ | ||
| 1840 | int gpiod_direction_output_raw(struct gpio_desc *desc, int value) | ||
| 1841 | { | ||
| 1842 | if (!desc || !desc->chip) { | ||
| 1843 | pr_warn("%s: invalid GPIO\n", __func__); | ||
| 1844 | return -EINVAL; | ||
| 1845 | } | ||
| 1846 | return _gpiod_direction_output_raw(desc, value); | ||
| 1847 | } | ||
| 1848 | EXPORT_SYMBOL_GPL(gpiod_direction_output_raw); | ||
| 1849 | |||
| 1850 | /** | ||
| 1851 | * gpiod_direction_output - set the GPIO direction to input | ||
| 1852 | * @desc: GPIO to set to output | ||
| 1853 | * @value: initial output value of the GPIO | ||
| 1854 | * | ||
| 1855 | * Set the direction of the passed GPIO to output, such as gpiod_set_value() can | ||
| 1856 | * be called safely on it. The initial value of the output must be specified | ||
| 1857 | * as the logical value of the GPIO, i.e. taking its ACTIVE_LOW status into | ||
| 1858 | * account. | ||
| 1859 | * | ||
| 1860 | * Return 0 in case of success, else an error code. | ||
| 1861 | */ | ||
| 1862 | int gpiod_direction_output(struct gpio_desc *desc, int value) | ||
| 1863 | { | ||
| 1864 | if (!desc || !desc->chip) { | ||
| 1865 | pr_warn("%s: invalid GPIO\n", __func__); | ||
| 1866 | return -EINVAL; | ||
| 1867 | } | ||
| 1868 | if (test_bit(FLAG_ACTIVE_LOW, &desc->flags)) | ||
| 1869 | value = !value; | ||
| 1870 | return _gpiod_direction_output_raw(desc, value); | ||
| 1871 | } | ||
| 1843 | EXPORT_SYMBOL_GPL(gpiod_direction_output); | 1872 | EXPORT_SYMBOL_GPL(gpiod_direction_output); |
| 1844 | 1873 | ||
| 1845 | /** | 1874 | /** |
diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h index a5f56a0213a7..23e364538ab5 100644 --- a/include/asm-generic/gpio.h +++ b/include/asm-generic/gpio.h | |||
| @@ -69,7 +69,7 @@ static inline int gpio_direction_input(unsigned gpio) | |||
| 69 | } | 69 | } |
| 70 | static inline int gpio_direction_output(unsigned gpio, int value) | 70 | static inline int gpio_direction_output(unsigned gpio, int value) |
| 71 | { | 71 | { |
| 72 | return gpiod_direction_output(gpio_to_desc(gpio), value); | 72 | return gpiod_direction_output_raw(gpio_to_desc(gpio), value); |
| 73 | } | 73 | } |
| 74 | 74 | ||
| 75 | static inline int gpio_set_debounce(unsigned gpio, unsigned debounce) | 75 | static inline int gpio_set_debounce(unsigned gpio, unsigned debounce) |
diff --git a/include/linux/gpio/consumer.h b/include/linux/gpio/consumer.h index 4d34dbbbad4d..387994325122 100644 --- a/include/linux/gpio/consumer.h +++ b/include/linux/gpio/consumer.h | |||
| @@ -36,6 +36,7 @@ void devm_gpiod_put(struct device *dev, struct gpio_desc *desc); | |||
| 36 | int gpiod_get_direction(const struct gpio_desc *desc); | 36 | int gpiod_get_direction(const struct gpio_desc *desc); |
| 37 | int gpiod_direction_input(struct gpio_desc *desc); | 37 | int gpiod_direction_input(struct gpio_desc *desc); |
| 38 | int gpiod_direction_output(struct gpio_desc *desc, int value); | 38 | int gpiod_direction_output(struct gpio_desc *desc, int value); |
| 39 | int gpiod_direction_output_raw(struct gpio_desc *desc, int value); | ||
| 39 | 40 | ||
| 40 | /* Value get/set from non-sleeping context */ | 41 | /* Value get/set from non-sleeping context */ |
| 41 | int gpiod_get_value(const struct gpio_desc *desc); | 42 | int gpiod_get_value(const struct gpio_desc *desc); |
| @@ -121,6 +122,12 @@ static inline int gpiod_direction_output(struct gpio_desc *desc, int value) | |||
| 121 | WARN_ON(1); | 122 | WARN_ON(1); |
| 122 | return -ENOSYS; | 123 | return -ENOSYS; |
| 123 | } | 124 | } |
| 125 | static inline int gpiod_direction_output_raw(struct gpio_desc *desc, int value) | ||
| 126 | { | ||
| 127 | /* GPIO can never have been requested */ | ||
| 128 | WARN_ON(1); | ||
| 129 | return -ENOSYS; | ||
| 130 | } | ||
| 124 | 131 | ||
| 125 | 132 | ||
| 126 | static inline int gpiod_get_value(const struct gpio_desc *desc) | 133 | static inline int gpiod_get_value(const struct gpio_desc *desc) |
