Home | History | Annotate | Line # | Download | only in dev
ite8181.c revision 1.17
      1  1.17    itojun /*	$NetBSD: ite8181.c,v 1.17 2002/08/06 22:53:37 itojun Exp $	*/
      2   1.1      sato 
      3   1.1      sato /*-
      4   1.8      sato  * Copyright (c) 2000,2001 SATO Kazumi
      5   1.1      sato  * All rights reserved.
      6   1.1      sato  *
      7   1.1      sato  * Redistribution and use in source and binary forms, with or without
      8   1.1      sato  * modification, are permitted provided that the following conditions
      9   1.1      sato  * are met:
     10   1.1      sato  * 1. Redistributions of source code must retain the above copyright
     11   1.1      sato  *    notice, this list of conditions and the following disclaimer.
     12   1.1      sato  * 2. Redistributions in binary form must reproduce the above copyright
     13   1.1      sato  *    notice, this list of conditions and the following disclaimer in the
     14   1.1      sato  *    documentation and/or other materials provided with the distribution.
     15   1.1      sato  *
     16   1.1      sato  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
     17   1.1      sato  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     18   1.1      sato  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     19   1.1      sato  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
     20   1.1      sato  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     21   1.1      sato  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     22   1.1      sato  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     23   1.1      sato  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     24   1.1      sato  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     25   1.1      sato  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     26   1.1      sato  * SUCH DAMAGE.
     27   1.1      sato  *
     28   1.1      sato  */
     29   1.1      sato 
     30   1.1      sato #include <sys/param.h>
     31   1.1      sato #include <sys/kernel.h>
     32   1.1      sato #include <sys/device.h>
     33   1.1      sato #include <sys/systm.h>
     34   1.1      sato #include <sys/boot_flag.h>
     35   1.2      sato #include <sys/buf.h>
     36   1.1      sato 
     37   1.1      sato #include <uvm/uvm_extern.h>
     38   1.1      sato 
     39   1.1      sato #include <dev/wscons/wsconsio.h>
     40   1.1      sato 
     41   1.1      sato #include <machine/bootinfo.h>
     42   1.1      sato #include <machine/bus.h>
     43   1.1      sato #include <machine/autoconf.h>
     44   1.1      sato #include <machine/config_hook.h>
     45   1.1      sato #include <machine/platid.h>
     46   1.1      sato #include <machine/platid_mask.h>
     47   1.1      sato 
     48   1.1      sato #include <hpcmips/dev/ite8181reg.h>
     49   1.1      sato #include <hpcmips/dev/ite8181var.h>
     50   1.1      sato #include "bivideo.h"
     51   1.1      sato #if NBIVIDEO > 0
     52   1.7       uch #include <dev/hpc/bivideovar.h>
     53   1.1      sato #endif
     54   1.7       uch #include <dev/hpc/hpccmapvar.h>
     55   1.1      sato 
     56   1.1      sato #define ITE8181DEBUG
     57   1.1      sato #ifdef ITE8181DEBUG
     58   1.1      sato #ifndef ITE8181DEBUG_CONF
     59   1.1      sato #define ITE8181DEBUG_CONF 0
     60   1.1      sato #endif
     61   1.1      sato int	ite8181_debug = ITE8181DEBUG_CONF;
     62   1.1      sato #define	DPRINTF(arg)     if (ite8181_debug) printf arg
     63   1.1      sato #define	DPRINTFN(n, arg) if (ite8181_debug > (n)) printf arg
     64   1.1      sato #define	VPRINTF(arg)     if (bootverbose || ite8181_debug) printf arg
     65   1.1      sato #define	VPRINTFN(n, arg) if (bootverbose || ite8181_debug > (n)) printf arg
     66   1.1      sato #else
     67   1.1      sato #define	DPRINTF(arg)
     68   1.1      sato #define DPRINTFN(n, arg)
     69   1.1      sato #define	VPRINTF(arg)     if (bootverbose) printf arg
     70   1.1      sato #define	VPRINTFN(n, arg) if (bootverbose) printf arg
     71   1.1      sato #endif
     72   1.1      sato 
     73   1.1      sato #ifndef ITE8181_LCD_CONTROL_ENABLE
     74   1.1      sato int ite8181_lcd_control_disable = 1;
     75   1.1      sato #else /* ITE8181_LCD_CONTROL_ENABLE */
     76   1.1      sato int ite8181_lcd_control_disable = 0;
     77   1.1      sato #endif /* ITE8181_LCD_CONTROL_ENABLE */
     78   1.1      sato 
     79   1.2      sato #define ITE8181_WINCE_CMAP
     80   1.2      sato 
     81   1.2      sato /*
     82   1.2      sato  * XXX:
     83   1.2      sato  * IBM WorkPad z50 power unit has too weak power.
     84   1.2      sato  * So we must wait too many times to access some device
     85   1.2      sato  * after LCD panel and BackLight on.
     86   1.2      sato  * Currently delay is not enough ??? FIXME
     87   1.2      sato  */
     88   1.2      sato #ifndef ITE8181_LCD_ON_SELF_DELAY
     89   1.3      sato #define ITE8181_LCD_ON_SELF_DELAY 1000
     90   1.2      sato #endif /* ITE8181_LCD_ON__SELF_DELAY */
     91   1.2      sato #ifndef ITE8181_LCD_ON_DELAY
     92   1.2      sato #define ITE8181_LCD_ON_DELAY 2000
     93   1.2      sato #endif /* ITE8181_LCD_ON_DELAY */
     94   1.2      sato int ite8181_lcd_on_self_delay = ITE8181_LCD_ON_SELF_DELAY; /* msec */
     95   1.2      sato int ite8181_lcd_on_delay = ITE8181_LCD_ON_DELAY; /* msec */
     96   1.2      sato 
     97   1.1      sato #define MSEC	1000
     98   1.1      sato /*
     99   1.1      sato  * function prototypes
    100   1.1      sato  */
    101  1.15       uch static void	ite8181_config_write_4(bus_space_tag_t, bus_space_handle_t,
    102  1.15       uch 		    int, int);
    103  1.15       uch static int	ite8181_config_read_4(bus_space_tag_t, bus_space_handle_t,
    104  1.15       uch 		    int);
    105  1.15       uch static void	ite8181_gui_write_4(struct ite8181_softc *, int, int);
    106  1.15       uch static int	ite8181_gui_read_4(struct ite8181_softc *, int);
    107  1.15       uch 
    108  1.15       uch static void	ite8181_gui_write_1(struct ite8181_softc *, int, int);
    109  1.15       uch static int	ite8181_gui_read_1(struct ite8181_softc *, int);
    110  1.15       uch 
    111  1.15       uch static void	ite8181_graphics_write_1(struct ite8181_softc *, int, int);
    112  1.15       uch static int	ite8181_graphics_read_1(struct ite8181_softc *, int);
    113  1.15       uch 
    114  1.15       uch static void	ite8181_ema_write_1(struct ite8181_softc *, int, int);
    115  1.15       uch static int	ite8181_ema_read_1(struct ite8181_softc *, int);
    116  1.15       uch 
    117  1.15       uch static void	ite8181_power(int, void *);
    118  1.15       uch static int	ite8181_hardpower(void *, int, long, void *);
    119  1.15       uch static int	ite8181_fbinit(struct hpcfb_fbconf *);
    120  1.15       uch static int	ite8181_ioctl(void *, u_long, caddr_t, int, struct proc *);
    121  1.15       uch static paddr_t	ite8181_mmap(void *, off_t offset, int);
    122  1.15       uch static void	ite8181_erase_cursor(struct ite8181_softc *);
    123  1.15       uch static int	ite8181_lcd_power(struct ite8181_softc *, int);
    124  1.15       uch 
    125  1.15       uch static void	ite8181_update_powerstate(struct ite8181_softc *, int);
    126  1.15       uch void	ite8181_init_backlight(struct ite8181_softc *, int);
    127  1.15       uch void	ite8181_init_brightness(struct ite8181_softc *, int);
    128  1.15       uch void	ite8181_init_contrast(struct ite8181_softc *, int);
    129  1.15       uch void	ite8181_set_brightness(struct ite8181_softc *, int);
    130  1.15       uch void	ite8181_set_contrast(struct ite8181_softc *, int);
    131   1.8      sato 
    132   1.1      sato /*
    133   1.1      sato  * static variables
    134   1.1      sato  */
    135   1.1      sato struct hpcfb_accessops ite8181_ha = {
    136   1.1      sato 	ite8181_ioctl, ite8181_mmap
    137   1.1      sato };
    138   1.1      sato 
    139   1.1      sato inline int
    140  1.15       uch ite8181_config_read_4(bus_space_tag_t iot, bus_space_handle_t ioh,
    141  1.15       uch     int byteoffset)
    142   1.1      sato {
    143  1.15       uch 
    144  1.15       uch 	return (bus_space_read_4(iot, ioh, ITE8181_CONF_OFFSET + byteoffset));
    145   1.1      sato }
    146   1.1      sato 
    147   1.1      sato inline void
    148  1.15       uch ite8181_config_write_4(bus_space_tag_t iot, bus_space_handle_t ioh,
    149  1.15       uch     int byteoffset, int data)
    150   1.1      sato {
    151  1.15       uch 
    152   1.1      sato 	bus_space_write_4(iot, ioh, ITE8181_CONF_OFFSET + byteoffset, data);
    153   1.1      sato }
    154   1.1      sato 
    155   1.1      sato inline int
    156  1.15       uch ite8181_gui_read_4(struct ite8181_softc *sc, int byteoffset)
    157   1.1      sato {
    158  1.15       uch 
    159  1.15       uch 	return (bus_space_read_4(sc->sc_iot, sc->sc_ioh,
    160  1.15       uch 	    sc->sc_gba + byteoffset));
    161   1.1      sato }
    162   1.1      sato 
    163   1.1      sato inline void
    164  1.15       uch ite8181_gui_write_4(struct ite8181_softc *sc, int byteoffset, int data)
    165   1.1      sato {
    166  1.15       uch 
    167  1.15       uch 	bus_space_write_4(sc->sc_iot, sc->sc_ioh, sc->sc_gba + byteoffset,
    168  1.15       uch 	    data);
    169   1.1      sato }
    170   1.1      sato 
    171   1.1      sato inline int
    172  1.15       uch ite8181_gui_read_1(struct ite8181_softc *sc, int byteoffset)
    173   1.1      sato {
    174  1.15       uch 
    175  1.15       uch 	return (bus_space_read_1(sc->sc_iot, sc->sc_ioh,
    176  1.15       uch 	    sc->sc_gba + byteoffset));
    177   1.1      sato }
    178   1.1      sato 
    179   1.1      sato inline void
    180  1.15       uch ite8181_gui_write_1(struct ite8181_softc *sc, int byteoffset, int data)
    181   1.1      sato {
    182  1.15       uch 
    183  1.15       uch 	bus_space_write_1(sc->sc_iot, sc->sc_ioh, sc->sc_gba + byteoffset,
    184  1.15       uch 	    data);
    185   1.1      sato }
    186   1.1      sato 
    187   1.1      sato inline int
    188  1.15       uch ite8181_graphics_read_1(struct ite8181_softc *sc, int byteoffset)
    189   1.1      sato {
    190  1.15       uch 
    191  1.15       uch 	return (bus_space_read_1(sc->sc_iot, sc->sc_ioh,
    192  1.15       uch 	    sc->sc_sba + byteoffset));
    193   1.1      sato }
    194   1.1      sato 
    195   1.1      sato inline void
    196  1.15       uch ite8181_graphics_write_1(struct ite8181_softc *sc, int byteoffset, int data)
    197   1.1      sato {
    198  1.15       uch 
    199  1.15       uch 	bus_space_write_1(sc->sc_iot, sc->sc_ioh, sc->sc_sba + byteoffset,
    200  1.15       uch 	    data);
    201   1.1      sato }
    202   1.1      sato 
    203   1.1      sato inline int
    204  1.15       uch ite8181_ema_read_1(struct ite8181_softc *sc, int byteoffset)
    205   1.1      sato {
    206  1.15       uch 
    207   1.1      sato 	ite8181_graphics_write_1(sc, ITE8181_EMA_EXAX, byteoffset);
    208  1.15       uch 	return (ite8181_graphics_read_1(sc, ITE8181_EMA_EXADATA));
    209   1.1      sato }
    210   1.1      sato 
    211   1.1      sato inline void
    212  1.15       uch ite8181_ema_write_1(struct ite8181_softc *sc, int byteoffset, int data)
    213   1.1      sato {
    214  1.15       uch 
    215   1.1      sato 	ite8181_graphics_write_1(sc, ITE8181_EMA_EXAX, byteoffset);
    216   1.1      sato 	ite8181_graphics_write_1(sc, ITE8181_EMA_EXADATA, data);
    217   1.1      sato }
    218   1.1      sato 
    219   1.1      sato int
    220  1.15       uch ite8181_probe(bus_space_tag_t iot, bus_space_handle_t ioh)
    221   1.1      sato {
    222   1.1      sato 	unsigned long regval;
    223   1.1      sato 
    224   1.1      sato #if NBIVIDEO > 0
    225  1.15       uch 	if (bivideo_dont_attach)  /* some video driver already attached */
    226   1.1      sato 		return (0);
    227   1.1      sato #endif /* NBIVIDEO > 0 */
    228   1.1      sato 
    229   1.1      sato 	regval = ite8181_config_read_4(iot, ioh, ITE8181_ID);
    230   1.1      sato 	VPRINTF(("ite8181_probe: vendor id=%04lx product id=%04lx\n",
    231  1.15       uch 	    regval & 0xffff, (regval >> 16) & 0xffff));
    232   1.1      sato 	if (regval != ((ITE8181_PRODUCT_ID << 16) | ITE8181_VENDER_ID))
    233   1.1      sato 		return (0);
    234   1.1      sato 
    235   1.1      sato 	return (1);
    236   1.1      sato }
    237   1.1      sato 
    238   1.1      sato void
    239  1.15       uch ite8181_attach(struct ite8181_softc *sc)
    240   1.1      sato {
    241   1.1      sato 	unsigned long regval;
    242   1.1      sato 	struct hpcfb_attach_args ha;
    243   1.1      sato 	int console = (bootinfo->bi_cnuse & BI_CNUSE_SERIAL) ? 0 : 1;
    244   1.1      sato 
    245   1.6      sato 	printf(": ");
    246   1.6      sato 	if (ite8181_fbinit(&sc->sc_fbconf) != 0) {
    247   1.6      sato 		/* just return so that hpcfb will not be attached */
    248   1.6      sato 		return;
    249   1.6      sato 	}
    250   1.6      sato 
    251   1.1      sato 	regval = ite8181_config_read_4(sc->sc_iot, sc->sc_ioh, ITE8181_CLASS);
    252   1.6      sato 	printf("ITE8181 Rev.%02lx", regval & ITE8181_REV_MASK);
    253   1.6      sato 	if (console) {
    254   1.6      sato 		printf(", console");
    255   1.6      sato 	}
    256   1.6      sato 	printf("\n");
    257   1.6      sato 	printf("%s: framebuffer address: 0x%08lx\n",
    258  1.15       uch 	    sc->sc_dev.dv_xname, (u_long)bootinfo->fb_addr);
    259  1.10      sato 	if (ite8181_lcd_control_disable)
    260  1.10      sato 		printf("%s: ite8181 lcd coontrol is DISABLED.\n",
    261  1.15       uch 		    sc->sc_dev.dv_xname);
    262   1.1      sato 
    263   1.1      sato 	/* set base offsets */
    264   1.1      sato 	sc->sc_mba = ite8181_config_read_4(sc->sc_iot, sc->sc_ioh, ITE8181_MBA);
    265   1.1      sato 	DPRINTFN(1, ("ite8181: Memory base offset %08x\n", sc->sc_mba));
    266   1.1      sato 	sc->sc_gba = ite8181_config_read_4(sc->sc_iot, sc->sc_ioh, ITE8181_GBA);
    267   1.1      sato 	DPRINTFN(1, ("ite8181: GUI base offset %08x\n", sc->sc_gba));
    268   1.1      sato 	sc->sc_sba = ite8181_config_read_4(sc->sc_iot, sc->sc_ioh, ITE8181_SBA);
    269   1.1      sato 	DPRINTFN(1, ("ite8181: Graphics base offset %08x\n", sc->sc_sba));
    270   1.1      sato 
    271   1.1      sato 	/* assume lcd is on */
    272   1.1      sato 	sc->sc_lcd = 1;
    273  1.11      sato 	/* erase wince cursor */
    274  1.11      sato 	ite8181_erase_cursor(sc);
    275   1.1      sato 
    276   1.1      sato 	/* Add a power hook to power saving */
    277   1.1      sato 	sc->sc_powerhook = powerhook_establish(ite8181_power, sc);
    278   1.1      sato 	if (sc->sc_powerhook == NULL)
    279   1.1      sato 		printf("%s: WARNING: unable to establish power hook\n",
    280  1.15       uch 		    sc->sc_dev.dv_xname);
    281   1.1      sato 
    282   1.1      sato 	/* Add a hard power hook to power saving */
    283   1.1      sato 	sc->sc_hardpowerhook = config_hook(CONFIG_HOOK_PMEVENT,
    284  1.15       uch 	    CONFIG_HOOK_PMEVENT_HARDPOWER,
    285  1.15       uch 	    CONFIG_HOOK_SHARE,
    286  1.15       uch 	    ite8181_hardpower, sc);
    287   1.1      sato 	if (sc->sc_hardpowerhook == NULL)
    288   1.1      sato 		printf("%s: WARNING: unable to establish hard power hook\n",
    289  1.15       uch 		    sc->sc_dev.dv_xname);
    290   1.1      sato 
    291   1.8      sato 	/* initialize backlight brightness and lcd contrast */
    292  1.11      sato 	sc->sc_lcd_inited = 0;
    293  1.11      sato 	ite8181_init_brightness(sc, 1);
    294  1.11      sato 	ite8181_init_contrast(sc, 1);
    295  1.11      sato 	ite8181_init_backlight(sc, 1);
    296   1.8      sato 
    297   1.1      sato 	if (console && hpcfb_cnattach(&sc->sc_fbconf) != 0) {
    298   1.1      sato 		panic("ite8181_attach: can't init fb console");
    299   1.1      sato 	}
    300   1.1      sato 
    301   1.1      sato 	ha.ha_console = console;
    302   1.1      sato 	ha.ha_accessops = &ite8181_ha;
    303   1.1      sato 	ha.ha_accessctx = sc;
    304   1.1      sato 	ha.ha_curfbconf = 0;
    305   1.1      sato 	ha.ha_nfbconf = 1;
    306   1.1      sato 	ha.ha_fbconflist = &sc->sc_fbconf;
    307   1.1      sato 	ha.ha_curdspconf = 0;
    308   1.1      sato 	ha.ha_ndspconf = 1;
    309   1.1      sato 	ha.ha_dspconflist = &sc->sc_dspconf;
    310   1.1      sato 
    311   1.1      sato 	config_found(&sc->sc_dev, &ha, hpcfbprint);
    312   1.1      sato 
    313   1.1      sato #if NBIVIDEO > 0
    314   1.1      sato 	/*
    315   1.1      sato 	 * bivideo is no longer need
    316   1.1      sato 	 */
    317   1.1      sato 	bivideo_dont_attach = 1;
    318   1.1      sato #endif /* NBIVIDEO > 0 */
    319   1.1      sato }
    320   1.1      sato 
    321  1.15       uch int
    322  1.15       uch ite8181_lcd_power(struct ite8181_softc *sc, int on)
    323   1.1      sato {
    324   1.1      sato 	int lcd_p;
    325   1.1      sato 	int lcd_s;
    326   1.1      sato 	int lcd_seq;
    327   1.1      sato 	int loop = 10;
    328   1.1      sato 
    329   1.1      sato 	if (ite8181_lcd_control_disable) {
    330   1.1      sato 		VPRINTF(("ite8171_lcd_control_disable!: %s\n", on?"on":"off"));
    331   1.1      sato 		return 0;
    332   1.1      sato 	}
    333   1.1      sato 
    334   1.1      sato 	if (sc->sc_lcd != on) {
    335   1.1      sato 		ite8181_ema_write_1(sc, ITE8181_EMA_ENABLEEMA,
    336  1.15       uch 		    ITE8181_EMA_ENABLEPASS);
    337   1.1      sato 		lcd_p = ite8181_ema_read_1(sc, ITE8181_EMA_LCDPOWER);
    338   1.1      sato 		lcd_s = ite8181_ema_read_1(sc, ITE8181_EMA_LCDPOWERSTAT);
    339   1.1      sato 		lcd_seq = ite8181_ema_read_1(sc, ITE8181_EMA_LCDPOWERSEQ);
    340   1.1      sato 		DPRINTFN(1,("ite8181_lcd_power(%d)< p=%x, s=%x, seq=%x\n",
    341  1.15       uch 		    on,
    342  1.15       uch 		    lcd_p, lcd_s, lcd_seq));
    343   1.1      sato 		if (on) {
    344   1.1      sato 			sc->sc_lcd = 1;
    345   1.1      sato 			lcd_seq |= (ITE8181_PUP0|ITE8181_PUP1|ITE8181_PUP2);
    346  1.15       uch 			ite8181_ema_write_1(sc, ITE8181_EMA_LCDPOWERSEQ,
    347  1.15       uch 			    lcd_seq);
    348   1.1      sato 			lcd_p &= ~ITE8181_LCDSTANDBY;
    349   1.1      sato 			ite8181_ema_write_1(sc, ITE8181_EMA_LCDPOWER, lcd_p);
    350   1.1      sato 			/*
    351   1.1      sato 			 * XXX:
    352   1.1      sato 			 * IBM WorkPad z50 power unit has too weak power.
    353   1.1      sato 			 * So we must wait too many times to access self device
    354   1.1      sato 			 * after LCD panel and BackLight on.
    355   1.1      sato 			 * Currently delay is not enough ??? FIXME
    356   1.1      sato 			 */
    357   1.2      sato 			delay(ite8181_lcd_on_self_delay*MSEC);
    358   1.1      sato 			while (loop--) {
    359  1.15       uch 				lcd_p = ite8181_ema_read_1(sc,
    360  1.15       uch 				    ITE8181_EMA_LCDPOWER);
    361  1.15       uch 				lcd_s = ite8181_ema_read_1(sc,
    362  1.15       uch 				    ITE8181_EMA_LCDPOWERSTAT);
    363  1.15       uch 				lcd_seq = ite8181_ema_read_1(sc,
    364  1.15       uch 				    ITE8181_EMA_LCDPOWERSEQ);
    365  1.15       uch 				DPRINTFN(1,("ite8181_lcd_power(%d)%d| p=%x,"
    366  1.15       uch 				    " s=%x, seq=%x\n", on, loop, lcd_p, lcd_s,
    367  1.15       uch 				    lcd_seq));
    368  1.15       uch 				/*
    369  1.15       uch 				 *  XXX the states which are not described
    370  1.15       uch 				 *  XXX in manual.
    371  1.15       uch 				 */
    372   1.1      sato 				if (!(lcd_s&ITE8181_LCDPSTANDBY) &&
    373  1.15       uch 				    !(lcd_s&ITE8181_LCDPUP) &&
    374  1.15       uch 				    (lcd_s&ITE8181_LCDPON))
    375   1.1      sato 					break;
    376   1.1      sato 				delay(100);
    377   1.1      sato 			}
    378   1.1      sato 			lcd_s |= ITE8181_PPTOBEON;
    379  1.15       uch 			ite8181_ema_write_1(sc, ITE8181_EMA_LCDPOWERSTAT,
    380  1.15       uch 			    lcd_s);
    381   1.1      sato 		} else {
    382   1.1      sato 			sc->sc_lcd = 0;
    383   1.1      sato 			lcd_p |= ITE8181_LCDSTANDBY;
    384   1.1      sato 			ite8181_ema_write_1(sc, ITE8181_EMA_LCDPOWER, lcd_p);
    385   1.1      sato 			while (loop--) {
    386  1.15       uch 				lcd_p = ite8181_ema_read_1(sc,
    387  1.15       uch 				    ITE8181_EMA_LCDPOWER);
    388  1.15       uch 				lcd_s = ite8181_ema_read_1(sc,
    389  1.15       uch 				    ITE8181_EMA_LCDPOWERSTAT);
    390  1.15       uch 				lcd_seq = ite8181_ema_read_1(sc,
    391  1.15       uch 				    ITE8181_EMA_LCDPOWERSEQ);
    392  1.15       uch 				DPRINTFN(1,("ite8181_lcd_power(%d)%d| p=%x,"
    393  1.15       uch 				    " s=%x, seq=%x\n", on, loop, lcd_p, lcd_s,
    394  1.15       uch 				    lcd_seq));
    395  1.15       uch 				/*
    396  1.15       uch 				 * XXX the states which are not described
    397  1.15       uch 				 * XXX in manual.
    398  1.15       uch 				 */
    399   1.1      sato 				if ((lcd_s&ITE8181_LCDPSTANDBY) &&
    400  1.15       uch 				    !(lcd_s&ITE8181_LCDPDOWN) &&
    401  1.15       uch 				    !(lcd_s&ITE8181_LCDPON))
    402   1.1      sato 					break;
    403   1.1      sato 				delay(100);
    404   1.1      sato 			}
    405   1.1      sato 			lcd_s &= ~ITE8181_PPTOBEON;
    406  1.15       uch 			ite8181_ema_write_1(sc, ITE8181_EMA_LCDPOWERSTAT,
    407  1.15       uch 			    lcd_s);
    408   1.1      sato 		}
    409   1.1      sato 		DPRINTFN(1,("ite8181_lcd_power(%d)> p=%x, s=%x, seq=%x\n",
    410  1.15       uch 		    on,
    411  1.15       uch 		    ite8181_ema_read_1(sc, ITE8181_EMA_LCDPOWER),
    412  1.15       uch 		    ite8181_ema_read_1(sc, ITE8181_EMA_LCDPOWERSTAT),
    413  1.15       uch 		    ite8181_ema_read_1(sc, ITE8181_EMA_LCDPOWERSEQ)));
    414   1.1      sato 		ite8181_ema_write_1(sc, ITE8181_EMA_ENABLEEMA,
    415  1.15       uch 		    ITE8181_EMA_DISABLEPASS);
    416   1.1      sato 	}
    417   1.1      sato 	return 0;
    418   1.1      sato }
    419   1.1      sato 
    420   1.1      sato static void
    421  1.15       uch ite8181_erase_cursor(struct ite8181_softc *sc)
    422   1.1      sato {
    423   1.1      sato 	ite8181_gui_write_1(sc, ITE8181_GUI_C1C, 0); /* Cursor 1 Control Reg. */
    424   1.1      sato 	/* other ? */
    425   1.1      sato }
    426   1.1      sato 
    427   1.8      sato static void
    428  1.15       uch ite8181_update_powerstate(struct ite8181_softc *sc, int updates)
    429   1.8      sato {
    430   1.8      sato 	if (updates & PWRSTAT_LCD)
    431   1.8      sato 		config_hook_call(CONFIG_HOOK_POWERCONTROL,
    432   1.8      sato 		    CONFIG_HOOK_POWERCONTROL_LCD,
    433   1.9      sato 		    (void*)!(sc->sc_powerstate &
    434  1.15       uch 			(PWRSTAT_VIDEOOFF|PWRSTAT_SUSPEND)));
    435   1.8      sato 
    436   1.8      sato 	if (updates & PWRSTAT_BACKLIGHT)
    437   1.8      sato 		config_hook_call(CONFIG_HOOK_POWERCONTROL,
    438   1.8      sato 		    CONFIG_HOOK_POWERCONTROL_LCDLIGHT,
    439   1.9      sato 		    (void*)(!(sc->sc_powerstate &
    440  1.15       uch 			(PWRSTAT_VIDEOOFF|PWRSTAT_SUSPEND)) &&
    441  1.15       uch 			(sc->sc_powerstate & PWRSTAT_BACKLIGHT)));
    442   1.8      sato }
    443   1.8      sato 
    444   1.1      sato static void
    445  1.15       uch ite8181_power(int why, void *arg)
    446   1.1      sato {
    447  1.10      sato         struct ite8181_softc *sc = arg;
    448  1.10      sato 
    449  1.10      sato 	switch (why) {
    450  1.10      sato 	case PWR_STANDBY:
    451  1.10      sato 		sc->sc_powerstate |= PWRSTAT_SUSPEND;
    452  1.10      sato 		ite8181_update_powerstate(sc, PWRSTAT_ALL);
    453  1.10      sato 		break;
    454  1.10      sato 	case PWR_SUSPEND:
    455  1.10      sato 		sc->sc_powerstate |= PWRSTAT_SUSPEND;
    456  1.10      sato 		ite8181_update_powerstate(sc, PWRSTAT_ALL);
    457  1.10      sato 		break;
    458  1.10      sato 	case PWR_RESUME:
    459  1.10      sato 		sc->sc_powerstate &= ~PWRSTAT_SUSPEND;
    460  1.10      sato 		ite8181_update_powerstate(sc, PWRSTAT_ALL);
    461  1.10      sato 		break;
    462  1.10      sato 	}
    463   1.1      sato }
    464   1.1      sato 
    465   1.1      sato static int
    466  1.15       uch ite8181_hardpower(void *ctx, int type, long id, void *msg)
    467   1.1      sato {
    468   1.1      sato 	struct ite8181_softc *sc = ctx;
    469   1.1      sato 	int why = (int)msg;
    470   1.1      sato 
    471   1.1      sato 	switch (why) {
    472   1.1      sato 	case PWR_STANDBY:
    473   1.1      sato 		/* ite8181_lcd_power(sc, 0); */
    474   1.1      sato 		delay(MSEC);
    475   1.1      sato 		break;
    476   1.1      sato 	case PWR_SUSPEND:
    477   1.1      sato 		ite8181_lcd_power(sc, 0);
    478   1.1      sato 		delay(MSEC);
    479   1.1      sato 		break;
    480   1.1      sato 	case PWR_RESUME:
    481   1.1      sato 		delay(MSEC);
    482   1.1      sato 		ite8181_lcd_power(sc, 1);
    483   1.1      sato 		/*
    484   1.1      sato 		 * XXX:
    485   1.1      sato 		 * IBM WorkPad z50 power unit has too weak power.
    486   1.1      sato 		 * So we must wait too many times to access other devices
    487   1.1      sato 		 * after LCD panel and BackLight on.
    488   1.1      sato 		 */
    489   1.2      sato 		delay(ite8181_lcd_on_delay*MSEC);
    490   1.1      sato 		break;
    491   1.1      sato 	}
    492   1.1      sato 
    493   1.1      sato 	/*
    494   1.1      sato 	 * you should wait until the
    495   1.1      sato 	 * power state transit sequence will end.
    496   1.1      sato 	 */
    497   1.1      sato 
    498   1.1      sato 	return (0);
    499   1.1      sato }
    500   1.1      sato 
    501   1.1      sato static int
    502  1.15       uch ite8181_fbinit(struct hpcfb_fbconf *fb)
    503   1.1      sato {
    504   1.1      sato 
    505   1.1      sato 	/*
    506   1.1      sato 	 * get fb settings from bootinfo
    507   1.1      sato 	 */
    508   1.1      sato 	if (bootinfo == NULL ||
    509   1.1      sato 	    bootinfo->fb_addr == 0 ||
    510   1.1      sato 	    bootinfo->fb_line_bytes == 0 ||
    511   1.1      sato 	    bootinfo->fb_width == 0 ||
    512   1.1      sato 	    bootinfo->fb_height == 0) {
    513  1.13    toshii 		printf("no frame buffer information.\n");
    514   1.1      sato 		return (-1);
    515   1.1      sato 	}
    516   1.1      sato 
    517   1.1      sato 	/* zero fill */
    518   1.1      sato 	bzero(fb, sizeof(*fb));
    519   1.1      sato 
    520   1.1      sato 	fb->hf_conf_index	= 0;	/* configuration index		*/
    521   1.1      sato 	fb->hf_nconfs		= 1;   	/* how many configurations	*/
    522   1.1      sato 	strcpy(fb->hf_name, "built-in video");
    523   1.1      sato 					/* frame buffer name		*/
    524   1.1      sato 	strcpy(fb->hf_conf_name, "default");
    525   1.1      sato 					/* configuration name		*/
    526   1.1      sato 	fb->hf_height		= bootinfo->fb_height;
    527   1.1      sato 	fb->hf_width		= bootinfo->fb_width;
    528   1.4  takemura 	fb->hf_baseaddr		= (u_long)bootinfo->fb_addr;
    529   1.4  takemura 	fb->hf_offset		= (u_long)bootinfo->fb_addr -
    530  1.15       uch 	    mips_ptob(mips_btop(bootinfo->fb_addr));
    531   1.1      sato 					/* frame buffer start offset   	*/
    532   1.1      sato 	fb->hf_bytes_per_line	= bootinfo->fb_line_bytes;
    533   1.1      sato 	fb->hf_nplanes		= 1;
    534   1.1      sato 	fb->hf_bytes_per_plane	= bootinfo->fb_height *
    535  1.15       uch 	    bootinfo->fb_line_bytes;
    536   1.1      sato 
    537   1.1      sato 	fb->hf_access_flags |= HPCFB_ACCESS_BYTE;
    538   1.1      sato 	fb->hf_access_flags |= HPCFB_ACCESS_WORD;
    539   1.1      sato 	fb->hf_access_flags |= HPCFB_ACCESS_DWORD;
    540   1.1      sato 
    541   1.1      sato 	switch (bootinfo->fb_type) {
    542   1.1      sato 		/*
    543   1.1      sato 		 * gray scale
    544   1.1      sato 		 */
    545   1.1      sato 	case BIFB_D2_M2L_3:
    546   1.1      sato 	case BIFB_D2_M2L_3x2:
    547   1.1      sato 		fb->hf_access_flags |= HPCFB_ACCESS_REVERSE;
    548   1.1      sato 		/* fall through */
    549   1.1      sato 	case BIFB_D2_M2L_0:
    550   1.1      sato 	case BIFB_D2_M2L_0x2:
    551   1.1      sato 		fb->hf_class = HPCFB_CLASS_GRAYSCALE;
    552   1.1      sato 		fb->hf_access_flags |= HPCFB_ACCESS_STATIC;
    553   1.1      sato 		fb->hf_pack_width = 8;
    554   1.1      sato 		fb->hf_pixels_per_pack = 4;
    555   1.1      sato 		fb->hf_pixel_width = 2;
    556   1.5      sato 		fb->hf_class_data_length = sizeof(struct hf_gray_tag);
    557   1.5      sato 		fb->hf_u.hf_gray.hf_flags = 0;	/* reserved for future use */
    558   1.5      sato 		break;
    559   1.5      sato 
    560   1.5      sato 	case BIFB_D4_M2L_F:
    561   1.5      sato 	case BIFB_D4_M2L_Fx2:
    562   1.5      sato 		fb->hf_access_flags |= HPCFB_ACCESS_REVERSE;
    563   1.5      sato 		/* fall through */
    564   1.5      sato 	case BIFB_D4_M2L_0:
    565   1.5      sato 	case BIFB_D4_M2L_0x2:
    566   1.5      sato 		fb->hf_class = HPCFB_CLASS_GRAYSCALE;
    567   1.5      sato 		fb->hf_access_flags |= HPCFB_ACCESS_STATIC;
    568   1.5      sato 		fb->hf_pack_width = 8;
    569   1.5      sato 		fb->hf_pixels_per_pack = 2;
    570   1.5      sato 		fb->hf_pixel_width = 4;
    571   1.1      sato 		fb->hf_class_data_length = sizeof(struct hf_gray_tag);
    572   1.1      sato 		fb->hf_u.hf_gray.hf_flags = 0;	/* reserved for future use */
    573   1.1      sato 		break;
    574   1.1      sato 
    575   1.1      sato 		/*
    576   1.1      sato 		 * indexed color
    577   1.1      sato 		 */
    578   1.1      sato 	case BIFB_D8_FF:
    579   1.1      sato 		fb->hf_access_flags |= HPCFB_ACCESS_REVERSE;
    580   1.1      sato 		/* fall through */
    581   1.1      sato 	case BIFB_D8_00:
    582   1.1      sato 		fb->hf_class = HPCFB_CLASS_INDEXCOLOR;
    583   1.1      sato 		fb->hf_access_flags |= HPCFB_ACCESS_STATIC;
    584   1.1      sato 		fb->hf_pack_width = 8;
    585   1.1      sato 		fb->hf_pixels_per_pack = 1;
    586   1.1      sato 		fb->hf_pixel_width = 8;
    587   1.1      sato 		fb->hf_class_data_length = sizeof(struct hf_indexed_tag);
    588   1.1      sato 		fb->hf_u.hf_indexed.hf_flags = 0; /* reserved for future use */
    589   1.1      sato 		break;
    590   1.1      sato 
    591   1.1      sato 		/*
    592   1.1      sato 		 * RGB color
    593   1.1      sato 		 */
    594   1.1      sato 	case BIFB_D16_FFFF:
    595   1.1      sato 		fb->hf_access_flags |= HPCFB_ACCESS_REVERSE;
    596   1.1      sato 		/* fall through */
    597   1.1      sato 	case BIFB_D16_0000:
    598   1.1      sato 		fb->hf_class = HPCFB_CLASS_RGBCOLOR;
    599   1.1      sato 		fb->hf_access_flags |= HPCFB_ACCESS_STATIC;
    600  1.14  takemura 		fb->hf_order_flags = HPCFB_REVORDER_BYTE;
    601   1.1      sato 		fb->hf_pack_width = 16;
    602   1.1      sato 		fb->hf_pixels_per_pack = 1;
    603   1.1      sato 		fb->hf_pixel_width = 16;
    604   1.1      sato 
    605   1.1      sato 		fb->hf_class_data_length = sizeof(struct hf_rgb_tag);
    606   1.1      sato 		fb->hf_u.hf_rgb.hf_flags = 0;	/* reserved for future use */
    607   1.1      sato 
    608   1.1      sato 		fb->hf_u.hf_rgb.hf_red_width = 5;
    609   1.1      sato 		fb->hf_u.hf_rgb.hf_red_shift = 11;
    610   1.1      sato 		fb->hf_u.hf_rgb.hf_green_width = 6;
    611   1.1      sato 		fb->hf_u.hf_rgb.hf_green_shift = 5;
    612   1.1      sato 		fb->hf_u.hf_rgb.hf_blue_width = 5;
    613   1.1      sato 		fb->hf_u.hf_rgb.hf_blue_shift = 0;
    614   1.1      sato 		fb->hf_u.hf_rgb.hf_alpha_width = 0;
    615   1.1      sato 		fb->hf_u.hf_rgb.hf_alpha_shift = 0;
    616   1.1      sato 		break;
    617   1.1      sato 
    618   1.1      sato 	default:
    619   1.1      sato 		printf("unknown type (=%d).\n", bootinfo->fb_type);
    620   1.1      sato 		return (-1);
    621   1.1      sato 		break;
    622   1.1      sato 	}
    623   1.1      sato 
    624   1.1      sato 	return (0); /* no error */
    625   1.1      sato }
    626   1.1      sato 
    627   1.1      sato int
    628   1.1      sato ite8181_ioctl(v, cmd, data, flag, p)
    629   1.1      sato 	void *v;
    630   1.1      sato 	u_long cmd;
    631   1.1      sato 	caddr_t data;
    632   1.1      sato 	int flag;
    633   1.1      sato 	struct proc *p;
    634   1.1      sato {
    635   1.1      sato 	struct ite8181_softc *sc = (struct ite8181_softc *)v;
    636   1.1      sato 	struct hpcfb_fbconf *fbconf;
    637   1.1      sato 	struct hpcfb_dspconf *dspconf;
    638   1.1      sato 	struct wsdisplay_cmap *cmap;
    639   1.8      sato 	struct wsdisplay_param *dispparam;
    640   1.1      sato 
    641   1.1      sato 	switch (cmd) {
    642   1.1      sato 	case WSDISPLAYIO_GETCMAP:
    643   1.1      sato 		cmap = (struct wsdisplay_cmap*)data;
    644   1.1      sato 
    645   1.1      sato 		if (sc->sc_fbconf.hf_class != HPCFB_CLASS_INDEXCOLOR ||
    646   1.1      sato 		    sc->sc_fbconf.hf_pack_width != 8 ||
    647   1.1      sato 		    256 <= cmap->index ||
    648  1.17    itojun 		    256 - cmap->index < cmap->count)
    649   1.1      sato 			return (EINVAL);
    650   1.1      sato 
    651   1.1      sato 		if (!uvm_useracc(cmap->red, cmap->count, B_WRITE) ||
    652   1.1      sato 		    !uvm_useracc(cmap->green, cmap->count, B_WRITE) ||
    653   1.1      sato 		    !uvm_useracc(cmap->blue, cmap->count, B_WRITE))
    654   1.1      sato 			return (EFAULT);
    655   1.1      sato 
    656   1.2      sato #ifdef ITE8181_WINCE_CMAP
    657   1.1      sato 		copyout(&bivideo_cmap_r[cmap->index], cmap->red, cmap->count);
    658   1.1      sato 		copyout(&bivideo_cmap_g[cmap->index], cmap->green,cmap->count);
    659   1.1      sato 		copyout(&bivideo_cmap_b[cmap->index], cmap->blue, cmap->count);
    660   1.1      sato 		return (0);
    661   1.2      sato #else /* ITE8181_WINCE_CMAP */
    662   1.2      sato 		return EINVAL;
    663   1.2      sato #endif /* ITE8181_WINCE_CMAP */
    664   1.1      sato 
    665   1.1      sato 	case WSDISPLAYIO_PUTCMAP:
    666   1.1      sato 		/*
    667   1.1      sato 		 * This driver can't set color map.
    668   1.1      sato 		 */
    669   1.1      sato 		return (EINVAL);
    670   1.9      sato 
    671   1.9      sato 	case WSDISPLAYIO_SVIDEO:
    672   1.9      sato 		if (*(int *)data == WSDISPLAYIO_VIDEO_OFF)
    673   1.9      sato 			sc->sc_powerstate |= PWRSTAT_VIDEOOFF;
    674   1.9      sato 		else
    675   1.9      sato 			sc->sc_powerstate &= ~PWRSTAT_VIDEOOFF;
    676   1.9      sato 		ite8181_update_powerstate(sc, PWRSTAT_ALL);
    677   1.9      sato 		return 0;
    678   1.9      sato 
    679   1.9      sato 	case WSDISPLAYIO_GVIDEO:
    680   1.9      sato 		*(int *)data = (sc->sc_powerstate&PWRSTAT_VIDEOOFF) ?
    681  1.15       uch 		    WSDISPLAYIO_VIDEO_OFF:WSDISPLAYIO_VIDEO_ON;
    682   1.9      sato 		return 0;
    683   1.1      sato 
    684   1.8      sato 
    685   1.8      sato 	case WSDISPLAYIO_GETPARAM:
    686   1.8      sato 		dispparam = (struct wsdisplay_param*)data;
    687   1.8      sato 		switch (dispparam->param) {
    688   1.8      sato 		case WSDISPLAYIO_PARAM_BACKLIGHT:
    689  1.11      sato 			VPRINTF(("ite8181_ioctl: GET:BACKLIGHT\n"));
    690  1.11      sato 			ite8181_init_brightness(sc, 0);
    691  1.11      sato 			ite8181_init_backlight(sc, 0);
    692  1.11      sato 			VPRINTF(("ite8181_ioctl: GET:(real)BACKLIGHT %d\n",
    693  1.15       uch 			    (sc->sc_powerstate&PWRSTAT_BACKLIGHT)? 1: 0));
    694   1.8      sato 			dispparam->min = 0;
    695   1.8      sato 			dispparam->max = 1;
    696   1.8      sato 			if (sc->sc_max_brightness > 0)
    697  1.15       uch 				dispparam->curval =
    698  1.15       uch 				    sc->sc_brightness > 0 ? 1: 0;
    699   1.8      sato 			else
    700   1.8      sato 				dispparam->curval =
    701  1.15       uch 				    (sc->sc_powerstate & PWRSTAT_BACKLIGHT)
    702  1.15       uch 				    ? 1: 0;
    703  1.11      sato 			VPRINTF(("ite8181_ioctl: GET:BACKLIGHT:%d(%s)\n",
    704  1.15       uch 			    dispparam->curval,
    705  1.15       uch 			    sc->sc_max_brightness > 0? "brightness": "light"));
    706   1.8      sato 			return 0;
    707   1.8      sato 			break;
    708   1.8      sato 		case WSDISPLAYIO_PARAM_CONTRAST:
    709  1.11      sato 			VPRINTF(("ite8181_ioctl: GET:CONTRAST\n"));
    710  1.11      sato 			ite8181_init_contrast(sc, 0);
    711   1.8      sato 			if (sc->sc_max_contrast > 0) {
    712   1.8      sato 				dispparam->min = 0;
    713   1.8      sato 				dispparam->max = sc->sc_max_contrast;
    714   1.8      sato 				dispparam->curval = sc->sc_contrast;
    715  1.15       uch 				VPRINTF(("ite8181_ioctl: GET:CONTRAST max=%d,"
    716  1.15       uch 				    " current=%d\n", sc->sc_max_contrast,
    717  1.15       uch 				    sc->sc_contrast));
    718   1.8      sato 				return 0;
    719   1.8      sato 			} else {
    720  1.15       uch 				VPRINTF(("ite8181_ioctl: "
    721  1.15       uch 				    "GET:CONTRAST EINVAL\n"));
    722   1.8      sato 				return (EINVAL);
    723   1.8      sato 			}
    724   1.8      sato 			break;
    725   1.8      sato 		case WSDISPLAYIO_PARAM_BRIGHTNESS:
    726  1.11      sato 			VPRINTF(("ite8181_ioctl: GET:BRIGHTNESS\n"));
    727  1.11      sato 			ite8181_init_brightness(sc, 0);
    728   1.8      sato 			if (sc->sc_max_brightness > 0) {
    729   1.8      sato 				dispparam->min = 0;
    730   1.8      sato 				dispparam->max = sc->sc_max_brightness;
    731   1.8      sato 				dispparam->curval = sc->sc_brightness;
    732  1.15       uch 				VPRINTF(("ite8181_ioctl: GET:BRIGHTNESS"
    733  1.15       uch 				    " max=%d, current=%d\n",
    734  1.15       uch 				    sc->sc_max_brightness, sc->sc_brightness));
    735   1.8      sato 				return 0;
    736   1.8      sato 			} else {
    737  1.15       uch 				VPRINTF(("ite8181_ioctl: GET:BRIGHTNESS"
    738  1.15       uch 				    " EINVAL\n"));
    739   1.8      sato 				return (EINVAL);
    740   1.8      sato 			}
    741   1.8      sato 			return (EINVAL);
    742   1.8      sato 		default:
    743   1.8      sato 			return (EINVAL);
    744   1.8      sato 		}
    745   1.8      sato 		return (0);
    746   1.8      sato 
    747   1.8      sato 	case WSDISPLAYIO_SETPARAM:
    748   1.8      sato 		dispparam = (struct wsdisplay_param*)data;
    749   1.8      sato 		switch (dispparam->param) {
    750   1.8      sato 		case WSDISPLAYIO_PARAM_BACKLIGHT:
    751  1.11      sato 			VPRINTF(("ite8181_ioctl: SET:BACKLIGHT\n"));
    752   1.8      sato 			if (dispparam->curval < 0 ||
    753   1.8      sato 			    1 < dispparam->curval)
    754   1.8      sato 				return (EINVAL);
    755  1.11      sato 			ite8181_init_brightness(sc, 0);
    756  1.15       uch 			VPRINTF(("ite8181_ioctl: SET:max brightness=%d\n",
    757  1.15       uch 			    sc->sc_max_brightness));
    758   1.8      sato 			if (sc->sc_max_brightness > 0) { /* dimmer */
    759   1.8      sato 				if (dispparam->curval == 0){
    760  1.15       uch 					sc->sc_brightness_save =
    761  1.15       uch 					    sc->sc_brightness;
    762  1.15       uch 					ite8181_set_brightness(sc, 0);/* min */
    763   1.8      sato 				} else {
    764   1.8      sato 					if (sc->sc_brightness_save == 0)
    765  1.15       uch 						sc->sc_brightness_save =
    766  1.15       uch 						    sc->sc_max_brightness;
    767  1.15       uch 					ite8181_set_brightness(sc,
    768  1.15       uch 					    sc->sc_brightness_save);
    769   1.8      sato 				}
    770  1.15       uch 				VPRINTF(("ite8181_ioctl: SET:BACKLIGHT:"
    771  1.15       uch 				    "brightness=%d\n", sc->sc_brightness));
    772   1.8      sato 			} else { /* off */
    773   1.8      sato 				if (dispparam->curval == 0)
    774   1.8      sato 					sc->sc_powerstate &= ~PWRSTAT_BACKLIGHT;
    775   1.8      sato 				else
    776   1.8      sato 					sc->sc_powerstate |= PWRSTAT_BACKLIGHT;
    777  1.15       uch 				VPRINTF(("ite8181_ioctl: SET:BACKLIGHT:"
    778  1.15       uch 				    "powerstate %d\n",
    779  1.15       uch 				    (sc->sc_powerstate & PWRSTAT_BACKLIGHT)
    780  1.15       uch 				    ? 1 : 0));
    781  1.15       uch 				ite8181_update_powerstate(sc,
    782  1.15       uch 				    PWRSTAT_BACKLIGHT);
    783  1.11      sato 				VPRINTF(("ite8181_ioctl: SET:BACKLIGHT:%d\n",
    784  1.15       uch 				    (sc->sc_powerstate & PWRSTAT_BACKLIGHT)
    785  1.15       uch 				    ? 1 : 0));
    786   1.8      sato 			}
    787   1.8      sato 			return 0;
    788   1.8      sato 			break;
    789   1.8      sato 		case WSDISPLAYIO_PARAM_CONTRAST:
    790  1.11      sato 			VPRINTF(("ite8181_ioctl: SET:CONTRAST\n"));
    791  1.11      sato 			ite8181_init_contrast(sc, 0);
    792   1.8      sato 			if (dispparam->curval < 0 ||
    793   1.8      sato 			    sc->sc_max_contrast < dispparam->curval)
    794   1.8      sato 				return (EINVAL);
    795   1.8      sato 			if (sc->sc_max_contrast > 0) {
    796   1.8      sato 				int org = sc->sc_contrast;
    797  1.15       uch 				ite8181_set_contrast(sc, dispparam->curval);
    798  1.15       uch 				VPRINTF(("ite8181_ioctl: SET:CONTRAST"
    799  1.15       uch 				    " org=%d, current=%d\n", org,
    800  1.15       uch 				    sc->sc_contrast));
    801   1.8      sato 				return 0;
    802   1.8      sato 			} else {
    803  1.15       uch 				VPRINTF(("ite8181_ioctl: SET:CONTRAST"
    804  1.15       uch 				    " EINVAL\n"));
    805   1.8      sato 				return (EINVAL);
    806   1.8      sato 			}
    807   1.8      sato 			break;
    808   1.8      sato 		case WSDISPLAYIO_PARAM_BRIGHTNESS:
    809  1.11      sato 			VPRINTF(("ite8181_ioctl: SET:BRIGHTNESS\n"));
    810  1.11      sato 			ite8181_init_brightness(sc, 0);
    811   1.8      sato 			if (dispparam->curval < 0 ||
    812   1.8      sato 			    sc->sc_max_brightness < dispparam->curval)
    813   1.8      sato 				return (EINVAL);
    814   1.8      sato 			if (sc->sc_max_brightness > 0) {
    815   1.8      sato 				int org = sc->sc_brightness;
    816  1.15       uch 				ite8181_set_brightness(sc, dispparam->curval);
    817  1.15       uch 				VPRINTF(("ite8181_ioctl: SET:BRIGHTNESS"
    818  1.15       uch 				    " org=%d, current=%d\n", org,
    819  1.15       uch 				    sc->sc_brightness));
    820   1.8      sato 				return 0;
    821   1.8      sato 			} else {
    822  1.15       uch 				VPRINTF(("ite8181_ioctl: SET:BRIGHTNESS"
    823  1.15       uch 				    " EINVAL\n"));
    824   1.8      sato 				return (EINVAL);
    825   1.8      sato 			}
    826   1.8      sato 			break;
    827   1.8      sato 		default:
    828   1.8      sato 			return (EINVAL);
    829   1.8      sato 		}
    830   1.8      sato 		return (0);
    831   1.8      sato 
    832   1.1      sato 	case HPCFBIO_GCONF:
    833   1.1      sato 		fbconf = (struct hpcfb_fbconf *)data;
    834   1.1      sato 		if (fbconf->hf_conf_index != 0 &&
    835   1.1      sato 		    fbconf->hf_conf_index != HPCFB_CURRENT_CONFIG) {
    836   1.1      sato 			return (EINVAL);
    837   1.1      sato 		}
    838   1.1      sato 		*fbconf = sc->sc_fbconf;	/* structure assignment */
    839   1.1      sato 		return (0);
    840   1.1      sato 	case HPCFBIO_SCONF:
    841   1.1      sato 		fbconf = (struct hpcfb_fbconf *)data;
    842   1.1      sato 		if (fbconf->hf_conf_index != 0 &&
    843   1.1      sato 		    fbconf->hf_conf_index != HPCFB_CURRENT_CONFIG) {
    844   1.1      sato 			return (EINVAL);
    845   1.1      sato 		}
    846   1.1      sato 		/*
    847   1.1      sato 		 * nothing to do because we have only one configration
    848   1.1      sato 		 */
    849   1.1      sato 		return (0);
    850   1.1      sato 	case HPCFBIO_GDSPCONF:
    851   1.1      sato 		dspconf = (struct hpcfb_dspconf *)data;
    852   1.1      sato 		if ((dspconf->hd_unit_index != 0 &&
    853  1.15       uch 		    dspconf->hd_unit_index != HPCFB_CURRENT_UNIT) ||
    854   1.1      sato 		    (dspconf->hd_conf_index != 0 &&
    855  1.15       uch 			dspconf->hd_conf_index != HPCFB_CURRENT_CONFIG)) {
    856   1.1      sato 			return (EINVAL);
    857   1.1      sato 		}
    858   1.1      sato 		*dspconf = sc->sc_dspconf;	/* structure assignment */
    859   1.1      sato 		return (0);
    860   1.1      sato 	case HPCFBIO_SDSPCONF:
    861   1.1      sato 		dspconf = (struct hpcfb_dspconf *)data;
    862   1.1      sato 		if ((dspconf->hd_unit_index != 0 &&
    863  1.15       uch 		    dspconf->hd_unit_index != HPCFB_CURRENT_UNIT) ||
    864   1.1      sato 		    (dspconf->hd_conf_index != 0 &&
    865  1.15       uch 			dspconf->hd_conf_index != HPCFB_CURRENT_CONFIG)) {
    866   1.1      sato 			return (EINVAL);
    867   1.1      sato 		}
    868   1.1      sato 		/*
    869   1.1      sato 		 * nothing to do
    870   1.1      sato 		 * because we have only one unit and one configration
    871   1.1      sato 		 */
    872   1.1      sato 		return (0);
    873   1.1      sato 	case HPCFBIO_GOP:
    874   1.1      sato 	case HPCFBIO_SOP:
    875   1.1      sato 		/*
    876   1.1      sato 		 * curently not implemented...
    877   1.1      sato 		 */
    878   1.1      sato 		return (EINVAL);
    879   1.1      sato 	}
    880   1.1      sato 
    881  1.16    atatat 	return (EPASSTHROUGH);
    882   1.1      sato }
    883   1.1      sato 
    884   1.1      sato paddr_t
    885  1.15       uch ite8181_mmap(void *ctx, off_t offset, int prot)
    886   1.1      sato {
    887   1.1      sato 	struct ite8181_softc *sc = (struct ite8181_softc *)ctx;
    888   1.1      sato 
    889   1.1      sato 	if (offset < 0 ||
    890   1.1      sato 	    (sc->sc_fbconf.hf_bytes_per_plane +
    891   1.1      sato 		sc->sc_fbconf.hf_offset) <  offset)
    892   1.1      sato 		return -1;
    893   1.1      sato 
    894   1.4  takemura 	return mips_btop((u_long)bootinfo->fb_addr + offset);
    895   1.8      sato }
    896   1.8      sato 
    897  1.11      sato 
    898   1.8      sato void
    899  1.15       uch ite8181_init_backlight(struct ite8181_softc *sc, int inattach)
    900   1.8      sato {
    901   1.8      sato 	int val = -1;
    902   1.8      sato 
    903  1.11      sato 	if (sc->sc_lcd_inited&BACKLIGHT_INITED)
    904  1.11      sato 		return;
    905  1.11      sato 
    906  1.10      sato 	if (config_hook_call(CONFIG_HOOK_GET,
    907  1.15       uch 	    CONFIG_HOOK_POWER_LCDLIGHT, &val) != -1) {
    908  1.11      sato 		/* we can get real light state */
    909  1.11      sato 		VPRINTF(("ite8181_init_backlight: real backlight=%d\n", val));
    910  1.10      sato 		if (val == 0)
    911  1.10      sato 			sc->sc_powerstate &= ~PWRSTAT_BACKLIGHT;
    912  1.10      sato 		else
    913  1.10      sato 			sc->sc_powerstate |= PWRSTAT_BACKLIGHT;
    914  1.11      sato 		sc->sc_lcd_inited |= BACKLIGHT_INITED;
    915  1.11      sato 	} else if (inattach) {
    916  1.11      sato 		/*
    917  1.11      sato 		   we cannot get real light state in attach time
    918  1.11      sato 		   because light device not yet attached.
    919  1.11      sato 		   we will retry in !inattach.
    920  1.11      sato 		   temporary assume light is on.
    921  1.15       uch 		*/
    922  1.10      sato 		sc->sc_powerstate |= PWRSTAT_BACKLIGHT;
    923  1.11      sato 	} else {
    924  1.11      sato 		/* we cannot get real light state, so work by myself state */
    925  1.11      sato 		sc->sc_lcd_inited |= BACKLIGHT_INITED;
    926  1.11      sato 	}
    927   1.8      sato }
    928   1.8      sato 
    929   1.8      sato void
    930  1.15       uch ite8181_init_brightness(struct ite8181_softc *sc, int inattach)
    931   1.8      sato {
    932   1.8      sato 	int val = -1;
    933   1.8      sato 
    934  1.11      sato 	if (sc->sc_lcd_inited&BRIGHTNESS_INITED)
    935  1.11      sato 		return;
    936  1.11      sato 
    937  1.11      sato 	VPRINTF(("ite8181_init_brightness\n"));
    938   1.8      sato 	if (config_hook_call(CONFIG_HOOK_GET,
    939  1.15       uch 	    CONFIG_HOOK_BRIGHTNESS_MAX, &val) != -1) {
    940  1.11      sato 		/* we can get real brightness max */
    941  1.15       uch 		VPRINTF(("ite8181_init_brightness: real brightness max=%d\n",
    942  1.15       uch 		    val));
    943  1.11      sato 		sc->sc_max_brightness = val;
    944  1.11      sato 		val = -1;
    945  1.11      sato 		if (config_hook_call(CONFIG_HOOK_GET,
    946  1.15       uch 		    CONFIG_HOOK_BRIGHTNESS, &val) != -1) {
    947  1.11      sato 			/* we can get real brightness */
    948  1.15       uch 			VPRINTF(("ite8181_init_brightness:"
    949  1.15       uch 			    " real brightness=%d\n", val));
    950  1.11      sato 			sc->sc_brightness_save = sc->sc_brightness = val;
    951  1.11      sato 		} else {
    952  1.11      sato 			sc->sc_brightness_save =
    953  1.15       uch 			    sc->sc_brightness = sc->sc_max_brightness;
    954  1.11      sato 		}
    955  1.11      sato 		sc->sc_lcd_inited |= BRIGHTNESS_INITED;
    956  1.11      sato 	} else if (inattach) {
    957  1.11      sato 		/*
    958  1.11      sato 		   we cannot get real brightness in attach time
    959  1.11      sato 		   because brightness device not yet attached.
    960  1.11      sato 		   we will retry in !inattach.
    961  1.15       uch 		*/
    962  1.11      sato 		sc->sc_max_brightness = -1;
    963  1.11      sato 		sc->sc_brightness = -1;
    964  1.11      sato 		sc->sc_brightness_save = -1;
    965  1.11      sato 	} else {
    966  1.11      sato 		/* we cannot get real brightness */
    967  1.11      sato 		sc->sc_lcd_inited |= BRIGHTNESS_INITED;
    968   1.8      sato 	}
    969  1.11      sato 
    970   1.8      sato 	return;
    971   1.8      sato }
    972   1.8      sato 
    973   1.8      sato void
    974  1.15       uch ite8181_init_contrast(struct ite8181_softc *sc, int inattach)
    975   1.8      sato {
    976   1.8      sato 	int val = -1;
    977   1.8      sato 
    978  1.11      sato 	if (sc->sc_lcd_inited&CONTRAST_INITED)
    979  1.11      sato 		return;
    980  1.11      sato 
    981  1.11      sato 	VPRINTF(("ite8181_init_contrast\n"));
    982   1.8      sato 	if (config_hook_call(CONFIG_HOOK_GET,
    983  1.15       uch 	    CONFIG_HOOK_CONTRAST_MAX, &val) != -1) {
    984  1.11      sato 		/* we can get real contrast max */
    985  1.11      sato 		VPRINTF(("ite8181_init_contrast: real contrast max=%d\n", val));
    986   1.8      sato 		sc->sc_max_contrast = val;
    987  1.11      sato 		val = -1;
    988  1.11      sato 		if (config_hook_call(CONFIG_HOOK_GET,
    989  1.15       uch 		    CONFIG_HOOK_CONTRAST, &val) != -1) {
    990  1.11      sato 			/* we can get real contrast */
    991  1.15       uch 			VPRINTF(("ite8181_init_contrast: real contrast=%d\n",
    992  1.15       uch 			    val));
    993  1.11      sato 			sc->sc_contrast = val;
    994  1.11      sato 		} else {
    995  1.11      sato 			sc->sc_contrast = sc->sc_max_contrast;
    996  1.11      sato 		}
    997  1.11      sato 		sc->sc_lcd_inited |= CONTRAST_INITED;
    998  1.11      sato 	} else if (inattach) {
    999  1.11      sato 		/*
   1000  1.11      sato 		   we cannot get real contrast in attach time
   1001  1.11      sato 		   because contrast device not yet attached.
   1002  1.11      sato 		   we will retry in !inattach.
   1003  1.15       uch 		*/
   1004  1.11      sato 		sc->sc_max_contrast = -1;
   1005  1.11      sato 		sc->sc_contrast = -1;
   1006  1.11      sato 	} else {
   1007  1.11      sato 		/* we cannot get real contrast */
   1008  1.11      sato 		sc->sc_lcd_inited |= CONTRAST_INITED;
   1009   1.8      sato 	}
   1010  1.11      sato 
   1011   1.8      sato 	return;
   1012   1.8      sato }
   1013  1.11      sato 
   1014   1.8      sato 
   1015   1.8      sato void
   1016  1.15       uch ite8181_set_brightness(struct ite8181_softc *sc, int val)
   1017   1.8      sato {
   1018  1.15       uch 
   1019   1.8      sato 	sc->sc_brightness = val;
   1020   1.8      sato 
   1021   1.8      sato 	config_hook_call(CONFIG_HOOK_SET, CONFIG_HOOK_BRIGHTNESS, &val);
   1022   1.8      sato 	if (config_hook_call(CONFIG_HOOK_GET,
   1023  1.15       uch 	    CONFIG_HOOK_BRIGHTNESS, &val) != -1) {
   1024   1.8      sato 		sc->sc_brightness = val;
   1025   1.8      sato 	}
   1026   1.8      sato }
   1027   1.8      sato 
   1028   1.8      sato void
   1029  1.15       uch ite8181_set_contrast(struct ite8181_softc *sc, int val)
   1030   1.8      sato {
   1031  1.15       uch 
   1032   1.8      sato 	sc->sc_contrast = val;
   1033   1.8      sato 
   1034   1.8      sato 	config_hook_call(CONFIG_HOOK_SET, CONFIG_HOOK_CONTRAST, &val);
   1035   1.8      sato 	if (config_hook_call(CONFIG_HOOK_GET,
   1036  1.15       uch 	    CONFIG_HOOK_CONTRAST, &val) != -1) {
   1037   1.8      sato 		sc->sc_contrast = val;
   1038   1.8      sato 	}
   1039   1.1      sato }
   1040