usb2422.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402
  1. /* Copyright 2021 QMK
  2. *
  3. * This program is free software: you can redistribute it and/or modify
  4. * it under the terms of the GNU General Public License as published by
  5. * the Free Software Foundation, either version 3 of the License, or
  6. * (at your option) any later version.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU General Public License
  14. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  15. */
  16. #include <string.h>
  17. #include "usb2422.h"
  18. #include "i2c_master.h"
  19. #include "wait.h"
  20. #include "gpio.h"
  21. /* -------- USB2422_VID : (USB2422L Offset: 0x00) (R/W 16) Vendor ID -------- */
  22. typedef union {
  23. struct {
  24. uint16_t VID_LSB : 8;
  25. uint16_t VID_MSB : 8;
  26. } bit; /*!< Structure used for bit access */
  27. uint16_t reg; /*!< Type used for register access */
  28. } USB2422_VID_Type;
  29. /* -------- USB2422_PID : (USB2422L Offset: 0x02) (R/W 16) Product ID -------- */
  30. typedef union {
  31. struct {
  32. uint16_t PID_LSB : 8;
  33. uint16_t PID_MSB : 8;
  34. } bit; /*!< Structure used for bit access */
  35. uint16_t reg; /*!< Type used for register access */
  36. } USB2422_PID_Type;
  37. /* -------- USB2422_DID : (USB2422L Offset: 0x04) (R/W 16) Device ID -------- */
  38. typedef union {
  39. struct {
  40. uint16_t DID_LSB : 8;
  41. uint16_t DID_MSB : 8;
  42. } bit; /*!< Structure used for bit access */
  43. uint16_t reg; /*!< Type used for register access */
  44. } USB2422_DID_Type;
  45. /* -------- USB2422_CFG1 : (USB2422L Offset: 0x06) (R/W 8) Configuration Data Byte 1-------- */
  46. typedef union {
  47. struct {
  48. uint8_t PORT_PWR : 1;
  49. uint8_t CURRENT_SNS : 2;
  50. uint8_t EOP_DISABLE : 1;
  51. uint8_t MTT_ENABLE : 1;
  52. uint8_t HS_DISABLE : 1;
  53. uint8_t : 1;
  54. uint8_t SELF_BUS_PWR : 1;
  55. } bit; /*!< Structure used for bit access */
  56. uint8_t reg; /*!< Type used for register access */
  57. } USB2422_CFG1_Type;
  58. /* -------- USB2422_CFG2 : (USB2422L Offset: 0x07) (R/W 8) Configuration Data Byte 2-------- */
  59. typedef union {
  60. struct {
  61. uint8_t : 3;
  62. uint8_t COMPOUND : 1;
  63. uint8_t OC_TIMER : 2;
  64. uint8_t : 1;
  65. uint8_t DYNAMIC : 1;
  66. } bit; /*!< Structure used for bit access */
  67. uint8_t reg; /*!< Type used for register access */
  68. } USB2422_CFG2_Type;
  69. /* -------- USB2422_CFG3 : (USB2422L Offset: 0x08) (R/W 16) Configuration Data Byte 3-------- */
  70. typedef union {
  71. struct {
  72. uint8_t STRING_EN : 1;
  73. uint8_t : 2;
  74. uint8_t PRTMAP_EN : 1;
  75. uint8_t : 4;
  76. } bit; /*!< Structure used for bit access */
  77. uint8_t reg; /*!< Type used for register access */
  78. } USB2422_CFG3_Type;
  79. /* -------- USB2422_NRD : (USB2422L Offset: 0x09) (R/W 8) Non Removable Device -------- */
  80. typedef union {
  81. struct {
  82. uint8_t : 5;
  83. uint8_t PORT2_NR : 1;
  84. uint8_t PORT1_NR : 1;
  85. uint8_t : 1;
  86. } bit; /*!< Structure used for bit access */
  87. uint8_t reg; /*!< Type used for register access */
  88. } USB2422_NRD_Type;
  89. /* -------- USB2422_PDS : (USB2422L Offset: 0x0A) (R/W 8) Port Diable for Self-Powered Operation -------- */
  90. typedef union {
  91. struct {
  92. uint8_t : 1;
  93. uint8_t PORT1_DIS : 1;
  94. uint8_t PORT2_DIS : 1;
  95. uint8_t : 5;
  96. } bit; /*!< Structure used for bit access */
  97. uint8_t reg; /*!< Type used for register access */
  98. } USB2422_PDS_Type;
  99. /* -------- USB2422_PDB : (USB2422L Offset: 0x0B) (R/W 8) Port Diable for Bus-Powered Operation -------- */
  100. typedef union {
  101. struct {
  102. uint8_t : 1;
  103. uint8_t PORT1_DIS : 1;
  104. uint8_t PORT2_DIS : 1;
  105. uint8_t : 5;
  106. } bit; /*!< Structure used for bit access */
  107. uint8_t reg; /*!< Type used for register access */
  108. } USB2422_PDB_Type;
  109. /* -------- USB2422_MAXPS : (USB2422L Offset: 0x0C) (R/W 8) Max Power for Self-Powered Operation -------- */
  110. typedef union {
  111. struct {
  112. uint8_t MAX_PWR_SP : 8;
  113. } bit; /*!< Structure used for bit access */
  114. uint8_t reg; /*!< Type used for register access */
  115. } USB2422_MAXPS_Type;
  116. /* -------- USB2422_MAXPB : (USB2422L Offset: 0x0D) (R/W 8) Max Power for Bus-Powered Operation -------- */
  117. typedef union {
  118. struct {
  119. uint8_t MAX_PWR_BP : 8;
  120. } bit; /*!< Structure used for bit access */
  121. uint8_t reg; /*!< Type used for register access */
  122. } USB2422_MAXPB_Type;
  123. /* -------- USB2422_HCMCS : (USB2422L Offset: 0x0E) (R/W 8) Hub Controller Max Current for Self-Powered Operation -------- */
  124. typedef union {
  125. struct {
  126. uint8_t HC_MAX_C_SP : 8;
  127. } bit; /*!< Structure used for bit access */
  128. uint8_t reg; /*!< Type used for register access */
  129. } USB2422_HCMCS_Type;
  130. /* -------- USB2422_HCMCB : (USB2422L Offset: 0x0F) (R/W 8) Hub Controller Max Current for Bus-Powered Operation -------- */
  131. typedef union {
  132. struct {
  133. uint8_t HC_MAX_C_BP : 8;
  134. } bit; /*!< Structure used for bit access */
  135. uint8_t reg; /*!< Type used for register access */
  136. } USB2422_HCMCB_Type;
  137. /* -------- USB2422_PWRT : (USB2422L Offset: 0x10) (R/W 8) Power On Time -------- */
  138. typedef union {
  139. struct {
  140. uint8_t POWER_ON_TIME : 8;
  141. } bit; /*!< Structure used for bit access */
  142. uint8_t reg; /*!< Type used for register access */
  143. } USB2422_PWRT_Type;
  144. /* -------- USB2422_LANGID LSB : (USB2422L Offset: 0x11) (R/W 16) Language ID -------- */
  145. typedef union {
  146. struct {
  147. uint8_t LANGID_LSB : 8;
  148. } bit; /*!< Structure used for bit access */
  149. uint8_t reg; /*!< Type used for register access */
  150. } USB2422_LANGID_LSB_Type;
  151. /* -------- USB2422_LANGID MSB : (USB2422L Offset: 0x12) (R/W 16) Language ID -------- */
  152. typedef union {
  153. struct {
  154. uint8_t LANGID_MSB : 8;
  155. } bit; /*!< Structure used for bit access */
  156. uint8_t reg; /*!< Type used for register access */
  157. } USB2422_LANGID_MSB_Type;
  158. /* -------- USB2422_MFRSL : (USB2422L Offset: 0x13) (R/W 8) Manufacturer String Length -------- */
  159. typedef union {
  160. struct {
  161. uint8_t MFR_STR_LEN : 8;
  162. } bit; /*!< Structure used for bit access */
  163. uint8_t reg; /*!< Type used for register access */
  164. } USB2422_MFRSL_Type;
  165. /* -------- USB2422_PRDSL : (USB2422L Offset: 0x14) (R/W 8) Product String Length -------- */
  166. typedef union {
  167. struct {
  168. uint8_t PRD_STR_LEN : 8;
  169. } bit; /*!< Structure used for bit access */
  170. uint8_t reg; /*!< Type used for register access */
  171. } USB2422_PRDSL_Type;
  172. /* -------- USB2422_SERSL : (USB2422L Offset: 0x15) (R/W 8) Serial String Length -------- */
  173. typedef union {
  174. struct {
  175. uint8_t SER_STR_LEN : 8;
  176. } bit; /*!< Structure used for bit access */
  177. uint8_t reg; /*!< Type used for register access */
  178. } USB2422_SERSL_Type;
  179. /* -------- USB2422_MFRSTR : (USB2422L Offset: 0x16-53) (R/W 8) Maufacturer String -------- */
  180. typedef uint16_t USB2422_MFRSTR_Type;
  181. /* -------- USB2422_PRDSTR : (USB2422L Offset: 0x54-91) (R/W 8) Product String -------- */
  182. typedef uint16_t USB2422_PRDSTR_Type;
  183. /* -------- USB2422_SERSTR : (USB2422L Offset: 0x92-CF) (R/W 8) Serial String -------- */
  184. typedef uint16_t USB2422_SERSTR_Type;
  185. /* -------- USB2422_BCEN : (USB2422L Offset: 0xD0) (R/W 8) Battery Charging Enable -------- */
  186. typedef union {
  187. struct {
  188. uint8_t : 1;
  189. uint8_t PORT1_BCE : 1;
  190. uint8_t PORT2_BCE : 1;
  191. uint8_t : 5;
  192. } bit; /*!< Structure used for bit access */
  193. uint8_t reg; /*!< Type used for register access */
  194. } USB2422_BCEN_Type;
  195. /* -------- USB2422_BOOSTUP : (USB2422L Offset: 0xF6) (R/W 8) Boost Upstream -------- */
  196. typedef union {
  197. struct {
  198. uint8_t BOOST : 2;
  199. uint8_t : 6;
  200. } bit; /*!< Structure used for bit access */
  201. uint8_t reg; /*!< Type used for register access */
  202. } USB2422_BOOSTUP_Type;
  203. /* -------- USB2422_BOOSTDOWN : (USB2422L Offset: 0xF8) (R/W 8) Boost Downstream -------- */
  204. typedef union {
  205. struct {
  206. uint8_t BOOST1 : 2;
  207. uint8_t BOOST2 : 2;
  208. uint8_t : 4;
  209. } bit; /*!< Structure used for bit access */
  210. uint8_t reg; /*!< Type used for register access */
  211. } USB2422_BOOSTDOWN_Type;
  212. /* -------- USB2422_PRTSP : (USB2422L Offset: 0xFA) (R/W 8) Port Swap -------- */
  213. typedef union {
  214. struct {
  215. uint8_t : 1;
  216. uint8_t PORT1_SP : 1;
  217. uint8_t PORT2_SP : 1;
  218. uint8_t : 5;
  219. } bit; /*!< Structure used for bit access */
  220. uint8_t reg; /*!< Type used for register access */
  221. } USB2422_PRTSP_Type;
  222. /* -------- USB2422_PRTR12 : (USB2422L Offset: 0xFB) (R/W 8) Port 1/2 Remap -------- */
  223. typedef union {
  224. struct {
  225. uint8_t PORT1_REMAP : 4;
  226. uint8_t PORT2_REMAP : 4;
  227. } bit; /*!< Structure used for bit access */
  228. uint8_t reg; /*!< Type used for register access */
  229. } USB2422_PRTR12_Type;
  230. #define USB2422_PRTR12_DISABLE 0
  231. #define USB2422_PRT12_P2TOL1 1
  232. #define USB2422_PRT12_P2XTOL2 2
  233. #define USB2422_PRT12_P1TOL1 1
  234. #define USB2422_PRT12_P1XTOL2 2
  235. /* -------- USB2422_STCD : (USB2422L Offset: 0xFF) (R/W 8) Status Command -------- */
  236. typedef union {
  237. struct {
  238. uint8_t USB_ATTACH : 1;
  239. uint8_t RESET : 1;
  240. uint8_t INTF_PWRDN : 1;
  241. uint8_t : 5;
  242. } bit; /*!< Structure used for bit access */
  243. uint8_t reg; /*!< Type used for register access */
  244. } USB2422_STCD_Type;
  245. /** \brief USB2422 device hardware registers */
  246. typedef struct {
  247. USB2422_VID_Type VID; /**< \brief Offset: 0x00*/
  248. USB2422_PID_Type PID; /**< \brief Offset: 0x02*/
  249. USB2422_DID_Type DID; /**< \brief Offset: 0x04*/
  250. USB2422_CFG1_Type CFG1; /**< \brief Offset: 0x06*/
  251. USB2422_CFG2_Type CFG2; /**< \brief Offset: 0x07*/
  252. USB2422_CFG3_Type CFG3; /**< \brief Offset: 0x08*/
  253. USB2422_NRD_Type NRD; /**< \brief Offset: 0x09*/
  254. USB2422_PDS_Type PDS; /**< \brief Offset: 0x0A*/
  255. USB2422_PDB_Type PDB; /**< \brief Offset: 0x0B*/
  256. USB2422_MAXPS_Type MAXPS; /**< \brief Offset: 0x0C*/
  257. USB2422_MAXPB_Type MAXPB; /**< \brief Offset: 0x0D*/
  258. USB2422_HCMCS_Type HCMCS; /**< \brief Offset: 0x0E*/
  259. USB2422_HCMCB_Type HCMCB; /**< \brief Offset: 0x0F*/
  260. USB2422_PWRT_Type PWRT; /**< \brief Offset: 0x10*/
  261. USB2422_LANGID_LSB_Type LANGID_LSB; /**< \brief Offset: 0x11*/
  262. USB2422_LANGID_MSB_Type LANGID_MSB; /**< \brief Offset: 0x12*/
  263. USB2422_MFRSL_Type MFRSL; /**< \brief Offset: 0x13*/
  264. USB2422_PRDSL_Type PRDSL; /**< \brief Offset: 0x14*/
  265. USB2422_SERSL_Type SERSL; /**< \brief Offset: 0x15*/
  266. USB2422_MFRSTR_Type MFRSTR[31]; /**< \brief Offset: 0x16*/
  267. USB2422_PRDSTR_Type PRDSTR[31]; /**< \brief Offset: 0x54*/
  268. USB2422_SERSTR_Type SERSTR[31]; /**< \brief Offset: 0x92*/
  269. USB2422_BCEN_Type BCEN; /**< \brief Offset: 0xD0*/
  270. uint8_t Reserved1[0x25];
  271. USB2422_BOOSTUP_Type BOOSTUP; /**< \brief Offset: 0xF6*/
  272. uint8_t Reserved2[0x1];
  273. USB2422_BOOSTDOWN_Type BOOSTDOWN; /**< \brief Offset: 0xF8*/
  274. uint8_t Reserved3[0x1];
  275. USB2422_PRTSP_Type PRTSP; /**< \brief Offset: 0xFA*/
  276. USB2422_PRTR12_Type PRTR12; /**< \brief Offset: 0xFB*/
  277. uint8_t Reserved4[0x3];
  278. USB2422_STCD_Type STCD; /**< \brief Offset: 0xFF*/
  279. } Usb2422_t;
  280. // ***************************************************************
  281. static Usb2422_t config;
  282. // ***************************************************************
  283. /** \brief Handle the conversion to allow simple strings
  284. */
  285. static void USB2422_strcpy(const char* str, USB2422_MFRSTR_Type* dest, uint8_t len) {
  286. for (uint8_t i = 0; i < len; i++) {
  287. dest[i] = str[i];
  288. }
  289. }
  290. /** \brief Handle the conversion to allow simple strings
  291. */
  292. static void USB2422_write_block(void) {
  293. static unsigned char i2c0_buf[34];
  294. unsigned char* dest = i2c0_buf;
  295. unsigned char* src;
  296. unsigned char* base = (unsigned char*)&config;
  297. for (src = base; src < base + 256; src += 32) {
  298. dest[0] = src - base;
  299. dest[1] = 32;
  300. memcpy(&dest[2], src, 32);
  301. i2c_transmit(USB2422_ADDRESS, dest, 34, 50000);
  302. wait_us(100);
  303. }
  304. }
  305. // ***************************************************************
  306. void USB2422_init() {
  307. #ifdef USB2422_RESET_PIN
  308. setPinOutput(USB2422_RESET_PIN);
  309. #endif
  310. #ifdef USB2422_ACTIVE_PIN
  311. setPinInput(USB2422_ACTIVE_PIN);
  312. #endif
  313. i2c_init(); // IC2 clk must be high at USB2422 reset release time to signal SMB configuration
  314. }
  315. void USB2422_configure() {
  316. static const char SERNAME[] = "Unavailable";
  317. memset(&config, 0, sizeof(Usb2422_t));
  318. // configure Usb2422 registers
  319. config.VID.reg = USB2422_VENDOR_ID;
  320. config.PID.reg = USB2422_PRODUCT_ID;
  321. config.DID.reg = USB2422_DEVICE_VER; // BCD format, eg 01.01
  322. config.CFG1.bit.SELF_BUS_PWR = 1; // self powered for now
  323. config.CFG1.bit.HS_DISABLE = 1; // full or high speed
  324. // config.CFG2.bit.COMPOUND = 0; // compound device
  325. config.CFG3.bit.STRING_EN = 1; // strings enabled
  326. // config.NRD.bit.PORT2_NR = 0; // MCU is non-removable
  327. config.MAXPB.reg = 20; // 0mA
  328. config.HCMCB.reg = 20; // 0mA
  329. config.MFRSL.reg = sizeof(USB2422_MANUFACTURER);
  330. config.PRDSL.reg = sizeof(USB2422_PRODUCT);
  331. config.SERSL.reg = sizeof(SERNAME);
  332. USB2422_strcpy(USB2422_MANUFACTURER, config.MFRSTR, sizeof(USB2422_MANUFACTURER));
  333. USB2422_strcpy(USB2422_PRODUCT, config.PRDSTR, sizeof(USB2422_PRODUCT));
  334. USB2422_strcpy(SERNAME, config.SERSTR, sizeof(SERNAME));
  335. // config.BOOSTUP.bit.BOOST=3; //upstream port
  336. // config.BOOSTDOWN.bit.BOOST1=0; // extra port
  337. // config.BOOSTDOWN.bit.BOOST2=2; //MCU is close
  338. config.STCD.bit.USB_ATTACH = 1;
  339. USB2422_write_block();
  340. }
  341. void USB2422_reset() {
  342. #ifdef USB2422_RESET_PIN
  343. writePinLow(USB2422_RESET_PIN);
  344. wait_us(2);
  345. writePinHigh(USB2422_RESET_PIN);
  346. #endif
  347. }
  348. bool USB2422_active() {
  349. #ifdef USB2422_ACTIVE_PIN
  350. return readPin(USB2422_ACTIVE_PIN);
  351. #else
  352. return 1;
  353. #endif
  354. }