diff options
author | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
---|---|---|
committer | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
commit | e5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch) | |
tree | d8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/9/omap/devdss.c |
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/9/omap/devdss.c')
-rwxr-xr-x | sys/src/9/omap/devdss.c | 180 |
1 files changed, 180 insertions, 0 deletions
diff --git a/sys/src/9/omap/devdss.c b/sys/src/9/omap/devdss.c new file mode 100755 index 000000000..17ad06abd --- /dev/null +++ b/sys/src/9/omap/devdss.c @@ -0,0 +1,180 @@ +/* + * omap35 display subsystem (dss) device interface to screen.c. + * implements #v/vgactl + */ +#include "u.h" +#include "../port/lib.h" +#include "mem.h" +#include "dat.h" +#include "fns.h" +#include "io.h" +#include "ureg.h" +#include "../port/error.h" + +#define Image IMAGE +#include <draw.h> +#include <memdraw.h> +#include <cursor.h> +#include "screen.h" +// #include "gamma.h" + +enum { + Qdir, + Qdss, +}; + +extern OScreen oscreen; +extern Settings settings[]; +extern Omap3fb *framebuf; + +static QLock dsslck; +static Dirtab dsstab[] = { + ".", {Qdir, 0, QTDIR}, 0, 0555|DMDIR, + "vgactl", {Qdss, 0}, 0, 0666, +}; + +static Chan* +screenattach(char *spec) +{ + return devattach('v', spec); +} + +static Walkqid* +screenwalk(Chan *c, Chan *nc, char **name, int nname) +{ + return devwalk(c, nc, name, nname, dsstab, nelem(dsstab), devgen); +} + +static int +screenstat(Chan *c, uchar *dp, int n) +{ + return devstat(c, dp, n, dsstab, nelem(dsstab), devgen); +} + +static Chan* +screenopen(Chan *c, int omode) +{ + if ((ulong)c->qid.path == Qdss) { + qlock(&dsslck); + oscreen.open = 1; + c->mode = openmode(omode); + c->flag |= COPEN; + c->offset = 0; + } + return c; +} + +static void +screenclose(Chan *c) +{ + if ((c->qid.type & QTDIR) == 0 && c->flag & COPEN) + if (c->qid.path == Qdss) { + oscreen.open = 0; + qunlock(&dsslck); + } +} + +static ulong +getchans(char *p) +{ + if (strncmp("x24" , p, 3) == 0) + return RGB24; /* can't work yet, pixels are shorts */ + else if (strncmp("x16", p, 3) == 0) + return RGB16; + else + return RGB16; +} + +static long +settingswrite(OScreen *scr, char *p) +{ + if (strncmp("800x600", p, 7) == 0) { + p += 7; + scr->settings = &settings[Res800x600]; + } else if (strncmp("1024x768", p, 8) == 0) { + p += 8; + scr->settings = &settings[Res1024x768]; + } else if (strncmp("1280x1024", p, 9) == 0) { + p += 9; + scr->settings = &settings[Res1280x1024]; + } else + return -1; + scr->settings->chan = getchans(p); + return 1; +} + +static long +screenread(Chan *c, void *a, long n, vlong off) +{ + int len, depth; + char *p; + Settings *set; + + switch ((ulong)c->qid.path) { + case Qdir: + return devdirread(c, a, n, dsstab, nelem(dsstab), devgen); + case Qdss: + set = oscreen.settings; + p = malloc(READSTR); + if(waserror()){ + free(p); + nexterror(); + } + if (set->chan == RGB16) + depth = 16; + else if (set->chan == RGB24) + depth = 24; + else + depth = 0; + len = snprint(p, READSTR, "size %dx%dx%d @ %d Hz\n" + "addr %#p size %ud\n", set->wid, set->ht, depth, + set->freq, framebuf, sizeof *framebuf); + USED(len); + n = readstr(off, a, n, p); + poperror(); + free(p); + return n; + default: + error(Egreg); + } + return 0; +} + +static long +screenwrite(Chan *c, void *a, long n, vlong off) +{ + switch ((ulong)c->qid.path) { + case Qdss: + if(off) + error(Ebadarg); + n = settingswrite(&oscreen, a); + if (n < 0) + error(Ebadctl); + screeninit(); + return n; + default: + error(Egreg); + } + return 0; +} + +Dev dssdevtab = { + L'v', + "dss", + + devreset, + devinit, + devshutdown, // TODO add a shutdown to stop dma to monitor + screenattach, + screenwalk, + screenstat, + screenopen, + devcreate, + screenclose, + screenread, + devbread, + screenwrite, + devbwrite, + devremove, + devwstat, +}; |