diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c index 193f15d50bba..4249e6d1a609 100644 --- a/drivers/gpio/gpiolib-of.c +++ b/drivers/gpio/gpiolib-of.c @@ -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; diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 9d96a349180e..123ebadbb2a9 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -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); diff --git a/include/dt-bindings/gpio/gpio.h b/include/dt-bindings/gpio/gpio.h index c673d2c87c60..be78a8962c93 100644 --- a/include/dt-bindings/gpio/gpio.h +++ b/include/dt-bindings/gpio/gpio.h @@ -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 diff --git a/include/linux/of_gpio.h b/include/linux/of_gpio.h index 3f87ea5b8bee..e8ba370948ac 100644 --- a/include/linux/of_gpio.h +++ b/include/linux/of_gpio.h @@ -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