aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJiri Kosina <jkosina@suse.cz>2006-12-08 12:40:53 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2006-12-08 13:43:12 -0500
commit229695e51efc4ed5e04ab471c82591d0f432909d (patch)
tree9e333780589010c61224f185a4a83323305e7d8d
parentdde5845a529ff753364a6d1aea61180946270bfa (diff)
[PATCH] Generic HID layer - API
- fixed generic API (added neccessary EXPORT_SYMBOL, fixed hid.h to provide correct prototypes) - extended hid_device with open/close/event function pointers to driver-specific functions - added driver specific driver_data to hid_device Signed-off-by: Jiri Kosina <jkosina@suse.cz> Signed-off-by: Marcel Holtmann <marcel@holtmann.org> Cc: Dmitry Torokhov <dmitry.torokhov@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/hid/hid-core.c22
-rw-r--r--drivers/hid/hid-input.c19
-rw-r--r--drivers/usb/input/hid-core.c9
-rw-r--r--drivers/usb/input/hid-ff.c2
-rw-r--r--drivers/usb/input/hiddev.c2
-rw-r--r--include/linux/hid.h36
6 files changed, 64 insertions, 26 deletions
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 689ae16adf33..8474a7923322 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * USB HID support for Linux 2 * HID support for Linux
3 * 3 *
4 * Copyright (c) 1999 Andreas Gal 4 * Copyright (c) 1999 Andreas Gal
5 * Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz> 5 * Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz>
@@ -31,8 +31,6 @@
31#undef DEBUG 31#undef DEBUG
32#undef DEBUG_DATA 32#undef DEBUG_DATA
33 33
34#include <linux/usb.h>
35
36#include <linux/hid.h> 34#include <linux/hid.h>
37#include <linux/hiddev.h> 35#include <linux/hiddev.h>
38 36
@@ -538,7 +536,7 @@ static void hid_free_report(struct hid_report *report)
538 * Free a device structure, all reports, and all fields. 536 * Free a device structure, all reports, and all fields.
539 */ 537 */
540 538
541static void hid_free_device(struct hid_device *device) 539void hid_free_device(struct hid_device *device)
542{ 540{
543 unsigned i,j; 541 unsigned i,j;
544 542
@@ -555,6 +553,7 @@ static void hid_free_device(struct hid_device *device)
555 kfree(device->rdesc); 553 kfree(device->rdesc);
556 kfree(device); 554 kfree(device);
557} 555}
556EXPORT_SYMBOL_GPL(hid_free_device);
558 557
559/* 558/*
560 * Fetch a report description item from the data stream. We support long 559 * Fetch a report description item from the data stream. We support long
@@ -629,7 +628,7 @@ static u8 *fetch_item(__u8 *start, __u8 *end, struct hid_item *item)
629 * enumerated, fields are attached to these reports. 628 * enumerated, fields are attached to these reports.
630 */ 629 */
631 630
632static struct hid_device *hid_parse_report(__u8 *start, unsigned size) 631struct hid_device *hid_parse_report(__u8 *start, unsigned size)
633{ 632{
634 struct hid_device *device; 633 struct hid_device *device;
635 struct hid_parser *parser; 634 struct hid_parser *parser;
@@ -719,6 +718,7 @@ static struct hid_device *hid_parse_report(__u8 *start, unsigned size)
719 kfree(parser); 718 kfree(parser);
720 return NULL; 719 return NULL;
721} 720}
721EXPORT_SYMBOL_GPL(hid_parse_report);
722 722
723/* 723/*
724 * Convert a signed n-bit integer to signed 32-bit integer. Common 724 * Convert a signed n-bit integer to signed 32-bit integer. Common
@@ -767,10 +767,10 @@ static __inline__ __u32 extract(__u8 *report, unsigned offset, unsigned n)
767 WARN_ON(n > 32); 767 WARN_ON(n > 32);
768 768
769 report += offset >> 3; /* adjust byte index */ 769 report += offset >> 3; /* adjust byte index */
770 offset &= 7; /* now only need bit offset into one byte */ 770 offset &= 7; /* now only need bit offset into one byte */
771 x = get_unaligned((u64 *) report); 771 x = get_unaligned((u64 *) report);
772 x = le64_to_cpu(x); 772 x = le64_to_cpu(x);
773 x = (x >> offset) & ((1ULL << n) - 1); /* extract bit field */ 773 x = (x >> offset) & ((1ULL << n) - 1); /* extract bit field */
774 return (u32) x; 774 return (u32) x;
775} 775}
776 776
@@ -829,7 +829,7 @@ static void hid_process_event(struct hid_device *hid, struct hid_field *field, s
829 * reporting to the layer). 829 * reporting to the layer).
830 */ 830 */
831 831
832static void hid_input_field(struct hid_device *hid, struct hid_field *field, __u8 *data, int interrupt) 832void hid_input_field(struct hid_device *hid, struct hid_field *field, __u8 *data, int interrupt)
833{ 833{
834 unsigned n; 834 unsigned n;
835 unsigned count = field->report_count; 835 unsigned count = field->report_count;
@@ -875,7 +875,7 @@ static void hid_input_field(struct hid_device *hid, struct hid_field *field, __u
875exit: 875exit:
876 kfree(value); 876 kfree(value);
877} 877}
878 878EXPORT_SYMBOL_GPL(hid_input_field);
879 879
880/* 880/*
881 * Output the field into the report. 881 * Output the field into the report.
@@ -900,7 +900,7 @@ static void hid_output_field(struct hid_field *field, __u8 *data)
900 * Create a report. 900 * Create a report.
901 */ 901 */
902 902
903static void hid_output_report(struct hid_report *report, __u8 *data) 903void hid_output_report(struct hid_report *report, __u8 *data)
904{ 904{
905 unsigned n; 905 unsigned n;
906 906
@@ -910,6 +910,7 @@ static void hid_output_report(struct hid_report *report, __u8 *data)
910 for (n = 0; n < report->maxfield; n++) 910 for (n = 0; n < report->maxfield; n++)
911 hid_output_field(report->field[n], data); 911 hid_output_field(report->field[n], data);
912} 912}
913EXPORT_SYMBOL_GPL(hid_output_report);
913 914
914/* 915/*
915 * Set a field value. The report this field belongs to has to be 916 * Set a field value. The report this field belongs to has to be
@@ -937,4 +938,5 @@ int hid_set_field(struct hid_field *field, unsigned offset, __s32 value)
937 field->value[offset] = value; 938 field->value[offset] = value;
938 return 0; 939 return 0;
939} 940}
941EXPORT_SYMBOL_GPL(hid_set_field);
940 942
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
index d459005062e0..6d3d80ba9582 100644
--- a/drivers/hid/hid-input.c
+++ b/drivers/hid/hid-input.c
@@ -727,8 +727,9 @@ void hidinput_report_event(struct hid_device *hid, struct hid_report *report)
727 list_for_each_entry(hidinput, &hid->inputs, list) 727 list_for_each_entry(hidinput, &hid->inputs, list)
728 input_sync(hidinput->input); 728 input_sync(hidinput->input);
729} 729}
730EXPORT_SYMBOL_GPL(hidinput_report_event);
730 731
731static int hidinput_find_field(struct hid_device *hid, unsigned int type, unsigned int code, struct hid_field **field) 732int hidinput_find_field(struct hid_device *hid, unsigned int type, unsigned int code, struct hid_field **field)
732{ 733{
733 struct hid_report *report; 734 struct hid_report *report;
734 int i, j; 735 int i, j;
@@ -743,6 +744,7 @@ static int hidinput_find_field(struct hid_device *hid, unsigned int type, unsign
743 } 744 }
744 return -1; 745 return -1;
745} 746}
747EXPORT_SYMBOL_GPL(hidinput_find_field);
746 748
747/* 749/*
748 * Register the input device; print a message. 750 * Register the input device; print a message.
@@ -752,7 +754,6 @@ static int hidinput_find_field(struct hid_device *hid, unsigned int type, unsign
752 754
753int hidinput_connect(struct hid_device *hid) 755int hidinput_connect(struct hid_device *hid)
754{ 756{
755 struct usb_device *dev = hid->dev;
756 struct hid_report *report; 757 struct hid_report *report;
757 struct hid_input *hidinput = NULL; 758 struct hid_input *hidinput = NULL;
758 struct input_dev *input_dev; 759 struct input_dev *input_dev;
@@ -786,14 +787,17 @@ int hidinput_connect(struct hid_device *hid)
786 } 787 }
787 788
788 input_dev->private = hid; 789 input_dev->private = hid;
789 input_dev->event = hidinput_input_event; 790 input_dev->event = hid->hidinput_input_event;
790 input_dev->open = hidinput_open; 791 input_dev->open = hid->hidinput_open;
791 input_dev->close = hidinput_close; 792 input_dev->close = hid->hidinput_close;
792 793
793 input_dev->name = hid->name; 794 input_dev->name = hid->name;
794 input_dev->phys = hid->phys; 795 input_dev->phys = hid->phys;
795 input_dev->uniq = hid->uniq; 796 input_dev->uniq = hid->uniq;
796 usb_to_input_id(dev, &input_dev->id); 797 input_dev->id.bustype = hid->bus;
798 input_dev->id.vendor = hid->vendor;
799 input_dev->id.product = hid->product;
800 input_dev->id.version = hid->version;
797 input_dev->cdev.dev = &hid->intf->dev; 801 input_dev->cdev.dev = &hid->intf->dev;
798 802
799 hidinput->input = input_dev; 803 hidinput->input = input_dev;
@@ -827,6 +831,7 @@ int hidinput_connect(struct hid_device *hid)
827 831
828 return 0; 832 return 0;
829} 833}
834EXPORT_SYMBOL_GPL(hidinput_connect);
830 835
831void hidinput_disconnect(struct hid_device *hid) 836void hidinput_disconnect(struct hid_device *hid)
832{ 837{
@@ -838,3 +843,5 @@ void hidinput_disconnect(struct hid_device *hid)
838 kfree(hidinput); 843 kfree(hidinput);
839 } 844 }
840} 845}
846EXPORT_SYMBOL_GPL(hidinput_disconnect);
847
diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c
index 06e169b6a17e..462947f74135 100644
--- a/drivers/usb/input/hid-core.c
+++ b/drivers/usb/input/hid-core.c
@@ -497,7 +497,7 @@ void hid_submit_report(struct hid_device *hid, struct hid_report *report, unsign
497 spin_unlock_irqrestore(&hid->ctrllock, flags); 497 spin_unlock_irqrestore(&hid->ctrllock, flags);
498} 498}
499 499
500static int hidinput_input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) 500static int usb_hidinput_input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
501{ 501{
502 struct hid_device *hid = dev->private; 502 struct hid_device *hid = dev->private;
503 struct hid_field *field; 503 struct hid_field *field;
@@ -1231,6 +1231,10 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf)
1231 le16_to_cpu(dev->descriptor.idVendor), 1231 le16_to_cpu(dev->descriptor.idVendor),
1232 le16_to_cpu(dev->descriptor.idProduct)); 1232 le16_to_cpu(dev->descriptor.idProduct));
1233 1233
1234 hid->bus = BUS_USB;
1235 hid->vendor = dev->descriptor.idVendor;
1236 hid->product = dev->descriptor.idProduct;
1237
1234 usb_make_path(dev, hid->phys, sizeof(hid->phys)); 1238 usb_make_path(dev, hid->phys, sizeof(hid->phys));
1235 strlcat(hid->phys, "/input", sizeof(hid->phys)); 1239 strlcat(hid->phys, "/input", sizeof(hid->phys));
1236 len = strlen(hid->phys); 1240 len = strlen(hid->phys);
@@ -1250,6 +1254,9 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf)
1250 hid->urbctrl->setup_dma = hid->cr_dma; 1254 hid->urbctrl->setup_dma = hid->cr_dma;
1251 hid->urbctrl->transfer_dma = hid->ctrlbuf_dma; 1255 hid->urbctrl->transfer_dma = hid->ctrlbuf_dma;
1252 hid->urbctrl->transfer_flags |= (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP); 1256 hid->urbctrl->transfer_flags |= (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP);
1257 hid->hidinput_input_event = usb_hidinput_input_event;
1258 hid->hidinput_open = hidinput_open;
1259 hid->hidinput_close = hidinput_close;
1253 1260
1254 return hid; 1261 return hid;
1255 1262
diff --git a/drivers/usb/input/hid-ff.c b/drivers/usb/input/hid-ff.c
index 4187f4ee9a9c..7ecdafa8eb7b 100644
--- a/drivers/usb/input/hid-ff.c
+++ b/drivers/usb/input/hid-ff.c
@@ -79,3 +79,5 @@ int hid_ff_init(struct hid_device* hid)
79 79
80 return init->init(hid); 80 return init->init(hid);
81} 81}
82EXPORT_SYMBOL_GPL(hid_ff_init);
83
diff --git a/drivers/usb/input/hiddev.c b/drivers/usb/input/hiddev.c
index cbd3b60d93bb..07d7996575cd 100644
--- a/drivers/usb/input/hiddev.c
+++ b/drivers/usb/input/hiddev.c
@@ -197,7 +197,7 @@ void hiddev_hid_event(struct hid_device *hid, struct hid_field *field,
197 197
198 hiddev_send_event(hid, &uref); 198 hiddev_send_event(hid, &uref);
199} 199}
200 200EXPORT_SYMBOL_GPL(hiddev_hid_event);
201 201
202void hiddev_report_event(struct hid_device *hid, struct hid_report *report) 202void hiddev_report_event(struct hid_device *hid, struct hid_report *report)
203{ 203{
diff --git a/include/linux/hid.h b/include/linux/hid.h
index ee567ae6fec1..0473b45b73b8 100644
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -403,11 +403,17 @@ struct hid_device { /* device report descriptor */
403 unsigned collection_size; /* Number of allocated hid_collections */ 403 unsigned collection_size; /* Number of allocated hid_collections */
404 unsigned maxcollection; /* Number of parsed collections */ 404 unsigned maxcollection; /* Number of parsed collections */
405 unsigned maxapplication; /* Number of applications */ 405 unsigned maxapplication; /* Number of applications */
406 unsigned short bus; /* BUS ID */
407 unsigned short vendor; /* Vendor ID */
408 unsigned short product; /* Product ID */
406 unsigned version; /* HID version */ 409 unsigned version; /* HID version */
407 unsigned country; /* HID country */ 410 unsigned country; /* HID country */
408 struct hid_report_enum report_enum[HID_REPORT_TYPES]; 411 struct hid_report_enum report_enum[HID_REPORT_TYPES];
409 412
410 struct usb_device *dev; /* USB device */ 413 struct usb_device *dev; /* device */
414
415 /* USB specific fields */
416
411 struct usb_interface *intf; /* USB interface */ 417 struct usb_interface *intf; /* USB interface */
412 int ifnum; /* USB interface number */ 418 int ifnum; /* USB interface number */
413 419
@@ -454,6 +460,13 @@ struct hid_device { /* device report descriptor */
454 char phys[64]; /* Device physical location */ 460 char phys[64]; /* Device physical location */
455 char uniq[64]; /* Device unique identifier (serial #) */ 461 char uniq[64]; /* Device unique identifier (serial #) */
456 462
463 void *driver_data;
464
465 /* device-specific function pointers */
466 int (*hidinput_input_event) (struct input_dev *, unsigned int, unsigned int, int);
467 int (*hidinput_open) (struct input_dev *);
468 void (*hidinput_close) (struct input_dev *);
469
457#ifdef CONFIG_USB_HIDINPUT_POWERBOOK 470#ifdef CONFIG_USB_HIDINPUT_POWERBOOK
458 unsigned long pb_pressed_fn[NBITS(KEY_MAX)]; 471 unsigned long pb_pressed_fn[NBITS(KEY_MAX)];
459 unsigned long pb_pressed_numlock[NBITS(KEY_MAX)]; 472 unsigned long pb_pressed_numlock[NBITS(KEY_MAX)];
@@ -502,17 +515,15 @@ struct hid_descriptor {
502/* Applications from HID Usage Tables 4/8/99 Version 1.1 */ 515/* Applications from HID Usage Tables 4/8/99 Version 1.1 */
503/* We ignore a few input applications that are not widely used */ 516/* We ignore a few input applications that are not widely used */
504#define IS_INPUT_APPLICATION(a) (((a >= 0x00010000) && (a <= 0x00010008)) || (a == 0x00010080) || (a == 0x000c0001)) 517#define IS_INPUT_APPLICATION(a) (((a >= 0x00010000) && (a <= 0x00010008)) || (a == 0x00010080) || (a == 0x000c0001))
518#else
519#define IS_INPUT_APPLICATION(a) (0)
520#endif
521
522/* HID core API */
505extern void hidinput_hid_event(struct hid_device *, struct hid_field *, struct hid_usage *, __s32); 523extern void hidinput_hid_event(struct hid_device *, struct hid_field *, struct hid_usage *, __s32);
506extern void hidinput_report_event(struct hid_device *hid, struct hid_report *report); 524extern void hidinput_report_event(struct hid_device *hid, struct hid_report *report);
507extern int hidinput_connect(struct hid_device *); 525extern int hidinput_connect(struct hid_device *);
508extern void hidinput_disconnect(struct hid_device *); 526extern void hidinput_disconnect(struct hid_device *);
509#else
510#define IS_INPUT_APPLICATION(a) (0)
511static inline void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value) { }
512static inline void hidinput_report_event(struct hid_device *hid, struct hid_report *report) { }
513static inline int hidinput_connect(struct hid_device *hid) { return -ENODEV; }
514static inline void hidinput_disconnect(struct hid_device *hid) { }
515#endif
516 527
517int hid_set_field(struct hid_field *, unsigned, __s32); 528int hid_set_field(struct hid_field *, unsigned, __s32);
518int hidinput_find_field(struct hid_device *hid, unsigned int type, unsigned int code, struct hid_field **field); 529int hidinput_find_field(struct hid_device *hid, unsigned int type, unsigned int code, struct hid_field **field);
@@ -536,5 +547,14 @@ static inline int hid_pidff_init(struct hid_device *hid) { return -ENODEV; }
536#else 547#else
537static inline int hid_ff_init(struct hid_device *hid) { return -1; } 548static inline int hid_ff_init(struct hid_device *hid) { return -1; }
538#endif 549#endif
550#ifdef DEBUG
551#define dbg(format, arg...) printk(KERN_DEBUG "%s: " format "\n" , \
552 __FILE__ , ## arg)
553#else
554#define dbg(format, arg...) do {} while (0)
555#endif
556
557#define err(format, arg...) printk(KERN_ERR "%s: " format "\n" , \
558 __FILE__ , ## arg)
539#endif 559#endif
540 560