[PATCH v3 1/5] tools/gpio: add gpio basic opereations

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Bamvor Jian Zhang <bamvor.zhangjian@xxxxxxxxxx>

Add basic gpio operations. User could get/set gpio value and/or flag for
specific gpio chardev.

Reference the "tools/testing/selftest/gpio/gpio-mockup-chardev.c" for
how to use it.

Signed-off-by: Bamvor Jian Zhang <bamvor.zhangjian@xxxxxxxxxx>
---
 tools/gpio/gpio-utils.c | 163 ++++++++++++++++++++++++++++++++++++++++++++++++
 tools/gpio/gpio-utils.h | 121 +++++++++++++++++++++++++++++++++++
 2 files changed, 284 insertions(+)

diff --git a/tools/gpio/gpio-utils.c b/tools/gpio/gpio-utils.c
index 8208718..3c0a35c 100644
--- a/tools/gpio/gpio-utils.c
+++ b/tools/gpio/gpio-utils.c
@@ -2,10 +2,173 @@
  * GPIO tools - helpers library for the GPIO tools
  *
  * Copyright (C) 2015 Linus Walleij
+ * Copyright (C) 2016 Bamvor Jian Zhang
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published by
  * the Free Software Foundation.
  */
 
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#include <fcntl.h>
+#include <getopt.h>
+#include <sys/ioctl.h>
+#include <linux/gpio.h>
 #include "gpio-utils.h"
