From: lakshmi.sowjanya.d@intel.com
To: linus.walleij@linaro.org
Cc: linux-gpio@vger.kernel.org, bgolaszewski@baylibre.com,
linux-kernel@vger.kernel.org, mgross@linux.intel.com,
andriy.shevchenko@linux.intel.com, tamal.saha@intel.com,
bala.senthil@intel.com, lakshmi.sowjanya.d@intel.com
Subject: [RFC PATCH v1 10/20] tools: gpio: Add GPIO output generation user application
Date: Tue, 24 Aug 2021 22:17:51 +0530 [thread overview]
Message-ID: <20210824164801.28896-11-lakshmi.sowjanya.d@intel.com> (raw)
In-Reply-To: <20210824164801.28896-1-lakshmi.sowjanya.d@intel.com>
From: Christopher Hall <christopher.s.hall@intel.com>
Add GPIO user application - gpio_event_gen - to generate output using
output methods added to GPIO lib. The output produced is 1 Hz clock
aligned to the system clock using singly scheduled edges.
gpio_event_gen accepts similar arguments to gpio-event-mon.
Example output:
$ gpio-event-gen -n gpiochip0 -o 0 -c 3
Generating events on line 0 on gpiochip1
clock realtime : 1612453529996832765
GPIO EVENT TRIGGER: 1612453531000000000
clock realtime 2 2 : 1612453531500000000
GPIO EVENT TRIGGER: 1612453531500000000
clock realtime 2 2 : 1612453532000000000
GPIO EVENT TRIGGER: 1612453532000000000
clock realtime 2 2 : 1612453532500000000
Produces 3 events of 1 Hz output on line 0 of chip/device 0.
Signed-off-by: Christopher Hall <christopher.s.hall@intel.com>
Signed-off-by: Tamal Saha <tamal.saha@intel.com>
Co-developed-by: Lakshmi Sowjanya D <lakshmi.sowjanya.d@intel.com>
Signed-off-by: Lakshmi Sowjanya D <lakshmi.sowjanya.d@intel.com>
Reviewed-by: Mark Gross <mgross@linux.intel.com>
---
tools/gpio/.gitignore | 1 +
tools/gpio/Build | 1 +
tools/gpio/Makefile | 11 ++-
tools/gpio/gpio-event-gen.c | 191 ++++++++++++++++++++++++++++++++++++
4 files changed, 203 insertions(+), 1 deletion(-)
create mode 100644 tools/gpio/gpio-event-gen.c
diff --git a/tools/gpio/.gitignore b/tools/gpio/.gitignore
index a00d604027a2..d5685cd0eb51 100644
--- a/tools/gpio/.gitignore
+++ b/tools/gpio/.gitignore
@@ -1,5 +1,6 @@
# SPDX-License-Identifier: GPL-2.0-only
gpio-event-mon
+gpio-event-gen
gpio-hammer
gpio-watch
lsgpio
diff --git a/tools/gpio/Build b/tools/gpio/Build
index 67c7b7f6a717..dc6a178c195a 100644
--- a/tools/gpio/Build
+++ b/tools/gpio/Build
@@ -2,4 +2,5 @@ gpio-utils-y += gpio-utils.o
lsgpio-y += lsgpio.o gpio-utils.o
gpio-hammer-y += gpio-hammer.o gpio-utils.o
gpio-event-mon-y += gpio-event-mon.o gpio-utils.o
+gpio-event-gen-y += gpio-event-gen.o gpio-utils.o
gpio-watch-y += gpio-watch.o
diff --git a/tools/gpio/Makefile b/tools/gpio/Makefile
index 440434027557..c9efaee76f28 100644
--- a/tools/gpio/Makefile
+++ b/tools/gpio/Makefile
@@ -18,7 +18,7 @@ MAKEFLAGS += -r
override CFLAGS += -O2 -Wall -g -D_GNU_SOURCE -I$(OUTPUT)include
-ALL_TARGETS := lsgpio gpio-hammer gpio-event-mon gpio-watch
+ALL_TARGETS := lsgpio gpio-hammer gpio-event-mon gpio-event-gen gpio-watch
ALL_PROGRAMS := $(patsubst %,$(OUTPUT)%,$(ALL_TARGETS))
all: $(ALL_PROGRAMS)
@@ -66,6 +66,15 @@ $(GPIO_EVENT_MON_IN): prepare FORCE $(OUTPUT)gpio-utils-in.o
$(OUTPUT)gpio-event-mon: $(GPIO_EVENT_MON_IN)
$(QUIET_LINK)$(CC) $(CFLAGS) $(LDFLAGS) $< -o $@
+#
+# gpio-event-gen
+#
+GPIO_EVENT_GEN_IN := $(OUTPUT)gpio-event-gen-in.o
+$(GPIO_EVENT_GEN_IN): prepare FORCE $(OUTPUT)gpio-utils-in.o
+ $(Q)$(MAKE) $(build)=gpio-event-gen
+$(OUTPUT)gpio-event-gen: $(GPIO_EVENT_GEN_IN)
+ $(QUIET_LINK)$(CC) $(CFLAGS) $(LDFLAGS) $< -o $@
+
#
# gpio-watch
#
diff --git a/tools/gpio/gpio-event-gen.c b/tools/gpio/gpio-event-gen.c
new file mode 100644
index 000000000000..3d5ef47d79d0
--- /dev/null
+++ b/tools/gpio/gpio-event-gen.c
@@ -0,0 +1,191 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * gpio-event-gen - generate GPIO line events from userspace
+ *
+ * Copyright (C) 2020 Intel Corporation
+ * Author: Christopher S Hall <christopher.s.hall@intel.com>
+ *
+ * Adapted from gpio-event-mon.c
+ * Copyright (C) 2016 Linus Walleij
+ *
+ * Usage:
+ * gpio-event-gen -n <device-name> -o <offset>
+ */
+
+#include <dirent.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <getopt.h>
+#include <inttypes.h>
+#include <linux/gpio.h>
+#include <poll.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <time.h>
+#include <unistd.h>
+
+#define NSEC_PER_SEC (1000000000ULL)
+#define TIMESPEC_TO_U64(x) (((uint64_t)(x).tv_sec) * NSEC_PER_SEC + (x).tv_nsec)
+#define U64_TO_TIMESPEC(x) \
+ ((struct timespec){ .tv_sec = (x) / NSEC_PER_SEC, \
+ .tv_nsec = (x) % NSEC_PER_SEC})
+
+int sleep_until(uint64_t systime)
+{
+ struct timespec wait_until;
+
+ wait_until = U64_TO_TIMESPEC(systime);
+ return clock_nanosleep(CLOCK_REALTIME, TIMER_ABSTIME, &wait_until, NULL);
+}
+
+int generate_events(const char *device_name,
+ unsigned int line[],
+ unsigned int num_lines,
+ uint32_t flags,
+ unsigned int loops)
+{
+ struct gpio_v2_line_request req;
+ struct gpio_v2_line_config config;
+ uint64_t trigger_time;
+ struct timespec now;
+ char *chrdev_name;
+ int ret, fd;
+ int i = 0;
+
+ 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;
+ }
+
+ memset(&config, 0, sizeof(config));
+ config.flags = flags;
+
+ memset(&req, 0, sizeof(req));
+
+ for (i = 0; i < num_lines; i++)
+ req.offsets[i] = line[i];
+ req.num_lines = num_lines;
+
+ req.config = config;
+ strcpy(req.consumer, "gpio-event-gen");
+
+ ret = ioctl(fd, GPIO_V2_GET_LINE_IOCTL, &req);
+ if (ret == -1) {
+ ret = -errno;
+ fprintf(stderr, "Failed to issue GET EVENT IOCTL (%d)\n", ret);
+ goto exit_close_error;
+ }
+
+ if (req.num_lines == 1) {
+ fprintf(stdout, "Generating events on line %u on %s\n",
+ line[0], device_name);
+ } else {
+ fprintf(stdout, "Generating events on %s for line %u",
+ device_name, line[0]);
+ for (i = 1; i < num_lines; i++)
+ fprintf(stdout, " line %u", line[i]);
+ }
+
+ clock_gettime(CLOCK_REALTIME, &now);
+ trigger_time = TIMESPEC_TO_U64(now);
+ trigger_time -= trigger_time % NSEC_PER_SEC;
+ trigger_time += 2 * NSEC_PER_SEC;
+ i = 0;
+ while (1) {
+ struct gpio_output_event out_event;
+
+ out_event.timestamp = trigger_time;
+ printf("GPIO EVENT TRIGGER: %llu\n", trigger_time);
+ ret = write(req.fd, &out_event, sizeof(out_event));
+ if (ret == -1) {
+ ret = -errno;
+ fprintf(stderr, "Failed to write event spec(%s)\n",
+ strerror(-ret));
+ break;
+ }
+
+ if (ret != sizeof(out_event)) {
+ fprintf(stderr, "Writing event spec failed\n");
+ ret = -EIO;
+ break;
+ }
+
+ sleep_until(trigger_time + NSEC_PER_SEC / 10);
+ trigger_time += NSEC_PER_SEC / 2;
+
+ i++;
+ if (i == loops)
+ break;
+ }
+
+exit_close_error:
+ if (close(fd) == -1)
+ perror("Failed to close GPIO character device file");
+ free(chrdev_name);
+ return ret;
+}
+
+void print_usage(void)
+{
+ fprintf(stderr, "Usage: gpio-event-gen [options]...;"
+ "Listen to events on GPIO lines, 0->1 1->0;"
+ " -n <name> Listen on GPIOs on a named device;"
+ "(must be stated);"
+ " -o <n> Offset to monitor;"
+ " [-c <n>] Do <n> loops;"
+ "(optional, infinite loop if not stated);"
+ " -? This helptext;"
+ "Example: gpio-event-gen -n gpiochip0 -o 0"
+ );
+}
+
+int main(int argc, char **argv)
+{
+ uint32_t flags = GPIO_V2_LINE_FLAG_OUTPUT;
+ const char *device_name = NULL;
+ unsigned int lines[GPIO_V2_LINES_MAX];
+ unsigned int loops = 0;
+ int num_lines = 0;
+ int c;
+
+ while ((c = getopt(argc, argv, "c:n:o:dsrf?")) != -1) {
+ switch (c) {
+ case 'c':
+ loops = strtoul(optarg, NULL, 10);
+ break;
+ case 'n':
+ device_name = optarg;
+ break;
+ case 'o':
+ if (num_lines >= GPIO_V2_LINES_MAX) {
+ print_usage();
+ return -1;
+ }
+ lines[num_lines] = strtoul(optarg, NULL, 10);
+ num_lines++;
+ break;
+ case '?':
+ print_usage();
+ return -1;
+ }
+ }
+
+ if (!device_name || num_lines == -1) {
+ print_usage();
+ return -1;
+ }
+
+ return generate_events(device_name, lines, num_lines,
+ flags, loops);
+}
--
2.17.1
next prev parent reply other threads:[~2021-08-24 16:48 UTC|newest]
Thread overview: 35+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-08-24 16:47 [RFC PATCH v1 00/20] Review Request: Add support for Intel PMC lakshmi.sowjanya.d
2021-08-24 16:47 ` [RFC PATCH v1 01/20] gpio: Add basic GPIO driver for Intel PMC Timed I/O device lakshmi.sowjanya.d
2021-08-24 16:47 ` [RFC PATCH v1 02/20] gpio: Add GPIO polling interface to GPIO lib lakshmi.sowjanya.d
2021-09-22 10:03 ` Bartosz Golaszewski
2021-10-07 2:14 ` Kent Gibson
2021-08-24 16:47 ` [RFC PATCH v1 03/20] arch: x86: Add ART support function to tsc code lakshmi.sowjanya.d
2021-08-24 16:47 ` [RFC PATCH v1 04/20] gpio: Add input code to Intel PMC Timed I/O Driver lakshmi.sowjanya.d
2021-08-24 16:47 ` [RFC PATCH v1 05/20] tools: gpio: Add additional polling support to gpio-event-mon lakshmi.sowjanya.d
2021-08-24 16:47 ` [RFC PATCH v1 06/20] gpio: Add set_input and polling interface to GPIO lib code lakshmi.sowjanya.d
2021-08-24 16:47 ` [RFC PATCH v1 07/20] gpio: Add output event generation method to GPIOLIB and PMC Driver lakshmi.sowjanya.d
2021-09-16 21:42 ` Linus Walleij
2021-09-17 7:27 ` Uwe Kleine-König
2021-09-19 19:38 ` Linus Walleij
2021-09-19 21:21 ` Clemens Gruber
2021-09-20 7:14 ` Uwe Kleine-König
2021-08-24 16:47 ` [RFC PATCH v1 08/20] kernel: time: Add system time to system counter translation lakshmi.sowjanya.d
2021-09-16 21:48 ` Linus Walleij
2021-08-24 16:47 ` [RFC PATCH v1 09/20] arch: x86: Add TSC to ART translation lakshmi.sowjanya.d
2021-08-24 16:47 ` lakshmi.sowjanya.d [this message]
2021-09-16 21:52 ` [RFC PATCH v1 10/20] tools: gpio: Add GPIO output generation user application Linus Walleij
2021-08-24 16:47 ` [RFC PATCH v1 11/20] gpio: Add event count interface to gpiolib lakshmi.sowjanya.d
2021-09-22 9:53 ` Bartosz Golaszewski
2021-08-24 16:47 ` [RFC PATCH v1 12/20] gpio: Add event count to Intel(R) PMC Timed I/O driver lakshmi.sowjanya.d
2021-08-24 16:47 ` [RFC PATCH v1 13/20] tools: gpio: Add event count capability to event monitor application lakshmi.sowjanya.d
2021-09-16 21:57 ` Linus Walleij
2021-08-24 16:47 ` [RFC PATCH v1 14/20] arch/x86: Add ART nanosecond to ART conversion lakshmi.sowjanya.d
2021-08-24 16:47 ` [RFC PATCH v1 15/20] pwm: Add capability for PWM Driver managed state lakshmi.sowjanya.d
2021-09-16 22:00 ` Linus Walleij
2021-08-24 16:47 ` [RFC PATCH v1 16/20] gpio: Add PWM capabilities to Intel(R) PMC TIO driver lakshmi.sowjanya.d
2021-08-24 16:47 ` [RFC PATCH v1 17/20] pwm: Add second alignment to the core PWM interface lakshmi.sowjanya.d
2021-08-24 16:47 ` [RFC PATCH v1 18/20] gpio: Add PWM alignment support to the Intel(R) PMC Timed I/O driver lakshmi.sowjanya.d
2021-08-24 16:48 ` [RFC PATCH v1 19/20] gpio: Add GPIO monitor line to Intel(R) Timed I/O Driver lakshmi.sowjanya.d
2021-08-24 16:48 ` [RFC PATCH v1 20/20] tools: gpio: Add PWM monitor application lakshmi.sowjanya.d
2021-09-16 21:21 ` [RFC PATCH v1 00/20] Review Request: Add support for Intel PMC Linus Walleij
2021-10-11 21:14 ` Dipen Patel
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20210824164801.28896-11-lakshmi.sowjanya.d@intel.com \
--to=lakshmi.sowjanya.d@intel.com \
--cc=andriy.shevchenko@linux.intel.com \
--cc=bala.senthil@intel.com \
--cc=bgolaszewski@baylibre.com \
--cc=linus.walleij@linaro.org \
--cc=linux-gpio@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mgross@linux.intel.com \
--cc=tamal.saha@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).