Home | History | Annotate | Line # | Download | only in dev
sed_saip.c revision 1.1
      1  1.1  toshii /*	$NetBSD: sed_saip.c,v 1.1 2001/06/01 02:51:03 toshii Exp $	*/
      2  1.1  toshii 
      3  1.1  toshii /*-
      4  1.1  toshii  * Copyright (c) 1999-2001
      5  1.1  toshii  *         Shin Takemura and PocketBSD Project. All rights reserved.
      6  1.1  toshii  *
      7  1.1  toshii  * Redistribution and use in source and binary forms, with or without
      8  1.1  toshii  * modification, are permitted provided that the following conditions
      9  1.1  toshii  * are met:
     10  1.1  toshii  * 1. Redistributions of source code must retain the above copyright
     11  1.1  toshii  *    notice, this list of conditions and the following disclaimer.
     12  1.1  toshii  * 2. Redistributions in binary form must reproduce the above copyright
     13  1.1  toshii  *    notice, this list of conditions and the following disclaimer in the
     14  1.1  toshii  *    documentation and/or other materials provided with the distribution.
     15  1.1  toshii  * 3. All advertising materials mentioning features or use of this software
     16  1.1  toshii  *    must display the following acknowledgement:
     17  1.1  toshii  *	This product includes software developed by the PocketBSD project
     18  1.1  toshii  *	and its contributors.
     19  1.1  toshii  * 4. Neither the name of the project nor the names of its contributors
     20  1.1  toshii  *    may be used to endorse or promote products derived from this software
     21  1.1  toshii  *    without specific prior written permission.
     22  1.1  toshii  *
     23  1.1  toshii  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     24  1.1  toshii  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     25  1.1  toshii  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     26  1.1  toshii  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     27  1.1  toshii  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     28  1.1  toshii  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     29  1.1  toshii  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     30  1.1  toshii  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     31  1.1  toshii  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     32  1.1  toshii  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     33  1.1  toshii  * SUCH DAMAGE.
     34  1.1  toshii  *
     35  1.1  toshii  */
     36  1.1  toshii #define FBDEBUG
     37  1.1  toshii static const char _copyright[] __attribute__ ((unused)) =
     38  1.1  toshii     "Copyright (c) 1999 Shin Takemura.  All rights reserved.";
     39  1.1  toshii static const char _rcsid[] __attribute__ ((unused)) =
     40  1.1  toshii     "$NetBSD: sed_saip.c,v 1.1 2001/06/01 02:51:03 toshii Exp $";
     41  1.1  toshii 
     42  1.1  toshii #include <sys/param.h>
     43  1.1  toshii #include <sys/systm.h>
     44  1.1  toshii #include <sys/device.h>
     45  1.1  toshii #include <sys/buf.h>
     46  1.1  toshii #include <sys/ioctl.h>
     47  1.1  toshii #include <sys/reboot.h>
     48  1.1  toshii 
     49  1.1  toshii #include <uvm/uvm_extern.h>
     50  1.1  toshii 
     51  1.1  toshii #include <machine/bus.h>
     52  1.1  toshii #include <machine/autoconf.h>
     53  1.1  toshii #include <machine/bootinfo.h>
     54  1.1  toshii #include <machine/config_hook.h>
     55  1.1  toshii 
     56  1.1  toshii #include <dev/wscons/wsconsio.h>
     57  1.1  toshii #include <dev/wscons/wsdisplayvar.h>
     58  1.1  toshii 
     59  1.1  toshii #include <dev/rasops/rasops.h>
     60  1.1  toshii 
     61  1.1  toshii #include <dev/hpc/hpcfbvar.h>
     62  1.1  toshii #include <dev/hpc/hpcfbio.h>
     63  1.1  toshii #include <dev/hpc/hpccmapvar.h>
     64  1.1  toshii 
     65  1.1  toshii #define VPRINTF(arg)	do { if (bootverbose) printf arg; } while(0);
     66  1.1  toshii 
     67  1.1  toshii /*
     68  1.1  toshii  *  function prototypes
     69  1.1  toshii  */
     70  1.1  toshii int	sed1356match(struct device *, struct cfdata *, void *);
     71  1.1  toshii void	sed1356attach(struct device *, struct device *, void *);
     72  1.1  toshii int	sed1356_ioctl(void *, u_long, caddr_t, int, struct proc *);
     73  1.1  toshii paddr_t	sed1356_mmap(void *, off_t, int);
     74  1.1  toshii 
     75  1.1  toshii struct sed1356_softc {
     76  1.1  toshii 	struct device		sc_dev;
     77  1.1  toshii 	struct hpcfb_fbconf	sc_fbconf;
     78  1.1  toshii 	struct hpcfb_dspconf	sc_dspconf;
     79  1.1  toshii 
     80  1.1  toshii 	void			*sc_powerhook;	/* power management hook */
     81  1.1  toshii 	int			sc_powerstate;
     82  1.1  toshii #define PWRSTAT_SUSPEND		(1<<0)
     83  1.1  toshii #define PWRSTAT_VIDEOOFF	(1<<1)
     84  1.1  toshii #define PWRSTAT_LCD		(1<<2)
     85  1.1  toshii #define PWRSTAT_BACKLIGHT	(1<<3)
     86  1.1  toshii #define PWRSTAT_ALL		(0xffffffff)
     87  1.1  toshii 	int			sc_lcd_inited;
     88  1.1  toshii #define BACKLIGHT_INITED	(1<<0)
     89  1.1  toshii #define BRIGHTNESS_INITED	(1<<1)
     90  1.1  toshii #define CONTRAST_INITED		(1<<2)
     91  1.1  toshii 	int			sc_brightness;
     92  1.1  toshii 	int			sc_brightness_save;
     93  1.1  toshii 	int			sc_max_brightness;
     94  1.1  toshii 	int			sc_contrast;
     95  1.1  toshii 	int			sc_max_contrast;
     96  1.1  toshii 
     97  1.1  toshii };
     98  1.1  toshii 
     99  1.1  toshii extern	struct bus_space sa11x0_bs_tag;
    100  1.1  toshii 
    101  1.1  toshii static int sed1356_init(struct hpcfb_fbconf *);
    102  1.1  toshii static void sed1356_power(int, void *);
    103  1.1  toshii static void sed1356_update_powerstate(struct sed1356_softc *, int);
    104  1.1  toshii void	sed1356_init_backlight(struct sed1356_softc *, int);
    105  1.1  toshii void	sed1356_init_brightness(struct sed1356_softc *, int);
    106  1.1  toshii void	sed1356_init_contrast(struct sed1356_softc *, int);
    107  1.1  toshii void	sed1356_set_brightness(struct sed1356_softc *, int);
    108  1.1  toshii void	sed1356_set_contrast(struct sed1356_softc *, int);
    109  1.1  toshii 
    110  1.1  toshii #if defined __mips__ || defined __sh__ || defined __arm__
    111  1.1  toshii #define __BTOP(x)		((paddr_t)(x) >> PGSHIFT)
    112  1.1  toshii #define __PTOB(x)		((paddr_t)(x) << PGSHIFT)
    113  1.1  toshii #else
    114  1.1  toshii #error "define btop, ptob."
    115  1.1  toshii #endif
    116  1.1  toshii 
    117  1.1  toshii /*
    118  1.1  toshii  *  static variables
    119  1.1  toshii  */
    120  1.1  toshii struct cfattach sed_ca = {
    121  1.1  toshii 	sizeof(struct sed1356_softc), sed1356match, sed1356attach,
    122  1.1  toshii };
    123  1.1  toshii struct hpcfb_accessops sed1356_ha = {
    124  1.1  toshii 	sed1356_ioctl, sed1356_mmap
    125  1.1  toshii };
    126  1.1  toshii 
    127  1.1  toshii static int console_flag = 0;
    128  1.1  toshii static int attach_flag = 0;
    129  1.1  toshii 
    130  1.1  toshii /*
    131  1.1  toshii  *  function bodies
    132  1.1  toshii  */
    133  1.1  toshii int
    134  1.1  toshii sed1356match(struct device *parent, struct cfdata *match, void *aux)
    135  1.1  toshii {
    136  1.1  toshii 
    137  1.1  toshii 	/* XXX check version register */
    138  1.1  toshii 	return 1;
    139  1.1  toshii }
    140  1.1  toshii 
    141  1.1  toshii void
    142  1.1  toshii sed1356attach(struct device *parent, struct device *self, void *aux)
    143  1.1  toshii {
    144  1.1  toshii 	struct sed1356_softc *sc = (struct sed1356_softc *)self;
    145  1.1  toshii 	struct hpcfb_attach_args ha;
    146  1.1  toshii 
    147  1.1  toshii 	if (attach_flag) {
    148  1.1  toshii 		panic("%s(%d): sed1356 attached twice", __FILE__, __LINE__);
    149  1.1  toshii 	}
    150  1.1  toshii 	attach_flag = 1;
    151  1.1  toshii 
    152  1.1  toshii 	if (sed1356_init(&sc->sc_fbconf) != 0) {
    153  1.1  toshii 		/* just return so that hpcfb will not be attached */
    154  1.1  toshii 		return;
    155  1.1  toshii 	}
    156  1.1  toshii 
    157  1.1  toshii 	printf("%s: Epson SED1356", sc->sc_dev.dv_xname);
    158  1.1  toshii 	if (console_flag) {
    159  1.1  toshii 		printf(", console");
    160  1.1  toshii 	}
    161  1.1  toshii 	printf("\n");
    162  1.1  toshii 	printf("%s: framebuffer address: 0x%08lx\n",
    163  1.1  toshii 		sc->sc_dev.dv_xname, (u_long)bootinfo->fb_addr);
    164  1.1  toshii 
    165  1.1  toshii 	/* Add a suspend hook to power saving */
    166  1.1  toshii 	sc->sc_powerstate = 0;
    167  1.1  toshii 	sc->sc_powerhook = powerhook_establish(sed1356_power, sc);
    168  1.1  toshii 	if (sc->sc_powerhook == NULL)
    169  1.1  toshii 		printf("%s: WARNING: unable to establish power hook\n",
    170  1.1  toshii 			sc->sc_dev.dv_xname);
    171  1.1  toshii 
    172  1.1  toshii 	/* initialize backlight brightness and lcd contrast */
    173  1.1  toshii 	sc->sc_lcd_inited = 0;
    174  1.1  toshii 	sed1356_init_brightness(sc, 1);
    175  1.1  toshii 	sed1356_init_contrast(sc, 1);
    176  1.1  toshii 	sed1356_init_backlight(sc, 1);
    177  1.1  toshii 
    178  1.1  toshii 	ha.ha_console = console_flag;
    179  1.1  toshii 	ha.ha_accessops = &sed1356_ha;
    180  1.1  toshii 	ha.ha_accessctx = sc;
    181  1.1  toshii 	ha.ha_curfbconf = 0;
    182  1.1  toshii 	ha.ha_nfbconf = 1;
    183  1.1  toshii 	ha.ha_fbconflist = &sc->sc_fbconf;
    184  1.1  toshii 	ha.ha_curdspconf = 0;
    185  1.1  toshii 	ha.ha_ndspconf = 1;
    186  1.1  toshii 	ha.ha_dspconflist = &sc->sc_dspconf;
    187  1.1  toshii 
    188  1.1  toshii 	config_found(self, &ha, hpcfbprint);
    189  1.1  toshii }
    190  1.1  toshii 
    191  1.1  toshii int
    192  1.1  toshii sed1356_getcnfb(struct hpcfb_fbconf *fb)
    193  1.1  toshii {
    194  1.1  toshii 	console_flag = 1;
    195  1.1  toshii 
    196  1.1  toshii 	return sed1356_init(fb);
    197  1.1  toshii }
    198  1.1  toshii 
    199  1.1  toshii static int
    200  1.1  toshii sed1356_init(struct hpcfb_fbconf *fb)
    201  1.1  toshii {
    202  1.1  toshii 	/*
    203  1.1  toshii 	 * get fb settings from bootinfo
    204  1.1  toshii 	 */
    205  1.1  toshii 	if (bootinfo == NULL ||
    206  1.1  toshii 	    bootinfo->fb_addr == 0 ||
    207  1.1  toshii 	    bootinfo->fb_line_bytes == 0 ||
    208  1.1  toshii 	    bootinfo->fb_width == 0 ||
    209  1.1  toshii 	    bootinfo->fb_height == 0) {
    210  1.1  toshii 		printf("no frame buffer infomation.\n");
    211  1.1  toshii 		return (-1);
    212  1.1  toshii 	}
    213  1.1  toshii 
    214  1.1  toshii 	/* zero fill */
    215  1.1  toshii 	bzero(fb, sizeof(*fb));
    216  1.1  toshii 
    217  1.1  toshii 	fb->hf_conf_index	= 0;	/* configuration index		*/
    218  1.1  toshii 	fb->hf_nconfs		= 1;   	/* how many configurations	*/
    219  1.1  toshii 	strcpy(fb->hf_name, "built-in video");
    220  1.1  toshii 					/* frame buffer name		*/
    221  1.1  toshii 	strcpy(fb->hf_conf_name, "default");
    222  1.1  toshii 					/* configuration name		*/
    223  1.1  toshii 	fb->hf_height		= bootinfo->fb_height;
    224  1.1  toshii 	fb->hf_width		= bootinfo->fb_width;
    225  1.1  toshii 	if (bus_space_map(&sa11x0_bs_tag, (bus_addr_t)bootinfo->fb_addr,
    226  1.1  toshii 			   bootinfo->fb_height * bootinfo->fb_line_bytes,
    227  1.1  toshii 			   0, &fb->hf_baseaddr)) {
    228  1.1  toshii 		printf("unable to map framebuffer\n");
    229  1.1  toshii 		return (-1);
    230  1.1  toshii 	}
    231  1.1  toshii 	fb->hf_offset		= (u_long)bootinfo->fb_addr -
    232  1.1  toshii 				      __PTOB(__BTOP(bootinfo->fb_addr));
    233  1.1  toshii 					/* frame buffer start offset   	*/
    234  1.1  toshii 	fb->hf_bytes_per_line	= bootinfo->fb_line_bytes;
    235  1.1  toshii 	fb->hf_nplanes		= 1;
    236  1.1  toshii 	fb->hf_bytes_per_plane	= bootinfo->fb_height *
    237  1.1  toshii 					bootinfo->fb_line_bytes;
    238  1.1  toshii 
    239  1.1  toshii 	fb->hf_access_flags |= HPCFB_ACCESS_BYTE;
    240  1.1  toshii 	fb->hf_access_flags |= HPCFB_ACCESS_WORD;
    241  1.1  toshii 	fb->hf_access_flags |= HPCFB_ACCESS_DWORD;
    242  1.1  toshii 
    243  1.1  toshii 	switch (bootinfo->fb_type) {
    244  1.1  toshii 		/*
    245  1.1  toshii 		 * gray scale
    246  1.1  toshii 		 */
    247  1.1  toshii 	case BIFB_D4_M2L_F:
    248  1.1  toshii 	case BIFB_D4_M2L_Fx2:
    249  1.1  toshii 		fb->hf_access_flags |= HPCFB_ACCESS_REVERSE;
    250  1.1  toshii 		/* fall through */
    251  1.1  toshii 	case BIFB_D4_M2L_0:
    252  1.1  toshii 	case BIFB_D4_M2L_0x2:
    253  1.1  toshii 		fb->hf_class = HPCFB_CLASS_GRAYSCALE;
    254  1.1  toshii 		fb->hf_access_flags |= HPCFB_ACCESS_STATIC;
    255  1.1  toshii 		fb->hf_pack_width = 8;
    256  1.1  toshii 		fb->hf_pixels_per_pack = 2;
    257  1.1  toshii 		fb->hf_pixel_width = 4;
    258  1.1  toshii 		fb->hf_class_data_length = sizeof(struct hf_gray_tag);
    259  1.1  toshii 		fb->hf_u.hf_gray.hf_flags = 0;	/* reserved for future use */
    260  1.1  toshii 		break;
    261  1.1  toshii 
    262  1.1  toshii 		/*
    263  1.1  toshii 		 * indexed color
    264  1.1  toshii 		 */
    265  1.1  toshii 	case BIFB_D8_FF:
    266  1.1  toshii 		fb->hf_access_flags |= HPCFB_ACCESS_REVERSE;
    267  1.1  toshii 		/* fall through */
    268  1.1  toshii 	case BIFB_D8_00:
    269  1.1  toshii 		fb->hf_class = HPCFB_CLASS_INDEXCOLOR;
    270  1.1  toshii 		fb->hf_access_flags |= HPCFB_ACCESS_STATIC;
    271  1.1  toshii 		fb->hf_pack_width = 8;
    272  1.1  toshii 		fb->hf_pixels_per_pack = 1;
    273  1.1  toshii 		fb->hf_pixel_width = 8;
    274  1.1  toshii 		fb->hf_class_data_length = sizeof(struct hf_indexed_tag);
    275  1.1  toshii 		fb->hf_u.hf_indexed.hf_flags = 0; /* reserved for future use */
    276  1.1  toshii 		break;
    277  1.1  toshii 
    278  1.1  toshii 		/*
    279  1.1  toshii 		 * RGB color
    280  1.1  toshii 		 */
    281  1.1  toshii 	case BIFB_D16_FFFF:
    282  1.1  toshii 		fb->hf_access_flags |= HPCFB_ACCESS_REVERSE;
    283  1.1  toshii 		/* fall through */
    284  1.1  toshii 	case BIFB_D16_0000:
    285  1.1  toshii 		fb->hf_class = HPCFB_CLASS_RGBCOLOR;
    286  1.1  toshii 		fb->hf_access_flags |= HPCFB_ACCESS_STATIC;
    287  1.1  toshii #if BYTE_ORDER == LITTLE_ENDIAN
    288  1.1  toshii 		fb->hf_swap_flags = HPCFB_SWAP_BYTE;
    289  1.1  toshii #endif
    290  1.1  toshii 		fb->hf_pack_width = 16;
    291  1.1  toshii 		fb->hf_pixels_per_pack = 1;
    292  1.1  toshii 		fb->hf_pixel_width = 16;
    293  1.1  toshii 
    294  1.1  toshii 		fb->hf_class_data_length = sizeof(struct hf_rgb_tag);
    295  1.1  toshii 		fb->hf_u.hf_rgb.hf_flags = 0;	/* reserved for future use */
    296  1.1  toshii 
    297  1.1  toshii 		fb->hf_u.hf_rgb.hf_red_width = 5;
    298  1.1  toshii 		fb->hf_u.hf_rgb.hf_red_shift = 11;
    299  1.1  toshii 		fb->hf_u.hf_rgb.hf_green_width = 6;
    300  1.1  toshii 		fb->hf_u.hf_rgb.hf_green_shift = 5;
    301  1.1  toshii 		fb->hf_u.hf_rgb.hf_blue_width = 5;
    302  1.1  toshii 		fb->hf_u.hf_rgb.hf_blue_shift = 0;
    303  1.1  toshii 		fb->hf_u.hf_rgb.hf_alpha_width = 0;
    304  1.1  toshii 		fb->hf_u.hf_rgb.hf_alpha_shift = 0;
    305  1.1  toshii 		break;
    306  1.1  toshii 
    307  1.1  toshii 	default:
    308  1.1  toshii 		printf("unsupported type %d.\n", bootinfo->fb_type);
    309  1.1  toshii 		return (-1);
    310  1.1  toshii 		break;
    311  1.1  toshii 	}
    312  1.1  toshii 
    313  1.1  toshii 	return (0); /* no error */
    314  1.1  toshii }
    315  1.1  toshii 
    316  1.1  toshii static void
    317  1.1  toshii sed1356_power(int why, void *arg)
    318  1.1  toshii {
    319  1.1  toshii 	struct sed1356_softc *sc = arg;
    320  1.1  toshii 
    321  1.1  toshii 	switch (why) {
    322  1.1  toshii 	case PWR_SUSPEND:
    323  1.1  toshii 	case PWR_STANDBY:
    324  1.1  toshii 		sc->sc_powerstate |= PWRSTAT_SUSPEND;
    325  1.1  toshii 		sed1356_update_powerstate(sc, PWRSTAT_ALL);
    326  1.1  toshii 		break;
    327  1.1  toshii 	case PWR_RESUME:
    328  1.1  toshii 		sc->sc_powerstate &= ~PWRSTAT_SUSPEND;
    329  1.1  toshii 		sed1356_update_powerstate(sc, PWRSTAT_ALL);
    330  1.1  toshii 		break;
    331  1.1  toshii 	}
    332  1.1  toshii }
    333  1.1  toshii 
    334  1.1  toshii static void
    335  1.1  toshii sed1356_update_powerstate(struct sed1356_softc *sc, int updates)
    336  1.1  toshii {
    337  1.1  toshii 	if (updates & PWRSTAT_LCD)
    338  1.1  toshii 		config_hook_call(CONFIG_HOOK_POWERCONTROL,
    339  1.1  toshii 		    CONFIG_HOOK_POWERCONTROL_LCD,
    340  1.1  toshii 		    (void*)!(sc->sc_powerstate &
    341  1.1  toshii 				(PWRSTAT_VIDEOOFF|PWRSTAT_SUSPEND)));
    342  1.1  toshii 
    343  1.1  toshii 	if (updates & PWRSTAT_BACKLIGHT)
    344  1.1  toshii 		config_hook_call(CONFIG_HOOK_POWERCONTROL,
    345  1.1  toshii 		    CONFIG_HOOK_POWERCONTROL_LCDLIGHT,
    346  1.1  toshii 		    (void*)(!(sc->sc_powerstate &
    347  1.1  toshii 				(PWRSTAT_VIDEOOFF|PWRSTAT_SUSPEND)) &&
    348  1.1  toshii 			     (sc->sc_powerstate & PWRSTAT_BACKLIGHT)));
    349  1.1  toshii }
    350  1.1  toshii 
    351  1.1  toshii int
    352  1.1  toshii sed1356_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p)
    353  1.1  toshii {
    354  1.1  toshii 	struct sed1356_softc *sc = (struct sed1356_softc *)v;
    355  1.1  toshii 	struct hpcfb_fbconf *fbconf;
    356  1.1  toshii 	struct hpcfb_dspconf *dspconf;
    357  1.1  toshii 	struct wsdisplay_param *dispparam;
    358  1.1  toshii 
    359  1.1  toshii 	switch (cmd) {
    360  1.1  toshii 	case WSDISPLAYIO_GETCMAP:
    361  1.1  toshii 	case WSDISPLAYIO_PUTCMAP:
    362  1.1  toshii 		/*
    363  1.1  toshii 		 * XXX should be able to handle color map in 4/8 bpp mode.
    364  1.1  toshii 		 */
    365  1.1  toshii 		return (EINVAL);
    366  1.1  toshii 
    367  1.1  toshii 	case WSDISPLAYIO_SVIDEO:
    368  1.1  toshii 		if (*(int *)data == WSDISPLAYIO_VIDEO_OFF)
    369  1.1  toshii 			sc->sc_powerstate |= PWRSTAT_VIDEOOFF;
    370  1.1  toshii 		else
    371  1.1  toshii 			sc->sc_powerstate &= ~PWRSTAT_VIDEOOFF;
    372  1.1  toshii 		sed1356_update_powerstate(sc, PWRSTAT_ALL);
    373  1.1  toshii 		return 0;
    374  1.1  toshii 
    375  1.1  toshii 	case WSDISPLAYIO_GVIDEO:
    376  1.1  toshii 		*(int *)data = (sc->sc_powerstate&PWRSTAT_VIDEOOFF) ?
    377  1.1  toshii 				WSDISPLAYIO_VIDEO_OFF:WSDISPLAYIO_VIDEO_ON;
    378  1.1  toshii 		return 0;
    379  1.1  toshii 
    380  1.1  toshii 
    381  1.1  toshii 	case WSDISPLAYIO_GETPARAM:
    382  1.1  toshii 		dispparam = (struct wsdisplay_param*)data;
    383  1.1  toshii 		switch (dispparam->param) {
    384  1.1  toshii 		case WSDISPLAYIO_PARAM_BACKLIGHT:
    385  1.1  toshii 			VPRINTF(("sed1356_ioctl: GET:BACKLIGHT\n"));
    386  1.1  toshii 			sed1356_init_brightness(sc, 0);
    387  1.1  toshii 			sed1356_init_backlight(sc, 0);
    388  1.1  toshii 			VPRINTF(("sed1356_ioctl: GET:(real)BACKLIGHT %d\n",
    389  1.1  toshii 				 (sc->sc_powerstate&PWRSTAT_BACKLIGHT)? 1: 0));
    390  1.1  toshii 			dispparam->min = 0;
    391  1.1  toshii 			dispparam->max = 1;
    392  1.1  toshii 			if (sc->sc_max_brightness > 0)
    393  1.1  toshii 				dispparam->curval = sc->sc_brightness > 0? 1: 0;
    394  1.1  toshii 			else
    395  1.1  toshii 				dispparam->curval =
    396  1.1  toshii 				    (sc->sc_powerstate&PWRSTAT_BACKLIGHT) ? 1: 0;
    397  1.1  toshii 			VPRINTF(("sed1356_ioctl: GET:BACKLIGHT:%d(%s)\n",
    398  1.1  toshii 				dispparam->curval,
    399  1.1  toshii 				sc->sc_max_brightness > 0? "brightness": "light"));
    400  1.1  toshii 			return 0;
    401  1.1  toshii 			break;
    402  1.1  toshii 		case WSDISPLAYIO_PARAM_CONTRAST:
    403  1.1  toshii 			VPRINTF(("sed1356_ioctl: GET:CONTRAST\n"));
    404  1.1  toshii 			sed1356_init_contrast(sc, 0);
    405  1.1  toshii 			if (sc->sc_max_contrast > 0) {
    406  1.1  toshii 				dispparam->min = 0;
    407  1.1  toshii 				dispparam->max = sc->sc_max_contrast;
    408  1.1  toshii 				dispparam->curval = sc->sc_contrast;
    409  1.1  toshii 				VPRINTF(("sed1356_ioctl: GET:CONTRAST max=%d, current=%d\n", sc->sc_max_contrast, sc->sc_contrast));
    410  1.1  toshii 				return 0;
    411  1.1  toshii 			} else {
    412  1.1  toshii 				VPRINTF(("sed1356_ioctl: GET:CONTRAST EINVAL\n"));
    413  1.1  toshii 				return (EINVAL);
    414  1.1  toshii 			}
    415  1.1  toshii 			break;
    416  1.1  toshii 		case WSDISPLAYIO_PARAM_BRIGHTNESS:
    417  1.1  toshii 			VPRINTF(("sed1356_ioctl: GET:BRIGHTNESS\n"));
    418  1.1  toshii 			sed1356_init_brightness(sc, 0);
    419  1.1  toshii 			if (sc->sc_max_brightness > 0) {
    420  1.1  toshii 				dispparam->min = 0;
    421  1.1  toshii 				dispparam->max = sc->sc_max_brightness;
    422  1.1  toshii 				dispparam->curval = sc->sc_brightness;
    423  1.1  toshii 				VPRINTF(("sed1356_ioctl: GET:BRIGHTNESS max=%d, current=%d\n", sc->sc_max_brightness, sc->sc_brightness));
    424  1.1  toshii 				return 0;
    425  1.1  toshii 			} else {
    426  1.1  toshii 				VPRINTF(("sed1356_ioctl: GET:BRIGHTNESS EINVAL\n"));
    427  1.1  toshii 				return (EINVAL);
    428  1.1  toshii 			}
    429  1.1  toshii 			return (EINVAL);
    430  1.1  toshii 		default:
    431  1.1  toshii 			return (EINVAL);
    432  1.1  toshii 		}
    433  1.1  toshii 		return (0);
    434  1.1  toshii 
    435  1.1  toshii 	case WSDISPLAYIO_SETPARAM:
    436  1.1  toshii 		dispparam = (struct wsdisplay_param*)data;
    437  1.1  toshii 		switch (dispparam->param) {
    438  1.1  toshii 		case WSDISPLAYIO_PARAM_BACKLIGHT:
    439  1.1  toshii 			VPRINTF(("sed1356_ioctl: SET:BACKLIGHT\n"));
    440  1.1  toshii 			if (dispparam->curval < 0 ||
    441  1.1  toshii 			    1 < dispparam->curval)
    442  1.1  toshii 				return (EINVAL);
    443  1.1  toshii 			sed1356_init_brightness(sc, 0);
    444  1.1  toshii 			VPRINTF(("sed1356_ioctl: SET:max brightness=%d\n", sc->sc_max_brightness));
    445  1.1  toshii 			if (sc->sc_max_brightness > 0) { /* dimmer */
    446  1.1  toshii 				if (dispparam->curval == 0){
    447  1.1  toshii 					sc->sc_brightness_save = sc->sc_brightness;
    448  1.1  toshii 					sed1356_set_brightness(sc, 0);	/* min */
    449  1.1  toshii 				} else {
    450  1.1  toshii 					if (sc->sc_brightness_save == 0)
    451  1.1  toshii 						sc->sc_brightness_save = sc->sc_max_brightness;
    452  1.1  toshii 					sed1356_set_brightness(sc, sc->sc_brightness_save);
    453  1.1  toshii 				}
    454  1.1  toshii 				VPRINTF(("sed1356_ioctl: SET:BACKLIGHT:brightness=%d\n", sc->sc_brightness));
    455  1.1  toshii 			} else { /* off */
    456  1.1  toshii 				if (dispparam->curval == 0)
    457  1.1  toshii 					sc->sc_powerstate &= ~PWRSTAT_BACKLIGHT;
    458  1.1  toshii 				else
    459  1.1  toshii 					sc->sc_powerstate |= PWRSTAT_BACKLIGHT;
    460  1.1  toshii 				VPRINTF(("sed1356_ioctl: SET:BACKLIGHT:powerstate %d\n",
    461  1.1  toshii 						(sc->sc_powerstate & PWRSTAT_BACKLIGHT)?1:0));
    462  1.1  toshii 				sed1356_update_powerstate(sc, PWRSTAT_BACKLIGHT);
    463  1.1  toshii 				VPRINTF(("sed1356_ioctl: SET:BACKLIGHT:%d\n",
    464  1.1  toshii 					(sc->sc_powerstate & PWRSTAT_BACKLIGHT)?1:0));
    465  1.1  toshii 			}
    466  1.1  toshii 			return 0;
    467  1.1  toshii 			break;
    468  1.1  toshii 		case WSDISPLAYIO_PARAM_CONTRAST:
    469  1.1  toshii 			VPRINTF(("sed1356_ioctl: SET:CONTRAST\n"));
    470  1.1  toshii 			sed1356_init_contrast(sc, 0);
    471  1.1  toshii 			if (dispparam->curval < 0 ||
    472  1.1  toshii 			    sc->sc_max_contrast < dispparam->curval)
    473  1.1  toshii 				return (EINVAL);
    474  1.1  toshii 			if (sc->sc_max_contrast > 0) {
    475  1.1  toshii 				int org = sc->sc_contrast;
    476  1.1  toshii 				sed1356_set_contrast(sc, dispparam->curval);
    477  1.1  toshii 				VPRINTF(("sed1356_ioctl: SET:CONTRAST org=%d, current=%d\n", org, sc->sc_contrast));
    478  1.1  toshii 				return 0;
    479  1.1  toshii 			} else {
    480  1.1  toshii 				VPRINTF(("sed1356_ioctl: SET:CONTRAST EINVAL\n"));
    481  1.1  toshii 				return (EINVAL);
    482  1.1  toshii 			}
    483  1.1  toshii 			break;
    484  1.1  toshii 		case WSDISPLAYIO_PARAM_BRIGHTNESS:
    485  1.1  toshii 			VPRINTF(("sed1356_ioctl: SET:BRIGHTNESS\n"));
    486  1.1  toshii 			sed1356_init_brightness(sc, 0);
    487  1.1  toshii 			if (dispparam->curval < 0 ||
    488  1.1  toshii 			    sc->sc_max_brightness < dispparam->curval)
    489  1.1  toshii 				return (EINVAL);
    490  1.1  toshii 			if (sc->sc_max_brightness > 0) {
    491  1.1  toshii 				int org = sc->sc_brightness;
    492  1.1  toshii 				sed1356_set_brightness(sc, dispparam->curval);
    493  1.1  toshii 				VPRINTF(("sed1356_ioctl: SET:BRIGHTNESS org=%d, current=%d\n", org, sc->sc_brightness));
    494  1.1  toshii 				return 0;
    495  1.1  toshii 			} else {
    496  1.1  toshii 				VPRINTF(("sed1356_ioctl: SET:BRIGHTNESS EINVAL\n"));
    497  1.1  toshii 				return (EINVAL);
    498  1.1  toshii 			}
    499  1.1  toshii 			break;
    500  1.1  toshii 		default:
    501  1.1  toshii 			return (EINVAL);
    502  1.1  toshii 		}
    503  1.1  toshii 		return (0);
    504  1.1  toshii 
    505  1.1  toshii 	case HPCFBIO_GCONF:
    506  1.1  toshii 		fbconf = (struct hpcfb_fbconf *)data;
    507  1.1  toshii 		if (fbconf->hf_conf_index != 0 &&
    508  1.1  toshii 		    fbconf->hf_conf_index != HPCFB_CURRENT_CONFIG) {
    509  1.1  toshii 			return (EINVAL);
    510  1.1  toshii 		}
    511  1.1  toshii 		*fbconf = sc->sc_fbconf;	/* structure assignment */
    512  1.1  toshii 		return (0);
    513  1.1  toshii 	case HPCFBIO_SCONF:
    514  1.1  toshii 		fbconf = (struct hpcfb_fbconf *)data;
    515  1.1  toshii 		if (fbconf->hf_conf_index != 0 &&
    516  1.1  toshii 		    fbconf->hf_conf_index != HPCFB_CURRENT_CONFIG) {
    517  1.1  toshii 			return (EINVAL);
    518  1.1  toshii 		}
    519  1.1  toshii 		/*
    520  1.1  toshii 		 * nothing to do because we have only one configration
    521  1.1  toshii 		 */
    522  1.1  toshii 		return (0);
    523  1.1  toshii 	case HPCFBIO_GDSPCONF:
    524  1.1  toshii 		dspconf = (struct hpcfb_dspconf *)data;
    525  1.1  toshii 		if ((dspconf->hd_unit_index != 0 &&
    526  1.1  toshii 		     dspconf->hd_unit_index != HPCFB_CURRENT_UNIT) ||
    527  1.1  toshii 		    (dspconf->hd_conf_index != 0 &&
    528  1.1  toshii 		     dspconf->hd_conf_index != HPCFB_CURRENT_CONFIG)) {
    529  1.1  toshii 			return (EINVAL);
    530  1.1  toshii 		}
    531  1.1  toshii 		*dspconf = sc->sc_dspconf;	/* structure assignment */
    532  1.1  toshii 		return (0);
    533  1.1  toshii 	case HPCFBIO_SDSPCONF:
    534  1.1  toshii 		dspconf = (struct hpcfb_dspconf *)data;
    535  1.1  toshii 		if ((dspconf->hd_unit_index != 0 &&
    536  1.1  toshii 		     dspconf->hd_unit_index != HPCFB_CURRENT_UNIT) ||
    537  1.1  toshii 		    (dspconf->hd_conf_index != 0 &&
    538  1.1  toshii 		     dspconf->hd_conf_index != HPCFB_CURRENT_CONFIG)) {
    539  1.1  toshii 			return (EINVAL);
    540  1.1  toshii 		}
    541  1.1  toshii 		/*
    542  1.1  toshii 		 * nothing to do
    543  1.1  toshii 		 * because we have only one unit and one configration
    544  1.1  toshii 		 */
    545  1.1  toshii 		return (0);
    546  1.1  toshii 	case HPCFBIO_GOP:
    547  1.1  toshii 	case HPCFBIO_SOP:
    548  1.1  toshii 		/*
    549  1.1  toshii 		 * curently not implemented...
    550  1.1  toshii 		 */
    551  1.1  toshii 		return (EINVAL);
    552  1.1  toshii 	}
    553  1.1  toshii 
    554  1.1  toshii 	return (ENOTTY);
    555  1.1  toshii }
    556  1.1  toshii 
    557  1.1  toshii paddr_t
    558  1.1  toshii sed1356_mmap(void *ctx, off_t offset, int prot)
    559  1.1  toshii {
    560  1.1  toshii 	struct sed1356_softc *sc = (struct sed1356_softc *)ctx;
    561  1.1  toshii 
    562  1.1  toshii 	if (offset < 0 ||
    563  1.1  toshii 	    (sc->sc_fbconf.hf_bytes_per_plane +
    564  1.1  toshii 		sc->sc_fbconf.hf_offset) <  offset)
    565  1.1  toshii 		return -1;
    566  1.1  toshii 
    567  1.1  toshii 	return __BTOP((u_long)bootinfo->fb_addr + offset);
    568  1.1  toshii }
    569  1.1  toshii 
    570  1.1  toshii 
    571  1.1  toshii void
    572  1.1  toshii sed1356_init_backlight(struct sed1356_softc *sc, int inattach)
    573  1.1  toshii {
    574  1.1  toshii 	int val = -1;
    575  1.1  toshii 
    576  1.1  toshii 	if (sc->sc_lcd_inited&BACKLIGHT_INITED)
    577  1.1  toshii 		return;
    578  1.1  toshii 
    579  1.1  toshii 	if (config_hook_call(CONFIG_HOOK_GET,
    580  1.1  toshii 	     CONFIG_HOOK_POWER_LCDLIGHT, &val) != -1) {
    581  1.1  toshii 		/* we can get real light state */
    582  1.1  toshii 		VPRINTF(("sed1356_init_backlight: real backlight=%d\n", val));
    583  1.1  toshii 		if (val == 0)
    584  1.1  toshii 			sc->sc_powerstate &= ~PWRSTAT_BACKLIGHT;
    585  1.1  toshii 		else
    586  1.1  toshii 			sc->sc_powerstate |= PWRSTAT_BACKLIGHT;
    587  1.1  toshii 		sc->sc_lcd_inited |= BACKLIGHT_INITED;
    588  1.1  toshii 	} else if (inattach) {
    589  1.1  toshii 		/*
    590  1.1  toshii 		   we cannot get real light state in attach time
    591  1.1  toshii 		   because light device not yet attached.
    592  1.1  toshii 		   we will retry in !inattach.
    593  1.1  toshii 		   temporary assume light is on.
    594  1.1  toshii 		 */
    595  1.1  toshii 		sc->sc_powerstate |= PWRSTAT_BACKLIGHT;
    596  1.1  toshii 	} else {
    597  1.1  toshii 		/* we cannot get real light state, so work by myself state */
    598  1.1  toshii 		sc->sc_lcd_inited |= BACKLIGHT_INITED;
    599  1.1  toshii 	}
    600  1.1  toshii }
    601  1.1  toshii 
    602  1.1  toshii void
    603  1.1  toshii sed1356_init_brightness(struct sed1356_softc *sc, int inattach)
    604  1.1  toshii {
    605  1.1  toshii 	int val = -1;
    606  1.1  toshii 
    607  1.1  toshii 	if (sc->sc_lcd_inited&BRIGHTNESS_INITED)
    608  1.1  toshii 		return;
    609  1.1  toshii 
    610  1.1  toshii 	VPRINTF(("sed1356_init_brightness\n"));
    611  1.1  toshii 	if (config_hook_call(CONFIG_HOOK_GET,
    612  1.1  toshii 	     CONFIG_HOOK_BRIGHTNESS_MAX, &val) != -1) {
    613  1.1  toshii 		/* we can get real brightness max */
    614  1.1  toshii 		VPRINTF(("sed1356_init_brightness: real brightness max=%d\n", val));
    615  1.1  toshii 		sc->sc_max_brightness = val;
    616  1.1  toshii 		val = -1;
    617  1.1  toshii 		if (config_hook_call(CONFIG_HOOK_GET,
    618  1.1  toshii 		     CONFIG_HOOK_BRIGHTNESS, &val) != -1) {
    619  1.1  toshii 			/* we can get real brightness */
    620  1.1  toshii 			VPRINTF(("sed1356_init_brightness: real brightness=%d\n", val));
    621  1.1  toshii 			sc->sc_brightness_save = sc->sc_brightness = val;
    622  1.1  toshii 		} else {
    623  1.1  toshii 			sc->sc_brightness_save =
    624  1.1  toshii 			sc->sc_brightness = sc->sc_max_brightness;
    625  1.1  toshii 		}
    626  1.1  toshii 		sc->sc_lcd_inited |= BRIGHTNESS_INITED;
    627  1.1  toshii 	} else if (inattach) {
    628  1.1  toshii 		/*
    629  1.1  toshii 		   we cannot get real brightness in attach time
    630  1.1  toshii 		   because brightness device not yet attached.
    631  1.1  toshii 		   we will retry in !inattach.
    632  1.1  toshii 		 */
    633  1.1  toshii 		sc->sc_max_brightness = -1;
    634  1.1  toshii 		sc->sc_brightness = -1;
    635  1.1  toshii 		sc->sc_brightness_save = -1;
    636  1.1  toshii 	} else {
    637  1.1  toshii 		/* we cannot get real brightness */
    638  1.1  toshii 		sc->sc_lcd_inited |= BRIGHTNESS_INITED;
    639  1.1  toshii 	}
    640  1.1  toshii 
    641  1.1  toshii 	return;
    642  1.1  toshii }
    643  1.1  toshii 
    644  1.1  toshii void
    645  1.1  toshii sed1356_init_contrast(struct sed1356_softc *sc, int inattach)
    646  1.1  toshii {
    647  1.1  toshii 	int val = -1;
    648  1.1  toshii 
    649  1.1  toshii 	if (sc->sc_lcd_inited&CONTRAST_INITED)
    650  1.1  toshii 		return;
    651  1.1  toshii 
    652  1.1  toshii 	VPRINTF(("sed1356_init_contrast\n"));
    653  1.1  toshii 	if (config_hook_call(CONFIG_HOOK_GET,
    654  1.1  toshii 	     CONFIG_HOOK_CONTRAST_MAX, &val) != -1) {
    655  1.1  toshii 		/* we can get real contrast max */
    656  1.1  toshii 		VPRINTF(("sed1356_init_contrast: real contrast max=%d\n", val));
    657  1.1  toshii 		sc->sc_max_contrast = val;
    658  1.1  toshii 		val = -1;
    659  1.1  toshii 		if (config_hook_call(CONFIG_HOOK_GET,
    660  1.1  toshii 		     CONFIG_HOOK_CONTRAST, &val) != -1) {
    661  1.1  toshii 			/* we can get real contrast */
    662  1.1  toshii 			VPRINTF(("sed1356_init_contrast: real contrast=%d\n", val));
    663  1.1  toshii 			sc->sc_contrast = val;
    664  1.1  toshii 		} else {
    665  1.1  toshii 			sc->sc_contrast = sc->sc_max_contrast;
    666  1.1  toshii 		}
    667  1.1  toshii 		sc->sc_lcd_inited |= CONTRAST_INITED;
    668  1.1  toshii 	} else if (inattach) {
    669  1.1  toshii 		/*
    670  1.1  toshii 		   we cannot get real contrast in attach time
    671  1.1  toshii 		   because contrast device not yet attached.
    672  1.1  toshii 		   we will retry in !inattach.
    673  1.1  toshii 		 */
    674  1.1  toshii 		sc->sc_max_contrast = -1;
    675  1.1  toshii 		sc->sc_contrast = -1;
    676  1.1  toshii 	} else {
    677  1.1  toshii 		/* we cannot get real contrast */
    678  1.1  toshii 		sc->sc_lcd_inited |= CONTRAST_INITED;
    679  1.1  toshii 	}
    680  1.1  toshii 
    681  1.1  toshii 	return;
    682  1.1  toshii }
    683  1.1  toshii 
    684  1.1  toshii void
    685  1.1  toshii sed1356_set_brightness(struct sed1356_softc *sc, int val)
    686  1.1  toshii {
    687  1.1  toshii 	sc->sc_brightness = val;
    688  1.1  toshii 
    689  1.1  toshii 	config_hook_call(CONFIG_HOOK_SET, CONFIG_HOOK_BRIGHTNESS, &val);
    690  1.1  toshii 	if (config_hook_call(CONFIG_HOOK_GET,
    691  1.1  toshii 	     CONFIG_HOOK_BRIGHTNESS, &val) != -1) {
    692  1.1  toshii 		sc->sc_brightness = val;
    693  1.1  toshii 	}
    694  1.1  toshii }
    695  1.1  toshii 
    696  1.1  toshii void
    697  1.1  toshii sed1356_set_contrast(struct sed1356_softc *sc, int val)
    698  1.1  toshii {
    699  1.1  toshii 	sc->sc_contrast = val;
    700  1.1  toshii 
    701  1.1  toshii 	config_hook_call(CONFIG_HOOK_SET, CONFIG_HOOK_CONTRAST, &val);
    702  1.1  toshii 	if (config_hook_call(CONFIG_HOOK_GET,
    703  1.1  toshii 	     CONFIG_HOOK_CONTRAST, &val) != -1) {
    704  1.1  toshii 		sc->sc_contrast = val;
    705  1.1  toshii 	}
    706  1.1  toshii }
    707