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