From: Sean Young <sean@mess.org>
To: linux-media@vger.kernel.org
Cc: linux-api@vger.kernel.org
Subject: [PATCH] [media] lirc: introduce LIRC_SET_POLL_MODE
Date: Mon, 6 Mar 2017 16:16:04 +0000 [thread overview]
Message-ID: <20170306161604.GA19637@gofer.mess.org> (raw)
In-Reply-To: <20170302133116.GA29616@gofer.mess.org>
If you want to poll for both decoded scancodes and raw IR, then this
ioctl will help you.
int fd = open("/dev/lirc0", O_RDONLY | O_NONBLOCK);
for (;;) {
unsigned mode = LIRC_MODE_SCANCODE | LIRC_MODE_MODE2;
ioctl(fd, LIRC_SET_POLL_MODE, &mode);
poll(&((struct pollfd){ .fd = fd, .events = POLLIN }), 1, -1);
mode = LIRC_MODE_SCANCODE;
ioctl(fd, LIRC_SET_REC_MODE, &mode);
struct lirc_scancode sc;
if (read(fd, &sc, sizeof(sc)) == sizeof(sc)) {
printf("scancode protocol:%d scancode:%llx\n",
sc.rc_type, sc.scancode);
}
mode = LIRC_MODE_MODE2;
ioctl(fd, LIRC_SET_REC_MODE, &mode);
unsigned sample;
if (read(fd, &sample, sizeof(sample)) == sizeof(sample)) {
if (LIRC_IS_SPACE(sample))
printf("space %u\n", LIRC_VAL(sample)));
if (LIRC_IS_PULSE(sample))
printf("pulse %u\n", LIRC_VAL(sample)));
}
}
Note that LIRC_SET_REC_MODE will also affect the poll mode, so you
must set it again before calling poll.
Signed-off-by: Sean Young <sean@mess.org>
---
Documentation/media/uapi/rc/lirc-func.rst | 1 +
Documentation/media/uapi/rc/lirc-set-poll-mode.rst | 44 ++++++++++++++++++++++
drivers/media/rc/ir-lirc-codec.c | 29 ++++++++++++--
drivers/media/rc/rc-core-priv.h | 1 +
include/uapi/linux/lirc.h | 9 +++++
5 files changed, 80 insertions(+), 4 deletions(-)
create mode 100644 Documentation/media/uapi/rc/lirc-set-poll-mode.rst
diff --git a/Documentation/media/uapi/rc/lirc-func.rst b/Documentation/media/uapi/rc/lirc-func.rst
index 9b5a772..3ae92af 100644
--- a/Documentation/media/uapi/rc/lirc-func.rst
+++ b/Documentation/media/uapi/rc/lirc-func.rst
@@ -26,3 +26,4 @@ LIRC Function Reference
lirc-set-rec-timeout-reports
lirc-set-measure-carrier-mode
lirc-set-wideband-receiver
+ lirc-set-poll-mode
diff --git a/Documentation/media/uapi/rc/lirc-set-poll-mode.rst b/Documentation/media/uapi/rc/lirc-set-poll-mode.rst
new file mode 100644
index 0000000..56112bb
--- /dev/null
+++ b/Documentation/media/uapi/rc/lirc-set-poll-mode.rst
@@ -0,0 +1,44 @@
+.. -*- coding: utf-8; mode: rst -*-
+
+.. _lirc_set_poll_mode:
+
+**********************************************
+ioctls LIRC_SET_POLL_MODE
+**********************************************
+
+Name
+====
+
+LIRC_SET_POLL_MODE - Set poll modes
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, LIRC_SET_POLL_MODE, __u32 modes)
+ :name: LIRC_SET_POLL_MODE
+
+Arguments
+=========
+
+``fd``
+ File descriptor returned by open().
+
+``modes``
+ Bitmask with enabled poll lirc modes
+
+Description
+===========
+
+Set lirc modes for which read readiness is reported by poll. Only
+:ref:`LIRC_MODE_MODE2 <lirc-mode-mode2>` and
+:ref:`LIRC_MODE_SCANCODE <lirc-mode-scancode>` are supported.
+Use :ref:`lirc_get_features` to find out which modes the driver supports.
+
+Note that using :ref:`lirc-set-rec-mode` resets the poll mode.
+
+Return Value
+============
+
+On success 0 is returned, on error -1 and the ``errno`` variable is set
+appropriately. The generic error codes are described at the
+:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/drivers/media/rc/ir-lirc-codec.c b/drivers/media/rc/ir-lirc-codec.c
index 960703a..a2a2229 100644
--- a/drivers/media/rc/ir-lirc-codec.c
+++ b/drivers/media/rc/ir-lirc-codec.c
@@ -258,6 +258,24 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int cmd,
}
lirc->rec_mode = val;
+ lirc->poll_mode = val;
+ return 0;
+
+ case LIRC_SET_POLL_MODE:
+ switch (dev->driver_type) {
+ case RC_DRIVER_SCANCODE:
+ if (val != LIRC_MODE_SCANCODE)
+ return -EINVAL;
+ break;
+ case RC_DRIVER_IR_RAW:
+ if (val & ~(LIRC_MODE_SCANCODE | LIRC_MODE_MODE2))
+ return -EINVAL;
+ break;
+ default:
+ return -ENOTTY;
+ }
+
+ lirc->poll_mode = val;
return 0;
case LIRC_GET_SEND_MODE:
@@ -396,11 +414,12 @@ static unsigned int ir_lirc_poll(struct file *filep,
if (!lirc->drv.attached) {
events = POLLHUP;
- } else if (lirc->rec_mode == LIRC_MODE_SCANCODE) {
- if (!kfifo_is_empty(&lirc->scancodes))
+ } else {
+ if ((lirc->poll_mode & LIRC_MODE_SCANCODE) &&
+ !kfifo_is_empty(&lirc->scancodes))
events = POLLIN | POLLRDNORM;
- } else if (lirc->rec_mode == LIRC_MODE_MODE2) {
- if (!kfifo_is_empty(&lirc->rawir))
+ if ((lirc->poll_mode & LIRC_MODE_MODE2) &&
+ !kfifo_is_empty(&lirc->rawir))
events = POLLIN | POLLRDNORM;
}
@@ -512,11 +531,13 @@ int ir_lirc_register(struct rc_dev *dev)
if (dev->driver_type == RC_DRIVER_SCANCODE) {
features |= LIRC_CAN_REC_SCANCODE;
+ node->poll_mode = LIRC_MODE_SCANCODE;
node->rec_mode = LIRC_MODE_SCANCODE;
} else if (dev->driver_type == RC_DRIVER_IR_RAW) {
features |= LIRC_CAN_REC_MODE2 | LIRC_CAN_REC_SCANCODE;
if (dev->rx_resolution)
features |= LIRC_CAN_GET_REC_RESOLUTION;
+ node->poll_mode = LIRC_MODE_MODE2;
node->rec_mode = LIRC_MODE_MODE2;
}
if (dev->tx_ir) {
diff --git a/drivers/media/rc/rc-core-priv.h b/drivers/media/rc/rc-core-priv.h
index b73222a..d630009 100644
--- a/drivers/media/rc/rc-core-priv.h
+++ b/drivers/media/rc/rc-core-priv.h
@@ -51,6 +51,7 @@ struct lirc_node {
u64 gap_duration;
bool gap;
bool send_timeout_reports;
+ int poll_mode;
int send_mode;
int rec_mode;
};
diff --git a/include/uapi/linux/lirc.h b/include/uapi/linux/lirc.h
index d04fc62..70e8a71 100644
--- a/include/uapi/linux/lirc.h
+++ b/include/uapi/linux/lirc.h
@@ -134,6 +134,15 @@
#define LIRC_SET_WIDEBAND_RECEIVER _IOW('i', 0x00000023, __u32)
/*
+ * For raw IR devices, both raw IR (LIRC_MODE_MODE2) and decodes scancodes
+ * (LIRC_MODE_SCANCODE) can be read. By default, poll will show read
+ * ready for the last mode set by LIRC_SET_REC_MODE. Use LIRC_SET_POLL_MODE
+ * LIRC_MODE_SCANCODE | LIRC_MODE_MODE2 to show read ready for both
+ * modes.
+ */
+#define LIRC_SET_POLL_MODE _IOW('i', 0x00000024, __u32)
+
+/*
* struct lirc_scancode - decoded scancodes with protocol
* @timestamp: Timestamp in nanoseconds using CLOCK_MONOTONIC when IR
* was decoded.
--
2.9.3
next prev parent reply other threads:[~2017-03-06 16:16 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-02-25 11:51 [PATCH v3 00/19] Teach lirc how to send and receive scancodes Sean Young
2017-02-25 11:51 ` [PATCH v3 01/19] [media] lirc: document lirc modes better Sean Young
2017-02-25 11:51 ` [PATCH v3 02/19] [media] lirc: return ENOTTY when ioctl is not supported Sean Young
2017-02-25 11:51 ` [PATCH v3 03/19] [media] lirc: return ENOTTY when device does support ioctl Sean Young
2017-02-25 11:51 ` [PATCH v3 04/19] [media] winbond: allow timeout to be set Sean Young
2017-02-25 11:51 ` [PATCH v3 05/19] [media] gpio-ir: do not allow a timeout of 0 Sean Young
2017-02-25 11:51 ` [PATCH v3 06/19] [media] rc: lirc keymap no longer makes any sense Sean Young
2017-02-25 11:51 ` [PATCH v3 07/19] [media] lirc: advertise LIRC_CAN_GET_REC_RESOLUTION and improve Sean Young
2017-02-25 11:51 ` [PATCH v3 08/19] [media] mce_kbd: add encoder Sean Young
2017-02-25 11:51 ` [PATCH v3 09/19] [media] serial_ir: iommap is a memory address, not bool Sean Young
2017-02-25 11:51 ` [PATCH v3 10/19] [media] lirc: use refcounting for lirc devices Sean Young
2017-02-25 11:51 ` [PATCH v3 11/19] [media] lirc: lirc interface should not be a raw decoder Sean Young
2017-02-25 11:51 ` [PATCH v3 12/19] [media] lirc: exorcise struct irctl Sean Young
2017-02-25 11:51 ` [PATCH v3 13/19] [media] lirc: use plain kfifo rather than lirc_buffer Sean Young
2017-02-25 11:51 ` [PATCH v3 14/19] [media] lirc: implement scancode sending Sean Young
2017-02-25 11:51 ` [PATCH v3 15/19] [media] rc: use the correct carrier for scancode transmit Sean Young
2017-02-25 11:51 ` [PATCH v3 16/19] [media] rc: auto load encoder if necessary Sean Young
2017-02-25 11:51 ` [PATCH v3 17/19] [media] lirc: implement reading scancode Sean Young
[not found] ` <b9722d41efc7dd75ddbab78a62f654aa56d9a0a3.1488023302.git.sean-hENCXIMQXOg@public.gmane.org>
2017-03-02 13:31 ` Sean Young
2017-03-02 13:31 ` Sean Young
2017-03-06 16:16 ` Sean Young [this message]
2017-02-25 11:51 ` [PATCH v3 18/19] [media] lirc: scancode rc devices should have a lirc device too Sean Young
2017-02-25 11:51 ` [PATCH v3 19/19] [media] lirc: document LIRC_MODE_SCANCODE Sean Young
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=20170306161604.GA19637@gofer.mess.org \
--to=sean@mess.org \
--cc=linux-api@vger.kernel.org \
--cc=linux-media@vger.kernel.org \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.