diff options
| author | Charles.Forsyth <devnull@localhost> | 2006-12-22 21:39:35 +0000 |
|---|---|---|
| committer | Charles.Forsyth <devnull@localhost> | 2006-12-22 21:39:35 +0000 |
| commit | 74a4d8c26dd3c1e9febcb717cfd6cb6512991a7a (patch) | |
| tree | c6e220ba61db3a6ea4052e6841296d829654e664 /os/cerf1110/devcerf.c | |
| parent | 46439007cf417cbd9ac8049bb4122c890097a0fa (diff) | |
20060303
Diffstat (limited to 'os/cerf1110/devcerf.c')
| -rw-r--r-- | os/cerf1110/devcerf.c | 128 |
1 files changed, 128 insertions, 0 deletions
diff --git a/os/cerf1110/devcerf.c b/os/cerf1110/devcerf.c new file mode 100644 index 00000000..3c0fc999 --- /dev/null +++ b/os/cerf1110/devcerf.c @@ -0,0 +1,128 @@ +#include "u.h" +#include "../port/lib.h" +#include "mem.h" +#include "dat.h" +#include "fns.h" +#include "../port/error.h" + +#include "io.h" + + +enum{ + Qdir, + Qled, +}; + +static +Dirtab cerftab[]={ + ".", {Qdir, 0, QTDIR}, 0, 0555, + "cerfled", {Qled, 0}, 0, 0660, +}; + +static void +cerfinit(void) /* default in dev.c */ +{ + int s; + + s = splhi(); + GPIOREG->gpdr |= 0xF; + GPIOREG->gpsr = 1<<0; /* we're here */ + splx(s); +} + +static Chan* +cerfattach(char* spec) +{ + return devattach('T', spec); +} + +static Walkqid* +cerfwalk(Chan *c, Chan *nc, char **name, int nname) +{ + return devwalk(c, nc, name, nname, cerftab, nelem(cerftab), devgen); +} + +static int +cerfstat(Chan* c, uchar *db, int n) +{ + return devstat(c, db, n, cerftab, nelem(cerftab), devgen); +} + +static Chan* +cerfopen(Chan* c, int omode) +{ + return devopen(c, omode, cerftab, nelem(cerftab), devgen); +} + +static void +cerfclose(Chan* c) +{ + USED(c); +} + +static long +cerfread(Chan* c, void* a, long n, vlong offset) +{ + char buf[16]; + + switch((ulong)c->qid.path){ + case Qdir: + return devdirread(c, a, n, cerftab, nelem(cerftab), devgen); + case Qled: + snprint(buf, sizeof(buf), "%2.2lux", GPIOREG->gplr&0xF); + return readstr(offset, a, n, buf); + default: + n=0; + break; + } + return n; +} + +static long +cerfwrite(Chan* c, void* a, long n, vlong) +{ + char buf[16]; + ulong v; + + switch((ulong)c->qid.path){ + case Qled: + if(n >= sizeof(buf)) + n = sizeof(buf)-1; + memmove(buf, a, n); + buf[n] = 0; + v = GPIOREG->gplr & 0xF; + if(buf[0] == '+') + v |= strtoul(buf+1, nil, 0); + else if(buf[0] == '-') + v &= ~strtoul(buf+1, nil, 0); + else + v = strtoul(buf, nil, 0); + GPIOREG->gpsr = v & 0xF; + GPIOREG->gpcr = ~v & 0xF; + break; + default: + error(Ebadusefd); + } + return n; +} + +Dev cerfdevtab = { + 'T', + "cerf", + + devreset, + cerfinit, + devshutdown, + cerfattach, + cerfwalk, + cerfstat, + cerfopen, + devcreate, + cerfclose, + cerfread, + devbread, + cerfwrite, + devbwrite, + devremove, + devwstat, +}; |
