1 /* $NetBSD: ite8181.c,v 1.26 2009/03/14 21:04:09 dsl Exp $ */
4 * Copyright (c) 2000,2001 SATO Kazumi
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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
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>
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>
55 #include <dev/hpc/bivideovar.h>
57 #include <dev/hpc/hpccmapvar.h>
61 #ifndef ITE8181DEBUG_CONF
62 #define ITE8181DEBUG_CONF 0
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
71 #define DPRINTFN(n, arg)
72 #define VPRINTF(arg) if (bootverbose) printf arg
73 #define VPRINTFN(n, arg) if (bootverbose) printf arg
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
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 */
102 * function prototypes
104 static void ite8181_config_write_4(bus_space_tag_t
, bus_space_handle_t
,
106 static int ite8181_config_read_4(bus_space_tag_t
, bus_space_handle_t
,
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);
138 struct hpcfb_accessops ite8181_ha
= {
139 ite8181_ioctl
, ite8181_mmap
143 ite8181_config_read_4(bus_space_tag_t iot
, bus_space_handle_t ioh
,
147 return (bus_space_read_4(iot
, ioh
, ITE8181_CONF_OFFSET
+ byteoffset
));
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
);
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
));
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
,
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
));
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
,
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
));
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
,
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
));
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
;
228 if (bivideo_dont_attach
) /* some video driver already attached */
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
))
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;
249 if (ite8181_fbinit(&sc
->sc_fbconf
) != 0) {
250 /* just return so that hpcfb will not be attached */
254 regval
= ite8181_config_read_4(sc
->sc_iot
, sc
->sc_ioh
, ITE8181_CLASS
);
255 printf("ITE8181 Rev.%02lx", regval
& ITE8181_REV_MASK
);
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 */
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
,
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
,
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
;
310 ha
.ha_fbconflist
= &sc
->sc_fbconf
;
311 ha
.ha_curdspconf
= 0;
313 ha
.ha_dspconflist
= &sc
->sc_dspconf
;
315 config_found(&sc
->sc_dev
, &ha
, hpcfbprint
);
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
)
333 if (ite8181_lcd_control_disable
) {
334 VPRINTF(("ite8171_lcd_control_disable!: %s\n", on
?"on":"off"));
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
));
349 lcd_seq
|= (ITE8181_PUP0
|ITE8181_PUP1
|ITE8181_PUP2
);
350 ite8181_ema_write_1(sc
, ITE8181_EMA_LCDPOWERSEQ
,
352 lcd_p
&= ~ITE8181_LCDSTANDBY
;
353 ite8181_ema_write_1(sc
, ITE8181_EMA_LCDPOWER
, lcd_p
);
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
);
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
,
373 * XXX the states which are not described
376 if (!(lcd_s
&ITE8181_LCDPSTANDBY
) &&
377 !(lcd_s
&ITE8181_LCDPUP
) &&
378 (lcd_s
&ITE8181_LCDPON
))
382 lcd_s
|= ITE8181_PPTOBEON
;
383 ite8181_ema_write_1(sc
, ITE8181_EMA_LCDPOWERSTAT
,
387 lcd_p
|= ITE8181_LCDSTANDBY
;
388 ite8181_ema_write_1(sc
, ITE8181_EMA_LCDPOWER
, lcd_p
);
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
,
400 * XXX the states which are not described
403 if ((lcd_s
&ITE8181_LCDPSTANDBY
) &&
404 !(lcd_s
&ITE8181_LCDPDOWN
) &&
405 !(lcd_s
&ITE8181_LCDPON
))
409 lcd_s
&= ~ITE8181_PPTOBEON
;
410 ite8181_ema_write_1(sc
, ITE8181_EMA_LCDPOWERSTAT
,
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
);
425 ite8181_erase_cursor(struct ite8181_softc
*sc
)
427 ite8181_gui_write_1(sc
, ITE8181_GUI_C1C
, 0); /* Cursor 1 Control Reg. */
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
)));
449 ite8181_power(int why
, void *arg
)
451 struct ite8181_softc
*sc
= arg
;
455 sc
->sc_powerstate
|= PWRSTAT_SUSPEND
;
456 ite8181_update_powerstate(sc
, PWRSTAT_ALL
);
459 sc
->sc_powerstate
|= PWRSTAT_SUSPEND
;
460 ite8181_update_powerstate(sc
, PWRSTAT_ALL
);
463 sc
->sc_powerstate
&= ~PWRSTAT_SUSPEND
;
464 ite8181_update_powerstate(sc
, PWRSTAT_ALL
);
470 ite8181_hardpower(void *ctx
, int type
, long id
, void *msg
)
472 struct ite8181_softc
*sc
= ctx
;
477 /* ite8181_lcd_power(sc, 0); */
481 ite8181_lcd_power(sc
, 0);
486 ite8181_lcd_power(sc
, 1);
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
);
498 * you should wait until the
499 * power state transit sequence will end.
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");
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
;
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
) {
550 case BIFB_D2_M2L_3x2
:
551 fb
->hf_access_flags
|= HPCFB_ACCESS_REVERSE
;
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 */
565 case BIFB_D4_M2L_Fx2
:
566 fb
->hf_access_flags
|= HPCFB_ACCESS_REVERSE
;
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 */
583 fb
->hf_access_flags
|= HPCFB_ACCESS_REVERSE
;
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 */
599 fb
->hf_access_flags
|= HPCFB_ACCESS_REVERSE
;
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;
623 printf("unknown type (=%d).\n", bootinfo
->fb_type
);
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
;
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
)
651 #ifdef ITE8181_WINCE_CMAP
652 error
= copyout(&bivideo_cmap_r
[cmap
->index
], cmap
->red
,
656 error
= copyout(&bivideo_cmap_g
[cmap
->index
], cmap
->green
,
660 error
= copyout(&bivideo_cmap_b
[cmap
->index
], cmap
->blue
,
663 #else /* ITE8181_WINCE_CMAP */
665 #endif /* ITE8181_WINCE_CMAP */
667 case WSDISPLAYIO_PUTCMAP
:
669 * This driver can't set color map.
673 case WSDISPLAYIO_SVIDEO
:
674 if (*(int *)data
== WSDISPLAYIO_VIDEO_OFF
)
675 sc
->sc_powerstate
|= PWRSTAT_VIDEOOFF
;
677 sc
->sc_powerstate
&= ~PWRSTAT_VIDEOOFF
;
678 ite8181_update_powerstate(sc
, PWRSTAT_ALL
);
681 case WSDISPLAYIO_GVIDEO
:
682 *(int *)data
= (sc
->sc_powerstate
&PWRSTAT_VIDEOOFF
) ?
683 WSDISPLAYIO_VIDEO_OFF
:WSDISPLAYIO_VIDEO_ON
;
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));
698 if (sc
->sc_max_brightness
> 0)
700 sc
->sc_brightness
> 0 ? 1: 0;
703 (sc
->sc_powerstate
& PWRSTAT_BACKLIGHT
)
705 VPRINTF(("ite8181_ioctl: GET:BACKLIGHT:%d(%s)\n",
707 sc
->sc_max_brightness
> 0? "brightness": "light"));
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) {
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
,
722 VPRINTF(("ite8181_ioctl: "
723 "GET:CONTRAST EINVAL\n"));
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) {
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
));
739 VPRINTF(("ite8181_ioctl: GET:BRIGHTNESS"
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
)
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
=
764 ite8181_set_brightness(sc
, 0);/* min */
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
));
775 if (dispparam
->curval
== 0)
776 sc
->sc_powerstate
&= ~PWRSTAT_BACKLIGHT
;
778 sc
->sc_powerstate
|= PWRSTAT_BACKLIGHT
;
779 VPRINTF(("ite8181_ioctl: SET:BACKLIGHT:"
781 (sc
->sc_powerstate
& PWRSTAT_BACKLIGHT
)
783 ite8181_update_powerstate(sc
,
785 VPRINTF(("ite8181_ioctl: SET:BACKLIGHT:%d\n",
786 (sc
->sc_powerstate
& PWRSTAT_BACKLIGHT
)
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
)
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
,
805 VPRINTF(("ite8181_ioctl: SET:CONTRAST"
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
)
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
,
824 VPRINTF(("ite8181_ioctl: SET:BRIGHTNESS"
835 fbconf
= (struct hpcfb_fbconf
*)data
;
836 if (fbconf
->hf_conf_index
!= 0 &&
837 fbconf
->hf_conf_index
!= HPCFB_CURRENT_CONFIG
) {
840 *fbconf
= sc
->sc_fbconf
; /* structure assignment */
843 fbconf
= (struct hpcfb_fbconf
*)data
;
844 if (fbconf
->hf_conf_index
!= 0 &&
845 fbconf
->hf_conf_index
!= HPCFB_CURRENT_CONFIG
) {
849 * nothing to do because we have only one configuration
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
)) {
860 *dspconf
= sc
->sc_dspconf
; /* structure assignment */
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
)) {
872 * because we have only one unit and one configuration
878 * curently not implemented...
883 return (EPASSTHROUGH
);
887 ite8181_mmap(void *ctx
, off_t offset
, int prot
)
889 struct ite8181_softc
*sc
= (struct ite8181_softc
*)ctx
;
892 (sc
->sc_fbconf
.hf_bytes_per_plane
+
893 sc
->sc_fbconf
.hf_offset
) < offset
)
896 return mips_btop((u_long
)bootinfo
->fb_addr
+ offset
);
901 ite8181_init_backlight(struct ite8181_softc
*sc
, int inattach
)
905 if (sc
->sc_lcd_inited
&BACKLIGHT_INITED
)
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
));
913 sc
->sc_powerstate
&= ~PWRSTAT_BACKLIGHT
;
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
;
926 /* we cannot get real light state, so work by myself state */
927 sc
->sc_lcd_inited
|= BACKLIGHT_INITED
;
932 ite8181_init_brightness(struct ite8181_softc
*sc
, int inattach
)
936 if (sc
->sc_lcd_inited
&BRIGHTNESS_INITED
)
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",
945 sc
->sc_max_brightness
= val
;
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
;
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;
968 /* we cannot get real brightness */
969 sc
->sc_lcd_inited
|= BRIGHTNESS_INITED
;
976 ite8181_init_contrast(struct ite8181_softc
*sc
, int inattach
)
980 if (sc
->sc_lcd_inited
&CONTRAST_INITED
)
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
;
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",
995 sc
->sc_contrast
= val
;
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;
1009 /* we cannot get real contrast */
1010 sc
->sc_lcd_inited
|= CONTRAST_INITED
;
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
;
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
;