aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2010-02-03 00:08:26 -0500
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2010-02-04 03:25:19 -0500
commit0b7024ac4df5821347141c18e680b7166bc1cb20 (patch)
tree7a61e55e66bdd39351b3ec39ecef367588b47170
parent1e87a43080a259a0e9739377708ece163b08de8d (diff)
Input: add match() method to input hanlders
Get rid of blacklist in input handler structure and instead allow handlers to define their own match() method to perform fine-grained filtering of supported devices. Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
-rw-r--r--drivers/char/keyboard.c24
-rw-r--r--drivers/input/input.c13
-rw-r--r--drivers/input/joydev.c32
-rw-r--r--include/linux/input.h6
4 files changed, 40 insertions, 35 deletions
diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c
index cbf64b985ef4..ada25bb8941e 100644
--- a/drivers/char/keyboard.c
+++ b/drivers/char/keyboard.c
@@ -1323,6 +1323,21 @@ static void kbd_event(struct input_handle *handle, unsigned int event_type,
1323 schedule_console_callback(); 1323 schedule_console_callback();
1324} 1324}
1325 1325
1326static bool kbd_match(struct input_handler *handler, struct input_dev *dev)
1327{
1328 int i;
1329
1330 if (test_bit(EV_SND, dev->evbit))
1331 return true;
1332
1333 if (test_bit(EV_KEY, dev->evbit))
1334 for (i = KEY_RESERVED; i < BTN_MISC; i++)
1335 if (test_bit(i, dev->keybit))
1336 return true;
1337
1338 return false;
1339}
1340
1326/* 1341/*
1327 * When a keyboard (or other input device) is found, the kbd_connect 1342 * When a keyboard (or other input device) is found, the kbd_connect
1328 * function is called. The function then looks at the device, and if it 1343 * function is called. The function then looks at the device, and if it
@@ -1334,14 +1349,6 @@ static int kbd_connect(struct input_handler *handler, struct input_dev *dev,
1334{ 1349{
1335 struct input_handle *handle; 1350 struct input_handle *handle;
1336 int error; 1351 int error;
1337 int i;
1338
1339 for (i = KEY_RESERVED; i < BTN_MISC; i++)
1340 if (test_bit(i, dev->keybit))
1341 break;
1342
1343 if (i == BTN_MISC && !test_bit(EV_SND, dev->evbit))
1344 return -ENODEV;
1345 1352
1346 handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL); 1353 handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL);
1347 if (!handle) 1354 if (!handle)
@@ -1407,6 +1414,7 @@ MODULE_DEVICE_TABLE(input, kbd_ids);
1407 1414
1408static struct input_handler kbd_handler = { 1415static struct input_handler kbd_handler = {
1409 .event = kbd_event, 1416 .event = kbd_event,
1417 .match = kbd_match,
1410 .connect = kbd_connect, 1418 .connect = kbd_connect,
1411 .disconnect = kbd_disconnect, 1419 .disconnect = kbd_disconnect,
1412 .start = kbd_start, 1420 .start = kbd_start,
diff --git a/drivers/input/input.c b/drivers/input/input.c
index 7080a9d4b840..dae49eba6ccd 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -723,12 +723,13 @@ EXPORT_SYMBOL(input_set_keycode);
723 if (i != BITS_TO_LONGS(max)) \ 723 if (i != BITS_TO_LONGS(max)) \
724 continue; 724 continue;
725 725
726static const struct input_device_id *input_match_device(const struct input_device_id *id, 726static const struct input_device_id *input_match_device(struct input_handler *handler,
727 struct input_dev *dev) 727 struct input_dev *dev)
728{ 728{
729 const struct input_device_id *id;
729 int i; 730 int i;
730 731
731 for (; id->flags || id->driver_info; id++) { 732 for (id = handler->id_table; id->flags || id->driver_info; id++) {
732 733
733 if (id->flags & INPUT_DEVICE_ID_MATCH_BUS) 734 if (id->flags & INPUT_DEVICE_ID_MATCH_BUS)
734 if (id->bustype != dev->id.bustype) 735 if (id->bustype != dev->id.bustype)
@@ -756,7 +757,8 @@ static const struct input_device_id *input_match_device(const struct input_devic
756 MATCH_BIT(ffbit, FF_MAX); 757 MATCH_BIT(ffbit, FF_MAX);
757 MATCH_BIT(swbit, SW_MAX); 758 MATCH_BIT(swbit, SW_MAX);
758 759
759 return id; 760 if (!handler->match || handler->match(handler, dev))
761 return id;
760 } 762 }
761 763
762 return NULL; 764 return NULL;
@@ -767,10 +769,7 @@ static int input_attach_handler(struct input_dev *dev, struct input_handler *han
767 const struct input_device_id *id; 769 const struct input_device_id *id;
768 int error; 770 int error;
769 771
770 if (handler->blacklist && input_match_device(handler->blacklist, dev)) 772 id = input_match_device(handler, dev);
771 return -ENODEV;
772
773 id = input_match_device(handler->id_table, dev);
774 if (!id) 773 if (!id)
775 return -ENODEV; 774 return -ENODEV;
776 775
diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c
index b1bd6dd32286..63e71f2a7acc 100644
--- a/drivers/input/joydev.c
+++ b/drivers/input/joydev.c
@@ -775,6 +775,20 @@ static void joydev_cleanup(struct joydev *joydev)
775 input_close_device(handle); 775 input_close_device(handle);
776} 776}
777 777
778
779static bool joydev_match(struct input_handler *handler, struct input_dev *dev)
780{
781 /* Avoid touchpads and touchscreens */
782 if (test_bit(EV_KEY, dev->evbit) && test_bit(BTN_TOUCH, dev->keybit))
783 return false;
784
785 /* Avoid tablets, digitisers and similar devices */
786 if (test_bit(EV_KEY, dev->evbit) && test_bit(BTN_DIGI, dev->keybit))
787 return false;
788
789 return true;
790}
791
778static int joydev_connect(struct input_handler *handler, struct input_dev *dev, 792static int joydev_connect(struct input_handler *handler, struct input_dev *dev,
779 const struct input_device_id *id) 793 const struct input_device_id *id)
780{ 794{
@@ -894,22 +908,6 @@ static void joydev_disconnect(struct input_handle *handle)
894 put_device(&joydev->dev); 908 put_device(&joydev->dev);
895} 909}
896 910
897static const struct input_device_id joydev_blacklist[] = {
898 {
899 .flags = INPUT_DEVICE_ID_MATCH_EVBIT |
900 INPUT_DEVICE_ID_MATCH_KEYBIT,
901 .evbit = { BIT_MASK(EV_KEY) },
902 .keybit = { [BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH) },
903 }, /* Avoid itouchpads and touchscreens */
904 {
905 .flags = INPUT_DEVICE_ID_MATCH_EVBIT |
906 INPUT_DEVICE_ID_MATCH_KEYBIT,
907 .evbit = { BIT_MASK(EV_KEY) },
908 .keybit = { [BIT_WORD(BTN_DIGI)] = BIT_MASK(BTN_DIGI) },
909 }, /* Avoid tablets, digitisers and similar devices */
910 { } /* Terminating entry */
911};
912
913static const struct input_device_id joydev_ids[] = { 911static const struct input_device_id joydev_ids[] = {
914 { 912 {
915 .flags = INPUT_DEVICE_ID_MATCH_EVBIT | 913 .flags = INPUT_DEVICE_ID_MATCH_EVBIT |
@@ -936,13 +934,13 @@ MODULE_DEVICE_TABLE(input, joydev_ids);
936 934
937static struct input_handler joydev_handler = { 935static struct input_handler joydev_handler = {
938 .event = joydev_event, 936 .event = joydev_event,
937 .match = joydev_match,
939 .connect = joydev_connect, 938 .connect = joydev_connect,
940 .disconnect = joydev_disconnect, 939 .disconnect = joydev_disconnect,
941 .fops = &joydev_fops, 940 .fops = &joydev_fops,
942 .minor = JOYDEV_MINOR_BASE, 941 .minor = JOYDEV_MINOR_BASE,
943 .name = "joydev", 942 .name = "joydev",
944 .id_table = joydev_ids, 943 .id_table = joydev_ids,
945 .blacklist = joydev_blacklist,
946}; 944};
947 945
948static int __init joydev_init(void) 946static int __init joydev_init(void)
diff --git a/include/linux/input.h b/include/linux/input.h
index 6c9d3d49fa91..8dc5d724c703 100644
--- a/include/linux/input.h
+++ b/include/linux/input.h
@@ -1200,6 +1200,8 @@ struct input_handle;
1200 * it may not sleep 1200 * it may not sleep
1201 * @filter: similar to @event; separates normal event handlers from 1201 * @filter: similar to @event; separates normal event handlers from
1202 * "filters". 1202 * "filters".
1203 * @match: called after comparing device's id with handler's id_table
1204 * to perform fine-grained matching between device and handler
1203 * @connect: called when attaching a handler to an input device 1205 * @connect: called when attaching a handler to an input device
1204 * @disconnect: disconnects a handler from input device 1206 * @disconnect: disconnects a handler from input device
1205 * @start: starts handler for given handle. This function is called by 1207 * @start: starts handler for given handle. This function is called by
@@ -1211,8 +1213,6 @@ struct input_handle;
1211 * @name: name of the handler, to be shown in /proc/bus/input/handlers 1213 * @name: name of the handler, to be shown in /proc/bus/input/handlers
1212 * @id_table: pointer to a table of input_device_ids this driver can 1214 * @id_table: pointer to a table of input_device_ids this driver can
1213 * handle 1215 * handle
1214 * @blacklist: pointer to a table of input_device_ids this driver should
1215 * ignore even if they match @id_table
1216 * @h_list: list of input handles associated with the handler 1216 * @h_list: list of input handles associated with the handler
1217 * @node: for placing the driver onto input_handler_list 1217 * @node: for placing the driver onto input_handler_list
1218 * 1218 *
@@ -1235,6 +1235,7 @@ struct input_handler {
1235 1235
1236 void (*event)(struct input_handle *handle, unsigned int type, unsigned int code, int value); 1236 void (*event)(struct input_handle *handle, unsigned int type, unsigned int code, int value);
1237 bool (*filter)(struct input_handle *handle, unsigned int type, unsigned int code, int value); 1237 bool (*filter)(struct input_handle *handle, unsigned int type, unsigned int code, int value);
1238 bool (*match)(struct input_handler *handler, struct input_dev *dev);
1238 int (*connect)(struct input_handler *handler, struct input_dev *dev, const struct input_device_id *id); 1239 int (*connect)(struct input_handler *handler, struct input_dev *dev, const struct input_device_id *id);
1239 void (*disconnect)(struct input_handle *handle); 1240 void (*disconnect)(struct input_handle *handle);
1240 void (*start)(struct input_handle *handle); 1241 void (*start)(struct input_handle *handle);
@@ -1244,7 +1245,6 @@ struct input_handler {
1244 const char *name; 1245 const char *name;
1245 1246
1246 const struct input_device_id *id_table; 1247 const struct input_device_id *id_table;
1247 const struct input_device_id *blacklist;
1248 1248
1249 struct list_head h_list; 1249 struct list_head h_list;
1250 struct list_head node; 1250 struct list_head node;