usb_device.h 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649
  1. /* Copyright (C) 2018 RDA Technologies Limited and/or its affiliates("RDA").
  2. * All rights reserved.
  3. *
  4. * This software is supplied "AS IS" without any warranties.
  5. * RDA assumes no responsibility or liability for the use of the software,
  6. * conveys no license or title under any patent, copyright, or mask work
  7. * right to the product. RDA reserves the right to make changes in the
  8. * software without notification. RDA also make no representation or
  9. * warranty that such application will be suitable for the specified use
  10. * without further testing or modification.
  11. */
  12. #ifndef _USB__DEVICE_H_
  13. #define _USB__DEVICE_H_
  14. #ifdef __cplusplus
  15. extern "C" {
  16. #endif
  17. #include <stdint.h>
  18. #include <stdbool.h>
  19. #include <stddef.h>
  20. #include "usb/usb_ch9.h"
  21. typedef enum
  22. {
  23. EP0_SETUP = 0,
  24. #define EP0_STATE_DIRIN_MASK 0b10
  25. #define EP0_STATE_DATA_MASK 0b1
  26. EP0_DATA_IN = 0b111,
  27. EP0_DATA_OUT = 0b101,
  28. EP0_STATUS_IN = 0b110,
  29. EP0_STATUS_OUT = 0b100,
  30. } ep0State_t;
  31. typedef enum
  32. {
  33. UDC_IDLE = 0,
  34. UDC_CONNECTED,
  35. UDC_DISCONNECT,
  36. } udcEvent_t;
  37. typedef void (*udcNotifier_t)(void *param, udcEvent_t event);
  38. /**
  39. * @brief USB device controller
  40. */
  41. typedef struct udc_s udc_t;
  42. /**
  43. * @brief USB device driver
  44. *
  45. * Such as a specific class, or a composite driver
  46. */
  47. typedef struct usb_dev_driver_s udevDrv_t;
  48. /**
  49. * @brief usb endpoint
  50. */
  51. typedef struct usb_ep
  52. {
  53. union {
  54. struct
  55. {
  56. uint8_t num : 7;
  57. uint8_t dirin : 1;
  58. };
  59. uint8_t address;
  60. };
  61. uint16_t mps;
  62. } usbEp_t;
  63. /**
  64. * @brief usb string
  65. */
  66. typedef struct usb_string
  67. {
  68. uint8_t id;
  69. uint8_t ref_count;
  70. const char *s;
  71. } usbString_t;
  72. /**
  73. * @brief the usb transfer request
  74. */
  75. typedef struct usb_xfer
  76. {
  77. void *buf; ///< transfer buffer
  78. uint32_t length; ///< transfer data length
  79. uint32_t actual; ///< actual transfered length, udc set it, caller only read
  80. int status; ///< transfer status, (0 - success; other negative - fail)
  81. uint8_t zlp; ///< may send zero packet or not, in transfer only
  82. uint8_t uncached; ///< address is uncached
  83. void *param; ///< caller context
  84. void (*complete)(usbEp_t *ep, struct usb_xfer *xfer); ///< transfer done callback
  85. } usbXfer_t;
  86. typedef struct
  87. {
  88. void (*setclk)(udc_t *udc, bool on); ///< set controller clock
  89. void (*setpower)(udc_t *udc, bool on); ///< set controller power
  90. void (*enable)(udc_t *udc); ///< enable the usb controller
  91. void (*disable)(udc_t *udc); ///< disable the usb controller
  92. void (*suspend)(udc_t *udc); ///< suspend the usb controller
  93. void (*resume)(udc_t *udc); ///< resume the usb controller
  94. } udcPlatOps_t;
  95. /**
  96. * @brief struct for udc operations
  97. */
  98. typedef struct
  99. {
  100. void (*start)(udc_t *udc); ///< start the udc
  101. void (*stop)(udc_t *udc); ///< stop the udc
  102. bool (*remote_wakeup)(udc_t *udc); ///< remote wakeup
  103. int (*enqueue)(udc_t *udc, usbEp_t *ep, usbXfer_t *req); ///< enqueue an usb request
  104. void (*dequeue)(udc_t *udc, usbEp_t *ep, usbXfer_t *req); ///< dequeue an usb request
  105. void (*dequeue_all)(udc_t *udc, usbEp_t *ep); ///< dequeue all for specific endpoint
  106. usbEp_t *(*ep_alloc)(udc_t *udc, usb_endpoint_descriptor_t *desc); ///< allocate an usb endpoint
  107. void (*ep_free)(udc_t *udc, usbEp_t *ep); ///< free an usb endpoint
  108. int (*ep_enable)(udc_t *udc, usbEp_t *ep); ///< enable the endpoint
  109. void (*ep_disable)(udc_t *udc, usbEp_t *ep); ///< disable the endpoint
  110. void (*ep_stall)(udc_t *udc, usbEp_t *ep, bool halt); ///< stall or clear stall for an endpoint
  111. usbXfer_t *(*xfer_alloc)(udc_t *udc); ///< allocate an usb xfer
  112. void (*xfer_free)(udc_t *udc, usbXfer_t *xfer); ///< free the usb xfer
  113. // gdb mode
  114. void (*gdb_poll)(udc_t *udc); ///< poll intr in gdb mode
  115. } udcOps_t;
  116. enum udc_feature
  117. {
  118. #define UDC_FEATURE_ATTRIBUTE_MASK 0xff
  119. /// UC Attribute
  120. UDC_FEATURE_REMOTE_WAKEUP = UC_REMOTE_WAKEUP,
  121. UDC_FEATURE_SELF_POWERED = UC_SELF_POWERED,
  122. UDC_FEATURE_BUS_POWERED = UC_BUS_POWERED,
  123. /// Software defined
  124. UDC_FEATURE_WAKEUP_ON_WRITE = (1 << 8),
  125. };
  126. #ifdef CONFIG_SOC_8850
  127. typedef struct musbFifo
  128. {
  129. void *data; ///< FIFO buffer
  130. size_t size; ///< FIFO buffer size
  131. size_t rd; ///< FIFO read pointer
  132. size_t wr; ///< FIFO write pointer
  133. } musbFifo_t;
  134. typedef struct
  135. {
  136. uint32_t addr;
  137. uint16_t frag_len;
  138. uint16_t blk_len;
  139. uint32_t link_end : 1;
  140. uint32_t sp : 1;
  141. uint32_t ioc : 1;
  142. uint32_t : 5;
  143. uint32_t haddr : 4;
  144. uint32_t : 20;
  145. uint32_t : 32; // This word is needed
  146. } UdcLinkList_t;
  147. #endif
  148. struct udc_s
  149. {
  150. int speed; ///< controller speed, from controller
  151. int feature; ///< controller feature defined in udc_feature
  152. udcPlatOps_t plat_ops; ///< operates for specific platform
  153. udcOps_t ops; ///< controller operates
  154. unsigned long platform_priv; ///< platform private data
  155. unsigned long controller_priv; ///< controller private data
  156. usbEp_t *ep0; ///< ep0, from controller
  157. #ifdef CONFIG_SOC_8850
  158. bool is_configured;
  159. void *rx_dma_buf;
  160. void *tx_dma_buf;
  161. UdcLinkList_t rx_linklist[15]; ///RX_dma linklist
  162. UdcLinkList_t tx_linklist[15]; ///TX_dma linklist
  163. musbFifo_t rx_fifo;
  164. musbFifo_t tx_fifo;
  165. unsigned int node_start;
  166. #endif
  167. };
  168. typedef struct
  169. {
  170. int (*bind)(udevDrv_t *driver);
  171. void (*unbind)(udevDrv_t *driver);
  172. int (*setup)(udevDrv_t *driver, const usb_device_request_t *setup);
  173. void (*start)(udevDrv_t *driver);
  174. void (*stop)(udevDrv_t *driver);
  175. void (*connect)(udevDrv_t *driver);
  176. void (*disconnect)(udevDrv_t *driver);
  177. void (*resume)(udevDrv_t *driver);
  178. void (*suspend)(udevDrv_t *driver);
  179. } udevDrvOps_t;
  180. struct usb_dev_driver_s
  181. {
  182. udc_t *udc;
  183. udevDrvOps_t ops;
  184. };
  185. #define USB_DUMMY_RX_BUF_SIZE (512)
  186. extern char gDummyUsbRxBuf[USB_DUMMY_RX_BUF_SIZE];
  187. /**
  188. * @brief Create the usb device controller instance
  189. *
  190. * @param name the controller device name
  191. * @return
  192. * - NULL fail
  193. * - the usb device controller
  194. */
  195. udc_t *udcCreate(uint32_t name);
  196. /**
  197. * @brief Destroy the udc
  198. *
  199. * @param udc the udc
  200. */
  201. void udcDestroy(udc_t *udc);
  202. /**
  203. * @brief Bind the udc driver to the udc
  204. *
  205. * @param udc the udc
  206. * @param drv the udc driver
  207. */
  208. void udcBindDriver(udc_t *udc, udevDrv_t *drv);
  209. /**
  210. * @brief Get the binding driver
  211. *
  212. * @param udc the udc
  213. * @return
  214. * - NULL No driver bind to this udc
  215. * - other the udc driver
  216. */
  217. udevDrv_t *udcGetDriver(udc_t *udc);
  218. /**
  219. * @brief udc set event notifier
  220. *
  221. * @param udc the udc
  222. * @param n the notifier
  223. * @param param caller context
  224. */
  225. void udcSetNotifier(udc_t *udc, udcNotifier_t n, void *param);
  226. /**
  227. * @brief udc connect
  228. * @param udc the udc
  229. */
  230. void udcConnect(udc_t *udc);
  231. /**
  232. * @brief udc disconnect
  233. * @param udc the udc
  234. */
  235. void udcDisconnect(udc_t *udc);
  236. /**
  237. * @brief udc suspend
  238. * @param udc the udc
  239. */
  240. void udcSuspend(udc_t *udc);
  241. /**
  242. * @brief udc resume
  243. * @param udc the udc
  244. */
  245. void udcResume(udc_t *udc);
  246. /**
  247. * @brief udc remote wakeup
  248. * @param udc the udc
  249. */
  250. bool udcRemoteWakeup(udc_t *udc);
  251. /**
  252. * @brief usb suspend or other status
  253. *
  254. * @param udc the udc
  255. * @return
  256. * - NULL fail
  257. * - the usb device controller
  258. */
  259. bool udcUsbIsSuspend(udc_t *udc);
  260. #define CHECK_UDC_PLAT_OPS(u, o) ((u) != NULL && (u)->plat_ops.o != NULL)
  261. #define CHECK_UDC_OPS(u, o) ((u) != NULL && (u)->ops.o != NULL)
  262. #define CHECK_DRV_OPS(d, o) ((d) != NULL && (d)->ops.o != NULL)
  263. /**
  264. * @brief The platform turn on/off usb power
  265. *
  266. * @param udc the udc
  267. * @param on on or off the power
  268. */
  269. static inline void udcPlatSetPower(udc_t *udc, bool on)
  270. {
  271. if (CHECK_UDC_PLAT_OPS(udc, setpower))
  272. return udc->plat_ops.setpower(udc, on);
  273. }
  274. /**
  275. * @brief The platform turn on/off clock
  276. *
  277. * @param udc the udc
  278. * @param on on or off the clock
  279. */
  280. static inline void udcPlatSetClock(udc_t *udc, bool on)
  281. {
  282. if (CHECK_UDC_PLAT_OPS(udc, setclk))
  283. return udc->plat_ops.setclk(udc, on);
  284. }
  285. /**
  286. * @brief The platform process on usb controller suspend
  287. *
  288. * @param udc the udc
  289. */
  290. static inline void udcPlatSuspend(udc_t *udc)
  291. {
  292. if (CHECK_UDC_PLAT_OPS(udc, suspend))
  293. udc->plat_ops.suspend(udc);
  294. }
  295. /**
  296. * @brief The platform process on usb controller resume
  297. *
  298. * @param udc the udc
  299. */
  300. static inline void udcPlatResume(udc_t *udc)
  301. {
  302. if (CHECK_UDC_PLAT_OPS(udc, resume))
  303. udc->plat_ops.resume(udc);
  304. }
  305. /**
  306. * @brief The platform enable usb module
  307. *
  308. * Init usb phy and others
  309. * @param udc the udc
  310. */
  311. static inline void udcPlatEnable(udc_t *udc)
  312. {
  313. if (CHECK_UDC_PLAT_OPS(udc, enable))
  314. return udc->plat_ops.enable(udc);
  315. }
  316. /**
  317. * @brief The platform disable usb module
  318. *
  319. * @param udc the udc
  320. */
  321. static inline void udcPlatDisable(udc_t *udc)
  322. {
  323. if (CHECK_UDC_PLAT_OPS(udc, disable))
  324. return udc->plat_ops.disable(udc);
  325. }
  326. /**
  327. * @brief Start udc, make the controller works
  328. *
  329. * @param udc the udc
  330. */
  331. void udcStart(udc_t *udc);
  332. /**
  333. * @brief Stop udc, the controller will be closed
  334. *
  335. * @param udc the udc
  336. */
  337. void udcStop(udc_t *udc);
  338. /**
  339. * @brief Enqueue an usb transfer
  340. *
  341. * Before call the method, caller should be sure ep is a valid
  342. * usb endpoint, and make sure full fill the usb transfer.
  343. *
  344. * @param udc the udc
  345. * @param ep the usb endpoint
  346. * @param xfer the usb transfer
  347. * @return
  348. * - 0 success
  349. * - (-1) fail
  350. */
  351. static inline int udcEpQueue(udc_t *udc, usbEp_t *ep, usbXfer_t *xfer)
  352. {
  353. if (CHECK_UDC_OPS(udc, enqueue) && ep != NULL && xfer != NULL)
  354. return udc->ops.enqueue(udc, ep, xfer);
  355. return -1;
  356. }
  357. /**
  358. * @brief Dequeue an usb transfer
  359. *
  360. * @param udc the udc
  361. * @param ep the usb endpoint
  362. * @param xfer the usb transfer
  363. */
  364. static inline void udcEpDequeue(udc_t *udc, usbEp_t *ep, usbXfer_t *xfer)
  365. {
  366. if (CHECK_UDC_OPS(udc, dequeue) && ep != NULL && xfer != NULL)
  367. udc->ops.dequeue(udc, ep, xfer);
  368. }
  369. /**
  370. * @brief Dequeue all transfers for an usb endpoint
  371. *
  372. * @param udc the udc
  373. * @param ep the usb endpoint
  374. */
  375. static inline void udcEpDequeueAll(udc_t *udc, usbEp_t *ep)
  376. {
  377. if (CHECK_UDC_OPS(udc, dequeue_all) && ep != NULL)
  378. udc->ops.dequeue_all(udc, ep);
  379. }
  380. /**
  381. * @brief Allocate an usb endpoint
  382. *
  383. * @param udc the udc
  384. * @param desc the usb endpoint descriptor
  385. * @return
  386. * - NULL fail
  387. * - other usb endpoint
  388. */
  389. static inline usbEp_t *udcEpAlloc(udc_t *udc, usb_endpoint_descriptor_t *desc)
  390. {
  391. if (CHECK_UDC_OPS(udc, ep_alloc) && desc != NULL)
  392. return udc->ops.ep_alloc(udc, desc);
  393. return NULL;
  394. }
  395. /**
  396. * @brief Free an usb endpoint
  397. *
  398. * @param udc the udc
  399. * @param ep the usb endpoint
  400. */
  401. static inline void udcEpFree(udc_t *udc, usbEp_t *ep)
  402. {
  403. if (CHECK_UDC_OPS(udc, ep_free) && ep != NULL)
  404. return udc->ops.ep_free(udc, ep);
  405. }
  406. /**
  407. * @brief Allocate an usb xfer
  408. *
  409. * @param udc the udc
  410. * @return
  411. * - NULL fail
  412. * - other the xfer
  413. */
  414. static inline usbXfer_t *udcXferAlloc(udc_t *udc)
  415. {
  416. if (CHECK_UDC_OPS(udc, xfer_alloc))
  417. return udc->ops.xfer_alloc(udc);
  418. return NULL;
  419. }
  420. /**
  421. * @brief Free an usb xfer
  422. *
  423. * @param udc the udc
  424. * @param xfer the xfer
  425. */
  426. static inline void udcXferFree(udc_t *udc, usbXfer_t *xfer)
  427. {
  428. if (CHECK_UDC_OPS(udc, xfer_free) && xfer)
  429. return udc->ops.xfer_free(udc, xfer);
  430. }
  431. /**
  432. * @brief Enable the endpoint
  433. *
  434. * @param udc the udc
  435. * @param ep the endpoint
  436. * @return
  437. * - (-1) fail
  438. * - other success
  439. */
  440. static inline int udcEpEnable(udc_t *udc, usbEp_t *ep)
  441. {
  442. if (CHECK_UDC_OPS(udc, ep_enable) && ep != NULL)
  443. return udc->ops.ep_enable(udc, ep);
  444. return -1;
  445. }
  446. /**
  447. * @brief Disable the endpoint
  448. *
  449. * @param udc the udc
  450. * @param ep the endpoint
  451. */
  452. static inline void udcEpDisable(udc_t *udc, usbEp_t *ep)
  453. {
  454. if (CHECK_UDC_OPS(udc, ep_disable) && ep != NULL)
  455. return udc->ops.ep_disable(udc, ep);
  456. }
  457. /**
  458. * @brief Stall an endpoint
  459. *
  460. * @param udc the udc
  461. * @param ep the usb endpoint
  462. * @param halt true: stall; false: clear stall
  463. */
  464. static inline void udcEpStall(udc_t *udc, usbEp_t *ep, bool halt)
  465. {
  466. if (CHECK_UDC_OPS(udc, ep_stall) && ep != NULL)
  467. udc->ops.ep_stall(udc, ep, halt);
  468. }
  469. /**
  470. * @brief Poll usb interrupt in gdb mode
  471. *
  472. * @param udc the usb device controller
  473. */
  474. static inline void udcGdbPollIntr(udc_t *udc)
  475. {
  476. if (CHECK_UDC_OPS(udc, gdb_poll))
  477. udc->ops.gdb_poll(udc);
  478. }
  479. /**
  480. * @brief usb deivce driver process setup packet
  481. *
  482. * @param drv the driver
  483. * @param setup the setup packet
  484. * @return
  485. * - (-1) process failed
  486. * - 0 success
  487. */
  488. static inline int udevDriverSetup(udevDrv_t *drv, const usb_device_request_t *setup)
  489. {
  490. if (CHECK_DRV_OPS(drv, setup))
  491. return drv->ops.setup(drv, setup);
  492. return -1;
  493. }
  494. /**
  495. * @brief usb device driver bind the usb controller
  496. *
  497. * @param drv the driver
  498. * @return
  499. * - (-1) failed
  500. * - 0 success
  501. */
  502. static inline int udevDriverBind(udevDrv_t *drv)
  503. {
  504. if (CHECK_DRV_OPS(drv, bind))
  505. return drv->ops.bind(drv);
  506. return -1;
  507. }
  508. /**
  509. * @brief usb device driver unbind the controller
  510. *
  511. * @param drv the driver
  512. */
  513. static inline void udevDriverUnbind(udevDrv_t *drv)
  514. {
  515. if (CHECK_DRV_OPS(drv, unbind))
  516. drv->ops.unbind(drv);
  517. }
  518. /**
  519. * @brief usb device driver start.
  520. *
  521. * Prepare environment, etc.
  522. *
  523. * @param drv the driver
  524. */
  525. static inline void udevDriverStart(udevDrv_t *drv)
  526. {
  527. if (CHECK_DRV_OPS(drv, start))
  528. drv->ops.start(drv);
  529. }
  530. /**
  531. * @brief usb device driver stop.
  532. *
  533. * Release resource and etc.
  534. *
  535. * @param drv the driver
  536. */
  537. static inline void udevDriverStop(udevDrv_t *drv)
  538. {
  539. if (CHECK_DRV_OPS(drv, stop))
  540. drv->ops.stop(drv);
  541. }
  542. /**
  543. * @brief usb device connect to a host
  544. *
  545. * @param drv the driver
  546. */
  547. static inline void udevDriverConnect(udevDrv_t *drv)
  548. {
  549. if (CHECK_DRV_OPS(drv, connect))
  550. drv->ops.connect(drv);
  551. }
  552. /**
  553. * @brief usb device disconnect to a host
  554. *
  555. * @param drv the driver
  556. */
  557. static inline void udevDriverDisconnect(udevDrv_t *drv)
  558. {
  559. if (CHECK_DRV_OPS(drv, disconnect))
  560. drv->ops.disconnect(drv);
  561. }
  562. /**
  563. * @brief usb device suspend to a host
  564. *
  565. * @param drv the driver
  566. */
  567. static inline void udevDriverSuspend(udevDrv_t *drv)
  568. {
  569. if (CHECK_DRV_OPS(drv, suspend))
  570. drv->ops.suspend(drv);
  571. }
  572. /**
  573. * @brief usb device resume to a host
  574. *
  575. * @param drv the driver
  576. */
  577. static inline void udevDriverResume(udevDrv_t *drv)
  578. {
  579. if (CHECK_DRV_OPS(drv, resume))
  580. drv->ops.resume(drv);
  581. }
  582. #ifdef __cplusplus
  583. }
  584. #endif
  585. #endif