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