ite8181.c revision 1.3.2.4 1 /* $NetBSD: ite8181.c,v 1.3.2.4 2000/12/08 09:26:31 bouyer 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 = (u_long)bootinfo->fb_addr;
483 fb->hf_offset = (u_long)bootinfo->fb_addr -
484 mips_ptob(mips_btop(bootinfo->fb_addr));
485 /* frame buffer start offset */
486 fb->hf_bytes_per_line = bootinfo->fb_line_bytes;
487 fb->hf_nplanes = 1;
488 fb->hf_bytes_per_plane = bootinfo->fb_height *
489 bootinfo->fb_line_bytes;
490
491 fb->hf_access_flags |= HPCFB_ACCESS_BYTE;
492 fb->hf_access_flags |= HPCFB_ACCESS_WORD;
493 fb->hf_access_flags |= HPCFB_ACCESS_DWORD;
494
495 switch (bootinfo->fb_type) {
496 /*
497 * gray scale
498 */
499 case BIFB_D2_M2L_3:
500 case BIFB_D2_M2L_3x2:
501 fb->hf_access_flags |= HPCFB_ACCESS_REVERSE;
502 /* fall through */
503 case BIFB_D2_M2L_0:
504 case BIFB_D2_M2L_0x2:
505 fb->hf_class = HPCFB_CLASS_GRAYSCALE;
506 fb->hf_access_flags |= HPCFB_ACCESS_STATIC;
507 fb->hf_pack_width = 8;
508 fb->hf_pixels_per_pack = 4;
509 fb->hf_pixel_width = 2;
510 fb->hf_class_data_length = sizeof(struct hf_gray_tag);
511 fb->hf_u.hf_gray.hf_flags = 0; /* reserved for future use */
512 break;
513
514 /*
515 * indexed color
516 */
517 case BIFB_D8_FF:
518 fb->hf_access_flags |= HPCFB_ACCESS_REVERSE;
519 /* fall through */
520 case BIFB_D8_00:
521 fb->hf_class = HPCFB_CLASS_INDEXCOLOR;
522 fb->hf_access_flags |= HPCFB_ACCESS_STATIC;
523 fb->hf_pack_width = 8;
524 fb->hf_pixels_per_pack = 1;
525 fb->hf_pixel_width = 8;
526 fb->hf_class_data_length = sizeof(struct hf_indexed_tag);
527 fb->hf_u.hf_indexed.hf_flags = 0; /* reserved for future use */
528 break;
529
530 /*
531 * RGB color
532 */
533 case BIFB_D16_FFFF:
534 fb->hf_access_flags |= HPCFB_ACCESS_REVERSE;
535 /* fall through */
536 case BIFB_D16_0000:
537 fb->hf_class = HPCFB_CLASS_RGBCOLOR;
538 fb->hf_access_flags |= HPCFB_ACCESS_STATIC;
539 #if BYTE_ORDER == LITTLE_ENDIAN
540 fb->hf_swap_flags = HPCFB_SWAP_BYTE;
541 #endif
542 fb->hf_pack_width = 16;
543 fb->hf_pixels_per_pack = 1;
544 fb->hf_pixel_width = 16;
545
546 fb->hf_class_data_length = sizeof(struct hf_rgb_tag);
547 fb->hf_u.hf_rgb.hf_flags = 0; /* reserved for future use */
548
549 fb->hf_u.hf_rgb.hf_red_width = 5;
550 fb->hf_u.hf_rgb.hf_red_shift = 11;
551 fb->hf_u.hf_rgb.hf_green_width = 6;
552 fb->hf_u.hf_rgb.hf_green_shift = 5;
553 fb->hf_u.hf_rgb.hf_blue_width = 5;
554 fb->hf_u.hf_rgb.hf_blue_shift = 0;
555 fb->hf_u.hf_rgb.hf_alpha_width = 0;
556 fb->hf_u.hf_rgb.hf_alpha_shift = 0;
557 break;
558
559 default:
560 printf("unknown type (=%d).\n", bootinfo->fb_type);
561 return (-1);
562 break;
563 }
564
565 return (0); /* no error */
566 }
567
568 int
569 ite8181_ioctl(v, cmd, data, flag, p)
570 void *v;
571 u_long cmd;
572 caddr_t data;
573 int flag;
574 struct proc *p;
575 {
576 struct ite8181_softc *sc = (struct ite8181_softc *)v;
577 struct hpcfb_fbconf *fbconf;
578 struct hpcfb_dspconf *dspconf;
579 struct wsdisplay_cmap *cmap;
580
581 switch (cmd) {
582 case WSDISPLAYIO_GETCMAP:
583 cmap = (struct wsdisplay_cmap*)data;
584
585 if (sc->sc_fbconf.hf_class != HPCFB_CLASS_INDEXCOLOR ||
586 sc->sc_fbconf.hf_pack_width != 8 ||
587 256 <= cmap->index ||
588 256 < (cmap->index + cmap->count))
589 return (EINVAL);
590
591 if (!uvm_useracc(cmap->red, cmap->count, B_WRITE) ||
592 !uvm_useracc(cmap->green, cmap->count, B_WRITE) ||
593 !uvm_useracc(cmap->blue, cmap->count, B_WRITE))
594 return (EFAULT);
595
596 #ifdef ITE8181_WINCE_CMAP
597 copyout(&bivideo_cmap_r[cmap->index], cmap->red, cmap->count);
598 copyout(&bivideo_cmap_g[cmap->index], cmap->green,cmap->count);
599 copyout(&bivideo_cmap_b[cmap->index], cmap->blue, cmap->count);
600 return (0);
601 #else /* ITE8181_WINCE_CMAP */
602 return EINVAL;
603 #endif /* ITE8181_WINCE_CMAP */
604
605 case WSDISPLAYIO_PUTCMAP:
606 /*
607 * This driver can't set color map.
608 */
609 return (EINVAL);
610
611 case HPCFBIO_GCONF:
612 fbconf = (struct hpcfb_fbconf *)data;
613 if (fbconf->hf_conf_index != 0 &&
614 fbconf->hf_conf_index != HPCFB_CURRENT_CONFIG) {
615 return (EINVAL);
616 }
617 *fbconf = sc->sc_fbconf; /* structure assignment */
618 return (0);
619 case HPCFBIO_SCONF:
620 fbconf = (struct hpcfb_fbconf *)data;
621 if (fbconf->hf_conf_index != 0 &&
622 fbconf->hf_conf_index != HPCFB_CURRENT_CONFIG) {
623 return (EINVAL);
624 }
625 /*
626 * nothing to do because we have only one configration
627 */
628 return (0);
629 case HPCFBIO_GDSPCONF:
630 dspconf = (struct hpcfb_dspconf *)data;
631 if ((dspconf->hd_unit_index != 0 &&
632 dspconf->hd_unit_index != HPCFB_CURRENT_UNIT) ||
633 (dspconf->hd_conf_index != 0 &&
634 dspconf->hd_conf_index != HPCFB_CURRENT_CONFIG)) {
635 return (EINVAL);
636 }
637 *dspconf = sc->sc_dspconf; /* structure assignment */
638 return (0);
639 case HPCFBIO_SDSPCONF:
640 dspconf = (struct hpcfb_dspconf *)data;
641 if ((dspconf->hd_unit_index != 0 &&
642 dspconf->hd_unit_index != HPCFB_CURRENT_UNIT) ||
643 (dspconf->hd_conf_index != 0 &&
644 dspconf->hd_conf_index != HPCFB_CURRENT_CONFIG)) {
645 return (EINVAL);
646 }
647 /*
648 * nothing to do
649 * because we have only one unit and one configration
650 */
651 return (0);
652 case HPCFBIO_GOP:
653 case HPCFBIO_SOP:
654 /*
655 * curently not implemented...
656 */
657 return (EINVAL);
658 }
659
660 return (ENOTTY);
661 }
662
663 paddr_t
664 ite8181_mmap(ctx, offset, prot)
665 void *ctx;
666 off_t offset;
667 int prot;
668 {
669 struct ite8181_softc *sc = (struct ite8181_softc *)ctx;
670
671 if (offset < 0 ||
672 (sc->sc_fbconf.hf_bytes_per_plane +
673 sc->sc_fbconf.hf_offset) < offset)
674 return -1;
675
676 return mips_btop((u_long)bootinfo->fb_addr + offset);
677 }
678