1 // SPDX-License-Identifier: GPL-2.0-only
3 * gpio-hammer - example swiss army knife to shake GPIO lines on a system
5 * Copyright (C) 2016 Linus Walleij
8 * gpio-hammer -n <device-name> -o <offset1> -o <offset2>
21 #include <sys/ioctl.h>
22 #include <linux/gpio.h>
23 #include "gpio-utils.h"
25 int hammer_device(const char *device_name
, unsigned int *lines
, int num_lines
,
28 struct gpio_v2_line_values values
;
29 struct gpio_v2_line_config config
;
30 char swirr
[] = "-\\|/";
34 unsigned int iteration
= 0;
36 memset(&config
, 0, sizeof(config
));
37 config
.flags
= GPIO_V2_LINE_FLAG_OUTPUT
;
39 ret
= gpiotools_request_line(device_name
, lines
, num_lines
,
40 &config
, "gpio-hammer");
48 for (i
= 0; i
< num_lines
; i
++)
49 gpiotools_set_bit(&values
.mask
, i
);
51 ret
= gpiotools_get_values(fd
, &values
);
53 goto exit_close_error
;
55 fprintf(stdout
, "Hammer lines [");
56 for (i
= 0; i
< num_lines
; i
++) {
57 fprintf(stdout
, "%d", lines
[i
]);
58 if (i
!= (num_lines
- 1))
59 fprintf(stdout
, ", ");
61 fprintf(stdout
, "] on %s, initial states: [", device_name
);
62 for (i
= 0; i
< num_lines
; i
++) {
63 fprintf(stdout
, "%d", gpiotools_test_bit(values
.bits
, i
));
64 if (i
!= (num_lines
- 1))
65 fprintf(stdout
, ", ");
67 fprintf(stdout
, "]\n");
72 /* Invert all lines so we blink */
73 for (i
= 0; i
< num_lines
; i
++)
74 gpiotools_change_bit(&values
.bits
, i
);
76 ret
= gpiotools_set_values(fd
, &values
);
78 goto exit_close_error
;
80 /* Re-read values to get status */
81 ret
= gpiotools_get_values(fd
, &values
);
83 goto exit_close_error
;
85 fprintf(stdout
, "[%c] ", swirr
[j
]);
87 if (j
== sizeof(swirr
) - 1)
91 for (i
= 0; i
< num_lines
; i
++) {
92 fprintf(stdout
, "%d: %d", lines
[i
],
93 gpiotools_test_bit(values
.bits
, i
));
94 if (i
!= (num_lines
- 1))
95 fprintf(stdout
, ", ");
97 fprintf(stdout
, "]\r");
101 if (loops
&& iteration
== loops
)
104 fprintf(stdout
, "\n");
108 gpiotools_release_line(fd
);
113 void print_usage(void)
115 fprintf(stderr
, "Usage: gpio-hammer [options]...\n"
116 "Hammer GPIO lines, 0->1->0->1...\n"
117 " -n <name> Hammer GPIOs on a named device (must be stated)\n"
118 " -o <n> Offset[s] to hammer, at least one, several can be stated\n"
119 " [-c <n>] Do <n> loops (optional, infinite loop if not stated)\n"
120 " -? This helptext\n"
123 "gpio-hammer -n gpiochip0 -o 4\n"
127 int main(int argc
, char **argv
)
129 const char *device_name
= NULL
;
130 unsigned int lines
[GPIOHANDLES_MAX
];
131 unsigned int loops
= 0;
137 while ((c
= getopt(argc
, argv
, "c:n:o:?")) != -1) {
140 loops
= strtoul(optarg
, NULL
, 10);
143 device_name
= optarg
;
147 * Avoid overflow. Do not immediately error, we want to
148 * be able to accurately report on the amount of times
149 * '-o' was given to give an accurate error message
151 if (i
< GPIOHANDLES_MAX
)
152 lines
[i
] = strtoul(optarg
, NULL
, 10);
162 if (i
>= GPIOHANDLES_MAX
) {
164 "Only %d occurrences of '-o' are allowed, %d were found\n",
165 GPIOHANDLES_MAX
, i
+ 1);
171 if (!device_name
|| !num_lines
) {
175 return hammer_device(device_name
, lines
, num_lines
, loops
);