ite8181.c revision 1.3 1 /* $NetBSD: ite8181.c,v 1.3 2000/10/27 08:09:15 sato Exp $ */
2
3 /*-
4 * Copyright (c) 2000 SATO Kazumi
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 *
28 */
29
30 #include <sys/param.h>
31 #include <sys/kernel.h>
32 #include <sys/device.h>
33 #include <sys/systm.h>
34 #include <sys/boot_flag.h>
35 #include <sys/buf.h>
36
37 #include <uvm/uvm_extern.h>
38
39 #include <dev/wscons/wsconsio.h>
40
41 #include <machine/bootinfo.h>
42 #include <machine/bus.h>
43 #include <machine/autoconf.h>
44 #include <machine/config_hook.h>
45 #include <machine/platid.h>
46 #include <machine/platid_mask.h>
47
48 #include <hpcmips/dev/ite8181reg.h>
49 #include <hpcmips/dev/ite8181var.h>
50 #include "bivideo.h"
51 #if NBIVIDEO > 0
52 #include <hpcmips/dev/bivideovar.h>
53 #endif
54 #include <hpcmips/dev/hpccmapvar.h>
55
56
57 #define ITE8181DEBUG
58 #ifdef ITE8181DEBUG
59 #ifndef ITE8181DEBUG_CONF
60 #define ITE8181DEBUG_CONF 0
61 #endif
62 int ite8181_debug = ITE8181DEBUG_CONF;
63 #define DPRINTF(arg) if (ite8181_debug) printf arg
64 #define DPRINTFN(n, arg) if (ite8181_debug > (n)) printf arg
65 #define VPRINTF(arg) if (bootverbose || ite8181_debug) printf arg
66 #define VPRINTFN(n, arg) if (bootverbose || ite8181_debug > (n)) printf arg
67 #else
68 #define DPRINTF(arg)
69 #define DPRINTFN(n, arg)
70 #define VPRINTF(arg) if (bootverbose) printf arg
71 #define VPRINTFN(n, arg) if (bootverbose) printf arg
72 #endif
73
74 #ifndef ITE8181_LCD_CONTROL_ENABLE
75 int ite8181_lcd_control_disable = 1;
76 #else /* ITE8181_LCD_CONTROL_ENABLE */
77 int ite8181_lcd_control_disable = 0;
78 #endif /* ITE8181_LCD_CONTROL_ENABLE */
79
80 #define ITE8181_WINCE_CMAP
81
82 /*
83 * XXX:
84 * IBM WorkPad z50 power unit has too weak power.
85 * So we must wait too many times to access some device
86 * after LCD panel and BackLight on.
87 * Currently delay is not enough ??? FIXME
88 */
89 #ifndef ITE8181_LCD_ON_SELF_DELAY
90 #define ITE8181_LCD_ON_SELF_DELAY 1000
91 #endif /* ITE8181_LCD_ON__SELF_DELAY */
92 #ifndef ITE8181_LCD_ON_DELAY
93 #define ITE8181_LCD_ON_DELAY 2000
94 #endif /* ITE8181_LCD_ON_DELAY */
95 int ite8181_lcd_on_self_delay = ITE8181_LCD_ON_SELF_DELAY; /* msec */
96 int ite8181_lcd_on_delay = ITE8181_LCD_ON_DELAY; /* msec */
97
98 #define MSEC 1000
99 /*
100 * function prototypes
101 */
102 static void ite8181_config_write_4 __P((bus_space_tag_t, bus_space_handle_t, int, int));
103 static int ite8181_config_read_4 __P((bus_space_tag_t, bus_space_handle_t, int));
104
105 static void ite8181_gui_write_4 __P((struct ite8181_softc *, int, int));
106 static int ite8181_gui_read_4 __P((struct ite8181_softc *, int));
107
108 static void ite8181_gui_write_1 __P((struct ite8181_softc *, int, int));
109 static int ite8181_gui_read_1 __P((struct ite8181_softc *, int));
110
111 static void ite8181_graphics_write_1 __P((struct ite8181_softc *, int, int));
112 static int ite8181_graphics_read_1 __P((struct ite8181_softc *, int));
113
114 static void ite8181_ema_write_1 __P((struct ite8181_softc *, int, int));
115 static int ite8181_ema_read_1 __P((struct ite8181_softc *, int));
116
117 static void ite8181_power __P((int, void *));
118 static int ite8181_hardpower __P((void *, int, long, void *));
119 static int ite8181_fbinit __P((struct hpcfb_fbconf *));
120 static int ite8181_ioctl __P((void *, u_long, caddr_t, int, struct proc *));
121 static paddr_t ite8181_mmap __P((void *, off_t offset, int));
122 static void ite8181_erase_cursor __P((struct ite8181_softc *));
123 static int ite8181_lcd_power __P((struct ite8181_softc *, int));
124 /*
125 * static variables
126 */
127 struct hpcfb_accessops ite8181_ha = {
128 ite8181_ioctl, ite8181_mmap
129 };
130
131 inline int
132 ite8181_config_read_4(iot, ioh, byteoffset)
133 bus_space_tag_t iot;
134 bus_space_handle_t ioh;
135 int byteoffset;
136 {
137 return bus_space_read_4(iot, ioh, ITE8181_CONF_OFFSET + byteoffset);
138 }
139
140 inline void
141 ite8181_config_write_4(iot, ioh, byteoffset, data)
142 bus_space_tag_t iot;
143 bus_space_handle_t ioh;
144 int byteoffset;
145 int data;
146 {
147 bus_space_write_4(iot, ioh, ITE8181_CONF_OFFSET + byteoffset, data);
148 }
149
150 inline int
151 ite8181_gui_read_4(sc, byteoffset)
152 struct ite8181_softc *sc;
153 int byteoffset;
154 {
155 return bus_space_read_4(sc->sc_iot, sc->sc_ioh,
156 sc->sc_gba + byteoffset);
157 }
158
159 inline void
160 ite8181_gui_write_4(sc, byteoffset, data)
161 struct ite8181_softc *sc;
162 int byteoffset;
163 int data;
164 {
165 bus_space_write_4(sc->sc_iot, sc->sc_ioh, sc->sc_gba + byteoffset, data);
166 }
167
168 inline int
169 ite8181_gui_read_1(sc, byteoffset)
170 struct ite8181_softc *sc;
171 int byteoffset;
172 {
173 return bus_space_read_1(sc->sc_iot, sc->sc_ioh,
174 sc->sc_gba + byteoffset);
175 }
176
177 inline void
178 ite8181_gui_write_1(sc, byteoffset, data)
179 struct ite8181_softc *sc;
180 int byteoffset;
181 int data;
182 {
183 bus_space_write_1(sc->sc_iot, sc->sc_ioh, sc->sc_gba + byteoffset, data);
184 }
185
186 inline int
187 ite8181_graphics_read_1(sc, byteoffset)
188 struct ite8181_softc *sc;
189 int byteoffset;
190 {
191 return bus_space_read_1(sc->sc_iot, sc->sc_ioh,
192 sc->sc_sba + byteoffset);
193 }
194
195 inline void
196 ite8181_graphics_write_1(sc, byteoffset, data)
197 struct ite8181_softc *sc;
198 int byteoffset;
199 int data;
200 {
201 bus_space_write_1(sc->sc_iot, sc->sc_ioh, sc->sc_sba + byteoffset, data);
202 }
203
204 inline int
205 ite8181_ema_read_1(sc, byteoffset)
206 struct ite8181_softc *sc;
207 int byteoffset;
208 {
209 ite8181_graphics_write_1(sc, ITE8181_EMA_EXAX, byteoffset);
210 return ite8181_graphics_read_1(sc, ITE8181_EMA_EXADATA);
211 }
212
213 inline void
214 ite8181_ema_write_1(sc, byteoffset, data)
215 struct ite8181_softc *sc;
216 int byteoffset;
217 int data;
218 {
219 ite8181_graphics_write_1(sc, ITE8181_EMA_EXAX, byteoffset);
220 ite8181_graphics_write_1(sc, ITE8181_EMA_EXADATA, data);
221 }
222
223 int
224 ite8181_probe(iot, ioh)
225 bus_space_tag_t iot;
226 bus_space_handle_t ioh;
227 {
228 unsigned long regval;
229
230 #if NBIVIDEO > 0
231 if (bivideo_dont_attach) /* some video driver already attached */
232 return (0);
233 #endif /* NBIVIDEO > 0 */
234
235 regval = ite8181_config_read_4(iot, ioh, ITE8181_ID);
236 VPRINTF(("ite8181_probe: vendor id=%04lx product id=%04lx\n",
237 regval & 0xffff, (regval >> 16) & 0xffff));
238 if (regval != ((ITE8181_PRODUCT_ID << 16) | ITE8181_VENDER_ID))
239 return (0);
240
241 return (1);
242 }
243
244 void
245 ite8181_attach(sc)
246 struct ite8181_softc *sc;
247 {
248 unsigned long regval;
249 struct hpcfb_attach_args ha;
250 int console = (bootinfo->bi_cnuse & BI_CNUSE_SERIAL) ? 0 : 1;
251
252 regval = ite8181_config_read_4(sc->sc_iot, sc->sc_ioh, ITE8181_CLASS);
253 printf(": ITE8181 Rev.%02lx\n", regval & ITE8181_REV_MASK);
254
255 /* set base offsets */
256 sc->sc_mba = ite8181_config_read_4(sc->sc_iot, sc->sc_ioh, ITE8181_MBA);
257 DPRINTFN(1, ("ite8181: Memory base offset %08x\n", sc->sc_mba));
258 sc->sc_gba = ite8181_config_read_4(sc->sc_iot, sc->sc_ioh, ITE8181_GBA);
259 DPRINTFN(1, ("ite8181: GUI base offset %08x\n", sc->sc_gba));
260 sc->sc_sba = ite8181_config_read_4(sc->sc_iot, sc->sc_ioh, ITE8181_SBA);
261 DPRINTFN(1, ("ite8181: Graphics base offset %08x\n", sc->sc_sba));
262
263 /* assume lcd is on */
264 sc->sc_lcd = 1;
265
266 /* Add a power hook to power saving */
267 sc->sc_powerstate = ITE8181_POWERSTATE_D0;
268 sc->sc_powerhook = powerhook_establish(ite8181_power, sc);
269 if (sc->sc_powerhook == NULL)
270 printf("%s: WARNING: unable to establish power hook\n",
271 sc->sc_dev.dv_xname);
272
273 /* Add a hard power hook to power saving */
274 sc->sc_hardpowerhook = config_hook(CONFIG_HOOK_PMEVENT,
275 CONFIG_HOOK_PMEVENT_HARDPOWER,
276 CONFIG_HOOK_SHARE,
277 ite8181_hardpower, sc);
278 if (sc->sc_hardpowerhook == NULL)
279 printf("%s: WARNING: unable to establish hard power hook\n",
280 sc->sc_dev.dv_xname);
281
282 ite8181_fbinit(&sc->sc_fbconf);
283
284 ite8181_erase_cursor(sc);
285
286 if (console && hpcfb_cnattach(&sc->sc_fbconf) != 0) {
287 panic("ite8181_attach: can't init fb console");
288 }
289
290 ha.ha_console = console;
291 ha.ha_accessops = &ite8181_ha;
292 ha.ha_accessctx = sc;
293 ha.ha_curfbconf = 0;
294 ha.ha_nfbconf = 1;
295 ha.ha_fbconflist = &sc->sc_fbconf;
296 ha.ha_curdspconf = 0;
297 ha.ha_ndspconf = 1;
298 ha.ha_dspconflist = &sc->sc_dspconf;
299
300 config_found(&sc->sc_dev, &ha, hpcfbprint);
301
302 #if NBIVIDEO > 0
303 /*
304 * bivideo is no longer need
305 */
306 bivideo_dont_attach = 1;
307 #endif /* NBIVIDEO > 0 */
308 }
309
310 int ite8181_lcd_power(sc, on)
311 struct ite8181_softc *sc;
312 int on;
313 {
314 int lcd_p;
315 int lcd_s;
316 int lcd_seq;
317 int loop = 10;
318
319 if (ite8181_lcd_control_disable) {
320 VPRINTF(("ite8171_lcd_control_disable!: %s\n", on?"on":"off"));
321 return 0;
322 }
323
324 if (sc->sc_lcd != on) {
325 ite8181_ema_write_1(sc, ITE8181_EMA_ENABLEEMA,
326 ITE8181_EMA_ENABLEPASS);
327 lcd_p = ite8181_ema_read_1(sc, ITE8181_EMA_LCDPOWER);
328 lcd_s = ite8181_ema_read_1(sc, ITE8181_EMA_LCDPOWERSTAT);
329 lcd_seq = ite8181_ema_read_1(sc, ITE8181_EMA_LCDPOWERSEQ);
330 DPRINTFN(1,("ite8181_lcd_power(%d)< p=%x, s=%x, seq=%x\n",
331 on,
332 lcd_p, lcd_s, lcd_seq));
333 if (on) {
334 sc->sc_lcd = 1;
335 lcd_seq |= (ITE8181_PUP0|ITE8181_PUP1|ITE8181_PUP2);
336 ite8181_ema_write_1(sc, ITE8181_EMA_LCDPOWERSEQ, lcd_seq);
337 lcd_p &= ~ITE8181_LCDSTANDBY;
338 ite8181_ema_write_1(sc, ITE8181_EMA_LCDPOWER, lcd_p);
339 /*
340 * XXX:
341 * IBM WorkPad z50 power unit has too weak power.
342 * So we must wait too many times to access self device
343 * after LCD panel and BackLight on.
344 * Currently delay is not enough ??? FIXME
345 */
346 delay(ite8181_lcd_on_self_delay*MSEC);
347 while (loop--) {
348 lcd_p = ite8181_ema_read_1(sc, ITE8181_EMA_LCDPOWER);
349 lcd_s = ite8181_ema_read_1(sc, ITE8181_EMA_LCDPOWERSTAT);
350 lcd_seq = ite8181_ema_read_1(sc, ITE8181_EMA_LCDPOWERSEQ);
351 DPRINTFN(1,("ite8181_lcd_power(%d)%d| p=%x, s=%x, seq=%x\n",
352 on, loop,
353 lcd_p, lcd_s, lcd_seq));
354 /* XXX the states which are not described in manual.*/
355 if (!(lcd_s&ITE8181_LCDPSTANDBY) &&
356 !(lcd_s&ITE8181_LCDPUP) &&
357 (lcd_s&ITE8181_LCDPON))
358 break;
359 delay(100);
360 }
361 lcd_s |= ITE8181_PPTOBEON;
362 ite8181_ema_write_1(sc, ITE8181_EMA_LCDPOWERSTAT, lcd_s);
363 } else {
364 sc->sc_lcd = 0;
365 lcd_p |= ITE8181_LCDSTANDBY;
366 ite8181_ema_write_1(sc, ITE8181_EMA_LCDPOWER, lcd_p);
367 while (loop--) {
368 lcd_p = ite8181_ema_read_1(sc, ITE8181_EMA_LCDPOWER);
369 lcd_s = ite8181_ema_read_1(sc, ITE8181_EMA_LCDPOWERSTAT);
370 lcd_seq = ite8181_ema_read_1(sc, ITE8181_EMA_LCDPOWERSEQ);
371 DPRINTFN(1,("ite8181_lcd_power(%d)%d| p=%x, s=%x, seq=%x\n",
372 on, loop,
373 lcd_p, lcd_s, lcd_seq));
374 /* XXX the states which are not described in manual.*/
375 if ((lcd_s&ITE8181_LCDPSTANDBY) &&
376 !(lcd_s&ITE8181_LCDPDOWN) &&
377 !(lcd_s&ITE8181_LCDPON))
378 break;
379 delay(100);
380 }
381 lcd_s &= ~ITE8181_PPTOBEON;
382 ite8181_ema_write_1(sc, ITE8181_EMA_LCDPOWERSTAT, lcd_s);
383 }
384 DPRINTFN(1,("ite8181_lcd_power(%d)> p=%x, s=%x, seq=%x\n",
385 on,
386 ite8181_ema_read_1(sc, ITE8181_EMA_LCDPOWER),
387 ite8181_ema_read_1(sc, ITE8181_EMA_LCDPOWERSTAT),
388 ite8181_ema_read_1(sc, ITE8181_EMA_LCDPOWERSEQ)));
389 ite8181_ema_write_1(sc, ITE8181_EMA_ENABLEEMA,
390 ITE8181_EMA_DISABLEPASS);
391 }
392 return 0;
393 }
394
395 static void
396 ite8181_erase_cursor(sc)
397 struct ite8181_softc *sc;
398 {
399 ite8181_gui_write_1(sc, ITE8181_GUI_C1C, 0); /* Cursor 1 Control Reg. */
400 /* other ? */
401 }
402
403 static void
404 ite8181_power(why, arg)
405 int why;
406 void *arg;
407 {
408 }
409
410 static int
411 ite8181_hardpower(ctx, type, id, msg)
412 void *ctx;
413 int type;
414 long id;
415 void *msg;
416 {
417 struct ite8181_softc *sc = ctx;
418 int why = (int)msg;
419
420 switch (why) {
421 case PWR_STANDBY:
422 sc->sc_powerstate = ITE8181_POWERSTATE_D3;
423 /* ite8181_lcd_power(sc, 0); */
424 delay(MSEC);
425 break;
426 case PWR_SUSPEND:
427 sc->sc_powerstate = ITE8181_POWERSTATE_D2;
428 ite8181_lcd_power(sc, 0);
429 delay(MSEC);
430 break;
431 case PWR_RESUME:
432 delay(MSEC);
433 sc->sc_powerstate = ITE8181_POWERSTATE_D0;
434 ite8181_lcd_power(sc, 1);
435 /*
436 * XXX:
437 * IBM WorkPad z50 power unit has too weak power.
438 * So we must wait too many times to access other devices
439 * after LCD panel and BackLight on.
440 */
441 delay(ite8181_lcd_on_delay*MSEC);
442 break;
443 }
444
445 /*
446 * you should wait until the
447 * power state transit sequence will end.
448 */
449
450 return (0);
451 }
452
453
454 static int
455 ite8181_fbinit(fb)
456 struct hpcfb_fbconf *fb;
457 {
458
459 /*
460 * get fb settings from bootinfo
461 */
462 if (bootinfo == NULL ||
463 bootinfo->fb_addr == 0 ||
464 bootinfo->fb_line_bytes == 0 ||
465 bootinfo->fb_width == 0 ||
466 bootinfo->fb_height == 0) {
467 printf("no frame buffer infomation.\n");
468 return (-1);
469 }
470
471 /* zero fill */
472 bzero(fb, sizeof(*fb));
473
474 fb->hf_conf_index = 0; /* configuration index */
475 fb->hf_nconfs = 1; /* how many configurations */
476 strcpy(fb->hf_name, "built-in video");
477 /* frame buffer name */
478 strcpy(fb->hf_conf_name, "default");
479 /* configuration name */
480 fb->hf_height = bootinfo->fb_height;
481 fb->hf_width = bootinfo->fb_width;
482 fb->hf_baseaddr = mips_ptob(mips_btop(bootinfo->fb_addr));
483 fb->hf_offset = (u_long)bootinfo->fb_addr - fb->hf_baseaddr;
484 /* frame buffer start offset */
485 fb->hf_bytes_per_line = bootinfo->fb_line_bytes;
486 fb->hf_nplanes = 1;
487 fb->hf_bytes_per_plane = bootinfo->fb_height *
488 bootinfo->fb_line_bytes;
489
490 fb->hf_access_flags |= HPCFB_ACCESS_BYTE;
491 fb->hf_access_flags |= HPCFB_ACCESS_WORD;
492 fb->hf_access_flags |= HPCFB_ACCESS_DWORD;
493
494 switch (bootinfo->fb_type) {
495 /*
496 * gray scale
497 */
498 case BIFB_D2_M2L_3:
499 case BIFB_D2_M2L_3x2:
500 fb->hf_access_flags |= HPCFB_ACCESS_REVERSE;
501 /* fall through */
502 case BIFB_D2_M2L_0:
503 case BIFB_D2_M2L_0x2:
504 fb->hf_class = HPCFB_CLASS_GRAYSCALE;
505 fb->hf_access_flags |= HPCFB_ACCESS_STATIC;
506 fb->hf_pack_width = 8;
507 fb->hf_pixels_per_pack = 4;
508 fb->hf_pixel_width = 2;
509 fb->hf_class_data_length = sizeof(struct hf_gray_tag);
510 fb->hf_u.hf_gray.hf_flags = 0; /* reserved for future use */
511 break;
512
513 /*
514 * indexed color
515 */
516 case BIFB_D8_FF:
517 fb->hf_access_flags |= HPCFB_ACCESS_REVERSE;
518 /* fall through */
519 case BIFB_D8_00:
520 fb->hf_class = HPCFB_CLASS_INDEXCOLOR;
521 fb->hf_access_flags |= HPCFB_ACCESS_STATIC;
522 fb->hf_pack_width = 8;
523 fb->hf_pixels_per_pack = 1;
524 fb->hf_pixel_width = 8;
525 fb->hf_class_data_length = sizeof(struct hf_indexed_tag);
526 fb->hf_u.hf_indexed.hf_flags = 0; /* reserved for future use */
527 break;
528
529 /*
530 * RGB color
531 */
532 case BIFB_D16_FFFF:
533 fb->hf_access_flags |= HPCFB_ACCESS_REVERSE;
534 /* fall through */
535 case BIFB_D16_0000:
536 fb->hf_class = HPCFB_CLASS_RGBCOLOR;
537 fb->hf_access_flags |= HPCFB_ACCESS_STATIC;
538 #if BYTE_ORDER == LITTLE_ENDIAN
539 fb->hf_swap_flags = HPCFB_SWAP_BYTE;
540 #endif
541 fb->hf_pack_width = 16;
542 fb->hf_pixels_per_pack = 1;
543 fb->hf_pixel_width = 16;
544
545 fb->hf_class_data_length = sizeof(struct hf_rgb_tag);
546 fb->hf_u.hf_rgb.hf_flags = 0; /* reserved for future use */
547
548 fb->hf_u.hf_rgb.hf_red_width = 5;
549 fb->hf_u.hf_rgb.hf_red_shift = 11;
550 fb->hf_u.hf_rgb.hf_green_width = 6;
551 fb->hf_u.hf_rgb.hf_green_shift = 5;
552 fb->hf_u.hf_rgb.hf_blue_width = 5;
553 fb->hf_u.hf_rgb.hf_blue_shift = 0;
554 fb->hf_u.hf_rgb.hf_alpha_width = 0;
555 fb->hf_u.hf_rgb.hf_alpha_shift = 0;
556 break;
557
558 default:
559 printf("unknown type (=%d).\n", bootinfo->fb_type);
560 return (-1);
561 break;
562 }
563
564 return (0); /* no error */
565 }
566
567 int
568 ite8181_ioctl(v, cmd, data, flag, p)
569 void *v;
570 u_long cmd;
571 caddr_t data;
572 int flag;
573 struct proc *p;
574 {
575 struct ite8181_softc *sc = (struct ite8181_softc *)v;
576 struct hpcfb_fbconf *fbconf;
577 struct hpcfb_dspconf *dspconf;
578 struct wsdisplay_cmap *cmap;
579
580 switch (cmd) {
581 case WSDISPLAYIO_GETCMAP:
582 cmap = (struct wsdisplay_cmap*)data;
583
584 if (sc->sc_fbconf.hf_class != HPCFB_CLASS_INDEXCOLOR ||
585 sc->sc_fbconf.hf_pack_width != 8 ||
586 256 <= cmap->index ||
587 256 < (cmap->index + cmap->count))
588 return (EINVAL);
589
590 if (!uvm_useracc(cmap->red, cmap->count, B_WRITE) ||
591 !uvm_useracc(cmap->green, cmap->count, B_WRITE) ||
592 !uvm_useracc(cmap->blue, cmap->count, B_WRITE))
593 return (EFAULT);
594
595 #ifdef ITE8181_WINCE_CMAP
596 copyout(&bivideo_cmap_r[cmap->index], cmap->red, cmap->count);
597 copyout(&bivideo_cmap_g[cmap->index], cmap->green,cmap->count);
598 copyout(&bivideo_cmap_b[cmap->index], cmap->blue, cmap->count);
599 return (0);
600 #else /* ITE8181_WINCE_CMAP */
601 return EINVAL;
602 #endif /* ITE8181_WINCE_CMAP */
603
604 case WSDISPLAYIO_PUTCMAP:
605 /*
606 * This driver can't set color map.
607 */
608 return (EINVAL);
609
610 case HPCFBIO_GCONF:
611 fbconf = (struct hpcfb_fbconf *)data;
612 if (fbconf->hf_conf_index != 0 &&
613 fbconf->hf_conf_index != HPCFB_CURRENT_CONFIG) {
614 return (EINVAL);
615 }
616 *fbconf = sc->sc_fbconf; /* structure assignment */
617 return (0);
618 case HPCFBIO_SCONF:
619 fbconf = (struct hpcfb_fbconf *)data;
620 if (fbconf->hf_conf_index != 0 &&
621 fbconf->hf_conf_index != HPCFB_CURRENT_CONFIG) {
622 return (EINVAL);
623 }
624 /*
625 * nothing to do because we have only one configration
626 */
627 return (0);
628 case HPCFBIO_GDSPCONF:
629 dspconf = (struct hpcfb_dspconf *)data;
630 if ((dspconf->hd_unit_index != 0 &&
631 dspconf->hd_unit_index != HPCFB_CURRENT_UNIT) ||
632 (dspconf->hd_conf_index != 0 &&
633 dspconf->hd_conf_index != HPCFB_CURRENT_CONFIG)) {
634 return (EINVAL);
635 }
636 *dspconf = sc->sc_dspconf; /* structure assignment */
637 return (0);
638 case HPCFBIO_SDSPCONF:
639 dspconf = (struct hpcfb_dspconf *)data;
640 if ((dspconf->hd_unit_index != 0 &&
641 dspconf->hd_unit_index != HPCFB_CURRENT_UNIT) ||
642 (dspconf->hd_conf_index != 0 &&
643 dspconf->hd_conf_index != HPCFB_CURRENT_CONFIG)) {
644 return (EINVAL);
645 }
646 /*
647 * nothing to do
648 * because we have only one unit and one configration
649 */
650 return (0);
651 case HPCFBIO_GOP:
652 case HPCFBIO_SOP:
653 /*
654 * curently not implemented...
655 */
656 return (EINVAL);
657 }
658
659 return (ENOTTY);
660 }
661
662 paddr_t
663 ite8181_mmap(ctx, offset, prot)
664 void *ctx;
665 off_t offset;
666 int prot;
667 {
668 struct ite8181_softc *sc = (struct ite8181_softc *)ctx;
669
670 if (offset < 0 ||
671 (sc->sc_fbconf.hf_bytes_per_plane +
672 sc->sc_fbconf.hf_offset) < offset)
673 return -1;
674
675 return mips_btop(sc->sc_fbconf.hf_baseaddr + offset);
676 }
677