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

Reply via email to