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