silabs.c 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. #include <u.h>
  2. #include <libc.h>
  3. #include <thread.h>
  4. #include "usb.h"
  5. #include "usbfs.h"
  6. #include "serial.h"
  7. #include "silabs.h"
  8. static Cinfo slinfo[] = {
  9. { 0x10c4, 0xea60, }, /* CP210x */
  10. { 0x10c4, 0xea61, }, /* CP210x */
  11. { 0, 0, },
  12. };
  13. enum {
  14. Enable = 0x00,
  15. Getbaud = 0x1D,
  16. Setbaud = 0x1E,
  17. Setlcr = 0x03,
  18. Getlcr = 0x04,
  19. Bitsmask = 0x0F00,
  20. Bitsshift = 8,
  21. Parmask = 0x00F0,
  22. Parshift = 4,
  23. Stopmask = 0x000F,
  24. Stop1 = 0x0000,
  25. Stop1_5 = 0x0001,
  26. Stop2 = 0x0002,
  27. };
  28. slmatch(char *info)
  29. {
  30. Cinfo *ip;
  31. char buf[50];
  32. for(ip = slinfo; ip->vid != 0; ip++){
  33. snprint(buf, sizeof buf, "vid %#06x did %#06x",
  34. ip->vid, ip->did);
  35. if(strstr(info, buf) != nil)
  36. return 0;
  37. }
  38. return -1;
  39. }
  40. static int
  41. slwrite(Serialport *p, int req, void *buf, int len)
  42. {
  43. Serial *ser;
  44. ser = p->s;
  45. return usbcmd(ser->dev, Rh2d | Rvendor | Riface, req, 0, p->interfc,
  46. buf, len);
  47. }
  48. static int
  49. slput(Serialport *p, uint op, uint val)
  50. {
  51. Serial *ser;
  52. ser = p->s;
  53. return usbcmd(ser->dev, Rh2d | Rvendor | Riface, op, val, p->interfc,
  54. nil, 0);
  55. }
  56. static int
  57. slread(Serialport *p, int req, void *buf, int len)
  58. {
  59. Serial *ser;
  60. ser = p->s;
  61. return usbcmd(ser->dev, Rd2h | Rvendor | Riface, req, 0, p->interfc,
  62. buf, len);
  63. }
  64. static int
  65. slinit(Serialport *p)
  66. {
  67. Serial *ser;
  68. ser = p->s;
  69. dsprint(2, "slinit\n");
  70. slput(p, Enable, 1);
  71. slops.getparam(p);
  72. /* p gets freed by closedev, the process has a reference */
  73. incref(ser->dev);
  74. return 0;
  75. }
  76. static int
  77. slgetparam(Serialport *p)
  78. {
  79. u16int lcr;
  80. slread(p, Getbaud, &p->baud, sizeof(p->baud));
  81. slread(p, Getlcr, &lcr, sizeof(lcr));
  82. p->bits = (lcr&Bitsmask)>>Bitsshift;
  83. p->parity = (lcr&Parmask)>>Parshift;
  84. p->stop = (lcr&Stopmask) == Stop1? 1 : 2;
  85. return 0;
  86. }
  87. static int
  88. slsetparam(Serialport *p)
  89. {
  90. u16int lcr;
  91. lcr = p->stop == 1? Stop1 : Stop2;
  92. lcr |= (p->bits<<Bitsshift) | (p->parity<<Parshift);
  93. slput(p, Setlcr, lcr);
  94. slwrite(p, Setbaud, &p->baud, sizeof(p->baud));
  95. return 0;
  96. }
  97. static int
  98. seteps(Serialport *p)
  99. {
  100. if(devctl(p->epin, "timeout 0") < 0){
  101. fprint(2, "can't set timeout on %s: %r\n", p->epin->dir);
  102. return -1;
  103. }
  104. return 0;
  105. }
  106. static int
  107. wait4data(Serialport *p, uchar *data, int count)
  108. {
  109. int n;
  110. qunlock(p->s);
  111. while ((n = read(p->epin->dfd, data, count)) == 0)
  112. ;
  113. qlock(p->s);
  114. return n;
  115. }
  116. Serialops slops = {
  117. .init = slinit,
  118. .getparam = slgetparam,
  119. .setparam = slsetparam,
  120. .seteps = seteps,
  121. .wait4data = wait4data,
  122. };