Home | History | Annotate | Line # | Download | only in dev
mq200.c revision 1.20
      1  1.20  takemura /*	$NetBSD: mq200.c,v 1.20 2002/04/14 06:07:41 takemura Exp $	*/
      2   1.1  takemura 
      3   1.1  takemura /*-
      4  1.13  takemura  * Copyright (c) 2000, 2001 TAKEMURA Shin
      5   1.1  takemura  * All rights reserved.
      6   1.1  takemura  *
      7   1.1  takemura  * Redistribution and use in source and binary forms, with or without
      8   1.1  takemura  * modification, are permitted provided that the following conditions
      9   1.1  takemura  * are met:
     10   1.1  takemura  * 1. Redistributions of source code must retain the above copyright
     11   1.1  takemura  *    notice, this list of conditions and the following disclaimer.
     12   1.1  takemura  * 2. Redistributions in binary form must reproduce the above copyright
     13   1.1  takemura  *    notice, this list of conditions and the following disclaimer in the
     14   1.1  takemura  *    documentation and/or other materials provided with the distribution.
     15   1.1  takemura  * 3. The name of the author may not be used to endorse or promote products
     16   1.1  takemura  *    derived from this software without specific prior written permission.
     17   1.1  takemura  *
     18   1.1  takemura  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     19   1.1  takemura  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     20   1.1  takemura  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     21   1.1  takemura  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     22   1.1  takemura  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     23   1.1  takemura  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     24   1.1  takemura  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     25   1.1  takemura  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     26   1.1  takemura  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     27   1.1  takemura  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     28   1.1  takemura  * SUCH DAMAGE.
     29   1.1  takemura  *
     30   1.1  takemura  */
     31   1.1  takemura 
     32   1.1  takemura #include <sys/param.h>
     33   1.1  takemura #include <sys/kernel.h>
     34   1.1  takemura #include <sys/device.h>
     35   1.1  takemura #include <sys/systm.h>
     36   1.2      sato #include <sys/reboot.h>
     37   1.1  takemura 
     38   1.1  takemura #include <uvm/uvm_extern.h>
     39   1.1  takemura 
     40   1.1  takemura #include <dev/wscons/wsconsio.h>
     41   1.1  takemura 
     42   1.1  takemura #include <machine/bootinfo.h>
     43   1.1  takemura #include <machine/bus.h>
     44   1.1  takemura #include <machine/autoconf.h>
     45   1.1  takemura #include <machine/config_hook.h>
     46   1.1  takemura #include <machine/platid.h>
     47   1.1  takemura #include <machine/platid_mask.h>
     48   1.1  takemura 
     49  1.13  takemura #include "opt_mq200.h"
     50   1.1  takemura #include <hpcmips/dev/mq200reg.h>
     51   1.1  takemura #include <hpcmips/dev/mq200var.h>
     52  1.13  takemura #include <hpcmips/dev/mq200priv.h>
     53  1.13  takemura 
     54   1.2      sato #include "bivideo.h"
     55   1.2      sato #if NBIVIDEO > 0
     56   1.9       uch #include <dev/hpc/bivideovar.h>
     57   1.2      sato #endif
     58   1.1  takemura 
     59   1.1  takemura /*
     60   1.1  takemura  * function prototypes
     61   1.1  takemura  */
     62  1.18       uch static void	mq200_power(int, void *);
     63  1.18       uch static int	mq200_hardpower(void *, int, long, void *);
     64  1.18       uch static int	mq200_fbinit(struct hpcfb_fbconf *);
     65  1.18       uch static int	mq200_ioctl(void *, u_long, caddr_t, int, struct proc *);
     66  1.18       uch static paddr_t	mq200_mmap(void *, off_t offset, int);
     67  1.18       uch static void	mq200_update_powerstate(struct mq200_softc *, int);
     68  1.18       uch void	mq200_init_backlight(struct mq200_softc *, int);
     69  1.18       uch void	mq200_init_brightness(struct mq200_softc *, int);
     70  1.18       uch void	mq200_init_contrast(struct mq200_softc *, int);
     71  1.18       uch void	mq200_set_brightness(struct mq200_softc *, int);
     72  1.18       uch void	mq200_set_contrast(struct mq200_softc *, int);
     73   1.1  takemura 
     74   1.1  takemura /*
     75   1.1  takemura  * static variables
     76   1.1  takemura  */
     77   1.1  takemura struct hpcfb_accessops mq200_ha = {
     78   1.1  takemura 	mq200_ioctl, mq200_mmap
     79   1.1  takemura };
     80   1.1  takemura 
     81  1.13  takemura #ifdef MQ200_DEBUG
     82  1.13  takemura int mq200_debug = MQ200DEBUG_CONF;
     83  1.13  takemura #endif
     84  1.13  takemura 
     85   1.1  takemura int
     86  1.18       uch mq200_probe(bus_space_tag_t iot, bus_space_handle_t ioh)
     87   1.1  takemura {
     88   1.1  takemura 	unsigned long regval;
     89   1.1  takemura 
     90   1.2      sato #if NBIVIDEO > 0
     91   1.2      sato 	if (bivideo_dont_attach) /* some video driver already attached */
     92   1.2      sato 		return (0);
     93   1.2      sato #endif /* NBIVIDEO > 0 */
     94   1.2      sato 
     95   1.1  takemura 	regval = bus_space_read_4(iot, ioh, MQ200_PC00R);
     96  1.13  takemura 	VPRINTF("probe: vendor id=%04lx product id=%04lx\n",
     97  1.18       uch 	    regval & 0xffff, (regval >> 16) & 0xffff);
     98   1.1  takemura 	if (regval != ((MQ200_PRODUCT_ID << 16) | MQ200_VENDOR_ID))
     99   1.1  takemura 		return (0);
    100   1.1  takemura 
    101   1.1  takemura 	return (1);
    102   1.1  takemura }
    103   1.1  takemura 
    104   1.1  takemura void
    105  1.18       uch mq200_attach(struct mq200_softc *sc)
    106   1.1  takemura {
    107   1.1  takemura 	unsigned long regval;
    108   1.1  takemura 	struct hpcfb_attach_args ha;
    109   1.1  takemura 	int console = (bootinfo->bi_cnuse & BI_CNUSE_SERIAL) ? 0 : 1;
    110   1.1  takemura 
    111   1.8      sato 	printf(": ");
    112   1.8      sato 	if (mq200_fbinit(&sc->sc_fbconf) != 0) {
    113   1.8      sato 		/* just return so that hpcfb will not be attached */
    114   1.8      sato 		return;
    115   1.8      sato 	}
    116   1.8      sato 
    117   1.8      sato 	sc->sc_fbconf.hf_baseaddr = (u_long)bootinfo->fb_addr;
    118   1.8      sato 	sc->sc_fbconf.hf_offset	= (u_long)sc->sc_fbconf.hf_baseaddr -
    119   1.8      sato 	    MIPS_PHYS_TO_KSEG1(mips_ptob(mips_btop(sc->sc_baseaddr)));
    120  1.13  takemura 	DPRINTF("hf_baseaddr=%lx\n", sc->sc_fbconf.hf_baseaddr);
    121  1.13  takemura 	DPRINTF("hf_offset=%lx\n", sc->sc_fbconf.hf_offset);
    122   1.8      sato 
    123  1.13  takemura 	regval = mq200_read(sc, MQ200_PC08R);
    124   1.8      sato 	printf("MQ200 Rev.%02lx video controller", regval & 0xff);
    125   1.8      sato 	if (console) {
    126   1.8      sato 		printf(", console");
    127   1.8      sato 	}
    128   1.8      sato 	printf("\n");
    129   1.8      sato         printf("%s: framebuffer address: 0x%08lx\n",
    130  1.18       uch 	    sc->sc_dev.dv_xname, (u_long)bootinfo->fb_addr);
    131  1.13  takemura 
    132  1.13  takemura 	/*
    133  1.13  takemura 	 * setup registers
    134  1.13  takemura 	 */
    135  1.13  takemura 	sc->sc_flags = 0;
    136  1.13  takemura 	sc->sc_baseclock = 12288;	/* 12.288 MHz */
    137  1.13  takemura #ifdef MQ200_DEBUG
    138  1.13  takemura 	if (bootverbose) {
    139  1.13  takemura 		/* dump current setting	*/
    140  1.13  takemura 		mq200_dump_all(sc);
    141  1.13  takemura 		mq200_dump_pll(sc);
    142  1.13  takemura 	}
    143  1.13  takemura #endif
    144  1.13  takemura 	mq200_setup_regctx(sc);
    145  1.13  takemura 	mq200_mdsetup(sc);
    146  1.13  takemura 	if (sc->sc_md) {
    147  1.20  takemura 		int mode;
    148  1.20  takemura 
    149  1.20  takemura 		switch (sc->sc_fbconf.hf_pixel_width) {
    150  1.20  takemura 		case  1:	mode = MQ200_GCC_1BPP;		break;
    151  1.20  takemura 		case  2:	mode = MQ200_GCC_2BPP;		break;
    152  1.20  takemura 		case  4:	mode = MQ200_GCC_4BPP;		break;
    153  1.20  takemura 		case  8:	mode = MQ200_GCC_8BPP;		break;
    154  1.20  takemura 		case 16:	mode = MQ200_GCC_16BPP_DIRECT;	break;
    155  1.20  takemura 		default:
    156  1.20  takemura 			printf("%s: %dbpp isn't supported\n",
    157  1.20  takemura 			    sc->sc_dev.dv_xname, sc->sc_fbconf.hf_pixel_width);
    158  1.20  takemura 			return;
    159  1.20  takemura 		}
    160  1.20  takemura 
    161  1.13  takemura 		if (sc->sc_md->md_flags & MQ200_MD_HAVEFP) {
    162  1.13  takemura 			sc->sc_flags |= MQ200_SC_GC2_ENABLE;	/* FP	*/
    163  1.13  takemura 		}
    164  1.13  takemura #if MQ200_USECRT
    165  1.13  takemura 		if (sc->sc_md->md_flags & MQ200_MD_HAVECRT) {
    166  1.13  takemura 			int i;
    167  1.13  takemura 			sc->sc_flags |= MQ200_SC_GC1_ENABLE;	/* CRT	*/
    168  1.13  takemura 			for (i = 0; i < mq200_crt_nparams; i++) {
    169  1.13  takemura 				sc->sc_crt = &mq200_crt_params[i];
    170  1.13  takemura 				if (sc->sc_md->md_fp_width <=
    171  1.13  takemura 				    mq200_crt_params[i].width &&
    172  1.13  takemura 				    sc->sc_md->md_fp_height <=
    173  1.13  takemura 				    mq200_crt_params[i].height)
    174  1.13  takemura 					break;
    175  1.13  takemura 			}
    176  1.13  takemura 		}
    177  1.13  takemura #endif
    178  1.13  takemura 		mq200_setup(sc);
    179  1.13  takemura 
    180  1.13  takemura 		if (sc->sc_flags & MQ200_SC_GC2_ENABLE)	/* FP	*/
    181  1.20  takemura 			mq200_win_enable(sc, MQ200_GC2, mode,
    182  1.20  takemura 			    sc->sc_fbconf.hf_baseaddr,
    183  1.20  takemura 			    sc->sc_fbconf.hf_width, sc->sc_fbconf.hf_height,
    184  1.20  takemura 			    sc->sc_fbconf.hf_bytes_per_plane);
    185  1.13  takemura 		if (sc->sc_flags & MQ200_SC_GC1_ENABLE)	/* CRT	*/
    186  1.20  takemura 			mq200_win_enable(sc, MQ200_GC1, mode,
    187  1.20  takemura 			    sc->sc_fbconf.hf_baseaddr,
    188  1.20  takemura 			    sc->sc_fbconf.hf_width, sc->sc_fbconf.hf_height,
    189  1.20  takemura 			    sc->sc_fbconf.hf_bytes_per_plane);
    190  1.13  takemura 	}
    191  1.13  takemura #ifdef MQ200_DEBUG
    192  1.13  takemura 	if (sc->sc_md == NULL || bootverbose) {
    193  1.13  takemura 		mq200_dump_pll(sc);
    194  1.13  takemura 	}
    195  1.13  takemura #endif
    196   1.8      sato 
    197   1.1  takemura 	/* Add a power hook to power saving */
    198  1.10      sato 	sc->sc_mq200pwstate = MQ200_POWERSTATE_D0;
    199   1.1  takemura 	sc->sc_powerhook = powerhook_establish(mq200_power, sc);
    200   1.1  takemura 	if (sc->sc_powerhook == NULL)
    201   1.1  takemura 		printf("%s: WARNING: unable to establish power hook\n",
    202  1.18       uch 		    sc->sc_dev.dv_xname);
    203   1.1  takemura 
    204   1.1  takemura 	/* Add a hard power hook to power saving */
    205   1.1  takemura 	sc->sc_hardpowerhook = config_hook(CONFIG_HOOK_PMEVENT,
    206  1.18       uch 	    CONFIG_HOOK_PMEVENT_HARDPOWER,
    207  1.18       uch 	    CONFIG_HOOK_SHARE,
    208  1.18       uch 	    mq200_hardpower, sc);
    209   1.1  takemura 	if (sc->sc_hardpowerhook == NULL)
    210   1.1  takemura 		printf("%s: WARNING: unable to establish hard power hook\n",
    211  1.18       uch 		    sc->sc_dev.dv_xname);
    212   1.1  takemura 
    213  1.10      sato 	/* initialize backlight brightness and lcd contrast */
    214  1.14      sato 	sc->sc_lcd_inited = 0;
    215  1.14      sato 	mq200_init_brightness(sc, 1);
    216  1.14      sato 	mq200_init_contrast(sc, 1);
    217  1.14      sato 	mq200_init_backlight(sc, 1);
    218  1.10      sato 
    219   1.1  takemura 	if (console && hpcfb_cnattach(&sc->sc_fbconf) != 0) {
    220   1.1  takemura 		panic("mq200_attach: can't init fb console");
    221   1.1  takemura 	}
    222   1.1  takemura 
    223   1.1  takemura 	ha.ha_console = console;
    224   1.1  takemura 	ha.ha_accessops = &mq200_ha;
    225   1.1  takemura 	ha.ha_accessctx = sc;
    226   1.1  takemura 	ha.ha_curfbconf = 0;
    227   1.1  takemura 	ha.ha_nfbconf = 1;
    228   1.1  takemura 	ha.ha_fbconflist = &sc->sc_fbconf;
    229   1.1  takemura 	ha.ha_curdspconf = 0;
    230   1.1  takemura 	ha.ha_ndspconf = 1;
    231   1.1  takemura 	ha.ha_dspconflist = &sc->sc_dspconf;
    232   1.1  takemura 
    233   1.1  takemura 	config_found(&sc->sc_dev, &ha, hpcfbprint);
    234   1.1  takemura 
    235   1.2      sato #if NBIVIDEO > 0
    236   1.1  takemura 	/*
    237   1.1  takemura 	 * bivideo is no longer need
    238   1.1  takemura 	 */
    239   1.1  takemura 	bivideo_dont_attach = 1;
    240   1.2      sato #endif /* NBIVIDEO > 0 */
    241   1.1  takemura }
    242   1.1  takemura 
    243  1.10      sato static void
    244  1.18       uch mq200_update_powerstate(struct mq200_softc *sc, int updates)
    245  1.10      sato {
    246  1.12      sato 
    247  1.10      sato 	if (updates & PWRSTAT_LCD)
    248  1.10      sato 		config_hook_call(CONFIG_HOOK_POWERCONTROL,
    249  1.10      sato 		    CONFIG_HOOK_POWERCONTROL_LCD,
    250  1.11      sato 		    (void*)!(sc->sc_powerstate &
    251  1.18       uch 			(PWRSTAT_VIDEOOFF|PWRSTAT_SUSPEND)));
    252  1.10      sato 
    253  1.10      sato 	if (updates & PWRSTAT_BACKLIGHT)
    254  1.10      sato 		config_hook_call(CONFIG_HOOK_POWERCONTROL,
    255  1.10      sato 		    CONFIG_HOOK_POWERCONTROL_LCDLIGHT,
    256  1.11      sato 		    (void*)(!(sc->sc_powerstate &
    257  1.18       uch 			(PWRSTAT_VIDEOOFF|PWRSTAT_SUSPEND)) &&
    258  1.18       uch 			(sc->sc_powerstate & PWRSTAT_BACKLIGHT)));
    259  1.10      sato }
    260  1.10      sato 
    261   1.1  takemura static void
    262  1.18       uch mq200_power(int why, void *arg)
    263   1.1  takemura {
    264   1.1  takemura 	struct mq200_softc *sc = arg;
    265   1.1  takemura 
    266   1.1  takemura 	switch (why) {
    267   1.1  takemura 	case PWR_SUSPEND:
    268  1.10      sato 		sc->sc_powerstate |= PWRSTAT_SUSPEND;
    269  1.10      sato 		mq200_update_powerstate(sc, PWRSTAT_ALL);
    270   1.1  takemura 		break;
    271   1.1  takemura 	case PWR_STANDBY:
    272  1.10      sato 		sc->sc_powerstate |= PWRSTAT_SUSPEND;
    273  1.10      sato 		mq200_update_powerstate(sc, PWRSTAT_ALL);
    274   1.1  takemura 		break;
    275   1.1  takemura 	case PWR_RESUME:
    276  1.10      sato 		sc->sc_powerstate &= ~PWRSTAT_SUSPEND;
    277  1.10      sato 		mq200_update_powerstate(sc, PWRSTAT_ALL);
    278   1.1  takemura 		break;
    279   1.1  takemura 	}
    280   1.1  takemura }
    281   1.1  takemura 
    282   1.1  takemura static int
    283  1.18       uch mq200_hardpower(void *ctx, int type, long id, void *msg)
    284   1.1  takemura {
    285   1.1  takemura 	struct mq200_softc *sc = ctx;
    286   1.1  takemura 	int why = (int)msg;
    287   1.1  takemura 
    288   1.1  takemura 	switch (why) {
    289   1.1  takemura 	case PWR_SUSPEND:
    290  1.10      sato 		sc->sc_mq200pwstate = MQ200_POWERSTATE_D2;
    291   1.1  takemura 		break;
    292   1.1  takemura 	case PWR_STANDBY:
    293  1.10      sato 		sc->sc_mq200pwstate = MQ200_POWERSTATE_D3;
    294   1.1  takemura 		break;
    295   1.1  takemura 	case PWR_RESUME:
    296  1.10      sato 		sc->sc_mq200pwstate = MQ200_POWERSTATE_D0;
    297   1.1  takemura 		break;
    298   1.1  takemura 	}
    299   1.1  takemura 
    300   1.1  takemura 	bus_space_write_4(sc->sc_iot, sc->sc_ioh,
    301  1.18       uch 	    MQ200_PMCSR, sc->sc_mq200pwstate);
    302   1.1  takemura 
    303   1.1  takemura 	/*
    304   1.1  takemura 	 * you should wait until the
    305   1.1  takemura 	 * power state transit sequence will end.
    306   1.1  takemura 	 */
    307   1.1  takemura 	{
    308   1.1  takemura 		unsigned long tmp;
    309   1.1  takemura 		do {
    310   1.1  takemura 			tmp = bus_space_read_4(sc->sc_iot, sc->sc_ioh,
    311  1.18       uch 			    MQ200_PMCSR);
    312  1.10      sato 		} while ((tmp & 0x3) != (sc->sc_mq200pwstate & 0x3));
    313   1.1  takemura 		delay(100000); /* XXX */
    314   1.1  takemura 	}
    315   1.1  takemura 
    316   1.1  takemura 	return (0);
    317   1.1  takemura }
    318   1.1  takemura 
    319   1.1  takemura 
    320   1.1  takemura static int
    321  1.18       uch mq200_fbinit(struct hpcfb_fbconf *fb)
    322   1.1  takemura {
    323   1.1  takemura 
    324   1.1  takemura 	/*
    325   1.1  takemura 	 * get fb settings from bootinfo
    326   1.1  takemura 	 */
    327   1.1  takemura 	if (bootinfo == NULL ||
    328   1.1  takemura 	    bootinfo->fb_addr == 0 ||
    329   1.1  takemura 	    bootinfo->fb_line_bytes == 0 ||
    330   1.1  takemura 	    bootinfo->fb_width == 0 ||
    331   1.1  takemura 	    bootinfo->fb_height == 0) {
    332  1.16    toshii 		printf("no frame buffer information.\n");
    333   1.1  takemura 		return (-1);
    334   1.1  takemura 	}
    335   1.1  takemura 
    336   1.1  takemura 	/* zero fill */
    337   1.1  takemura 	bzero(fb, sizeof(*fb));
    338   1.1  takemura 
    339   1.1  takemura 	fb->hf_conf_index	= 0;	/* configuration index		*/
    340   1.1  takemura 	fb->hf_nconfs		= 1;   	/* how many configurations	*/
    341   1.1  takemura 	strcpy(fb->hf_name, "built-in video");
    342   1.1  takemura 					/* frame buffer name		*/
    343   1.1  takemura 	strcpy(fb->hf_conf_name, "default");
    344   1.1  takemura 					/* configuration name		*/
    345   1.1  takemura 	fb->hf_height		= bootinfo->fb_height;
    346   1.1  takemura 	fb->hf_width		= bootinfo->fb_width;
    347   1.1  takemura 	fb->hf_baseaddr		= mips_ptob(mips_btop(bootinfo->fb_addr));
    348   1.1  takemura 	fb->hf_offset		= (u_long)bootinfo->fb_addr - fb->hf_baseaddr;
    349   1.1  takemura 					/* frame buffer start offset   	*/
    350   1.1  takemura 	fb->hf_bytes_per_line	= bootinfo->fb_line_bytes;
    351   1.1  takemura 	fb->hf_nplanes		= 1;
    352   1.1  takemura 	fb->hf_bytes_per_plane	= bootinfo->fb_height *
    353  1.18       uch 	    bootinfo->fb_line_bytes;
    354   1.1  takemura 
    355   1.1  takemura 	fb->hf_access_flags |= HPCFB_ACCESS_BYTE;
    356   1.1  takemura 	fb->hf_access_flags |= HPCFB_ACCESS_WORD;
    357   1.1  takemura 	fb->hf_access_flags |= HPCFB_ACCESS_DWORD;
    358   1.1  takemura 
    359   1.1  takemura 	switch (bootinfo->fb_type) {
    360  1.20  takemura 		/*
    361  1.20  takemura 		 * monochrome
    362  1.20  takemura 		 */
    363  1.20  takemura 	case BIFB_D1_M2L_1:
    364  1.20  takemura 		fb->hf_access_flags |= HPCFB_ACCESS_REVERSE;
    365  1.20  takemura 		/* fall through */
    366  1.20  takemura 	case BIFB_D1_M2L_0:
    367  1.20  takemura 		fb->hf_class = HPCFB_CLASS_GRAYSCALE;
    368  1.20  takemura 		fb->hf_access_flags |= HPCFB_ACCESS_STATIC;
    369  1.20  takemura 		fb->hf_pack_width = 8;
    370  1.20  takemura 		fb->hf_pixels_per_pack = 8;
    371  1.20  takemura 		fb->hf_pixel_width = 1;
    372  1.20  takemura 		fb->hf_class_data_length = sizeof(struct hf_gray_tag);
    373  1.20  takemura 		fb->hf_u.hf_gray.hf_flags = 0;	/* reserved for future use */
    374  1.20  takemura 		break;
    375  1.20  takemura 
    376   1.1  takemura 		/*
    377   1.1  takemura 		 * gray scale
    378   1.1  takemura 		 */
    379   1.1  takemura 	case BIFB_D2_M2L_3:
    380   1.1  takemura 	case BIFB_D2_M2L_3x2:
    381   1.1  takemura 		fb->hf_access_flags |= HPCFB_ACCESS_REVERSE;
    382   1.1  takemura 		/* fall through */
    383   1.1  takemura 	case BIFB_D2_M2L_0:
    384   1.1  takemura 	case BIFB_D2_M2L_0x2:
    385   1.1  takemura 		fb->hf_class = HPCFB_CLASS_GRAYSCALE;
    386   1.1  takemura 		fb->hf_access_flags |= HPCFB_ACCESS_STATIC;
    387   1.1  takemura 		fb->hf_pack_width = 8;
    388   1.1  takemura 		fb->hf_pixels_per_pack = 4;
    389   1.1  takemura 		fb->hf_pixel_width = 2;
    390   1.7  takemura 		fb->hf_class_data_length = sizeof(struct hf_gray_tag);
    391   1.7  takemura 		fb->hf_u.hf_gray.hf_flags = 0;	/* reserved for future use */
    392   1.7  takemura 		break;
    393   1.7  takemura 
    394   1.7  takemura 	case BIFB_D4_M2L_F:
    395   1.7  takemura 	case BIFB_D4_M2L_Fx2:
    396   1.7  takemura 		fb->hf_access_flags |= HPCFB_ACCESS_REVERSE;
    397   1.7  takemura 		/* fall through */
    398   1.7  takemura 	case BIFB_D4_M2L_0:
    399   1.7  takemura 	case BIFB_D4_M2L_0x2:
    400   1.7  takemura 		fb->hf_class = HPCFB_CLASS_GRAYSCALE;
    401   1.7  takemura 		fb->hf_access_flags |= HPCFB_ACCESS_STATIC;
    402   1.7  takemura 		fb->hf_pack_width = 8;
    403   1.7  takemura 		fb->hf_pixels_per_pack = 2;
    404   1.7  takemura 		fb->hf_pixel_width = 4;
    405   1.1  takemura 		fb->hf_class_data_length = sizeof(struct hf_gray_tag);
    406   1.1  takemura 		fb->hf_u.hf_gray.hf_flags = 0;	/* reserved for future use */
    407   1.1  takemura 		break;
    408   1.1  takemura 
    409   1.1  takemura 		/*
    410   1.1  takemura 		 * indexed color
    411   1.1  takemura 		 */
    412   1.1  takemura 	case BIFB_D8_FF:
    413   1.1  takemura 		fb->hf_access_flags |= HPCFB_ACCESS_REVERSE;
    414   1.1  takemura 		/* fall through */
    415   1.1  takemura 	case BIFB_D8_00:
    416   1.1  takemura 		fb->hf_class = HPCFB_CLASS_INDEXCOLOR;
    417   1.1  takemura 		fb->hf_access_flags |= HPCFB_ACCESS_STATIC;
    418   1.1  takemura 		fb->hf_pack_width = 8;
    419   1.1  takemura 		fb->hf_pixels_per_pack = 1;
    420   1.1  takemura 		fb->hf_pixel_width = 8;
    421   1.1  takemura 		fb->hf_class_data_length = sizeof(struct hf_indexed_tag);
    422   1.1  takemura 		fb->hf_u.hf_indexed.hf_flags = 0; /* reserved for future use */
    423   1.1  takemura 		break;
    424   1.1  takemura 
    425   1.1  takemura 		/*
    426   1.1  takemura 		 * RGB color
    427   1.1  takemura 		 */
    428   1.1  takemura 	case BIFB_D16_FFFF:
    429   1.1  takemura 		fb->hf_access_flags |= HPCFB_ACCESS_REVERSE;
    430   1.1  takemura 		/* fall through */
    431   1.1  takemura 	case BIFB_D16_0000:
    432   1.1  takemura 		fb->hf_class = HPCFB_CLASS_RGBCOLOR;
    433   1.1  takemura 		fb->hf_access_flags |= HPCFB_ACCESS_STATIC;
    434  1.17  takemura 		fb->hf_order_flags = HPCFB_REVORDER_BYTE;
    435   1.1  takemura 		fb->hf_pack_width = 16;
    436   1.1  takemura 		fb->hf_pixels_per_pack = 1;
    437   1.1  takemura 		fb->hf_pixel_width = 16;
    438   1.1  takemura 
    439   1.1  takemura 		fb->hf_class_data_length = sizeof(struct hf_rgb_tag);
    440   1.1  takemura 		fb->hf_u.hf_rgb.hf_flags = 0;	/* reserved for future use */
    441   1.1  takemura 
    442   1.1  takemura 		fb->hf_u.hf_rgb.hf_red_width = 5;
    443   1.1  takemura 		fb->hf_u.hf_rgb.hf_red_shift = 11;
    444   1.1  takemura 		fb->hf_u.hf_rgb.hf_green_width = 6;
    445   1.1  takemura 		fb->hf_u.hf_rgb.hf_green_shift = 5;
    446   1.1  takemura 		fb->hf_u.hf_rgb.hf_blue_width = 5;
    447   1.1  takemura 		fb->hf_u.hf_rgb.hf_blue_shift = 0;
    448   1.1  takemura 		fb->hf_u.hf_rgb.hf_alpha_width = 0;
    449   1.1  takemura 		fb->hf_u.hf_rgb.hf_alpha_shift = 0;
    450   1.1  takemura 		break;
    451   1.1  takemura 
    452   1.1  takemura 	default:
    453   1.1  takemura 		printf("unknown type (=%d).\n", bootinfo->fb_type);
    454   1.1  takemura 		return (-1);
    455   1.1  takemura 		break;
    456   1.1  takemura 	}
    457   1.1  takemura 
    458   1.1  takemura 	return (0); /* no error */
    459   1.1  takemura }
    460   1.1  takemura 
    461   1.1  takemura int
    462   1.1  takemura mq200_ioctl(v, cmd, data, flag, p)
    463   1.1  takemura 	void *v;
    464   1.1  takemura 	u_long cmd;
    465   1.1  takemura 	caddr_t data;
    466   1.1  takemura 	int flag;
    467   1.1  takemura 	struct proc *p;
    468   1.1  takemura {
    469   1.1  takemura 	struct mq200_softc *sc = (struct mq200_softc *)v;
    470   1.1  takemura 	struct hpcfb_fbconf *fbconf;
    471   1.1  takemura 	struct hpcfb_dspconf *dspconf;
    472   1.1  takemura 	struct wsdisplay_cmap *cmap;
    473   1.6      sato 	struct wsdisplay_param *dispparam;
    474   1.1  takemura 
    475   1.1  takemura 	switch (cmd) {
    476   1.1  takemura 	case WSDISPLAYIO_GETCMAP:
    477   1.1  takemura 		cmap = (struct wsdisplay_cmap*)data;
    478   1.1  takemura 
    479   1.1  takemura 		if (sc->sc_fbconf.hf_class != HPCFB_CLASS_INDEXCOLOR ||
    480   1.1  takemura 		    sc->sc_fbconf.hf_pack_width != 8 ||
    481   1.1  takemura 		    256 <= cmap->index ||
    482   1.1  takemura 		    256 < (cmap->index + cmap->count))
    483   1.1  takemura 			return (EINVAL);
    484   1.1  takemura 
    485   1.1  takemura #if 0
    486   1.1  takemura 		if (!uvm_useracc(cmap->red, cmap->count, B_WRITE) ||
    487   1.1  takemura 		    !uvm_useracc(cmap->green, cmap->count, B_WRITE) ||
    488   1.1  takemura 		    !uvm_useracc(cmap->blue, cmap->count, B_WRITE))
    489   1.1  takemura 			return (EFAULT);
    490   1.1  takemura 
    491   1.1  takemura 		copyout(&bivideo_cmap_r[cmap->index], cmap->red, cmap->count);
    492   1.1  takemura 		copyout(&bivideo_cmap_g[cmap->index], cmap->green,cmap->count);
    493   1.1  takemura 		copyout(&bivideo_cmap_b[cmap->index], cmap->blue, cmap->count);
    494   1.1  takemura #endif
    495   1.1  takemura 
    496   1.1  takemura 		return (0);
    497   1.1  takemura 
    498   1.1  takemura 	case WSDISPLAYIO_PUTCMAP:
    499   1.1  takemura 		/*
    500   1.1  takemura 		 * This driver can't set color map.
    501   1.1  takemura 		 */
    502   1.1  takemura 		return (EINVAL);
    503  1.11      sato 
    504  1.11      sato 	case WSDISPLAYIO_SVIDEO:
    505  1.11      sato 		if (*(int *)data == WSDISPLAYIO_VIDEO_OFF)
    506  1.11      sato 			sc->sc_powerstate |= PWRSTAT_VIDEOOFF;
    507  1.11      sato 		else
    508  1.11      sato 			sc->sc_powerstate &= ~PWRSTAT_VIDEOOFF;
    509  1.11      sato 		mq200_update_powerstate(sc, PWRSTAT_ALL);
    510  1.11      sato 		return 0;
    511  1.11      sato 
    512  1.11      sato 	case WSDISPLAYIO_GVIDEO:
    513  1.11      sato 		*(int *)data = (sc->sc_powerstate&PWRSTAT_VIDEOOFF) ?
    514  1.18       uch 		    WSDISPLAYIO_VIDEO_OFF:WSDISPLAYIO_VIDEO_ON;
    515  1.11      sato 		return 0;
    516   1.6      sato 
    517   1.6      sato 	case WSDISPLAYIO_GETPARAM:
    518   1.6      sato 		dispparam = (struct wsdisplay_param*)data;
    519   1.6      sato 		switch (dispparam->param) {
    520   1.6      sato 		case WSDISPLAYIO_PARAM_BACKLIGHT:
    521  1.14      sato 			VPRINTF("ioctl: GET:BACKLIGHT\n");
    522  1.14      sato 			mq200_init_brightness(sc, 0);
    523  1.14      sato 			mq200_init_backlight(sc, 0);
    524  1.14      sato 			VPRINTF("ioctl: GET:(real)BACKLIGHT %d\n",
    525  1.18       uch 			    (sc->sc_powerstate&PWRSTAT_BACKLIGHT)? 1: 0);
    526  1.10      sato 			dispparam->min = 0;
    527  1.10      sato 			dispparam->max = 1;
    528  1.10      sato 			if (sc->sc_max_brightness > 0)
    529  1.18       uch 				dispparam->curval = sc->sc_brightness > 0
    530  1.18       uch 				    ? 1: 0;
    531  1.10      sato 			else
    532  1.10      sato 				dispparam->curval =
    533  1.18       uch 				    (sc->sc_powerstate&PWRSTAT_BACKLIGHT)
    534  1.18       uch 				    ? 1: 0;
    535  1.14      sato 			VPRINTF("ioctl: GET:BACKLIGHT:%d(%s)\n",
    536  1.18       uch 			    dispparam->curval,
    537  1.18       uch 			    sc->sc_max_brightness > 0? "brightness": "light");
    538  1.10      sato 			return 0;
    539  1.10      sato 			break;
    540   1.6      sato 		case WSDISPLAYIO_PARAM_CONTRAST:
    541  1.14      sato 			VPRINTF("ioctl: GET:CONTRAST\n");
    542  1.14      sato 			mq200_init_contrast(sc, 0);
    543  1.10      sato 			if (sc->sc_max_contrast > 0) {
    544  1.10      sato 				dispparam->min = 0;
    545  1.10      sato 				dispparam->max = sc->sc_max_contrast;
    546  1.10      sato 				dispparam->curval = sc->sc_contrast;
    547  1.18       uch 				VPRINTF("ioctl: GET:CONTRAST"
    548  1.18       uch 				    " max=%d, current=%d\n",
    549  1.18       uch 				    sc->sc_max_contrast, sc->sc_contrast);
    550  1.10      sato 				return 0;
    551  1.10      sato 			} else {
    552  1.14      sato 				VPRINTF("ioctl: GET:CONTRAST EINVAL\n");
    553  1.10      sato 				return (EINVAL);
    554  1.10      sato 			}
    555  1.10      sato 			break;
    556   1.6      sato 		case WSDISPLAYIO_PARAM_BRIGHTNESS:
    557  1.14      sato 			VPRINTF("ioctl: GET:BRIGHTNESS\n");
    558  1.14      sato 			mq200_init_brightness(sc, 0);
    559  1.10      sato 			if (sc->sc_max_brightness > 0) {
    560  1.10      sato 				dispparam->min = 0;
    561  1.10      sato 				dispparam->max = sc->sc_max_brightness;
    562  1.10      sato 				dispparam->curval = sc->sc_brightness;
    563  1.18       uch 				VPRINTF("ioctl: GET:BRIGHTNESS"
    564  1.18       uch 				    " max=%d, current=%d\n",
    565  1.18       uch 				    sc->sc_max_brightness, sc->sc_brightness);
    566  1.10      sato 				return 0;
    567  1.10      sato 			} else {
    568  1.14      sato 				VPRINTF("ioctl: GET:BRIGHTNESS EINVAL\n");
    569  1.10      sato 				return (EINVAL);
    570  1.10      sato 			}
    571   1.6      sato 			return (EINVAL);
    572   1.6      sato 		default:
    573   1.6      sato 			return (EINVAL);
    574   1.6      sato 		}
    575   1.6      sato 		return (0);
    576   1.6      sato 
    577   1.6      sato 	case WSDISPLAYIO_SETPARAM:
    578   1.6      sato 		dispparam = (struct wsdisplay_param*)data;
    579   1.6      sato 		switch (dispparam->param) {
    580   1.6      sato 		case WSDISPLAYIO_PARAM_BACKLIGHT:
    581  1.14      sato 			VPRINTF("ioctl: SET:BACKLIGHT\n");
    582  1.10      sato 			if (dispparam->curval < 0 ||
    583  1.10      sato 			    1 < dispparam->curval)
    584  1.10      sato 				return (EINVAL);
    585  1.14      sato 			mq200_init_brightness(sc, 0);
    586  1.18       uch 			VPRINTF("ioctl: SET:max brightness=%d\n",
    587  1.18       uch 			    sc->sc_max_brightness);
    588  1.10      sato 			if (sc->sc_max_brightness > 0) { /* dimmer */
    589  1.10      sato 				if (dispparam->curval == 0){
    590  1.18       uch 					sc->sc_brightness_save =
    591  1.18       uch 					    sc->sc_brightness;
    592  1.18       uch 					mq200_set_brightness(sc, 0); /* min */
    593  1.10      sato 				} else {
    594  1.10      sato 					if (sc->sc_brightness_save == 0)
    595  1.18       uch 						sc->sc_brightness_save =
    596  1.18       uch 						    sc->sc_max_brightness;
    597  1.18       uch 					mq200_set_brightness(sc,
    598  1.18       uch 					    sc->sc_brightness_save);
    599  1.10      sato 				}
    600  1.18       uch 				VPRINTF("ioctl: SET:BACKLIGHT:"
    601  1.18       uch 				    " brightness=%d\n", sc->sc_brightness);
    602  1.10      sato 			} else { /* off */
    603  1.10      sato 				if (dispparam->curval == 0)
    604  1.10      sato 					sc->sc_powerstate &= ~PWRSTAT_BACKLIGHT;
    605  1.10      sato 				else
    606  1.10      sato 					sc->sc_powerstate |= PWRSTAT_BACKLIGHT;
    607  1.18       uch 				VPRINTF("ioctl: SET:BACKLIGHT:"
    608  1.18       uch 				    " powerstate %d\n",
    609  1.18       uch 				    (sc->sc_powerstate & PWRSTAT_BACKLIGHT)
    610  1.18       uch 				    ? 1 : 0);
    611  1.10      sato 				mq200_update_powerstate(sc, PWRSTAT_BACKLIGHT);
    612  1.14      sato 				VPRINTF("ioctl: SET:BACKLIGHT:%d\n",
    613  1.18       uch 				    (sc->sc_powerstate & PWRSTAT_BACKLIGHT)
    614  1.18       uch 				    ? 1 : 0);
    615  1.10      sato 			}
    616  1.10      sato 			return 0;
    617  1.10      sato 			break;
    618   1.6      sato 		case WSDISPLAYIO_PARAM_CONTRAST:
    619  1.14      sato 			VPRINTF("ioctl: SET:CONTRAST\n");
    620  1.14      sato 			mq200_init_contrast(sc, 0);
    621  1.10      sato 			if (dispparam->curval < 0 ||
    622  1.10      sato 			    sc->sc_max_contrast < dispparam->curval)
    623  1.10      sato 				return (EINVAL);
    624  1.10      sato 			if (sc->sc_max_contrast > 0) {
    625  1.10      sato 				int org = sc->sc_contrast;
    626  1.18       uch 				mq200_set_contrast(sc, dispparam->curval);
    627  1.18       uch 				VPRINTF("ioctl: SET:CONTRAST"
    628  1.18       uch 				    " org=%d, current=%d\n", org,
    629  1.18       uch 				    sc->sc_contrast);
    630  1.18       uch 				VPRINTF("ioctl: SETPARAM:"
    631  1.18       uch 				    " CONTRAST org=%d, current=%d\n", org,
    632  1.18       uch 				    sc->sc_contrast);
    633  1.10      sato 				return 0;
    634  1.10      sato 			} else {
    635  1.14      sato 				VPRINTF("ioctl: SET:CONTRAST EINVAL\n");
    636  1.10      sato 				return (EINVAL);
    637  1.10      sato 			}
    638  1.10      sato 			break;
    639   1.6      sato 		case WSDISPLAYIO_PARAM_BRIGHTNESS:
    640  1.14      sato 			VPRINTF("ioctl: SET:BRIGHTNESS\n");
    641  1.14      sato 			mq200_init_brightness(sc, 0);
    642  1.10      sato 			if (dispparam->curval < 0 ||
    643  1.10      sato 			    sc->sc_max_brightness < dispparam->curval)
    644  1.10      sato 				return (EINVAL);
    645  1.10      sato 			if (sc->sc_max_brightness > 0) {
    646  1.10      sato 				int org = sc->sc_brightness;
    647  1.18       uch 				mq200_set_brightness(sc, dispparam->curval);
    648  1.18       uch 				VPRINTF("ioctl: SET:BRIGHTNESS"
    649  1.18       uch 				    " org=%d, current=%d\n", org,
    650  1.18       uch 				    sc->sc_brightness);
    651  1.10      sato 				return 0;
    652  1.10      sato 			} else {
    653  1.14      sato 				VPRINTF("ioctl: SET:BRIGHTNESS EINVAL\n");
    654  1.10      sato 				return (EINVAL);
    655  1.10      sato 			}
    656  1.10      sato 			break;
    657   1.6      sato 		default:
    658   1.6      sato 			return (EINVAL);
    659   1.6      sato 		}
    660   1.6      sato 		return (0);
    661   1.1  takemura 
    662   1.1  takemura 	case HPCFBIO_GCONF:
    663   1.1  takemura 		fbconf = (struct hpcfb_fbconf *)data;
    664   1.1  takemura 		if (fbconf->hf_conf_index != 0 &&
    665   1.1  takemura 		    fbconf->hf_conf_index != HPCFB_CURRENT_CONFIG) {
    666   1.1  takemura 			return (EINVAL);
    667   1.1  takemura 		}
    668   1.1  takemura 		*fbconf = sc->sc_fbconf;	/* structure assignment */
    669   1.1  takemura 		return (0);
    670   1.1  takemura 	case HPCFBIO_SCONF:
    671   1.1  takemura 		fbconf = (struct hpcfb_fbconf *)data;
    672   1.1  takemura 		if (fbconf->hf_conf_index != 0 &&
    673   1.1  takemura 		    fbconf->hf_conf_index != HPCFB_CURRENT_CONFIG) {
    674   1.1  takemura 			return (EINVAL);
    675   1.1  takemura 		}
    676   1.1  takemura 		/*
    677   1.1  takemura 		 * nothing to do because we have only one configration
    678   1.1  takemura 		 */
    679   1.1  takemura 		return (0);
    680   1.1  takemura 	case HPCFBIO_GDSPCONF:
    681   1.1  takemura 		dspconf = (struct hpcfb_dspconf *)data;
    682   1.1  takemura 		if ((dspconf->hd_unit_index != 0 &&
    683  1.18       uch 		    dspconf->hd_unit_index != HPCFB_CURRENT_UNIT) ||
    684   1.1  takemura 		    (dspconf->hd_conf_index != 0 &&
    685  1.18       uch 			dspconf->hd_conf_index != HPCFB_CURRENT_CONFIG)) {
    686   1.1  takemura 			return (EINVAL);
    687   1.1  takemura 		}
    688   1.1  takemura 		*dspconf = sc->sc_dspconf;	/* structure assignment */
    689   1.1  takemura 		return (0);
    690   1.1  takemura 	case HPCFBIO_SDSPCONF:
    691   1.1  takemura 		dspconf = (struct hpcfb_dspconf *)data;
    692   1.1  takemura 		if ((dspconf->hd_unit_index != 0 &&
    693  1.18       uch 		    dspconf->hd_unit_index != HPCFB_CURRENT_UNIT) ||
    694   1.1  takemura 		    (dspconf->hd_conf_index != 0 &&
    695  1.18       uch 			dspconf->hd_conf_index != HPCFB_CURRENT_CONFIG)) {
    696   1.1  takemura 			return (EINVAL);
    697   1.1  takemura 		}
    698   1.1  takemura 		/*
    699   1.1  takemura 		 * nothing to do
    700   1.1  takemura 		 * because we have only one unit and one configration
    701   1.1  takemura 		 */
    702   1.1  takemura 		return (0);
    703   1.1  takemura 	case HPCFBIO_GOP:
    704   1.1  takemura 	case HPCFBIO_SOP:
    705   1.1  takemura 		/*
    706   1.1  takemura 		 * curently not implemented...
    707   1.1  takemura 		 */
    708   1.1  takemura 		return (EINVAL);
    709   1.1  takemura 	}
    710   1.1  takemura 
    711  1.19    atatat 	return (EPASSTHROUGH);
    712   1.1  takemura }
    713   1.1  takemura 
    714   1.1  takemura paddr_t
    715  1.18       uch mq200_mmap(void *ctx, off_t offset, int prot)
    716   1.1  takemura {
    717   1.1  takemura 	struct mq200_softc *sc = (struct mq200_softc *)ctx;
    718   1.1  takemura 
    719   1.3  takemura 	if (offset < 0 || MQ200_MAPSIZE <= offset)
    720   1.1  takemura 		return -1;
    721   1.1  takemura 
    722   1.3  takemura 	return mips_btop(sc->sc_baseaddr + offset);
    723  1.10      sato }
    724  1.10      sato 
    725  1.10      sato 
    726  1.10      sato void
    727  1.18       uch mq200_init_backlight(struct mq200_softc *sc, int inattach)
    728  1.10      sato {
    729  1.10      sato 	int val = -1;
    730  1.10      sato 
    731  1.14      sato 	if (sc->sc_lcd_inited&BACKLIGHT_INITED)
    732  1.14      sato 		return;
    733  1.14      sato 
    734  1.12      sato 	if (config_hook_call(CONFIG_HOOK_GET,
    735  1.18       uch 	    CONFIG_HOOK_POWER_LCDLIGHT, &val) != -1) {
    736  1.14      sato 		/* we can get real light state */
    737  1.14      sato 		VPRINTF("init_backlight: real backlight=%d\n", val);
    738  1.12      sato 		if (val == 0)
    739  1.12      sato 			sc->sc_powerstate &= ~PWRSTAT_BACKLIGHT;
    740  1.12      sato 		else
    741  1.12      sato 			sc->sc_powerstate |= PWRSTAT_BACKLIGHT;
    742  1.14      sato 		sc->sc_lcd_inited |= BACKLIGHT_INITED;
    743  1.14      sato 	} else if (inattach) {
    744  1.14      sato 		/*
    745  1.14      sato 		   we cannot get real light state in attach time
    746  1.14      sato 		   because light device not yet attached.
    747  1.14      sato 		   we will retry in !inattach.
    748  1.14      sato 		   temporary assume light is on.
    749  1.18       uch 		*/
    750  1.12      sato 		sc->sc_powerstate |= PWRSTAT_BACKLIGHT;
    751  1.14      sato 	} else {
    752  1.14      sato 		/* we cannot get real light state, so work by myself state */
    753  1.14      sato 		sc->sc_lcd_inited |= BACKLIGHT_INITED;
    754  1.14      sato 	}
    755  1.10      sato }
    756  1.10      sato 
    757  1.10      sato void
    758  1.18       uch mq200_init_brightness(struct mq200_softc *sc, int inattach)
    759  1.10      sato {
    760  1.10      sato 	int val = -1;
    761  1.10      sato 
    762  1.14      sato 	if (sc->sc_lcd_inited&BRIGHTNESS_INITED)
    763  1.14      sato 		return;
    764  1.14      sato 
    765  1.13  takemura 	VPRINTF("init_brightness\n");
    766  1.10      sato 	if (config_hook_call(CONFIG_HOOK_GET,
    767  1.18       uch 	    CONFIG_HOOK_BRIGHTNESS_MAX, &val) != -1) {
    768  1.14      sato 		/* we can get real brightness max */
    769  1.14      sato 		VPRINTF("init_brightness: real brightness max=%d\n", val);
    770  1.10      sato 		sc->sc_max_brightness = val;
    771  1.14      sato 		val = -1;
    772  1.14      sato 		if (config_hook_call(CONFIG_HOOK_GET,
    773  1.18       uch 		    CONFIG_HOOK_BRIGHTNESS, &val) != -1) {
    774  1.14      sato 			/* we can get real brightness */
    775  1.14      sato 			VPRINTF("init_brightness: real brightness=%d\n", val);
    776  1.14      sato 			sc->sc_brightness_save = sc->sc_brightness = val;
    777  1.14      sato 		} else {
    778  1.14      sato 			sc->sc_brightness_save =
    779  1.18       uch 			    sc->sc_brightness = sc->sc_max_brightness;
    780  1.14      sato 		}
    781  1.14      sato 		sc->sc_lcd_inited |= BRIGHTNESS_INITED;
    782  1.14      sato 	} else if (inattach) {
    783  1.14      sato 		/*
    784  1.14      sato 		   we cannot get real brightness in attach time
    785  1.14      sato 		   because brightness device not yet attached.
    786  1.14      sato 		   we will retry in !inattach.
    787  1.18       uch 		*/
    788  1.14      sato 		sc->sc_max_brightness = -1;
    789  1.14      sato 		sc->sc_brightness = -1;
    790  1.14      sato 		sc->sc_brightness_save = -1;
    791  1.14      sato 	} else {
    792  1.14      sato 		/* we cannot get real brightness */
    793  1.14      sato 		sc->sc_lcd_inited |= BRIGHTNESS_INITED;
    794  1.10      sato 	}
    795  1.14      sato 
    796  1.10      sato 	return;
    797  1.10      sato }
    798  1.10      sato 
    799  1.10      sato 
    800  1.10      sato void
    801  1.18       uch mq200_init_contrast(struct mq200_softc *sc, int inattach)
    802  1.10      sato {
    803  1.10      sato 	int val = -1;
    804  1.10      sato 
    805  1.14      sato 	if (sc->sc_lcd_inited&CONTRAST_INITED)
    806  1.14      sato 		return;
    807  1.14      sato 
    808  1.13  takemura 	VPRINTF("init_contrast\n");
    809  1.10      sato 	if (config_hook_call(CONFIG_HOOK_GET,
    810  1.18       uch 	    CONFIG_HOOK_CONTRAST_MAX, &val) != -1) {
    811  1.14      sato 		/* we can get real contrast max */
    812  1.14      sato 		VPRINTF("init_contrast: real contrast max=%d\n", val);
    813  1.10      sato 		sc->sc_max_contrast = val;
    814  1.14      sato 		val = -1;
    815  1.14      sato 		if (config_hook_call(CONFIG_HOOK_GET,
    816  1.18       uch 		    CONFIG_HOOK_CONTRAST, &val) != -1) {
    817  1.14      sato 			/* we can get real contrast */
    818  1.14      sato 			VPRINTF("init_contrast: real contrast=%d\n", val);
    819  1.14      sato 			sc->sc_contrast = val;
    820  1.14      sato 		} else {
    821  1.14      sato 			sc->sc_contrast = sc->sc_max_contrast;
    822  1.14      sato 		}
    823  1.14      sato 		sc->sc_lcd_inited |= CONTRAST_INITED;
    824  1.14      sato 	} else if (inattach) {
    825  1.14      sato 		/*
    826  1.14      sato 		   we cannot get real contrast in attach time
    827  1.14      sato 		   because contrast device not yet attached.
    828  1.14      sato 		   we will retry in !inattach.
    829  1.18       uch 		*/
    830  1.14      sato 		sc->sc_max_contrast = -1;
    831  1.14      sato 		sc->sc_contrast = -1;
    832  1.14      sato 	} else {
    833  1.14      sato 		/* we cannot get real contrast */
    834  1.14      sato 		sc->sc_lcd_inited |= CONTRAST_INITED;
    835  1.10      sato 	}
    836  1.14      sato 
    837  1.10      sato 	return;
    838  1.10      sato }
    839  1.14      sato 
    840  1.10      sato 
    841  1.10      sato void
    842  1.18       uch mq200_set_brightness(struct mq200_softc *sc, int val)
    843  1.10      sato {
    844  1.10      sato 	sc->sc_brightness = val;
    845  1.10      sato 
    846  1.10      sato 	config_hook_call(CONFIG_HOOK_SET, CONFIG_HOOK_BRIGHTNESS, &val);
    847  1.10      sato 	if (config_hook_call(CONFIG_HOOK_GET,
    848  1.18       uch 	    CONFIG_HOOK_BRIGHTNESS, &val) != -1) {
    849  1.10      sato 		sc->sc_brightness = val;
    850  1.10      sato 	}
    851  1.10      sato }
    852  1.10      sato 
    853  1.10      sato void
    854  1.18       uch mq200_set_contrast(struct mq200_softc *sc, int val)
    855  1.10      sato {
    856  1.10      sato 	sc->sc_contrast = val;
    857  1.10      sato 
    858  1.10      sato 	config_hook_call(CONFIG_HOOK_SET, CONFIG_HOOK_CONTRAST, &val);
    859  1.10      sato 	if (config_hook_call(CONFIG_HOOK_GET,
    860  1.18       uch 	    CONFIG_HOOK_CONTRAST, &val) != -1) {
    861  1.10      sato 		sc->sc_contrast = val;
    862  1.10      sato 	}
    863   1.1  takemura }
    864