+
+#define COMSUMER "gpio-utils"
+
+int gpio_request(const char *device_name, unsigned int *lines,
+		 unsigned int nlines, unsigned int flag,
+		 struct gpiohandle_data *data, const char *consumer_label)
+{
+	struct gpiohandle_request req;
+	char *chrdev_name;
+	int fd;
+	int i;
+	int ret;
+
+	ret = asprintf(&chrdev_name, "/dev/%s", device_name);
+	if (ret < 0)
+		return -ENOMEM;
+
+	fd = open(chrdev_name, 0);
+	if (fd == -1) {
+		ret = -errno;
+		fprintf(stderr, "Failed to open %s\n", chrdev_name);
+		goto exit_close_error;
+	}
+
+	for (i = 0; i < nlines; i++)
+		req.lineoffsets[i] = lines[i];
+
+	req.flags = flag;
+	strcpy(req.consumer_label, consumer_label);
+	req.lines = nlines;
+	if (flag & GPIOHANDLE_REQUEST_OUTPUT)
+		memcpy(req.default_values, data, sizeof(req.default_values));
+
+	ret = ioctl(fd, GPIO_GET_LINEHANDLE_IOCTL, &req);
+	if (ret == -1) {
+		ret = -errno;
+		fprintf(stderr, "Failed to issue GET LINEHANDLE IOCTL (%d)\n",
+			ret);
+		goto exit_close_error;
+	}
+
+exit_close_error:
+	if (close(fd) == -1)
+		perror("Failed to close GPIO character device file");
+	free(chrdev_name);
+	return ret < 0 ? ret : req.fd;
+}
+
+int gpio_set_values(const int fd, struct gpiohandle_data *data)
+{
+	int ret;
+
+	ret = ioctl(fd, GPIOHANDLE_SET_LINE_VALUES_IOCTL, data);
+	if (ret == -1) {
+		ret = -errno;
+		fprintf(stderr, "Failed to issue %s (%d)\n",
+			"GPIOHANDLE_SET_LINE_VALUES_IOCTL", ret);
+		goto exit_close_error;
+	}
+
+exit_close_error:
+	return ret;
+}
+
+int gpio_get_values(const int fd, struct gpiohandle_data *data)
+{
+	int ret;
+
+	ret = ioctl(fd, GPIOHANDLE_GET_LINE_VALUES_IOCTL, data);
+	if (ret == -1) {
+		ret = -errno;
+		fprintf(stderr, "Failed to issue %s (%d)\n",
+			"GPIOHANDLE_GET_LINE_VALUES_IOCTL", ret);
+		goto exit_close_error;
+	}
+
+exit_close_error:
+	return ret;
+}
+
+int gpio_release(const int fd)
+{
+	int ret;
+
+	ret = close(fd);
+	if (ret < -1)
+		perror("Failed to close GPIO LINEHANDLE device file");
+
+	return ret;
+}
+
+int gpio_gets(const char *device_name, unsigned int *lines, unsigned int nlines,
+	      unsigned int flag, struct gpiohandle_data *data)
+{
+	int fd;
+	int ret;
+
+	ret = gpio_request(device_name, lines, nlines, flag, data, COMSUMER);
+	if (ret < 0)
+		return ret;
+
+	fd = ret;
+	ret = gpio_get_values(fd, data);
+	ret = gpio_release(fd);
+	return ret;
+}
+
+int gpio_sets(const char *device_name, unsigned int *lines, unsigned int nlines,
+	      unsigned int flag, struct gpiohandle_data *data)
+{
+	int ret;
+
+	ret = gpio_request(device_name, lines, nlines, flag, data, COMSUMER);
+	if (ret < 0)
+		return ret;
+
+	ret = gpio_release(ret);
+	return ret;
+}
+
+int gpio_get(const char *device_name, unsigned int line, unsigned int flag)
+{
+	struct gpiohandle_data data;
+	unsigned int lines[] = {line};
+
+	gpio_gets(device_name, lines, 1, flag, &data);
+	return data.values[0];
+}
+
+int gpio_set(const char *device_name, unsigned int line, unsigned int flag,
+	     unsigned int value)
+{
+	struct gpiohandle_data data;
+	unsigned int lines[] = {line};
+
+	data.values[0] = value;
+	return gpio_sets(device_name, lines, 1, flag, &data);
+}
+
+int gpio_set_flag(const char *device_name, unsigned int line, unsigned int flag)
+{
+	struct gpiohandle_data data;
+	unsigned int lines[] = {line};
+	int ret;
+
+	ret = gpio_request(device_name, lines, 1, flag, &data, COMSUMER);
+	if (ret < 0)
+		return ret;
+
+	ret = gpio_release(ret);
+	return ret;
+}
+
diff --git a/tools/gpio/gpio-utils.h b/tools/gpio/gpio-utils.h
index 5f57133..fcf87b6 100644
--- a/tools/gpio/gpio-utils.h
+++ b/tools/gpio/gpio-utils.h
@@ -24,4 +24,125 @@ static inline int check_prefix(const char *str, const char *prefix)
 		strncmp(str, prefix, strlen(prefix)) == 0;
 }
 
