diff options
author | Alan Ott <alan@signal11.us> | 2011-01-18 03:04:39 -0500 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2011-02-11 09:05:49 -0500 |
commit | b4dbde9da8ece42bbe4c70c26bac3b28dd6a3ddb (patch) | |
tree | fde6ca709962906877c25e0910d67ca5c00beb74 /drivers/hid/usbhid | |
parent | 0825411ade21a39ac63b3e011d092b1f95b5f3f5 (diff) |
HID: Add Support for Setting and Getting Feature Reports from hidraw
Per the HID Specification, Feature reports must be sent and received on
the Configuration endpoint (EP 0) through the Set_Report/Get_Report
interfaces. This patch adds two ioctls to hidraw to set and get feature
reports to and from the device. Modifications were made to hidraw and
usbhid.
New hidraw ioctls:
HIDIOCSFEATURE - Perform a Set_Report transfer of a Feature report.
HIDIOCGFEATURE - Perform a Get_Report transfer of a Feature report.
Signed-off-by: Alan Ott <alan@signal11.us>
Signed-off-by: Antonio Ospite <ospite@studenti.unina.it>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Diffstat (limited to 'drivers/hid/usbhid')
-rw-r--r-- | drivers/hid/usbhid/hid-core.c | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c index b336dd84036f..38c261a40c74 100644 --- a/drivers/hid/usbhid/hid-core.c +++ b/drivers/hid/usbhid/hid-core.c | |||
@@ -799,6 +799,40 @@ static int hid_alloc_buffers(struct usb_device *dev, struct hid_device *hid) | |||
799 | return 0; | 799 | return 0; |
800 | } | 800 | } |
801 | 801 | ||
802 | static int usbhid_get_raw_report(struct hid_device *hid, | ||
803 | unsigned char report_number, __u8 *buf, size_t count, | ||
804 | unsigned char report_type) | ||
805 | { | ||
806 | struct usbhid_device *usbhid = hid->driver_data; | ||
807 | struct usb_device *dev = hid_to_usb_dev(hid); | ||
808 | struct usb_interface *intf = usbhid->intf; | ||
809 | struct usb_host_interface *interface = intf->cur_altsetting; | ||
810 | int skipped_report_id = 0; | ||
811 | int ret; | ||
812 | |||
813 | /* Byte 0 is the report number. Report data starts at byte 1.*/ | ||
814 | buf[0] = report_number; | ||
815 | if (report_number == 0x0) { | ||
816 | /* Offset the return buffer by 1, so that the report ID | ||
817 | will remain in byte 0. */ | ||
818 | buf++; | ||
819 | count--; | ||
820 | skipped_report_id = 1; | ||
821 | } | ||
822 | ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), | ||
823 | HID_REQ_GET_REPORT, | ||
824 | USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE, | ||
825 | ((report_type + 1) << 8) | report_number, | ||
826 | interface->desc.bInterfaceNumber, buf, count, | ||
827 | USB_CTRL_SET_TIMEOUT); | ||
828 | |||
829 | /* count also the report id */ | ||
830 | if (ret > 0 && skipped_report_id) | ||
831 | ret++; | ||
832 | |||
833 | return ret; | ||
834 | } | ||
835 | |||
802 | static int usbhid_output_raw_report(struct hid_device *hid, __u8 *buf, size_t count, | 836 | static int usbhid_output_raw_report(struct hid_device *hid, __u8 *buf, size_t count, |
803 | unsigned char report_type) | 837 | unsigned char report_type) |
804 | { | 838 | { |
@@ -1139,6 +1173,7 @@ static int usbhid_probe(struct usb_interface *intf, const struct usb_device_id * | |||
1139 | 1173 | ||
1140 | usb_set_intfdata(intf, hid); | 1174 | usb_set_intfdata(intf, hid); |
1141 | hid->ll_driver = &usb_hid_driver; | 1175 | hid->ll_driver = &usb_hid_driver; |
1176 | hid->hid_get_raw_report = usbhid_get_raw_report; | ||
1142 | hid->hid_output_raw_report = usbhid_output_raw_report; | 1177 | hid->hid_output_raw_report = usbhid_output_raw_report; |
1143 | hid->ff_init = hid_pidff_init; | 1178 | hid->ff_init = hid_pidff_init; |
1144 | #ifdef CONFIG_USB_HIDDEV | 1179 | #ifdef CONFIG_USB_HIDDEV |