STRUCT RC_DEV(9)
β¨ struct rc_dev(9) β¨
okay bestie, so this is literally the blueprint for a remote control device in the kernel β the struct rc_dev is what represents an RC device and it's giving main character energy in ./include/media/rc-core.h. we're talking Kernel API Manual vibes, and i'm gonna walk you through every single member because there are a LOT and they all matter, no cap π
πΈ SYNOPSIS πΈ
like, here's the whole struct in all its glory β every field, every callback, exactly as it lives in the header. don't skip any of it, bestie, it's all important:
struct rc_dev {
struct device dev;
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 π
okay so now we're getting into the actual members one by one. this is the part where you really get to know your rc_dev, bestie. every single one, let's go β¨
devβ the driver model's view of this device. like, this is how the rest of the kernel sees it, periodt.registeredβ set totruebyrc_register_device, andfalsebyrc_unregister_device. it's the "are we live yet" flag basically πidleβ used to keep track of RX state. lowkey just a little bookkeeping buddy.encode_wakeupβ wakeup filtering uses the IR encode API, so the allowed wakeup protocols is literally the set of all raw encoders. iykyk πminorβ unique minor remote control device number. everyone gets their own number, no sharing πsysfs_groupsβ sysfs attribute groups. the whole array of them.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, and it's astruct input_id.driver_nameβ name of the hardware driver which registered this device. like, who's your parent, bestie?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 callshow_protocolsorstore_protocols. so like, nobody jumps the gun, okay? πrawβ additional data for raw pulse/space devices.input_devβ the input child device used to communicate events to userspace. this is the messenger to the outside world π¦driver_typeβ specifies if protocol decoding is done in hardware or software. hardware girlies vs software girlies, both valid πusersβ number of current users of the device.allowed_protocolsβ bitmask with the supportedRC_PROTO_BIT_*protocols.enabled_protocolsβ bitmask with the enabledRC_PROTO_BIT_*protocols.allowed_wakeup_protocolsβ bitmask with the supportedRC_PROTO_BIT_*wakeup protocols.wakeup_protocolβ the enabledRC_PROTO_*wakeup protocol, orRC_PROTO_UNKNOWNif it's disabled. like, it's either on with a real protocol or it's giving unknown energy πscancode_filterβ scancode filter.scancode_wakeup_filterβ scancode wakeup filters.scancode_maskβ okay so this one is a whole thing: 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. so like, drivers, don't touch unless you know what you're doing, fr fr β οΈprivβ driver-specific data. it's giving "my own little corner" energy.keylockβ protects the remaining members of the struct. it's the bodyguard for everything after this point π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. like a little countdown timer, but in kernel time β³timer_keyupβ timer for releasing a keypress.timer_repeatβ timer for autorepeat events. this is needed for CEC, which has non-standard repeats. so don't @ me about it, it's a CEC thing π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. (this one lives inside the#ifdef CONFIG_LIRCblock, so it's conditional bestie)lirc_cdevβ lirc char cdev.gap_startβ start time for gap after timeout if non-zero.lirc_fh_lockβ protectslirc_fhlist.lirc_fhβ list of open files.
okay now we're into the callback members, which are like the action functions of the struct. these are the ones that actually DO stuff when the kernel calls them. slay π
change_protocolβ allow changing the protocol used on hardware decoders. it takesstruct rc_dev *dev, u64 *rc_proto.openβ callback to allow drivers to enable polling/irq when IR input device is opened. (yes the original says "when IR input device is opened" β i'm just giving you the facts, bestie)closeβ callback to allow drivers to disable polling/irq when IR input device is opened. again, that's what it says β i'm not fixing it, i'm just the messenger π«Ά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%). literally zero to a hundred, periodt.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. so it's like "shh, don't bother the host until something actually happens" energy π΄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 zero then wakeup should be disabled.wakeup_protocolwill be set to a valid protocol if mask is nonzero. important detail bestie β zero mask means no wakeup, no cap πs_timeoutβ set hardware timeout in us.
π SEE ALSO π
okay so if you want to go deeper (and you KNOW you do), the kernel file to look at is ./include/media/rc-core.h, and these are the related pages you should absolutely check out, bestie:
enum rc_driver_type(9)struct rc_scancode_filter(9)enum rc_filter_type(9)struct lirc_fh(9)rc_allocate_device(9)devm_rc_allocate_device(9)rc_free_device(9)rc_register_device(9)devm_rc_register_device(9)rc_unregister_device(9)
that's the whole page, bestie! now go forth and register some remote control devices with confidence π¦β¨
source: ./include/media β version date: October 2026 β struct rc_dev(9) π
π¦ where this page comes from
- nixpkgs unstable: linux-manual 7.3.1
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms