LIRC stands for Linux Infrared Remote Control. The LIRC device interface is a bi-directional interface for transporting raw IR and decoded scancodes data between userspace and kernelspace. Fundamentally, it is just a chardev (/dev/lircX, for X = 0, 1, 2, ...), with a number of standard struct file_operations defined on it. With respect to transporting raw IR and decoded scancodes to and fro, the essential fops are read, write and ioctl.
Example dmesg output upon a driver registering w/LIRC:
$ dmesg |grep lirc_dev rc rc0: lirc_dev: driver mceusb registered at minor = 0, raw IR receiver, raw IR transmitter
What you should see for a chardev:
$ ls -l /dev/lirc* crw-rw---- 1 root root 248, 0 Jul 2 22:20 /dev/lirc0
5.2. LIRC modes¶
LIRC supports some modes of receiving and sending IR codes, as shown on the following table.
This mode is for both sending and receiving IR.
For transmitting (aka sending), create a
struct lirc_scancodewith the desired scancode set in the
rc_protoset the IR protocol, and all other members set to 0. Write this struct to the lirc device.
For receiving, you read
struct lirc_scancodefrom the lirc device, with
scancodeset to the received scancode and the IR protocol
rc_proto. If the scancode maps to a valid key code, this is set in the
keycodefield, else it is set to
LIRC_SCANCODE_FLAG_TOGGLEset if the toggle bit is set in protocols that support it (e.g. rc-5 and rc-6), or
LIRC_SCANCODE_FLAG_REPEATfor when a repeat is received for protocols that support it (e.g. nec).
In the Sanyo and NEC protocol, if you hold a button on remote, rather than repeating the entire scancode, the remote sends a shorter message with no scancode, which just means button is held, a “repeat”. When this is received, the
LIRC_SCANCODE_FLAG_REPEATis set and the scancode and keycode is repeated.
With nec, there is no way to distinguish “button hold” from “repeatedly pressing the same button”. The rc-5 and rc-6 protocols have a toggle bit. When a button is released and pressed again, the toggle bit is inverted. If the toggle bit is set, the
timestampfield is filled with the time nanoseconds (in
CLOCK_MONOTONIC) when the scancode was decoded.
The driver returns a sequence of pulse and space codes to userspace, as a series of u32 values.
This mode is used only for IR receive.
The upper 8 bits determine the packet type, and the lower 24 bits the payload. Use
LIRC_VALUE()macro to get the payload, and the macro
LIRC_MODE2()will give you the type, which is one of:
LIRC_MODE2_PULSESignifies the presence of IR in microseconds.
LIRC_MODE2_SPACESignifies absence of IR in microseconds.
LIRC_MODE2_FREQUENCYIf measurement of the carrier frequency was enabled with ioctl LIRC_SET_MEASURE_CARRIER_MODE then this packet gives you the carrier frequency in Hertz.
LIRC_MODE2_TIMEOUTIf timeout reports are enabled with ioctl LIRC_SET_REC_TIMEOUT_REPORTS, when the timeout set with ioctl LIRC_GET_REC_TIMEOUT and LIRC_SET_REC_TIMEOUT expires due to no IR being detected, this packet will be sent, with the number of microseconds with no IR.
In pulse mode, a sequence of pulse/space integer values are written to the lirc device using LIRC write().
The values are alternating pulse and space lengths, in microseconds. The first and last entry must be a pulse, so there must be an odd number of entries.
This mode is used only for IR send.
5.3. Remote Controller protocol¶
rc_proto in the LIRC Header File lists all the
supported IR protocols:
the Remote Controller protocol
- Protocol not known
- Protocol known but proprietary
- Philips RC5 protocol
- Philips RC5x 20 bit protocol
- StreamZap variant of RC5
- JVC protocol
- Sony 12 bit protocol
- Sony 15 bit protocol
- Sony 20 bit protocol
- NEC protocol
- Extended NEC protocol
- NEC 32 bit protocol
- Sanyo protocol
- RC6-ish MCE keyboard
- RC6-ish MCE mouse
- Philips RC6-0-16 protocol
- Philips RC6-6A-20 protocol
- Philips RC6-6A-24 protocol
- Philips RC6-6A-32 protocol
- MCE (Philips RC6-6A-32 subtype) protocol
- Sharp protocol
- XMP protocol
- CEC protocol
- iMon Pad protocol