diff options
Diffstat (limited to 'drivers/input/misc/ati_remote2.c')
-rw-r--r-- | drivers/input/misc/ati_remote2.c | 119 |
1 files changed, 82 insertions, 37 deletions
diff --git a/drivers/input/misc/ati_remote2.c b/drivers/input/misc/ati_remote2.c index e148749b5851..0b0e9be63542 100644 --- a/drivers/input/misc/ati_remote2.c +++ b/drivers/input/misc/ati_remote2.c @@ -38,7 +38,8 @@ enum { }; static int ati_remote2_set_mask(const char *val, - struct kernel_param *kp, unsigned int max) + const struct kernel_param *kp, + unsigned int max) { unsigned long mask; int ret; @@ -59,28 +60,31 @@ static int ati_remote2_set_mask(const char *val, } static int ati_remote2_set_channel_mask(const char *val, - struct kernel_param *kp) + const struct kernel_param *kp) { pr_debug("%s()\n", __func__); return ati_remote2_set_mask(val, kp, ATI_REMOTE2_MAX_CHANNEL_MASK); } -static int ati_remote2_get_channel_mask(char *buffer, struct kernel_param *kp) +static int ati_remote2_get_channel_mask(char *buffer, + const struct kernel_param *kp) { pr_debug("%s()\n", __func__); return sprintf(buffer, "0x%04x", *(unsigned int *)kp->arg); } -static int ati_remote2_set_mode_mask(const char *val, struct kernel_param *kp) +static int ati_remote2_set_mode_mask(const char *val, + const struct kernel_param *kp) { pr_debug("%s()\n", __func__); return ati_remote2_set_mask(val, kp, ATI_REMOTE2_MAX_MODE_MASK); } -static int ati_remote2_get_mode_mask(char *buffer, struct kernel_param *kp) +static int ati_remote2_get_mode_mask(char *buffer, + const struct kernel_param *kp) { pr_debug("%s()\n", __func__); @@ -89,15 +93,19 @@ static int ati_remote2_get_mode_mask(char *buffer, struct kernel_param *kp) static unsigned int channel_mask = ATI_REMOTE2_MAX_CHANNEL_MASK; #define param_check_channel_mask(name, p) __param_check(name, p, unsigned int) -#define param_set_channel_mask ati_remote2_set_channel_mask -#define param_get_channel_mask ati_remote2_get_channel_mask +static struct kernel_param_ops param_ops_channel_mask = { + .set = ati_remote2_set_channel_mask, + .get = ati_remote2_get_channel_mask, +}; module_param(channel_mask, channel_mask, 0644); MODULE_PARM_DESC(channel_mask, "Bitmask of channels to accept <15:Channel16>...<1:Channel2><0:Channel1>"); static unsigned int mode_mask = ATI_REMOTE2_MAX_MODE_MASK; #define param_check_mode_mask(name, p) __param_check(name, p, unsigned int) -#define param_set_mode_mask ati_remote2_set_mode_mask -#define param_get_mode_mask ati_remote2_get_mode_mask +static struct kernel_param_ops param_ops_mode_mask = { + .set = ati_remote2_set_mode_mask, + .get = ati_remote2_get_mode_mask, +}; module_param(mode_mask, mode_mask, 0644); MODULE_PARM_DESC(mode_mask, "Bitmask of modes to accept <4:PC><3:AUX4><2:AUX3><1:AUX2><0:AUX1>"); @@ -475,51 +483,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; } @@ -567,8 +612,8 @@ static int ati_remote2_input_init(struct ati_remote2 *ar2) idev->open = ati_remote2_open; idev->close = ati_remote2_close; - idev->getkeycode = ati_remote2_getkeycode; - idev->setkeycode = ati_remote2_setkeycode; + idev->getkeycode_new = ati_remote2_getkeycode; + idev->setkeycode_new = ati_remote2_setkeycode; idev->name = ar2->name; idev->phys = ar2->phys; |