18e8e69d6SThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-only */
26bda9644SMauro Carvalho Chehab /*
36bda9644SMauro Carvalho Chehab * Remote Controller core header
46bda9644SMauro Carvalho Chehab *
537e59f87SMauro Carvalho Chehab * Copyright (C) 2009-2010 by Mauro Carvalho Chehab
66bda9644SMauro Carvalho Chehab */
76bda9644SMauro Carvalho Chehab
8ca86674bSMauro Carvalho Chehab #ifndef _RC_CORE
9ca86674bSMauro Carvalho Chehab #define _RC_CORE
106bda9644SMauro Carvalho Chehab
116bda9644SMauro Carvalho Chehab #include <linux/spinlock.h>
12a6ddd4feSSean Young #include <linux/cdev.h>
136bda9644SMauro Carvalho Chehab #include <linux/kfifo.h>
146bda9644SMauro Carvalho Chehab #include <linux/time.h>
156bda9644SMauro Carvalho Chehab #include <linux/timer.h>
166bda9644SMauro Carvalho Chehab #include <media/rc-map.h>
176bda9644SMauro Carvalho Chehab
185b6137dcSMauro Carvalho Chehab /**
19f4ab70e3SMauro Carvalho Chehab * enum rc_driver_type - type of the RC driver.
205b6137dcSMauro Carvalho Chehab *
21f4ab70e3SMauro Carvalho Chehab * @RC_DRIVER_SCANCODE: Driver or hardware generates a scancode.
225b6137dcSMauro Carvalho Chehab * @RC_DRIVER_IR_RAW: Driver or hardware generates pulse/space sequences.
235b6137dcSMauro Carvalho Chehab * It needs a Infra-Red pulse/space decoder
24d34aee10SAndi Shyti * @RC_DRIVER_IR_RAW_TX: Device transmitter only,
25d34aee10SAndi Shyti * driver requires pulse/space data sequence.
265b6137dcSMauro Carvalho Chehab */
276bda9644SMauro Carvalho Chehab enum rc_driver_type {
285b6137dcSMauro Carvalho Chehab RC_DRIVER_SCANCODE = 0,
295b6137dcSMauro Carvalho Chehab RC_DRIVER_IR_RAW,
30d34aee10SAndi Shyti RC_DRIVER_IR_RAW_TX,
316bda9644SMauro Carvalho Chehab };
326bda9644SMauro Carvalho Chehab
336bda9644SMauro Carvalho Chehab /**
3400942d1aSJames Hogan * struct rc_scancode_filter - Filter scan codes.
3500942d1aSJames Hogan * @data: Scancode data to match.
3600942d1aSJames Hogan * @mask: Mask of bits of scancode to compare.
3700942d1aSJames Hogan */
3800942d1aSJames Hogan struct rc_scancode_filter {
3900942d1aSJames Hogan u32 data;
4000942d1aSJames Hogan u32 mask;
4100942d1aSJames Hogan };
4200942d1aSJames Hogan
4300942d1aSJames Hogan /**
4400942d1aSJames Hogan * enum rc_filter_type - Filter type constants.
4500942d1aSJames Hogan * @RC_FILTER_NORMAL: Filter for normal operation.
4600942d1aSJames Hogan * @RC_FILTER_WAKEUP: Filter for waking from suspend.
4700942d1aSJames Hogan * @RC_FILTER_MAX: Number of filter types.
4800942d1aSJames Hogan */
4900942d1aSJames Hogan enum rc_filter_type {
5000942d1aSJames Hogan RC_FILTER_NORMAL = 0,
5100942d1aSJames Hogan RC_FILTER_WAKEUP,
5200942d1aSJames Hogan
5300942d1aSJames Hogan RC_FILTER_MAX
5400942d1aSJames Hogan };
5500942d1aSJames Hogan
5600942d1aSJames Hogan /**
577e45d660SSean Young * struct lirc_fh - represents an open lirc file
587e45d660SSean Young * @list: list of open file handles
597e45d660SSean Young * @rc: rcdev for this lirc chardev
607e45d660SSean Young * @carrier_low: when setting the carrier range, first the low end must be
617e45d660SSean Young * set with an ioctl and then the high end with another ioctl
627e45d660SSean Young * @rawir: queue for incoming raw IR
637e45d660SSean Young * @scancodes: queue for incoming decoded scancodes
647e45d660SSean Young * @wait_poll: poll struct for lirc device
657e45d660SSean Young * @send_mode: lirc mode for sending, either LIRC_MODE_SCANCODE or
667e45d660SSean Young * LIRC_MODE_PULSE
677e45d660SSean Young * @rec_mode: lirc mode for receiving, either LIRC_MODE_SCANCODE or
687e45d660SSean Young * LIRC_MODE_MODE2
697e45d660SSean Young */
707e45d660SSean Young struct lirc_fh {
717e45d660SSean Young struct list_head list;
727e45d660SSean Young struct rc_dev *rc;
737e45d660SSean Young int carrier_low;
747e45d660SSean Young DECLARE_KFIFO_PTR(rawir, unsigned int);
757e45d660SSean Young DECLARE_KFIFO_PTR(scancodes, struct lirc_scancode);
767e45d660SSean Young wait_queue_head_t wait_poll;
777e45d660SSean Young u8 send_mode;
787e45d660SSean Young u8 rec_mode;
797e45d660SSean Young };
807e45d660SSean Young
817e45d660SSean Young /**
826bda9644SMauro Carvalho Chehab * struct rc_dev - represents a remote control device
836bda9644SMauro Carvalho Chehab * @dev: driver model's view of this device
84ddbf7d5aSHeiner Kallweit * @managed_alloc: devm_rc_allocate_device was used to create rc_dev
8599b0f3c9SDavid Härdeman * @sysfs_groups: sysfs attribute groups
86518f4b26SSean Young * @device_name: name of the rc child device
876bda9644SMauro Carvalho Chehab * @input_phys: physical path to the input child device
886bda9644SMauro Carvalho Chehab * @input_id: id of the input child device (struct input_id)
896bda9644SMauro Carvalho Chehab * @driver_name: name of the hardware driver which registered this device
906bda9644SMauro Carvalho Chehab * @map_name: name of the default keymap
91b088ba65SMauro Carvalho Chehab * @rc_map: current scan/key table
9208aeb7c9SJarod Wilson * @lock: used to ensure we've filled in all protocol details before
9308aeb7c9SJarod Wilson * anyone can call show_protocols or store_protocols
94fcb13097SDavid Härdeman * @minor: unique minor remote control device number
956bda9644SMauro Carvalho Chehab * @raw: additional data for raw pulse/space devices
966bda9644SMauro Carvalho Chehab * @input_dev: the input child device used to communicate events to userspace
976bda9644SMauro Carvalho Chehab * @driver_type: specifies if protocol decoding is done in hardware or software
986bda9644SMauro Carvalho Chehab * @idle: used to keep track of RX state
99f423ccc1SJames Hogan * @encode_wakeup: wakeup filtering uses IR encode API, therefore the allowed
100f423ccc1SJames Hogan * wakeup protocols is the set of all raw encoders
1016d741bfeSSean Young * @allowed_protocols: bitmask with the supported RC_PROTO_BIT_* protocols
1026d741bfeSSean Young * @enabled_protocols: bitmask with the enabled RC_PROTO_BIT_* protocols
1036d741bfeSSean Young * @allowed_wakeup_protocols: bitmask with the supported RC_PROTO_BIT_* wakeup
1046d741bfeSSean Young * protocols
1056d741bfeSSean Young * @wakeup_protocol: the enabled RC_PROTO_* wakeup protocol or
1066d741bfeSSean Young * RC_PROTO_UNKNOWN if disabled.
107c5540fbbSDavid Härdeman * @scancode_filter: scancode filter
108c5540fbbSDavid Härdeman * @scancode_wakeup_filter: scancode wakeup filters
1099d2f1d3cSDavid Härdeman * @scancode_mask: some hardware decoders are not capable of providing the full
1106bda9644SMauro Carvalho Chehab * scancode to the application. As this is a hardware limit, we can't do
1116bda9644SMauro Carvalho Chehab * anything with it. Yet, as the same keycode table can be used with other
1126bda9644SMauro Carvalho Chehab * devices, a mask is provided to allow its usage. Drivers should generally
1136bda9644SMauro Carvalho Chehab * leave this field in blank
1149d2f1d3cSDavid Härdeman * @users: number of current users of the device
1156bda9644SMauro Carvalho Chehab * @priv: driver-specific data
1166bda9644SMauro Carvalho Chehab * @keylock: protects the remaining members of the struct
1176bda9644SMauro Carvalho Chehab * @keypressed: whether a key is currently pressed
1186bda9644SMauro Carvalho Chehab * @keyup_jiffies: time (in jiffies) when the current keypress should be released
1196bda9644SMauro Carvalho Chehab * @timer_keyup: timer for releasing a keypress
12057c642cbSSean Young * @timer_repeat: timer for autorepeat events. This is needed for CEC, which
12157c642cbSSean Young * has non-standard repeats.
1226bda9644SMauro Carvalho Chehab * @last_keycode: keycode of last keypress
123120703f9SDavid Härdeman * @last_protocol: protocol of last keypress
1246bda9644SMauro Carvalho Chehab * @last_scancode: scancode of last keypress
1256bda9644SMauro Carvalho Chehab * @last_toggle: toggle value of last command
1266bda9644SMauro Carvalho Chehab * @timeout: optional time after which device stops sending data
1276bda9644SMauro Carvalho Chehab * @min_timeout: minimum timeout supported by device
1286bda9644SMauro Carvalho Chehab * @max_timeout: maximum timeout supported by device
129528222d8SSean Young * @rx_resolution : resolution (in us) of input sampler
130528222d8SSean Young * @tx_resolution: resolution (in us) of output sampler
131a6ddd4feSSean Young * @lirc_dev: lirc device
132a6ddd4feSSean Young * @lirc_cdev: lirc char cdev
133d49a14a9SSean Young * @gap_start: start time for gap after timeout if non-zero
1347e45d660SSean Young * @lirc_fh_lock: protects lirc_fh list
1357e45d660SSean Young * @lirc_fh: list of open files
1367790e81fSSean Young * @registered: set to true by rc_register_device(), false by
1377790e81fSSean Young * rc_unregister_device
1386bda9644SMauro Carvalho Chehab * @change_protocol: allow changing the protocol used on hardware decoders
1396bda9644SMauro Carvalho Chehab * @open: callback to allow drivers to enable polling/irq when IR input device
1406bda9644SMauro Carvalho Chehab * is opened.
1416bda9644SMauro Carvalho Chehab * @close: callback to allow drivers to disable polling/irq when IR input device
1426bda9644SMauro Carvalho Chehab * is opened.
1436bda9644SMauro Carvalho Chehab * @s_tx_mask: set transmitter mask (for devices with multiple tx outputs)
1446bda9644SMauro Carvalho Chehab * @s_tx_carrier: set transmit carrier frequency
1456bda9644SMauro Carvalho Chehab * @s_tx_duty_cycle: set transmit duty cycle (0% - 100%)
146fa810845SMauro Carvalho Chehab * @s_rx_carrier_range: inform driver about carrier it is expected to handle
1476bda9644SMauro Carvalho Chehab * @tx_ir: transmit IR
1486bda9644SMauro Carvalho Chehab * @s_idle: enable/disable hardware idle mode, upon which,
1496bda9644SMauro Carvalho Chehab * device doesn't interrupt host until it sees IR pulses
1508b777edfSSean Young * @s_wideband_receiver: enable wide band receiver used for learning
1516bda9644SMauro Carvalho Chehab * @s_carrier_report: enable carrier reports
15223c843b5SDavid Härdeman * @s_filter: set the scancode filter
1530751d33cSSean Young * @s_wakeup_filter: set the wakeup scancode filter. If the mask is zero
1540751d33cSSean Young * then wakeup should be disabled. wakeup_protocol will be set to
1550751d33cSSean Young * a valid protocol if mask is nonzero.
156528222d8SSean Young * @s_timeout: set hardware timeout in us
1576bda9644SMauro Carvalho Chehab */
1586bda9644SMauro Carvalho Chehab struct rc_dev {
1596bda9644SMauro Carvalho Chehab struct device dev;
160ddbf7d5aSHeiner Kallweit bool managed_alloc;
16199b0f3c9SDavid Härdeman const struct attribute_group *sysfs_groups[5];
162518f4b26SSean Young const char *device_name;
1636bda9644SMauro Carvalho Chehab const char *input_phys;
1646bda9644SMauro Carvalho Chehab struct input_id input_id;
165518f4b26SSean Young const char *driver_name;
1666bda9644SMauro Carvalho Chehab const char *map_name;
167b088ba65SMauro Carvalho Chehab struct rc_map rc_map;
16808aeb7c9SJarod Wilson struct mutex lock;
169fcb13097SDavid Härdeman unsigned int minor;
1706bda9644SMauro Carvalho Chehab struct ir_raw_event_ctrl *raw;
1716bda9644SMauro Carvalho Chehab struct input_dev *input_dev;
1726bda9644SMauro Carvalho Chehab enum rc_driver_type driver_type;
1736bda9644SMauro Carvalho Chehab bool idle;
174f423ccc1SJames Hogan bool encode_wakeup;
175c5540fbbSDavid Härdeman u64 allowed_protocols;
176c5540fbbSDavid Härdeman u64 enabled_protocols;
177c5540fbbSDavid Härdeman u64 allowed_wakeup_protocols;
1786d741bfeSSean Young enum rc_proto wakeup_protocol;
179c5540fbbSDavid Härdeman struct rc_scancode_filter scancode_filter;
180c5540fbbSDavid Härdeman struct rc_scancode_filter scancode_wakeup_filter;
1819d2f1d3cSDavid Härdeman u32 scancode_mask;
1828b2ff320SSrinivas Kandagatla u32 users;
1836bda9644SMauro Carvalho Chehab void *priv;
1846bda9644SMauro Carvalho Chehab spinlock_t keylock;
1856bda9644SMauro Carvalho Chehab bool keypressed;
1866bda9644SMauro Carvalho Chehab unsigned long keyup_jiffies;
1876bda9644SMauro Carvalho Chehab struct timer_list timer_keyup;
18857c642cbSSean Young struct timer_list timer_repeat;
1896bda9644SMauro Carvalho Chehab u32 last_keycode;
1906d741bfeSSean Young enum rc_proto last_protocol;
191e6c6d7d4SSean Young u64 last_scancode;
1926bda9644SMauro Carvalho Chehab u8 last_toggle;
1936bda9644SMauro Carvalho Chehab u32 timeout;
1946bda9644SMauro Carvalho Chehab u32 min_timeout;
1956bda9644SMauro Carvalho Chehab u32 max_timeout;
1966bda9644SMauro Carvalho Chehab u32 rx_resolution;
1976bda9644SMauro Carvalho Chehab u32 tx_resolution;
198a60d64b1SSean Young #ifdef CONFIG_LIRC
199a6ddd4feSSean Young struct device lirc_dev;
200a6ddd4feSSean Young struct cdev lirc_cdev;
201a60d64b1SSean Young ktime_t gap_start;
2027e45d660SSean Young spinlock_t lirc_fh_lock;
2037e45d660SSean Young struct list_head lirc_fh;
204a60d64b1SSean Young #endif
2057790e81fSSean Young bool registered;
2066d741bfeSSean Young int (*change_protocol)(struct rc_dev *dev, u64 *rc_proto);
2076bda9644SMauro Carvalho Chehab int (*open)(struct rc_dev *dev);
2086bda9644SMauro Carvalho Chehab void (*close)(struct rc_dev *dev);
2096bda9644SMauro Carvalho Chehab int (*s_tx_mask)(struct rc_dev *dev, u32 mask);
2106bda9644SMauro Carvalho Chehab int (*s_tx_carrier)(struct rc_dev *dev, u32 carrier);
2116bda9644SMauro Carvalho Chehab int (*s_tx_duty_cycle)(struct rc_dev *dev, u32 duty_cycle);
2126bda9644SMauro Carvalho Chehab int (*s_rx_carrier_range)(struct rc_dev *dev, u32 min, u32 max);
2135588dc2bSDavid Härdeman int (*tx_ir)(struct rc_dev *dev, unsigned *txbuf, unsigned n);
2146bda9644SMauro Carvalho Chehab void (*s_idle)(struct rc_dev *dev, bool enable);
2158b777edfSSean Young int (*s_wideband_receiver)(struct rc_dev *dev, int enable);
2166bda9644SMauro Carvalho Chehab int (*s_carrier_report) (struct rc_dev *dev, int enable);
21700942d1aSJames Hogan int (*s_filter)(struct rc_dev *dev,
21823c843b5SDavid Härdeman struct rc_scancode_filter *filter);
21923c843b5SDavid Härdeman int (*s_wakeup_filter)(struct rc_dev *dev,
22000942d1aSJames Hogan struct rc_scancode_filter *filter);
2214f253cecSSean Young int (*s_timeout)(struct rc_dev *dev,
2224f253cecSSean Young unsigned int timeout);
2236bda9644SMauro Carvalho Chehab };
2246bda9644SMauro Carvalho Chehab
225ca86674bSMauro Carvalho Chehab #define to_rc_dev(d) container_of(d, struct rc_dev, dev)
226ca86674bSMauro Carvalho Chehab
227ca86674bSMauro Carvalho Chehab /*
228ca86674bSMauro Carvalho Chehab * From rc-main.c
229ca86674bSMauro Carvalho Chehab * Those functions can be used on any type of Remote Controller. They
230ca86674bSMauro Carvalho Chehab * basically creates an input_dev and properly reports the device as a
231ca86674bSMauro Carvalho Chehab * Remote Controller, at sys/class/rc.
232ca86674bSMauro Carvalho Chehab */
233ca86674bSMauro Carvalho Chehab
2345b6137dcSMauro Carvalho Chehab /**
2355b6137dcSMauro Carvalho Chehab * rc_allocate_device - Allocates a RC device
2365b6137dcSMauro Carvalho Chehab *
2370f7499fdSAndi Shyti * @rc_driver_type: specifies the type of the RC output to be allocated
2385b6137dcSMauro Carvalho Chehab * returns a pointer to struct rc_dev.
2395b6137dcSMauro Carvalho Chehab */
2400f7499fdSAndi Shyti struct rc_dev *rc_allocate_device(enum rc_driver_type);
2415b6137dcSMauro Carvalho Chehab
2425b6137dcSMauro Carvalho Chehab /**
243ddbf7d5aSHeiner Kallweit * devm_rc_allocate_device - Managed RC device allocation
244ddbf7d5aSHeiner Kallweit *
245ddbf7d5aSHeiner Kallweit * @dev: pointer to struct device
2460f7499fdSAndi Shyti * @rc_driver_type: specifies the type of the RC output to be allocated
247ddbf7d5aSHeiner Kallweit * returns a pointer to struct rc_dev.
248ddbf7d5aSHeiner Kallweit */
2490f7499fdSAndi Shyti struct rc_dev *devm_rc_allocate_device(struct device *dev, enum rc_driver_type);
250ddbf7d5aSHeiner Kallweit
251ddbf7d5aSHeiner Kallweit /**
2525b6137dcSMauro Carvalho Chehab * rc_free_device - Frees a RC device
2535b6137dcSMauro Carvalho Chehab *
2545b6137dcSMauro Carvalho Chehab * @dev: pointer to struct rc_dev.
2555b6137dcSMauro Carvalho Chehab */
256ca86674bSMauro Carvalho Chehab void rc_free_device(struct rc_dev *dev);
2575b6137dcSMauro Carvalho Chehab
2585b6137dcSMauro Carvalho Chehab /**
2595b6137dcSMauro Carvalho Chehab * rc_register_device - Registers a RC device
2605b6137dcSMauro Carvalho Chehab *
2615b6137dcSMauro Carvalho Chehab * @dev: pointer to struct rc_dev.
2625b6137dcSMauro Carvalho Chehab */
263ca86674bSMauro Carvalho Chehab int rc_register_device(struct rc_dev *dev);
2645b6137dcSMauro Carvalho Chehab
2655b6137dcSMauro Carvalho Chehab /**
266ddbf7d5aSHeiner Kallweit * devm_rc_register_device - Manageded registering of a RC device
267ddbf7d5aSHeiner Kallweit *
268ddbf7d5aSHeiner Kallweit * @parent: pointer to struct device.
269ddbf7d5aSHeiner Kallweit * @dev: pointer to struct rc_dev.
270ddbf7d5aSHeiner Kallweit */
271ddbf7d5aSHeiner Kallweit int devm_rc_register_device(struct device *parent, struct rc_dev *dev);
272ddbf7d5aSHeiner Kallweit
273ddbf7d5aSHeiner Kallweit /**
2745b6137dcSMauro Carvalho Chehab * rc_unregister_device - Unregisters a RC device
2755b6137dcSMauro Carvalho Chehab *
2765b6137dcSMauro Carvalho Chehab * @dev: pointer to struct rc_dev.
2775b6137dcSMauro Carvalho Chehab */
278ca86674bSMauro Carvalho Chehab void rc_unregister_device(struct rc_dev *dev);
279ca86674bSMauro Carvalho Chehab
280ca86674bSMauro Carvalho Chehab void rc_repeat(struct rc_dev *dev);
281e6c6d7d4SSean Young void rc_keydown(struct rc_dev *dev, enum rc_proto protocol, u64 scancode,
2826d741bfeSSean Young u8 toggle);
2836d741bfeSSean Young void rc_keydown_notimeout(struct rc_dev *dev, enum rc_proto protocol,
284e6c6d7d4SSean Young u64 scancode, u8 toggle);
285ca86674bSMauro Carvalho Chehab void rc_keyup(struct rc_dev *dev);
286e6c6d7d4SSean Young u32 rc_g_keycode_from_table(struct rc_dev *dev, u64 scancode);
287ca86674bSMauro Carvalho Chehab
288ca86674bSMauro Carvalho Chehab /*
289ca86674bSMauro Carvalho Chehab * From rc-raw.c
290ca86674bSMauro Carvalho Chehab * The Raw interface is specific to InfraRed. It may be a good idea to
291ca86674bSMauro Carvalho Chehab * split it later into a separate header.
292ca86674bSMauro Carvalho Chehab */
2936bda9644SMauro Carvalho Chehab struct ir_raw_event {
2946bda9644SMauro Carvalho Chehab union {
2956bda9644SMauro Carvalho Chehab u32 duration;
2966bda9644SMauro Carvalho Chehab u32 carrier;
2975f61ff86SHeiner Kallweit };
2986bda9644SMauro Carvalho Chehab u8 duty_cycle;
2996bda9644SMauro Carvalho Chehab
3006bda9644SMauro Carvalho Chehab unsigned pulse:1;
301*950170d6SSean Young unsigned overflow:1;
3026bda9644SMauro Carvalho Chehab unsigned timeout:1;
3036bda9644SMauro Carvalho Chehab unsigned carrier_report:1;
3046bda9644SMauro Carvalho Chehab };
3056bda9644SMauro Carvalho Chehab
3065aad7242SJarod Wilson #define US_TO_NS(usec) ((usec) * 1000)
3075aad7242SJarod Wilson #define MS_TO_US(msec) ((msec) * 1000)
308528222d8SSean Young #define IR_MAX_DURATION MS_TO_US(500)
309528222d8SSean Young #define IR_DEFAULT_TIMEOUT MS_TO_US(125)
31050634548SSean Young #define IR_MAX_TIMEOUT LIRC_VALUE_MASK
3116bda9644SMauro Carvalho Chehab
3126bda9644SMauro Carvalho Chehab void ir_raw_event_handle(struct rc_dev *dev);
3136bda9644SMauro Carvalho Chehab int ir_raw_event_store(struct rc_dev *dev, struct ir_raw_event *ev);
31486fe1ac0SSean Young int ir_raw_event_store_edge(struct rc_dev *dev, bool pulse);
3156bda9644SMauro Carvalho Chehab int ir_raw_event_store_with_filter(struct rc_dev *dev,
3166bda9644SMauro Carvalho Chehab struct ir_raw_event *ev);
3178d7a77ceSSean Young int ir_raw_event_store_with_timeout(struct rc_dev *dev,
3188d7a77ceSSean Young struct ir_raw_event *ev);
3196bda9644SMauro Carvalho Chehab void ir_raw_event_set_idle(struct rc_dev *dev, bool idle);
3206d741bfeSSean Young int ir_raw_encode_scancode(enum rc_proto protocol, u32 scancode,
3213875233dSJames Hogan struct ir_raw_event *events, unsigned int max);
322cdfaa01cSSean Young int ir_raw_encode_carrier(enum rc_proto protocol);
3236bda9644SMauro Carvalho Chehab
ir_raw_event_overflow(struct rc_dev * dev)324*950170d6SSean Young static inline void ir_raw_event_overflow(struct rc_dev *dev)
3256bda9644SMauro Carvalho Chehab {
326*950170d6SSean Young ir_raw_event_store(dev, &((struct ir_raw_event) { .overflow = true }));
327e0d51e6cSSean Young dev->idle = true;
3286bda9644SMauro Carvalho Chehab ir_raw_event_handle(dev);
3296bda9644SMauro Carvalho Chehab }
3306bda9644SMauro Carvalho Chehab
3316bda9644SMauro Carvalho Chehab /* extract mask bits out of data and pack them into the result */
ir_extract_bits(u32 data,u32 mask)3326bda9644SMauro Carvalho Chehab static inline u32 ir_extract_bits(u32 data, u32 mask)
3336bda9644SMauro Carvalho Chehab {
3346bda9644SMauro Carvalho Chehab u32 vbit = 1, value = 0;
3356bda9644SMauro Carvalho Chehab
3366bda9644SMauro Carvalho Chehab do {
3376bda9644SMauro Carvalho Chehab if (mask & 1) {
3386bda9644SMauro Carvalho Chehab if (data & 1)
3396bda9644SMauro Carvalho Chehab value |= vbit;
3406bda9644SMauro Carvalho Chehab vbit <<= 1;
3416bda9644SMauro Carvalho Chehab }
3426bda9644SMauro Carvalho Chehab data >>= 1;
3436bda9644SMauro Carvalho Chehab } while (mask >>= 1);
3446bda9644SMauro Carvalho Chehab
3456bda9644SMauro Carvalho Chehab return value;
3466bda9644SMauro Carvalho Chehab }
3476bda9644SMauro Carvalho Chehab
348e8ffda78SShawn Guo /* Get NEC scancode and protocol type from address and command bytes */
ir_nec_bytes_to_scancode(u8 address,u8 not_address,u8 command,u8 not_command,enum rc_proto * protocol)349e8ffda78SShawn Guo static inline u32 ir_nec_bytes_to_scancode(u8 address, u8 not_address,
350e8ffda78SShawn Guo u8 command, u8 not_command,
3516d741bfeSSean Young enum rc_proto *protocol)
352e8ffda78SShawn Guo {
353e8ffda78SShawn Guo u32 scancode;
354e8ffda78SShawn Guo
355e8ffda78SShawn Guo if ((command ^ not_command) != 0xff) {
356e8ffda78SShawn Guo /* NEC transport, but modified protocol, used by at
357e8ffda78SShawn Guo * least Apple and TiVo remotes
358e8ffda78SShawn Guo */
359e8ffda78SShawn Guo scancode = not_address << 24 |
360e8ffda78SShawn Guo address << 16 |
361e8ffda78SShawn Guo not_command << 8 |
362e8ffda78SShawn Guo command;
3636d741bfeSSean Young *protocol = RC_PROTO_NEC32;
364e8ffda78SShawn Guo } else if ((address ^ not_address) != 0xff) {
365e8ffda78SShawn Guo /* Extended NEC */
366e8ffda78SShawn Guo scancode = address << 16 |
367e8ffda78SShawn Guo not_address << 8 |
368e8ffda78SShawn Guo command;
3696d741bfeSSean Young *protocol = RC_PROTO_NECX;
370e8ffda78SShawn Guo } else {
371e8ffda78SShawn Guo /* Normal NEC */
372e8ffda78SShawn Guo scancode = address << 8 | command;
3736d741bfeSSean Young *protocol = RC_PROTO_NEC;
374e8ffda78SShawn Guo }
375e8ffda78SShawn Guo
376e8ffda78SShawn Guo return scancode;
377e8ffda78SShawn Guo }
378e8ffda78SShawn Guo
379ca86674bSMauro Carvalho Chehab #endif /* _RC_CORE */
380