4.Remote Controller devices

4.1.Remote Controller core

The remote controller core implements infrastructure to receive and sendremote controller keyboard keystrokes and mouse events.

Every time a key is pressed on a remote controller, a scan code is produced.Also, on most hardware, keeping a key pressed for more than a few dozens ofmilliseconds produce a repeat key event. That’s somewhat similar to whata normal keyboard or mouse is handled internally on Linux[1]. So, theremote controller core is implemented on the top of the linux input/evdevinterface.

[1]

The main difference is that, on keyboard events, the keyboard controllerproduces one event for a key press and another one for key release. Oninfrared-based remote controllers, there’s no key release event. Instead,an extra code is produced to indicate key repeats.

However, most of the remote controllers use infrared (IR) to transmit signals.As there are several protocols used to modulate infrared signals, oneimportant part of the core is dedicated to adjust the driver and the coresystem to support the infrared protocol used by the emitter.

The infrared transmission is done by blinking a infrared emitter using acarrier. The carrier can be switched on or off by the IR transmitterhardware. When the carrier is switched on, it is calledPULSE.When the carrier is switched off, it is calledSPACE.

In other words, a typical IR transmission can be viewed as a sequence ofPULSE andSPACE events, each with a given duration.

The carrier parameters (frequency, duty cycle) and the intervals forPULSE andSPACE events depend on the protocol.For example, the NEC protocol uses a carrier of 38kHz, and transmissionsstart with a 9msPULSE and a 4.5ms SPACE. It then transmits 16 bits ofscan code, being 8 bits for address (usually it is a fixed number for agiven remote controller), followed by 8 bits of code. A bit “1” is modulatedwith 560µsPULSE followed by 1690µsSPACE and a bit “0” is modulatedwith 560µsPULSE followed by 560µsSPACE.

At receiver, a simple low-pass filter can be used to convert the receivedsignal in a sequence ofPULSE/SPACE events, filtering out the carrierfrequency. Due to that, the receiver doesn’t care about the carrier’sactual frequency parameters: all it has to do is to measure the amountof time it receivesPULSE/SPACE events.So, a simple IR receiver hardware will just provide a sequence of timingsfor those events to the Kernel. The drivers for hardware with such kind ofreceivers are identified byRC_DRIVER_IR_RAW, as defined byrc_driver_type[2]. Other hardware come with amicrocontroller that decode thePULSE/SPACE sequence and return scancodes to the Kernel. Such kind of receivers are identifiedbyRC_DRIVER_SCANCODE.

[2]

The RC core also supports devices that have just IR emitters,without any receivers. Right now, all such devices work only inraw TX mode. Such kind of hardware is identified asRC_DRIVER_IR_RAW_TX.

When the RC core receives events produced byRC_DRIVER_IR_RAW IRreceivers, it needs to decode the IR protocol, in order to obtain thecorresponding scan code. The protocols supported by the RC core aredefined at enumrc_proto.

When the RC code receives a scan code (either directly, by a driverof the typeRC_DRIVER_SCANCODE, or via its IR decoders), it needsto convert into a Linux input event code. This is done via a mappingtable.

The Kernel has support for mapping tables available on most mediadevices. It also supports loading a table in runtime, via somesysfs nodes. See theRC userspace APIfor more details.

4.1.1.Remote controller data structures and functions

enumrc_driver_type

type of the RC driver.

Constants

RC_DRIVER_SCANCODE

Driver or hardware generates a scancode.

RC_DRIVER_IR_RAW

Driver or hardware generates pulse/space sequences.It needs a Infra-Red pulse/space decoder

RC_DRIVER_IR_RAW_TX

Device transmitter only,driver requires pulse/space data sequence.

structrc_scancode_filter

Filter scan codes.

Definition:

struct rc_scancode_filter {    u32 data;    u32 mask;};

Members

data

Scancode data to match.

mask

Mask of bits of scancode to compare.

enumrc_filter_type

Filter type constants.

Constants

RC_FILTER_NORMAL

Filter for normal operation.

RC_FILTER_WAKEUP

Filter for waking from suspend.

RC_FILTER_MAX

Number of filter types.

structlirc_fh

represents an open lirc file

Definition:

struct lirc_fh {    struct list_head list;    struct rc_dev *rc;    unsigned int *rawir;    struct lirc_scancode *scancodes;    wait_queue_head_t wait_poll;    u32 carrier_low;    u8 send_mode;    u8 rec_mode;};

Members

list

list of open file handles

rc

rcdev for this lirc chardev

rawir

