linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
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


  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).