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