Home | History | Annotate | Line # | Download | only in dev
j6x0lcd.c revision 1.3.2.6
      1  1.3.2.6  skrll /*	$NetBSD: j6x0lcd.c,v 1.3.2.6 2005/11/10 13:56:31 skrll Exp $ */
      2  1.3.2.2  skrll 
      3  1.3.2.2  skrll /*
      4  1.3.2.6  skrll  * Copyright (c) 2004, 2005 Valeriy E. Ushakov
      5  1.3.2.2  skrll  * All rights reserved.
      6  1.3.2.2  skrll  *
      7  1.3.2.2  skrll  * Redistribution and use in source and binary forms, with or without
      8  1.3.2.2  skrll  * modification, are permitted provided that the following conditions
      9  1.3.2.2  skrll  * are met:
     10  1.3.2.2  skrll  * 1. Redistributions of source code must retain the above copyright
     11  1.3.2.2  skrll  *    notice, this list of conditions and the following disclaimer.
     12  1.3.2.2  skrll  * 2. Redistributions in binary form must reproduce the above copyright
     13  1.3.2.2  skrll  *    notice, this list of conditions and the following disclaimer in the
     14  1.3.2.2  skrll  *    documentation and/or other materials provided with the distribution.
     15  1.3.2.2  skrll  * 3. The name of the author may not be used to endorse or promote products
     16  1.3.2.2  skrll  *    derived from this software without specific prior written permission
     17  1.3.2.2  skrll  *
     18  1.3.2.2  skrll  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     19  1.3.2.2  skrll  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     20  1.3.2.2  skrll  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     21  1.3.2.2  skrll  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     22  1.3.2.2  skrll  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     23  1.3.2.2  skrll  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     24  1.3.2.2  skrll  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     25  1.3.2.2  skrll  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     26  1.3.2.2  skrll  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     27  1.3.2.2  skrll  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     28  1.3.2.2  skrll  */
     29  1.3.2.2  skrll 
     30  1.3.2.2  skrll #include <sys/cdefs.h>
     31  1.3.2.6  skrll __KERNEL_RCSID(0, "$NetBSD: j6x0lcd.c,v 1.3.2.6 2005/11/10 13:56:31 skrll Exp $");
     32  1.3.2.2  skrll 
     33  1.3.2.2  skrll #include <sys/param.h>
     34  1.3.2.2  skrll #include <sys/kernel.h>
     35  1.3.2.2  skrll #include <sys/device.h>
     36  1.3.2.2  skrll #include <sys/systm.h>
     37  1.3.2.2  skrll #ifdef GPROF
     38  1.3.2.2  skrll #include <sys/gmon.h>
     39  1.3.2.2  skrll #endif
     40  1.3.2.2  skrll 
     41  1.3.2.2  skrll #include <machine/platid.h>
     42  1.3.2.2  skrll #include <machine/platid_mask.h>
     43  1.3.2.2  skrll 
     44  1.3.2.2  skrll #include <machine/config_hook.h>
     45  1.3.2.2  skrll 
     46  1.3.2.2  skrll #include <sh3/dacreg.h>
     47  1.3.2.2  skrll #include <hpcsh/dev/hd64461/hd64461var.h> /* XXX: for hd64461_reg_read_2 &c */
     48  1.3.2.2  skrll #include <hpcsh/dev/hd64461/hd64461reg.h>
     49  1.3.2.2  skrll #include <hpcsh/dev/hd64461/hd64461gpioreg.h>
     50  1.3.2.2  skrll 
     51  1.3.2.6  skrll #define arraysize(ary) (sizeof(ary) / sizeof(ary[0]))
     52  1.3.2.6  skrll 
     53  1.3.2.2  skrll 
     54  1.3.2.2  skrll /*
     55  1.3.2.2  skrll  * LCD power: controlled by pin 0 in HD64461 GPIO port B.
     56  1.3.2.2  skrll  *   0 - power on
     57  1.3.2.2  skrll  *   1 - power off
     58  1.3.2.2  skrll  */
     59  1.3.2.6  skrll #define HD64461_GPBDR_J6X0_LCD_OFF	0x01
     60  1.3.2.2  skrll 
     61  1.3.2.6  skrll #define HD64461_GPBCR_J6X0_LCD_OFF_MASK	0xfffc
     62  1.3.2.6  skrll #define HD64461_GPBCR_J6X0_LCD_OFF_BITS	0x0001
     63  1.3.2.2  skrll 
     64  1.3.2.2  skrll 
     65  1.3.2.2  skrll /*
     66  1.3.2.2  skrll  * LCD brightness: controlled by DAC channel 0.  Larger channel values
     67  1.3.2.2  skrll  * mean dimmer.  Values smaller (i.e. brighter) then 0x5e seems to
     68  1.3.2.2  skrll  * result in no visible changes.
     69  1.3.2.2  skrll  */
     70  1.3.2.2  skrll #define J6X0LCD_BRIGHTNESS_DA_MAX	0x5e
     71  1.3.2.2  skrll #define J6X0LCD_BRIGHTNESS_DA_MIN	0xff
     72  1.3.2.2  skrll 
     73  1.3.2.2  skrll #define J6X0LCD_DA_TO_BRIGHTNESS(da) \
     74  1.3.2.2  skrll 	(J6X0LCD_BRIGHTNESS_DA_MIN - (da))
     75  1.3.2.2  skrll 
     76  1.3.2.2  skrll #define J6X0LCD_BRIGHTNESS_TO_DA(br) \
     77  1.3.2.2  skrll 	(J6X0LCD_BRIGHTNESS_DA_MIN - (br))
     78  1.3.2.2  skrll 
     79  1.3.2.2  skrll #define J6X0LCD_BRIGHTNESS_MAX \
     80  1.3.2.2  skrll 	J6X0LCD_DA_TO_BRIGHTNESS(J6X0LCD_BRIGHTNESS_DA_MAX)
     81  1.3.2.2  skrll 
     82  1.3.2.2  skrll /* convenience macro to accesses DAC registers */
     83  1.3.2.2  skrll #define DAC_(x)    (*((volatile uint8_t *)SH7709_DA ## x))
     84  1.3.2.2  skrll 
     85  1.3.2.2  skrll 
     86  1.3.2.2  skrll /*
     87  1.3.2.6  skrll  * LCD contrast in 680 is controlled by pins 6..3 of HD64461 GPIO
     88  1.3.2.6  skrll  * port B.  6th pin is the least significant bit, 3rd pin is the most
     89  1.3.2.6  skrll  * significant.  The bits are inverted: 0 = .1111...; 1 = .0111...;
     90  1.3.2.6  skrll  * etc.  Larger values mean "blacker".
     91  1.3.2.2  skrll  *
     92  1.3.2.6  skrll  * The contrast value is programmed by setting bits in the data
     93  1.3.2.6  skrll  * register to all ones, and changing the mode of the pins in the
     94  1.3.2.6  skrll  * control register, setting logical "ones" to GPIO output mode (1),
     95  1.3.2.6  skrll  * and switching "zeroes" to input mode (3).
     96  1.3.2.2  skrll  */
     97  1.3.2.6  skrll #define HD64461_GPBDR_J680_CONTRAST_BITS	0x78	/* set */
     98  1.3.2.6  skrll #define HD64461_GPBCR_J680_CONTRAST_MASK	0xc03f
     99  1.3.2.2  skrll 
    100  1.3.2.6  skrll static const uint8_t j6x0lcd_contrast680_pins[] = { 6, 5, 4, 3 };
    101  1.3.2.2  skrll 
    102  1.3.2.6  skrll static const uint16_t j6x0lcd_contrast680_control_bits[] = {
    103  1.3.2.6  skrll 	0x1540, 0x3540, 0x1d40, 0x3d40, 0x1740, 0x3740, 0x1f40, 0x3f40,
    104  1.3.2.6  skrll 	0x15c0, 0x35c0, 0x1dc0, 0x3dc0, 0x17c0, 0x37c0, 0x1fc0, 0x3fc0
    105  1.3.2.2  skrll };
    106  1.3.2.2  skrll 
    107  1.3.2.2  skrll 
    108  1.3.2.6  skrll /*
    109  1.3.2.6  skrll  * LCD contrast in 620lx is controlled by pins 7,6,3,4,5 of HD64461
    110  1.3.2.6  skrll  * GPIO port B (in the order from the least significant to the most
    111  1.3.2.6  skrll  * significant).  The bits are inverted: 0 = 11111...; 5 = 01110...;
    112  1.3.2.6  skrll  * etc.  Larger values mean "whiter".
    113  1.3.2.6  skrll  *
    114  1.3.2.6  skrll  * The contrast value is programmed by setting bits in the data
    115  1.3.2.6  skrll  * register to all zeroes, and changing the mode of the pins in the
    116  1.3.2.6  skrll  * control register, setting logical "ones" to GPIO output mode (1),
    117  1.3.2.6  skrll  * and switching "zeroes" to input mode (3).
    118  1.3.2.6  skrll  */
    119  1.3.2.6  skrll #define HD64461_GPBDR_J620LX_CONTRAST_BITS	0xf8	/* clear */
    120  1.3.2.6  skrll #define HD64461_GPBCR_J620LX_CONTRAST_MASK	0x003f
    121  1.3.2.6  skrll 
    122  1.3.2.6  skrll static const uint8_t j6x0lcd_contrast620lx_pins[] = { 7, 6, 3, 4, 5 };
    123  1.3.2.6  skrll 
    124  1.3.2.6  skrll static const uint16_t j6x0lcd_contrast620lx_control_bits[] = {
    125  1.3.2.6  skrll 	0xffc0, 0x7fc0, 0xdfc0, 0x5fc0, 0xff40, 0x7f40, 0xdf40, 0x5f40,
    126  1.3.2.6  skrll 	0xfdc0, 0x7dc0, 0xddc0, 0x5dc0, 0xfd40, 0x7d40, 0xdd40, 0x5d40,
    127  1.3.2.6  skrll 	0xf7c0, 0x77c0, 0xd7c0, 0x57c0, 0xf740, 0x7740, 0xd740, 0x5740,
    128  1.3.2.6  skrll 	0xf5c0, 0x75c0, 0xd5c0, 0x55c0, 0xf540, 0x7540, 0xd540, 0x5540
    129  1.3.2.2  skrll };
    130  1.3.2.2  skrll 
    131  1.3.2.2  skrll 
    132  1.3.2.6  skrll 
    133  1.3.2.2  skrll struct j6x0lcd_softc {
    134  1.3.2.2  skrll 	struct device sc_dev;
    135  1.3.2.2  skrll 	int sc_brightness;
    136  1.3.2.2  skrll 	int sc_contrast;
    137  1.3.2.6  skrll 
    138  1.3.2.6  skrll 	int sc_contrast_max;
    139  1.3.2.6  skrll 	uint16_t sc_contrast_mask;
    140  1.3.2.6  skrll 	const uint16_t *sc_contrast_control_bits;
    141  1.3.2.2  skrll };
    142  1.3.2.2  skrll 
    143  1.3.2.2  skrll static int	j6x0lcd_match(struct device *, struct cfdata *, void *);
    144  1.3.2.2  skrll static void	j6x0lcd_attach(struct device *, struct device *, void *);
    145  1.3.2.2  skrll 
    146  1.3.2.2  skrll CFATTACH_DECL(j6x0lcd, sizeof(struct j6x0lcd_softc),
    147  1.3.2.2  skrll     j6x0lcd_match, j6x0lcd_attach, NULL, NULL);
    148  1.3.2.2  skrll 
    149  1.3.2.2  skrll 
    150  1.3.2.2  skrll static int	j6x0lcd_param(void *, int, long, void *);
    151  1.3.2.2  skrll static int	j6x0lcd_power(void *, int, long, void *);
    152  1.3.2.2  skrll 
    153  1.3.2.6  skrll static int	j6x0lcd_contrast_raw(uint16_t, int, const uint8_t *);
    154  1.3.2.6  skrll static void	j6x0lcd_contrast_set(struct j6x0lcd_softc *, int);
    155  1.3.2.6  skrll 
    156  1.3.2.6  skrll 
    157  1.3.2.2  skrll 
    158  1.3.2.2  skrll static int
    159  1.3.2.2  skrll j6x0lcd_match(struct device *parent, struct cfdata *cfp, void *aux)
    160  1.3.2.2  skrll {
    161  1.3.2.2  skrll 
    162  1.3.2.2  skrll 	/*
    163  1.3.2.6  skrll 	 * XXX: platid_mask_MACH_HP_LX also matches 360LX.  It's not
    164  1.3.2.6  skrll 	 * confirmed whether touch panel in 360LX is connected this
    165  1.3.2.6  skrll 	 * way.  We may need to regroup platid masks.
    166  1.3.2.2  skrll 	 */
    167  1.3.2.6  skrll 	if (!platid_match(&platid, &platid_mask_MACH_HP_JORNADA_6XX)
    168  1.3.2.6  skrll 	    && !platid_match(&platid, &platid_mask_MACH_HP_LX))
    169  1.3.2.2  skrll 		return (0);
    170  1.3.2.2  skrll 
    171  1.3.2.2  skrll 	if (strcmp(cfp->cf_name, "j6x0lcd") != 0)
    172  1.3.2.2  skrll 		return (0);
    173  1.3.2.2  skrll 
    174  1.3.2.2  skrll 	return (1);
    175  1.3.2.2  skrll }
    176  1.3.2.2  skrll 
    177  1.3.2.2  skrll 
    178  1.3.2.2  skrll static void
    179  1.3.2.2  skrll j6x0lcd_attach(struct device *parent, struct device *self, void *aux)
    180  1.3.2.2  skrll {
    181  1.3.2.2  skrll 	struct j6x0lcd_softc *sc = (struct j6x0lcd_softc *)self;
    182  1.3.2.2  skrll 	uint16_t bcr, bdr;
    183  1.3.2.2  skrll 	uint8_t dcr, ddr;
    184  1.3.2.2  skrll 
    185  1.3.2.5  skrll 	/*
    186  1.3.2.2  skrll 	 * Brightness is controlled by DAC channel 0.
    187  1.3.2.2  skrll 	 */
    188  1.3.2.2  skrll 	dcr = DAC_(CR);
    189  1.3.2.2  skrll 	dcr &= ~SH7709_DACR_DAE; /* want to control each channel separately */
    190  1.3.2.2  skrll 	dcr |= SH7709_DACR_DAOE0; /* enable channel 0 */
    191  1.3.2.2  skrll 	DAC_(CR) = dcr;
    192  1.3.2.2  skrll 
    193  1.3.2.2  skrll 	ddr = DAC_(DR0);
    194  1.3.2.2  skrll 	sc->sc_brightness = J6X0LCD_DA_TO_BRIGHTNESS(ddr);
    195  1.3.2.2  skrll 
    196  1.3.2.2  skrll 	/*
    197  1.3.2.2  skrll 	 * Contrast and power are controlled by HD64461 GPIO port B.
    198  1.3.2.2  skrll 	 */
    199  1.3.2.2  skrll 	bcr = hd64461_reg_read_2(HD64461_GPBCR_REG16);
    200  1.3.2.2  skrll 	bdr = hd64461_reg_read_2(HD64461_GPBDR_REG16);
    201  1.3.2.2  skrll 
    202  1.3.2.6  skrll 	/*
    203  1.3.2.6  skrll 	 * Make sure LCD is turned on.
    204  1.3.2.6  skrll 	 */
    205  1.3.2.6  skrll 	bcr &= HD64461_GPBCR_J6X0_LCD_OFF_MASK;
    206  1.3.2.6  skrll 	bcr |= HD64461_GPBCR_J6X0_LCD_OFF_BITS; /* output mode */
    207  1.3.2.2  skrll 
    208  1.3.2.6  skrll 	bdr &= ~HD64461_GPBDR_J6X0_LCD_OFF;
    209  1.3.2.2  skrll 
    210  1.3.2.6  skrll 	/*
    211  1.3.2.6  skrll 	 * 620LX and 680 have different contrast control.
    212  1.3.2.6  skrll 	 */
    213  1.3.2.6  skrll 	if (platid_match(&platid, &platid_mask_MACH_HP_JORNADA_6XX)) {
    214  1.3.2.6  skrll 		bdr |= HD64461_GPBDR_J680_CONTRAST_BITS;
    215  1.3.2.6  skrll 
    216  1.3.2.6  skrll 		sc->sc_contrast_mask =
    217  1.3.2.6  skrll 			HD64461_GPBCR_J680_CONTRAST_MASK;
    218  1.3.2.6  skrll 		sc->sc_contrast_control_bits =
    219  1.3.2.6  skrll 			j6x0lcd_contrast680_control_bits;
    220  1.3.2.6  skrll 		sc->sc_contrast_max =
    221  1.3.2.6  skrll 			arraysize(j6x0lcd_contrast680_control_bits) - 1;
    222  1.3.2.6  skrll 
    223  1.3.2.6  skrll 		sc->sc_contrast = sc->sc_contrast_max
    224  1.3.2.6  skrll 			- j6x0lcd_contrast_raw(bcr,
    225  1.3.2.6  skrll 				arraysize(j6x0lcd_contrast680_pins),
    226  1.3.2.6  skrll 				j6x0lcd_contrast680_pins);
    227  1.3.2.6  skrll 	} else {
    228  1.3.2.6  skrll 		bdr &= ~HD64461_GPBDR_J620LX_CONTRAST_BITS;
    229  1.3.2.6  skrll 
    230  1.3.2.6  skrll 		sc->sc_contrast_mask =
    231  1.3.2.6  skrll 			HD64461_GPBCR_J620LX_CONTRAST_MASK;
    232  1.3.2.6  skrll 		sc->sc_contrast_control_bits =
    233  1.3.2.6  skrll 			j6x0lcd_contrast620lx_control_bits;
    234  1.3.2.6  skrll 		sc->sc_contrast_max =
    235  1.3.2.6  skrll 			arraysize(j6x0lcd_contrast620lx_control_bits) - 1;
    236  1.3.2.6  skrll 
    237  1.3.2.6  skrll 		sc->sc_contrast =
    238  1.3.2.6  skrll 			j6x0lcd_contrast_raw(bcr,
    239  1.3.2.6  skrll 				arraysize(j6x0lcd_contrast620lx_pins),
    240  1.3.2.6  skrll 				j6x0lcd_contrast620lx_pins);
    241  1.3.2.6  skrll 	}
    242  1.3.2.2  skrll 
    243  1.3.2.2  skrll 	hd64461_reg_write_2(HD64461_GPBCR_REG16, bcr);
    244  1.3.2.6  skrll 	hd64461_reg_write_2(HD64461_GPBDR_REG16, bdr);
    245  1.3.2.2  skrll 
    246  1.3.2.2  skrll 	printf(": brightness %d, contrast %d\n",
    247  1.3.2.2  skrll 	       sc->sc_brightness, sc->sc_contrast);
    248  1.3.2.2  skrll 
    249  1.3.2.2  skrll 
    250  1.3.2.2  skrll 	/* LCD brightness hooks */
    251  1.3.2.5  skrll 	config_hook(CONFIG_HOOK_GET, CONFIG_HOOK_BRIGHTNESS_MAX,
    252  1.3.2.2  skrll 		    CONFIG_HOOK_SHARE,
    253  1.3.2.2  skrll 		    j6x0lcd_param, sc);
    254  1.3.2.5  skrll 	config_hook(CONFIG_HOOK_GET, CONFIG_HOOK_BRIGHTNESS,
    255  1.3.2.2  skrll 		    CONFIG_HOOK_SHARE,
    256  1.3.2.2  skrll 		    j6x0lcd_param, sc);
    257  1.3.2.5  skrll 	config_hook(CONFIG_HOOK_SET, CONFIG_HOOK_BRIGHTNESS,
    258  1.3.2.2  skrll 		    CONFIG_HOOK_SHARE,
    259  1.3.2.2  skrll 		    j6x0lcd_param, sc);
    260  1.3.2.2  skrll 
    261  1.3.2.2  skrll 	/* LCD contrast hooks */
    262  1.3.2.5  skrll 	config_hook(CONFIG_HOOK_GET, CONFIG_HOOK_CONTRAST_MAX,
    263  1.3.2.2  skrll 		    CONFIG_HOOK_SHARE,
    264  1.3.2.2  skrll 		    j6x0lcd_param, sc);
    265  1.3.2.5  skrll 	config_hook(CONFIG_HOOK_GET, CONFIG_HOOK_CONTRAST,
    266  1.3.2.2  skrll 		    CONFIG_HOOK_SHARE,
    267  1.3.2.2  skrll 		    j6x0lcd_param, sc);
    268  1.3.2.5  skrll 	config_hook(CONFIG_HOOK_SET, CONFIG_HOOK_CONTRAST,
    269  1.3.2.2  skrll 		    CONFIG_HOOK_SHARE,
    270  1.3.2.2  skrll 		    j6x0lcd_param, sc);
    271  1.3.2.2  skrll 
    272  1.3.2.2  skrll 	/* LCD on/off hook */
    273  1.3.2.2  skrll 	config_hook(CONFIG_HOOK_POWERCONTROL,
    274  1.3.2.2  skrll 		    CONFIG_HOOK_POWERCONTROL_LCD,
    275  1.3.2.2  skrll 		    CONFIG_HOOK_SHARE,
    276  1.3.2.2  skrll 		    j6x0lcd_power, sc);
    277  1.3.2.2  skrll }
    278  1.3.2.2  skrll 
    279  1.3.2.2  skrll 
    280  1.3.2.6  skrll /*
    281  1.3.2.6  skrll  * Get raw contrast value programmed in GPIO port B control register.
    282  1.3.2.6  skrll  * Used only at attach time to get initial contrast.
    283  1.3.2.6  skrll  */
    284  1.3.2.6  skrll static int
    285  1.3.2.6  skrll j6x0lcd_contrast_raw(uint16_t bcr, int width, const uint8_t *pin)
    286  1.3.2.6  skrll {
    287  1.3.2.6  skrll 	int contrast;
    288  1.3.2.6  skrll 	int bit;
    289  1.3.2.6  skrll 
    290  1.3.2.6  skrll 	contrast = 0;
    291  1.3.2.6  skrll 	for (bit = 0; bit < width; ++bit) {
    292  1.3.2.6  skrll 		unsigned int c, v;
    293  1.3.2.6  skrll 
    294  1.3.2.6  skrll 		c = (bcr >> (pin[bit] << 1)) & 0x3;
    295  1.3.2.6  skrll 		if (c == 1)	/* output mode? */
    296  1.3.2.6  skrll 			v = 1;
    297  1.3.2.6  skrll 		else
    298  1.3.2.6  skrll 			v = 0;
    299  1.3.2.6  skrll 		contrast |= (v << bit);
    300  1.3.2.6  skrll 	}
    301  1.3.2.6  skrll 
    302  1.3.2.6  skrll 	return contrast;
    303  1.3.2.6  skrll }
    304  1.3.2.6  skrll 
    305  1.3.2.6  skrll 
    306  1.3.2.6  skrll /*
    307  1.3.2.6  skrll  * Set contrast by programming GPIO port B control register.
    308  1.3.2.6  skrll  * Data register has been initialized at attach time.
    309  1.3.2.6  skrll  */
    310  1.3.2.6  skrll static void
    311  1.3.2.6  skrll j6x0lcd_contrast_set(struct j6x0lcd_softc *sc, int contrast)
    312  1.3.2.6  skrll {
    313  1.3.2.6  skrll 	uint16_t bcr;
    314  1.3.2.6  skrll 
    315  1.3.2.6  skrll 	sc->sc_contrast = contrast;
    316  1.3.2.6  skrll 
    317  1.3.2.6  skrll 	bcr = hd64461_reg_read_2(HD64461_GPBCR_REG16);
    318  1.3.2.6  skrll 
    319  1.3.2.6  skrll 	bcr &= sc->sc_contrast_mask;
    320  1.3.2.6  skrll 	bcr |= sc->sc_contrast_control_bits[contrast];
    321  1.3.2.6  skrll 
    322  1.3.2.6  skrll 	hd64461_reg_write_2(HD64461_GPBCR_REG16, bcr);
    323  1.3.2.6  skrll }
    324  1.3.2.6  skrll 
    325  1.3.2.6  skrll 
    326  1.3.2.2  skrll static int
    327  1.3.2.2  skrll j6x0lcd_param(ctx, type, id, msg)
    328  1.3.2.2  skrll 	void *ctx;
    329  1.3.2.2  skrll 	int type;
    330  1.3.2.2  skrll 	long id;
    331  1.3.2.2  skrll 	void *msg;
    332  1.3.2.2  skrll {
    333  1.3.2.2  skrll 	struct j6x0lcd_softc *sc = ctx;
    334  1.3.2.2  skrll 	int value;
    335  1.3.2.2  skrll 	uint8_t dr;
    336  1.3.2.2  skrll 
    337  1.3.2.2  skrll 	switch (type) {
    338  1.3.2.2  skrll 	case CONFIG_HOOK_GET:
    339  1.3.2.2  skrll 		switch (id) {
    340  1.3.2.2  skrll 		case CONFIG_HOOK_CONTRAST:
    341  1.3.2.2  skrll 			*(int *)msg = sc->sc_contrast;
    342  1.3.2.2  skrll 			return (0);
    343  1.3.2.2  skrll 
    344  1.3.2.2  skrll 		case CONFIG_HOOK_CONTRAST_MAX:
    345  1.3.2.6  skrll 			*(int *)msg = sc->sc_contrast_max;
    346  1.3.2.2  skrll 			return (0);
    347  1.3.2.2  skrll 
    348  1.3.2.2  skrll 		case CONFIG_HOOK_BRIGHTNESS:
    349  1.3.2.2  skrll 			*(int *)msg = sc->sc_brightness;
    350  1.3.2.2  skrll 			return (0);
    351  1.3.2.2  skrll 
    352  1.3.2.2  skrll 		case CONFIG_HOOK_BRIGHTNESS_MAX:
    353  1.3.2.2  skrll 			*(int *)msg = J6X0LCD_BRIGHTNESS_MAX;
    354  1.3.2.2  skrll 			return (0);
    355  1.3.2.2  skrll 		}
    356  1.3.2.2  skrll 		break;
    357  1.3.2.2  skrll 
    358  1.3.2.2  skrll 	case CONFIG_HOOK_SET:
    359  1.3.2.2  skrll 		value = *(int *)msg;
    360  1.3.2.2  skrll 		if (value < 0)
    361  1.3.2.2  skrll 			value = 0;
    362  1.3.2.2  skrll 
    363  1.3.2.2  skrll 		switch (id) {
    364  1.3.2.2  skrll 		case CONFIG_HOOK_CONTRAST:
    365  1.3.2.6  skrll 			if (value > sc->sc_contrast_max)
    366  1.3.2.6  skrll 				value = sc->sc_contrast_max;
    367  1.3.2.6  skrll 			j6x0lcd_contrast_set(sc, value);
    368  1.3.2.2  skrll 			return (0);
    369  1.3.2.2  skrll 
    370  1.3.2.2  skrll 		case CONFIG_HOOK_BRIGHTNESS:
    371  1.3.2.2  skrll 			if (value > J6X0LCD_BRIGHTNESS_MAX)
    372  1.3.2.2  skrll 				value = J6X0LCD_BRIGHTNESS_MAX;
    373  1.3.2.2  skrll 			sc->sc_brightness = value;
    374  1.3.2.2  skrll 
    375  1.3.2.2  skrll 			dr = J6X0LCD_BRIGHTNESS_TO_DA(value);
    376  1.3.2.2  skrll 			DAC_(DR0) = dr;
    377  1.3.2.2  skrll 			return (0);
    378  1.3.2.2  skrll 		}
    379  1.3.2.2  skrll 		break;
    380  1.3.2.2  skrll 	}
    381  1.3.2.2  skrll 
    382  1.3.2.2  skrll 	return (EINVAL);
    383  1.3.2.2  skrll }
    384  1.3.2.2  skrll 
    385  1.3.2.2  skrll 
    386  1.3.2.2  skrll static int
    387  1.3.2.2  skrll j6x0lcd_power(ctx, type, id, msg)
    388  1.3.2.5  skrll 	void *ctx;
    389  1.3.2.5  skrll 	int type;
    390  1.3.2.5  skrll 	long id;
    391  1.3.2.2  skrll 	void *msg;
    392  1.3.2.2  skrll {
    393  1.3.2.2  skrll 	int on;
    394  1.3.2.2  skrll 	uint16_t r;
    395  1.3.2.2  skrll 
    396  1.3.2.2  skrll 	if (type != CONFIG_HOOK_POWERCONTROL
    397  1.3.2.2  skrll 	    || id != CONFIG_HOOK_POWERCONTROL_LCD)
    398  1.3.2.2  skrll 		return (EINVAL);
    399  1.3.2.2  skrll 
    400  1.3.2.2  skrll 	on = (int)msg;
    401  1.3.2.2  skrll 
    402  1.3.2.2  skrll 	r = hd64461_reg_read_2(HD64461_GPBDR_REG16);
    403  1.3.2.2  skrll 	if (on)
    404  1.3.2.6  skrll 		r &= ~HD64461_GPBDR_J6X0_LCD_OFF;
    405  1.3.2.2  skrll 	else
    406  1.3.2.6  skrll 		r |= HD64461_GPBDR_J6X0_LCD_OFF;
    407  1.3.2.2  skrll 	hd64461_reg_write_2(HD64461_GPBDR_REG16, r);
    408  1.3.2.2  skrll 
    409  1.3.2.2  skrll 	return (0);
    410  1.3.2.2  skrll }
    411