xref: /plan9/sys/src/9/omap/devdss.c (revision 5efba40621eb0e8502497b8c98fd368f3bc4d354)
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*
screenattach(char * spec)37 screenattach(char *spec)
38 {
39 	return devattach('v', spec);
40 }
41 
42 static Walkqid*
screenwalk(Chan * c,Chan * nc,char ** name,int nname)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
screenstat(Chan * c,uchar * dp,int n)49 screenstat(Chan *c, uchar *dp, int n)
50 {
51 	return devstat(c, dp, n, dsstab, nelem(dsstab), devgen);
52 }
53 
54 static Chan*
screenopen(Chan * c,int omode)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
screenclose(Chan * c)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
getchans(char * p)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
settingswrite(OScreen * scr,char * p)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
screenread(Chan * c,void * a,long n,vlong off)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
screenwrite(Chan * c,void * a,long n,vlong off)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 };
181