diff options
author | Henrik Rydberg <rydberg@euromail.se> | 2010-12-18 14:51:13 -0500 |
---|---|---|
committer | Henrik Rydberg <rydberg@euromail.se> | 2010-12-20 03:37:33 -0500 |
commit | 85b7720039fc000b561c20fe2aaa3b54cddae4a7 (patch) | |
tree | 8fee2c82e215b87699ad6615239752af50ac9310 /drivers | |
parent | 4dd295a73e80b55c3fec25555bf0a5d253023740 (diff) |
Input: introduce device properties
Today, userspace sets up an input device based on the data it emits.
This is not always enough; a tablet and a touchscreen may emit exactly
the same data, for instance, but the former should be set up with a
pointer whereas the latter does not need to. Recently, a new type of
touchpad has emerged where the buttons are under the pad, which
changes logic without changing the emitted data. This patch introduces
a new ioctl, EVIOCGPROP, which enables user access to a set of device
properties useful during setup. The properties are given as a bitmap
in the same fashion as the event types, and are also made available
via sysfs, uevent and /proc/bus/input/devices.
Acked-by: Ping Cheng <pingc@wacom.com>
Acked-by: Chase Douglas <chase.douglas@canonical.com>
Acked-by: Dmitry Torokhov <dtor@mail.ru>
Signed-off-by: Henrik Rydberg <rydberg@euromail.se>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/input/evdev.c | 4 | ||||
-rw-r--r-- | drivers/input/input.c | 19 | ||||
-rw-r--r-- | drivers/input/misc/uinput.c | 4 |
3 files changed, 27 insertions, 0 deletions
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index e3f7fc6f9565..0cd97e8f0c9a 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c | |||
@@ -677,6 +677,10 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd, | |||
677 | #define EVIOC_MASK_SIZE(nr) ((nr) & ~(_IOC_SIZEMASK << _IOC_SIZESHIFT)) | 677 | #define EVIOC_MASK_SIZE(nr) ((nr) & ~(_IOC_SIZEMASK << _IOC_SIZESHIFT)) |
678 | switch (EVIOC_MASK_SIZE(cmd)) { | 678 | switch (EVIOC_MASK_SIZE(cmd)) { |
679 | 679 | ||
680 | case EVIOCGPROP(0): | ||
681 | return bits_to_user(dev->propbit, INPUT_PROP_MAX, | ||
682 | size, p, compat_mode); | ||
683 | |||
680 | case EVIOCGKEY(0): | 684 | case EVIOCGKEY(0): |
681 | return bits_to_user(dev->key, KEY_MAX, size, p, compat_mode); | 685 | return bits_to_user(dev->key, KEY_MAX, size, p, compat_mode); |
682 | 686 | ||
diff --git a/drivers/input/input.c b/drivers/input/input.c index 37708d1d86ec..9ea713f4192b 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c | |||
@@ -1095,6 +1095,8 @@ static int input_devices_seq_show(struct seq_file *seq, void *v) | |||
1095 | seq_printf(seq, "%s ", handle->name); | 1095 | seq_printf(seq, "%s ", handle->name); |
1096 | seq_putc(seq, '\n'); | 1096 | seq_putc(seq, '\n'); |
1097 | 1097 | ||
1098 | input_seq_print_bitmap(seq, "PROP", dev->propbit, INPUT_PROP_MAX); | ||
1099 | |||
1098 | input_seq_print_bitmap(seq, "EV", dev->evbit, EV_MAX); | 1100 | input_seq_print_bitmap(seq, "EV", dev->evbit, EV_MAX); |
1099 | if (test_bit(EV_KEY, dev->evbit)) | 1101 | if (test_bit(EV_KEY, dev->evbit)) |
1100 | input_seq_print_bitmap(seq, "KEY", dev->keybit, KEY_MAX); | 1102 | input_seq_print_bitmap(seq, "KEY", dev->keybit, KEY_MAX); |
@@ -1318,11 +1320,26 @@ static ssize_t input_dev_show_modalias(struct device *dev, | |||
1318 | } | 1320 | } |
1319 | static DEVICE_ATTR(modalias, S_IRUGO, input_dev_show_modalias, NULL); | 1321 | static DEVICE_ATTR(modalias, S_IRUGO, input_dev_show_modalias, NULL); |
1320 | 1322 | ||
1323 | static int input_print_bitmap(char *buf, int buf_size, unsigned long *bitmap, | ||
1324 | int max, int add_cr); | ||
1325 | |||
1326 | static ssize_t input_dev_show_properties(struct device *dev, | ||
1327 | struct device_attribute *attr, | ||
1328 | char *buf) | ||
1329 | { | ||
1330 | struct input_dev *input_dev = to_input_dev(dev); | ||
1331 | int len = input_print_bitmap(buf, PAGE_SIZE, input_dev->propbit, | ||
1332 | INPUT_PROP_MAX, true); | ||
1333 | return min_t(int, len, PAGE_SIZE); | ||
1334 | } | ||
1335 | static DEVICE_ATTR(properties, S_IRUGO, input_dev_show_properties, NULL); | ||
1336 | |||
1321 | static struct attribute *input_dev_attrs[] = { | 1337 | static struct attribute *input_dev_attrs[] = { |
1322 | &dev_attr_name.attr, | 1338 | &dev_attr_name.attr, |
1323 | &dev_attr_phys.attr, | 1339 | &dev_attr_phys.attr, |
1324 | &dev_attr_uniq.attr, | 1340 | &dev_attr_uniq.attr, |
1325 | &dev_attr_modalias.attr, | 1341 | &dev_attr_modalias.attr, |
1342 | &dev_attr_properties.attr, | ||
1326 | NULL | 1343 | NULL |
1327 | }; | 1344 | }; |
1328 | 1345 | ||
@@ -1522,6 +1539,8 @@ static int input_dev_uevent(struct device *device, struct kobj_uevent_env *env) | |||
1522 | if (dev->uniq) | 1539 | if (dev->uniq) |
1523 | INPUT_ADD_HOTPLUG_VAR("UNIQ=\"%s\"", dev->uniq); | 1540 | INPUT_ADD_HOTPLUG_VAR("UNIQ=\"%s\"", dev->uniq); |
1524 | 1541 | ||
1542 | INPUT_ADD_HOTPLUG_BM_VAR("PROP=", dev->propbit, INPUT_PROP_MAX); | ||
1543 | |||
1525 | INPUT_ADD_HOTPLUG_BM_VAR("EV=", dev->evbit, EV_MAX); | 1544 | INPUT_ADD_HOTPLUG_BM_VAR("EV=", dev->evbit, EV_MAX); |
1526 | if (test_bit(EV_KEY, dev->evbit)) | 1545 | if (test_bit(EV_KEY, dev->evbit)) |
1527 | INPUT_ADD_HOTPLUG_BM_VAR("KEY=", dev->keybit, KEY_MAX); | 1546 | INPUT_ADD_HOTPLUG_BM_VAR("KEY=", dev->keybit, KEY_MAX); |
diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c index bea89722c4e9..82542a1c1098 100644 --- a/drivers/input/misc/uinput.c +++ b/drivers/input/misc/uinput.c | |||
@@ -680,6 +680,10 @@ static long uinput_ioctl_handler(struct file *file, unsigned int cmd, | |||
680 | retval = uinput_set_bit(arg, swbit, SW_MAX); | 680 | retval = uinput_set_bit(arg, swbit, SW_MAX); |
681 | break; | 681 | break; |
682 | 682 | ||
683 | case UI_SET_PROPBIT: | ||
684 | retval = uinput_set_bit(arg, propbit, INPUT_PROP_MAX); | ||
685 | break; | ||
686 | |||
683 | case UI_SET_PHYS: | 687 | case UI_SET_PHYS: |
684 | if (udev->state == UIST_CREATED) { | 688 | if (udev->state == UIST_CREATED) { |
685 | retval = -EINVAL; | 689 | retval = -EINVAL; |