1 /*
2  * SPDX-FileCopyrightText: 2019-2025 SiFli Technologies(Nanjing) Co., Ltd
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #ifndef BF0_HAL_USB_COMMON_H
8 #define BF0_HAL_USB_COMMON_H
9 
10 
11 
12 #ifdef __cplusplus
13 extern "C" {
14 #endif
15 
16 #define USB_CLASS_DEVICE                0x00
17 #define USB_CLASS_AUDIO                 0x01
18 #define USB_CLASS_CDC                   0x02
19 #define USB_CLASS_HID                   0x03
20 #define USB_CLASS_PHYSICAL              0x05
21 #define USB_CLASS_IMAGE                 0x06
22 #define USB_CLASS_PRINTER               0x07
23 #define USB_CLASS_MASS_STORAGE          0x08
24 #define USB_CLASS_HUB                   0x09
25 #define USB_CLASS_CDC_DATA              0x0a
26 #define USB_CLASS_SMART_CARD            0x0b
27 #define USB_CLASS_SECURITY              0x0d
28 #define USB_CLASS_VIDEO                 0x0e
29 #define USB_CLASS_HEALTHCARE            0x0f
30 #define USB_CLASS_DIAG_DEVICE           0xdc
31 #define USB_CLASS_WIRELESS              0xe0
32 #define USB_CLASS_MISC                  0xef
33 #define USB_CLASS_APP_SPECIFIC          0xfe
34 #define USB_CLASS_VEND_SPECIFIC         0xff
35 
36 #define USB_DESC_TYPE_DEVICE            0x01
37 #define USB_DESC_TYPE_CONFIGURATION     0x02
38 #define USB_DESC_TYPE_STRING            0x03
39 #define USB_DESC_TYPE_INTERFACE         0x04
40 #define USB_DESC_TYPE_ENDPOINT          0x05
41 #define USB_DESC_TYPE_DEVICEQUALIFIER   0x06
42 #define USB_DESC_TYPE_OTHERSPEED        0x07
43 #define USB_DESC_TYPE_IAD               0x0b
44 #define USB_DESC_TYPE_HID               0x21
45 #define USB_DESC_TYPE_REPORT            0x22
46 #define USB_DESC_TYPE_PHYSICAL          0x23
47 #define USB_DESC_TYPE_HUB               0x29
48 
49 #define USB_DESC_LENGTH_DEVICE          0x12
50 #define USB_DESC_LENGTH_CONFIG          0x9
51 #define USB_DESC_LENGTH_IAD             0x8
52 #define USB_DESC_LENGTH_STRING          0x4
53 #define USB_DESC_LENGTH_INTERFACE       0x9
54 #define USB_DESC_LENGTH_ENDPOINT        0x7
55 
56 #define USB_REQ_TYPE_STANDARD           0x00
57 #define USB_REQ_TYPE_CLASS              0x20
58 #define USB_REQ_TYPE_VENDOR             0x40
59 #define USB_REQ_TYPE_MASK               0x60
60 
61 #define USB_REQ_TYPE_DIR_OUT            0x00
62 #define USB_REQ_TYPE_DIR_IN             0x80
63 
64 #define USB_REQ_TYPE_DEVICE             0x00
65 #define USB_REQ_TYPE_INTERFACE          0x01
66 #define USB_REQ_TYPE_ENDPOINT           0x02
67 #define USB_REQ_TYPE_OTHER              0x03
68 #define USB_REQ_TYPE_RECIPIENT_MASK     0x1f
69 
70 #define USB_FEATURE_ENDPOINT_HALT       0x00
71 #define USB_FEATURE_DEV_REMOTE_WAKEUP   0x01
72 #define USB_FEATURE_TEST_MODE           0x02
73 
74 #define USB_REQ_GET_STATUS              0x00
75 #define USB_REQ_CLEAR_FEATURE           0x01
76 #define USB_REQ_SET_FEATURE             0x03
77 #define USB_REQ_SET_ADDRESS             0x05
78 #define USB_REQ_GET_DESCRIPTOR          0x06
79 #define USB_REQ_SET_DESCRIPTOR          0x07
80 #define USB_REQ_GET_CONFIGURATION       0x08
81 #define USB_REQ_SET_CONFIGURATION       0x09
82 #define USB_REQ_GET_INTERFACE           0x0A
83 #define USB_REQ_SET_INTERFACE           0x0B
84 #define USB_REQ_SYNCH_FRAME             0x0C
85 #define USB_REQ_SET_ENCRYPTION          0x0D
86 #define USB_REQ_GET_ENCRYPTION          0x0E
87 #define USB_REQ_RPIPE_ABORT             0x0E
88 #define USB_REQ_SET_HANDSHAKE           0x0F
89 #define USB_REQ_RPIPE_RESET             0x0F
90 #define USB_REQ_GET_HANDSHAKE           0x10
91 #define USB_REQ_SET_CONNECTION          0x11
92 #define USB_REQ_SET_SECURITY_DATA       0x12
93 #define USB_REQ_GET_SECURITY_DATA       0x13
94 #define USB_REQ_SET_WUSB_DATA           0x14
95 #define USB_REQ_LOOPBACK_DATA_WRITE     0x15
96 #define USB_REQ_LOOPBACK_DATA_READ      0x16
97 #define USB_REQ_SET_INTERFACE_DS        0x17
98 
99 #define USB_STRING_LANGID_INDEX         0x00
100 #define USB_STRING_MANU_INDEX           0x01
101 #define USB_STRING_PRODUCT_INDEX        0x02
102 #define USB_STRING_SERIAL_INDEX         0x03
103 #define USB_STRING_CONFIG_INDEX         0x04
104 #define USB_STRING_INTERFACE_INDEX      0x05
105 #define USB_STRING_OS_INDEX             0x06
106 #define USB_STRING_MAX                  USB_STRING_OS_INDEX
107 
108 #define USB_STRING_OS                   "MSFT100A"
109 
110 #define USB_PID_OUT                     0x01
111 #define USB_PID_ACK                     0x02
112 #define USB_PID_DATA0                   0x03
113 #define USB_PID_SOF                     0x05
114 #define USB_PID_IN                      0x09
115 #define USB_PID_NACK                    0x0A
116 #define USB_PID_DATA1                   0x0B
117 #define USB_PID_PRE                     0x0C
118 #define USB_PID_SETUP                   0x0D
119 #define USB_PID_STALL                   0x0E
120 
121 #define USB_EP_DESC_OUT                 0x00
122 #define USB_EP_DESC_IN                  0x80
123 #define USB_EP_DESC_NUM_MASK            0x0f
124 
125 #define USB_EP_ATTR_CONTROL             0x00
126 #define USB_EP_ATTR_ISOC                0x01
127 #define USB_EP_ATTR_BULK                0x02
128 #define USB_EP_ATTR_INT                 0x03
129 #define USB_EP_ATTR_TYPE_MASK           0x03
130 
131 #define USB_EPNO_MASK                   0x7f
132 #define USB_DIR_OUT                     0x00
133 #define USB_DIR_IN                      0x80
134 #define USB_DIR_INOUT                   0x40
135 #define USB_DIR_MASK                    0x80
136 
137 #define ID_UNASSIGNED                   0
138 #define ID_ASSIGNED                     1
139 
140 #define RH_GET_PORT_STATUS              0
141 #define RH_SET_PORT_STATUS              1
142 #define RH_CLEAR_PORT_FEATURE           2
143 #define RH_SET_PORT_FEATURE             3
144 
145 #define USB_BUS_POWERED                 0
146 #define USB_SELF_POWERED                1
147 #define USB_REMOTE_WAKEUP               1
148 #define USB_EP_HALT                     0
149 
150 /*
151  * Port feature numbers
152  */
153 #define PORT_FEAT_CONNECTION            0
154 #define PORT_FEAT_ENABLE                1
155 #define PORT_FEAT_SUSPEND               2
156 #define PORT_FEAT_OVER_CURRENT          3
157 #define PORT_FEAT_RESET                 4
158 #define PORT_FEAT_POWER                 8
159 #define PORT_FEAT_LOWSPEED              9
160 #define PORT_FEAT_HIGHSPEED             10
161 #define PORT_FEAT_C_CONNECTION          16
162 #define PORT_FEAT_C_ENABLE              17
163 #define PORT_FEAT_C_SUSPEND             18
164 #define PORT_FEAT_C_OVER_CURRENT        19
165 #define PORT_FEAT_C_RESET               20
166 
167 /*
168     The HcRhPortStatus[1:NDP] register is used to control and report port events on a per-port
169     basis. NumberDownstreamPorts represents the number of HcRhPortStatus registers that are
170     implemented in hardware.  The lower word is used to reflect the port status, whereas the upper
171     word reflects the status change bits.  Some status bits are implemented with special write behavior
172     (see below).  If a transaction (token through handshake) is in progress when a write to change
173     port status occurs, the resulting port status change must be postponed until the transaction
174     completes.  Reserved bits should always be written '0'.
175 */
176 #define PORT_CCS                        0x00000001UL    /* R:CurrentConnectStatus - W:ClearPortEnable    */
177 #define PORT_PES                        0x00000002UL    /* R:PortEnableStatus - W:SetPortEnable             */
178 #define PORT_PSS                        0x00000004UL    /* R:PortSuspendStatus - W:SetPortSuspend        */
179 #define PORT_POCI                       0x00000008UL    /* R:PortOverCurrentIndicator - W:ClearSuspendStatus    */
180 #define PORT_PRS                        0x00000010UL    /* R:PortResetStatus - W: SetPortReset            */
181 #define PORT_PPS                        0x00000100UL    /* R:PortPowerStatus - W: SetPortPower            */
182 #define PORT_LSDA                       0x00000200UL    /* R:LowSpeedDeviceAttached - W:ClearPortPower    */
183 #define PORT_CCSC                       0x00010000UL
184 #define PORT_PESC                       0x00020000UL
185 #define PORT_PSSC                       0x00040000UL
186 #define PORT_POCIC                      0x00080000UL
187 #define PORT_PRSC                       0x00100000UL
188 
189 /*
190  *Hub Status & Hub Change bit masks
191  */
192 #define HUB_STATUS_LOCAL_POWER          0x0001
193 #define HUB_STATUS_OVERCURRENT          0x0002
194 
195 #define HUB_CHANGE_LOCAL_POWER          0x0001
196 #define HUB_CHANGE_OVERCURRENT          0x0002
197 
198 #define USB_EP_ATTR(attr)               (attr & USB_EP_ATTR_TYPE_MASK)
199 #define USB_EP_DESC_NUM(addr)           (addr & USB_EP_DESC_NUM_MASK)
200 #define USB_EP_DIR(addr)                ((addr & USB_DIR_MASK)>>7)
201 
202 #define HID_REPORT_ID_KEYBOARD1         1
203 #define HID_REPORT_ID_KEYBOARD2         2
204 #define HID_REPORT_ID_KEYBOARD3         3
205 #define HID_REPORT_ID_KEYBOARD4         7
206 #define HID_REPORT_ID_MEDIA             4
207 #define HID_REPORT_ID_GENERAL           5
208 #define HID_REPORT_ID_MOUSE             6
209 
210 
211 #define uswap_32(x) \
212     ((((x) & 0xff000000) >> 24) | \
213      (((x) & 0x00ff0000) >>  8) | \
214      (((x) & 0x0000ff00) <<  8) | \
215      (((x) & 0x000000ff) << 24))
216 
217 #define  uswap_8(x) \
218     (((uint16_t)(*((uint8_t *)(x)))) + \
219     (((uint16_t)(*(((uint8_t *)(x)) + 1))) << 8))
220 
221 typedef void (*func_callback)(void *context);
222 typedef enum
223 {
224     USB_STATE_NOTATTACHED = 0,
225     USB_STATE_ATTACHED,
226     USB_STATE_POWERED,
227     USB_STATE_RECONNECTING,
228     USB_STATE_UNAUTHENTICATED,
229     USB_STATE_DEFAULT,
230     USB_STATE_ADDRESS,
231     USB_STATE_CONFIGURED,
232     USB_STATE_SUSPENDED
233 } udevice_state_t;
234 
235 typedef enum
236 {
237     STAGE_IDLE,
238     STAGE_SETUP,
239     STAGE_STATUS_IN,
240     STAGE_STATUS_OUT,
241     STAGE_DIN,
242     STAGE_DOUT
243 } uep0_stage_t;
244 
245 
246 struct usb_descriptor
247 {
248     uint8_t bLength;
249     uint8_t type;
250 };
251 typedef struct usb_descriptor *udesc_t;
252 
253 struct udevice_descriptor
254 {
255     uint8_t bLength;
256     uint8_t type;
257     uint16_t bcdUSB;
258     uint8_t bDeviceClass;
259     uint8_t bDeviceSubClass;
260     uint8_t bDeviceProtocol;
261     uint8_t bMaxPacketSize0;
262     uint16_t idVendor;
263     uint16_t idProduct;
264     uint16_t bcdDevice;
265     uint8_t iManufacturer;
266     uint8_t iProduct;
267     uint8_t iSerialNumber;
268     uint8_t bNumConfigurations;
269 };
270 typedef struct udevice_descriptor *udev_desc_t;
271 
272 struct uconfig_descriptor
273 {
274     uint8_t bLength;
275     uint8_t type;
276     uint16_t wTotalLength;
277     uint8_t bNumInterfaces;
278     uint8_t bConfigurationValue;
279     uint8_t iConfiguration;
280     uint8_t bmAttributes;
281     uint8_t MaxPower;
282     uint8_t data[256];
283 };
284 typedef struct uconfig_descriptor *ucfg_desc_t;
285 
286 struct uinterface_descriptor
287 {
288     uint8_t bLength;
289     uint8_t type;
290     uint8_t bInterfaceNumber;
291     uint8_t bAlternateSetting;
292     uint8_t bNumEndpoints;
293     uint8_t bInterfaceClass;
294     uint8_t bInterfaceSubClass;
295     uint8_t bInterfaceProtocol;
296     uint8_t iInterface;
297 };
298 typedef struct uinterface_descriptor *uintf_desc_t;
299 
300 /* Interface Association Descriptor (IAD) */
301 struct uiad_descriptor
302 {
303     uint8_t bLength;
304     uint8_t bDescriptorType;
305     uint8_t bFirstInterface;
306     uint8_t bInterfaceCount;
307     uint8_t bFunctionClass;
308     uint8_t bFunctionSubClass;
309     uint8_t bFunctionProtocol;
310     uint8_t iFunction;
311 };
312 typedef struct uiad_descriptor *uiad_desc_t;
313 
314 struct uendpoint_descriptor
315 {
316     uint8_t  bLength;
317     uint8_t  type;
318     uint8_t  bEndpointAddress;
319     uint8_t  bmAttributes;
320     uint16_t wMaxPacketSize;
321     uint8_t  bInterval;
322 };
323 typedef struct uendpoint_descriptor *uep_desc_t;
324 
325 struct ustring_descriptor
326 {
327     uint8_t bLength;
328     uint8_t type;
329     uint8_t String[64];
330 };
331 typedef struct ustring_descriptor *ustr_desc_t;
332 
333 struct uhub_descriptor
334 {
335     uint8_t length;
336     uint8_t type;
337     uint8_t num_ports;
338     uint16_t characteristics;
339     uint8_t pwron_to_good;        /* power on to power good */
340     uint8_t current;
341     uint8_t removable[8];
342     uint8_t pwr_ctl[8];
343 } __attribute__((packed));
344 typedef struct uhub_descriptor *uhub_desc_t;
345 
346 /* USB_DESC_TYPE_DEVICEQUALIFIER: Device Qualifier descriptor */
347 struct usb_qualifier_descriptor
348 {
349     uint8_t  bLength;
350     uint8_t  bDescriptorType;
351 
352     uint16_t bcdUSB; // TODO: big-endian.
353     uint8_t  bDeviceClass;
354     uint8_t  bDeviceSubClass;
355     uint8_t  bDeviceProtocol;
356     uint8_t  bMaxPacketSize0;
357     uint8_t  bNumConfigurations;
358     uint8_t  bRESERVED;
359 } __attribute__((packed));
360 
361 struct usb_os_header_comp_id_descriptor
362 {
363     uint32_t dwLength;
364     uint16_t bcdVersion;
365     uint16_t wIndex;
366     uint8_t  bCount;
367     uint8_t  reserved[7];
368 };
369 typedef struct usb_os_header_comp_id_descriptor *usb_os_header_desc_t;
370 
371 struct usb_os_property_header
372 {
373     uint32_t dwLength;
374     uint16_t bcdVersion;
375     uint16_t wIndex;
376     uint16_t wCount;
377 };
378 typedef struct usb_os_property_header *usb_os_property_header_t;
379 
380 #ifndef HID_SUB_DESCRIPTOR_MAX
381     #define  HID_SUB_DESCRIPTOR_MAX        1
382 #endif
383 
384 struct uhid_descriptor
385 {
386     uint8_t  bLength;
387     uint8_t  type;
388     uint16_t bcdHID;
389     uint8_t  bCountryCode;
390     uint8_t  bNumDescriptors;
391     struct hid_descriptor_list
392     {
393         uint8_t type;
394         uint16_t wLength;
395     } Descriptor[HID_SUB_DESCRIPTOR_MAX];
396 };
397 typedef struct uhid_descriptor *uhid_desc_t;
398 
399 struct hid_report
400 {
401     uint8_t report_id;
402     uint8_t report[63];
403     uint8_t size;
404 };
405 typedef struct hid_report *hid_report_t;
406 extern void HID_Report_Received(hid_report_t report);
407 
408 struct urequest
409 {
410     uint8_t  request_type;
411     uint8_t  bRequest;
412     uint16_t wValue;
413     uint16_t wIndex;
414     uint16_t wLength;
415 };
416 typedef struct urequest *ureq_t;
417 
418 #ifndef MIN
419     #define MIN(a, b) (a < b ? a : b)
420 #endif
421 #ifndef MAX
422     #define MAX(a, b) (a > b ? a : b)
423 #endif
424 
425 /*
426  * the define related to mass storage
427  */
428 #define USBREQ_GET_MAX_LUN              0xfe
429 #define USBREQ_MASS_STORAGE_RESET       0xff
430 
431 #define SIZEOF_CSW                      0x0d
432 #define SIZEOF_CBW                      0x1f
433 #define SIZEOF_INQUIRY_CMD              0x24
434 #define SIZEOF_MODE_SENSE_6             0x4
435 #define SIZEOF_READ_CAPACITIES          0xc
436 #define SIZEOF_READ_CAPACITY            0x8
437 #define SIZEOF_REQUEST_SENSE            0x12
438 
439 #define CBWFLAGS_DIR_M                  0x80
440 #define CBWFLAGS_DIR_IN                 0x80
441 #define CBWFLAGS_DIR_OUT                0x00
442 
443 #define SCSI_TEST_UNIT_READY            0x00
444 #define SCSI_REQUEST_SENSE              0x03
445 #define SCSI_INQUIRY_CMD                0x12
446 #define SCSI_ALLOW_REMOVAL              0x1e
447 #define SCSI_MODE_SENSE_6               0x1a
448 #define SCSI_START_STOP                 0x1b
449 #define SCSI_READ_CAPACITIES            0x23
450 #define SCSI_READ_CAPACITY              0x25
451 #define SCSI_READ_10                    0x28
452 #define SCSI_WRITE_10                   0x2a
453 #define SCSI_VERIFY_10                  0x2f
454 
455 #define CBW_SIGNATURE                   0x43425355
456 #define CSW_SIGNATURE                   0x53425355
457 #define CBW_TAG_VALUE                   0x12345678
458 
459 struct ustorage_cbw
460 {
461     uint32_t signature;
462     uint32_t tag;
463     uint32_t xfer_len;
464     uint8_t dflags;
465     uint8_t lun;
466     uint8_t cb_len;
467     uint8_t cb[16];
468 };
469 typedef struct ustorage_cbw *ustorage_cbw_t;
470 
471 struct ustorage_csw
472 {
473     uint32_t signature;
474     uint32_t tag;
475     uint32_t data_reside;
476     uint8_t  status;
477 };
478 typedef struct ustorage_csw *ustorage_csw_t;
479 
480 
481 #ifdef __cplusplus
482 }
483 #endif
484 #endif