~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/tools/testing/selftests/gpio/gpio-mockup-cdev.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0
  2 /*
  3  * GPIO mockup cdev test helper
  4  *
  5  * Copyright (C) 2020 Kent Gibson
  6  */
  7 
  8 #include <errno.h>
  9 #include <fcntl.h>
 10 #include <signal.h>
 11 #include <stdint.h>
 12 #include <stdio.h>
 13 #include <stdlib.h>
 14 #include <string.h>
 15 #include <unistd.h>
 16 #include <sys/ioctl.h>
 17 #include <linux/gpio.h>
 18 
 19 #define CONSUMER        "gpio-mockup-cdev"
 20 
 21 static int request_line_v2(int cfd, unsigned int offset,
 22                            uint64_t flags, unsigned int val)
 23 {
 24         struct gpio_v2_line_request req;
 25         int ret;
 26 
 27         memset(&req, 0, sizeof(req));
 28         req.num_lines = 1;
 29         req.offsets[0] = offset;
 30         req.config.flags = flags;
 31         strcpy(req.consumer, CONSUMER);
 32         if (flags & GPIO_V2_LINE_FLAG_OUTPUT) {
 33                 req.config.num_attrs = 1;
 34                 req.config.attrs[0].mask = 1;
 35                 req.config.attrs[0].attr.id = GPIO_V2_LINE_ATTR_ID_OUTPUT_VALUES;
 36                 if (val)
 37                         req.config.attrs[0].attr.values = 1;
 38         }
 39         ret = ioctl(cfd, GPIO_V2_GET_LINE_IOCTL, &req);
 40         if (ret == -1)
 41                 return -errno;
 42         return req.fd;
 43 }
 44 
 45 
 46 static int get_value_v2(int lfd)
 47 {
 48         struct gpio_v2_line_values vals;
 49         int ret;
 50 
 51         memset(&vals, 0, sizeof(vals));
 52         vals.mask = 1;
 53         ret = ioctl(lfd, GPIO_V2_LINE_GET_VALUES_IOCTL, &vals);
 54         if (ret == -1)
 55                 return -errno;
 56         return vals.bits & 0x1;
 57 }
 58 
 59 static int request_line_v1(int cfd, unsigned int offset,
 60                            uint32_t flags, unsigned int val)
 61 {
 62         struct gpiohandle_request req;
 63         int ret;
 64 
 65         memset(&req, 0, sizeof(req));
 66         req.lines = 1;
 67         req.lineoffsets[0] = offset;
 68         req.flags = flags;
 69         strcpy(req.consumer_label, CONSUMER);
 70         if (flags & GPIOHANDLE_REQUEST_OUTPUT)
 71                 req.default_values[0] = val;
 72 
 73         ret = ioctl(cfd, GPIO_GET_LINEHANDLE_IOCTL, &req);
 74         if (ret == -1)
 75                 return -errno;
 76         return req.fd;
 77 }
 78 
 79 static int get_value_v1(int lfd)
 80 {
 81         struct gpiohandle_data vals;
 82         int ret;
 83 
 84         memset(&vals, 0, sizeof(vals));
 85         ret = ioctl(lfd, GPIOHANDLE_GET_LINE_VALUES_IOCTL, &vals);
 86         if (ret == -1)
 87                 return -errno;
 88         return vals.values[0];
 89 }
 90 
 91 static void usage(char *prog)
 92 {
 93         printf("Usage: %s [-l] [-b <bias>] [-s <value>] [-u <uAPI>] <gpiochip> <offset>\n", prog);
 94         printf("        -b: set line bias to one of pull-down, pull-up, disabled\n");
 95         printf("               (default is to leave bias unchanged):\n");
 96         printf("        -l: set line active low (default is active high)\n");
 97         printf("        -s: set line value (default is to get line value)\n");
 98         printf("        -u: uAPI version to use (default is 2)\n");
 99         exit(-1);
100 }
101 
102 static int wait_signal(void)
103 {
104         int sig;
105         sigset_t wset;
106 
107         sigemptyset(&wset);
108         sigaddset(&wset, SIGHUP);
109         sigaddset(&wset, SIGINT);
110         sigaddset(&wset, SIGTERM);
111         sigwait(&wset, &sig);
112 
113         return sig;
114 }
115 
116 int main(int argc, char *argv[])
117 {
118         char *chip;
119         int opt, ret, cfd, lfd;
120         unsigned int offset, val = 0, abiv;
121         uint32_t flags_v1;
122         uint64_t flags_v2;
123 
124         abiv = 2;
125         ret = 0;
126         flags_v1 = GPIOHANDLE_REQUEST_INPUT;
127         flags_v2 = GPIO_V2_LINE_FLAG_INPUT;
128 
129         while ((opt = getopt(argc, argv, "lb:s:u:")) != -1) {
130                 switch (opt) {
131                 case 'l':
132                         flags_v1 |= GPIOHANDLE_REQUEST_ACTIVE_LOW;
133                         flags_v2 |= GPIO_V2_LINE_FLAG_ACTIVE_LOW;
134                         break;
135                 case 'b':
136                         if (strcmp("pull-up", optarg) == 0) {
137                                 flags_v1 |= GPIOHANDLE_REQUEST_BIAS_PULL_UP;
138                                 flags_v2 |= GPIO_V2_LINE_FLAG_BIAS_PULL_UP;
139                         } else if (strcmp("pull-down", optarg) == 0) {
140                                 flags_v1 |= GPIOHANDLE_REQUEST_BIAS_PULL_DOWN;
141                                 flags_v2 |= GPIO_V2_LINE_FLAG_BIAS_PULL_DOWN;
142                         } else if (strcmp("disabled", optarg) == 0) {
143                                 flags_v1 |= GPIOHANDLE_REQUEST_BIAS_DISABLE;
144                                 flags_v2 |= GPIO_V2_LINE_FLAG_BIAS_DISABLED;
145                         }
146                         break;
147                 case 's':
148                         val = atoi(optarg);
149                         flags_v1 &= ~GPIOHANDLE_REQUEST_INPUT;
150                         flags_v1 |= GPIOHANDLE_REQUEST_OUTPUT;
151                         flags_v2 &= ~GPIO_V2_LINE_FLAG_INPUT;
152                         flags_v2 |= GPIO_V2_LINE_FLAG_OUTPUT;
153                         break;
154                 case 'u':
155                         abiv = atoi(optarg);
156                         break;
157                 default:
158                         usage(argv[0]);
159                 }
160         }
161 
162         if (argc < optind + 2)
163                 usage(argv[0]);
164 
165         chip = argv[optind];
166         offset = atoi(argv[optind + 1]);
167 
168         cfd = open(chip, 0);
169         if (cfd == -1) {
170                 fprintf(stderr, "Failed to open %s: %s\n", chip, strerror(errno));
171                 return -errno;
172         }
173 
174         if (abiv == 1)
175                 lfd = request_line_v1(cfd, offset, flags_v1, val);
176         else
177                 lfd = request_line_v2(cfd, offset, flags_v2, val);
178 
179         close(cfd);
180 
181         if (lfd < 0) {
182                 fprintf(stderr, "Failed to request %s:%d: %s\n", chip, offset, strerror(-lfd));
183                 return lfd;
184         }
185 
186         if (flags_v2 & GPIO_V2_LINE_FLAG_OUTPUT) {
187                 wait_signal();
188         } else {
189                 if (abiv == 1)
190                         ret = get_value_v1(lfd);
191                 else
192                         ret = get_value_v2(lfd);
193         }
194 
195         close(lfd);
196 
197         return ret;
198 }
199 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php