2019-11-27 12:17:54 +03:00
// SPDX-License-Identifier: GPL-2.0-only
/*
* gpio - watch - monitor unrequested lines for property changes using the
* character device
*
* Copyright ( C ) 2019 BayLibre SAS
* Author : Bartosz Golaszewski < bgolaszewski @ baylibre . com >
*/
# include <ctype.h>
# include <errno.h>
# include <fcntl.h>
2021-01-07 07:00:20 +03:00
# include <inttypes.h>
2019-11-27 12:17:54 +03:00
# include <linux/gpio.h>
# include <poll.h>
# include <stdbool.h>
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# include <sys/ioctl.h>
# include <unistd.h>
int main ( int argc , char * * argv )
{
2020-09-28 03:28:02 +03:00
struct gpio_v2_line_info_changed chg ;
struct gpio_v2_line_info req ;
2019-11-27 12:17:54 +03:00
struct pollfd pfd ;
int fd , i , j , ret ;
char * event , * end ;
ssize_t rd ;
if ( argc < 3 )
goto err_usage ;
fd = open ( argv [ 1 ] , O_RDWR | O_CLOEXEC ) ;
if ( fd < 0 ) {
perror ( " unable to open gpiochip " ) ;
return EXIT_FAILURE ;
}
for ( i = 0 , j = 2 ; i < argc - 2 ; i + + , j + + ) {
memset ( & req , 0 , sizeof ( req ) ) ;
2020-09-28 03:28:02 +03:00
req . offset = strtoul ( argv [ j ] , & end , 0 ) ;
2019-11-27 12:17:54 +03:00
if ( * end ! = ' \0 ' )
goto err_usage ;
2020-09-28 03:28:02 +03:00
ret = ioctl ( fd , GPIO_V2_GET_LINEINFO_WATCH_IOCTL , & req ) ;
2019-11-27 12:17:54 +03:00
if ( ret ) {
perror ( " unable to set up line watch " ) ;
return EXIT_FAILURE ;
}
}
pfd . fd = fd ;
pfd . events = POLLIN | POLLPRI ;
for ( ; ; ) {
ret = poll ( & pfd , 1 , 5000 ) ;
if ( ret < 0 ) {
perror ( " error polling the linechanged fd " ) ;
return EXIT_FAILURE ;
} else if ( ret > 0 ) {
memset ( & chg , 0 , sizeof ( chg ) ) ;
rd = read ( pfd . fd , & chg , sizeof ( chg ) ) ;
if ( rd < 0 | | rd ! = sizeof ( chg ) ) {
if ( rd ! = sizeof ( chg ) )
errno = EIO ;
perror ( " error reading line change event " ) ;
return EXIT_FAILURE ;
}
switch ( chg . event_type ) {
2020-09-28 03:28:02 +03:00
case GPIO_V2_LINE_CHANGED_REQUESTED :
2019-11-27 12:17:54 +03:00
event = " requested " ;
break ;
2020-09-28 03:28:02 +03:00
case GPIO_V2_LINE_CHANGED_RELEASED :
2019-11-27 12:17:54 +03:00
event = " released " ;
break ;
2020-09-28 03:28:02 +03:00
case GPIO_V2_LINE_CHANGED_CONFIG :
2019-11-27 12:17:54 +03:00
event = " config changed " ;
break ;
default :
fprintf ( stderr ,
" invalid event type received from the kernel \n " ) ;
return EXIT_FAILURE ;
}
2021-01-07 07:00:20 +03:00
printf ( " line %u: %s at % " PRIu64 " \n " ,
chg . info . offset , event , ( uint64_t ) chg . timestamp_ns ) ;
2019-11-27 12:17:54 +03:00
}
}
return 0 ;
err_usage :
printf ( " %s: <gpiochip> <line0> <line1> ... \n " , argv [ 0 ] ) ;
return EXIT_FAILURE ;
}