No empty .Rs/.Re
[netbsd-mini2440.git] / sys / arch / hpcmips / dev / ite8181.c
blobea3c4d6e5b468a7a63023771dad2fe527f61e1e7
1 /* $NetBSD: ite8181.c,v 1.26 2009/03/14 21:04:09 dsl Exp $ */
3 /*-
4 * Copyright (c) 2000,2001 SATO Kazumi
5 * All rights reserved.
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.
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.
30 #include <sys/cdefs.h>
31 __KERNEL_RCSID(0, "$NetBSD: ite8181.c,v 1.26 2009/03/14 21:04:09 dsl Exp $");
33 #include <sys/param.h>
34 #include <sys/kernel.h>
35 #include <sys/device.h>
36 #include <sys/systm.h>
37 #include <sys/boot_flag.h>
38 #include <sys/buf.h>
40 #include <uvm/uvm_extern.h>
42 #include <dev/wscons/wsconsio.h>
44 #include <machine/bootinfo.h>
45 #include <machine/bus.h>
46 #include <machine/autoconf.h>
47 #include <machine/config_hook.h>
48 #include <machine/platid.h>
49 #include <machine/platid_mask.h>
51 #include <hpcmips/dev/ite8181reg.h>
52 #include <hpcmips/dev/ite8181var.h>
53 #include "bivideo.h"
54 #if NBIVIDEO > 0
55 #include <dev/hpc/bivideovar.h>
56 #endif
57 #include <dev/hpc/hpccmapvar.h>
59 #define ITE8181DEBUG
60 #ifdef ITE8181DEBUG
61 #ifndef ITE8181DEBUG_CONF
62 #define ITE8181DEBUG_CONF 0
63 #endif
64 int ite8181_debug = ITE8181DEBUG_CONF;
65 #define DPRINTF(arg) if (ite8181_debug) printf arg
66 #define DPRINTFN(n, arg) if (ite8181_debug > (n)) printf arg
67 #define VPRINTF(arg) if (bootverbose || ite8181_debug) printf arg
68 #define VPRINTFN(n, arg) if (bootverbose || ite8181_debug > (n)) printf arg
69 #else
70 #define DPRINTF(arg)
71 #define DPRINTFN(n, arg)
72 #define VPRINTF(arg) if (bootverbose) printf arg
73 #define VPRINTFN(n, arg) if (bootverbose) printf arg
74 #endif
76 #ifndef ITE8181_LCD_CONTROL_ENABLE
77 int ite8181_lcd_control_disable = 1;
78 #else /* ITE8181_LCD_CONTROL_ENABLE */
79 int ite8181_lcd_control_disable = 0;
80 #endif /* ITE8181_LCD_CONTROL_ENABLE */
82 #define ITE8181_WINCE_CMAP
85 * XXX:
86 * IBM WorkPad z50 power unit has too weak power.
87 * So we must wait too many times to access some device
88 * after LCD panel and BackLight on.
89 * Currently delay is not enough ??? FIXME
91 #ifndef ITE8181_LCD_ON_SELF_DELAY
92 #define ITE8181_LCD_ON_SELF_DELAY 1000
93 #endif /* ITE8181_LCD_ON__SELF_DELAY */
94 #ifndef ITE8181_LCD_ON_DELAY
95 #define ITE8181_LCD_ON_DELAY 2000
96 #endif /* ITE8181_LCD_ON_DELAY */
97 int ite8181_lcd_on_self_delay = ITE8181_LCD_ON_SELF_DELAY; /* msec */
98 int ite8181_lcd_on_delay = ITE8181_LCD_ON_DELAY; /* msec */
100 #define MSEC 1000
102 * function prototypes
104 static void ite8181_config_write_4(bus_space_tag_t, bus_space_handle_t,
105 int, int);
106 static int ite8181_config_read_4(bus_space_tag_t, bus_space_handle_t,
107 int);
108 static void ite8181_gui_write_4(struct ite8181_softc *, int, int);
109 static int ite8181_gui_read_4(struct ite8181_softc *, int);
111 static void ite8181_gui_write_1(struct ite8181_softc *, int, int);
112 static int ite8181_gui_read_1(struct ite8181_softc *, int);
114 static void ite8181_graphics_write_1(struct ite8181_softc *, int, int);
115 static int ite8181_graphics_read_1(struct ite8181_softc *, int);
117 static void ite8181_ema_write_1(struct ite8181_softc *, int, int);
118 static int ite8181_ema_read_1(struct ite8181_softc *, int);
120 static void ite8181_power(int, void *);
121 static int ite8181_hardpower(void *, int, long, void *);
122 static int ite8181_fbinit(struct hpcfb_fbconf *);
123 static int ite8181_ioctl(void *, u_long, void *, int, struct lwp *);
124 static paddr_t ite8181_mmap(void *, off_t offset, int);
125 static void ite8181_erase_cursor(struct ite8181_softc *);
126 static int ite8181_lcd_power(struct ite8181_softc *, int);
128 static void ite8181_update_powerstate(struct ite8181_softc *, int);
129 void ite8181_init_backlight(struct ite8181_softc *, int);
130 void ite8181_init_brightness(struct ite8181_softc *, int);
131 void ite8181_init_contrast(struct ite8181_softc *, int);
132 void ite8181_set_brightness(struct ite8181_softc *, int);
133 void ite8181_set_contrast(struct ite8181_softc *, int);
136 * static variables
138 struct hpcfb_accessops ite8181_ha = {
139 ite8181_ioctl, ite8181_mmap
142 inline int
143 ite8181_config_read_4(bus_space_tag_t iot, bus_space_handle_t ioh,
144 int byteoffset)
147 return (bus_space_read_4(iot, ioh, ITE8181_CONF_OFFSET + byteoffset));
150 inline void
151 ite8181_config_write_4(bus_space_tag_t iot, bus_space_handle_t ioh,
152 int byteoffset, int data)
155 bus_space_write_4(iot, ioh, ITE8181_CONF_OFFSET + byteoffset, data);
158 inline int
159 ite8181_gui_read_4(struct ite8181_softc *sc, int byteoffset)
162 return (bus_space_read_4(sc->sc_iot, sc->sc_ioh,
163 sc->sc_gba + byteoffset));
166 inline void
167 ite8181_gui_write_4(struct ite8181_softc *sc, int byteoffset, int data)
170 bus_space_write_4(sc->sc_iot, sc->sc_ioh, sc->sc_gba + byteoffset,
171 data);
174 inline int
175 ite8181_gui_read_1(struct ite8181_softc *sc, int byteoffset)
178 return (bus_space_read_1(sc->sc_iot, sc->sc_ioh,
179 sc->sc_gba + byteoffset));
182 inline void
183 ite8181_gui_write_1(struct ite8181_softc *sc, int byteoffset, int data)
186 bus_space_write_1(sc->sc_iot, sc->sc_ioh, sc->sc_gba + byteoffset,
187 data);
190 inline int
191 ite8181_graphics_read_1(struct ite8181_softc *sc, int byteoffset)
194 return (bus_space_read_1(sc->sc_iot, sc->sc_ioh,
195 sc->sc_sba + byteoffset));
198 inline void
199 ite8181_graphics_write_1(struct ite8181_softc *sc, int byteoffset, int data)
202 bus_space_write_1(sc->sc_iot, sc->sc_ioh, sc->sc_sba + byteoffset,
203 data);
206 inline int
207 ite8181_ema_read_1(struct ite8181_softc *sc, int byteoffset)
210 ite8181_graphics_write_1(sc, ITE8181_EMA_EXAX, byteoffset);
211 return (ite8181_graphics_read_1(sc, ITE8181_EMA_EXADATA));
214 inline void
215 ite8181_ema_write_1(struct ite8181_softc *sc, int byteoffset, int data)
218 ite8181_graphics_write_1(sc, ITE8181_EMA_EXAX, byteoffset);
219 ite8181_graphics_write_1(sc, ITE8181_EMA_EXADATA, data);
223 ite8181_probe(bus_space_tag_t iot, bus_space_handle_t ioh)
225 unsigned long regval;
227 #if NBIVIDEO > 0
228 if (bivideo_dont_attach) /* some video driver already attached */
229 return (0);
230 #endif /* NBIVIDEO > 0 */
232 regval = ite8181_config_read_4(iot, ioh, ITE8181_ID);
233 VPRINTF(("ite8181_probe: vendor id=%04lx product id=%04lx\n",
234 regval & 0xffff, (regval >> 16) & 0xffff));
235 if (regval != ((ITE8181_PRODUCT_ID << 16) | ITE8181_VENDER_ID))
236 return (0);
238 return (1);
241 void
242 ite8181_attach(struct ite8181_softc *sc)
244 unsigned long regval;
245 struct hpcfb_attach_args ha;
246 int console = (bootinfo->bi_cnuse & BI_CNUSE_SERIAL) ? 0 : 1;
248 printf(": ");
249 if (ite8181_fbinit(&sc->sc_fbconf) != 0) {
250 /* just return so that hpcfb will not be attached */
251 return;
254 regval = ite8181_config_read_4(sc->sc_iot, sc->sc_ioh, ITE8181_CLASS);
255 printf("ITE8181 Rev.%02lx", regval & ITE8181_REV_MASK);
256 if (console) {
257 printf(", console");
259 printf("\n");
260 printf("%s: framebuffer address: 0x%08lx\n",
261 sc->sc_dev.dv_xname, (u_long)bootinfo->fb_addr);
262 if (ite8181_lcd_control_disable)
263 printf("%s: ite8181 lcd control is DISABLED.\n",
264 sc->sc_dev.dv_xname);
266 /* set base offsets */
267 sc->sc_mba = ite8181_config_read_4(sc->sc_iot, sc->sc_ioh, ITE8181_MBA);
268 DPRINTFN(1, ("ite8181: Memory base offset %08x\n", sc->sc_mba));
269 sc->sc_gba = ite8181_config_read_4(sc->sc_iot, sc->sc_ioh, ITE8181_GBA);
270 DPRINTFN(1, ("ite8181: GUI base offset %08x\n", sc->sc_gba));
271 sc->sc_sba = ite8181_config_read_4(sc->sc_iot, sc->sc_ioh, ITE8181_SBA);
272 DPRINTFN(1, ("ite8181: Graphics base offset %08x\n", sc->sc_sba));
274 /* assume lcd is on */
275 sc->sc_lcd = 1;
276 /* erase wince cursor */
277 ite8181_erase_cursor(sc);
279 /* Add a power hook to power saving */
280 sc->sc_powerhook = powerhook_establish(sc->sc_dev.dv_xname,
281 ite8181_power, sc);
282 if (sc->sc_powerhook == NULL)
283 printf("%s: WARNING: unable to establish power hook\n",
284 sc->sc_dev.dv_xname);
286 /* Add a hard power hook to power saving */
287 sc->sc_hardpowerhook = config_hook(CONFIG_HOOK_PMEVENT,
288 CONFIG_HOOK_PMEVENT_HARDPOWER,
289 CONFIG_HOOK_SHARE,
290 ite8181_hardpower, sc);
291 if (sc->sc_hardpowerhook == NULL)
292 printf("%s: WARNING: unable to establish hard power hook\n",
293 sc->sc_dev.dv_xname);
295 /* initialize backlight brightness and lcd contrast */
296 sc->sc_lcd_inited = 0;
297 ite8181_init_brightness(sc, 1);
298 ite8181_init_contrast(sc, 1);
299 ite8181_init_backlight(sc, 1);
301 if (console && hpcfb_cnattach(&sc->sc_fbconf) != 0) {
302 panic("ite8181_attach: can't init fb console");
305 ha.ha_console = console;
306 ha.ha_accessops = &ite8181_ha;
307 ha.ha_accessctx = sc;
308 ha.ha_curfbconf = 0;
309 ha.ha_nfbconf = 1;
310 ha.ha_fbconflist = &sc->sc_fbconf;
311 ha.ha_curdspconf = 0;
312 ha.ha_ndspconf = 1;
313 ha.ha_dspconflist = &sc->sc_dspconf;
315 config_found(&sc->sc_dev, &ha, hpcfbprint);
317 #if NBIVIDEO > 0
319 * bivideo is no longer need
321 bivideo_dont_attach = 1;
322 #endif /* NBIVIDEO > 0 */
326 ite8181_lcd_power(struct ite8181_softc *sc, int on)
328 int lcd_p;
329 int lcd_s;
330 int lcd_seq;
331 int loop = 10;
333 if (ite8181_lcd_control_disable) {
334 VPRINTF(("ite8171_lcd_control_disable!: %s\n", on?"on":"off"));
335 return 0;
338 if (sc->sc_lcd != on) {
339 ite8181_ema_write_1(sc, ITE8181_EMA_ENABLEEMA,
340 ITE8181_EMA_ENABLEPASS);
341 lcd_p = ite8181_ema_read_1(sc, ITE8181_EMA_LCDPOWER);
342 lcd_s = ite8181_ema_read_1(sc, ITE8181_EMA_LCDPOWERSTAT);
343 lcd_seq = ite8181_ema_read_1(sc, ITE8181_EMA_LCDPOWERSEQ);
344 DPRINTFN(1,("ite8181_lcd_power(%d)< p=%x, s=%x, seq=%x\n",
346 lcd_p, lcd_s, lcd_seq));
347 if (on) {
348 sc->sc_lcd = 1;
349 lcd_seq |= (ITE8181_PUP0|ITE8181_PUP1|ITE8181_PUP2);
350 ite8181_ema_write_1(sc, ITE8181_EMA_LCDPOWERSEQ,
351 lcd_seq);
352 lcd_p &= ~ITE8181_LCDSTANDBY;
353 ite8181_ema_write_1(sc, ITE8181_EMA_LCDPOWER, lcd_p);
355 * XXX:
356 * IBM WorkPad z50 power unit has too weak power.
357 * So we must wait too many times to access self device
358 * after LCD panel and BackLight on.
359 * Currently delay is not enough ??? FIXME
361 delay(ite8181_lcd_on_self_delay*MSEC);
362 while (loop--) {
363 lcd_p = ite8181_ema_read_1(sc,
364 ITE8181_EMA_LCDPOWER);
365 lcd_s = ite8181_ema_read_1(sc,
366 ITE8181_EMA_LCDPOWERSTAT);
367 lcd_seq = ite8181_ema_read_1(sc,
368 ITE8181_EMA_LCDPOWERSEQ);
369 DPRINTFN(1,("ite8181_lcd_power(%d)%d| p=%x,"
370 " s=%x, seq=%x\n", on, loop, lcd_p, lcd_s,
371 lcd_seq));
373 * XXX the states which are not described
374 * XXX in manual.
376 if (!(lcd_s&ITE8181_LCDPSTANDBY) &&
377 !(lcd_s&ITE8181_LCDPUP) &&
378 (lcd_s&ITE8181_LCDPON))
379 break;
380 delay(100);
382 lcd_s |= ITE8181_PPTOBEON;
383 ite8181_ema_write_1(sc, ITE8181_EMA_LCDPOWERSTAT,
384 lcd_s);
385 } else {
386 sc->sc_lcd = 0;
387 lcd_p |= ITE8181_LCDSTANDBY;
388 ite8181_ema_write_1(sc, ITE8181_EMA_LCDPOWER, lcd_p);
389 while (loop--) {
390 lcd_p = ite8181_ema_read_1(sc,
391 ITE8181_EMA_LCDPOWER);
392 lcd_s = ite8181_ema_read_1(sc,
393 ITE8181_EMA_LCDPOWERSTAT);
394 lcd_seq = ite8181_ema_read_1(sc,
395 ITE8181_EMA_LCDPOWERSEQ);
396 DPRINTFN(1,("ite8181_lcd_power(%d)%d| p=%x,"
397 " s=%x, seq=%x\n", on, loop, lcd_p, lcd_s,
398 lcd_seq));
400 * XXX the states which are not described
401 * XXX in manual.
403 if ((lcd_s&ITE8181_LCDPSTANDBY) &&
404 !(lcd_s&ITE8181_LCDPDOWN) &&
405 !(lcd_s&ITE8181_LCDPON))
406 break;
407 delay(100);
409 lcd_s &= ~ITE8181_PPTOBEON;
410 ite8181_ema_write_1(sc, ITE8181_EMA_LCDPOWERSTAT,
411 lcd_s);
413 DPRINTFN(1,("ite8181_lcd_power(%d)> p=%x, s=%x, seq=%x\n",
415 ite8181_ema_read_1(sc, ITE8181_EMA_LCDPOWER),
416 ite8181_ema_read_1(sc, ITE8181_EMA_LCDPOWERSTAT),
417 ite8181_ema_read_1(sc, ITE8181_EMA_LCDPOWERSEQ)));
418 ite8181_ema_write_1(sc, ITE8181_EMA_ENABLEEMA,
419 ITE8181_EMA_DISABLEPASS);
421 return 0;
424 static void
425 ite8181_erase_cursor(struct ite8181_softc *sc)
427 ite8181_gui_write_1(sc, ITE8181_GUI_C1C, 0); /* Cursor 1 Control Reg. */
428 /* other ? */
431 static void
432 ite8181_update_powerstate(struct ite8181_softc *sc, int updates)
434 if (updates & PWRSTAT_LCD)
435 config_hook_call(CONFIG_HOOK_POWERCONTROL,
436 CONFIG_HOOK_POWERCONTROL_LCD,
437 (void*)!(sc->sc_powerstate &
438 (PWRSTAT_VIDEOOFF|PWRSTAT_SUSPEND)));
440 if (updates & PWRSTAT_BACKLIGHT)
441 config_hook_call(CONFIG_HOOK_POWERCONTROL,
442 CONFIG_HOOK_POWERCONTROL_LCDLIGHT,
443 (void*)(!(sc->sc_powerstate &
444 (PWRSTAT_VIDEOOFF|PWRSTAT_SUSPEND)) &&
445 (sc->sc_powerstate & PWRSTAT_BACKLIGHT)));
448 static void
449 ite8181_power(int why, void *arg)
451 struct ite8181_softc *sc = arg;
453 switch (why) {
454 case PWR_STANDBY:
455 sc->sc_powerstate |= PWRSTAT_SUSPEND;
456 ite8181_update_powerstate(sc, PWRSTAT_ALL);
457 break;
458 case PWR_SUSPEND:
459 sc->sc_powerstate |= PWRSTAT_SUSPEND;
460 ite8181_update_powerstate(sc, PWRSTAT_ALL);
461 break;
462 case PWR_RESUME:
463 sc->sc_powerstate &= ~PWRSTAT_SUSPEND;
464 ite8181_update_powerstate(sc, PWRSTAT_ALL);
465 break;
469 static int
470 ite8181_hardpower(void *ctx, int type, long id, void *msg)
472 struct ite8181_softc *sc = ctx;
473 int why = (int)msg;
475 switch (why) {
476 case PWR_STANDBY:
477 /* ite8181_lcd_power(sc, 0); */
478 delay(MSEC);
479 break;
480 case PWR_SUSPEND:
481 ite8181_lcd_power(sc, 0);
482 delay(MSEC);
483 break;
484 case PWR_RESUME:
485 delay(MSEC);
486 ite8181_lcd_power(sc, 1);
488 * XXX:
489 * IBM WorkPad z50 power unit has too weak power.
490 * So we must wait too many times to access other devices
491 * after LCD panel and BackLight on.
493 delay(ite8181_lcd_on_delay*MSEC);
494 break;
498 * you should wait until the
499 * power state transit sequence will end.
502 return (0);
505 static int
506 ite8181_fbinit(struct hpcfb_fbconf *fb)
510 * get fb settings from bootinfo
512 if (bootinfo == NULL ||
513 bootinfo->fb_addr == 0 ||
514 bootinfo->fb_line_bytes == 0 ||
515 bootinfo->fb_width == 0 ||
516 bootinfo->fb_height == 0) {
517 printf("no frame buffer information.\n");
518 return (-1);
521 /* zero fill */
522 memset(fb, 0, sizeof(*fb));
524 fb->hf_conf_index = 0; /* configuration index */
525 fb->hf_nconfs = 1; /* how many configurations */
526 strcpy(fb->hf_name, "built-in video");
527 /* frame buffer name */
528 strcpy(fb->hf_conf_name, "default");
529 /* configuration name */
530 fb->hf_height = bootinfo->fb_height;
531 fb->hf_width = bootinfo->fb_width;
532 fb->hf_baseaddr = (u_long)bootinfo->fb_addr;
533 fb->hf_offset = (u_long)bootinfo->fb_addr -
534 mips_ptob(mips_btop(bootinfo->fb_addr));
535 /* frame buffer start offset */
536 fb->hf_bytes_per_line = bootinfo->fb_line_bytes;
537 fb->hf_nplanes = 1;
538 fb->hf_bytes_per_plane = bootinfo->fb_height *
539 bootinfo->fb_line_bytes;
541 fb->hf_access_flags |= HPCFB_ACCESS_BYTE;
542 fb->hf_access_flags |= HPCFB_ACCESS_WORD;
543 fb->hf_access_flags |= HPCFB_ACCESS_DWORD;
545 switch (bootinfo->fb_type) {
547 * gray scale
549 case BIFB_D2_M2L_3:
550 case BIFB_D2_M2L_3x2:
551 fb->hf_access_flags |= HPCFB_ACCESS_REVERSE;
552 /* fall through */
553 case BIFB_D2_M2L_0:
554 case BIFB_D2_M2L_0x2:
555 fb->hf_class = HPCFB_CLASS_GRAYSCALE;
556 fb->hf_access_flags |= HPCFB_ACCESS_STATIC;
557 fb->hf_pack_width = 8;
558 fb->hf_pixels_per_pack = 4;
559 fb->hf_pixel_width = 2;
560 fb->hf_class_data_length = sizeof(struct hf_gray_tag);
561 fb->hf_u.hf_gray.hf_flags = 0; /* reserved for future use */
562 break;
564 case BIFB_D4_M2L_F:
565 case BIFB_D4_M2L_Fx2:
566 fb->hf_access_flags |= HPCFB_ACCESS_REVERSE;
567 /* fall through */
568 case BIFB_D4_M2L_0:
569 case BIFB_D4_M2L_0x2:
570 fb->hf_class = HPCFB_CLASS_GRAYSCALE;
571 fb->hf_access_flags |= HPCFB_ACCESS_STATIC;
572 fb->hf_pack_width = 8;
573 fb->hf_pixels_per_pack = 2;
574 fb->hf_pixel_width = 4;
575 fb->hf_class_data_length = sizeof(struct hf_gray_tag);
576 fb->hf_u.hf_gray.hf_flags = 0; /* reserved for future use */
577 break;
580 * indexed color
582 case BIFB_D8_FF:
583 fb->hf_access_flags |= HPCFB_ACCESS_REVERSE;
584 /* fall through */
585 case BIFB_D8_00:
586 fb->hf_class = HPCFB_CLASS_INDEXCOLOR;
587 fb->hf_access_flags |= HPCFB_ACCESS_STATIC;
588 fb->hf_pack_width = 8;
589 fb->hf_pixels_per_pack = 1;
590 fb->hf_pixel_width = 8;
591 fb->hf_class_data_length = sizeof(struct hf_indexed_tag);
592 fb->hf_u.hf_indexed.hf_flags = 0; /* reserved for future use */
593 break;
596 * RGB color
598 case BIFB_D16_FFFF:
599 fb->hf_access_flags |= HPCFB_ACCESS_REVERSE;
600 /* fall through */
601 case BIFB_D16_0000:
602 fb->hf_class = HPCFB_CLASS_RGBCOLOR;
603 fb->hf_access_flags |= HPCFB_ACCESS_STATIC;
604 fb->hf_order_flags = HPCFB_REVORDER_BYTE;
605 fb->hf_pack_width = 16;
606 fb->hf_pixels_per_pack = 1;
607 fb->hf_pixel_width = 16;
609 fb->hf_class_data_length = sizeof(struct hf_rgb_tag);
610 fb->hf_u.hf_rgb.hf_flags = 0; /* reserved for future use */
612 fb->hf_u.hf_rgb.hf_red_width = 5;
613 fb->hf_u.hf_rgb.hf_red_shift = 11;
614 fb->hf_u.hf_rgb.hf_green_width = 6;
615 fb->hf_u.hf_rgb.hf_green_shift = 5;
616 fb->hf_u.hf_rgb.hf_blue_width = 5;
617 fb->hf_u.hf_rgb.hf_blue_shift = 0;
618 fb->hf_u.hf_rgb.hf_alpha_width = 0;
619 fb->hf_u.hf_rgb.hf_alpha_shift = 0;
620 break;
622 default:
623 printf("unknown type (=%d).\n", bootinfo->fb_type);
624 return (-1);
625 break;
628 return (0); /* no error */
632 ite8181_ioctl(void *v, u_long cmd, void *data, int flag, struct lwp *l)
634 struct ite8181_softc *sc = (struct ite8181_softc *)v;
635 struct hpcfb_fbconf *fbconf;
636 struct hpcfb_dspconf *dspconf;
637 struct wsdisplay_cmap *cmap;
638 struct wsdisplay_param *dispparam;
639 int error;
641 switch (cmd) {
642 case WSDISPLAYIO_GETCMAP:
643 cmap = (struct wsdisplay_cmap *)data;
645 if (sc->sc_fbconf.hf_class != HPCFB_CLASS_INDEXCOLOR ||
646 sc->sc_fbconf.hf_pack_width != 8 ||
647 256 <= cmap->index ||
648 256 - cmap->index < cmap->count)
649 return (EINVAL);
651 #ifdef ITE8181_WINCE_CMAP
652 error = copyout(&bivideo_cmap_r[cmap->index], cmap->red,
653 cmap->count);
654 if (error)
655 return error;
656 error = copyout(&bivideo_cmap_g[cmap->index], cmap->green,
657 cmap->count);
658 if (error)
659 return error;
660 error = copyout(&bivideo_cmap_b[cmap->index], cmap->blue,
661 cmap->count);
662 return error;
663 #else /* ITE8181_WINCE_CMAP */
664 return EINVAL;
665 #endif /* ITE8181_WINCE_CMAP */
667 case WSDISPLAYIO_PUTCMAP:
669 * This driver can't set color map.
671 return (EINVAL);
673 case WSDISPLAYIO_SVIDEO:
674 if (*(int *)data == WSDISPLAYIO_VIDEO_OFF)
675 sc->sc_powerstate |= PWRSTAT_VIDEOOFF;
676 else
677 sc->sc_powerstate &= ~PWRSTAT_VIDEOOFF;
678 ite8181_update_powerstate(sc, PWRSTAT_ALL);
679 return 0;
681 case WSDISPLAYIO_GVIDEO:
682 *(int *)data = (sc->sc_powerstate&PWRSTAT_VIDEOOFF) ?
683 WSDISPLAYIO_VIDEO_OFF:WSDISPLAYIO_VIDEO_ON;
684 return 0;
687 case WSDISPLAYIO_GETPARAM:
688 dispparam = (struct wsdisplay_param*)data;
689 switch (dispparam->param) {
690 case WSDISPLAYIO_PARAM_BACKLIGHT:
691 VPRINTF(("ite8181_ioctl: GET:BACKLIGHT\n"));
692 ite8181_init_brightness(sc, 0);
693 ite8181_init_backlight(sc, 0);
694 VPRINTF(("ite8181_ioctl: GET:(real)BACKLIGHT %d\n",
695 (sc->sc_powerstate&PWRSTAT_BACKLIGHT)? 1: 0));
696 dispparam->min = 0;
697 dispparam->max = 1;
698 if (sc->sc_max_brightness > 0)
699 dispparam->curval =
700 sc->sc_brightness > 0 ? 1: 0;
701 else
702 dispparam->curval =
703 (sc->sc_powerstate & PWRSTAT_BACKLIGHT)
704 ? 1: 0;
705 VPRINTF(("ite8181_ioctl: GET:BACKLIGHT:%d(%s)\n",
706 dispparam->curval,
707 sc->sc_max_brightness > 0? "brightness": "light"));
708 return 0;
709 break;
710 case WSDISPLAYIO_PARAM_CONTRAST:
711 VPRINTF(("ite8181_ioctl: GET:CONTRAST\n"));
712 ite8181_init_contrast(sc, 0);
713 if (sc->sc_max_contrast > 0) {
714 dispparam->min = 0;
715 dispparam->max = sc->sc_max_contrast;
716 dispparam->curval = sc->sc_contrast;
717 VPRINTF(("ite8181_ioctl: GET:CONTRAST max=%d,"
718 " current=%d\n", sc->sc_max_contrast,
719 sc->sc_contrast));
720 return 0;
721 } else {
722 VPRINTF(("ite8181_ioctl: "
723 "GET:CONTRAST EINVAL\n"));
724 return (EINVAL);
726 break;
727 case WSDISPLAYIO_PARAM_BRIGHTNESS:
728 VPRINTF(("ite8181_ioctl: GET:BRIGHTNESS\n"));
729 ite8181_init_brightness(sc, 0);
730 if (sc->sc_max_brightness > 0) {
731 dispparam->min = 0;
732 dispparam->max = sc->sc_max_brightness;
733 dispparam->curval = sc->sc_brightness;
734 VPRINTF(("ite8181_ioctl: GET:BRIGHTNESS"
735 " max=%d, current=%d\n",
736 sc->sc_max_brightness, sc->sc_brightness));
737 return 0;
738 } else {
739 VPRINTF(("ite8181_ioctl: GET:BRIGHTNESS"
740 " EINVAL\n"));
741 return (EINVAL);
743 return (EINVAL);
744 default:
745 return (EINVAL);
747 return (0);
749 case WSDISPLAYIO_SETPARAM:
750 dispparam = (struct wsdisplay_param*)data;
751 switch (dispparam->param) {
752 case WSDISPLAYIO_PARAM_BACKLIGHT:
753 VPRINTF(("ite8181_ioctl: SET:BACKLIGHT\n"));
754 if (dispparam->curval < 0 ||
755 1 < dispparam->curval)
756 return (EINVAL);
757 ite8181_init_brightness(sc, 0);
758 VPRINTF(("ite8181_ioctl: SET:max brightness=%d\n",
759 sc->sc_max_brightness));
760 if (sc->sc_max_brightness > 0) { /* dimmer */
761 if (dispparam->curval == 0){
762 sc->sc_brightness_save =
763 sc->sc_brightness;
764 ite8181_set_brightness(sc, 0);/* min */
765 } else {
766 if (sc->sc_brightness_save == 0)
767 sc->sc_brightness_save =
768 sc->sc_max_brightness;
769 ite8181_set_brightness(sc,
770 sc->sc_brightness_save);
772 VPRINTF(("ite8181_ioctl: SET:BACKLIGHT:"
773 "brightness=%d\n", sc->sc_brightness));
774 } else { /* off */
775 if (dispparam->curval == 0)
776 sc->sc_powerstate &= ~PWRSTAT_BACKLIGHT;
777 else
778 sc->sc_powerstate |= PWRSTAT_BACKLIGHT;
779 VPRINTF(("ite8181_ioctl: SET:BACKLIGHT:"
780 "powerstate %d\n",
781 (sc->sc_powerstate & PWRSTAT_BACKLIGHT)
782 ? 1 : 0));
783 ite8181_update_powerstate(sc,
784 PWRSTAT_BACKLIGHT);
785 VPRINTF(("ite8181_ioctl: SET:BACKLIGHT:%d\n",
786 (sc->sc_powerstate & PWRSTAT_BACKLIGHT)
787 ? 1 : 0));
789 return 0;
790 break;
791 case WSDISPLAYIO_PARAM_CONTRAST:
792 VPRINTF(("ite8181_ioctl: SET:CONTRAST\n"));
793 ite8181_init_contrast(sc, 0);
794 if (dispparam->curval < 0 ||
795 sc->sc_max_contrast < dispparam->curval)
796 return (EINVAL);
797 if (sc->sc_max_contrast > 0) {
798 int org = sc->sc_contrast;
799 ite8181_set_contrast(sc, dispparam->curval);
800 VPRINTF(("ite8181_ioctl: SET:CONTRAST"
801 " org=%d, current=%d\n", org,
802 sc->sc_contrast));
803 return 0;
804 } else {
805 VPRINTF(("ite8181_ioctl: SET:CONTRAST"
806 " EINVAL\n"));
807 return (EINVAL);
809 break;
810 case WSDISPLAYIO_PARAM_BRIGHTNESS:
811 VPRINTF(("ite8181_ioctl: SET:BRIGHTNESS\n"));
812 ite8181_init_brightness(sc, 0);
813 if (dispparam->curval < 0 ||
814 sc->sc_max_brightness < dispparam->curval)
815 return (EINVAL);
816 if (sc->sc_max_brightness > 0) {
817 int org = sc->sc_brightness;
818 ite8181_set_brightness(sc, dispparam->curval);
819 VPRINTF(("ite8181_ioctl: SET:BRIGHTNESS"
820 " org=%d, current=%d\n", org,
821 sc->sc_brightness));
822 return 0;
823 } else {
824 VPRINTF(("ite8181_ioctl: SET:BRIGHTNESS"
825 " EINVAL\n"));
826 return (EINVAL);
828 break;
829 default:
830 return (EINVAL);
832 return (0);
834 case HPCFBIO_GCONF:
835 fbconf = (struct hpcfb_fbconf *)data;
836 if (fbconf->hf_conf_index != 0 &&
837 fbconf->hf_conf_index != HPCFB_CURRENT_CONFIG) {
838 return (EINVAL);
840 *fbconf = sc->sc_fbconf; /* structure assignment */
841 return (0);
842 case HPCFBIO_SCONF:
843 fbconf = (struct hpcfb_fbconf *)data;
844 if (fbconf->hf_conf_index != 0 &&
845 fbconf->hf_conf_index != HPCFB_CURRENT_CONFIG) {
846 return (EINVAL);
849 * nothing to do because we have only one configuration
851 return (0);
852 case HPCFBIO_GDSPCONF:
853 dspconf = (struct hpcfb_dspconf *)data;
854 if ((dspconf->hd_unit_index != 0 &&
855 dspconf->hd_unit_index != HPCFB_CURRENT_UNIT) ||
856 (dspconf->hd_conf_index != 0 &&
857 dspconf->hd_conf_index != HPCFB_CURRENT_CONFIG)) {
858 return (EINVAL);
860 *dspconf = sc->sc_dspconf; /* structure assignment */
861 return (0);
862 case HPCFBIO_SDSPCONF:
863 dspconf = (struct hpcfb_dspconf *)data;
864 if ((dspconf->hd_unit_index != 0 &&
865 dspconf->hd_unit_index != HPCFB_CURRENT_UNIT) ||
866 (dspconf->hd_conf_index != 0 &&
867 dspconf->hd_conf_index != HPCFB_CURRENT_CONFIG)) {
868 return (EINVAL);
871 * nothing to do
872 * because we have only one unit and one configuration
874 return (0);
875 case HPCFBIO_GOP:
876 case HPCFBIO_SOP:
878 * curently not implemented...
880 return (EINVAL);
883 return (EPASSTHROUGH);
886 paddr_t
887 ite8181_mmap(void *ctx, off_t offset, int prot)
889 struct ite8181_softc *sc = (struct ite8181_softc *)ctx;
891 if (offset < 0 ||
892 (sc->sc_fbconf.hf_bytes_per_plane +
893 sc->sc_fbconf.hf_offset) < offset)
894 return -1;
896 return mips_btop((u_long)bootinfo->fb_addr + offset);
900 void
901 ite8181_init_backlight(struct ite8181_softc *sc, int inattach)
903 int val = -1;
905 if (sc->sc_lcd_inited&BACKLIGHT_INITED)
906 return;
908 if (config_hook_call(CONFIG_HOOK_GET,
909 CONFIG_HOOK_POWER_LCDLIGHT, &val) != -1) {
910 /* we can get real light state */
911 VPRINTF(("ite8181_init_backlight: real backlight=%d\n", val));
912 if (val == 0)
913 sc->sc_powerstate &= ~PWRSTAT_BACKLIGHT;
914 else
915 sc->sc_powerstate |= PWRSTAT_BACKLIGHT;
916 sc->sc_lcd_inited |= BACKLIGHT_INITED;
917 } else if (inattach) {
919 we cannot get real light state in attach time
920 because light device not yet attached.
921 we will retry in !inattach.
922 temporary assume light is on.
924 sc->sc_powerstate |= PWRSTAT_BACKLIGHT;
925 } else {
926 /* we cannot get real light state, so work by myself state */
927 sc->sc_lcd_inited |= BACKLIGHT_INITED;
931 void
932 ite8181_init_brightness(struct ite8181_softc *sc, int inattach)
934 int val = -1;
936 if (sc->sc_lcd_inited&BRIGHTNESS_INITED)
937 return;
939 VPRINTF(("ite8181_init_brightness\n"));
940 if (config_hook_call(CONFIG_HOOK_GET,
941 CONFIG_HOOK_BRIGHTNESS_MAX, &val) != -1) {
942 /* we can get real brightness max */
943 VPRINTF(("ite8181_init_brightness: real brightness max=%d\n",
944 val));
945 sc->sc_max_brightness = val;
946 val = -1;
947 if (config_hook_call(CONFIG_HOOK_GET,
948 CONFIG_HOOK_BRIGHTNESS, &val) != -1) {
949 /* we can get real brightness */
950 VPRINTF(("ite8181_init_brightness:"
951 " real brightness=%d\n", val));
952 sc->sc_brightness_save = sc->sc_brightness = val;
953 } else {
954 sc->sc_brightness_save =
955 sc->sc_brightness = sc->sc_max_brightness;
957 sc->sc_lcd_inited |= BRIGHTNESS_INITED;
958 } else if (inattach) {
960 we cannot get real brightness in attach time
961 because brightness device not yet attached.
962 we will retry in !inattach.
964 sc->sc_max_brightness = -1;
965 sc->sc_brightness = -1;
966 sc->sc_brightness_save = -1;
967 } else {
968 /* we cannot get real brightness */
969 sc->sc_lcd_inited |= BRIGHTNESS_INITED;
972 return;
975 void
976 ite8181_init_contrast(struct ite8181_softc *sc, int inattach)
978 int val = -1;
980 if (sc->sc_lcd_inited&CONTRAST_INITED)
981 return;
983 VPRINTF(("ite8181_init_contrast\n"));
984 if (config_hook_call(CONFIG_HOOK_GET,
985 CONFIG_HOOK_CONTRAST_MAX, &val) != -1) {
986 /* we can get real contrast max */
987 VPRINTF(("ite8181_init_contrast: real contrast max=%d\n", val));
988 sc->sc_max_contrast = val;
989 val = -1;
990 if (config_hook_call(CONFIG_HOOK_GET,
991 CONFIG_HOOK_CONTRAST, &val) != -1) {
992 /* we can get real contrast */
993 VPRINTF(("ite8181_init_contrast: real contrast=%d\n",
994 val));
995 sc->sc_contrast = val;
996 } else {
997 sc->sc_contrast = sc->sc_max_contrast;
999 sc->sc_lcd_inited |= CONTRAST_INITED;
1000 } else if (inattach) {
1002 we cannot get real contrast in attach time
1003 because contrast device not yet attached.
1004 we will retry in !inattach.
1006 sc->sc_max_contrast = -1;
1007 sc->sc_contrast = -1;
1008 } else {
1009 /* we cannot get real contrast */
1010 sc->sc_lcd_inited |= CONTRAST_INITED;
1013 return;
1017 void
1018 ite8181_set_brightness(struct ite8181_softc *sc, int val)
1021 sc->sc_brightness = val;
1023 config_hook_call(CONFIG_HOOK_SET, CONFIG_HOOK_BRIGHTNESS, &val);
1024 if (config_hook_call(CONFIG_HOOK_GET,
1025 CONFIG_HOOK_BRIGHTNESS, &val) != -1) {
1026 sc->sc_brightness = val;
1030 void
1031 ite8181_set_contrast(struct ite8181_softc *sc, int val)
1034 sc->sc_contrast = val;
1036 config_hook_call(CONFIG_HOOK_SET, CONFIG_HOOK_CONTRAST, &val);
1037 if (config_hook_call(CONFIG_HOOK_GET,
1038 CONFIG_HOOK_CONTRAST, &val) != -1) {
1039 sc->sc_contrast = val;