From cde9070d9970eef1f7ec2360586c802a16230ad8 Mon Sep 17 00:00:00 2001 From: hc <hc@nodka.com> Date: Fri, 10 May 2024 07:43:50 +0000 Subject: [PATCH] rtl88x2CE_WiFi_linux driver --- kernel/drivers/media/rc/rc-main.c | 139 +++++++++++++++++++++++++++++++++------------- 1 files changed, 99 insertions(+), 40 deletions(-) diff --git a/kernel/drivers/media/rc/rc-main.c b/kernel/drivers/media/rc/rc-main.c index 6ea6038..8e88dc8 100644 --- a/kernel/drivers/media/rc/rc-main.c +++ b/kernel/drivers/media/rc/rc-main.c @@ -70,6 +70,13 @@ [RC_PROTO_CEC] = { .name = "cec", .repeat_period = 0 }, [RC_PROTO_IMON] = { .name = "imon", .scancode_bits = 0x7fffffff, .repeat_period = 114 }, + [RC_PROTO_RCMM12] = { .name = "rc-mm-12", + .scancode_bits = 0x00000fff, .repeat_period = 114 }, + [RC_PROTO_RCMM24] = { .name = "rc-mm-24", + .scancode_bits = 0x00ffffff, .repeat_period = 114 }, + [RC_PROTO_RCMM32] = { .name = "rc-mm-32", + .scancode_bits = 0xffffffff, .repeat_period = 114 }, + [RC_PROTO_XBOX_DVD] = { .name = "xbox-dvd", .repeat_period = 64 }, }; /* Used to keep track of known keymaps */ @@ -155,6 +162,41 @@ .name = RC_MAP_EMPTY, } }; + +/** + * scancode_to_u64() - converts scancode in &struct input_keymap_entry + * @ke: keymap entry containing scancode to be converted. + * @scancode: pointer to the location where converted scancode should + * be stored. + * + * This function is a version of input_scancode_to_scalar specialized for + * rc-core. + */ +static int scancode_to_u64(const struct input_keymap_entry *ke, u64 *scancode) +{ + switch (ke->len) { + case 1: + *scancode = *((u8 *)ke->scancode); + break; + + case 2: + *scancode = *((u16 *)ke->scancode); + break; + + case 4: + *scancode = *((u32 *)ke->scancode); + break; + + case 8: + *scancode = *((u64 *)ke->scancode); + break; + + default: + return -EINVAL; + } + + return 0; +} /** * ir_create_table() - initializes a scancode table @@ -278,13 +320,13 @@ /* Did the user wish to remove the mapping? */ if (new_keycode == KEY_RESERVED || new_keycode == KEY_UNKNOWN) { - dev_dbg(&dev->dev, "#%d: Deleting scan 0x%04x\n", + dev_dbg(&dev->dev, "#%d: Deleting scan 0x%04llx\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 { - dev_dbg(&dev->dev, "#%d: %s scan 0x%04x with key 0x%04x\n", + dev_dbg(&dev->dev, "#%d: %s scan 0x%04llx with key 0x%04x\n", index, old_keycode == KEY_RESERVED ? "New" : "Replacing", rc_map->scan[index].scancode, new_keycode); @@ -327,8 +369,7 @@ */ static unsigned int ir_establish_scancode(struct rc_dev *dev, struct rc_map *rc_map, - unsigned int scancode, - bool resize) + u64 scancode, bool resize) { unsigned int i; @@ -387,7 +428,7 @@ struct rc_dev *rdev = input_get_drvdata(idev); struct rc_map *rc_map = &rdev->rc_map; unsigned int index; - unsigned int scancode; + u64 scancode; int retval = 0; unsigned long flags; @@ -400,7 +441,7 @@ goto out; } } else { - retval = input_scancode_to_scalar(ke, &scancode); + retval = scancode_to_u64(ke, &scancode); if (retval) goto out; @@ -427,8 +468,7 @@ * * return: -ENOMEM if all keycodes could not be inserted, otherwise zero. */ -static int ir_setkeytable(struct rc_dev *dev, - const struct rc_map *from) +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; @@ -459,7 +499,7 @@ static int rc_map_cmp(const void *key, const void *elt) { - const unsigned int *scancode = key; + const u64 *scancode = key; const struct rc_map_table *e = elt; if (*scancode < e->scancode) @@ -480,7 +520,7 @@ * return: index in the table, -1U if not found */ static unsigned int ir_lookup_by_scancode(const struct rc_map *rc_map, - unsigned int scancode) + u64 scancode) { struct rc_map_table *res; @@ -509,7 +549,7 @@ struct rc_map_table *entry; unsigned long flags; unsigned int index; - unsigned int scancode; + u64 scancode; int retval; spin_lock_irqsave(&rc_map->lock, flags); @@ -517,7 +557,7 @@ if (ke->flags & INPUT_KEYMAP_BY_INDEX) { index = ke->index; } else { - retval = input_scancode_to_scalar(ke, &scancode); + retval = scancode_to_u64(ke, &scancode); if (retval) goto out; @@ -531,7 +571,6 @@ 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 @@ -563,7 +602,7 @@ * * return: the corresponding keycode, or KEY_RESERVED */ -u32 rc_g_keycode_from_table(struct rc_dev *dev, u32 scancode) +u32 rc_g_keycode_from_table(struct rc_dev *dev, u64 scancode) { struct rc_map *rc_map = &dev->rc_map; unsigned int keycode; @@ -579,7 +618,7 @@ spin_unlock_irqrestore(&rc_map->lock, flags); if (keycode != KEY_RESERVED) - dev_dbg(&dev->dev, "%s: scancode 0x%04x keycode 0x%02x\n", + dev_dbg(&dev->dev, "%s: scancode 0x%04llx keycode 0x%02x\n", dev->device_name, scancode, keycode); return keycode; @@ -698,7 +737,7 @@ void rc_repeat(struct rc_dev *dev) { unsigned long flags; - unsigned int timeout = nsecs_to_jiffies(dev->timeout) + + unsigned int timeout = usecs_to_jiffies(dev->timeout) + msecs_to_jiffies(repeat_period(dev->last_protocol)); struct lirc_scancode sc = { .scancode = dev->last_scancode, .rc_proto = dev->last_protocol, @@ -708,12 +747,15 @@ }; if (dev->allowed_protocols != RC_PROTO_BIT_CEC) - ir_lirc_scancode_event(dev, &sc); + lirc_scancode_event(dev, &sc); 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->last_scancode <= U32_MAX) { + input_event(dev->input_dev, EV_MSC, MSC_SCAN, + dev->last_scancode); + input_sync(dev->input_dev); + } if (dev->keypressed) { dev->keyup_jiffies = jiffies + timeout; @@ -736,7 +778,7 @@ * called with keylock held. */ static void ir_do_keydown(struct rc_dev *dev, enum rc_proto protocol, - u32 scancode, u32 keycode, u8 toggle) + u64 scancode, u32 keycode, u8 toggle) { bool new_event = (!dev->keypressed || dev->last_protocol != protocol || @@ -749,12 +791,13 @@ }; if (dev->allowed_protocols != RC_PROTO_BIT_CEC) - ir_lirc_scancode_event(dev, &sc); + lirc_scancode_event(dev, &sc); if (new_event && dev->keypressed) ir_do_keyup(dev, false); - input_event(dev->input_dev, EV_MSC, MSC_SCAN, scancode); + if (scancode <= U32_MAX) + input_event(dev->input_dev, EV_MSC, MSC_SCAN, scancode); dev->last_protocol = protocol; dev->last_scancode = scancode; @@ -765,7 +808,7 @@ /* Register a keypress */ dev->keypressed = true; - dev_dbg(&dev->dev, "%s: key down event, key 0x%04x, protocol 0x%04x, scancode 0x%08x\n", + dev_dbg(&dev->dev, "%s: key down event, key 0x%04x, protocol 0x%04x, scancode 0x%08llx\n", dev->device_name, keycode, protocol, scancode); input_report_key(dev->input_dev, keycode, 1); @@ -802,7 +845,7 @@ * 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_proto protocol, u32 scancode, +void rc_keydown(struct rc_dev *dev, enum rc_proto protocol, u64 scancode, u8 toggle) { unsigned long flags; @@ -812,7 +855,7 @@ ir_do_keydown(dev, protocol, scancode, keycode, toggle); if (dev->keypressed) { - dev->keyup_jiffies = jiffies + nsecs_to_jiffies(dev->timeout) + + dev->keyup_jiffies = jiffies + usecs_to_jiffies(dev->timeout) + msecs_to_jiffies(repeat_period(protocol)); mod_timer(&dev->timer_keyup, dev->keyup_jiffies); } @@ -833,7 +876,7 @@ * remote control. The driver must manually call rc_keyup() at a later stage. */ void rc_keydown_notimeout(struct rc_dev *dev, enum rc_proto protocol, - u32 scancode, u8 toggle) + u64 scancode, u8 toggle) { unsigned long flags; u32 keycode = rc_g_keycode_from_table(dev, scancode); @@ -1018,6 +1061,10 @@ { RC_PROTO_BIT_XMP, "xmp", "ir-xmp-decoder" }, { RC_PROTO_BIT_CEC, "cec", NULL }, { RC_PROTO_BIT_IMON, "imon", "ir-imon-decoder" }, + { RC_PROTO_BIT_RCMM12 | + RC_PROTO_BIT_RCMM24 | + RC_PROTO_BIT_RCMM32, "rc-mm", "ir-rcmm-decoder" }, + { RC_PROTO_BIT_XBOX_DVD, "xbox-dvd", NULL }, }; /** @@ -1047,7 +1094,7 @@ * @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?/protocols. + * it is triggered by reading /sys/class/rc/rc?/protocols. * It returns the protocol names of supported protocols. * Enabled protocols are printed in brackets. * @@ -1218,7 +1265,7 @@ * @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. + * It is triggered 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. * @@ -1306,7 +1353,7 @@ * @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 is triggered 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. * @@ -1349,7 +1396,7 @@ * @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]. + * It is triggered 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. @@ -1437,7 +1484,7 @@ * @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 is triggered by reading /sys/class/rc/rc?/wakeup_protocols. * It returns the protocol names of supported protocols. * The enabled protocols are printed in brackets. * @@ -1488,7 +1535,7 @@ * @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. + * It is triggered by writing to /sys/class/rc/rc?/wakeup_protocols. * Returns @len on success or a negative error code. * * dev->lock is taken to guard against races between @@ -1499,7 +1546,7 @@ const char *buf, size_t len) { struct rc_dev *dev = to_rc_dev(device); - enum rc_proto protocol; + enum rc_proto protocol = RC_PROTO_UNKNOWN; ssize_t rc; u64 allowed; int i; @@ -1512,9 +1559,7 @@ allowed = dev->allowed_wakeup_protocols; - if (sysfs_streq(buf, "none")) { - protocol = RC_PROTO_UNKNOWN; - } else { + if (!sysfs_streq(buf, "none")) { for (i = 0; i < ARRAY_SIZE(protocols); i++) { if ((allowed & (1ULL << i)) && sysfs_streq(buf, protocols[i].name)) { @@ -1769,10 +1814,18 @@ dev->enabled_protocols = rc_proto; } + /* Keyboard events */ 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); + + /* Pointer/mouse events */ + set_bit(INPUT_PROP_POINTING_STICK, dev->input_dev->propbit); + set_bit(EV_REL, dev->input_dev->evbit); + set_bit(REL_X, dev->input_dev->relbit); + set_bit(REL_Y, dev->input_dev->relbit); + if (dev->open) dev->input_dev->open = ir_open; if (dev->close) @@ -1893,7 +1946,7 @@ * keycodes with rc_keydown, so lirc must be registered first. */ if (dev->allowed_protocols != RC_PROTO_BIT_CEC) { - rc = ir_lirc_register(dev); + rc = lirc_register(dev); if (rc < 0) goto out_dev; } @@ -1919,7 +1972,7 @@ rc_free_rx_device(dev); out_lirc: if (dev->allowed_protocols != RC_PROTO_BIT_CEC) - ir_lirc_unregister(dev); + lirc_unregister(dev); out_dev: device_del(&dev->dev); out_rx_free: @@ -1983,7 +2036,7 @@ * that userspace polling will get notified. */ if (dev->allowed_protocols != RC_PROTO_BIT_CEC) - ir_lirc_unregister(dev); + lirc_unregister(dev); device_del(&dev->dev); @@ -2011,11 +2064,14 @@ if (rc) { pr_err("rc_core: unable to init lirc\n"); class_unregister(&rc_class); - return 0; + return rc; } led_trigger_register_simple("rc-feedback", &led_feedback); rc_map_register(&empty_map); +#ifdef CONFIG_MEDIA_CEC_RC + rc_map_register(&cec_map); +#endif return 0; } @@ -2025,6 +2081,9 @@ lirc_dev_exit(); class_unregister(&rc_class); led_trigger_unregister_simple(led_feedback); +#ifdef CONFIG_MEDIA_CEC_RC + rc_map_unregister(&cec_map); +#endif rc_map_unregister(&empty_map); } -- Gitblit v1.6.2