diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-04-30 12:37:55 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-04-30 12:37:55 -0400 |
| commit | 19b344efa35dbc253e2d10403dafe6aafda73c56 (patch) | |
| tree | 47c4ad25398642bcf1a93e186d77548ced3f7a2a /include/linux | |
| parent | 5d434fcb255dec99189f1c58a06e4f56e12bf77d (diff) | |
| parent | ad1b890e06af049fb48d7ccb799d0e96c071c893 (diff) | |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid
Pull HID updates from Jiri Kosina:
- hid driver transport cleanup, finalizing the long-desired decoupling
of core from transport layers, by Benjamin Tissoires and Henrik
Rydberg
- support for hybrid finger/pen multitouch HID devices, by Benjamin
Tissoires
- fix for long-standing issue in Logitech unifying driver sometimes not
inializing properly due to device specifics, by Andrew de los Reyes
- Wii remote driver updates to support 2nd generation of devices, by
David Herrmann
- support for Apple IR remote
- roccat driver now supports new devices (Roccat Kone Pure, IskuFX), by
Stefan Achatz
- debugfs locking fixes in hid debug interface, by Jiri Kosina
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid: (43 commits)
HID: protect hid_debug_list
HID: debug: break out hid_dump_report() into hid-debug
HID: Add PID for Japanese version of NE4K keyboard
HID: hid-lg4ff add support for new version of DFGT wheel
HID: icade: u16 which never < 0
HID: clarify Magic Mouse Kconfig description
HID: appleir: add support for Apple ir devices
HID: roccat: added media key support for Kone
HID: hid-lenovo-tpkbd: remove doubled hid_get_drvdata
HID: i2c-hid: fix length for set/get report in i2c hid
HID: wiimote: parse reduced status reports
HID: wiimote: add 2nd generation Wii Remote IDs
HID: wiimote: use unique battery names
HID: hidraw: warn if userspace headers are outdated
HID: multitouch: force BTN_STYLUS for pen devices
HID: multitouch: append " Pen" to the name of the stylus input
HID: multitouch: add handling for pen in dual-sensors device
HID: multitouch: change touch sensor detection in mt_input_configured()
HID: multitouch: do not map usage from non used reports
HID: multitouch: breaks out touch handling in specific functions
...
Diffstat (limited to 'include/linux')
| -rw-r--r-- | include/linux/hid-debug.h | 6 | ||||
| -rw-r--r-- | include/linux/hid.h | 101 |
2 files changed, 104 insertions, 3 deletions
diff --git a/include/linux/hid-debug.h b/include/linux/hid-debug.h index 53744fa1c8b7..8663f216c563 100644 --- a/include/linux/hid-debug.h +++ b/include/linux/hid-debug.h | |||
| @@ -22,11 +22,12 @@ | |||
| 22 | * | 22 | * |
| 23 | */ | 23 | */ |
| 24 | 24 | ||
| 25 | #define HID_DEBUG_BUFSIZE 512 | ||
| 26 | |||
| 27 | #ifdef CONFIG_DEBUG_FS | 25 | #ifdef CONFIG_DEBUG_FS |
| 28 | 26 | ||
| 27 | #define HID_DEBUG_BUFSIZE 512 | ||
| 28 | |||
| 29 | void hid_dump_input(struct hid_device *, struct hid_usage *, __s32); | 29 | void hid_dump_input(struct hid_device *, struct hid_usage *, __s32); |
| 30 | void hid_dump_report(struct hid_device *, int , u8 *, int); | ||
| 30 | void hid_dump_device(struct hid_device *, struct seq_file *); | 31 | void hid_dump_device(struct hid_device *, struct seq_file *); |
| 31 | void hid_dump_field(struct hid_field *, int, struct seq_file *); | 32 | void hid_dump_field(struct hid_field *, int, struct seq_file *); |
| 32 | char *hid_resolv_usage(unsigned, struct seq_file *); | 33 | char *hid_resolv_usage(unsigned, struct seq_file *); |
| @@ -50,6 +51,7 @@ struct hid_debug_list { | |||
| 50 | #else | 51 | #else |
| 51 | 52 | ||
| 52 | #define hid_dump_input(a,b,c) do { } while (0) | 53 | #define hid_dump_input(a,b,c) do { } while (0) |
| 54 | #define hid_dump_report(a,b,c,d) do { } while (0) | ||
| 53 | #define hid_dump_device(a,b) do { } while (0) | 55 | #define hid_dump_device(a,b) do { } while (0) |
| 54 | #define hid_dump_field(a,b,c) do { } while (0) | 56 | #define hid_dump_field(a,b,c) do { } while (0) |
| 55 | #define hid_resolv_usage(a,b) do { } while (0) | 57 | #define hid_resolv_usage(a,b) do { } while (0) |
diff --git a/include/linux/hid.h b/include/linux/hid.h index e14b465b1146..af1b86d46f6e 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h | |||
| @@ -282,6 +282,7 @@ struct hid_item { | |||
| 282 | #define HID_QUIRK_BADPAD 0x00000020 | 282 | #define HID_QUIRK_BADPAD 0x00000020 |
| 283 | #define HID_QUIRK_MULTI_INPUT 0x00000040 | 283 | #define HID_QUIRK_MULTI_INPUT 0x00000040 |
| 284 | #define HID_QUIRK_HIDINPUT_FORCE 0x00000080 | 284 | #define HID_QUIRK_HIDINPUT_FORCE 0x00000080 |
| 285 | #define HID_QUIRK_NO_EMPTY_INPUT 0x00000100 | ||
| 285 | #define HID_QUIRK_SKIP_OUTPUT_REPORTS 0x00010000 | 286 | #define HID_QUIRK_SKIP_OUTPUT_REPORTS 0x00010000 |
| 286 | #define HID_QUIRK_FULLSPEED_INTERVAL 0x10000000 | 287 | #define HID_QUIRK_FULLSPEED_INTERVAL 0x10000000 |
| 287 | #define HID_QUIRK_NO_INIT_REPORTS 0x20000000 | 288 | #define HID_QUIRK_NO_INIT_REPORTS 0x20000000 |
| @@ -456,7 +457,8 @@ struct hid_device { /* device report descriptor */ | |||
| 456 | unsigned country; /* HID country */ | 457 | unsigned country; /* HID country */ |
| 457 | struct hid_report_enum report_enum[HID_REPORT_TYPES]; | 458 | struct hid_report_enum report_enum[HID_REPORT_TYPES]; |
| 458 | 459 | ||
| 459 | struct semaphore driver_lock; /* protects the current driver */ | 460 | struct semaphore driver_lock; /* protects the current driver, except during input */ |
| 461 | struct semaphore driver_input_lock; /* protects the current driver */ | ||
| 460 | struct device dev; /* device */ | 462 | struct device dev; /* device */ |
| 461 | struct hid_driver *driver; | 463 | struct hid_driver *driver; |
| 462 | struct hid_ll_driver *ll_driver; | 464 | struct hid_ll_driver *ll_driver; |
| @@ -477,6 +479,7 @@ struct hid_device { /* device report descriptor */ | |||
| 477 | unsigned int status; /* see STAT flags above */ | 479 | unsigned int status; /* see STAT flags above */ |
| 478 | unsigned claimed; /* Claimed by hidinput, hiddev? */ | 480 | unsigned claimed; /* Claimed by hidinput, hiddev? */ |
| 479 | unsigned quirks; /* Various quirks the device can pull on us */ | 481 | unsigned quirks; /* Various quirks the device can pull on us */ |
| 482 | bool io_started; /* Protected by driver_lock. If IO has started */ | ||
| 480 | 483 | ||
| 481 | struct list_head inputs; /* The list of inputs */ | 484 | struct list_head inputs; /* The list of inputs */ |
| 482 | void *hiddev; /* The hiddev structure */ | 485 | void *hiddev; /* The hiddev structure */ |
| @@ -512,6 +515,7 @@ struct hid_device { /* device report descriptor */ | |||
| 512 | struct dentry *debug_rdesc; | 515 | struct dentry *debug_rdesc; |
| 513 | struct dentry *debug_events; | 516 | struct dentry *debug_events; |
| 514 | struct list_head debug_list; | 517 | struct list_head debug_list; |
| 518 | struct mutex debug_list_lock; | ||
| 515 | wait_queue_head_t debug_wait; | 519 | wait_queue_head_t debug_wait; |
| 516 | }; | 520 | }; |
| 517 | 521 | ||
| @@ -599,6 +603,10 @@ struct hid_usage_id { | |||
| 599 | * @resume: invoked on resume if device was not reset (NULL means nop) | 603 | * @resume: invoked on resume if device was not reset (NULL means nop) |
| 600 | * @reset_resume: invoked on resume if device was reset (NULL means nop) | 604 | * @reset_resume: invoked on resume if device was reset (NULL means nop) |
| 601 | * | 605 | * |
| 606 | * probe should return -errno on error, or 0 on success. During probe, | ||
| 607 | * input will not be passed to raw_event unless hid_device_io_start is | ||
| 608 | * called. | ||
| 609 | * | ||
| 602 | * raw_event and event should return 0 on no action performed, 1 when no | 610 | * raw_event and event should return 0 on no action performed, 1 when no |
| 603 | * further processing should be done and negative on error | 611 | * further processing should be done and negative on error |
| 604 | * | 612 | * |
| @@ -662,6 +670,9 @@ struct hid_driver { | |||
| 662 | * @hidinput_input_event: event input event (e.g. ff or leds) | 670 | * @hidinput_input_event: event input event (e.g. ff or leds) |
| 663 | * @parse: this method is called only once to parse the device data, | 671 | * @parse: this method is called only once to parse the device data, |
| 664 | * shouldn't allocate anything to not leak memory | 672 | * shouldn't allocate anything to not leak memory |
| 673 | * @request: send report request to device (e.g. feature report) | ||
| 674 | * @wait: wait for buffered io to complete (send/recv reports) | ||
| 675 | * @idle: send idle request to device | ||
| 665 | */ | 676 | */ |
| 666 | struct hid_ll_driver { | 677 | struct hid_ll_driver { |
| 667 | int (*start)(struct hid_device *hdev); | 678 | int (*start)(struct hid_device *hdev); |
| @@ -676,6 +687,13 @@ struct hid_ll_driver { | |||
| 676 | unsigned int code, int value); | 687 | unsigned int code, int value); |
| 677 | 688 | ||
| 678 | int (*parse)(struct hid_device *hdev); | 689 | int (*parse)(struct hid_device *hdev); |
| 690 | |||
| 691 | void (*request)(struct hid_device *hdev, | ||
| 692 | struct hid_report *report, int reqtype); | ||
| 693 | |||
| 694 | int (*wait)(struct hid_device *hdev); | ||
| 695 | int (*idle)(struct hid_device *hdev, int report, int idle, int reqtype); | ||
| 696 | |||
| 679 | }; | 697 | }; |
| 680 | 698 | ||
| 681 | #define PM_HINT_FULLON 1<<5 | 699 | #define PM_HINT_FULLON 1<<5 |
| @@ -738,6 +756,44 @@ const struct hid_device_id *hid_match_id(struct hid_device *hdev, | |||
| 738 | s32 hid_snto32(__u32 value, unsigned n); | 756 | s32 hid_snto32(__u32 value, unsigned n); |
| 739 | 757 | ||
| 740 | /** | 758 | /** |
| 759 | * hid_device_io_start - enable HID input during probe, remove | ||
| 760 | * | ||
| 761 | * @hid - the device | ||
| 762 | * | ||
| 763 | * This should only be called during probe or remove and only be | ||
| 764 | * called by the thread calling probe or remove. It will allow | ||
| 765 | * incoming packets to be delivered to the driver. | ||
| 766 | */ | ||
| 767 | static inline void hid_device_io_start(struct hid_device *hid) { | ||
| 768 | if (hid->io_started) { | ||
| 769 | dev_warn(&hid->dev, "io already started"); | ||
| 770 | return; | ||
| 771 | } | ||
| 772 | hid->io_started = true; | ||
| 773 | up(&hid->driver_input_lock); | ||
| 774 | } | ||
| 775 | |||
| 776 | /** | ||
| 777 | * hid_device_io_stop - disable HID input during probe, remove | ||
| 778 | * | ||
| 779 | * @hid - the device | ||
| 780 | * | ||
| 781 | * Should only be called after hid_device_io_start. It will prevent | ||
| 782 | * incoming packets from going to the driver for the duration of | ||
| 783 | * probe, remove. If called during probe, packets will still go to the | ||
| 784 | * driver after probe is complete. This function should only be called | ||
| 785 | * by the thread calling probe or remove. | ||
| 786 | */ | ||
| 787 | static inline void hid_device_io_stop(struct hid_device *hid) { | ||
| 788 | if (!hid->io_started) { | ||
| 789 | dev_warn(&hid->dev, "io already stopped"); | ||
| 790 | return; | ||
| 791 | } | ||
| 792 | hid->io_started = false; | ||
| 793 | down(&hid->driver_input_lock); | ||
| 794 | } | ||
| 795 | |||
| 796 | /** | ||
| 741 | * hid_map_usage - map usage input bits | 797 | * hid_map_usage - map usage input bits |
| 742 | * | 798 | * |
| 743 | * @hidinput: hidinput which we are interested in | 799 | * @hidinput: hidinput which we are interested in |
| @@ -883,6 +939,49 @@ static inline int hid_hw_power(struct hid_device *hdev, int level) | |||
| 883 | return hdev->ll_driver->power ? hdev->ll_driver->power(hdev, level) : 0; | 939 | return hdev->ll_driver->power ? hdev->ll_driver->power(hdev, level) : 0; |
| 884 | } | 940 | } |
| 885 | 941 | ||
| 942 | |||
| 943 | /** | ||
| 944 | * hid_hw_request - send report request to device | ||
| 945 | * | ||
| 946 | * @hdev: hid device | ||
| 947 | * @report: report to send | ||
| 948 | * @reqtype: hid request type | ||
| 949 | */ | ||
| 950 | static inline void hid_hw_request(struct hid_device *hdev, | ||
| 951 | struct hid_report *report, int reqtype) | ||
| 952 | { | ||
| 953 | if (hdev->ll_driver->request) | ||
| 954 | hdev->ll_driver->request(hdev, report, reqtype); | ||
| 955 | } | ||
| 956 | |||
| 957 | /** | ||
| 958 | * hid_hw_idle - send idle request to device | ||
| 959 | * | ||
| 960 | * @hdev: hid device | ||
| 961 | * @report: report to control | ||
| 962 | * @idle: idle state | ||
| 963 | * @reqtype: hid request type | ||
| 964 | */ | ||
| 965 | static inline int hid_hw_idle(struct hid_device *hdev, int report, int idle, | ||
| 966 | int reqtype) | ||
| 967 | { | ||
| 968 | if (hdev->ll_driver->idle) | ||
| 969 | return hdev->ll_driver->idle(hdev, report, idle, reqtype); | ||
| 970 | |||
| 971 | return 0; | ||
| 972 | } | ||
| 973 | |||
| 974 | /** | ||
| 975 | * hid_hw_wait - wait for buffered io to complete | ||
| 976 | * | ||
| 977 | * @hdev: hid device | ||
| 978 | */ | ||
| 979 | static inline void hid_hw_wait(struct hid_device *hdev) | ||
| 980 | { | ||
| 981 | if (hdev->ll_driver->wait) | ||
| 982 | hdev->ll_driver->wait(hdev); | ||
| 983 | } | ||
| 984 | |||
| 886 | int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, int size, | 985 | int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, int size, |
| 887 | int interrupt); | 986 | int interrupt); |
| 888 | 987 | ||
