Skip to content

Commit

Permalink
HID: add hooks for getkeycode() and setkeycode() methods
Browse files Browse the repository at this point in the history
Provide hooks for getkeycode() and setkeycode() methods to
input_dev.

Signed-off-by: Marvin Raaijmakers <[email protected]>
Signed-off-by: Jiri Kosina <[email protected]>
  • Loading branch information
Marvin Raaijmakers authored and Jiri Kosina committed May 9, 2007
1 parent e071298 commit fe7ba31
Showing 1 changed file with 85 additions and 0 deletions.
85 changes: 85 additions & 0 deletions drivers/hid/hid-input.c
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,89 @@ static inline void hidinput_pb_setup(struct input_dev *input)
}
#endif

static inline int match_scancode(int code, int scancode)
{
if (scancode == 0)
return 1;
return ((code & (HID_USAGE_PAGE | HID_USAGE)) == scancode);
}

static inline int match_keycode(int code, int keycode)
{
if (keycode == 0)
return 1;
return (code == keycode);
}

static struct hid_usage *hidinput_find_key(struct hid_device *hid,
int scancode, int keycode)
{
int i, j, k;
struct hid_report *report;
struct hid_usage *usage;

for (k = HID_INPUT_REPORT; k <= HID_OUTPUT_REPORT; k++) {
list_for_each_entry(report, &hid->report_enum[k].report_list, list) {
for (i = 0; i < report->maxfield; i++) {
for ( j = 0; j < report->field[i]->maxusage; j++) {
usage = report->field[i]->usage + j;
if (usage->type == EV_KEY &&
match_scancode(usage->hid, scancode) &&
match_keycode(usage->code, keycode))
return usage;
}
}
}
}
return NULL;
}

static int hidinput_getkeycode(struct input_dev *dev, int scancode,
int *keycode)
{
struct hid_device *hid = dev->private;
struct hid_usage *usage;

usage = hidinput_find_key(hid, scancode, 0);
if (usage) {
*keycode = usage->code;
return 0;
}
return -EINVAL;
}

static int hidinput_setkeycode(struct input_dev *dev, int scancode,
int keycode)
{
struct hid_device *hid = dev->private;
struct hid_usage *usage;
int old_keycode;

if (keycode < 0 || keycode > KEY_MAX)
return -EINVAL;

usage = hidinput_find_key(hid, scancode, 0);
if (usage) {
old_keycode = usage->code;
usage->code = keycode;

clear_bit(old_keycode, dev->keybit);
set_bit(usage->code, dev->keybit);
#ifdef CONFIG_HID_DEBUG
printk (KERN_DEBUG "Assigned keycode %d to HID usage code %x\n", keycode, scancode);
#endif
/* Set the keybit for the old keycode if the old keycode is used
* by another key */
if (hidinput_find_key (hid, 0, old_keycode))
set_bit(old_keycode, dev->keybit);

return 0;
}

return -EINVAL;
}


static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_field *field,
struct hid_usage *usage)
{
Expand Down Expand Up @@ -919,6 +1002,8 @@ int hidinput_connect(struct hid_device *hid)
input_dev->event = hid->hidinput_input_event;
input_dev->open = hidinput_open;
input_dev->close = hidinput_close;
input_dev->setkeycode = hidinput_setkeycode;
input_dev->getkeycode = hidinput_getkeycode;

input_dev->name = hid->name;
input_dev->phys = hid->phys;
Expand Down

0 comments on commit fe7ba31

Please sign in to comment.