summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHenrik Rydberg <rydberg@euromail.se>2013-02-25 11:31:43 +0100
committerMandar Padmawar <mpadmawar@nvidia.com>2014-06-25 00:49:22 -0700
commit24ecbc72fa2f744b82c46001173b88af9ad6f665 (patch)
treed8d25459dd293f350fcc486c9bfb4abd04c43be7
parent03594fba1aadc12c1eb79b4d338418768a0d6abb (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.c13
-rw-r--r--include/linux/hid.h22
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);