Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fe7ba31f authored by Marvin Raaijmakers's avatar Marvin Raaijmakers Committed by Jiri Kosina
Browse files

HID: add hooks for getkeycode() and setkeycode() methods



Provide hooks for getkeycode() and setkeycode() methods to
input_dev.

Signed-off-by: default avatarMarvin Raaijmakers <marvin.raaijmakers@gmail.com>
Signed-off-by: default avatarJiri Kosina <jkosina@suse.cz>
parent e0712985
Loading
Loading
Loading
Loading
+85 −0
Original line number Original line Diff line number Diff line
@@ -240,6 +240,89 @@ static inline void hidinput_pb_setup(struct input_dev *input)
}
}
#endif
#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,
static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_field *field,
				     struct hid_usage *usage)
				     struct hid_usage *usage)
{
{
@@ -919,6 +1002,8 @@ int hidinput_connect(struct hid_device *hid)
				input_dev->event = hid->hidinput_input_event;
				input_dev->event = hid->hidinput_input_event;
				input_dev->open = hidinput_open;
				input_dev->open = hidinput_open;
				input_dev->close = hidinput_close;
				input_dev->close = hidinput_close;
				input_dev->setkeycode = hidinput_setkeycode;
				input_dev->getkeycode = hidinput_getkeycode;


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