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