Gitweb: http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=2c1d8aea2ca76df1b1de2aed23e3ceda2a044ed1 Commit: 2c1d8aea2ca76df1b1de2aed23e3ceda2a044ed1 Parent: 3c5f4b25f3552c9bcb52eb956753a3c8140480b7 Author: Jiri Kosina <[EMAIL PROTECTED]> AuthorDate: Wed Jul 4 16:45:59 2007 +0200 Committer: Jiri Kosina <[EMAIL PROTECTED]> CommitDate: Mon Jul 9 14:13:37 2007 +0200
HID: handle cases of volume knobs generating relative values There are some devices (for example Dell Multimedia Keyboard SK-8135) that have a volume control knob which generates relative events instead of absolute. hid-input maps them to ABS_VOLUME. HUT pages don't restrict volume to absolute values. Adding REL_VOLUME doesn't seem feasible, nothing knows how to handle it. This patch translates relative ABS_VOLUME events into appropriate number of series of VOLUME_UP or VOLUME_DOWN events respectively, so that userspace sees the correct values in the end. kernel.org bugzilla 5233 Reported-by: Jochen Eisinger <[EMAIL PROTECTED]> Signed-off-by: Jiri Kosina <[EMAIL PROTECTED]> --- drivers/hid/hid-input.c | 25 +++++++++++++++++++++++++ 1 files changed, 25 insertions(+), 0 deletions(-) diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index 60de16a..bf7e307 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c @@ -882,6 +882,16 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel field->dpad = usage->code; } + /* for those devices which produce Consumer volume usage as relative, + * we emulate pressing volumeup/volumedown appropriate number of times + * in hidinput_hid_event() + */ + if ((usage->type == EV_ABS) && (field->flags & HID_MAIN_ITEM_RELATIVE) && + (usage->code == ABS_VOLUME)) { + set_bit(KEY_VOLUMEUP, input->keybit); + set_bit(KEY_VOLUMEDOWN, input->keybit); + } + hid_resolv_event(usage->type, usage->code); #ifdef CONFIG_HID_DEBUG printk("\n"); @@ -972,6 +982,21 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct if ((usage->type == EV_KEY) && (usage->code == 0)) /* Key 0 is "unassigned", not KEY_UNKNOWN */ return; + if ((usage->type == EV_ABS) && (field->flags & HID_MAIN_ITEM_RELATIVE) && + (usage->code == ABS_VOLUME)) { + int count = abs(value); + int direction = value > 0 ? KEY_VOLUMEUP : KEY_VOLUMEDOWN; + int i; + + for (i = 0; i < count; i++) { + input_event(input, EV_KEY, direction, 1); + input_sync(input); + input_event(input, EV_KEY, direction, 0); + input_sync(input); + } + return; + } + input_event(input, usage->type, usage->code, value); if ((field->flags & HID_MAIN_ITEM_RELATIVE) && (usage->type == EV_KEY)) - To unsubscribe from this list: send the line "unsubscribe git-commits-head" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html