+/* Basic operation of gpio */
+/*
+ * Request the lines for gpio with device_name. Could set the default value
+ * in request.
+ * device_name:    the name of gpiochip in "/dev", such as gpiochip0.
+ * lines:	   the array of which line should be requested.
+ * nline:          the total number of line
+ * flag:           input, output and so on. Reference "linux/gpio.h" for the
+ *                 meaning for flag.
+ * data:	   default value when flag is GPIOHANDLE_REQUEST_OUTPUT.
+ * consumer_label: the name of consumer, such as "sysfs", "powerkey".
+ *
+ * Return value:   On success return the fd of specific gpiochip. It could be
+ *                 release by gpio_release.
+ *		   On failure return the errno.
+ */
+int gpio_request(const char *device_name, unsigned int *lines,
+		 unsigned int nlines, unsigned int flag,
+		 struct gpiohandle_data *data, const char *consumer_label);
+/*
+ * Set the value of gpio for fd
+ * fd:             the fd returned by gpio_request
+ * data:	   the value want to set
+ *
+ * Return value:   On success return 0
+ *		   On failure return the errno.
+ */
+int gpio_set_values(const int fd, struct gpiohandle_data *data);
+
+/*
+ * Get the value of gpio for fd
+ * fd:             the fd returned by gpio_request
+ * data:	   the valud get from gpiochip.
+ *
+ * Return value:   On success return 0
+ *		   On failure return the errno.
+ */
+int gpio_get_values(const int fd, struct gpiohandle_data *data);
+
+/*
+ * release the fd for gpiochip
+ */
+int gpio_release(const int fd);
+
+/* Easy operation for one time get/set */
+/*
+ * Get one pin value from line of device_name. Could change the flag if
+ * necessary.
+ * device_name: the name of gpiochip in "/dev", such as gpiochip0.
+ * line:        number of line, such as 2.
+ * flag:        input, output and so on. Reference "linux/gpio.h" for the
+ *              meaning for flag. Set to 0 if do not want to update the
+ *              flag. It is the recommandation value.
+ *
+ * Return value:   On success return the value get from gpiochip.
+ *		   On failure return the errno.
+ */
+int gpio_get(const char *device_name, unsigned int line, unsigned int flag);
+
+/*
+ * Get pins value from line of device_name. Could change the flag if
+ * necessary.
+ * device_name: the name of gpiochip in "/dev", such as gpiochip0.
+ * lines:	   the array of which line should be requested.
+ * nline:          the total number of line
+ * flag:           input, output and so on. Reference "linux/gpio.h" for the
+ *                 meaning for flag.
+ * data:	   the valud get from gpiochip.
+ *
+ * Return value:   On success return 0
+ *		   On failure return the errno.
+ */
+int gpio_gets(const char *device_name, unsigned int *lines, unsigned int nlines,
+	      unsigned int flag, struct gpiohandle_data *data);
+
+/*
+ * Set one pin value from line of device_name. Could change the flag if
+ * necessary.
+ * device_name: the name of gpiochip in "/dev", such as gpiochip0.
+ * line:        number of line, such as 2.
+ * flag:        input, output and so on. Reference "linux/gpio.h" for the
+ *              meaning for flag. Set to 0 if do not want to update the
+ *              flag. It is the recommandation value.
+ * value:	the value want to set the gpio line.
+ *
+ * Return value:   On success return 0
+ *		   On failure return the errno.
+ */
+int gpio_set(const char *device_name, unsigned int line, unsigned int flag,
+	     unsigned int value);
+
+/*
+ * Set pins value from line of device_name. Could change the flag if
+ * necessary.
+ * device_name: the name of gpiochip in "/dev", such as gpiochip0.
+ * lines:	   the array of which line should be requested.
+ * nline:          the total number of line
+ * flag:           input, output and so on. Reference "linux/gpio.h" for the
+ *                 meaning for flag.
+ * data:	   the value want to set
+ *
+ * Return value:   On success return 0
+ *		   On failure return the errno.
+ */
+int gpio_sets(const char *device_name, unsigned int *lines, unsigned int nlines,
+	      unsigned int flag, struct gpiohandle_data *data);
+
+/*
+ * set the flag for device_name. Mainly for changing the direction of gpio
+ *
+ * device_name: the name of gpiochip in "/dev", such as gpiochip0.
+ * line:        number of line, such as 2.
+ * flag:        input, output and so on. Reference "linux/gpio.h" for the
+ *              meaning for flag.
+ *
+ * Return value:   On success return 0
+ *		   On failure return the errno.
+ */
+int gpio_set_flag(const char *device_name, unsigned int line,
+		  unsigned int flag);
+
 #endif /* _GPIO_UTILS_H_ */
-- 
1.8.4.5

--
To unsubscribe from this list: send the line "unsubscribe linux-gpio" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux SPI]     [Linux Kernel]     [Linux ARM (vger)]     [Linux ARM MSM]     [Linux Omap]     [Linux Arm]     [Linux Tegra]     [Fedora ARM]     [Linux for Samsung SOC]     [eCos]     [Linux Fastboot]     [Gcc Help]     [Git]     [DCCP]     [IETF Announce]     [Security]     [Linux MIPS]     [Yosemite Campsites]

  Powered by Linux