brgl/libgpiod

Is there any way to enable pull-up or pull-down resistor?

Closed this issue · 22 comments

I'm trying to use python bindings to libgpiod-1.2 on Raspberry Pi Model B Rev 2. Looks like pull-up/ pull-down resistors can't be enabled? Could you recommend any way to do that? Or should I configure that with device tree?

brgl commented

What do you mean exactly? Can you give an example?

For example, this is a piece of documentation for RPi.GPIO library, which uses deprecated sysfs interface, as I understand: https://sourceforge.net/p/raspberry-gpio-python/wiki/Inputs/.

In my particular situation I have 6 normally open buttons that connect +3.3V to GPIO pins when pressed. So I need to enable embedded pull-down resistors. If I don't enable them I sometimes get a lot of fake events reported by gpiomon.py. As I understand that is because of electromagnetical noise/interference.

I managed to configure pull-downs using device tree overlay, but that it not so convenient as it could be using a user-space library.

hiya we just bumped into this too - its a little surprising since pull-ups and pull-downs are a core functionality of input pins. more chips will support pullup/down than open drain/source which has a flag.
for example: https://learn.adafruit.com/circuitpython-on-raspberrypi-linux/digital-i-o#wiring-3-13
the button is wired to ground only. an internal resistor in the chip will pull the pin high when not tied low.

here's a longer article https://grantwinney.com/using-pullup-and-pulldown-resistors-on-the-raspberry-pi/

is there something we're missing? we could help add support if ya like :)

brgl commented

Hey @ladyada, @rommar

First off: libgpiod can only support features exposed by the kernel uAPI. You're talking about a very component-specific feature and even the kernel code that deals with pull-ups/downs is driver-specific - take a look at device tree bindings: there is no generic PULL_UP/DOWN property defined, only certain drivers using their own constants.

@rommar just looked at the code you're referencing: I'm seeing that the pull-up/down resistors are set by directly poking certain registers of the SoC from user-space. This is dangerous and not portable. Since libgpiod is supposed to work on all linux systems - this is never going to fly.

ooooh ok thanks for the details @brgl - we'll use vendor-supplied libraries for that, and libgpiod whenever we can + advise people to use an external pullup. thanks :)

brgl commented

@ladyada @rommar Hi again guys!

Since your use case makes perfect sense I started looking into a way to implement it in a generic way. For starters we need to add this feature to the kernel uAPI. While this shouldn't be difficult, I'm not seeing many GPIO drivers (as opposed to pinctrl drivers which do it routinely) that handle the PULLUP/DOWN property in their set_config() callback. What HW are you using exactly and does it run upstream kernel?

The more details the better.

The idea is to add a userspace flag that gpiolib would interpret and call set_config() with relevant paramters.

fivdi commented

@brgl I'm really happy to see that you have reopened this issue.

Although I'm not @ladyada or @rommar I'd still like to say what hardware I use and why I'd like it if gpiod could handle PULLUP/DOWN resistors,

I use various variants of the the Raspberry Pi that run the kernel supplied with the Raspbian images available at raspberrypi.org. I also use various variants of the BeagleBone that run the kernel supplied with the Debian images available at beagleboard.org. To be honest, I'm not sure if this means that I'm running an upstream kernel but I think it does.

And now for some more detail.

I'd prefer to have to know as little as possible about GPIO drivers, pinctrl drivers and device tree overlays. That being said, I can actually manage to write a device tree overlay to configure PULLUP/DOWN resistors, for example, here's one for the Raspberry Pi that uses pinctrl. However, and this is an important point, I spent a huge amount of time figuring out how to write that device tree overlay. I would imagine that there have been many people in the same situation that gave up at some point.

Also, I have never built the Linux kernel and I don't think I want to know how to do it. I'd prefer to leave this up to people who really know what they are doing like @RobertCNelson who creates the Debian images for the BeagleBone.

What I want to do is implement code that runs in userspace. I use onoff to access GPIOs from userspace, I use i2c-bus to access I2C devices from user space and I use spi-device to access SPI devices from userspace.

The huge advantage of gpiod being capable of configuring PULLUP/DOWN resistors is that it would save many many people a huge amount of time. They wouldn't have to know about drivers and device tree overlays. It would also increase the number of people that are capable of configuring PULLUP/DOWN resistors as I'm fairly certain that a large number of people will simple give up trying to configuring them today as it is so complex and so much know-how is needed. It would result is a much better user experience for people working with GPIOs from userspace.

thanks @brgl i'll echo that Raspi is primarily what people use, beaglebone black is second, and then a mishmash of various Allwinner boards like the Orange Pi, Nano Pi. There's a few people who like the ASUS Tinkerboard. some of these chips, like the Allwinner, dont seem to have any exposure to pullup/down - some do via MMIO like the RasPi. I use Raspbian stable release on Pi, latest Debian from BBB, and Armbian for anything else.

you don't see a lot of drivers use it because its not always supported, so most people fall-back on using a hardware resistor.

Here's the most popular utility on the raspi for controlling pull's
https://github.com/WiringPi/WiringPi/blob/master/wiringPi/wiringPi.c#L536
as you can see...its quite exciting :)

fivdi commented

An alternative to the wiringPi utility for configuring pins on the Raspberry Pi is the new "gpio" config.txt command which has been available since March 2018. It can be used to configure pins, including PULLUP/DOWN resistors, at boot time by adding the appropriate calls to /boot/config.txt.

