From 7c9ca5e4777bd7afdaa03b010a9c3a04f3ba916d Mon Sep 17 00:00:00 2001 From: Fabio Belavenuto Date: Thu, 2 Feb 2023 14:05:13 -0300 Subject: [PATCH] Adding rc module --- apollolake-4.4.180/rc-core.ko | Bin 0 -> 38792 bytes broadwell-4.4.180/rc-core.ko | Bin 0 -> 39352 bytes broadwellnk-4.4.180/rc-core.ko | Bin 0 -> 39352 bytes denverton-4.4.180/rc-core.ko | Bin 0 -> 39416 bytes geminilake-4.4.180/rc-core.ko | Bin 0 -> 38664 bytes r1000-4.4.180/rc-core.ko | Bin 0 -> 39352 bytes src/4.x/defines.apollolake | 1 + src/4.x/drivers/media/Makefile | 2 +- src/4.x/drivers/media/rc/Makefile | 39 + src/4.x/drivers/media/rc/rc-core-priv.h | 241 ++++ src/4.x/drivers/media/rc/rc-ir-raw.c | 369 ++++++ src/4.x/drivers/media/rc/rc-main.c | 1538 +++++++++++++++++++++++ v1000-4.4.180/rc-core.ko | Bin 0 -> 39352 bytes 13 files changed, 2189 insertions(+), 1 deletion(-) create mode 100644 apollolake-4.4.180/rc-core.ko create mode 100644 broadwell-4.4.180/rc-core.ko create mode 100644 broadwellnk-4.4.180/rc-core.ko create mode 100644 denverton-4.4.180/rc-core.ko create mode 100644 geminilake-4.4.180/rc-core.ko create mode 100644 r1000-4.4.180/rc-core.ko create mode 100644 src/4.x/drivers/media/rc/Makefile create mode 100644 src/4.x/drivers/media/rc/rc-core-priv.h create mode 100644 src/4.x/drivers/media/rc/rc-ir-raw.c create mode 100644 src/4.x/drivers/media/rc/rc-main.c create mode 100644 v1000-4.4.180/rc-core.ko diff --git a/apollolake-4.4.180/rc-core.ko b/apollolake-4.4.180/rc-core.ko new file mode 100644 index 0000000000000000000000000000000000000000..637fa12e5f4afc287483e04915e34dbff8c3289d GIT binary patch literal 38792 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 literal 0 HcmV?d00001 diff --git a/denverton-4.4.180/rc-core.ko b/denverton-4.4.180/rc-core.ko new file mode 100644 index 0000000000000000000000000000000000000000..e659d67322190484cd8ba723e0473c5a21a1578b GIT binary patch literal 39416 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 literal 0 HcmV?d00001 diff --git a/geminilake-4.4.180/rc-core.ko b/geminilake-4.4.180/rc-core.ko new file mode 100644 index 0000000000000000000000000000000000000000..b7cbcccf2dba75879601e587863466a95349c5bf GIT binary patch literal 38664 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 literal 0 HcmV?d00001 diff --git a/r1000-4.4.180/rc-core.ko b/r1000-4.4.180/rc-core.ko new file mode 100644 index 0000000000000000000000000000000000000000..80ec270795ef1cd0cd066b3c63019365cd0acb44 GIT binary patch literal 39352 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 +#include +#include + +struct ir_raw_handler { + struct list_head list; + + u64 protocols; /* which are handled by this handler */ + int (*decode)(struct rc_dev *dev, struct ir_raw_event event); + + /* These two should only be used by the lirc decoder */ + int (*raw_register)(struct rc_dev *dev); + int (*raw_unregister)(struct rc_dev *dev); +}; + +struct ir_raw_event_ctrl { + struct list_head list; /* to keep track of raw clients */ + struct task_struct *thread; + spinlock_t lock; + struct kfifo_rec_ptr_1 kfifo; /* fifo for the pulse/space durations */ + ktime_t last_event; /* when last event occurred */ + enum raw_event_type last_type; /* last event type */ + struct rc_dev *dev; /* pointer to the parent rc_dev */ + + /* raw decoder state follows */ + struct ir_raw_event prev_ev; + struct ir_raw_event this_ev; + struct nec_dec { + int state; + unsigned count; + u32 bits; + bool is_nec_x; + bool necx_repeat; + } nec; + struct rc5_dec { + int state; + u32 bits; + unsigned count; + bool is_rc5x; + } rc5; + struct rc6_dec { + int state; + u8 header; + u32 body; + bool toggle; + unsigned count; + unsigned wanted_bits; + } rc6; + struct sony_dec { + int state; + u32 bits; + unsigned count; + } sony; + struct jvc_dec { + int state; + u16 bits; + u16 old_bits; + unsigned count; + bool first; + bool toggle; + } jvc; + struct sanyo_dec { + int state; + unsigned count; + u64 bits; + } sanyo; + struct sharp_dec { + int state; + unsigned count; + u32 bits; + unsigned int pulse_len; + } sharp; + struct mce_kbd_dec { + struct input_dev *idev; + struct timer_list rx_timeout; + char name[64]; + char phys[64]; + int state; + u8 header; + u32 body; + unsigned count; + unsigned wanted_bits; + } mce_kbd; + struct lirc_codec { + struct rc_dev *dev; + struct lirc_driver *drv; + int carrier_low; + + ktime_t gap_start; + u64 gap_duration; + bool gap; + bool send_timeout_reports; + + } lirc; + struct xmp_dec { + int state; + unsigned count; + u32 durations[16]; + } xmp; +}; + +/* macros for IR decoders */ +static inline bool geq_margin(unsigned d1, unsigned d2, unsigned margin) +{ + return d1 > (d2 - margin); +} + +static inline bool eq_margin(unsigned d1, unsigned d2, unsigned margin) +{ + return ((d1 > (d2 - margin)) && (d1 < (d2 + margin))); +} + +static inline bool is_transition(struct ir_raw_event *x, struct ir_raw_event *y) +{ + return x->pulse != y->pulse; +} + +static inline void decrease_duration(struct ir_raw_event *ev, unsigned duration) +{ + if (duration > ev->duration) + ev->duration = 0; + else + ev->duration -= duration; +} + +/* Returns true if event is normal pulse/space event */ +static inline bool is_timing_event(struct ir_raw_event ev) +{ + return !ev.carrier_report && !ev.reset; +} + +#define TO_US(duration) DIV_ROUND_CLOSEST((duration), 1000) +#define TO_STR(is_pulse) ((is_pulse) ? "pulse" : "space") + +/* + * Routines from rc-raw.c to be used internally and by decoders + */ +u64 ir_raw_get_allowed_protocols(void); +int ir_raw_event_register(struct rc_dev *dev); +void ir_raw_event_unregister(struct rc_dev *dev); +int ir_raw_handler_register(struct ir_raw_handler *ir_raw_handler); +void ir_raw_handler_unregister(struct ir_raw_handler *ir_raw_handler); +void ir_raw_init(void); + +/* + * Decoder initialization code + * + * Those load logic are called during ir-core init, and automatically + * loads the compiled decoders for their usage with IR raw events + */ + +/* from ir-nec-decoder.c */ +#ifdef CONFIG_IR_NEC_DECODER_MODULE +#define load_nec_decode() request_module_nowait("ir-nec-decoder") +#else +static inline void load_nec_decode(void) { } +#endif + +/* from ir-rc5-decoder.c */ +#ifdef CONFIG_IR_RC5_DECODER_MODULE +#define load_rc5_decode() request_module_nowait("ir-rc5-decoder") +#else +static inline void load_rc5_decode(void) { } +#endif + +/* from ir-rc6-decoder.c */ +#ifdef CONFIG_IR_RC6_DECODER_MODULE +#define load_rc6_decode() request_module_nowait("ir-rc6-decoder") +#else +static inline void load_rc6_decode(void) { } +#endif + +/* from ir-jvc-decoder.c */ +#ifdef CONFIG_IR_JVC_DECODER_MODULE +#define load_jvc_decode() request_module_nowait("ir-jvc-decoder") +#else +static inline void load_jvc_decode(void) { } +#endif + +/* from ir-sony-decoder.c */ +#ifdef CONFIG_IR_SONY_DECODER_MODULE +#define load_sony_decode() request_module_nowait("ir-sony-decoder") +#else +static inline void load_sony_decode(void) { } +#endif + +/* from ir-sanyo-decoder.c */ +#ifdef CONFIG_IR_SANYO_DECODER_MODULE +#define load_sanyo_decode() request_module_nowait("ir-sanyo-decoder") +#else +static inline void load_sanyo_decode(void) { } +#endif + +/* from ir-sharp-decoder.c */ +#ifdef CONFIG_IR_SHARP_DECODER_MODULE +#define load_sharp_decode() request_module_nowait("ir-sharp-decoder") +#else +static inline void load_sharp_decode(void) { } +#endif + +/* from ir-mce_kbd-decoder.c */ +#ifdef CONFIG_IR_MCE_KBD_DECODER_MODULE +#define load_mce_kbd_decode() request_module_nowait("ir-mce_kbd-decoder") +#else +static inline void load_mce_kbd_decode(void) { } +#endif + +/* from ir-lirc-codec.c */ +#ifdef CONFIG_IR_LIRC_CODEC_MODULE +#define load_lirc_codec() request_module_nowait("ir-lirc-codec") +#else +static inline void load_lirc_codec(void) { } +#endif + +/* from ir-xmp-decoder.c */ +#ifdef CONFIG_IR_XMP_DECODER_MODULE +#define load_xmp_decode() request_module_nowait("ir-xmp-decoder") +#else +static inline void load_xmp_decode(void) { } +#endif + + +#endif /* _RC_CORE_PRIV */ diff --git a/src/4.x/drivers/media/rc/rc-ir-raw.c b/src/4.x/drivers/media/rc/rc-ir-raw.c new file mode 100644 index 000000000..ad260520a --- /dev/null +++ b/src/4.x/drivers/media/rc/rc-ir-raw.c @@ -0,0 +1,369 @@ +/* rc-ir-raw.c - handle IR pulse/space events + * + * Copyright (C) 2010 by Mauro Carvalho Chehab + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include "rc-core-priv.h" + +/* Define the max number of pulse/space transitions to buffer */ +#define MAX_IR_EVENT_SIZE 512 + +/* Used to keep track of IR raw clients, protected by ir_raw_handler_lock */ +static LIST_HEAD(ir_raw_client_list); + +/* Used to handle IR raw handler extensions */ +static DEFINE_MUTEX(ir_raw_handler_lock); +static LIST_HEAD(ir_raw_handler_list); +static u64 available_protocols; + +static int ir_raw_event_thread(void *data) +{ + struct ir_raw_event ev; + struct ir_raw_handler *handler; + struct ir_raw_event_ctrl *raw = (struct ir_raw_event_ctrl *)data; + int retval; + + while (!kthread_should_stop()) { + + spin_lock_irq(&raw->lock); + retval = kfifo_len(&raw->kfifo); + + if (retval < sizeof(ev)) { + set_current_state(TASK_INTERRUPTIBLE); + + if (kthread_should_stop()) + set_current_state(TASK_RUNNING); + + spin_unlock_irq(&raw->lock); + schedule(); + continue; + } + + retval = kfifo_out(&raw->kfifo, &ev, sizeof(ev)); + spin_unlock_irq(&raw->lock); + + mutex_lock(&ir_raw_handler_lock); + list_for_each_entry(handler, &ir_raw_handler_list, list) + handler->decode(raw->dev, ev); + raw->prev_ev = ev; + mutex_unlock(&ir_raw_handler_lock); + } + + return 0; +} + +/** + * ir_raw_event_store() - pass a pulse/space duration to the raw ir decoders + * @dev: the struct rc_dev device descriptor + * @ev: the struct ir_raw_event descriptor of the pulse/space + * + * This routine (which may be called from an interrupt context) stores a + * pulse/space duration for the raw ir decoding state machines. Pulses are + * signalled as positive values and spaces as negative values. A zero value + * will reset the decoding state machines. + */ +int ir_raw_event_store(struct rc_dev *dev, struct ir_raw_event *ev) +{ + if (!dev->raw) + return -EINVAL; + + IR_dprintk(2, "sample: (%05dus %s)\n", + TO_US(ev->duration), TO_STR(ev->pulse)); + + if (kfifo_in(&dev->raw->kfifo, ev, sizeof(*ev)) != sizeof(*ev)) + return -ENOMEM; + + return 0; +} +EXPORT_SYMBOL_GPL(ir_raw_event_store); + +/** + * ir_raw_event_store_edge() - notify raw ir decoders of the start of a pulse/space + * @dev: the struct rc_dev device descriptor + * @type: the type of the event that has occurred + * + * This routine (which may be called from an interrupt context) is used to + * store the beginning of an ir pulse or space (or the start/end of ir + * reception) for the raw ir decoding state machines. This is used by + * hardware which does not provide durations directly but only interrupts + * (or similar events) on state change. + */ +int ir_raw_event_store_edge(struct rc_dev *dev, enum raw_event_type type) +{ + ktime_t now; + s64 delta; /* ns */ + DEFINE_IR_RAW_EVENT(ev); + int rc = 0; + int delay; + + if (!dev->raw) + return -EINVAL; + + now = ktime_get(); + delta = ktime_to_ns(ktime_sub(now, dev->raw->last_event)); + delay = MS_TO_NS(dev->input_dev->rep[REP_DELAY]); + + /* Check for a long duration since last event or if we're + * being called for the first time, note that delta can't + * possibly be negative. + */ + if (delta > delay || !dev->raw->last_type) + type |= IR_START_EVENT; + else + ev.duration = delta; + + if (type & IR_START_EVENT) + ir_raw_event_reset(dev); + else if (dev->raw->last_type & IR_SPACE) { + ev.pulse = false; + rc = ir_raw_event_store(dev, &ev); + } else if (dev->raw->last_type & IR_PULSE) { + ev.pulse = true; + rc = ir_raw_event_store(dev, &ev); + } else + return 0; + + dev->raw->last_event = now; + dev->raw->last_type = type; + return rc; +} +EXPORT_SYMBOL_GPL(ir_raw_event_store_edge); + +/** + * ir_raw_event_store_with_filter() - pass next pulse/space to decoders with some processing + * @dev: the struct rc_dev device descriptor + * @type: the type of the event that has occurred + * + * This routine (which may be called from an interrupt context) works + * in similar manner to ir_raw_event_store_edge. + * This routine is intended for devices with limited internal buffer + * It automerges samples of same type, and handles timeouts. Returns non-zero + * if the event was added, and zero if the event was ignored due to idle + * processing. + */ +int ir_raw_event_store_with_filter(struct rc_dev *dev, struct ir_raw_event *ev) +{ + if (!dev->raw) + return -EINVAL; + + /* Ignore spaces in idle mode */ + if (dev->idle && !ev->pulse) + return 0; + else if (dev->idle) + ir_raw_event_set_idle(dev, false); + + if (!dev->raw->this_ev.duration) + dev->raw->this_ev = *ev; + else if (ev->pulse == dev->raw->this_ev.pulse) + dev->raw->this_ev.duration += ev->duration; + else { + ir_raw_event_store(dev, &dev->raw->this_ev); + dev->raw->this_ev = *ev; + } + + /* Enter idle mode if nessesary */ + if (!ev->pulse && dev->timeout && + dev->raw->this_ev.duration >= dev->timeout) + ir_raw_event_set_idle(dev, true); + + return 1; +} +EXPORT_SYMBOL_GPL(ir_raw_event_store_with_filter); + +/** + * ir_raw_event_set_idle() - provide hint to rc-core when the device is idle or not + * @dev: the struct rc_dev device descriptor + * @idle: whether the device is idle or not + */ +void ir_raw_event_set_idle(struct rc_dev *dev, bool idle) +{ + if (!dev->raw) + return; + + IR_dprintk(2, "%s idle mode\n", idle ? "enter" : "leave"); + + if (idle) { + dev->raw->this_ev.timeout = true; + ir_raw_event_store(dev, &dev->raw->this_ev); + init_ir_raw_event(&dev->raw->this_ev); + } + + if (dev->s_idle) + dev->s_idle(dev, idle); + + dev->idle = idle; +} +EXPORT_SYMBOL_GPL(ir_raw_event_set_idle); + +/** + * ir_raw_event_handle() - schedules the decoding of stored ir data + * @dev: the struct rc_dev device descriptor + * + * This routine will tell rc-core to start decoding stored ir data. + */ +void ir_raw_event_handle(struct rc_dev *dev) +{ + unsigned long flags; + + if (!dev->raw) + return; + + spin_lock_irqsave(&dev->raw->lock, flags); + wake_up_process(dev->raw->thread); + spin_unlock_irqrestore(&dev->raw->lock, flags); +} +EXPORT_SYMBOL_GPL(ir_raw_event_handle); + +/* used internally by the sysfs interface */ +u64 +ir_raw_get_allowed_protocols(void) +{ + u64 protocols; + mutex_lock(&ir_raw_handler_lock); + protocols = available_protocols; + mutex_unlock(&ir_raw_handler_lock); + return protocols; +} + +static int change_protocol(struct rc_dev *dev, u64 *rc_type) +{ + /* the caller will update dev->enabled_protocols */ + return 0; +} + +/* + * Used to (un)register raw event clients + */ +int ir_raw_event_register(struct rc_dev *dev) +{ + int rc; + struct ir_raw_handler *handler; + + if (!dev) + return -EINVAL; + + dev->raw = kzalloc(sizeof(*dev->raw), GFP_KERNEL); + if (!dev->raw) + return -ENOMEM; + + dev->raw->dev = dev; + dev->change_protocol = change_protocol; + rc = kfifo_alloc(&dev->raw->kfifo, + sizeof(struct ir_raw_event) * MAX_IR_EVENT_SIZE, + GFP_KERNEL); + if (rc < 0) + goto out; + + spin_lock_init(&dev->raw->lock); + dev->raw->thread = kthread_run(ir_raw_event_thread, dev->raw, + "rc%u", dev->minor); + + if (IS_ERR(dev->raw->thread)) { + rc = PTR_ERR(dev->raw->thread); + goto out; + } + + mutex_lock(&ir_raw_handler_lock); + list_add_tail(&dev->raw->list, &ir_raw_client_list); + list_for_each_entry(handler, &ir_raw_handler_list, list) + if (handler->raw_register) + handler->raw_register(dev); + mutex_unlock(&ir_raw_handler_lock); + + return 0; + +out: + kfree(dev->raw); + dev->raw = NULL; + return rc; +} + +void ir_raw_event_unregister(struct rc_dev *dev) +{ + struct ir_raw_handler *handler; + + if (!dev || !dev->raw) + return; + + kthread_stop(dev->raw->thread); + + mutex_lock(&ir_raw_handler_lock); + list_del(&dev->raw->list); + list_for_each_entry(handler, &ir_raw_handler_list, list) + if (handler->raw_unregister) + handler->raw_unregister(dev); + mutex_unlock(&ir_raw_handler_lock); + + kfifo_free(&dev->raw->kfifo); + kfree(dev->raw); + dev->raw = NULL; +} + +/* + * Extension interface - used to register the IR decoders + */ + +int ir_raw_handler_register(struct ir_raw_handler *ir_raw_handler) +{ + struct ir_raw_event_ctrl *raw; + + mutex_lock(&ir_raw_handler_lock); + list_add_tail(&ir_raw_handler->list, &ir_raw_handler_list); + if (ir_raw_handler->raw_register) + list_for_each_entry(raw, &ir_raw_client_list, list) + ir_raw_handler->raw_register(raw->dev); + available_protocols |= ir_raw_handler->protocols; + mutex_unlock(&ir_raw_handler_lock); + + return 0; +} +EXPORT_SYMBOL(ir_raw_handler_register); + +void ir_raw_handler_unregister(struct ir_raw_handler *ir_raw_handler) +{ + struct ir_raw_event_ctrl *raw; + + mutex_lock(&ir_raw_handler_lock); + list_del(&ir_raw_handler->list); + if (ir_raw_handler->raw_unregister) + list_for_each_entry(raw, &ir_raw_client_list, list) + ir_raw_handler->raw_unregister(raw->dev); + available_protocols &= ~ir_raw_handler->protocols; + mutex_unlock(&ir_raw_handler_lock); +} +EXPORT_SYMBOL(ir_raw_handler_unregister); + +void ir_raw_init(void) +{ + /* Load the decoder modules */ + + load_nec_decode(); + load_rc5_decode(); + load_rc6_decode(); + load_jvc_decode(); + load_sony_decode(); + load_sanyo_decode(); + load_sharp_decode(); + load_mce_kbd_decode(); + load_lirc_codec(); + load_xmp_decode(); + + /* If needed, we may later add some init code. In this case, + it is needed to change the CONFIG_MODULE test at rc-core.h + */ +} diff --git a/src/4.x/drivers/media/rc/rc-main.c b/src/4.x/drivers/media/rc/rc-main.c new file mode 100644 index 000000000..3f0f71ada --- /dev/null +++ b/src/4.x/drivers/media/rc/rc-main.c @@ -0,0 +1,1538 @@ +/* rc-main.c - Remote Controller core module + * + * Copyright (C) 2009-2010 by Mauro Carvalho Chehab + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "rc-core-priv.h" + +/* Sizes are in bytes, 256 bytes allows for 32 entries on x64 */ +#define IR_TAB_MIN_SIZE 256 +#define IR_TAB_MAX_SIZE 8192 +#define RC_DEV_MAX 256 + +/* FIXME: IR_KEYPRESS_TIMEOUT should be protocol specific */ +#define IR_KEYPRESS_TIMEOUT 250 + +/* Used to keep track of known keymaps */ +static LIST_HEAD(rc_map_list); +static DEFINE_SPINLOCK(rc_map_lock); +static struct led_trigger *led_feedback; + +/* Used to keep track of rc devices */ +static DEFINE_IDA(rc_ida); + +static struct rc_map_list *seek_rc_map(const char *name) +{ + struct rc_map_list *map = NULL; + + spin_lock(&rc_map_lock); + list_for_each_entry(map, &rc_map_list, list) { + if (!strcmp(name, map->map.name)) { + spin_unlock(&rc_map_lock); + return map; + } + } + spin_unlock(&rc_map_lock); + + return NULL; +} + +struct rc_map *rc_map_get(const char *name) +{ + + struct rc_map_list *map; + + map = seek_rc_map(name); +#ifdef MODULE + if (!map) { + int rc = request_module("%s", name); + if (rc < 0) { + printk(KERN_ERR "Couldn't load IR keymap %s\n", name); + return NULL; + } + msleep(20); /* Give some time for IR to register */ + + map = seek_rc_map(name); + } +#endif + if (!map) { + printk(KERN_ERR "IR keymap %s not found\n", name); + return NULL; + } + + printk(KERN_INFO "Registered IR keymap %s\n", map->map.name); + + return &map->map; +} +EXPORT_SYMBOL_GPL(rc_map_get); + +int rc_map_register(struct rc_map_list *map) +{ + spin_lock(&rc_map_lock); + list_add_tail(&map->list, &rc_map_list); + spin_unlock(&rc_map_lock); + return 0; +} +EXPORT_SYMBOL_GPL(rc_map_register); + +void rc_map_unregister(struct rc_map_list *map) +{ + spin_lock(&rc_map_lock); + list_del(&map->list); + spin_unlock(&rc_map_lock); +} +EXPORT_SYMBOL_GPL(rc_map_unregister); + + +static struct rc_map_table empty[] = { + { 0x2a, KEY_COFFEE }, +}; + +static struct rc_map_list empty_map = { + .map = { + .scan = empty, + .size = ARRAY_SIZE(empty), + .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_EMPTY, + } +}; + +/** + * ir_create_table() - initializes a scancode table + * @rc_map: the rc_map to initialize + * @name: name to assign to the table + * @rc_type: ir type to assign to the new table + * @size: initial size of the table + * @return: zero on success or a negative error code + * + * This routine will initialize the rc_map and will allocate + * memory to hold at least the specified number of elements. + */ +static int ir_create_table(struct rc_map *rc_map, + const char *name, u64 rc_type, size_t size) +{ + rc_map->name = name; + rc_map->rc_type = rc_type; + rc_map->alloc = roundup_pow_of_two(size * sizeof(struct rc_map_table)); + rc_map->size = rc_map->alloc / sizeof(struct rc_map_table); + rc_map->scan = kmalloc(rc_map->alloc, GFP_KERNEL); + if (!rc_map->scan) + return -ENOMEM; + + IR_dprintk(1, "Allocated space for %u keycode entries (%u bytes)\n", + rc_map->size, rc_map->alloc); + return 0; +} + +/** + * ir_free_table() - frees memory allocated by a scancode table + * @rc_map: the table whose mappings need to be freed + * + * This routine will free memory alloctaed for key mappings used by given + * scancode table. + */ +static void ir_free_table(struct rc_map *rc_map) +{ + rc_map->size = 0; + kfree(rc_map->scan); + rc_map->scan = NULL; +} + +/** + * ir_resize_table() - resizes a scancode table if necessary + * @rc_map: the rc_map to resize + * @gfp_flags: gfp flags to use when allocating memory + * @return: zero on success or a negative error code + * + * This routine will shrink the rc_map if it has lots of + * unused entries and grow it if it is full. + */ +static int ir_resize_table(struct rc_map *rc_map, gfp_t gfp_flags) +{ + unsigned int oldalloc = rc_map->alloc; + unsigned int newalloc = oldalloc; + struct rc_map_table *oldscan = rc_map->scan; + struct rc_map_table *newscan; + + if (rc_map->size == rc_map->len) { + /* All entries in use -> grow keytable */ + if (rc_map->alloc >= IR_TAB_MAX_SIZE) + return -ENOMEM; + + newalloc *= 2; + IR_dprintk(1, "Growing table to %u bytes\n", newalloc); + } + + if ((rc_map->len * 3 < rc_map->size) && (oldalloc > IR_TAB_MIN_SIZE)) { + /* Less than 1/3 of entries in use -> shrink keytable */ + newalloc /= 2; + IR_dprintk(1, "Shrinking table to %u bytes\n", newalloc); + } + + if (newalloc == oldalloc) + return 0; + + newscan = kmalloc(newalloc, gfp_flags); + if (!newscan) { + IR_dprintk(1, "Failed to kmalloc %u bytes\n", newalloc); + return -ENOMEM; + } + + memcpy(newscan, rc_map->scan, rc_map->len * sizeof(struct rc_map_table)); + rc_map->scan = newscan; + rc_map->alloc = newalloc; + rc_map->size = rc_map->alloc / sizeof(struct rc_map_table); + kfree(oldscan); + return 0; +} + +/** + * ir_update_mapping() - set a keycode in the scancode->keycode table + * @dev: the struct rc_dev device descriptor + * @rc_map: scancode table to be adjusted + * @index: index of the mapping that needs to be updated + * @keycode: the desired keycode + * @return: previous keycode assigned to the mapping + * + * This routine is used to update scancode->keycode mapping at given + * position. + */ +static unsigned int ir_update_mapping(struct rc_dev *dev, + struct rc_map *rc_map, + unsigned int index, + unsigned int new_keycode) +{ + int old_keycode = rc_map->scan[index].keycode; + int i; + + /* Did the user wish to remove the mapping? */ + if (new_keycode == KEY_RESERVED || new_keycode == KEY_UNKNOWN) { + IR_dprintk(1, "#%d: Deleting scan 0x%04x\n", + index, rc_map->scan[index].scancode); + rc_map->len--; + memmove(&rc_map->scan[index], &rc_map->scan[index+ 1], + (rc_map->len - index) * sizeof(struct rc_map_table)); + } else { + IR_dprintk(1, "#%d: %s scan 0x%04x with key 0x%04x\n", + index, + old_keycode == KEY_RESERVED ? "New" : "Replacing", + rc_map->scan[index].scancode, new_keycode); + rc_map->scan[index].keycode = new_keycode; + __set_bit(new_keycode, dev->input_dev->keybit); + } + + if (old_keycode != KEY_RESERVED) { + /* A previous mapping was updated... */ + __clear_bit(old_keycode, dev->input_dev->keybit); + /* ... but another scancode might use the same keycode */ + for (i = 0; i < rc_map->len; i++) { + if (rc_map->scan[i].keycode == old_keycode) { + __set_bit(old_keycode, dev->input_dev->keybit); + break; + } + } + + /* Possibly shrink the keytable, failure is not a problem */ + ir_resize_table(rc_map, GFP_ATOMIC); + } + + return old_keycode; +} + +/** + * ir_establish_scancode() - set a keycode in the scancode->keycode table + * @dev: the struct rc_dev device descriptor + * @rc_map: scancode table to be searched + * @scancode: the desired scancode + * @resize: controls whether we allowed to resize the table to + * accommodate not yet present scancodes + * @return: index of the mapping containing scancode in question + * or -1U in case of failure. + * + * This routine is used to locate given scancode in rc_map. + * If scancode is not yet present the routine will allocate a new slot + * for it. + */ +static unsigned int ir_establish_scancode(struct rc_dev *dev, + struct rc_map *rc_map, + unsigned int scancode, + bool resize) +{ + unsigned int i; + + /* + * Unfortunately, some hardware-based IR decoders don't provide + * all bits for the complete IR code. In general, they provide only + * the command part of the IR code. Yet, as it is possible to replace + * the provided IR with another one, it is needed to allow loading + * IR tables from other remotes. So, we support specifying a mask to + * indicate the valid bits of the scancodes. + */ + if (dev->scancode_mask) + scancode &= dev->scancode_mask; + + /* First check if we already have a mapping for this ir command */ + for (i = 0; i < rc_map->len; i++) { + if (rc_map->scan[i].scancode == scancode) + return i; + + /* Keytable is sorted from lowest to highest scancode */ + if (rc_map->scan[i].scancode >= scancode) + break; + } + + /* No previous mapping found, we might need to grow the table */ + if (rc_map->size == rc_map->len) { + if (!resize || ir_resize_table(rc_map, GFP_ATOMIC)) + return -1U; + } + + /* i is the proper index to insert our new keycode */ + if (i < rc_map->len) + memmove(&rc_map->scan[i + 1], &rc_map->scan[i], + (rc_map->len - i) * sizeof(struct rc_map_table)); + rc_map->scan[i].scancode = scancode; + rc_map->scan[i].keycode = KEY_RESERVED; + rc_map->len++; + + return i; +} + +/** + * ir_setkeycode() - set a keycode in the scancode->keycode table + * @idev: the struct input_dev device descriptor + * @scancode: the desired scancode + * @keycode: result + * @return: -EINVAL if the keycode could not be inserted, otherwise zero. + * + * This routine is used to handle evdev EVIOCSKEY ioctl. + */ +static int ir_setkeycode(struct input_dev *idev, + const struct input_keymap_entry *ke, + unsigned int *old_keycode) +{ + struct rc_dev *rdev = input_get_drvdata(idev); + struct rc_map *rc_map = &rdev->rc_map; + unsigned int index; + unsigned int scancode; + int retval = 0; + unsigned long flags; + + spin_lock_irqsave(&rc_map->lock, flags); + + if (ke->flags & INPUT_KEYMAP_BY_INDEX) { + index = ke->index; + if (index >= rc_map->len) { + retval = -EINVAL; + goto out; + } + } else { + retval = input_scancode_to_scalar(ke, &scancode); + if (retval) + goto out; + + index = ir_establish_scancode(rdev, rc_map, scancode, true); + if (index >= rc_map->len) { + retval = -ENOMEM; + goto out; + } + } + + *old_keycode = ir_update_mapping(rdev, rc_map, index, ke->keycode); + +out: + spin_unlock_irqrestore(&rc_map->lock, flags); + return retval; +} + +/** + * ir_setkeytable() - sets several entries in the scancode->keycode table + * @dev: the struct rc_dev device descriptor + * @to: the struct rc_map to copy entries to + * @from: the struct rc_map to copy entries from + * @return: -ENOMEM if all keycodes could not be inserted, otherwise zero. + * + * This routine is used to handle table initialization. + */ +static int ir_setkeytable(struct rc_dev *dev, + const struct rc_map *from) +{ + struct rc_map *rc_map = &dev->rc_map; + unsigned int i, index; + int rc; + + rc = ir_create_table(rc_map, from->name, + from->rc_type, from->size); + if (rc) + return rc; + + IR_dprintk(1, "Allocated space for %u keycode entries (%u bytes)\n", + rc_map->size, rc_map->alloc); + + for (i = 0; i < from->size; i++) { + index = ir_establish_scancode(dev, rc_map, + from->scan[i].scancode, false); + if (index >= rc_map->len) { + rc = -ENOMEM; + break; + } + + ir_update_mapping(dev, rc_map, index, + from->scan[i].keycode); + } + + if (rc) + ir_free_table(rc_map); + + return rc; +} + +/** + * ir_lookup_by_scancode() - locate mapping by scancode + * @rc_map: the struct rc_map to search + * @scancode: scancode to look for in the table + * @return: index in the table, -1U if not found + * + * This routine performs binary search in RC keykeymap table for + * given scancode. + */ +static unsigned int ir_lookup_by_scancode(const struct rc_map *rc_map, + unsigned int scancode) +{ + int start = 0; + int end = rc_map->len - 1; + int mid; + + while (start <= end) { + mid = (start + end) / 2; + if (rc_map->scan[mid].scancode < scancode) + start = mid + 1; + else if (rc_map->scan[mid].scancode > scancode) + end = mid - 1; + else + return mid; + } + + return -1U; +} + +/** + * ir_getkeycode() - get a keycode from the scancode->keycode table + * @idev: the struct input_dev device descriptor + * @scancode: the desired scancode + * @keycode: used to return the keycode, if found, or KEY_RESERVED + * @return: always returns zero. + * + * This routine is used to handle evdev EVIOCGKEY ioctl. + */ +static int ir_getkeycode(struct input_dev *idev, + struct input_keymap_entry *ke) +{ + struct rc_dev *rdev = input_get_drvdata(idev); + struct rc_map *rc_map = &rdev->rc_map; + struct rc_map_table *entry; + unsigned long flags; + unsigned int index; + unsigned int scancode; + int retval; + + spin_lock_irqsave(&rc_map->lock, flags); + + if (ke->flags & INPUT_KEYMAP_BY_INDEX) { + index = ke->index; + } else { + retval = input_scancode_to_scalar(ke, &scancode); + if (retval) + goto out; + + index = ir_lookup_by_scancode(rc_map, scancode); + } + + if (index < rc_map->len) { + entry = &rc_map->scan[index]; + + ke->index = index; + ke->keycode = entry->keycode; + ke->len = sizeof(entry->scancode); + memcpy(ke->scancode, &entry->scancode, sizeof(entry->scancode)); + + } else if (!(ke->flags & INPUT_KEYMAP_BY_INDEX)) { + /* + * We do not really know the valid range of scancodes + * so let's respond with KEY_RESERVED to anything we + * do not have mapping for [yet]. + */ + ke->index = index; + ke->keycode = KEY_RESERVED; + } else { + retval = -EINVAL; + goto out; + } + + retval = 0; + +out: + spin_unlock_irqrestore(&rc_map->lock, flags); + return retval; +} + +/** + * rc_g_keycode_from_table() - gets the keycode that corresponds to a scancode + * @dev: the struct rc_dev descriptor of the device + * @scancode: the scancode to look for + * @return: the corresponding keycode, or KEY_RESERVED + * + * This routine is used by drivers which need to convert a scancode to a + * keycode. Normally it should not be used since drivers should have no + * interest in keycodes. + */ +u32 rc_g_keycode_from_table(struct rc_dev *dev, u32 scancode) +{ + struct rc_map *rc_map = &dev->rc_map; + unsigned int keycode; + unsigned int index; + unsigned long flags; + + spin_lock_irqsave(&rc_map->lock, flags); + + index = ir_lookup_by_scancode(rc_map, scancode); + keycode = index < rc_map->len ? + rc_map->scan[index].keycode : KEY_RESERVED; + + spin_unlock_irqrestore(&rc_map->lock, flags); + + if (keycode != KEY_RESERVED) + IR_dprintk(1, "%s: scancode 0x%04x keycode 0x%02x\n", + dev->input_name, scancode, keycode); + + return keycode; +} +EXPORT_SYMBOL_GPL(rc_g_keycode_from_table); + +/** + * ir_do_keyup() - internal function to signal the release of a keypress + * @dev: the struct rc_dev descriptor of the device + * @sync: whether or not to call input_sync + * + * This function is used internally to release a keypress, it must be + * called with keylock held. + */ +static void ir_do_keyup(struct rc_dev *dev, bool sync) +{ + if (!dev->keypressed) + return; + + IR_dprintk(1, "keyup key 0x%04x\n", dev->last_keycode); + input_report_key(dev->input_dev, dev->last_keycode, 0); + led_trigger_event(led_feedback, LED_OFF); + if (sync) + input_sync(dev->input_dev); + dev->keypressed = false; +} + +/** + * rc_keyup() - signals the release of a keypress + * @dev: the struct rc_dev descriptor of the device + * + * This routine is used to signal that a key has been released on the + * remote control. + */ +void rc_keyup(struct rc_dev *dev) +{ + unsigned long flags; + + spin_lock_irqsave(&dev->keylock, flags); + ir_do_keyup(dev, true); + spin_unlock_irqrestore(&dev->keylock, flags); +} +EXPORT_SYMBOL_GPL(rc_keyup); + +/** + * ir_timer_keyup() - generates a keyup event after a timeout + * @cookie: a pointer to the struct rc_dev for the device + * + * This routine will generate a keyup event some time after a keydown event + * is generated when no further activity has been detected. + */ +static void ir_timer_keyup(unsigned long cookie) +{ + struct rc_dev *dev = (struct rc_dev *)cookie; + unsigned long flags; + + /* + * ir->keyup_jiffies is used to prevent a race condition if a + * hardware interrupt occurs at this point and the keyup timer + * event is moved further into the future as a result. + * + * The timer will then be reactivated and this function called + * again in the future. We need to exit gracefully in that case + * to allow the input subsystem to do its auto-repeat magic or + * a keyup event might follow immediately after the keydown. + */ + spin_lock_irqsave(&dev->keylock, flags); + if (time_is_before_eq_jiffies(dev->keyup_jiffies)) + ir_do_keyup(dev, true); + spin_unlock_irqrestore(&dev->keylock, flags); +} + +/** + * rc_repeat() - signals that a key is still pressed + * @dev: the struct rc_dev descriptor of the device + * + * This routine is used by IR decoders when a repeat message which does + * not include the necessary bits to reproduce the scancode has been + * received. + */ +void rc_repeat(struct rc_dev *dev) +{ + unsigned long flags; + + spin_lock_irqsave(&dev->keylock, flags); + + input_event(dev->input_dev, EV_MSC, MSC_SCAN, dev->last_scancode); + input_sync(dev->input_dev); + + if (!dev->keypressed) + goto out; + + dev->keyup_jiffies = jiffies + msecs_to_jiffies(IR_KEYPRESS_TIMEOUT); + mod_timer(&dev->timer_keyup, dev->keyup_jiffies); + +out: + spin_unlock_irqrestore(&dev->keylock, flags); +} +EXPORT_SYMBOL_GPL(rc_repeat); + +/** + * ir_do_keydown() - internal function to process a keypress + * @dev: the struct rc_dev descriptor of the device + * @protocol: the protocol of the keypress + * @scancode: the scancode of the keypress + * @keycode: the keycode of the keypress + * @toggle: the toggle value of the keypress + * + * This function is used internally to register a keypress, it must be + * called with keylock held. + */ +static void ir_do_keydown(struct rc_dev *dev, enum rc_type protocol, + u32 scancode, u32 keycode, u8 toggle) +{ + bool new_event = (!dev->keypressed || + dev->last_protocol != protocol || + dev->last_scancode != scancode || + dev->last_toggle != toggle); + + if (new_event && dev->keypressed) + ir_do_keyup(dev, false); + + input_event(dev->input_dev, EV_MSC, MSC_SCAN, scancode); + + if (new_event && keycode != KEY_RESERVED) { + /* Register a keypress */ + dev->keypressed = true; + dev->last_protocol = protocol; + dev->last_scancode = scancode; + dev->last_toggle = toggle; + dev->last_keycode = keycode; + + IR_dprintk(1, "%s: key down event, " + "key 0x%04x, protocol 0x%04x, scancode 0x%08x\n", + dev->input_name, keycode, protocol, scancode); + input_report_key(dev->input_dev, keycode, 1); + + led_trigger_event(led_feedback, LED_FULL); + } + + input_sync(dev->input_dev); +} + +/** + * rc_keydown() - generates input event for a key press + * @dev: the struct rc_dev descriptor of the device + * @protocol: the protocol for the keypress + * @scancode: the scancode for the keypress + * @toggle: the toggle value (protocol dependent, if the protocol doesn't + * support toggle values, this should be set to zero) + * + * This routine is used to signal that a key has been pressed on the + * remote control. + */ +void rc_keydown(struct rc_dev *dev, enum rc_type protocol, u32 scancode, u8 toggle) +{ + unsigned long flags; + u32 keycode = rc_g_keycode_from_table(dev, scancode); + + spin_lock_irqsave(&dev->keylock, flags); + ir_do_keydown(dev, protocol, scancode, keycode, toggle); + + if (dev->keypressed) { + dev->keyup_jiffies = jiffies + msecs_to_jiffies(IR_KEYPRESS_TIMEOUT); + mod_timer(&dev->timer_keyup, dev->keyup_jiffies); + } + spin_unlock_irqrestore(&dev->keylock, flags); +} +EXPORT_SYMBOL_GPL(rc_keydown); + +/** + * rc_keydown_notimeout() - generates input event for a key press without + * an automatic keyup event at a later time + * @dev: the struct rc_dev descriptor of the device + * @protocol: the protocol for the keypress + * @scancode: the scancode for the keypress + * @toggle: the toggle value (protocol dependent, if the protocol doesn't + * support toggle values, this should be set to zero) + * + * This routine is used to signal that a key has been pressed on the + * remote control. The driver must manually call rc_keyup() at a later stage. + */ +void rc_keydown_notimeout(struct rc_dev *dev, enum rc_type protocol, + u32 scancode, u8 toggle) +{ + unsigned long flags; + u32 keycode = rc_g_keycode_from_table(dev, scancode); + + spin_lock_irqsave(&dev->keylock, flags); + ir_do_keydown(dev, protocol, scancode, keycode, toggle); + spin_unlock_irqrestore(&dev->keylock, flags); +} +EXPORT_SYMBOL_GPL(rc_keydown_notimeout); + +int rc_open(struct rc_dev *rdev) +{ + int rval = 0; + + if (!rdev) + return -EINVAL; + + mutex_lock(&rdev->lock); + if (!rdev->users++ && rdev->open != NULL) + rval = rdev->open(rdev); + + if (rval) + rdev->users--; + + mutex_unlock(&rdev->lock); + + return rval; +} +EXPORT_SYMBOL_GPL(rc_open); + +static int ir_open(struct input_dev *idev) +{ + struct rc_dev *rdev = input_get_drvdata(idev); + + return rc_open(rdev); +} + +void rc_close(struct rc_dev *rdev) +{ + if (rdev) { + mutex_lock(&rdev->lock); + + if (!--rdev->users && rdev->close != NULL) + rdev->close(rdev); + + mutex_unlock(&rdev->lock); + } +} +EXPORT_SYMBOL_GPL(rc_close); + +static void ir_close(struct input_dev *idev) +{ + struct rc_dev *rdev = input_get_drvdata(idev); + rc_close(rdev); +} + +/* class for /sys/class/rc */ +static char *rc_devnode(struct device *dev, umode_t *mode) +{ + return kasprintf(GFP_KERNEL, "rc/%s", dev_name(dev)); +} + +static struct class rc_class = { + .name = "rc", + .devnode = rc_devnode, +}; + +/* + * These are the protocol textual descriptions that are + * used by the sysfs protocols file. Note that the order + * of the entries is relevant. + */ +static struct { + u64 type; + char *name; +} proto_names[] = { + { RC_BIT_NONE, "none" }, + { RC_BIT_OTHER, "other" }, + { RC_BIT_UNKNOWN, "unknown" }, + { RC_BIT_RC5 | + RC_BIT_RC5X, "rc-5" }, + { RC_BIT_NEC, "nec" }, + { RC_BIT_RC6_0 | + RC_BIT_RC6_6A_20 | + RC_BIT_RC6_6A_24 | + RC_BIT_RC6_6A_32 | + RC_BIT_RC6_MCE, "rc-6" }, + { RC_BIT_JVC, "jvc" }, + { RC_BIT_SONY12 | + RC_BIT_SONY15 | + RC_BIT_SONY20, "sony" }, + { RC_BIT_RC5_SZ, "rc-5-sz" }, + { RC_BIT_SANYO, "sanyo" }, + { RC_BIT_SHARP, "sharp" }, + { RC_BIT_MCE_KBD, "mce_kbd" }, + { RC_BIT_XMP, "xmp" }, +}; + +/** + * struct rc_filter_attribute - Device attribute relating to a filter type. + * @attr: Device attribute. + * @type: Filter type. + * @mask: false for filter value, true for filter mask. + */ +struct rc_filter_attribute { + struct device_attribute attr; + enum rc_filter_type type; + bool mask; +}; +#define to_rc_filter_attr(a) container_of(a, struct rc_filter_attribute, attr) + +#define RC_PROTO_ATTR(_name, _mode, _show, _store, _type) \ + struct rc_filter_attribute dev_attr_##_name = { \ + .attr = __ATTR(_name, _mode, _show, _store), \ + .type = (_type), \ + } +#define RC_FILTER_ATTR(_name, _mode, _show, _store, _type, _mask) \ + struct rc_filter_attribute dev_attr_##_name = { \ + .attr = __ATTR(_name, _mode, _show, _store), \ + .type = (_type), \ + .mask = (_mask), \ + } + +static bool lirc_is_present(void) +{ +#if defined(CONFIG_LIRC_MODULE) + struct module *lirc; + + mutex_lock(&module_mutex); + lirc = find_module("lirc_dev"); + mutex_unlock(&module_mutex); + + return lirc ? true : false; +#elif defined(CONFIG_LIRC) + return true; +#else + return false; +#endif +} + +/** + * show_protocols() - shows the current/wakeup IR protocol(s) + * @device: the device descriptor + * @mattr: the device attribute struct + * @buf: a pointer to the output buffer + * + * This routine is a callback routine for input read the IR protocol type(s). + * it is trigged by reading /sys/class/rc/rc?/[wakeup_]protocols. + * It returns the protocol names of supported protocols. + * Enabled protocols are printed in brackets. + * + * dev->lock is taken to guard against races between device + * registration, store_protocols and show_protocols. + */ +static ssize_t show_protocols(struct device *device, + struct device_attribute *mattr, char *buf) +{ + struct rc_dev *dev = to_rc_dev(device); + struct rc_filter_attribute *fattr = to_rc_filter_attr(mattr); + u64 allowed, enabled; + char *tmp = buf; + int i; + + /* Device is being removed */ + if (!dev) + return -EINVAL; + + mutex_lock(&dev->lock); + + if (fattr->type == RC_FILTER_NORMAL) { + enabled = dev->enabled_protocols; + allowed = dev->allowed_protocols; + if (dev->raw && !allowed) + allowed = ir_raw_get_allowed_protocols(); + } else { + enabled = dev->enabled_wakeup_protocols; + allowed = dev->allowed_wakeup_protocols; + } + + mutex_unlock(&dev->lock); + + IR_dprintk(1, "%s: allowed - 0x%llx, enabled - 0x%llx\n", + __func__, (long long)allowed, (long long)enabled); + + for (i = 0; i < ARRAY_SIZE(proto_names); i++) { + if (allowed & enabled & proto_names[i].type) + tmp += sprintf(tmp, "[%s] ", proto_names[i].name); + else if (allowed & proto_names[i].type) + tmp += sprintf(tmp, "%s ", proto_names[i].name); + + if (allowed & proto_names[i].type) + allowed &= ~proto_names[i].type; + } + + if (dev->driver_type == RC_DRIVER_IR_RAW && lirc_is_present()) + tmp += sprintf(tmp, "[lirc] "); + + if (tmp != buf) + tmp--; + *tmp = '\n'; + + return tmp + 1 - buf; +} + +/** + * parse_protocol_change() - parses a protocol change request + * @protocols: pointer to the bitmask of current protocols + * @buf: pointer to the buffer with a list of changes + * + * Writing "+proto" will add a protocol to the protocol mask. + * Writing "-proto" will remove a protocol from protocol mask. + * Writing "proto" will enable only "proto". + * Writing "none" will disable all protocols. + * Returns the number of changes performed or a negative error code. + */ +static int parse_protocol_change(u64 *protocols, const char *buf) +{ + const char *tmp; + unsigned count = 0; + bool enable, disable; + u64 mask; + int i; + + while ((tmp = strsep((char **)&buf, " \n")) != NULL) { + if (!*tmp) + break; + + if (*tmp == '+') { + enable = true; + disable = false; + tmp++; + } else if (*tmp == '-') { + enable = false; + disable = true; + tmp++; + } else { + enable = false; + disable = false; + } + + for (i = 0; i < ARRAY_SIZE(proto_names); i++) { + if (!strcasecmp(tmp, proto_names[i].name)) { + mask = proto_names[i].type; + break; + } + } + + if (i == ARRAY_SIZE(proto_names)) { + if (!strcasecmp(tmp, "lirc")) + mask = 0; + else { + IR_dprintk(1, "Unknown protocol: '%s'\n", tmp); + return -EINVAL; + } + } + + count++; + + if (enable) + *protocols |= mask; + else if (disable) + *protocols &= ~mask; + else + *protocols = mask; + } + + if (!count) { + IR_dprintk(1, "Protocol not specified\n"); + return -EINVAL; + } + + return count; +} + +/** + * store_protocols() - changes the current/wakeup IR protocol(s) + * @device: the device descriptor + * @mattr: the device attribute struct + * @buf: a pointer to the input buffer + * @len: length of the input buffer + * + * This routine is for changing the IR protocol type. + * It is trigged by writing to /sys/class/rc/rc?/[wakeup_]protocols. + * See parse_protocol_change() for the valid commands. + * Returns @len on success or a negative error code. + * + * dev->lock is taken to guard against races between device + * registration, store_protocols and show_protocols. + */ +static ssize_t store_protocols(struct device *device, + struct device_attribute *mattr, + const char *buf, size_t len) +{ + struct rc_dev *dev = to_rc_dev(device); + struct rc_filter_attribute *fattr = to_rc_filter_attr(mattr); + u64 *current_protocols; + int (*change_protocol)(struct rc_dev *dev, u64 *rc_type); + struct rc_scancode_filter *filter; + int (*set_filter)(struct rc_dev *dev, struct rc_scancode_filter *filter); + u64 old_protocols, new_protocols; + ssize_t rc; + + /* Device is being removed */ + if (!dev) + return -EINVAL; + + if (fattr->type == RC_FILTER_NORMAL) { + IR_dprintk(1, "Normal protocol change requested\n"); + current_protocols = &dev->enabled_protocols; + change_protocol = dev->change_protocol; + filter = &dev->scancode_filter; + set_filter = dev->s_filter; + } else { + IR_dprintk(1, "Wakeup protocol change requested\n"); + current_protocols = &dev->enabled_wakeup_protocols; + change_protocol = dev->change_wakeup_protocol; + filter = &dev->scancode_wakeup_filter; + set_filter = dev->s_wakeup_filter; + } + + if (!change_protocol) { + IR_dprintk(1, "Protocol switching not supported\n"); + return -EINVAL; + } + + mutex_lock(&dev->lock); + + old_protocols = *current_protocols; + new_protocols = old_protocols; + rc = parse_protocol_change(&new_protocols, buf); + if (rc < 0) + goto out; + + rc = change_protocol(dev, &new_protocols); + if (rc < 0) { + IR_dprintk(1, "Error setting protocols to 0x%llx\n", + (long long)new_protocols); + goto out; + } + + if (new_protocols != old_protocols) { + *current_protocols = new_protocols; + IR_dprintk(1, "Protocols changed to 0x%llx\n", + (long long)new_protocols); + } + + /* + * If a protocol change was attempted the filter may need updating, even + * if the actual protocol mask hasn't changed (since the driver may have + * cleared the filter). + * Try setting the same filter with the new protocol (if any). + * Fall back to clearing the filter. + */ + if (set_filter && filter->mask) { + if (new_protocols) + rc = set_filter(dev, filter); + else + rc = -1; + + if (rc < 0) { + filter->data = 0; + filter->mask = 0; + set_filter(dev, filter); + } + } + + rc = len; + +out: + mutex_unlock(&dev->lock); + return rc; +} + +/** + * show_filter() - shows the current scancode filter value or mask + * @device: the device descriptor + * @attr: the device attribute struct + * @buf: a pointer to the output buffer + * + * This routine is a callback routine to read a scancode filter value or mask. + * It is trigged by reading /sys/class/rc/rc?/[wakeup_]filter[_mask]. + * It prints the current scancode filter value or mask of the appropriate filter + * type in hexadecimal into @buf and returns the size of the buffer. + * + * Bits of the filter value corresponding to set bits in the filter mask are + * compared against input scancodes and non-matching scancodes are discarded. + * + * dev->lock is taken to guard against races between device registration, + * store_filter and show_filter. + */ +static ssize_t show_filter(struct device *device, + struct device_attribute *attr, + char *buf) +{ + struct rc_dev *dev = to_rc_dev(device); + struct rc_filter_attribute *fattr = to_rc_filter_attr(attr); + struct rc_scancode_filter *filter; + u32 val; + + /* Device is being removed */ + if (!dev) + return -EINVAL; + + if (fattr->type == RC_FILTER_NORMAL) + filter = &dev->scancode_filter; + else + filter = &dev->scancode_wakeup_filter; + + mutex_lock(&dev->lock); + if (fattr->mask) + val = filter->mask; + else + val = filter->data; + mutex_unlock(&dev->lock); + + return sprintf(buf, "%#x\n", val); +} + +/** + * store_filter() - changes the scancode filter value + * @device: the device descriptor + * @attr: the device attribute struct + * @buf: a pointer to the input buffer + * @len: length of the input buffer + * + * This routine is for changing a scancode filter value or mask. + * It is trigged by writing to /sys/class/rc/rc?/[wakeup_]filter[_mask]. + * Returns -EINVAL if an invalid filter value for the current protocol was + * specified or if scancode filtering is not supported by the driver, otherwise + * returns @len. + * + * Bits of the filter value corresponding to set bits in the filter mask are + * compared against input scancodes and non-matching scancodes are discarded. + * + * dev->lock is taken to guard against races between device registration, + * store_filter and show_filter. + */ +static ssize_t store_filter(struct device *device, + struct device_attribute *attr, + const char *buf, size_t len) +{ + struct rc_dev *dev = to_rc_dev(device); + struct rc_filter_attribute *fattr = to_rc_filter_attr(attr); + struct rc_scancode_filter new_filter, *filter; + int ret; + unsigned long val; + int (*set_filter)(struct rc_dev *dev, struct rc_scancode_filter *filter); + u64 *enabled_protocols; + + /* Device is being removed */ + if (!dev) + return -EINVAL; + + ret = kstrtoul(buf, 0, &val); + if (ret < 0) + return ret; + + if (fattr->type == RC_FILTER_NORMAL) { + set_filter = dev->s_filter; + enabled_protocols = &dev->enabled_protocols; + filter = &dev->scancode_filter; + } else { + set_filter = dev->s_wakeup_filter; + enabled_protocols = &dev->enabled_wakeup_protocols; + filter = &dev->scancode_wakeup_filter; + } + + if (!set_filter) + return -EINVAL; + + mutex_lock(&dev->lock); + + new_filter = *filter; + if (fattr->mask) + new_filter.mask = val; + else + new_filter.data = val; + + if (!*enabled_protocols && val) { + /* refuse to set a filter unless a protocol is enabled */ + ret = -EINVAL; + goto unlock; + } + + ret = set_filter(dev, &new_filter); + if (ret < 0) + goto unlock; + + *filter = new_filter; + +unlock: + mutex_unlock(&dev->lock); + return (ret < 0) ? ret : len; +} + +static void rc_dev_release(struct device *device) +{ +} + +#define ADD_HOTPLUG_VAR(fmt, val...) \ + do { \ + int err = add_uevent_var(env, fmt, val); \ + if (err) \ + return err; \ + } while (0) + +static int rc_dev_uevent(struct device *device, struct kobj_uevent_env *env) +{ + struct rc_dev *dev = to_rc_dev(device); + + if (dev->rc_map.name) + ADD_HOTPLUG_VAR("NAME=%s", dev->rc_map.name); + if (dev->driver_name) + ADD_HOTPLUG_VAR("DRV_NAME=%s", dev->driver_name); + + return 0; +} + +/* + * Static device attribute struct with the sysfs attributes for IR's + */ +static RC_PROTO_ATTR(protocols, S_IRUGO | S_IWUSR, + show_protocols, store_protocols, RC_FILTER_NORMAL); +static RC_PROTO_ATTR(wakeup_protocols, S_IRUGO | S_IWUSR, + show_protocols, store_protocols, RC_FILTER_WAKEUP); +static RC_FILTER_ATTR(filter, S_IRUGO|S_IWUSR, + show_filter, store_filter, RC_FILTER_NORMAL, false); +static RC_FILTER_ATTR(filter_mask, S_IRUGO|S_IWUSR, + show_filter, store_filter, RC_FILTER_NORMAL, true); +static RC_FILTER_ATTR(wakeup_filter, S_IRUGO|S_IWUSR, + show_filter, store_filter, RC_FILTER_WAKEUP, false); +static RC_FILTER_ATTR(wakeup_filter_mask, S_IRUGO|S_IWUSR, + show_filter, store_filter, RC_FILTER_WAKEUP, true); + +static struct attribute *rc_dev_protocol_attrs[] = { + &dev_attr_protocols.attr.attr, + NULL, +}; + +static struct attribute_group rc_dev_protocol_attr_grp = { + .attrs = rc_dev_protocol_attrs, +}; + +static struct attribute *rc_dev_wakeup_protocol_attrs[] = { + &dev_attr_wakeup_protocols.attr.attr, + NULL, +}; + +static struct attribute_group rc_dev_wakeup_protocol_attr_grp = { + .attrs = rc_dev_wakeup_protocol_attrs, +}; + +static struct attribute *rc_dev_filter_attrs[] = { + &dev_attr_filter.attr.attr, + &dev_attr_filter_mask.attr.attr, + NULL, +}; + +static struct attribute_group rc_dev_filter_attr_grp = { + .attrs = rc_dev_filter_attrs, +}; + +static struct attribute *rc_dev_wakeup_filter_attrs[] = { + &dev_attr_wakeup_filter.attr.attr, + &dev_attr_wakeup_filter_mask.attr.attr, + NULL, +}; + +static struct attribute_group rc_dev_wakeup_filter_attr_grp = { + .attrs = rc_dev_wakeup_filter_attrs, +}; + +static struct device_type rc_dev_type = { + .release = rc_dev_release, + .uevent = rc_dev_uevent, +}; + +struct rc_dev *rc_allocate_device(void) +{ + struct rc_dev *dev; + + dev = kzalloc(sizeof(*dev), GFP_KERNEL); + if (!dev) + return NULL; + + dev->input_dev = input_allocate_device(); + if (!dev->input_dev) { + kfree(dev); + return NULL; + } + + dev->input_dev->getkeycode = ir_getkeycode; + dev->input_dev->setkeycode = ir_setkeycode; + input_set_drvdata(dev->input_dev, dev); + + spin_lock_init(&dev->rc_map.lock); + spin_lock_init(&dev->keylock); + mutex_init(&dev->lock); + setup_timer(&dev->timer_keyup, ir_timer_keyup, (unsigned long)dev); + + dev->dev.type = &rc_dev_type; + dev->dev.class = &rc_class; + device_initialize(&dev->dev); + + __module_get(THIS_MODULE); + return dev; +} +EXPORT_SYMBOL_GPL(rc_allocate_device); + +void rc_free_device(struct rc_dev *dev) +{ + if (!dev) + return; + + input_free_device(dev->input_dev); + + put_device(&dev->dev); + + kfree(dev); + module_put(THIS_MODULE); +} +EXPORT_SYMBOL_GPL(rc_free_device); + +int rc_register_device(struct rc_dev *dev) +{ + static bool raw_init = false; /* raw decoders loaded? */ + struct rc_map *rc_map; + const char *path; + int attr = 0; + int minor; + int rc; + + if (!dev || !dev->map_name) + return -EINVAL; + + rc_map = rc_map_get(dev->map_name); + if (!rc_map) + rc_map = rc_map_get(RC_MAP_EMPTY); + if (!rc_map || !rc_map->scan || rc_map->size == 0) + return -EINVAL; + + set_bit(EV_KEY, dev->input_dev->evbit); + set_bit(EV_REP, dev->input_dev->evbit); + set_bit(EV_MSC, dev->input_dev->evbit); + set_bit(MSC_SCAN, dev->input_dev->mscbit); + if (dev->open) + dev->input_dev->open = ir_open; + if (dev->close) + dev->input_dev->close = ir_close; + + minor = ida_simple_get(&rc_ida, 0, RC_DEV_MAX, GFP_KERNEL); + if (minor < 0) + return minor; + + dev->minor = minor; + dev_set_name(&dev->dev, "rc%u", dev->minor); + dev_set_drvdata(&dev->dev, dev); + + dev->dev.groups = dev->sysfs_groups; + dev->sysfs_groups[attr++] = &rc_dev_protocol_attr_grp; + if (dev->s_filter) + dev->sysfs_groups[attr++] = &rc_dev_filter_attr_grp; + if (dev->s_wakeup_filter) + dev->sysfs_groups[attr++] = &rc_dev_wakeup_filter_attr_grp; + if (dev->change_wakeup_protocol) + dev->sysfs_groups[attr++] = &rc_dev_wakeup_protocol_attr_grp; + dev->sysfs_groups[attr++] = NULL; + + /* + * Take the lock here, as the device sysfs node will appear + * when device_add() is called, which may trigger an ir-keytable udev + * rule, which will in turn call show_protocols and access + * dev->enabled_protocols before it has been initialized. + */ + mutex_lock(&dev->lock); + + rc = device_add(&dev->dev); + if (rc) + goto out_unlock; + + rc = ir_setkeytable(dev, rc_map); + if (rc) + goto out_dev; + + dev->input_dev->dev.parent = &dev->dev; + memcpy(&dev->input_dev->id, &dev->input_id, sizeof(dev->input_id)); + dev->input_dev->phys = dev->input_phys; + dev->input_dev->name = dev->input_name; + + /* input_register_device can call ir_open, so unlock mutex here */ + mutex_unlock(&dev->lock); + + rc = input_register_device(dev->input_dev); + + mutex_lock(&dev->lock); + + if (rc) + goto out_table; + + /* + * Default delay of 250ms is too short for some protocols, especially + * since the timeout is currently set to 250ms. Increase it to 500ms, + * to avoid wrong repetition of the keycodes. Note that this must be + * set after the call to input_register_device(). + */ + dev->input_dev->rep[REP_DELAY] = 500; + + /* + * As a repeat event on protocols like RC-5 and NEC take as long as + * 110/114ms, using 33ms as a repeat period is not the right thing + * to do. + */ + dev->input_dev->rep[REP_PERIOD] = 125; + + path = kobject_get_path(&dev->dev.kobj, GFP_KERNEL); + printk(KERN_INFO "%s: %s as %s\n", + dev_name(&dev->dev), + dev->input_name ? dev->input_name : "Unspecified device", + path ? path : "N/A"); + kfree(path); + + if (dev->driver_type == RC_DRIVER_IR_RAW) { + /* Load raw decoders, if they aren't already */ + if (!raw_init) { + IR_dprintk(1, "Loading raw decoders\n"); + ir_raw_init(); + raw_init = true; + } + /* calls ir_register_device so unlock mutex here*/ + mutex_unlock(&dev->lock); + rc = ir_raw_event_register(dev); + mutex_lock(&dev->lock); + if (rc < 0) + goto out_input; + } + + if (dev->change_protocol) { + u64 rc_type = (1ll << rc_map->rc_type); + rc = dev->change_protocol(dev, &rc_type); + if (rc < 0) + goto out_raw; + dev->enabled_protocols = rc_type; + } + + mutex_unlock(&dev->lock); + + IR_dprintk(1, "Registered rc%u (driver: %s, remote: %s, mode %s)\n", + dev->minor, + dev->driver_name ? dev->driver_name : "unknown", + rc_map->name ? rc_map->name : "unknown", + dev->driver_type == RC_DRIVER_IR_RAW ? "raw" : "cooked"); + + return 0; + +out_raw: + if (dev->driver_type == RC_DRIVER_IR_RAW) + ir_raw_event_unregister(dev); +out_input: + input_unregister_device(dev->input_dev); + dev->input_dev = NULL; +out_table: + ir_free_table(&dev->rc_map); +out_dev: + device_del(&dev->dev); +out_unlock: + mutex_unlock(&dev->lock); + ida_simple_remove(&rc_ida, minor); + return rc; +} +EXPORT_SYMBOL_GPL(rc_register_device); + +void rc_unregister_device(struct rc_dev *dev) +{ + if (!dev) + return; + + del_timer_sync(&dev->timer_keyup); + + if (dev->driver_type == RC_DRIVER_IR_RAW) + ir_raw_event_unregister(dev); + + /* Freeing the table should also call the stop callback */ + ir_free_table(&dev->rc_map); + IR_dprintk(1, "Freed keycode table\n"); + + input_unregister_device(dev->input_dev); + dev->input_dev = NULL; + + device_del(&dev->dev); + + ida_simple_remove(&rc_ida, dev->minor); + + rc_free_device(dev); +} + +EXPORT_SYMBOL_GPL(rc_unregister_device); + +/* + * Init/exit code for the module. Basically, creates/removes /sys/class/rc + */ + +static int __init rc_core_init(void) +{ + int rc = class_register(&rc_class); + if (rc) { + printk(KERN_ERR "rc_core: unable to register rc class\n"); + return rc; + } + + led_trigger_register_simple("rc-feedback", &led_feedback); + rc_map_register(&empty_map); + + return 0; +} + +static void __exit rc_core_exit(void) +{ + class_unregister(&rc_class); + led_trigger_unregister_simple(led_feedback); + rc_map_unregister(&empty_map); +} + +subsys_initcall(rc_core_init); +module_exit(rc_core_exit); + +int rc_core_debug; /* ir_debug level (0,1,2) */ +EXPORT_SYMBOL_GPL(rc_core_debug); +module_param_named(debug, rc_core_debug, int, 0644); + +MODULE_AUTHOR("Mauro Carvalho Chehab"); +MODULE_LICENSE("GPL"); diff --git a/v1000-4.4.180/rc-core.ko b/v1000-4.4.180/rc-core.ko new file mode 100644 index 0000000000000000000000000000000000000000..95c0b2c324605128eb1f66861421f072d5ade6e4 GIT binary patch literal 39352 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 literal 0 HcmV?d00001