queue for incoming raw IR

scancodes

queue for incoming decoded scancodes

wait_poll

poll struct for lirc device

carrier_low

when setting the carrier range, first the low end must beset with an ioctl and then the high end with another ioctl

send_mode

lirc mode for sending, either LIRC_MODE_SCANCODE orLIRC_MODE_PULSE

rec_mode

lirc mode for receiving, either LIRC_MODE_SCANCODE orLIRC_MODE_MODE2

structrc_dev

represents a remote control device

Definition:

struct rc_dev {    struct device                   dev;    bool managed_alloc;    bool registered;    bool idle;    bool encode_wakeup;    unsigned int                    minor;    const struct attribute_group    *sysfs_groups[5];    const char                      *device_name;    const char                      *input_phys;    struct input_id                 input_id;    const char                      *driver_name;    const char                      *map_name;    struct rc_map                   rc_map;    struct mutex                    lock;    struct ir_raw_event_ctrl        *raw;    struct input_dev                *input_dev;    enum rc_driver_type             driver_type;    u32 users;    u64 allowed_protocols;    u64 enabled_protocols;    u64 allowed_wakeup_protocols;    enum rc_proto                   wakeup_protocol;    struct rc_scancode_filter       scancode_filter;    struct rc_scancode_filter       scancode_wakeup_filter;    u32 scancode_mask;    void *priv;    spinlock_t keylock;    bool keypressed;    u8 last_toggle;    u32 last_keycode;    enum rc_proto                   last_protocol;    u64 last_scancode;    unsigned long                   keyup_jiffies;    struct timer_list               timer_keyup;    struct timer_list               timer_repeat;    u32 timeout;    u32 min_timeout;    u32 max_timeout;    u32 rx_resolution;#ifdef CONFIG_LIRC;    struct device                   lirc_dev;    struct cdev                     lirc_cdev;    ktime_t gap_start;    spinlock_t lirc_fh_lock;    struct list_head                lirc_fh;#endif;    int (*change_protocol)(struct rc_dev *dev, u64 *rc_proto);    int (*open)(struct rc_dev *dev);    void (*close)(struct rc_dev *dev);    int (*s_tx_mask)(struct rc_dev *dev, u32 mask);    int (*s_tx_carrier)(struct rc_dev *dev, u32 carrier);    int (*s_tx_duty_cycle)(struct rc_dev *dev, u32 duty_cycle);    int (*s_rx_carrier_range)(struct rc_dev *dev, u32 min, u32 max);    int (*tx_ir)(struct rc_dev *dev, unsigned *txbuf, unsigned n);    void (*s_idle)(struct rc_dev *dev, bool enable);    int (*s_wideband_receiver)(struct rc_dev *dev, int enable);    int (*s_carrier_report) (struct rc_dev *dev, int enable);    int (*s_filter)(struct rc_dev *dev, struct rc_scancode_filter *filter);    int (*s_wakeup_filter)(struct rc_dev *dev, struct rc_scancode_filter *filter);    int (*s_timeout)(struct rc_dev *dev, unsigned int timeout);};

Members

dev

driver model’s view of this device

managed_alloc

devm_rc_allocate_device was used to create rc_dev

registered

set to true byrc_register_device(), false byrc_unregister_device

idle

used to keep track of RX state

encode_wakeup

wakeup filtering uses IR encode API, therefore the allowedwakeup protocols is the set of all raw encoders

minor

unique minor remote control device number

sysfs_groups

sysfs attribute groups

device_name

name of the rc child device

input_phys

physical path to the input child device

input_id

id of the input child device (structinput_id)

driver_name

name of the hardware driver which registered this device

map_name

name of the default keymap

rc_map

current scan/key table

lock

used to ensure we’ve filled in all protocol details beforeanyone can call show_protocols or store_protocols

raw

additional data for raw pulse/space devices

input_dev

the input child device used to communicate events to userspace

driver_type

specifies if protocol decoding is done in hardware or software

users

number of current users of the device

allowed_protocols

bitmask with the supported RC_PROTO_BIT_* protocols

enabled_protocols

bitmask with the enabled RC_PROTO_BIT_* protocols

allowed_wakeup_protocols

bitmask with the supported RC_PROTO_BIT_* wakeupprotocols

wakeup_protocol

the enabled RC_PROTO_* wakeup protocol orRC_PROTO_UNKNOWN if disabled.

scancode_filter

scancode filter

scancode_wakeup_filter

scancode wakeup filters

scancode_mask

some hardware decoders are not capable of providing the fullscancode to the application. As this is a hardware limit, we can’t doanything with it. Yet, as the same keycode table can be used with otherdevices, a mask is provided to allow its usage. Drivers should generallyleave this field in blank

priv

driver-specific data

keylock

protects the remaining members of the struct

keypressed

whether a key is currently pressed

last_toggle

toggle value of last command

last_keycode

keycode of last keypress

last_protocol

protocol of last keypress

last_scancode

scancode of last keypress

keyup_jiffies

time (in jiffies) when the current keypress should be released

timer_keyup

timer for releasing a keypress

timer_repeat

timer for autorepeat events. This is needed for CEC, whichhas non-standard repeats.

timeout

optional time after which device stops sending data

min_timeout

minimum timeout supported by device

max_timeout

maximum timeout supported by device

rx_resolution

resolution (in us) of input sampler

lirc_dev

lirc device

lirc_cdev

lirc char cdev

gap_start

start time for gap after timeout if non-zero

lirc_fh_lock

protects lirc_fh list

lirc_fh

list of open files

change_protocol

allow changing the protocol used on hardware decoders

open

callback to allow drivers to enable polling/irq when IR input deviceis opened.

close

callback to allow drivers to disable polling/irq when IR input deviceis opened.

s_tx_mask

set transmitter mask (for devices with multiple tx outputs)

s_tx_carrier

set transmit carrier frequency

s_tx_duty_cycle

set transmit duty cycle (0% - 100%)

s_rx_carrier_range

inform driver about carrier it is expected to handle

tx_ir

transmit IR

s_idle

enable/disable hardware idle mode, upon which,device doesn’t interrupt host until it sees IR pulses

s_wideband_receiver

enable wide band receiver used for learning

s_carrier_report

enable carrier reports

s_filter

set the scancode filter

s_wakeup_filter

set the wakeup scancode filter. If the mask is zerothen wakeup should be disabled. wakeup_protocol will be set toa valid protocol if mask is nonzero.

s_timeout

set hardware timeout in us

structrc_dev*rc_allocate_device(enumrc_driver_type)

Allocates a RC device

Parameters

enumrc_driver_type

specifies the type of the RC output to be allocatedreturns a pointer tostructrc_dev.

structrc_dev*devm_rc_allocate_device(structdevice*dev,enumrc_driver_type)

Managed RC device allocation

Parameters

structdevice*dev

pointer tostructdevice

enumrc_driver_type

specifies the type of the RC output to be allocatedreturns a pointer tostructrc_dev.

voidrc_free_device(structrc_dev*dev)

Frees a RC device

Parameters

structrc_dev*dev

pointer tostructrc_dev.

intrc_register_device(structrc_dev*dev)

Registers a RC device

Parameters

structrc_dev*dev

pointer tostructrc_dev.

intdevm_rc_register_device(structdevice*parent,structrc_dev*dev)

Manageded registering of a RC device

Parameters

structdevice*parent

pointer tostructdevice.

structrc_dev*dev

pointer tostructrc_dev.

voidrc_unregister_device(structrc_dev*dev)

Unregisters a RC device

Parameters

structrc_dev*dev

pointer tostructrc_dev.

structrc_map_table

represents a scancode/keycode pair

Definition:

struct rc_map_table {    u64 scancode;    u32 keycode;};

Members

scancode

scan code (u64)

keycode

Linux input keycode

structrc_map

represents a keycode map table

Definition:

struct rc_map {    struct rc_map_table     *scan;    unsigned int            size;    unsigned int            len;    unsigned int            alloc;    enum rc_proto           rc_proto;    const char              *name;    spinlock_t lock;};

Members

scan

pointer to structrc_map_table

size

Max number of entries

len

Number of entries that are in use

alloc

size of *scan, in bytes

rc_proto

type of the remote controller protocol, as defined atenumrc_proto

name

name of the key map table

lock

lock to protect access to this structure

structrc_map_list

list of the registeredrc_map maps

Definition:

struct rc_map_list {    struct list_head         list;    struct rc_map map;};

Members

list

pointer to structlist_head

map

pointer to structrc_map

intrc_map_register(structrc_map_list*map)

Registers a Remote Controller scancode map

Parameters

structrc_map_list*map

pointer tostructrc_map_list

voidrc_map_unregister(structrc_map_list*map)

Unregisters a Remote Controller scancode map

Parameters

structrc_map_list*map

pointer tostructrc_map_list

structrc_map*rc_map_get(constchar*name)

gets an RC map from its name

Parameters

constchar*name

name of the RC scancode map