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.
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_SCANCODEDriver or hardware generates a scancode.
RC_DRIVER_IR_RAWDriver or hardware generates pulse/space sequences.It needs a Infra-Red pulse/space decoder
RC_DRIVER_IR_RAW_TXDevice transmitter only,driver requires pulse/space data sequence.
- structrc_scancode_filter¶
Filter scan codes.
Definition:
struct rc_scancode_filter { u32 data; u32 mask;};Members
dataScancode data to match.
maskMask of bits of scancode to compare.
- enumrc_filter_type¶
Filter type constants.
Constants
RC_FILTER_NORMALFilter for normal operation.
RC_FILTER_WAKEUPFilter for waking from suspend.
RC_FILTER_MAXNumber 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
listlist of open file handles
rcrcdev for this lirc chardev
rawirqueue for incoming raw IR
scancodesqueue for incoming decoded scancodes
wait_pollpoll struct for lirc device
carrier_lowwhen setting the carrier range, first the low end must beset with an ioctl and then the high end with another ioctl
send_modelirc mode for sending, either LIRC_MODE_SCANCODE orLIRC_MODE_PULSE
rec_modelirc 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
devdriver model’s view of this device
managed_allocdevm_rc_allocate_device was used to create rc_dev
registeredset to true by
rc_register_device(), false byrc_unregister_deviceidleused to keep track of RX state
encode_wakeupwakeup filtering uses IR encode API, therefore the allowedwakeup protocols is the set of all raw encoders
minorunique minor remote control device number
sysfs_groupssysfs attribute groups
device_namename of the rc child device
input_physphysical path to the input child device
input_idid of the input child device (
structinput_id)driver_namename of the hardware driver which registered this device
map_namename of the default keymap
rc_mapcurrent scan/key table
lockused to ensure we’ve filled in all protocol details beforeanyone can call show_protocols or store_protocols
rawadditional data for raw pulse/space devices
input_devthe input child device used to communicate events to userspace
driver_typespecifies if protocol decoding is done in hardware or software
usersnumber of current users of the device
allowed_protocolsbitmask with the supported RC_PROTO_BIT_* protocols
enabled_protocolsbitmask with the enabled RC_PROTO_BIT_* protocols
allowed_wakeup_protocolsbitmask with the supported RC_PROTO_BIT_* wakeupprotocols
wakeup_protocolthe enabled RC_PROTO_* wakeup protocol orRC_PROTO_UNKNOWN if disabled.
scancode_filterscancode filter
scancode_wakeup_filterscancode wakeup filters
scancode_masksome 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
privdriver-specific data
keylockprotects the remaining members of the struct
keypressedwhether a key is currently pressed
last_toggletoggle value of last command
last_keycodekeycode of last keypress
last_protocolprotocol of last keypress
last_scancodescancode of last keypress
keyup_jiffiestime (in jiffies) when the current keypress should be released
timer_keyuptimer for releasing a keypress
timer_repeattimer for autorepeat events. This is needed for CEC, whichhas non-standard repeats.
timeoutoptional time after which device stops sending data
min_timeoutminimum timeout supported by device
max_timeoutmaximum timeout supported by device
rx_resolutionresolution (in us) of input sampler
lirc_devlirc device
lirc_cdevlirc char cdev
gap_startstart time for gap after timeout if non-zero
lirc_fh_lockprotects lirc_fh list
lirc_fhlist of open files
change_protocolallow changing the protocol used on hardware decoders
opencallback to allow drivers to enable polling/irq when IR input deviceis opened.
closecallback to allow drivers to disable polling/irq when IR input deviceis opened.
s_tx_maskset transmitter mask (for devices with multiple tx outputs)
s_tx_carrierset transmit carrier frequency
s_tx_duty_cycleset transmit duty cycle (0% - 100%)
s_rx_carrier_rangeinform driver about carrier it is expected to handle
tx_irtransmit IR
s_idleenable/disable hardware idle mode, upon which,device doesn’t interrupt host until it sees IR pulses
s_wideband_receiverenable wide band receiver used for learning
s_carrier_reportenable carrier reports
s_filterset the scancode filter
s_wakeup_filterset 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_timeoutset hardware timeout in us
- structrc_dev*rc_allocate_device(enumrc_driver_type)¶
Allocates a RC device
Parameters
enumrc_driver_typespecifies the type of the RC output to be allocatedreturns a pointer to
structrc_dev.
- structrc_dev*devm_rc_allocate_device(structdevice*dev,enumrc_driver_type)¶
Managed RC device allocation
Parameters
structdevice*devpointer to
structdeviceenumrc_driver_typespecifies the type of the RC output to be allocatedreturns a pointer to
structrc_dev.
Parameters
structrc_dev*devpointer to
structrc_dev.
Parameters
structrc_dev*devpointer to
structrc_dev.
- intdevm_rc_register_device(structdevice*parent,structrc_dev*dev)¶
Manageded registering of a RC device
Parameters
structdevice*parentpointer to
structdevice.structrc_dev*devpointer to
structrc_dev.
Parameters
structrc_dev*devpointer to
structrc_dev.
- structrc_map_table¶
represents a scancode/keycode pair
Definition:
struct rc_map_table { u64 scancode; u32 keycode;};Members
scancodescan code (u64)
keycodeLinux 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
scanpointer to struct
rc_map_tablesizeMax number of entries
lenNumber of entries that are in use
allocsize of *scan, in bytes
rc_prototype of the remote controller protocol, as defined atenum
rc_protonamename of the key map table
locklock to protect access to this structure
Definition:
struct rc_map_list { struct list_head list; struct rc_map map;};Members
listpointer to struct
list_headmappointer to struct
rc_map
- intrc_map_register(structrc_map_list*map)¶
Registers a Remote Controller scancode map
Parameters
structrc_map_list*mappointer to
structrc_map_list
- voidrc_map_unregister(structrc_map_list*map)¶
Unregisters a Remote Controller scancode map
Parameters
structrc_map_list*mappointer to
structrc_map_list
Parameters
constchar*namename of the RC scancode map