rust-embedded / gpio-cdev

Rust interface to the Linux GPIO Character Device API (/dev/gpiochip...)
Apache License 2.0
213 stars 37 forks source link

Control the mode or peripheral function aka alternate mode of GPIO PINs. #77

Closed Chris2m closed 11 months ago

Chris2m commented 1 year ago

Is it possible to use gpio-cdev to change the peripheral function of a GPIO PIN?

For context, I'm using gpio-cdev on a Raspberry PI to turn GPIO PIN 2 into output mode and send a wake pulse to a chip connected via I2C. Unfortunately, calling chip.get_line(2).request(LineRequestFlags::OUTPUT, 1, "test") changes the mode of the GPIO PIN to output and I have not yet found a way of "resetting" the PIN to its original state after completing the wake pulse.

I found, however, I can reset it manually from the command line using sudo raspi-gpio set 2 a0 but I was wondering if the same could be accomplished from within gpio-cdev or if it could be extended to allow for that.

posborne commented 1 year ago

@Chris2m If you issue another request for a line handle as an input, that will change the GPIO pin mode if allowed. The kernel doesn't track the previous state, so you'll need to do that in your application.

Chris2m commented 1 year ago

Hi @posborne , thanks for getting back to me. The issue is that there does not seem to be a way for gpio-cdev to retrieve the current state including all flags (such as a0, a1, ...). So when I change the GPIO PINs 2 and 3 on a Raspberry PI to output for instance, it overrides their previously defined alternate function flags with no way to restore them. The only way I've found is to use the command line 'raspi-gpio set 2,3 a0'. Wondering if a solution could be to allow gpio-cdev to retrieve all bits of the state flag so I can save and restore them.

posborne commented 12 months ago

@Chris2m I see, the raspi-gpio is directly messing with the registers in a way that is highly discouraged generally when trying to use linux with a board. The GPIO system and interfaces this crate exposes do not provide any ability to change pins in the processor to another function at runtime.

I believe you may be able to achieve this via device tree overlays, though I don't have significant expertise with this on the raspberry pi. In some cases, what you might be trying to do might not be well supported using userspace APIs. Many of the alternate modes for pins require that the kernel be aware of not just the function for the pin but need to also then be tied to the driver that would make use of it, etc.