Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 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
};