aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid/usbhid
diff options
context:
space:
mode:
authorAlan Ott <alan@signal11.us>2011-01-18 03:04:39 -0500
committerJiri Kosina <jkosina@suse.cz>2011-02-11 09:05:49 -0500
commitb4dbde9da8ece42bbe4c70c26bac3b28dd6a3ddb (patch)
treefde6ca709962906877c25e0910d67ca5c00beb74 /drivers/hid/usbhid
parent0825411ade21a39ac63b3e011d092b1f95b5f3f5 (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.c35
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
802static 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
802static int usbhid_output_raw_report(struct hid_device *hid, __u8 *buf, size_t count, 836static 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