forked from torvalds/linux
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
tools/leds: Add led_hw_brightness_mon program
LED subsystem supports POLLPRI on "brightness_hw_changed" sysfs file of LED class devices. This tool demonstrates how to use the feature. Signed-off-by: Jacek Anaszewski <[email protected]> Acked-by: Hans de Goede <[email protected]> Acked-by: Pavel Machek <[email protected]>
- Loading branch information
1 parent
0cb8eb3
commit ae34732
Showing
2 changed files
with
86 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
/* | ||
* led_hw_brightness_mon.c | ||
* | ||
* This program monitors LED brightness level changes having its origin | ||
* in hardware/firmware, i.e. outside of kernel control. | ||
* A timestamp and brightness value is printed each time the brightness changes. | ||
* | ||
* Usage: led_hw_brightness_mon <device-name> | ||
* | ||
* <device-name> is the name of the LED class device to be monitored. Pressing | ||
* CTRL+C will exit. | ||
*/ | ||
|
||
#include <errno.h> | ||
#include <fcntl.h> | ||
#include <poll.h> | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <string.h> | ||
#include <time.h> | ||
#include <unistd.h> | ||
|
||
#include <linux/uleds.h> | ||
|
||
int main(int argc, char const *argv[]) | ||
{ | ||
int fd, ret; | ||
char brightness_file_path[LED_MAX_NAME_SIZE + 11]; | ||
struct pollfd pollfd; | ||
struct timespec ts; | ||
char buf[11]; | ||
|
||
if (argc != 2) { | ||
fprintf(stderr, "Requires <device-name> argument\n"); | ||
return 1; | ||
} | ||
|
||
snprintf(brightness_file_path, LED_MAX_NAME_SIZE, | ||
"/sys/class/leds/%s/brightness_hw_changed", argv[1]); | ||
|
||
fd = open(brightness_file_path, O_RDONLY); | ||
if (fd == -1) { | ||
printf("Failed to open %s file\n", brightness_file_path); | ||
return 1; | ||
} | ||
|
||
/* | ||
* read may fail if no hw brightness change has occurred so far, | ||
* but it is required to avoid spurious poll notifications in | ||
* the opposite case. | ||
*/ | ||
read(fd, buf, sizeof(buf)); | ||
|
||
pollfd.fd = fd; | ||
pollfd.events = POLLPRI; | ||
|
||
while (1) { | ||
ret = poll(&pollfd, 1, -1); | ||
if (ret == -1) { | ||
printf("Failed to poll %s file (%d)\n", | ||
brightness_file_path, ret); | ||
ret = 1; | ||
break; | ||
} | ||
|
||
clock_gettime(CLOCK_MONOTONIC, &ts); | ||
|
||
ret = read(fd, buf, sizeof(buf)); | ||
if (ret < 0) | ||
break; | ||
|
||
ret = lseek(pollfd.fd, 0, SEEK_SET); | ||
if (ret < 0) { | ||
printf("lseek failed (%d)\n", ret); | ||
break; | ||
} | ||
|
||
printf("[%ld.%09ld] %d\n", ts.tv_sec, ts.tv_nsec, atoi(buf)); | ||
} | ||
|
||
close(fd); | ||
|
||
return ret; | ||
} |