0

I am working on an application for an NXP iMX7ULP custom board. I am trying to open a GPIO pin from user-mode using the character mode interface. I keep getting EINVAL on the ioctl(GPIO_GET_LINEHANDLE_IOCTL). I cannot see to find the bug or underlying reason to why this won't work.

This is the code

void LinuxGPIO::Enable(GPIODirection direction)
{
    auto deviceName = GetDeviceName(_bspPin); // returns /dev/gpiochip0 which is correct
    int chipFd = open(deviceName.c_str(), O_RDONLY);
    if (chipFd < 0)
        throw std::runtime_error("Could not open GPIO device");
    // printChipInfo(chipFd);
    gpiohandle_request request;
    memset(&request, 0, sizeof(request));
    request.lineoffsets[0] = GetDevicePin(_bspPin); // Sets the line number to 15 which is correct
    request.lines = 1;
    if (direction == GPIODirection::IN)
        request.flags = GPIOHANDLE_REQUEST_INPUT;
    else if (direction == GPIODirection::OUT)
        request.flags = GPIOHANDLE_REQUEST_OUTPUT;
    else
        assert(direction == GPIODirection::IN || direction == GPIODirection::OUT);
    // fails here with EINVAL
    int status = ioctl(chipFd, GPIO_GET_LINEHANDLE_IOCTL, &request);
    // int err = errno;
    close(chipFd);
    if (status == -1)
        throw std::runtime_error("Could not open GPIO device pin");
    _direction = direction;
    _fd = request.fd;
}

I have checked the device tree, nothing is using this pin (PTC pin 15). I have verified that the GPIO chip and line offset are correct. I have also tried to export via sysfs, I can export but cannot change the pin direction (says write error Invalid argument).

I have successfully been able to print the GPIO chip info and line info using GPIO_GET_CHIPINFO_IOCTL and GPIO_GET_LINEINFO_IOCTL. Flags set for the line are INPUT and ACTIVE_HIGH without a KERNEL flag set.

0andriy
  • 4,183
  • 1
  • 24
  • 37
MrJones
  • 29
  • 1
  • which driver is it? – stark Mar 21 '23 at 23:02
  • Under the device tree GPIO_PTC uses compatible id of "fsl,imx7ulp-gpio", "fsl,vf610-gpio". IOMUX uses "fsl,imx7ulp-iomuxc1". Is that what you are asking or is there another way to find that information? – MrJones Mar 22 '23 at 14:31
  • 1
    Looks like it uses the vf610 driver https://elixir.bootlin.com/linux/latest/source/drivers/gpio/gpio-vf610.c#L68 – stark Mar 22 '23 at 17:05
  • 1
    Failing routine is here https://elixir.bootlin.com/linux/latest/source/drivers/gpio/gpiolib-cdev.c#L344 Maybe you can follow the code and figure out what is failing. Turning up logging may help. – stark Mar 22 '23 at 17:34
  • @stark Thank you I will look into how to do this to investigate other issues I now have. I was able to change the pin's direction by adding a pinctrl to the device tree and now sysfs works as expected. Input mode works, but output mode doesn't actually pull the pin high or low, even though a read on the /sys/class/gpio/gpio15/value says it is the desired output level. – MrJones Mar 23 '23 at 13:29
  • Why don't you use `libgpiod` instead of direct access to kernel ABI? – 0andriy Mar 24 '23 at 14:09

0 Answers0