aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorHenrik Rydberg <rydberg@euromail.se>2010-12-18 14:51:13 -0500
committerHenrik Rydberg <rydberg@euromail.se>2010-12-20 03:37:33 -0500
commit85b7720039fc000b561c20fe2aaa3b54cddae4a7 (patch)
tree8fee2c82e215b87699ad6615239752af50ac9310 /drivers
parent4dd295a73e80b55c3fec25555bf0a5d253023740 (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.c4
-rw-r--r--drivers/input/input.c19
-rw-r--r--drivers/input/misc/uinput.c4
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}
1319static DEVICE_ATTR(modalias, S_IRUGO, input_dev_show_modalias, NULL); 1321static DEVICE_ATTR(modalias, S_IRUGO, input_dev_show_modalias, NULL);
1320 1322
1323static int input_print_bitmap(char *buf, int buf_size, unsigned long *bitmap,
1324 int max, int add_cr);
1325
1326static 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}
1335static DEVICE_ATTR(properties, S_IRUGO, input_dev_show_properties, NULL);
1336
1321static struct attribute *input_dev_attrs[] = { 1337static 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;