.\" $NetBSD: gpioirq.4,v 1.5 2024/09/14 21:12:10 andvar Exp $
.\"
.\" Copyright (c) 2016, 2023 Brad Spencer <brad@anduin.eldar.org>
.\"
.\" Permission to use, copy, modify, and distribute this software for any
.\" purpose with or without fee is hereby granted, provided that the above
.\" copyright notice and this permission notice appear in all copies.
.\"
.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
.Dd November 5, 2023
.Dt GPIOIRQ 4
.Os
.Sh NAME
.Nm gpioirq
.Nd Install an interrupt handler on GPIO pins
.Sh SYNOPSIS
.Cd "gpioirq* at gpio? offset 0 mask 0x1 flag 0x00"
.Sh DESCRIPTION
The
.Nm
driver attaches an interrupt handler to a one or more GPIO pins.
.Pp
The base pin number is specified in the kernel configuration file with the
.Ar offset
locator.
The
.Ar mask
locator can be 0x01 or greater to indicate that more pins should have an
interrupt handler attached to them.
.Pp
The
.Ar flag
locator specifies the interrupt mode to use:
.Bl -tag -width "XXXXXXXX"
.It Dv 0x01
Interrupt on the positive
.Pq rising
edge of the pin.
.It Dv 0x02
Interrupt on the negative
.Pq falling
edge of the pin.
.It Dv 0x04
Interrupt on both edges of the pin.
.It Dv 0x08
Assert the interrupt as long as the pin is high.
.It Dv 0x10
Assert the interrupt as long as the pin is low.
.El
.Pp
Note that the interrupts modes are mutually-exclusive, and exactly one
interrupt mode must be specified.
These flags correspond to the
.Dv GPIO_INTR
mode bits defined in
.Pa sys/gpio.h .
In addition to the interrupt mode, setting
.Dv 0x1000
in
.Ar flags
will enable the printing of a message to the console whenever the
interrupt handler is called.
.Pp
The
.Ar offset ,
.Ar mask ,
and
.Ar flag
locators can also be specified when
.Nm
is attached at runtime using the
.Dv GPIOATTACH
.Xr ioctl 2
on the
.Xr gpio 4
device.
.Sh FILES
.Bl -tag -width "/dev/gpioirqu" -compact
.It /dev/gpioirq Ns Ar u
GPIOIRQ device unit
.Ar u
file.
The output from this device are three uint8_t bytes every time an interrupt fires.
The bytes contain the device unit, pin number and the current state of the pin.
.Sh EXAMPLES
The following example will output the device unit, pin and
the pins current state for pins 4, 5, 6, 7, 8, 9, 10, 11, 12 on gpio0:
.Bd -literal -offset indent
/etc/gpio.conf contains:
gpio0 attach gpioirq 4 0x1ff 0x04

or a kernel was compiled to have the same parameters.

#!/usr/pkg/bin/perl

$dev = "/dev/gpioirq0";

sysopen(DEV,$dev,O_RDONLY) || die "sysopen: $!";

while (sysread(DEV,$b,3)) {
    @v = unpack("CCC",$b);

    print join(',',@v);
    print "\\n";
}

.Sh SEE ALSO
.Xr gpio 4 ,
.Xr drvctl 8 ,
.Xr gpioctl 8
.Sh HISTORY
The
.Nm
driver first appeared in
.Nx 9.0 .
.Sh AUTHORS
.An -nosplit
The
.Nm
driver was written by
.An Brad Spencer Aq Mt brad@anduin.eldar.org .
.Sh BUGS
When an interrupt fires in most devices there is not any information carried
along in the interrupt as to whether or not the pin is high or low.  Hence the
driver reads the current state of the pin after the interrupt has fired and it is
possible that the state of the pin could have changed between the time the interrupt
fired and the reading of the state.  As a practical matter the only time the pin state
will be reported wrong is if there is a very large number of interrupts happening.  The
driver could have made some assumptions if the interrupt was only for a rising edge or falling
edge as in those cases it would be possible to know what the pin state would have been, but
in the case of the double edge, there really will not be any way to be sure with most hardware
and, in any case, the
.Xr gpio 4
infrastructure does not support getting at that information even if it did exist.
.Pp
It is important that if the
.Xr gpioirq 4
device is opened that it be read, as it may be possible
to run the kernel out of memory if the device is opened but not read and interrupts
occur on a pin tied to the driver.