lirc transmit waits for the IR to complete, since existing versions
of lircd (prior to 0.9.4) rely on this. Allows this to be configurable
if this is not desirable.

Signed-off-by: Sean Young <s...@mess.org>
---
 Documentation/media/uapi/rc/lirc-func.rst          |  1 +
 .../media/uapi/rc/lirc-set-transmitter-wait.rst    | 46 ++++++++++++++++++++++
 Documentation/media/uapi/rc/lirc-write.rst         |  6 ++-
 drivers/media/rc/ir-lirc-codec.c                   | 29 +++++++++-----
 drivers/media/rc/rc-core-priv.h                    |  2 +-
 include/uapi/linux/lirc.h                          |  5 +++
 6 files changed, 76 insertions(+), 13 deletions(-)
 create mode 100644 Documentation/media/uapi/rc/lirc-set-transmitter-wait.rst

diff --git a/Documentation/media/uapi/rc/lirc-func.rst 
b/Documentation/media/uapi/rc/lirc-func.rst
index 9b5a772..be02ca2 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-transmitter-wait
diff --git a/Documentation/media/uapi/rc/lirc-set-transmitter-wait.rst 
b/Documentation/media/uapi/rc/lirc-set-transmitter-wait.rst
new file mode 100644
index 0000000..37835ad
--- /dev/null
+++ b/Documentation/media/uapi/rc/lirc-set-transmitter-wait.rst
@@ -0,0 +1,46 @@
+.. -*- coding: utf-8; mode: rst -*-
+
+.. _lirc_set_transmitter_mask:
+
+*******************************
+ioctl LIRC_SET_TRANSMITTER_WAIT
+*******************************
+
+Name
+====
+
+LIRC_SET_TRANSMITTER_WAIT - Wait for IR to transmit
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, LIRC_SET_TRANSMITTER_WAIT, __u32 *enable )
+    :name: LIRC_SET_TRANSMITTER_WAIT
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by open().
+
+``enable``
+    enable = 1 means wait for IR to transmit before write() returns,
+    enable = 0 means return as soon as the driver has sent the commmand
+    to the hardware.
+
+
+Description
+===========
+
+Early lirc drivers would only return from write() when the IR had been
+transmitted and the lirc daemon relies on this for calculating when to
+send the next IR signal. Some drivers (e.g. usb drivers) can return
+earlier than that.
+
+
+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/Documentation/media/uapi/rc/lirc-write.rst 
b/Documentation/media/uapi/rc/lirc-write.rst
index 3b035c6..32c2152 100644
--- a/Documentation/media/uapi/rc/lirc-write.rst
+++ b/Documentation/media/uapi/rc/lirc-write.rst
@@ -46,8 +46,10 @@ The data written to the chardev is a pulse/space sequence of 
integer
 values. Pulses and spaces are only marked implicitly by their position.
 The data must start and end with a pulse, therefore, the data must
 always include an uneven number of samples. The write function must
-block until the data has been transmitted by the hardware. If more data
-is provided than the hardware can send, the driver returns ``EINVAL``.
+block until the data has been transmitted by the hardware, unless
+:ref:`LIRC_SET_TRANSMITTER_WAIT <LIRC_SET_TRANSMITTER_WAIT>` has been
+disabled. If more data is provided than the hardware can send, the driver
+returns ``EINVAL``.
 
 
 Return Value
diff --git a/drivers/media/rc/ir-lirc-codec.c b/drivers/media/rc/ir-lirc-codec.c
index c327730..110e501 100644
--- a/drivers/media/rc/ir-lirc-codec.c
+++ b/drivers/media/rc/ir-lirc-codec.c
@@ -161,17 +161,19 @@ static ssize_t ir_lirc_transmit_ir(struct file *file, 
const char __user *buf,
 
        ret *= sizeof(unsigned int);
 
-       /*
-        * The lircd gap calculation expects the write function to
-        * wait for the actual IR signal to be transmitted before
-        * returning.
-        */
-       towait = ktime_us_delta(ktime_add_us(start, duration), ktime_get());
-       if (towait > 0) {
-               set_current_state(TASK_INTERRUPTIBLE);
-               schedule_timeout(usecs_to_jiffies(towait));
+       if (!lirc->tx_no_wait) {
+               /*
+                * The lircd gap calculation expects the write function to
+                * wait for the actual IR signal to be transmitted before
+                * returning.
+                */
+               towait = ktime_us_delta(ktime_add_us(start, duration),
+                                                               ktime_get());
+               if (towait > 0) {
+                       set_current_state(TASK_INTERRUPTIBLE);
+                       schedule_timeout(usecs_to_jiffies(towait));
+               }
        }
-
 out:
        kfree(txbuf);
        return ret;
@@ -234,6 +236,13 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int 
cmd,
 
                return dev->s_tx_duty_cycle(dev, val);
 
+       case LIRC_SET_TRANSMITTER_WAIT:
+               if (!dev->tx_ir)
+                       return -ENOTTY;
+
+               lirc->tx_no_wait = !val;
+               break;
+
        /* RX settings */
        case LIRC_SET_REC_CARRIER:
                if (!dev->s_rx_carrier_range)
diff --git a/drivers/media/rc/rc-core-priv.h b/drivers/media/rc/rc-core-priv.h
index 585d5e5..0c0d2f2 100644
--- a/drivers/media/rc/rc-core-priv.h
+++ b/drivers/media/rc/rc-core-priv.h
@@ -112,7 +112,7 @@ struct ir_raw_event_ctrl {
                u64 gap_duration;
                bool gap;
                bool send_timeout_reports;
-
+               bool tx_no_wait;
        } lirc;
        struct xmp_dec {
                int state;
diff --git a/include/uapi/linux/lirc.h b/include/uapi/linux/lirc.h
index 991ab45..3874f21 100644
--- a/include/uapi/linux/lirc.h
+++ b/include/uapi/linux/lirc.h
@@ -130,4 +130,9 @@
 
 #define LIRC_SET_WIDEBAND_RECEIVER     _IOW('i', 0x00000023, __u32)
 
+/*
+ * Should the lirc driver wait until the IR has been transmitted.
+ */
+#define LIRC_SET_TRANSMITTER_WAIT      _IOW('i', 0x00000024, __u32)
+
 #endif
-- 
2.7.4

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

Reply via email to