diff options
Diffstat (limited to 'drivers/input/misc/ati_remote2.c')
| -rw-r--r-- | drivers/input/misc/ati_remote2.c | 139 |
1 files changed, 82 insertions, 57 deletions
diff --git a/drivers/input/misc/ati_remote2.c b/drivers/input/misc/ati_remote2.c index 23257652b8e..f63341f20b9 100644 --- a/drivers/input/misc/ati_remote2.c +++ b/drivers/input/misc/ati_remote2.c @@ -11,6 +11,7 @@ #include <linux/usb/input.h> #include <linux/slab.h> +#include <linux/module.h> #define DRIVER_DESC "ATI/Philips USB RF remote driver" #define DRIVER_VERSION "0.3" @@ -41,13 +42,13 @@ static int ati_remote2_set_mask(const char *val, const struct kernel_param *kp, unsigned int max) { - unsigned long mask; + unsigned int mask; int ret; if (!val) return -EINVAL; - ret = strict_strtoul(val, 0, &mask); + ret = kstrtouint(val, 0, &mask); if (ret) return ret; @@ -483,51 +484,88 @@ static void ati_remote2_complete_key(struct urb *urb) } static int ati_remote2_getkeycode(struct input_dev *idev, - unsigned int scancode, unsigned int *keycode) + struct input_keymap_entry *ke) { struct ati_remote2 *ar2 = input_get_drvdata(idev); unsigned int mode; - int index; - - mode = scancode >> 8; - if (mode > ATI_REMOTE2_PC || !((1 << mode) & ar2->mode_mask)) - return -EINVAL; + int offset; + unsigned int index; + unsigned int scancode; + + if (ke->flags & INPUT_KEYMAP_BY_INDEX) { + index = ke->index; + if (index >= ATI_REMOTE2_MODES * + ARRAY_SIZE(ati_remote2_key_table)) + return -EINVAL; + + mode = ke->index / ARRAY_SIZE(ati_remote2_key_table); + offset = ke->index % ARRAY_SIZE(ati_remote2_key_table); + scancode = (mode << 8) + ati_remote2_key_table[offset].hw_code; + } else { + if (input_scancode_to_scalar(ke, &scancode)) + return -EINVAL; + + mode = scancode >> 8; + if (mode > ATI_REMOTE2_PC) + return -EINVAL; + + offset = ati_remote2_lookup(scancode & 0xff); + if (offset < 0) + return -EINVAL; + + index = mode * ARRAY_SIZE(ati_remote2_key_table) + offset; + } - index = ati_remote2_lookup(scancode & 0xFF); - if (index < 0) - return -EINVAL; + ke->keycode = ar2->keycode[mode][offset]; + ke->len = sizeof(scancode); + memcpy(&ke->scancode, &scancode, sizeof(scancode)); + ke->index = index; - *keycode = ar2->keycode[mode][index]; return 0; } static int ati_remote2_setkeycode(struct input_dev *idev, - unsigned int scancode, unsigned int keycode) + const struct input_keymap_entry *ke, + unsigned int *old_keycode) { struct ati_remote2 *ar2 = input_get_drvdata(idev); - unsigned int mode, old_keycode; - int index; - - mode = scancode >> 8; - if (mode > ATI_REMOTE2_PC || !((1 << mode) & ar2->mode_mask)) - return -EINVAL; - - index = ati_remote2_lookup(scancode & 0xFF); - if (index < 0) - return -EINVAL; + unsigned int mode; + int offset; + unsigned int index; + unsigned int scancode; + + if (ke->flags & INPUT_KEYMAP_BY_INDEX) { + if (ke->index >= ATI_REMOTE2_MODES * + ARRAY_SIZE(ati_remote2_key_table)) + return -EINVAL; + + mode = ke->index / ARRAY_SIZE(ati_remote2_key_table); + offset = ke->index % ARRAY_SIZE(ati_remote2_key_table); + } else { + if (input_scancode_to_scalar(ke, &scancode)) + return -EINVAL; + + mode = scancode >> 8; + if (mode > ATI_REMOTE2_PC) + return -EINVAL; + + offset = ati_remote2_lookup(scancode & 0xff); + if (offset < 0) + return -EINVAL; + } - old_keycode = ar2->keycode[mode][index]; - ar2->keycode[mode][index] = keycode; - __set_bit(keycode, idev->keybit); + *old_keycode = ar2->keycode[mode][offset]; + ar2->keycode[mode][offset] = ke->keycode; + __set_bit(ke->keycode, idev->keybit); for (mode = 0; mode < ATI_REMOTE2_MODES; mode++) { for (index = 0; index < ARRAY_SIZE(ati_remote2_key_table); index++) { - if (ar2->keycode[mode][index] == old_keycode) + if (ar2->keycode[mode][index] == *old_keycode) return 0; } } - __clear_bit(old_keycode, idev->keybit); + __clear_bit(*old_keycode, idev->keybit); return 0; } @@ -682,11 +720,12 @@ static ssize_t ati_remote2_store_channel_mask(struct device *dev, struct usb_device *udev = to_usb_device(dev); struct usb_interface *intf = usb_ifnum_to_if(udev, 0); struct ati_remote2 *ar2 = usb_get_intfdata(intf); - unsigned long mask; + unsigned int mask; int r; - if (strict_strtoul(buf, 0, &mask)) - return -EINVAL; + r = kstrtouint(buf, 0, &mask); + if (r) + return r; if (mask & ~ATI_REMOTE2_MAX_CHANNEL_MASK) return -EINVAL; @@ -700,14 +739,17 @@ static ssize_t ati_remote2_store_channel_mask(struct device *dev, mutex_lock(&ati_remote2_mutex); - if (mask != ar2->channel_mask && !ati_remote2_setup(ar2, mask)) - ar2->channel_mask = mask; + if (mask != ar2->channel_mask) { + r = ati_remote2_setup(ar2, mask); + if (!r) + ar2->channel_mask = mask; + } mutex_unlock(&ati_remote2_mutex); usb_autopm_put_interface(ar2->intf[0]); - return count; + return r ? r : count; } static ssize_t ati_remote2_show_mode_mask(struct device *dev, @@ -728,10 +770,12 @@ static ssize_t ati_remote2_store_mode_mask(struct device *dev, struct usb_device *udev = to_usb_device(dev); struct usb_interface *intf = usb_ifnum_to_if(udev, 0); struct ati_remote2 *ar2 = usb_get_intfdata(intf); - unsigned long mask; + unsigned int mask; + int err; - if (strict_strtoul(buf, 0, &mask)) - return -EINVAL; + err = kstrtouint(buf, 0, &mask); + if (err) + return err; if (mask & ~ATI_REMOTE2_MAX_MODE_MASK) return -EINVAL; @@ -969,23 +1013,4 @@ static int ati_remote2_post_reset(struct usb_interface *interface) return r; } -static int __init ati_remote2_init(void) -{ - int r; - - r = usb_register(&ati_remote2_driver); - if (r) - printk(KERN_ERR "ati_remote2: usb_register() = %d\n", r); - else - printk(KERN_INFO "ati_remote2: " DRIVER_DESC " " DRIVER_VERSION "\n"); - - return r; -} - -static void __exit ati_remote2_exit(void) -{ - usb_deregister(&ati_remote2_driver); -} - -module_init(ati_remote2_init); -module_exit(ati_remote2_exit); +module_usb_driver(ati_remote2_driver); |
