diff options
author | Henrik Rydberg <rydberg@euromail.se> | 2013-02-25 11:31:43 +0100 |
---|---|---|
committer | Mandar Padmawar <mpadmawar@nvidia.com> | 2014-06-25 00:49:22 -0700 |
commit | 24ecbc72fa2f744b82c46001173b88af9ad6f665 (patch) | |
tree | d8d25459dd293f350fcc486c9bfb4abd04c43be7 | |
parent | 03594fba1aadc12c1eb79b4d338418768a0d6abb (diff) |
HID: Extend the interface with report requests
Some drivers send reports directly to underlying device, creating an
unwanted dependency on the underlying transport layer. This patch adds
hid_hw_request() to the interface, thereby removing usbhid from the
lion share of the drivers.
Signed-off-by: Henrik Rydberg <rydberg@euromail.se>
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
(cherry picked from commit e90a6df80dc45ab53d2f4f4db297434e48c0208e)
Change-Id: Ib042c9600a56d092e1548e7c12a1fddf28a0ac5b
Signed-off-by: Jean Huang <jeanh@nvidia.com>
Reviewed-on: http://git-master/r/427991
GVS: Gerrit_Virtual_Submit
-rw-r--r-- | drivers/hid/usbhid/hid-core.c | 13 | ||||
-rw-r--r-- | include/linux/hid.h | 22 |
2 files changed, 34 insertions, 1 deletions
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c index f03401947718..ec70dd25ba59 100644 --- a/drivers/hid/usbhid/hid-core.c +++ b/drivers/hid/usbhid/hid-core.c @@ -1242,6 +1242,18 @@ static int usbhid_power(struct hid_device *hid, int lvl) return r; } +static void usbhid_request(struct hid_device *hid, struct hid_report *rep, int reqtype) +{ + switch (reqtype) { + case HID_REQ_GET_REPORT: + usbhid_submit_report(hid, rep, USB_DIR_IN); + break; + case HID_REQ_SET_REPORT: + usbhid_submit_report(hid, rep, USB_DIR_OUT); + break; + } +} + static struct hid_ll_driver usb_hid_driver = { .parse = usbhid_parse, .start = usbhid_start, @@ -1250,6 +1262,7 @@ static struct hid_ll_driver usb_hid_driver = { .close = usbhid_close, .power = usbhid_power, .hidinput_input_event = usb_hidinput_input_event, + .request = usbhid_request, }; static int usbhid_probe(struct usb_interface *intf, const struct usb_device_id *id) diff --git a/include/linux/hid.h b/include/linux/hid.h index 18f54de6ad09..45c97479a317 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -686,6 +686,7 @@ struct hid_driver { * @hidinput_input_event: event input event (e.g. ff or leds) * @parse: this method is called only once to parse the device data, * shouldn't allocate anything to not leak memory + * @request: send report request to device (e.g. feature report) */ struct hid_ll_driver { int (*start)(struct hid_device *hdev); @@ -700,6 +701,10 @@ struct hid_ll_driver { unsigned int code, int value); int (*parse)(struct hid_device *hdev); + + void (*request)(struct hid_device *hdev, + struct hid_report *report, int reqtype); + }; #define PM_HINT_FULLON 1<<5 @@ -905,7 +910,22 @@ static inline int hid_hw_power(struct hid_device *hdev, int level) return hdev->ll_driver->power ? hdev->ll_driver->power(hdev, level) : 0; } -void hid_report_raw_event(struct hid_device *hid, int type, u8 *data, int size, + +/** + * hid_hw_request - send report request to device + * + * @hdev: hid device + * @report: report to send + * @reqtype: hid request type + */ +static inline void hid_hw_request(struct hid_device *hdev, + struct hid_report *report, int reqtype) +{ + if (hdev->ll_driver->request) + hdev->ll_driver->request(hdev, report, reqtype); +} + +int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, int size, int interrupt); extern int hid_generic_init(void); |