1 #include "u.h"
2 #include "../port/lib.h"
3 #include "mem.h"
4 #include "dat.h"
5 #include "fns.h"
6 #include "../port/error.h"
7
8 #include "io.h"
9
10
11 enum{
12 Qdir,
13 Qled,
14 };
15
16 static
17 Dirtab cerftab[]={
18 ".", {Qdir, 0, QTDIR}, 0, 0555,
19 "cerfled", {Qled, 0}, 0, 0660,
20 };
21
22 static void
cerfinit(void)23 cerfinit(void) /* default in dev.c */
24 {
25 int s;
26
27 s = splhi();
28 GPIOREG->gpdr |= 0xF;
29 GPIOREG->gpsr = 1<<0; /* we're here */
30 splx(s);
31 }
32
33 static Chan*
cerfattach(char * spec)34 cerfattach(char* spec)
35 {
36 return devattach('T', spec);
37 }
38
39 static Walkqid*
cerfwalk(Chan * c,Chan * nc,char ** name,int nname)40 cerfwalk(Chan *c, Chan *nc, char **name, int nname)
41 {
42 return devwalk(c, nc, name, nname, cerftab, nelem(cerftab), devgen);
43 }
44
45 static int
cerfstat(Chan * c,uchar * db,int n)46 cerfstat(Chan* c, uchar *db, int n)
47 {
48 return devstat(c, db, n, cerftab, nelem(cerftab), devgen);
49 }
50
51 static Chan*
cerfopen(Chan * c,int omode)52 cerfopen(Chan* c, int omode)
53 {
54 return devopen(c, omode, cerftab, nelem(cerftab), devgen);
55 }
56
57 static void
cerfclose(Chan * c)58 cerfclose(Chan* c)
59 {
60 USED(c);
61 }
62
63 static long
cerfread(Chan * c,void * a,long n,vlong offset)64 cerfread(Chan* c, void* a, long n, vlong offset)
65 {
66 char buf[16];
67
68 switch((ulong)c->qid.path){
69 case Qdir:
70 return devdirread(c, a, n, cerftab, nelem(cerftab), devgen);
71 case Qled:
72 snprint(buf, sizeof(buf), "%2.2lux", GPIOREG->gplr&0xF);
73 return readstr(offset, a, n, buf);
74 default:
75 n=0;
76 break;
77 }
78 return n;
79 }
80
81 static long
cerfwrite(Chan * c,void * a,long n,vlong)82 cerfwrite(Chan* c, void* a, long n, vlong)
83 {
84 char buf[16];
85 ulong v;
86
87 switch((ulong)c->qid.path){
88 case Qled:
89 if(n >= sizeof(buf))
90 n = sizeof(buf)-1;
91 memmove(buf, a, n);
92 buf[n] = 0;
93 v = GPIOREG->gplr & 0xF;
94 if(buf[0] == '+')
95 v |= strtoul(buf+1, nil, 0);
96 else if(buf[0] == '-')
97 v &= ~strtoul(buf+1, nil, 0);
98 else
99 v = strtoul(buf, nil, 0);
100 GPIOREG->gpsr = v & 0xF;
101 GPIOREG->gpcr = ~v & 0xF;
102 break;
103 default:
104 error(Ebadusefd);
105 }
106 return n;
107 }
108
109 Dev cerfdevtab = {
110 'T',
111 "cerf",
112
113 devreset,
114 cerfinit,
115 devshutdown,
116 cerfattach,
117 cerfwalk,
118 cerfstat,
119 cerfopen,
120 devcreate,
121 cerfclose,
122 cerfread,
123 devbread,
124 cerfwrite,
125 devbwrite,
126 devremove,
127 devwstat,
128 };
129