root/tools/gpio/gpio-utils.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. gpiotools_request_linehandle
  2. gpiotools_set_values
  3. gpiotools_get_values
  4. gpiotools_release_linehandle
  5. gpiotools_get
  6. gpiotools_gets
  7. gpiotools_set
  8. gpiotools_sets

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * GPIO tools - helpers library for the GPIO tools
   4  *
   5  * Copyright (C) 2015 Linus Walleij
   6  * Copyright (C) 2016 Bamvor Jian Zhang
   7  */
   8 
   9 #include <unistd.h>
  10 #include <stdlib.h>
  11 #include <stdio.h>
  12 #include <errno.h>
  13 #include <string.h>
  14 #include <fcntl.h>
  15 #include <getopt.h>
  16 #include <sys/ioctl.h>
  17 #include <linux/gpio.h>
  18 #include "gpio-utils.h"
  19 
  20 #define COMSUMER "gpio-utils"
  21 
  22 /**
  23  * doc: Operation of gpio
  24  *
  25  * Provide the api of gpiochip for chardev interface. There are two
  26  * types of api.  The first one provide as same function as each
  27  * ioctl, including request and release for lines of gpio, read/write
  28  * the value of gpio. If the user want to do lots of read and write of
  29  * lines of gpio, user should use this type of api.
  30  *
  31  * The second one provide the easy to use api for user. Each of the
  32  * following api will request gpio lines, do the operation and then
  33  * release these lines.
  34  */
  35 /**
  36  * gpiotools_request_linehandle() - request gpio lines in a gpiochip
  37  * @device_name:        The name of gpiochip without prefix "/dev/",
  38  *                      such as "gpiochip0"
  39  * @lines:              An array desired lines, specified by offset
  40  *                      index for the associated GPIO device.
  41  * @nline:              The number of lines to request.
  42  * @flag:               The new flag for requsted gpio. Reference
  43  *                      "linux/gpio.h" for the meaning of flag.
  44  * @data:               Default value will be set to gpio when flag is
  45  *                      GPIOHANDLE_REQUEST_OUTPUT.
  46  * @consumer_label:     The name of consumer, such as "sysfs",
  47  *                      "powerkey". This is useful for other users to
  48  *                      know who is using.
  49  *
  50  * Request gpio lines through the ioctl provided by chardev. User
  51  * could call gpiotools_set_values() and gpiotools_get_values() to
  52  * read and write respectively through the returned fd. Call
  53  * gpiotools_release_linehandle() to release these lines after that.
  54  *
  55  * Return:              On success return the fd;
  56  *                      On failure return the errno.
  57  */
  58 int gpiotools_request_linehandle(const char *device_name, unsigned int *lines,
  59                                  unsigned int nlines, unsigned int flag,
  60                                  struct gpiohandle_data *data,
  61                                  const char *consumer_label)
  62 {
  63         struct gpiohandle_request req;
  64         char *chrdev_name;
  65         int fd;
  66         int i;
  67         int ret;
  68 
  69         ret = asprintf(&chrdev_name, "/dev/%s", device_name);
  70         if (ret < 0)
  71                 return -ENOMEM;
  72 
  73         fd = open(chrdev_name, 0);
  74         if (fd == -1) {
  75                 ret = -errno;
  76                 fprintf(stderr, "Failed to open %s, %s\n",
  77                         chrdev_name, strerror(errno));
  78                 goto exit_close_error;
  79         }
  80 
  81         for (i = 0; i < nlines; i++)
  82                 req.lineoffsets[i] = lines[i];
  83 
  84         req.flags = flag;
  85         strcpy(req.consumer_label, consumer_label);
  86         req.lines = nlines;
  87         if (flag & GPIOHANDLE_REQUEST_OUTPUT)
  88                 memcpy(req.default_values, data, sizeof(req.default_values));
  89 
  90         ret = ioctl(fd, GPIO_GET_LINEHANDLE_IOCTL, &req);
  91         if (ret == -1) {
  92                 ret = -errno;
  93                 fprintf(stderr, "Failed to issue %s (%d), %s\n",
  94                         "GPIO_GET_LINEHANDLE_IOCTL", ret, strerror(errno));
  95         }
  96 
  97 exit_close_error:
  98         if (close(fd) == -1)
  99                 perror("Failed to close GPIO character device file");
 100         free(chrdev_name);
 101         return ret < 0 ? ret : req.fd;
 102 }
 103 /**
 104  * gpiotools_set_values(): Set the value of gpio(s)
 105  * @fd:                 The fd returned by
 106  *                      gpiotools_request_linehandle().
 107  * @data:               The array of values want to set.
 108  *
 109  * Return:              On success return 0;
 110  *                      On failure return the errno.
 111  */
 112 int gpiotools_set_values(const int fd, struct gpiohandle_data *data)
 113 {
 114         int ret;
 115 
 116         ret = ioctl(fd, GPIOHANDLE_SET_LINE_VALUES_IOCTL, data);
 117         if (ret == -1) {
 118                 ret = -errno;
 119                 fprintf(stderr, "Failed to issue %s (%d), %s\n",
 120                         "GPIOHANDLE_SET_LINE_VALUES_IOCTL", ret,
 121                         strerror(errno));
 122         }
 123 
 124         return ret;
 125 }
 126 
 127 /**
 128  * gpiotools_get_values(): Get the value of gpio(s)
 129  * @fd:                 The fd returned by
 130  *                      gpiotools_request_linehandle().
 131  * @data:               The array of values get from hardware.
 132  *
 133  * Return:              On success return 0;
 134  *                      On failure return the errno.
 135  */
 136 int gpiotools_get_values(const int fd, struct gpiohandle_data *data)
 137 {
 138         int ret;
 139 
 140         ret = ioctl(fd, GPIOHANDLE_GET_LINE_VALUES_IOCTL, data);
 141         if (ret == -1) {
 142                 ret = -errno;
 143                 fprintf(stderr, "Failed to issue %s (%d), %s\n",
 144                         "GPIOHANDLE_GET_LINE_VALUES_IOCTL", ret,
 145                         strerror(errno));
 146         }
 147 
 148         return ret;
 149 }
 150 
 151 /**
 152  * gpiotools_release_linehandle(): Release the line(s) of gpiochip
 153  * @fd:                 The fd returned by
 154  *                      gpiotools_request_linehandle().
 155  *
 156  * Return:              On success return 0;
 157  *                      On failure return the errno.
 158  */
 159 int gpiotools_release_linehandle(const int fd)
 160 {
 161         int ret;
 162 
 163         ret = close(fd);
 164         if (ret == -1) {
 165                 perror("Failed to close GPIO LINEHANDLE device file");
 166                 ret = -errno;
 167         }
 168 
 169         return ret;
 170 }
 171 
 172 /**
 173  * gpiotools_get(): Get value from specific line
 174  * @device_name:        The name of gpiochip without prefix "/dev/",
 175  *                      such as "gpiochip0"
 176  * @line:               number of line, such as 2.
 177  *
 178  * Return:              On success return 0;
 179  *                      On failure return the errno.
 180  */
 181 int gpiotools_get(const char *device_name, unsigned int line)
 182 {
 183         struct gpiohandle_data data;
 184         unsigned int lines[] = {line};
 185 
 186         gpiotools_gets(device_name, lines, 1, &data);
 187         return data.values[0];
 188 }
 189 
 190 
 191 /**
 192  * gpiotools_gets(): Get values from specific lines.
 193  * @device_name:        The name of gpiochip without prefix "/dev/",
 194  *                      such as "gpiochip0".
 195  * @lines:              An array desired lines, specified by offset
 196  *                      index for the associated GPIO device.
 197  * @nline:              The number of lines to request.
 198  * @data:               The array of values get from gpiochip.
 199  *
 200  * Return:              On success return 0;
 201  *                      On failure return the errno.
 202  */
 203 int gpiotools_gets(const char *device_name, unsigned int *lines,
 204                    unsigned int nlines, struct gpiohandle_data *data)
 205 {
 206         int fd;
 207         int ret;
 208         int ret_close;
 209 
 210         ret = gpiotools_request_linehandle(device_name, lines, nlines,
 211                                            GPIOHANDLE_REQUEST_INPUT, data,
 212                                            COMSUMER);
 213         if (ret < 0)
 214                 return ret;
 215 
 216         fd = ret;
 217         ret = gpiotools_get_values(fd, data);
 218         ret_close = gpiotools_release_linehandle(fd);
 219         return ret < 0 ? ret : ret_close;
 220 }
 221 
 222 /**
 223  * gpiotools_set(): Set value to specific line
 224  * @device_name:        The name of gpiochip without prefix "/dev/",
 225  *                      such as "gpiochip0"
 226  * @line:               number of line, such as 2.
 227  * @value:              The value of gpio, must be 0(low) or 1(high).
 228  *
 229  * Return:              On success return 0;
 230  *                      On failure return the errno.
 231  */
 232 int gpiotools_set(const char *device_name, unsigned int line,
 233                   unsigned int value)
 234 {
 235         struct gpiohandle_data data;
 236         unsigned int lines[] = {line};
 237 
 238         data.values[0] = value;
 239         return gpiotools_sets(device_name, lines, 1, &data);
 240 }
 241 
 242 /**
 243  * gpiotools_sets(): Set values to specific lines.
 244  * @device_name:        The name of gpiochip without prefix "/dev/",
 245  *                      such as "gpiochip0".
 246  * @lines:              An array desired lines, specified by offset
 247  *                      index for the associated GPIO device.
 248  * @nline:              The number of lines to request.
 249  * @data:               The array of values set to gpiochip, must be
 250  *                      0(low) or 1(high).
 251  *
 252  * Return:              On success return 0;
 253  *                      On failure return the errno.
 254  */
 255 int gpiotools_sets(const char *device_name, unsigned int *lines,
 256                    unsigned int nlines, struct gpiohandle_data *data)
 257 {
 258         int ret;
 259 
 260         ret = gpiotools_request_linehandle(device_name, lines, nlines,
 261                                            GPIOHANDLE_REQUEST_OUTPUT, data,
 262                                            COMSUMER);
 263         if (ret < 0)
 264                 return ret;
 265 
 266         return gpiotools_release_linehandle(ret);
 267 }

/* [<][>][^][v][top][bottom][index][help] */