From 5d1646d90e1f2cceb9f0828f4b28318cd0ec7744 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sat, 27 Apr 2024 12:05:51 +0200 Subject: Adding upstream version 5.10.209. Signed-off-by: Daniel Baumann --- tools/gpio/gpio-hammer.c | 176 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 176 insertions(+) create mode 100644 tools/gpio/gpio-hammer.c (limited to 'tools/gpio/gpio-hammer.c') diff --git a/tools/gpio/gpio-hammer.c b/tools/gpio/gpio-hammer.c new file mode 100644 index 000000000..54fdf59dd --- /dev/null +++ b/tools/gpio/gpio-hammer.c @@ -0,0 +1,176 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * gpio-hammer - example swiss army knife to shake GPIO lines on a system + * + * Copyright (C) 2016 Linus Walleij + * + * Usage: + * gpio-hammer -n -o -o + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "gpio-utils.h" + +int hammer_device(const char *device_name, unsigned int *lines, int num_lines, + unsigned int loops) +{ + struct gpio_v2_line_values values; + struct gpio_v2_line_config config; + char swirr[] = "-\\|/"; + int fd; + int ret; + int i, j; + unsigned int iteration = 0; + + memset(&config, 0, sizeof(config)); + config.flags = GPIO_V2_LINE_FLAG_OUTPUT; + + ret = gpiotools_request_line(device_name, lines, num_lines, + &config, "gpio-hammer"); + if (ret < 0) + goto exit_error; + else + fd = ret; + + values.mask = 0; + values.bits = 0; + for (i = 0; i < num_lines; i++) + gpiotools_set_bit(&values.mask, i); + + ret = gpiotools_get_values(fd, &values); + if (ret < 0) + goto exit_close_error; + + fprintf(stdout, "Hammer lines ["); + for (i = 0; i < num_lines; i++) { + fprintf(stdout, "%d", lines[i]); + if (i != (num_lines - 1)) + fprintf(stdout, ", "); + } + fprintf(stdout, "] on %s, initial states: [", device_name); + for (i = 0; i < num_lines; i++) { + fprintf(stdout, "%d", gpiotools_test_bit(values.bits, i)); + if (i != (num_lines - 1)) + fprintf(stdout, ", "); + } + fprintf(stdout, "]\n"); + + /* Hammertime! */ + j = 0; + while (1) { + /* Invert all lines so we blink */ + for (i = 0; i < num_lines; i++) + gpiotools_change_bit(&values.bits, i); + + ret = gpiotools_set_values(fd, &values); + if (ret < 0) + goto exit_close_error; + + /* Re-read values to get status */ + ret = gpiotools_get_values(fd, &values); + if (ret < 0) + goto exit_close_error; + + fprintf(stdout, "[%c] ", swirr[j]); + j++; + if (j == sizeof(swirr) - 1) + j = 0; + + fprintf(stdout, "["); + for (i = 0; i < num_lines; i++) { + fprintf(stdout, "%d: %d", lines[i], + gpiotools_test_bit(values.bits, i)); + if (i != (num_lines - 1)) + fprintf(stdout, ", "); + } + fprintf(stdout, "]\r"); + fflush(stdout); + sleep(1); + iteration++; + if (loops && iteration == loops) + break; + } + fprintf(stdout, "\n"); + ret = 0; + +exit_close_error: + gpiotools_release_line(fd); +exit_error: + return ret; +} + +void print_usage(void) +{ + fprintf(stderr, "Usage: gpio-hammer [options]...\n" + "Hammer GPIO lines, 0->1->0->1...\n" + " -n Hammer GPIOs on a named device (must be stated)\n" + " -o Offset[s] to hammer, at least one, several can be stated\n" + " [-c ] Do loops (optional, infinite loop if not stated)\n" + " -? This helptext\n" + "\n" + "Example:\n" + "gpio-hammer -n gpiochip0 -o 4\n" + ); +} + +int main(int argc, char **argv) +{ + const char *device_name = NULL; + unsigned int lines[GPIOHANDLES_MAX]; + unsigned int loops = 0; + int num_lines; + int c; + int i; + + i = 0; + while ((c = getopt(argc, argv, "c:n:o:?")) != -1) { + switch (c) { + case 'c': + loops = strtoul(optarg, NULL, 10); + break; + case 'n': + device_name = optarg; + break; + case 'o': + /* + * Avoid overflow. Do not immediately error, we want to + * be able to accurately report on the amount of times + * '-o' was given to give an accurate error message + */ + if (i < GPIOHANDLES_MAX) + lines[i] = strtoul(optarg, NULL, 10); + + i++; + break; + case '?': + print_usage(); + return -1; + } + } + + if (i >= GPIOHANDLES_MAX) { + fprintf(stderr, + "Only %d occurrences of '-o' are allowed, %d were found\n", + GPIOHANDLES_MAX, i + 1); + return -1; + } + + num_lines = i; + + if (!device_name || !num_lines) { + print_usage(); + return -1; + } + return hammer_device(device_name, lines, num_lines, loops); +} -- cgit v1.2.3