1 1.29 andvar /* $NetBSD: sed_saip.c,v 1.29 2022/05/28 10:36:22 andvar 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.20 peter * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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.20 peter * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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.13 lukem 36 1.13 lukem #include <sys/cdefs.h> 37 1.29 andvar __KERNEL_RCSID(0, "$NetBSD: sed_saip.c,v 1.29 2022/05/28 10:36:22 andvar Exp $"); 38 1.1 toshii 39 1.1 toshii #include <sys/param.h> 40 1.1 toshii #include <sys/systm.h> 41 1.1 toshii #include <sys/device.h> 42 1.1 toshii #include <sys/buf.h> 43 1.1 toshii #include <sys/ioctl.h> 44 1.1 toshii #include <sys/reboot.h> 45 1.25 dyoung #include <sys/bus.h> 46 1.1 toshii 47 1.1 toshii #include <machine/bootinfo.h> 48 1.1 toshii #include <machine/config_hook.h> 49 1.4 toshii #include <machine/platid.h> 50 1.4 toshii #include <machine/platid_mask.h> 51 1.1 toshii 52 1.1 toshii #include <dev/wscons/wsconsio.h> 53 1.1 toshii #include <dev/wscons/wsdisplayvar.h> 54 1.1 toshii 55 1.1 toshii #include <dev/rasops/rasops.h> 56 1.1 toshii 57 1.1 toshii #include <dev/hpc/hpcfbvar.h> 58 1.1 toshii #include <dev/hpc/hpcfbio.h> 59 1.1 toshii #include <dev/hpc/hpccmapvar.h> 60 1.1 toshii 61 1.18 peter #include <hpcarm/dev/sed1356var.h> 62 1.4 toshii 63 1.17 peter #ifdef SED_DEBUG 64 1.24 rjs #define VPRINTF(arg) do { if (bootverbose) aprint_normal arg; } while (0) 65 1.17 peter #else 66 1.17 peter #define VPRINTF(arg) /* nothing */ 67 1.17 peter #endif 68 1.1 toshii 69 1.1 toshii /* 70 1.18 peter * Function prototypes. 71 1.1 toshii */ 72 1.24 rjs static int sed1356_match(device_t, cfdata_t, void *); 73 1.24 rjs static void sed1356_attach(device_t, device_t, void *); 74 1.22 christos static int sed1356_ioctl(void *, u_long, void *, int, struct lwp *); 75 1.18 peter static paddr_t sed1356_mmap(void *, off_t, int); 76 1.18 peter 77 1.18 peter static int sed1356_init(struct hpcfb_fbconf *); 78 1.18 peter static void sed1356_power(int, void *); 79 1.18 peter static void sed1356_update_powerstate(struct sed1356_softc *, int); 80 1.18 peter static void sed1356_init_backlight(struct sed1356_softc *, int); 81 1.18 peter static void sed1356_set_brightness(struct sed1356_softc *, int); 82 1.18 peter static void sed1356_set_contrast(struct sed1356_softc *, int); 83 1.1 toshii 84 1.1 toshii #if defined __mips__ || defined __sh__ || defined __arm__ 85 1.1 toshii #define __BTOP(x) ((paddr_t)(x) >> PGSHIFT) 86 1.1 toshii #define __PTOB(x) ((paddr_t)(x) << PGSHIFT) 87 1.1 toshii #else 88 1.1 toshii #error "define btop, ptob." 89 1.1 toshii #endif 90 1.1 toshii 91 1.1 toshii /* 92 1.18 peter * External functions/variables. 93 1.18 peter */ 94 1.18 peter extern struct cfdriver sed_cd; 95 1.18 peter extern struct bus_space sa11x0_bs_tag; 96 1.18 peter extern int j720lcd_power(void *, int, long, void *); /* XXX */ 97 1.18 peter 98 1.18 peter /* 99 1.18 peter * Static variables. 100 1.1 toshii */ 101 1.24 rjs CFATTACH_DECL_NEW(sed, sizeof(struct sed1356_softc), 102 1.18 peter sed1356_match, sed1356_attach, NULL, NULL); 103 1.1 toshii struct hpcfb_accessops sed1356_ha = { 104 1.1 toshii sed1356_ioctl, sed1356_mmap 105 1.1 toshii }; 106 1.1 toshii 107 1.1 toshii static int attach_flag = 0; 108 1.1 toshii 109 1.1 toshii /* 110 1.18 peter * Function bodies. 111 1.1 toshii */ 112 1.18 peter static int 113 1.24 rjs sed1356_match(device_t parent, cfdata_t match, void *aux) 114 1.1 toshii { 115 1.1 toshii 116 1.1 toshii /* XXX check version register */ 117 1.1 toshii return 1; 118 1.1 toshii } 119 1.1 toshii 120 1.18 peter static void 121 1.24 rjs sed1356_attach(device_t parent, device_t self, void *aux) 122 1.1 toshii { 123 1.24 rjs struct sed1356_softc *sc = device_private(self); 124 1.1 toshii struct hpcfb_attach_args ha; 125 1.9 toshii int console = (bootinfo->bi_cnuse & BI_CNUSE_SERIAL) ? 0 : 1; 126 1.5 toshii 127 1.1 toshii if (attach_flag) { 128 1.1 toshii panic("%s(%d): sed1356 attached twice", __FILE__, __LINE__); 129 1.1 toshii } 130 1.1 toshii attach_flag = 1; 131 1.1 toshii 132 1.1 toshii if (sed1356_init(&sc->sc_fbconf) != 0) { 133 1.1 toshii /* just return so that hpcfb will not be attached */ 134 1.1 toshii return; 135 1.1 toshii } 136 1.24 rjs aprint_normal("\n"); 137 1.1 toshii 138 1.24 rjs sc->sc_dev = self; 139 1.4 toshii sc->sc_iot = &sa11x0_bs_tag; 140 1.24 rjs sc->sc_parent = device_private(parent); 141 1.4 toshii if (bus_space_map(sc->sc_iot, (bus_addr_t)bootinfo->fb_addr & ~0x3fffff, 142 1.18 peter 0x200, 0, &sc->sc_regh)) { 143 1.24 rjs aprint_normal_dev(self, "unable to map register\n"); 144 1.4 toshii return; 145 1.4 toshii } 146 1.4 toshii 147 1.24 rjs aprint_normal_dev(self, "Epson SED1356"); 148 1.9 toshii if (console) { 149 1.24 rjs aprint_normal(", console"); 150 1.1 toshii } 151 1.24 rjs aprint_normal("\n"); 152 1.24 rjs aprint_normal_dev(self, "framebuffer address: 0x%08lx\n", 153 1.24 rjs (u_long)bootinfo->fb_addr); 154 1.1 toshii 155 1.1 toshii /* Add a suspend hook to power saving */ 156 1.1 toshii sc->sc_powerstate = 0; 157 1.26 chs sc->sc_powerhook = powerhook_establish(device_xname(self), 158 1.21 jmcneill sed1356_power, sc); 159 1.1 toshii if (sc->sc_powerhook == NULL) 160 1.24 rjs aprint_normal_dev(self, "WARNING: unable to establish power hook\n"); 161 1.1 toshii 162 1.18 peter /* Initialize backlight brightness and lcd contrast */ 163 1.1 toshii sc->sc_lcd_inited = 0; 164 1.1 toshii sed1356_init_brightness(sc, 1); 165 1.1 toshii sed1356_init_contrast(sc, 1); 166 1.1 toshii sed1356_init_backlight(sc, 1); 167 1.1 toshii 168 1.9 toshii if (console && hpcfb_cnattach(&sc->sc_fbconf) != 0) 169 1.18 peter panic("sed1356_attach: cannot init fb console"); 170 1.9 toshii 171 1.9 toshii ha.ha_console = console; 172 1.1 toshii ha.ha_accessops = &sed1356_ha; 173 1.1 toshii ha.ha_accessctx = sc; 174 1.1 toshii ha.ha_curfbconf = 0; 175 1.1 toshii ha.ha_nfbconf = 1; 176 1.1 toshii ha.ha_fbconflist = &sc->sc_fbconf; 177 1.1 toshii ha.ha_curdspconf = 0; 178 1.1 toshii ha.ha_ndspconf = 1; 179 1.1 toshii ha.ha_dspconflist = &sc->sc_dspconf; 180 1.1 toshii 181 1.4 toshii /* XXX */ 182 1.4 toshii if (platid_match(&platid, &platid_mask_MACH_HP_JORNADA_7XX)) { 183 1.4 toshii config_hook(CONFIG_HOOK_POWERCONTROL, 184 1.4 toshii CONFIG_HOOK_POWERCONTROL_LCDLIGHT, 185 1.16 peter CONFIG_HOOK_SHARE, j720lcd_power, sc); 186 1.4 toshii } 187 1.4 toshii 188 1.28 thorpej config_found(self, &ha, hpcfbprint, CFARGS_NONE); 189 1.1 toshii } 190 1.1 toshii 191 1.1 toshii static int 192 1.1 toshii sed1356_init(struct hpcfb_fbconf *fb) 193 1.1 toshii { 194 1.1 toshii /* 195 1.1 toshii * get fb settings from bootinfo 196 1.1 toshii */ 197 1.1 toshii if (bootinfo == NULL || 198 1.1 toshii bootinfo->fb_addr == 0 || 199 1.1 toshii bootinfo->fb_line_bytes == 0 || 200 1.1 toshii bootinfo->fb_width == 0 || 201 1.1 toshii bootinfo->fb_height == 0) { 202 1.24 rjs aprint_normal("no frame buffer information.\n"); 203 1.18 peter return -1; 204 1.1 toshii } 205 1.1 toshii 206 1.1 toshii /* zero fill */ 207 1.6 ichiro memset(fb, 0, sizeof(*fb)); 208 1.1 toshii 209 1.1 toshii fb->hf_conf_index = 0; /* configuration index */ 210 1.1 toshii fb->hf_nconfs = 1; /* how many configurations */ 211 1.1 toshii strcpy(fb->hf_name, "built-in video"); 212 1.1 toshii /* frame buffer name */ 213 1.1 toshii strcpy(fb->hf_conf_name, "default"); 214 1.1 toshii /* configuration name */ 215 1.1 toshii fb->hf_height = bootinfo->fb_height; 216 1.1 toshii fb->hf_width = bootinfo->fb_width; 217 1.4 toshii 218 1.1 toshii if (bus_space_map(&sa11x0_bs_tag, (bus_addr_t)bootinfo->fb_addr, 219 1.1 toshii bootinfo->fb_height * bootinfo->fb_line_bytes, 220 1.1 toshii 0, &fb->hf_baseaddr)) { 221 1.24 rjs aprint_normal("unable to map framebuffer\n"); 222 1.18 peter return -1; 223 1.1 toshii } 224 1.1 toshii fb->hf_offset = (u_long)bootinfo->fb_addr - 225 1.1 toshii __PTOB(__BTOP(bootinfo->fb_addr)); 226 1.1 toshii /* frame buffer start offset */ 227 1.1 toshii fb->hf_bytes_per_line = bootinfo->fb_line_bytes; 228 1.1 toshii fb->hf_nplanes = 1; 229 1.1 toshii fb->hf_bytes_per_plane = bootinfo->fb_height * 230 1.1 toshii bootinfo->fb_line_bytes; 231 1.1 toshii 232 1.1 toshii fb->hf_access_flags |= HPCFB_ACCESS_BYTE; 233 1.1 toshii fb->hf_access_flags |= HPCFB_ACCESS_WORD; 234 1.1 toshii fb->hf_access_flags |= HPCFB_ACCESS_DWORD; 235 1.1 toshii 236 1.1 toshii switch (bootinfo->fb_type) { 237 1.1 toshii /* 238 1.1 toshii * gray scale 239 1.1 toshii */ 240 1.1 toshii case BIFB_D4_M2L_F: 241 1.1 toshii case BIFB_D4_M2L_Fx2: 242 1.1 toshii fb->hf_access_flags |= HPCFB_ACCESS_REVERSE; 243 1.1 toshii /* fall through */ 244 1.1 toshii case BIFB_D4_M2L_0: 245 1.1 toshii case BIFB_D4_M2L_0x2: 246 1.1 toshii fb->hf_class = HPCFB_CLASS_GRAYSCALE; 247 1.1 toshii fb->hf_access_flags |= HPCFB_ACCESS_STATIC; 248 1.1 toshii fb->hf_pack_width = 8; 249 1.1 toshii fb->hf_pixels_per_pack = 2; 250 1.1 toshii fb->hf_pixel_width = 4; 251 1.1 toshii fb->hf_class_data_length = sizeof(struct hf_gray_tag); 252 1.1 toshii fb->hf_u.hf_gray.hf_flags = 0; /* reserved for future use */ 253 1.1 toshii break; 254 1.1 toshii 255 1.1 toshii /* 256 1.1 toshii * indexed color 257 1.1 toshii */ 258 1.1 toshii case BIFB_D8_FF: 259 1.1 toshii fb->hf_access_flags |= HPCFB_ACCESS_REVERSE; 260 1.1 toshii /* fall through */ 261 1.1 toshii case BIFB_D8_00: 262 1.1 toshii fb->hf_class = HPCFB_CLASS_INDEXCOLOR; 263 1.1 toshii fb->hf_access_flags |= HPCFB_ACCESS_STATIC; 264 1.1 toshii fb->hf_pack_width = 8; 265 1.1 toshii fb->hf_pixels_per_pack = 1; 266 1.1 toshii fb->hf_pixel_width = 8; 267 1.1 toshii fb->hf_class_data_length = sizeof(struct hf_indexed_tag); 268 1.1 toshii fb->hf_u.hf_indexed.hf_flags = 0; /* reserved for future use */ 269 1.1 toshii break; 270 1.1 toshii 271 1.1 toshii /* 272 1.1 toshii * RGB color 273 1.1 toshii */ 274 1.1 toshii case BIFB_D16_FFFF: 275 1.1 toshii fb->hf_access_flags |= HPCFB_ACCESS_REVERSE; 276 1.1 toshii /* fall through */ 277 1.1 toshii case BIFB_D16_0000: 278 1.1 toshii fb->hf_class = HPCFB_CLASS_RGBCOLOR; 279 1.1 toshii fb->hf_access_flags |= HPCFB_ACCESS_STATIC; 280 1.8 takemura fb->hf_order_flags = HPCFB_REVORDER_BYTE; 281 1.1 toshii fb->hf_pack_width = 16; 282 1.1 toshii fb->hf_pixels_per_pack = 1; 283 1.1 toshii fb->hf_pixel_width = 16; 284 1.1 toshii 285 1.1 toshii fb->hf_class_data_length = sizeof(struct hf_rgb_tag); 286 1.1 toshii fb->hf_u.hf_rgb.hf_flags = 0; /* reserved for future use */ 287 1.1 toshii 288 1.1 toshii fb->hf_u.hf_rgb.hf_red_width = 5; 289 1.1 toshii fb->hf_u.hf_rgb.hf_red_shift = 11; 290 1.1 toshii fb->hf_u.hf_rgb.hf_green_width = 6; 291 1.1 toshii fb->hf_u.hf_rgb.hf_green_shift = 5; 292 1.1 toshii fb->hf_u.hf_rgb.hf_blue_width = 5; 293 1.1 toshii fb->hf_u.hf_rgb.hf_blue_shift = 0; 294 1.1 toshii fb->hf_u.hf_rgb.hf_alpha_width = 0; 295 1.1 toshii fb->hf_u.hf_rgb.hf_alpha_shift = 0; 296 1.1 toshii break; 297 1.1 toshii 298 1.1 toshii default: 299 1.24 rjs aprint_normal("unsupported type %d.\n", bootinfo->fb_type); 300 1.18 peter return -1; 301 1.1 toshii } 302 1.1 toshii 303 1.18 peter return 0; /* no error */ 304 1.1 toshii } 305 1.1 toshii 306 1.19 blymn static void 307 1.1 toshii sed1356_power(int why, void *arg) 308 1.1 toshii { 309 1.1 toshii struct sed1356_softc *sc = arg; 310 1.1 toshii 311 1.1 toshii switch (why) { 312 1.1 toshii case PWR_SUSPEND: 313 1.1 toshii case PWR_STANDBY: 314 1.1 toshii sc->sc_powerstate |= PWRSTAT_SUSPEND; 315 1.1 toshii sed1356_update_powerstate(sc, PWRSTAT_ALL); 316 1.1 toshii break; 317 1.1 toshii case PWR_RESUME: 318 1.1 toshii sc->sc_powerstate &= ~PWRSTAT_SUSPEND; 319 1.1 toshii sed1356_update_powerstate(sc, PWRSTAT_ALL); 320 1.1 toshii break; 321 1.1 toshii } 322 1.1 toshii } 323 1.1 toshii 324 1.1 toshii static void 325 1.1 toshii sed1356_update_powerstate(struct sed1356_softc *sc, int updates) 326 1.1 toshii { 327 1.1 toshii if (updates & PWRSTAT_LCD) 328 1.1 toshii config_hook_call(CONFIG_HOOK_POWERCONTROL, 329 1.1 toshii CONFIG_HOOK_POWERCONTROL_LCD, 330 1.19 blymn (void *)!(sc->sc_powerstate & 331 1.1 toshii (PWRSTAT_VIDEOOFF|PWRSTAT_SUSPEND))); 332 1.1 toshii 333 1.1 toshii if (updates & PWRSTAT_BACKLIGHT) 334 1.1 toshii config_hook_call(CONFIG_HOOK_POWERCONTROL, 335 1.1 toshii CONFIG_HOOK_POWERCONTROL_LCDLIGHT, 336 1.19 blymn (void *)(!(sc->sc_powerstate & 337 1.1 toshii (PWRSTAT_VIDEOOFF|PWRSTAT_SUSPEND)) && 338 1.1 toshii (sc->sc_powerstate & PWRSTAT_BACKLIGHT))); 339 1.1 toshii } 340 1.1 toshii 341 1.18 peter static int 342 1.22 christos sed1356_ioctl(void *v, u_long cmd, void *data, int flag, struct lwp *l) 343 1.1 toshii { 344 1.1 toshii struct sed1356_softc *sc = (struct sed1356_softc *)v; 345 1.1 toshii struct hpcfb_fbconf *fbconf; 346 1.1 toshii struct hpcfb_dspconf *dspconf; 347 1.1 toshii struct wsdisplay_param *dispparam; 348 1.1 toshii 349 1.1 toshii switch (cmd) { 350 1.1 toshii case WSDISPLAYIO_GETCMAP: 351 1.1 toshii case WSDISPLAYIO_PUTCMAP: 352 1.1 toshii /* 353 1.1 toshii * XXX should be able to handle color map in 4/8 bpp mode. 354 1.1 toshii */ 355 1.18 peter return EINVAL; 356 1.19 blymn 357 1.1 toshii case WSDISPLAYIO_SVIDEO: 358 1.1 toshii if (*(int *)data == WSDISPLAYIO_VIDEO_OFF) 359 1.1 toshii sc->sc_powerstate |= PWRSTAT_VIDEOOFF; 360 1.1 toshii else 361 1.1 toshii sc->sc_powerstate &= ~PWRSTAT_VIDEOOFF; 362 1.1 toshii sed1356_update_powerstate(sc, PWRSTAT_ALL); 363 1.1 toshii return 0; 364 1.1 toshii 365 1.1 toshii case WSDISPLAYIO_GVIDEO: 366 1.19 blymn *(int *)data = (sc->sc_powerstate & PWRSTAT_VIDEOOFF) ? 367 1.18 peter WSDISPLAYIO_VIDEO_OFF : WSDISPLAYIO_VIDEO_ON; 368 1.1 toshii return 0; 369 1.1 toshii 370 1.1 toshii case WSDISPLAYIO_GETPARAM: 371 1.18 peter dispparam = (struct wsdisplay_param *)data; 372 1.1 toshii switch (dispparam->param) { 373 1.1 toshii case WSDISPLAYIO_PARAM_BACKLIGHT: 374 1.1 toshii VPRINTF(("sed1356_ioctl: GET:BACKLIGHT\n")); 375 1.1 toshii sed1356_init_brightness(sc, 0); 376 1.1 toshii sed1356_init_backlight(sc, 0); 377 1.1 toshii VPRINTF(("sed1356_ioctl: GET:(real)BACKLIGHT %d\n", 378 1.18 peter (sc->sc_powerstate & PWRSTAT_BACKLIGHT) ? 1: 0)); 379 1.1 toshii dispparam->min = 0; 380 1.1 toshii dispparam->max = 1; 381 1.1 toshii if (sc->sc_max_brightness > 0) 382 1.18 peter dispparam->curval = (sc->sc_brightness > 0) ? 383 1.18 peter 1 : 0; 384 1.1 toshii else 385 1.1 toshii dispparam->curval = 386 1.18 peter (sc->sc_powerstate & PWRSTAT_BACKLIGHT) ? 387 1.18 peter 1 : 0; 388 1.1 toshii VPRINTF(("sed1356_ioctl: GET:BACKLIGHT:%d(%s)\n", 389 1.18 peter dispparam->curval, (sc->sc_max_brightness > 0) ? 390 1.18 peter "brightness": "light")); 391 1.1 toshii return 0; 392 1.18 peter 393 1.1 toshii case WSDISPLAYIO_PARAM_CONTRAST: 394 1.1 toshii VPRINTF(("sed1356_ioctl: GET:CONTRAST\n")); 395 1.1 toshii sed1356_init_contrast(sc, 0); 396 1.1 toshii if (sc->sc_max_contrast > 0) { 397 1.1 toshii dispparam->min = 0; 398 1.1 toshii dispparam->max = sc->sc_max_contrast; 399 1.1 toshii dispparam->curval = sc->sc_contrast; 400 1.18 peter VPRINTF(("sed1356_ioctl: GET:CONTRAST max=%d," 401 1.18 peter " current=%d\n", sc->sc_max_contrast, 402 1.18 peter sc->sc_contrast)); 403 1.1 toshii return 0; 404 1.1 toshii } 405 1.18 peter VPRINTF(("sed1356_ioctl: GET:CONTRAST EINVAL\n")); 406 1.18 peter return EINVAL; 407 1.18 peter 408 1.1 toshii case WSDISPLAYIO_PARAM_BRIGHTNESS: 409 1.1 toshii VPRINTF(("sed1356_ioctl: GET:BRIGHTNESS\n")); 410 1.1 toshii sed1356_init_brightness(sc, 0); 411 1.1 toshii if (sc->sc_max_brightness > 0) { 412 1.1 toshii dispparam->min = 0; 413 1.1 toshii dispparam->max = sc->sc_max_brightness; 414 1.1 toshii dispparam->curval = sc->sc_brightness; 415 1.18 peter VPRINTF(("sed1356_ioctl: GET:BRIGHTNESS max=%d," 416 1.18 peter " current=%d\n", sc->sc_max_brightness, 417 1.18 peter sc->sc_brightness)); 418 1.1 toshii return 0; 419 1.19 blymn } 420 1.18 peter VPRINTF(("sed1356_ioctl: GET:BRIGHTNESS EINVAL\n")); 421 1.18 peter return EINVAL; 422 1.18 peter 423 1.1 toshii default: 424 1.18 peter return EINVAL; 425 1.1 toshii } 426 1.18 peter break; 427 1.1 toshii 428 1.1 toshii case WSDISPLAYIO_SETPARAM: 429 1.1 toshii dispparam = (struct wsdisplay_param*)data; 430 1.1 toshii switch (dispparam->param) { 431 1.1 toshii case WSDISPLAYIO_PARAM_BACKLIGHT: 432 1.1 toshii VPRINTF(("sed1356_ioctl: SET:BACKLIGHT\n")); 433 1.18 peter if (dispparam->curval < 0 || 1 < dispparam->curval) 434 1.18 peter return EINVAL; 435 1.1 toshii sed1356_init_brightness(sc, 0); 436 1.18 peter VPRINTF(("sed1356_ioctl: SET:max brightness=%d\n", 437 1.18 peter sc->sc_max_brightness)); 438 1.1 toshii if (sc->sc_max_brightness > 0) { /* dimmer */ 439 1.1 toshii if (dispparam->curval == 0){ 440 1.18 peter sc->sc_brightness_save = 441 1.18 peter sc->sc_brightness; 442 1.18 peter sed1356_set_brightness(sc, 0); /* min */ 443 1.1 toshii } else { 444 1.1 toshii if (sc->sc_brightness_save == 0) 445 1.18 peter sc->sc_brightness_save = 446 1.18 peter sc->sc_max_brightness; 447 1.18 peter sed1356_set_brightness(sc, 448 1.18 peter sc->sc_brightness_save); 449 1.1 toshii } 450 1.18 peter VPRINTF(("sed1356_ioctl: SET:BACKLIGHT:" 451 1.18 peter "brightness=%d\n", sc->sc_brightness)); 452 1.1 toshii } else { /* off */ 453 1.1 toshii if (dispparam->curval == 0) 454 1.1 toshii sc->sc_powerstate &= ~PWRSTAT_BACKLIGHT; 455 1.1 toshii else 456 1.1 toshii sc->sc_powerstate |= PWRSTAT_BACKLIGHT; 457 1.18 peter VPRINTF(("sed1356_ioctl: SET:BACKLIGHT:" 458 1.18 peter "powerstate %d\n", (sc->sc_powerstate & 459 1.18 peter PWRSTAT_BACKLIGHT) ? 1 : 0)); 460 1.1 toshii sed1356_update_powerstate(sc, PWRSTAT_BACKLIGHT); 461 1.1 toshii VPRINTF(("sed1356_ioctl: SET:BACKLIGHT:%d\n", 462 1.18 peter (sc->sc_powerstate & PWRSTAT_BACKLIGHT) ? 463 1.18 peter 1 : 0)); 464 1.1 toshii } 465 1.1 toshii return 0; 466 1.18 peter 467 1.1 toshii case WSDISPLAYIO_PARAM_CONTRAST: 468 1.1 toshii VPRINTF(("sed1356_ioctl: SET:CONTRAST\n")); 469 1.1 toshii sed1356_init_contrast(sc, 0); 470 1.1 toshii if (dispparam->curval < 0 || 471 1.1 toshii sc->sc_max_contrast < dispparam->curval) 472 1.18 peter return EINVAL; 473 1.1 toshii if (sc->sc_max_contrast > 0) { 474 1.20 peter VPRINTF(("sed1356_ioctl: SET:CONTRAST org=%d", 475 1.20 peter sc->sc_contrast)); 476 1.19 blymn sed1356_set_contrast(sc, dispparam->curval); 477 1.20 peter VPRINTF((", current=%d\n", sc->sc_contrast)); 478 1.1 toshii return 0; 479 1.1 toshii } 480 1.18 peter VPRINTF(("sed1356_ioctl: SET:CONTRAST EINVAL\n")); 481 1.18 peter return EINVAL; 482 1.18 peter 483 1.1 toshii case WSDISPLAYIO_PARAM_BRIGHTNESS: 484 1.1 toshii VPRINTF(("sed1356_ioctl: SET:BRIGHTNESS\n")); 485 1.1 toshii sed1356_init_brightness(sc, 0); 486 1.1 toshii if (dispparam->curval < 0 || 487 1.1 toshii sc->sc_max_brightness < dispparam->curval) 488 1.18 peter return EINVAL; 489 1.1 toshii if (sc->sc_max_brightness > 0) { 490 1.20 peter VPRINTF(("sed1356_ioctl: SET:BRIGHTNESS org=%d", 491 1.20 peter sc->sc_brightness)); 492 1.19 blymn sed1356_set_brightness(sc, dispparam->curval); 493 1.20 peter VPRINTF((", current=%d\n", sc->sc_brightness)); 494 1.1 toshii return 0; 495 1.1 toshii } 496 1.18 peter VPRINTF(("sed1356_ioctl: SET:BRIGHTNESS EINVAL\n")); 497 1.18 peter return EINVAL; 498 1.18 peter 499 1.1 toshii default: 500 1.18 peter return EINVAL; 501 1.1 toshii } 502 1.18 peter return 0; 503 1.1 toshii 504 1.1 toshii case HPCFBIO_GCONF: 505 1.1 toshii fbconf = (struct hpcfb_fbconf *)data; 506 1.1 toshii if (fbconf->hf_conf_index != 0 && 507 1.1 toshii fbconf->hf_conf_index != HPCFB_CURRENT_CONFIG) { 508 1.18 peter return EINVAL; 509 1.1 toshii } 510 1.1 toshii *fbconf = sc->sc_fbconf; /* structure assignment */ 511 1.18 peter return 0; 512 1.1 toshii case HPCFBIO_SCONF: 513 1.1 toshii fbconf = (struct hpcfb_fbconf *)data; 514 1.1 toshii if (fbconf->hf_conf_index != 0 && 515 1.1 toshii fbconf->hf_conf_index != HPCFB_CURRENT_CONFIG) { 516 1.18 peter return EINVAL; 517 1.1 toshii } 518 1.1 toshii /* 519 1.14 abs * nothing to do because we have only one configuration 520 1.1 toshii */ 521 1.18 peter return 0; 522 1.1 toshii case HPCFBIO_GDSPCONF: 523 1.1 toshii dspconf = (struct hpcfb_dspconf *)data; 524 1.1 toshii if ((dspconf->hd_unit_index != 0 && 525 1.1 toshii dspconf->hd_unit_index != HPCFB_CURRENT_UNIT) || 526 1.1 toshii (dspconf->hd_conf_index != 0 && 527 1.1 toshii dspconf->hd_conf_index != HPCFB_CURRENT_CONFIG)) { 528 1.18 peter return EINVAL; 529 1.1 toshii } 530 1.1 toshii *dspconf = sc->sc_dspconf; /* structure assignment */ 531 1.18 peter return 0; 532 1.1 toshii case HPCFBIO_SDSPCONF: 533 1.1 toshii dspconf = (struct hpcfb_dspconf *)data; 534 1.1 toshii if ((dspconf->hd_unit_index != 0 && 535 1.1 toshii dspconf->hd_unit_index != HPCFB_CURRENT_UNIT) || 536 1.1 toshii (dspconf->hd_conf_index != 0 && 537 1.1 toshii dspconf->hd_conf_index != HPCFB_CURRENT_CONFIG)) { 538 1.18 peter return EINVAL; 539 1.1 toshii } 540 1.1 toshii /* 541 1.1 toshii * nothing to do 542 1.14 abs * because we have only one unit and one configuration 543 1.1 toshii */ 544 1.18 peter return 0; 545 1.1 toshii case HPCFBIO_GOP: 546 1.1 toshii case HPCFBIO_SOP: 547 1.1 toshii /* 548 1.29 andvar * currently not implemented... 549 1.1 toshii */ 550 1.18 peter return EINVAL; 551 1.1 toshii } 552 1.1 toshii 553 1.18 peter return EPASSTHROUGH; 554 1.1 toshii } 555 1.1 toshii 556 1.18 peter static paddr_t 557 1.1 toshii sed1356_mmap(void *ctx, off_t offset, int prot) 558 1.1 toshii { 559 1.1 toshii struct sed1356_softc *sc = (struct sed1356_softc *)ctx; 560 1.1 toshii 561 1.1 toshii if (offset < 0 || 562 1.1 toshii (sc->sc_fbconf.hf_bytes_per_plane + 563 1.18 peter sc->sc_fbconf.hf_offset) < offset) 564 1.1 toshii return -1; 565 1.1 toshii 566 1.1 toshii return __BTOP((u_long)bootinfo->fb_addr + offset); 567 1.1 toshii } 568 1.1 toshii 569 1.18 peter static void 570 1.1 toshii sed1356_init_backlight(struct sed1356_softc *sc, int inattach) 571 1.1 toshii { 572 1.1 toshii int val = -1; 573 1.1 toshii 574 1.18 peter if (sc->sc_lcd_inited & BACKLIGHT_INITED) 575 1.1 toshii return; 576 1.1 toshii 577 1.18 peter if (config_hook_call(CONFIG_HOOK_GET, 578 1.18 peter CONFIG_HOOK_POWER_LCDLIGHT, &val) != -1) { 579 1.1 toshii /* we can get real light state */ 580 1.1 toshii VPRINTF(("sed1356_init_backlight: real backlight=%d\n", val)); 581 1.1 toshii if (val == 0) 582 1.1 toshii sc->sc_powerstate &= ~PWRSTAT_BACKLIGHT; 583 1.1 toshii else 584 1.1 toshii sc->sc_powerstate |= PWRSTAT_BACKLIGHT; 585 1.1 toshii sc->sc_lcd_inited |= BACKLIGHT_INITED; 586 1.1 toshii } else if (inattach) { 587 1.19 blymn /* 588 1.1 toshii we cannot get real light state in attach time 589 1.1 toshii because light device not yet attached. 590 1.1 toshii we will retry in !inattach. 591 1.1 toshii temporary assume light is on. 592 1.1 toshii */ 593 1.1 toshii sc->sc_powerstate |= PWRSTAT_BACKLIGHT; 594 1.1 toshii } else { 595 1.1 toshii /* we cannot get real light state, so work by myself state */ 596 1.1 toshii sc->sc_lcd_inited |= BACKLIGHT_INITED; 597 1.1 toshii } 598 1.1 toshii } 599 1.1 toshii 600 1.1 toshii void 601 1.1 toshii sed1356_init_brightness(struct sed1356_softc *sc, int inattach) 602 1.1 toshii { 603 1.1 toshii int val = -1; 604 1.1 toshii 605 1.18 peter if (sc->sc_lcd_inited & BRIGHTNESS_INITED) 606 1.1 toshii return; 607 1.1 toshii 608 1.1 toshii VPRINTF(("sed1356_init_brightness\n")); 609 1.18 peter if (config_hook_call(CONFIG_HOOK_GET, 610 1.18 peter CONFIG_HOOK_BRIGHTNESS_MAX, &val) != -1) { 611 1.1 toshii /* we can get real brightness max */ 612 1.18 peter VPRINTF(("sed1356_init_brightness: " 613 1.18 peter "real brightness max=%d\n", val)); 614 1.1 toshii sc->sc_max_brightness = val; 615 1.1 toshii val = -1; 616 1.18 peter if (config_hook_call(CONFIG_HOOK_GET, 617 1.18 peter CONFIG_HOOK_BRIGHTNESS, &val) != -1) { 618 1.1 toshii /* we can get real brightness */ 619 1.18 peter VPRINTF(("sed1356_init_brightness: " 620 1.18 peter "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.19 blymn /* 629 1.18 peter * we cannot get real brightness in attach time 630 1.18 peter * because brightness device not yet attached. 631 1.18 peter * 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 642 1.1 toshii void 643 1.1 toshii sed1356_init_contrast(struct sed1356_softc *sc, int inattach) 644 1.1 toshii { 645 1.1 toshii int val = -1; 646 1.1 toshii 647 1.18 peter if (sc->sc_lcd_inited & CONTRAST_INITED) 648 1.1 toshii return; 649 1.1 toshii 650 1.1 toshii VPRINTF(("sed1356_init_contrast\n")); 651 1.18 peter if (config_hook_call(CONFIG_HOOK_GET, 652 1.18 peter CONFIG_HOOK_CONTRAST_MAX, &val) != -1) { 653 1.1 toshii /* we can get real contrast max */ 654 1.18 peter VPRINTF(("sed1356_init_contrast: " 655 1.18 peter "real contrast max=%d\n", val)); 656 1.1 toshii sc->sc_max_contrast = val; 657 1.1 toshii val = -1; 658 1.18 peter if (config_hook_call(CONFIG_HOOK_GET, 659 1.18 peter CONFIG_HOOK_CONTRAST, &val) != -1) { 660 1.1 toshii /* we can get real contrast */ 661 1.18 peter VPRINTF(("sed1356_init_contrast: " 662 1.18 peter "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.19 blymn /* 670 1.18 peter * we cannot get real contrast in attach time 671 1.18 peter * because contrast device not yet attached. 672 1.18 peter * 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 682 1.18 peter static void 683 1.1 toshii sed1356_set_brightness(struct sed1356_softc *sc, int val) 684 1.1 toshii { 685 1.1 toshii sc->sc_brightness = val; 686 1.1 toshii 687 1.1 toshii config_hook_call(CONFIG_HOOK_SET, CONFIG_HOOK_BRIGHTNESS, &val); 688 1.18 peter if (config_hook_call(CONFIG_HOOK_GET, 689 1.18 peter CONFIG_HOOK_BRIGHTNESS, &val) != -1) { 690 1.1 toshii sc->sc_brightness = val; 691 1.1 toshii } 692 1.1 toshii } 693 1.1 toshii 694 1.18 peter static void 695 1.1 toshii sed1356_set_contrast(struct sed1356_softc *sc, int val) 696 1.1 toshii { 697 1.1 toshii sc->sc_contrast = val; 698 1.1 toshii 699 1.1 toshii config_hook_call(CONFIG_HOOK_SET, CONFIG_HOOK_CONTRAST, &val); 700 1.18 peter if (config_hook_call(CONFIG_HOOK_GET, 701 1.18 peter CONFIG_HOOK_CONTRAST, &val) != -1) { 702 1.1 toshii sc->sc_contrast = val; 703 1.1 toshii } 704 1.1 toshii } 705 1.16 peter 706 1.16 peter void 707 1.16 peter sed1356_toggle_lcdlight(void) 708 1.16 peter { 709 1.23 rafal struct sed1356_softc *sc = device_lookup_private(&sed_cd, 0); 710 1.16 peter 711 1.16 peter if (sc->sc_powerstate & PWRSTAT_VIDEOOFF) 712 1.16 peter sc->sc_powerstate &= ~PWRSTAT_VIDEOOFF; 713 1.16 peter else 714 1.16 peter sc->sc_powerstate |= PWRSTAT_VIDEOOFF; 715 1.16 peter 716 1.16 peter sed1356_update_powerstate(sc, PWRSTAT_ALL); 717 1.16 peter } 718