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