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