3. Remote Controller devices¶
3.1. Remote Controller core¶
The remote controller core implements infrastructure to receive and send remote 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 of milliseconds produce a repeat key event. That’s somewhat similar to what a normal keyboard or mouse is handled internally on Linux[1]. So, the remote controller core is implemented on the top of the linux input/evdev interface.
[1] | The main difference is that, on keyboard events, the keyboard controller produces one event for a key press and another one for key release. On infrared-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, one important part of the core is dedicated to adjust the driver and the core system to support the infrared protocol used by the emitter.
The infrared transmission is done by blinking a infrared emitter using a carrier. The carrier can be switched on or off by the IR transmitter hardware. When the carrier is switched on, it is called PULSE. When the carrier is switched off, it is called SPACE.
In other words, a typical IR transmission can be viewed as a sequence of PULSE and SPACE events, each with a given duration.
The carrier parameters (frequency, duty cycle) and the intervals for PULSE and SPACE events depend on the protocol. For example, the NEC protocol uses a carrier of 38kHz, and transmissions start with a 9ms PULSE and a 4.5ms SPACE. It then transmits 16 bits of scan code, being 8 bits for address (usually it is a fixed number for a given remote controller), followed by 8 bits of code. A bit “1” is modulated with 560µs PULSE followed by 1690µs SPACE and a bit “0” is modulated with 560µs PULSE followed by 560µs SPACE.
At receiver, a simple low-pass filter can be used to convert the received
signal in a sequence of PULSE/SPACE events, filtering out the carrier
frequency. Due to that, the receiver doesn’t care about the carrier’s
actual frequency parameters: all it has to do is to measure the amount
of time it receives PULSE/SPACE events.
So, a simple IR receiver hardware will just provide a sequence of timings
for those events to the Kernel. The drivers for hardware with such kind of
receivers are identified by RC_DRIVER_IR_RAW
, as defined by
rc_driver_type
[2]. Other hardware come with a
microcontroller that decode the PULSE/SPACE sequence and return scan
codes to the Kernel. Such kind of receivers are identified
by RC_DRIVER_SCANCODE
.
[2] | The RC core also supports devices that have just IR emitters,
without any receivers. Right now, all such devices work only in
raw TX mode. Such kind of hardware is identified as
RC_DRIVER_IR_RAW_TX . |
When the RC core receives events produced by RC_DRIVER_IR_RAW
IR
receivers, it needs to decode the IR protocol, in order to obtain the
corresponding scan code. The protocols supported by the RC core are
defined at enum rc_proto
.
When the RC code receives a scan code (either directly, by a driver
of the type RC_DRIVER_SCANCODE
, or via its IR decoders), it needs
to convert into a Linux input event code. This is done via a mapping
table.
The Kernel has support for mapping tables available on most media devices. It also supports loading a table in runtime, via some sysfs nodes. See the RC userspace API for more details.
3.1.1. Remote controller data structures and functions¶
-
enum
rc_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.
-
struct
rc_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.
-
enum
rc_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.
-
struct
lirc_fh
¶ represents an open lirc file
Definition
struct lirc_fh {
struct list_head list;
struct rc_dev *rc;
int carrier_low;
bool send_timeout_reports;
unsigned int *rawir;
struct lirc_scancode *scancodes;
wait_queue_head_t wait_poll;
u8 send_mode;
u8 rec_mode;
};
Members
list
- list of open file handles
rc
- rcdev for this lirc chardev
carrier_low
- when setting the carrier range, first the low end must be set with an ioctl and then the high end with another ioctl
send_timeout_reports
- report timeouts in lirc raw IR.
rawir
- queue for incoming raw IR
scancodes
- queue for incoming decoded scancodes
wait_poll
- poll struct for lirc device
send_mode
- lirc mode for sending, either LIRC_MODE_SCANCODE or LIRC_MODE_PULSE
rec_mode
- lirc mode for receiving, either LIRC_MODE_SCANCODE or LIRC_MODE_MODE2
-
struct
rc_dev
¶ represents a remote control device
Definition
struct rc_dev {
struct device dev;
bool managed_alloc;
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;
unsigned int minor;
struct ir_raw_event_ctrl *raw;
struct input_dev *input_dev;
enum rc_driver_type driver_type;
bool idle;
bool encode_wakeup;
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;
u32 users;
void *priv;
spinlock_t keylock;
bool keypressed;
unsigned long keyup_jiffies;
struct timer_list timer_keyup;
struct timer_list timer_repeat;
u32 last_keycode;
enum rc_proto last_protocol;
u32 last_scancode;
u8 last_toggle;
u32 timeout;
u32 min_timeout;
u32 max_timeout;
u32 rx_resolution;
u32 tx_resolution;
#ifdef CONFIG_LIRC;
struct device lirc_dev;
struct cdev lirc_cdev;
ktime_t gap_start;
u64 gap_duration;
bool gap;
spinlock_t lirc_fh_lock;
struct list_head lirc_fh;
#endif;
bool registered;
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_learning_mode)(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
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 (struct input_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 before anyone can call show_protocols or store_protocols
minor
- unique minor remote control device number
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
idle
- used to keep track of RX state
encode_wakeup
- wakeup filtering uses IR encode API, therefore the allowed wakeup protocols is the set of all raw encoders
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_* wakeup protocols
wakeup_protocol
- the enabled RC_PROTO_* wakeup protocol or RC_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 full scancode to the application. As this is a hardware limit, we can’t do anything with it. Yet, as the same keycode table can be used with other devices, a mask is provided to allow its usage. Drivers should generally leave this field in blank
users
- number of current users of the device
priv
- driver-specific data
keylock
- protects the remaining members of the struct
keypressed
- whether a key is currently pressed
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, which has non-standard repeats.
last_keycode
- keycode of last keypress
last_protocol
- protocol of last keypress
last_scancode
- scancode of last keypress
last_toggle
- toggle value of last command
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 ns) of input sampler
tx_resolution
- resolution (in ns) of output sampler
lirc_dev
- lirc device
lirc_cdev
- lirc char cdev
gap_start
- time when gap starts
gap_duration
- duration of initial gap
gap
- true if we’re in a gap
lirc_fh_lock
- protects lirc_fh list
lirc_fh
- list of open files
registered
- set to true by
rc_register_device()
, false by rc_unregister_device change_protocol
- allow changing the protocol used on hardware decoders
open
- callback to allow drivers to enable polling/irq when IR input device is opened.
close
- callback to allow drivers to disable polling/irq when IR input device is 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_learning_mode
- 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 zero then wakeup should be disabled. wakeup_protocol will be set to a valid protocol if mask is nonzero.
s_timeout
- set hardware timeout in ns
Parameters
enum rc_driver_type
- specifies the type of the RC output to be allocated returns a pointer to struct rc_dev.
-
struct rc_dev *
devm_rc_allocate_device
(struct device * dev, enum rc_driver_type)¶ Managed RC device allocation
Parameters
struct device * dev
- pointer to struct device
enum rc_driver_type
- specifies the type of the RC output to be allocated returns a pointer to struct rc_dev.
Parameters
struct rc_dev * dev
- pointer to struct rc_dev.
Parameters
struct rc_dev * dev
- pointer to struct rc_dev.
-
int
devm_rc_register_device
(struct device * parent, struct rc_dev * dev)¶ Manageded registering of a RC device
Parameters
struct device * parent
- pointer to struct device.
struct rc_dev * dev
- pointer to struct rc_dev.
Parameters
struct rc_dev * dev
- pointer to struct rc_dev.
-
struct
rc_map_table
¶ represents a scancode/keycode pair
Definition
struct rc_map_table {
u32 scancode;
u32 keycode;
};
Members
scancode
- scan code (u32)
keycode
- Linux input keycode
-
struct
rc_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 struct
rc_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 at
enum
rc_proto
name
- name of the key map table
lock
- lock to protect access to this structure
Definition
struct rc_map_list {
struct list_head list;
struct rc_map map;
};
Members
list
- pointer to struct
list_head
map
- pointer to struct
rc_map
-
int
rc_map_register
(struct rc_map_list * map)¶ Registers a Remote Controller scancode map
Parameters
struct rc_map_list * map
- pointer to struct rc_map_list
-
void
rc_map_unregister
(struct rc_map_list * map)¶ Unregisters a Remote Controller scancode map
Parameters
struct rc_map_list * map
- pointer to struct rc_map_list
Parameters
const char * name
- name of the RC scancode map