xref: /inferno-os/os/cerf1110/devcerf.c (revision 74a4d8c26dd3c1e9febcb717cfd6cb6512991a7a)
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