18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Remote Controller core header 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright (C) 2009-2010 by Mauro Carvalho Chehab 68c2ecf20Sopenharmony_ci */ 78c2ecf20Sopenharmony_ci 88c2ecf20Sopenharmony_ci#ifndef _RC_CORE 98c2ecf20Sopenharmony_ci#define _RC_CORE 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_ci#include <linux/spinlock.h> 128c2ecf20Sopenharmony_ci#include <linux/cdev.h> 138c2ecf20Sopenharmony_ci#include <linux/kfifo.h> 148c2ecf20Sopenharmony_ci#include <linux/time.h> 158c2ecf20Sopenharmony_ci#include <linux/timer.h> 168c2ecf20Sopenharmony_ci#include <media/rc-map.h> 178c2ecf20Sopenharmony_ci 188c2ecf20Sopenharmony_ci/** 198c2ecf20Sopenharmony_ci * enum rc_driver_type - type of the RC driver. 208c2ecf20Sopenharmony_ci * 218c2ecf20Sopenharmony_ci * @RC_DRIVER_SCANCODE: Driver or hardware generates a scancode. 228c2ecf20Sopenharmony_ci * @RC_DRIVER_IR_RAW: Driver or hardware generates pulse/space sequences. 238c2ecf20Sopenharmony_ci * It needs a Infra-Red pulse/space decoder 248c2ecf20Sopenharmony_ci * @RC_DRIVER_IR_RAW_TX: Device transmitter only, 258c2ecf20Sopenharmony_ci * driver requires pulse/space data sequence. 268c2ecf20Sopenharmony_ci */ 278c2ecf20Sopenharmony_cienum rc_driver_type { 288c2ecf20Sopenharmony_ci RC_DRIVER_SCANCODE = 0, 298c2ecf20Sopenharmony_ci RC_DRIVER_IR_RAW, 308c2ecf20Sopenharmony_ci RC_DRIVER_IR_RAW_TX, 318c2ecf20Sopenharmony_ci}; 328c2ecf20Sopenharmony_ci 338c2ecf20Sopenharmony_ci/** 348c2ecf20Sopenharmony_ci * struct rc_scancode_filter - Filter scan codes. 358c2ecf20Sopenharmony_ci * @data: Scancode data to match. 368c2ecf20Sopenharmony_ci * @mask: Mask of bits of scancode to compare. 378c2ecf20Sopenharmony_ci */ 388c2ecf20Sopenharmony_cistruct rc_scancode_filter { 398c2ecf20Sopenharmony_ci u32 data; 408c2ecf20Sopenharmony_ci u32 mask; 418c2ecf20Sopenharmony_ci}; 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_ci/** 448c2ecf20Sopenharmony_ci * enum rc_filter_type - Filter type constants. 458c2ecf20Sopenharmony_ci * @RC_FILTER_NORMAL: Filter for normal operation. 468c2ecf20Sopenharmony_ci * @RC_FILTER_WAKEUP: Filter for waking from suspend. 478c2ecf20Sopenharmony_ci * @RC_FILTER_MAX: Number of filter types. 488c2ecf20Sopenharmony_ci */ 498c2ecf20Sopenharmony_cienum rc_filter_type { 508c2ecf20Sopenharmony_ci RC_FILTER_NORMAL = 0, 518c2ecf20Sopenharmony_ci RC_FILTER_WAKEUP, 528c2ecf20Sopenharmony_ci 538c2ecf20Sopenharmony_ci RC_FILTER_MAX 548c2ecf20Sopenharmony_ci}; 558c2ecf20Sopenharmony_ci 568c2ecf20Sopenharmony_ci/** 578c2ecf20Sopenharmony_ci * struct lirc_fh - represents an open lirc file 588c2ecf20Sopenharmony_ci * @list: list of open file handles 598c2ecf20Sopenharmony_ci * @rc: rcdev for this lirc chardev 608c2ecf20Sopenharmony_ci * @carrier_low: when setting the carrier range, first the low end must be 618c2ecf20Sopenharmony_ci * set with an ioctl and then the high end with another ioctl 628c2ecf20Sopenharmony_ci * @send_timeout_reports: report timeouts in lirc raw IR. 638c2ecf20Sopenharmony_ci * @rawir: queue for incoming raw IR 648c2ecf20Sopenharmony_ci * @scancodes: queue for incoming decoded scancodes 658c2ecf20Sopenharmony_ci * @wait_poll: poll struct for lirc device 668c2ecf20Sopenharmony_ci * @send_mode: lirc mode for sending, either LIRC_MODE_SCANCODE or 678c2ecf20Sopenharmony_ci * LIRC_MODE_PULSE 688c2ecf20Sopenharmony_ci * @rec_mode: lirc mode for receiving, either LIRC_MODE_SCANCODE or 698c2ecf20Sopenharmony_ci * LIRC_MODE_MODE2 708c2ecf20Sopenharmony_ci */ 718c2ecf20Sopenharmony_cistruct lirc_fh { 728c2ecf20Sopenharmony_ci struct list_head list; 738c2ecf20Sopenharmony_ci struct rc_dev *rc; 748c2ecf20Sopenharmony_ci int carrier_low; 758c2ecf20Sopenharmony_ci bool send_timeout_reports; 768c2ecf20Sopenharmony_ci DECLARE_KFIFO_PTR(rawir, unsigned int); 778c2ecf20Sopenharmony_ci DECLARE_KFIFO_PTR(scancodes, struct lirc_scancode); 788c2ecf20Sopenharmony_ci wait_queue_head_t wait_poll; 798c2ecf20Sopenharmony_ci u8 send_mode; 808c2ecf20Sopenharmony_ci u8 rec_mode; 818c2ecf20Sopenharmony_ci}; 828c2ecf20Sopenharmony_ci 838c2ecf20Sopenharmony_ci/** 848c2ecf20Sopenharmony_ci * struct rc_dev - represents a remote control device 858c2ecf20Sopenharmony_ci * @dev: driver model's view of this device 868c2ecf20Sopenharmony_ci * @managed_alloc: devm_rc_allocate_device was used to create rc_dev 878c2ecf20Sopenharmony_ci * @sysfs_groups: sysfs attribute groups 888c2ecf20Sopenharmony_ci * @device_name: name of the rc child device 898c2ecf20Sopenharmony_ci * @input_phys: physical path to the input child device 908c2ecf20Sopenharmony_ci * @input_id: id of the input child device (struct input_id) 918c2ecf20Sopenharmony_ci * @driver_name: name of the hardware driver which registered this device 928c2ecf20Sopenharmony_ci * @map_name: name of the default keymap 938c2ecf20Sopenharmony_ci * @rc_map: current scan/key table 948c2ecf20Sopenharmony_ci * @lock: used to ensure we've filled in all protocol details before 958c2ecf20Sopenharmony_ci * anyone can call show_protocols or store_protocols 968c2ecf20Sopenharmony_ci * @minor: unique minor remote control device number 978c2ecf20Sopenharmony_ci * @raw: additional data for raw pulse/space devices 988c2ecf20Sopenharmony_ci * @input_dev: the input child device used to communicate events to userspace 998c2ecf20Sopenharmony_ci * @driver_type: specifies if protocol decoding is done in hardware or software 1008c2ecf20Sopenharmony_ci * @idle: used to keep track of RX state 1018c2ecf20Sopenharmony_ci * @encode_wakeup: wakeup filtering uses IR encode API, therefore the allowed 1028c2ecf20Sopenharmony_ci * wakeup protocols is the set of all raw encoders 1038c2ecf20Sopenharmony_ci * @allowed_protocols: bitmask with the supported RC_PROTO_BIT_* protocols 1048c2ecf20Sopenharmony_ci * @enabled_protocols: bitmask with the enabled RC_PROTO_BIT_* protocols 1058c2ecf20Sopenharmony_ci * @allowed_wakeup_protocols: bitmask with the supported RC_PROTO_BIT_* wakeup 1068c2ecf20Sopenharmony_ci * protocols 1078c2ecf20Sopenharmony_ci * @wakeup_protocol: the enabled RC_PROTO_* wakeup protocol or 1088c2ecf20Sopenharmony_ci * RC_PROTO_UNKNOWN if disabled. 1098c2ecf20Sopenharmony_ci * @scancode_filter: scancode filter 1108c2ecf20Sopenharmony_ci * @scancode_wakeup_filter: scancode wakeup filters 1118c2ecf20Sopenharmony_ci * @scancode_mask: some hardware decoders are not capable of providing the full 1128c2ecf20Sopenharmony_ci * scancode to the application. As this is a hardware limit, we can't do 1138c2ecf20Sopenharmony_ci * anything with it. Yet, as the same keycode table can be used with other 1148c2ecf20Sopenharmony_ci * devices, a mask is provided to allow its usage. Drivers should generally 1158c2ecf20Sopenharmony_ci * leave this field in blank 1168c2ecf20Sopenharmony_ci * @users: number of current users of the device 1178c2ecf20Sopenharmony_ci * @priv: driver-specific data 1188c2ecf20Sopenharmony_ci * @keylock: protects the remaining members of the struct 1198c2ecf20Sopenharmony_ci * @keypressed: whether a key is currently pressed 1208c2ecf20Sopenharmony_ci * @keyup_jiffies: time (in jiffies) when the current keypress should be released 1218c2ecf20Sopenharmony_ci * @timer_keyup: timer for releasing a keypress 1228c2ecf20Sopenharmony_ci * @timer_repeat: timer for autorepeat events. This is needed for CEC, which 1238c2ecf20Sopenharmony_ci * has non-standard repeats. 1248c2ecf20Sopenharmony_ci * @last_keycode: keycode of last keypress 1258c2ecf20Sopenharmony_ci * @last_protocol: protocol of last keypress 1268c2ecf20Sopenharmony_ci * @last_scancode: scancode of last keypress 1278c2ecf20Sopenharmony_ci * @last_toggle: toggle value of last command 1288c2ecf20Sopenharmony_ci * @timeout: optional time after which device stops sending data 1298c2ecf20Sopenharmony_ci * @min_timeout: minimum timeout supported by device 1308c2ecf20Sopenharmony_ci * @max_timeout: maximum timeout supported by device 1318c2ecf20Sopenharmony_ci * @rx_resolution : resolution (in us) of input sampler 1328c2ecf20Sopenharmony_ci * @tx_resolution: resolution (in us) of output sampler 1338c2ecf20Sopenharmony_ci * @lirc_dev: lirc device 1348c2ecf20Sopenharmony_ci * @lirc_cdev: lirc char cdev 1358c2ecf20Sopenharmony_ci * @gap_start: time when gap starts 1368c2ecf20Sopenharmony_ci * @gap_duration: duration of initial gap 1378c2ecf20Sopenharmony_ci * @gap: true if we're in a gap 1388c2ecf20Sopenharmony_ci * @lirc_fh_lock: protects lirc_fh list 1398c2ecf20Sopenharmony_ci * @lirc_fh: list of open files 1408c2ecf20Sopenharmony_ci * @registered: set to true by rc_register_device(), false by 1418c2ecf20Sopenharmony_ci * rc_unregister_device 1428c2ecf20Sopenharmony_ci * @change_protocol: allow changing the protocol used on hardware decoders 1438c2ecf20Sopenharmony_ci * @open: callback to allow drivers to enable polling/irq when IR input device 1448c2ecf20Sopenharmony_ci * is opened. 1458c2ecf20Sopenharmony_ci * @close: callback to allow drivers to disable polling/irq when IR input device 1468c2ecf20Sopenharmony_ci * is opened. 1478c2ecf20Sopenharmony_ci * @s_tx_mask: set transmitter mask (for devices with multiple tx outputs) 1488c2ecf20Sopenharmony_ci * @s_tx_carrier: set transmit carrier frequency 1498c2ecf20Sopenharmony_ci * @s_tx_duty_cycle: set transmit duty cycle (0% - 100%) 1508c2ecf20Sopenharmony_ci * @s_rx_carrier_range: inform driver about carrier it is expected to handle 1518c2ecf20Sopenharmony_ci * @tx_ir: transmit IR 1528c2ecf20Sopenharmony_ci * @s_idle: enable/disable hardware idle mode, upon which, 1538c2ecf20Sopenharmony_ci * device doesn't interrupt host until it sees IR pulses 1548c2ecf20Sopenharmony_ci * @s_learning_mode: enable wide band receiver used for learning 1558c2ecf20Sopenharmony_ci * @s_carrier_report: enable carrier reports 1568c2ecf20Sopenharmony_ci * @s_filter: set the scancode filter 1578c2ecf20Sopenharmony_ci * @s_wakeup_filter: set the wakeup scancode filter. If the mask is zero 1588c2ecf20Sopenharmony_ci * then wakeup should be disabled. wakeup_protocol will be set to 1598c2ecf20Sopenharmony_ci * a valid protocol if mask is nonzero. 1608c2ecf20Sopenharmony_ci * @s_timeout: set hardware timeout in us 1618c2ecf20Sopenharmony_ci */ 1628c2ecf20Sopenharmony_cistruct rc_dev { 1638c2ecf20Sopenharmony_ci struct device dev; 1648c2ecf20Sopenharmony_ci bool managed_alloc; 1658c2ecf20Sopenharmony_ci const struct attribute_group *sysfs_groups[5]; 1668c2ecf20Sopenharmony_ci const char *device_name; 1678c2ecf20Sopenharmony_ci const char *input_phys; 1688c2ecf20Sopenharmony_ci struct input_id input_id; 1698c2ecf20Sopenharmony_ci const char *driver_name; 1708c2ecf20Sopenharmony_ci const char *map_name; 1718c2ecf20Sopenharmony_ci struct rc_map rc_map; 1728c2ecf20Sopenharmony_ci struct mutex lock; 1738c2ecf20Sopenharmony_ci unsigned int minor; 1748c2ecf20Sopenharmony_ci struct ir_raw_event_ctrl *raw; 1758c2ecf20Sopenharmony_ci struct input_dev *input_dev; 1768c2ecf20Sopenharmony_ci enum rc_driver_type driver_type; 1778c2ecf20Sopenharmony_ci bool idle; 1788c2ecf20Sopenharmony_ci bool encode_wakeup; 1798c2ecf20Sopenharmony_ci u64 allowed_protocols; 1808c2ecf20Sopenharmony_ci u64 enabled_protocols; 1818c2ecf20Sopenharmony_ci u64 allowed_wakeup_protocols; 1828c2ecf20Sopenharmony_ci enum rc_proto wakeup_protocol; 1838c2ecf20Sopenharmony_ci struct rc_scancode_filter scancode_filter; 1848c2ecf20Sopenharmony_ci struct rc_scancode_filter scancode_wakeup_filter; 1858c2ecf20Sopenharmony_ci u32 scancode_mask; 1868c2ecf20Sopenharmony_ci u32 users; 1878c2ecf20Sopenharmony_ci void *priv; 1888c2ecf20Sopenharmony_ci spinlock_t keylock; 1898c2ecf20Sopenharmony_ci bool keypressed; 1908c2ecf20Sopenharmony_ci unsigned long keyup_jiffies; 1918c2ecf20Sopenharmony_ci struct timer_list timer_keyup; 1928c2ecf20Sopenharmony_ci struct timer_list timer_repeat; 1938c2ecf20Sopenharmony_ci u32 last_keycode; 1948c2ecf20Sopenharmony_ci enum rc_proto last_protocol; 1958c2ecf20Sopenharmony_ci u64 last_scancode; 1968c2ecf20Sopenharmony_ci u8 last_toggle; 1978c2ecf20Sopenharmony_ci u32 timeout; 1988c2ecf20Sopenharmony_ci u32 min_timeout; 1998c2ecf20Sopenharmony_ci u32 max_timeout; 2008c2ecf20Sopenharmony_ci u32 rx_resolution; 2018c2ecf20Sopenharmony_ci u32 tx_resolution; 2028c2ecf20Sopenharmony_ci#ifdef CONFIG_LIRC 2038c2ecf20Sopenharmony_ci struct device lirc_dev; 2048c2ecf20Sopenharmony_ci struct cdev lirc_cdev; 2058c2ecf20Sopenharmony_ci ktime_t gap_start; 2068c2ecf20Sopenharmony_ci u64 gap_duration; 2078c2ecf20Sopenharmony_ci bool gap; 2088c2ecf20Sopenharmony_ci spinlock_t lirc_fh_lock; 2098c2ecf20Sopenharmony_ci struct list_head lirc_fh; 2108c2ecf20Sopenharmony_ci#endif 2118c2ecf20Sopenharmony_ci bool registered; 2128c2ecf20Sopenharmony_ci int (*change_protocol)(struct rc_dev *dev, u64 *rc_proto); 2138c2ecf20Sopenharmony_ci int (*open)(struct rc_dev *dev); 2148c2ecf20Sopenharmony_ci void (*close)(struct rc_dev *dev); 2158c2ecf20Sopenharmony_ci int (*s_tx_mask)(struct rc_dev *dev, u32 mask); 2168c2ecf20Sopenharmony_ci int (*s_tx_carrier)(struct rc_dev *dev, u32 carrier); 2178c2ecf20Sopenharmony_ci int (*s_tx_duty_cycle)(struct rc_dev *dev, u32 duty_cycle); 2188c2ecf20Sopenharmony_ci int (*s_rx_carrier_range)(struct rc_dev *dev, u32 min, u32 max); 2198c2ecf20Sopenharmony_ci int (*tx_ir)(struct rc_dev *dev, unsigned *txbuf, unsigned n); 2208c2ecf20Sopenharmony_ci void (*s_idle)(struct rc_dev *dev, bool enable); 2218c2ecf20Sopenharmony_ci int (*s_learning_mode)(struct rc_dev *dev, int enable); 2228c2ecf20Sopenharmony_ci int (*s_carrier_report) (struct rc_dev *dev, int enable); 2238c2ecf20Sopenharmony_ci int (*s_filter)(struct rc_dev *dev, 2248c2ecf20Sopenharmony_ci struct rc_scancode_filter *filter); 2258c2ecf20Sopenharmony_ci int (*s_wakeup_filter)(struct rc_dev *dev, 2268c2ecf20Sopenharmony_ci struct rc_scancode_filter *filter); 2278c2ecf20Sopenharmony_ci int (*s_timeout)(struct rc_dev *dev, 2288c2ecf20Sopenharmony_ci unsigned int timeout); 2298c2ecf20Sopenharmony_ci}; 2308c2ecf20Sopenharmony_ci 2318c2ecf20Sopenharmony_ci#define to_rc_dev(d) container_of(d, struct rc_dev, dev) 2328c2ecf20Sopenharmony_ci 2338c2ecf20Sopenharmony_ci/* 2348c2ecf20Sopenharmony_ci * From rc-main.c 2358c2ecf20Sopenharmony_ci * Those functions can be used on any type of Remote Controller. They 2368c2ecf20Sopenharmony_ci * basically creates an input_dev and properly reports the device as a 2378c2ecf20Sopenharmony_ci * Remote Controller, at sys/class/rc. 2388c2ecf20Sopenharmony_ci */ 2398c2ecf20Sopenharmony_ci 2408c2ecf20Sopenharmony_ci/** 2418c2ecf20Sopenharmony_ci * rc_allocate_device - Allocates a RC device 2428c2ecf20Sopenharmony_ci * 2438c2ecf20Sopenharmony_ci * @rc_driver_type: specifies the type of the RC output to be allocated 2448c2ecf20Sopenharmony_ci * returns a pointer to struct rc_dev. 2458c2ecf20Sopenharmony_ci */ 2468c2ecf20Sopenharmony_cistruct rc_dev *rc_allocate_device(enum rc_driver_type); 2478c2ecf20Sopenharmony_ci 2488c2ecf20Sopenharmony_ci/** 2498c2ecf20Sopenharmony_ci * devm_rc_allocate_device - Managed RC device allocation 2508c2ecf20Sopenharmony_ci * 2518c2ecf20Sopenharmony_ci * @dev: pointer to struct device 2528c2ecf20Sopenharmony_ci * @rc_driver_type: specifies the type of the RC output to be allocated 2538c2ecf20Sopenharmony_ci * returns a pointer to struct rc_dev. 2548c2ecf20Sopenharmony_ci */ 2558c2ecf20Sopenharmony_cistruct rc_dev *devm_rc_allocate_device(struct device *dev, enum rc_driver_type); 2568c2ecf20Sopenharmony_ci 2578c2ecf20Sopenharmony_ci/** 2588c2ecf20Sopenharmony_ci * rc_free_device - Frees a RC device 2598c2ecf20Sopenharmony_ci * 2608c2ecf20Sopenharmony_ci * @dev: pointer to struct rc_dev. 2618c2ecf20Sopenharmony_ci */ 2628c2ecf20Sopenharmony_civoid rc_free_device(struct rc_dev *dev); 2638c2ecf20Sopenharmony_ci 2648c2ecf20Sopenharmony_ci/** 2658c2ecf20Sopenharmony_ci * rc_register_device - Registers a RC device 2668c2ecf20Sopenharmony_ci * 2678c2ecf20Sopenharmony_ci * @dev: pointer to struct rc_dev. 2688c2ecf20Sopenharmony_ci */ 2698c2ecf20Sopenharmony_ciint rc_register_device(struct rc_dev *dev); 2708c2ecf20Sopenharmony_ci 2718c2ecf20Sopenharmony_ci/** 2728c2ecf20Sopenharmony_ci * devm_rc_register_device - Manageded registering of a RC device 2738c2ecf20Sopenharmony_ci * 2748c2ecf20Sopenharmony_ci * @parent: pointer to struct device. 2758c2ecf20Sopenharmony_ci * @dev: pointer to struct rc_dev. 2768c2ecf20Sopenharmony_ci */ 2778c2ecf20Sopenharmony_ciint devm_rc_register_device(struct device *parent, struct rc_dev *dev); 2788c2ecf20Sopenharmony_ci 2798c2ecf20Sopenharmony_ci/** 2808c2ecf20Sopenharmony_ci * rc_unregister_device - Unregisters a RC device 2818c2ecf20Sopenharmony_ci * 2828c2ecf20Sopenharmony_ci * @dev: pointer to struct rc_dev. 2838c2ecf20Sopenharmony_ci */ 2848c2ecf20Sopenharmony_civoid rc_unregister_device(struct rc_dev *dev); 2858c2ecf20Sopenharmony_ci 2868c2ecf20Sopenharmony_civoid rc_repeat(struct rc_dev *dev); 2878c2ecf20Sopenharmony_civoid rc_keydown(struct rc_dev *dev, enum rc_proto protocol, u64 scancode, 2888c2ecf20Sopenharmony_ci u8 toggle); 2898c2ecf20Sopenharmony_civoid rc_keydown_notimeout(struct rc_dev *dev, enum rc_proto protocol, 2908c2ecf20Sopenharmony_ci u64 scancode, u8 toggle); 2918c2ecf20Sopenharmony_civoid rc_keyup(struct rc_dev *dev); 2928c2ecf20Sopenharmony_ciu32 rc_g_keycode_from_table(struct rc_dev *dev, u64 scancode); 2938c2ecf20Sopenharmony_ci 2948c2ecf20Sopenharmony_ci/* 2958c2ecf20Sopenharmony_ci * From rc-raw.c 2968c2ecf20Sopenharmony_ci * The Raw interface is specific to InfraRed. It may be a good idea to 2978c2ecf20Sopenharmony_ci * split it later into a separate header. 2988c2ecf20Sopenharmony_ci */ 2998c2ecf20Sopenharmony_cistruct ir_raw_event { 3008c2ecf20Sopenharmony_ci union { 3018c2ecf20Sopenharmony_ci u32 duration; 3028c2ecf20Sopenharmony_ci u32 carrier; 3038c2ecf20Sopenharmony_ci }; 3048c2ecf20Sopenharmony_ci u8 duty_cycle; 3058c2ecf20Sopenharmony_ci 3068c2ecf20Sopenharmony_ci unsigned pulse:1; 3078c2ecf20Sopenharmony_ci unsigned reset:1; 3088c2ecf20Sopenharmony_ci unsigned timeout:1; 3098c2ecf20Sopenharmony_ci unsigned carrier_report:1; 3108c2ecf20Sopenharmony_ci}; 3118c2ecf20Sopenharmony_ci 3128c2ecf20Sopenharmony_ci#define US_TO_NS(usec) ((usec) * 1000) 3138c2ecf20Sopenharmony_ci#define MS_TO_US(msec) ((msec) * 1000) 3148c2ecf20Sopenharmony_ci#define IR_MAX_DURATION MS_TO_US(500) 3158c2ecf20Sopenharmony_ci#define IR_DEFAULT_TIMEOUT MS_TO_US(125) 3168c2ecf20Sopenharmony_ci 3178c2ecf20Sopenharmony_civoid ir_raw_event_handle(struct rc_dev *dev); 3188c2ecf20Sopenharmony_ciint ir_raw_event_store(struct rc_dev *dev, struct ir_raw_event *ev); 3198c2ecf20Sopenharmony_ciint ir_raw_event_store_edge(struct rc_dev *dev, bool pulse); 3208c2ecf20Sopenharmony_ciint ir_raw_event_store_with_filter(struct rc_dev *dev, 3218c2ecf20Sopenharmony_ci struct ir_raw_event *ev); 3228c2ecf20Sopenharmony_ciint ir_raw_event_store_with_timeout(struct rc_dev *dev, 3238c2ecf20Sopenharmony_ci struct ir_raw_event *ev); 3248c2ecf20Sopenharmony_civoid ir_raw_event_set_idle(struct rc_dev *dev, bool idle); 3258c2ecf20Sopenharmony_ciint ir_raw_encode_scancode(enum rc_proto protocol, u32 scancode, 3268c2ecf20Sopenharmony_ci struct ir_raw_event *events, unsigned int max); 3278c2ecf20Sopenharmony_ciint ir_raw_encode_carrier(enum rc_proto protocol); 3288c2ecf20Sopenharmony_ci 3298c2ecf20Sopenharmony_cistatic inline void ir_raw_event_reset(struct rc_dev *dev) 3308c2ecf20Sopenharmony_ci{ 3318c2ecf20Sopenharmony_ci ir_raw_event_store(dev, &((struct ir_raw_event) { .reset = true })); 3328c2ecf20Sopenharmony_ci dev->idle = true; 3338c2ecf20Sopenharmony_ci ir_raw_event_handle(dev); 3348c2ecf20Sopenharmony_ci} 3358c2ecf20Sopenharmony_ci 3368c2ecf20Sopenharmony_ci/* extract mask bits out of data and pack them into the result */ 3378c2ecf20Sopenharmony_cistatic inline u32 ir_extract_bits(u32 data, u32 mask) 3388c2ecf20Sopenharmony_ci{ 3398c2ecf20Sopenharmony_ci u32 vbit = 1, value = 0; 3408c2ecf20Sopenharmony_ci 3418c2ecf20Sopenharmony_ci do { 3428c2ecf20Sopenharmony_ci if (mask & 1) { 3438c2ecf20Sopenharmony_ci if (data & 1) 3448c2ecf20Sopenharmony_ci value |= vbit; 3458c2ecf20Sopenharmony_ci vbit <<= 1; 3468c2ecf20Sopenharmony_ci } 3478c2ecf20Sopenharmony_ci data >>= 1; 3488c2ecf20Sopenharmony_ci } while (mask >>= 1); 3498c2ecf20Sopenharmony_ci 3508c2ecf20Sopenharmony_ci return value; 3518c2ecf20Sopenharmony_ci} 3528c2ecf20Sopenharmony_ci 3538c2ecf20Sopenharmony_ci/* Get NEC scancode and protocol type from address and command bytes */ 3548c2ecf20Sopenharmony_cistatic inline u32 ir_nec_bytes_to_scancode(u8 address, u8 not_address, 3558c2ecf20Sopenharmony_ci u8 command, u8 not_command, 3568c2ecf20Sopenharmony_ci enum rc_proto *protocol) 3578c2ecf20Sopenharmony_ci{ 3588c2ecf20Sopenharmony_ci u32 scancode; 3598c2ecf20Sopenharmony_ci 3608c2ecf20Sopenharmony_ci if ((command ^ not_command) != 0xff) { 3618c2ecf20Sopenharmony_ci /* NEC transport, but modified protocol, used by at 3628c2ecf20Sopenharmony_ci * least Apple and TiVo remotes 3638c2ecf20Sopenharmony_ci */ 3648c2ecf20Sopenharmony_ci scancode = not_address << 24 | 3658c2ecf20Sopenharmony_ci address << 16 | 3668c2ecf20Sopenharmony_ci not_command << 8 | 3678c2ecf20Sopenharmony_ci command; 3688c2ecf20Sopenharmony_ci *protocol = RC_PROTO_NEC32; 3698c2ecf20Sopenharmony_ci } else if ((address ^ not_address) != 0xff) { 3708c2ecf20Sopenharmony_ci /* Extended NEC */ 3718c2ecf20Sopenharmony_ci scancode = address << 16 | 3728c2ecf20Sopenharmony_ci not_address << 8 | 3738c2ecf20Sopenharmony_ci command; 3748c2ecf20Sopenharmony_ci *protocol = RC_PROTO_NECX; 3758c2ecf20Sopenharmony_ci } else { 3768c2ecf20Sopenharmony_ci /* Normal NEC */ 3778c2ecf20Sopenharmony_ci scancode = address << 8 | command; 3788c2ecf20Sopenharmony_ci *protocol = RC_PROTO_NEC; 3798c2ecf20Sopenharmony_ci } 3808c2ecf20Sopenharmony_ci 3818c2ecf20Sopenharmony_ci return scancode; 3828c2ecf20Sopenharmony_ci} 3838c2ecf20Sopenharmony_ci 3848c2ecf20Sopenharmony_ci#endif /* _RC_CORE */ 385