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 }; 181