]> git.lizzy.rs Git - plan9front.git/blob - sys/src/9/omap/devdss.c
kernel: make addbroken() static, remove misleading Proc* argument
[plan9front.git] / sys / src / 9 / omap / devdss.c
1 /*
2  * omap35 display subsystem (dss) device interface to screen.c.
3  * implements #v/vgactl
4  */
5 #include "u.h"
6 #include "../port/lib.h"
7 #include "mem.h"
8 #include "dat.h"
9 #include "fns.h"
10 #include "io.h"
11 #include "ureg.h"
12 #include "../port/error.h"
13
14 #define Image   IMAGE
15 #include <draw.h>
16 #include <memdraw.h>
17 #include <cursor.h>
18 #include "screen.h"
19 // #include "gamma.h"
20
21 enum {
22         Qdir,
23         Qdss,
24 };
25
26 extern OScreen oscreen;
27 extern Settings settings[];
28 extern Omap3fb *framebuf;
29
30 static QLock dsslck;
31 static Dirtab dsstab[] = {
32         ".",            {Qdir, 0, QTDIR},       0,      0555|DMDIR,
33         "vgactl",       {Qdss, 0},              0,      0666,
34 };
35
36 static Chan*
37 screenattach(char *spec)
38 {
39         return devattach('v', spec);
40 }
41
42 static Walkqid*
43 screenwalk(Chan *c, Chan *nc, char **name, int nname)
44 {
45         return devwalk(c, nc, name, nname, dsstab, nelem(dsstab), devgen);
46 }
47
48 static int
49 screenstat(Chan *c, uchar *dp, int n)
50 {
51         return devstat(c, dp, n, dsstab, nelem(dsstab), devgen);
52 }
53
54 static Chan*
55 screenopen(Chan *c, int omode)
56 {
57         if ((ulong)c->qid.path == Qdss) {
58                 qlock(&dsslck);
59                 oscreen.open = 1;
60                 c->mode = openmode(omode);
61                 c->flag |= COPEN;
62                 c->offset = 0;
63         }
64         return c;
65 }
66
67 static void
68 screenclose(Chan *c)
69 {
70         if ((c->qid.type & QTDIR) == 0 && c->flag & COPEN)
71                 if (c->qid.path == Qdss) {
72                         oscreen.open = 0;
73                         qunlock(&dsslck);
74                 }
75 }
76
77 static ulong
78 getchans(char *p)
79 {
80         if (strncmp("x24" , p, 3) == 0)
81                 return RGB24;           /* can't work yet, pixels are shorts */
82         else if (strncmp("x16", p, 3) == 0)
83                 return RGB16;
84         else
85                 return RGB16;
86 }
87
88 static long
89 settingswrite(OScreen *scr, char *p)
90 {
91         if (strncmp("800x600", p, 7) == 0) {
92                 p += 7;
93                 scr->settings = &settings[Res800x600];
94         } else if (strncmp("1024x768", p, 8) == 0) {
95                 p += 8;
96                 scr->settings = &settings[Res1024x768];
97         } else if (strncmp("1280x1024", p, 9) == 0) {
98                 p += 9;
99                 scr->settings = &settings[Res1280x1024];
100         } else
101                 return -1;
102         scr->settings->chan = getchans(p);
103         return 1;
104 }
105
106 static long
107 screenread(Chan *c, void *a, long n, vlong off)
108 {
109         int len, depth;
110         char *p;
111         Settings *set;
112
113         switch ((ulong)c->qid.path) {
114         case Qdir:
115                 return devdirread(c, a, n, dsstab, nelem(dsstab), devgen);
116         case Qdss:
117                 set = oscreen.settings;
118                 p = malloc(READSTR);
119                 if(waserror()){
120                         free(p);
121                         nexterror();
122                 }
123                 if (set->chan == RGB16)
124                         depth = 16;
125                 else if (set->chan == RGB24)
126                         depth = 24;
127                 else
128                         depth = 0;
129                 len = snprint(p, READSTR, "size %dx%dx%d @ %d Hz\n"
130                         "addr %#p size %ud\n", set->wid, set->ht, depth,
131                         set->freq, framebuf, sizeof *framebuf);
132                 USED(len);
133                 n = readstr(off, a, n, p);
134                 poperror();
135                 free(p);
136                 return n;
137         default:
138                 error(Egreg);
139         }
140         return 0;
141 }
142
143 static long
144 screenwrite(Chan *c, void *a, long n, vlong off)
145 {
146         switch ((ulong)c->qid.path) {
147         case Qdss:
148                 if(off)
149                         error(Ebadarg);
150                 n = settingswrite(&oscreen, a);
151                 if (n < 0)
152                         error(Ebadctl);
153                 screeninit();
154                 return n;
155         default:
156                 error(Egreg);
157         }
158         return 0;
159 }
160
161 Dev dssdevtab = {
162         L'v',
163         "dss",
164
165         devreset,
166         devinit,
167         devshutdown,            // TODO add a shutdown to stop dma to monitor
168         screenattach,
169         screenwalk,
170         screenstat,
171         screenopen,
172         devcreate,
173         screenclose,
174         screenread,
175         devbread,
176         screenwrite,
177         devbwrite,
178         devremove,
179         devwstat,
180 };