Skip to content

Commit d449991

Browse files
tpetazzoniLinus Walleij
authored andcommitted
gpio: add core support for pull-up/pull-down configuration
This commit adds support for configuring the pull-up and pull-down resistors available in some GPIO controllers. While configuring pull-up/pull-down is already possible through the pinctrl subsystem, some GPIO controllers, especially simple ones such as GPIO expanders on I2C, don't have any pinmuxing capability and therefore do not use the pinctrl subsystem. This commit implements the GPIO_PULL_UP and GPIO_PULL_DOWN flags, which can be used from the Device Tree, to enable a pull-up or pull-down resistor on a given GPIO. The flag is simply propagated all the way to the core GPIO subsystem, where it is used to call the gpio_chip ->set_config callback with the appropriate existing PIN_CONFIG_BIAS_* values. Signed-off-by: Thomas Petazzoni <[email protected]> Signed-off-by: Linus Walleij <[email protected]>
1 parent 6581eaf commit d449991

File tree

5 files changed

+29
-0
lines changed

5 files changed

+29
-0
lines changed

drivers/gpio/gpiolib-of.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,11 @@ struct gpio_desc *of_find_gpio(struct device *dev, const char *con_id,
345345
if (of_flags & OF_GPIO_TRANSITORY)
346346
*flags |= GPIO_TRANSITORY;
347347

348+
if (of_flags & OF_GPIO_PULL_UP)
349+
*flags |= GPIO_PULL_UP;
350+
if (of_flags & OF_GPIO_PULL_DOWN)
351+
*flags |= GPIO_PULL_DOWN;
352+
348353
return desc;
349354
}
350355

drivers/gpio/gpiolib.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2573,6 +2573,13 @@ int gpiod_direction_input(struct gpio_desc *desc)
25732573
if (status == 0)
25742574
clear_bit(FLAG_IS_OUT, &desc->flags);
25752575

2576+
if (test_bit(FLAG_PULL_UP, &desc->flags))
2577+
gpio_set_config(chip, gpio_chip_hwgpio(desc),
2578+
PIN_CONFIG_BIAS_PULL_UP);
2579+
else if (test_bit(FLAG_PULL_DOWN, &desc->flags))
2580+
gpio_set_config(chip, gpio_chip_hwgpio(desc),
2581+
PIN_CONFIG_BIAS_PULL_DOWN);
2582+
25762583
trace_gpio_direction(desc_to_gpio(desc), 1, status);
25772584

25782585
return status;
@@ -4050,6 +4057,17 @@ int gpiod_configure_flags(struct gpio_desc *desc, const char *con_id,
40504057
if (lflags & GPIO_OPEN_SOURCE)
40514058
set_bit(FLAG_OPEN_SOURCE, &desc->flags);
40524059

4060+
if ((lflags & GPIO_PULL_UP) && (lflags & GPIO_PULL_DOWN)) {
4061+
gpiod_err(desc,
4062+
"both pull-up and pull-down enabled, invalid configuration\n");
4063+
return -EINVAL;
4064+
}
4065+
4066+
if (lflags & GPIO_PULL_UP)
4067+
set_bit(FLAG_PULL_UP, &desc->flags);
4068+
else if (lflags & GPIO_PULL_DOWN)
4069+
set_bit(FLAG_PULL_DOWN, &desc->flags);
4070+
40534071
status = gpiod_set_transitory(desc, (lflags & GPIO_TRANSITORY));
40544072
if (status < 0)
40554073
return status;

drivers/gpio/gpiolib.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,8 @@ struct gpio_desc {
219219
#define FLAG_IRQ_IS_ENABLED 10 /* GPIO is connected to an enabled IRQ */
220220
#define FLAG_IS_HOGGED 11 /* GPIO is hogged */
221221
#define FLAG_TRANSITORY 12 /* GPIO may lose value in sleep or reset */
222+
#define FLAG_PULL_UP 13 /* GPIO has pull up enabled */
223+
#define FLAG_PULL_DOWN 14 /* GPIO has pull down enabled */
222224

223225
/* Connection label */
224226
const char *label;

include/linux/gpio/machine.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ enum gpio_lookup_flags {
1212
GPIO_OPEN_SOURCE = (1 << 2),
1313
GPIO_PERSISTENT = (0 << 3),
1414
GPIO_TRANSITORY = (1 << 3),
15+
GPIO_PULL_UP = (1 << 4),
16+
GPIO_PULL_DOWN = (1 << 5),
1517
};
1618

1719
/**

include/linux/of_gpio.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ enum of_gpio_flags {
2828
OF_GPIO_SINGLE_ENDED = 0x2,
2929
OF_GPIO_OPEN_DRAIN = 0x4,
3030
OF_GPIO_TRANSITORY = 0x8,
31+
OF_GPIO_PULL_UP = 0x10,
32+
OF_GPIO_PULL_DOWN = 0x20,
3133
};
3234

3335
#ifdef CONFIG_OF_GPIO

0 commit comments

Comments
 (0)