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