1 #ifndef _IPXE_USBHID_H
2 #define _IPXE_USBHID_H
3 
4 /** @file
5  *
6  * USB human interface devices (HID)
7  *
8  */
9 
10 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
11 
12 #include <ipxe/usb.h>
13 
14 /** Class code for human interface devices */
15 #define USB_CLASS_HID 3
16 
17 /** Subclass code for boot devices */
18 #define USB_SUBCLASS_HID_BOOT 1
19 
20 /** Set protocol */
21 #define USBHID_SET_PROTOCOL						\
22 	( USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE |		\
23 	  USB_REQUEST_TYPE ( 0x0b ) )
24 
25 /** Boot protocol */
26 #define USBHID_PROTOCOL_BOOT 0
27 
28 /** Report protocol */
29 #define USBHID_PROTOCOL_REPORT 1
30 
31 /** Set idle time */
32 #define USBHID_SET_IDLE							\
33 	( USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE |		\
34 	  USB_REQUEST_TYPE ( 0x0a ) )
35 
36 /** Set report */
37 #define USBHID_SET_REPORT						\
38 	( USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE |		\
39 	  USB_REQUEST_TYPE ( 0x09 ) )
40 
41 /** Input report type */
42 #define USBHID_REPORT_INPUT 0x01
43 
44 /** Output report type */
45 #define USBHID_REPORT_OUTPUT 0x02
46 
47 /** Feature report type */
48 #define USBHID_REPORT_FEATURE 0x03
49 
50 /** A USB human interface device */
51 struct usb_hid {
52 	/** USB function */
53 	struct usb_function *func;
54 	/** Interrupt IN endpoint */
55 	struct usb_endpoint in;
56 	/** Interrupt OUT endpoint (optional) */
57 	struct usb_endpoint out;
58 };
59 
60 /**
61  * Initialise USB human interface device
62  *
63  * @v hid		USB human interface device
64  * @v func		USB function
65  * @v in		Interrupt IN endpoint operations
66  * @v out		Interrupt OUT endpoint operations (or NULL)
67  */
68 static inline __attribute__ (( always_inline )) void
usbhid_init(struct usb_hid * hid,struct usb_function * func,struct usb_endpoint_driver_operations * in,struct usb_endpoint_driver_operations * out)69 usbhid_init ( struct usb_hid *hid, struct usb_function *func,
70 	      struct usb_endpoint_driver_operations *in,
71 	      struct usb_endpoint_driver_operations *out ) {
72 	struct usb_device *usb = func->usb;
73 
74 	hid->func = func;
75 	usb_endpoint_init ( &hid->in, usb, in );
76 	if ( out )
77 		usb_endpoint_init ( &hid->out, usb, out );
78 }
79 
80 /**
81  * Set protocol
82  *
83  * @v usb		USB device
84  * @v interface		Interface number
85  * @v protocol		HID protocol
86  * @ret rc		Return status code
87  */
88 static inline __attribute__ (( always_inline )) int
usbhid_set_protocol(struct usb_device * usb,unsigned int interface,unsigned int protocol)89 usbhid_set_protocol ( struct usb_device *usb, unsigned int interface,
90 		      unsigned int protocol ) {
91 
92 	return usb_control ( usb, USBHID_SET_PROTOCOL, protocol, interface,
93 			     NULL, 0 );
94 }
95 
96 /**
97  * Set idle time
98  *
99  * @v usb		USB device
100  * @v interface		Interface number
101  * @v report		Report ID
102  * @v duration		Duration (in 4ms units)
103  * @ret rc		Return status code
104  */
105 static inline __attribute__ (( always_inline )) int
usbhid_set_idle(struct usb_device * usb,unsigned int interface,unsigned int report,unsigned int duration)106 usbhid_set_idle ( struct usb_device *usb, unsigned int interface,
107 		  unsigned int report, unsigned int duration ) {
108 
109 	return usb_control ( usb, USBHID_SET_IDLE,
110 			     ( ( duration << 8 ) | report ),
111 			     interface, NULL, 0 );
112 }
113 
114 /**
115  * Set report
116  *
117  * @v usb		USB device
118  * @v interface		Interface number
119  * @v type		Report type
120  * @v report		Report ID
121  * @v data		Report data
122  * @v len		Length of report data
123  * @ret rc		Return status code
124  */
125 static inline __attribute__ (( always_inline )) int
usbhid_set_report(struct usb_device * usb,unsigned int interface,unsigned int type,unsigned int report,void * data,size_t len)126 usbhid_set_report ( struct usb_device *usb, unsigned int interface,
127 		    unsigned int type, unsigned int report, void *data,
128 		    size_t len ) {
129 
130 	return usb_control ( usb, USBHID_SET_REPORT, ( ( type << 8 ) | report ),
131 			     interface, data, len );
132 }
133 
134 extern int usbhid_open ( struct usb_hid *hid );
135 extern void usbhid_close ( struct usb_hid *hid );
136 extern int usbhid_refill ( struct usb_hid *hid );
137 extern int usbhid_describe ( struct usb_hid *hid,
138 			     struct usb_configuration_descriptor *config );
139 
140 #endif /* _IPXE_USBHID_H */
141