gpio: core: Decouple open drain/source flag with active low/high

PD#161621: gpio: core: Decouple open drain/source flag with active low/high

Currently, the GPIO interface is said to Open Drain if it is Single
Ended and active LOW. Similarly, it is said as Open Source if it is
Single Ended and active HIGH.

The active HIGH/LOW is used in the interface for setting the pin
state to HIGH or LOW when enabling/disabling the interface.

In Open Drain interface, pin is set to HIGH by putting pin in
high impedance and LOW by driving to the LOW.

In Open Source interface, pin is set to HIGH by driving pin to
HIGH and set to LOW by putting pin in high impedance.

With above, the Open Drain/Source is unrelated to the active LOW/HIGH
in interface. There is interface where the enable/disable of interface
is ether active LOW or HIGH but it is Open Drain type.

Hence decouple the Open Drain with Single Ended + Active LOW and
Open Source with Single Ended + Active HIGH.

Adding different flag for the Open Drain/Open Source which is valid
only when Single ended flag is enabled.

Note: the patch from v4.14-rc6 with original commit ID 4c0facddb

Change-Id: I2f652614d3783caee3f510dc70e5e185379f49a7
Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
This commit is contained in:
Laxman Dewangan
2017-04-06 19:05:52 +05:30
committed by Jianxin Pan
parent 8b00f1bd65
commit f29628b716
4 changed files with 31 additions and 0 deletions

View File

@@ -147,7 +147,11 @@ struct gpio_desc *of_find_gpio(struct device *dev, const char *con_id,
*flags |= GPIO_ACTIVE_LOW;
if (of_flags & OF_GPIO_SINGLE_ENDED) {
#ifdef CONFIG_AMLOGIC_MODIFY
if (of_flags & OF_GPIO_OPEN_DRAIN)
#else
if (of_flags & OF_GPIO_ACTIVE_LOW)
#endif
*flags |= GPIO_OPEN_DRAIN;
else
*flags |= GPIO_OPEN_SOURCE;

View File

@@ -3319,6 +3319,9 @@ struct gpio_desc *fwnode_get_named_gpiod(struct fwnode_handle *fwnode,
struct gpio_desc *desc = ERR_PTR(-ENODEV);
bool active_low = false;
bool single_ended = false;
#ifdef CONFIG_AMLOGIC_MODIFY
bool open_drain = false;
#endif
int ret;
if (!fwnode)
@@ -3332,6 +3335,9 @@ struct gpio_desc *fwnode_get_named_gpiod(struct fwnode_handle *fwnode,
if (!IS_ERR(desc)) {
active_low = flags & OF_GPIO_ACTIVE_LOW;
single_ended = flags & OF_GPIO_SINGLE_ENDED;
#ifdef CONFIG_AMLOGIC_MODIFY
open_drain = flags & OF_GPIO_OPEN_DRAIN;
#endif
}
} else if (is_acpi_node(fwnode)) {
struct acpi_gpio_info info;
@@ -3352,7 +3358,11 @@ struct gpio_desc *fwnode_get_named_gpiod(struct fwnode_handle *fwnode,
set_bit(FLAG_ACTIVE_LOW, &desc->flags);
if (single_ended) {
#ifdef CONFIG_AMLOGIC_MODIFY
if (open_drain)
#else
if (active_low)
#endif
set_bit(FLAG_OPEN_DRAIN, &desc->flags);
else
set_bit(FLAG_OPEN_SOURCE, &desc->flags);

View File

@@ -17,11 +17,25 @@
#define GPIO_PUSH_PULL 0
#define GPIO_SINGLE_ENDED 2
#ifdef CONFIG_AMLOGIC_MODIFY
/* Bit 2 express Open drain or open source */
#define GPIO_LINE_OPEN_SOURCE 0
#define GPIO_LINE_OPEN_DRAIN 4
/*
* Open Drain/Collector is the combination of single-ended open drain interface.
* Open Source/Emitter is the combination of single-ended open source interface.
*/
#define GPIO_OPEN_DRAIN (GPIO_SINGLE_ENDED | GPIO_LINE_OPEN_DRAIN)
#define GPIO_OPEN_SOURCE (GPIO_SINGLE_ENDED | GPIO_LINE_OPEN_SOURCE)
#else
/*
* Open Drain/Collector is the combination of single-ended active low,
* Open Source/Emitter is the combination of single-ended active high.
*/
#define GPIO_OPEN_DRAIN (GPIO_SINGLE_ENDED | GPIO_ACTIVE_LOW)
#define GPIO_OPEN_SOURCE (GPIO_SINGLE_ENDED | GPIO_ACTIVE_HIGH)
#endif
#endif

View File

@@ -30,6 +30,9 @@ struct device_node;
enum of_gpio_flags {
OF_GPIO_ACTIVE_LOW = 0x1,
OF_GPIO_SINGLE_ENDED = 0x2,
#ifdef CONFIG_AMLOGIC_MODIFY
OF_GPIO_OPEN_DRAIN = 0x4,
#endif
};
#ifdef CONFIG_OF_GPIO