On the BeagleBone the config-pin utility can be used to configure pins from userspace. The documentation for the config-pin utility linked to here is a little dated.

brgl commented

@brgl I'm really happy to see that you have reopened this issue.

Although I'm not @ladyada or @rommar I'd still like to say what hardware I use and why I'd like it if gpiod could handle PULLUP/DOWN resistors,

I use various variants of the the Raspberry Pi that run the kernel supplied with the Raspbian images available at raspberrypi.org. I also use various variants of the BeagleBone that run the kernel supplied with the Debian images available at beagleboard.org. To be honest, I'm not sure if this means that I'm running an upstream kernel but I think it does.

Actually a distro kernel usually has some patches on top of mainline but I guess your GPIO drivers are probably close if not the same as upstream.

And now for some more detail.

I'd prefer to have to know as little as possible about GPIO drivers, pinctrl drivers and device tree overlays. That being said, I can actually manage to write a device tree overlay to configure PULLUP/DOWN resistors, for example, here's one for the Raspberry Pi that uses pinctrl. However, and this is an important point, I spent a huge amount of time figuring out how to write that device tree overlay. I would imagine that there have been many people in the same situation that gave up at some point.

Also, I have never built the Linux kernel and I don't think I want to know how to do it. I'd prefer to leave this up to people who really know what they are doing like @RobertCNelson who creates the Debian images for the BeagleBone.

What I want to do is implement code that runs in userspace. I use onoff to access GPIOs from userspace, I use i2c-bus to access I2C devices from user space and I use spi-device to access SPI devices from userspace.

This new potential feature will not be available in the sysfs interface (the one used by onoff) - only the character device.

The huge advantage of gpiod being capable of configuring PULLUP/DOWN resistors is that it would save many many people a huge amount of time. They wouldn't have to know about drivers and device tree overlays. It would also increase the number of people that are capable of configuring PULLUP/DOWN resistors as I'm fairly certain that a large number of people will simple give up trying to configuring them today as it is so complex and so much know-how is needed. It would result is a much better user experience for people working with GPIOs from userspace.

This is why I want to add this. This will however probably be a lengthy process. Any new kernel user interface must be well designed, reviewed and most importantly - future-proof. Only once this lands in the mainline kernel and gets released can I add support for it to libgpiod,

brgl commented

thanks @brgl i'll echo that Raspi is primarily what people use, beaglebone black is second, and then a mishmash of various Allwinner boards like the Orange Pi, Nano Pi. There's a few people who like the ASUS Tinkerboard. some of these chips, like the Allwinner, dont seem to have any exposure to pullup/down - some do via MMIO like the RasPi. I use Raspbian stable release on Pi, latest Debian from BBB, and Armbian for anything else.

you don't see a lot of drivers use it because its not always supported, so most people fall-back on using a hardware resistor.

This may be the first obstacle. If we want to support it in a generic way (and we do want it, since libgpiod will only ever support "official" upstream APIs) we need to first have some drivers that implement the right callbacks.

I see that the gpio-omap driver only supports PIN_CONFIG_INPUT_DEBOUNCE in its set_config callback. I need to first see about adding configurable internal pull up/downs in the upstream driver. But that's for after Christmas.

Enjoy your holidays!

Here's the most popular utility on the raspi for controlling pull's
https://github.com/WiringPi/WiringPi/blob/master/wiringPi/wiringPi.c#L536
as you can see...its quite exciting :)

fivdi commented

This new potential feature will not be available in the sysfs interface (the one used by onoff) - only the character device.

That's ok. onoff would need to be replaced by something using using libgpiod.

I want to mention that since 4.18 the bcm/pinctrl-bcm2835.c (Raspberry Pi) is a generic pinctrl driver and supports the following generic pinconf parameter:

  • PIN_CONFIG_BIAS_DISABLE
  • PIN_CONFIG_BIAS_PULL_DOWN
  • PIN_CONFIG_BIAS_PULL_UP
brgl commented

@lategoodbye Normally the preferred approach is to split the pinctrl and gpio functionalities into two separate drivers - I'm not sure what the reason for having them both in pinctrl-bcm2835.c was exactly.
Anyway: those PIN_CONFIG options are only supported in the pinctrl subsystem - there's no set_config callback defined for the gpio part and it's what we need to make it work over /dev/gpiochip.

@brgl The pinctrl driver has been written long before my time as maintainer. I assume this comes from the fact that pinctrl and gpio register lie in same address range of the SoC.

If i get it right from commit ("pinctrl / gpio: Introduce .set_config() callback for GPIO chips") we only need to set the set_config callback of the gpiochip to gpiochip_generic_config to delegate this to the pinctrl driver.

brgl commented

@lategoodbye yes this should work indeed. Do you mind sending a patch?

I will prepare it. Thanks

Just a quick bump to say I'm a very happy libgpiod user on the Raspberry Pi, and I would love to see pin control as well. I'm running the latest 4.14 kernel provided by "rpi-update", but I might consider test-driving the latest if testing is required.

@nettings In order to use this upcoming feature you will need to use a mainline kernel which isn't available via rpi-update. 4.14 is too old.

@lategoodbye, now it is: rpi-update will bump your kernel to 4.19.25 as of today. Time to play!

I'm sorry but 4.19.x doesn't have the mentioned patch, it will land in Linux 5.1. But the bias configuration via GPIOLIB is still missing.

Oh, I meant the pinctrl-bcm2835.c driver you mentioned before. But great to hear the delegated pin control feature is already underway. Thanks for your efforts!