Hello there!
First, I'd like to thank all who contribute to libgpiod which is really handy! :D
I'm currently developing a GPIO expander module for Linux 6.1.70 which runs on a Raspberry PI. Basic functionality should be implemented as a gpio_chip
is created and provides get_direction
, direction_input
, direction_output
, get
and set
functions.
For quick testing purposes I'm using a manually built libgpiod at commit fc2f2feaa99dce8aab6381168051f2725b537621
which is from january 16, so fairly recent. This is so I can make sure the executables are using libgpiod V2 (the one that comes with Raspberry PI's OS is the V1).
After loading my module, I successfully create a gpiochip. In my system, /dev/gpiochip2. This can be checked with gpiodetect
:
wedev@raspberrypi:~/Downloads/libgpiod $ ./tools/gpiodetect
gpiochip0 [pinctrl-bcm2711] (58 lines)
gpiochip1 [raspberrypi-exp-gpio] (8 lines)
gpiochip2 [pi4ioe5v6416] (16 lines)
and gpioinfo 2
:
gpiochip2 - 16 lines:
line 0: unnamed unused input active-high
line 1: unnamed unused input active-high
line 2: unnamed unused input active-high
line 3: unnamed unused input active-high
line 4: unnamed unused input active-high
line 5: unnamed unused output active-high
line 6: unnamed unused input active-high
line 7: unnamed unused input active-high
line 8: unnamed unused input active-high
line 9: unnamed unused input active-high
line 10: unnamed unused input active-high
line 11: unnamed unused input active-high
line 12: unnamed unused input active-high
line 13: unnamed unused input active-high
line 14: unnamed unused input active-high
line 15: unnamed unused input active-high
The problem I'm facing is that gpioget
is complaining about an invalid IOCTL when I try to use it, even though gpioset
works just fine.
wedev@raspberrypi:~/Downloads/libgpiod $ ./tools/gpioget -c 2 0
/home/wedev/Downloads/libgpiod/tools/.libs/gpioget: unable to read GPIO line values: Inappropriate ioctl for device
I've tracked the syscalls made by gpioget
in two scenarios one of them for /dev/gpiochip0
and the other for /dev/gpiochip2
gpioget -c 2 4
gpioget -c 0 4
They run the same, until this point:
ioctl(3, GPIO_GET_CHIPINFO_IOCTL, {name="gpiochip2", label="pi4ioe5v6416", lines=16}) = 0
ioctl(3, GPIO_V2_GET_LINE_IOCTL, {num_lines=1, offsets=[4], consumer="gpioget", config={flags=GPIO_V2_LINE_FLAG_INPUT, num_attrs=0}} => {fd=0}) = 1
ioctl(0, GPIO_V2_LINE_GET_VALUES_IOCTL, {mask=0x1}) = -1 ENOTTY (Inappropriate ioctl for device)
write(2, "/home/wedev/Downloads/libgpiod/t"..., 52/home/wedev/Downloads/libgpiod/tools/.libs/gpioget: ) = 52
write(2, "unable to read GPIO line values", 31unable to read GPIO line values) = 31
write(2, ": Inappropriate ioctl for device"..., 33: Inappropriate ioctl for device
) = 33
exit_group(1) = ?
+++ exited with 1 +++
Notice that in line 3, I get an -ENOTTY. And that in that line, I've used 0 as the fd
, which was given by the previous ioctl call.
This is an example of the right behaviour:
openat(AT_FDCWD, "/dev/gpiochip0", O_RDWR|O_CLOEXEC) = 3
ioctl(3, GPIO_GET_CHIPINFO_IOCTL, {name="gpiochip0", label="pinctrl-bcm2711", lines=58}) = 0
ioctl(3, GPIO_V2_GET_LINE_IOCTL, {num_lines=1, offsets=[4], consumer="gpioget", config={flags=GPIO_V2_LINE_FLAG_INPUT, num_attrs=0}} => {fd=4}) = 0
ioctl(4, GPIO_V2_LINE_GET_VALUES_IOCTL, {mask=0x1} => {bits=0x1}) = 0
close(4) = 0
close(3) = 0
newfstatat(1, "", {st_mode=S_IFCHR|0620, st_rdev=makedev(0x88, 0), ...}, AT_EMPTY_PATH) = 0
write(1, "\"4\"=active\n", 11) = 11
exit_group(0) = ?
+++ exited with 0 +++
So I think that it's not GPIO_V2_LINE_GET_VALUES_IOCTL
that is failing, but GPIO_V2_GET_LINE_IOCTL
that is returning a positive value even though gpio_v2_line_request::fd
is 0, which the comments at include/uapi/linux/gpio.h
say should be an error.
Can someone help me figure this out?