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