5.1. Introduction

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.

LIRC_MODE_SCANCODE

This mode is for both sending and receiving IR.

For transmitting (aka sending), create a struct lirc_scancode with the desired scancode set in the scancode member, rc_proto set the IR protocol, and all other members set to 0. Write this struct to the lirc device.

For receiving, you read struct lirc_scancode from the lirc device, with scancode set to the received scancode and the IR protocol rc_proto. If the scancode maps to a valid key code, this is set in the keycode field, else it is set to KEY_RESERVED.

The flags can have LIRC_SCANCODE_FLAG_TOGGLE set if the toggle bit is set in protocols that support it (e.g. rc-5 and rc-6), or LIRC_SCANCODE_FLAG_REPEAT for 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_REPEAT is 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 LIRC_SCANCODE_FLAG_TOGGLE is set.

The timestamp field is filled with the time nanoseconds (in CLOCK_MONOTONIC) when the scancode was decoded.

LIRC_MODE_MODE2

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_PULSE

Signifies the presence of IR in microseconds.

LIRC_MODE2_SPACE

Signifies absence of IR in microseconds.

LIRC_MODE2_FREQUENCY

If 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_TIMEOUT

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

LIRC_MODE_PULSE

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

An enum rc_proto in the LIRC Header File lists all the supported IR protocols:

enum rc_proto

the Remote Controller protocol

Constants

RC_PROTO_UNKNOWN
Protocol not known
RC_PROTO_OTHER
Protocol known but proprietary
RC_PROTO_RC5
Philips RC5 protocol
RC_PROTO_RC5X_20
Philips RC5x 20 bit protocol
RC_PROTO_RC5_SZ
StreamZap variant of RC5
RC_PROTO_JVC
JVC protocol
RC_PROTO_SONY12
Sony 12 bit protocol
RC_PROTO_SONY15
Sony 15 bit protocol
RC_PROTO_SONY20
Sony 20 bit protocol
RC_PROTO_NEC
NEC protocol
RC_PROTO_NECX
Extended NEC protocol
RC_PROTO_NEC32
NEC 32 bit protocol
RC_PROTO_SANYO
Sanyo protocol
RC_PROTO_MCIR2_KBD
RC6-ish MCE keyboard
RC_PROTO_MCIR2_MSE
RC6-ish MCE mouse
RC_PROTO_RC6_0
Philips RC6-0-16 protocol
RC_PROTO_RC6_6A_20
Philips RC6-6A-20 protocol
RC_PROTO_RC6_6A_24
Philips RC6-6A-24 protocol
RC_PROTO_RC6_6A_32
Philips RC6-6A-32 protocol
RC_PROTO_RC6_MCE
MCE (Philips RC6-6A-32 subtype) protocol
RC_PROTO_SHARP
Sharp protocol
RC_PROTO_XMP
XMP protocol
RC_PROTO_CEC
CEC protocol
RC_PROTO_IMON
iMon Pad protocol
RC_PROTO_RCMM12
RC-MM protocol 12 bits
RC_PROTO_RCMM24
RC-MM protocol 24 bits
RC_PROTO_RCMM32
RC-MM protocol 32 bits
RC_PROTO_XBOX_DVD
Xbox DVD Movie Playback Kit protocol