Sync usage with man page.
[netbsd-mini2440.git] / sys / dev / hpc / bivideo.c
blob18288e58657fae7f934e96e8dfe1416ebca72cd3
1 /* $NetBSD: bivideo.c,v 1.29 2009/05/12 12:13:49 cegger Exp $ */
3 /*-
4 * Copyright (c) 1999-2001
5 * Shin Takemura and PocketBSD Project. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by the PocketBSD project
18 * and its contributors.
19 * 4. Neither the name of the project nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
37 #include <sys/cdefs.h>
38 __KERNEL_RCSID(0, "$NetBSD: bivideo.c,v 1.29 2009/05/12 12:13:49 cegger Exp $");
40 #ifdef _KERNEL_OPT
41 #include "opt_hpcfb.h"
42 #endif
44 #include <sys/param.h>
45 #include <sys/systm.h>
46 #include <sys/device.h>
47 #include <sys/buf.h>
48 #include <sys/ioctl.h>
49 #include <sys/reboot.h>
51 #include <uvm/uvm_extern.h>
53 #include <sys/bus.h>
54 #include <machine/autoconf.h>
55 #include <machine/bootinfo.h>
56 #include <machine/config_hook.h>
58 #include <dev/wscons/wsconsio.h>
59 #include <dev/wscons/wsdisplayvar.h>
61 #include <dev/rasops/rasops.h>
63 #include <dev/hpc/hpcfbvar.h>
64 #include <dev/hpc/hpcfbio.h>
65 #include <dev/hpc/bivideovar.h>
66 #include <dev/hpc/hpccmapvar.h>
68 #ifdef FBDEBUG
69 #define VPRINTF(arg) do { if (bootverbose) printf arg; } while (0)
70 #else
71 #define VPRINTF(arg) /* nothing */
72 #endif
75 * global variables
77 int bivideo_dont_attach = 0;
80 * function prototypes
82 int bivideomatch(device_t, cfdata_t, void *);
83 void bivideoattach(device_t, device_t, void *);
84 int bivideo_ioctl(void *, u_long, void *, int, struct lwp *);
85 paddr_t bivideo_mmap(void *, off_t, int);
87 struct bivideo_softc {
88 struct device sc_dev;
89 struct hpcfb_fbconf sc_fbconf;
90 struct hpcfb_dspconf sc_dspconf;
91 void *sc_powerhook; /* power management hook */
92 int sc_powerstate;
93 #define PWRSTAT_SUSPEND (1<<0)
94 #define PWRSTAT_VIDEOOFF (1<<1)
95 #define PWRSTAT_LCD (1<<2)
96 #define PWRSTAT_BACKLIGHT (1<<3)
97 #define PWRSTAT_ALL (0xffffffff)
98 int sc_lcd_inited;
99 #define BACKLIGHT_INITED (1<<0)
100 #define BRIGHTNESS_INITED (1<<1)
101 #define CONTRAST_INITED (1<<2)
102 int sc_brightness;
103 int sc_brightness_save;
104 int sc_max_brightness;
105 int sc_contrast;
106 int sc_max_contrast;
110 static int bivideo_init(struct hpcfb_fbconf *);
111 static void bivideo_power(int, void *);
112 static void bivideo_update_powerstate(struct bivideo_softc *, int);
113 void bivideo_init_backlight(struct bivideo_softc *, int);
114 void bivideo_init_brightness(struct bivideo_softc *, int);
115 void bivideo_init_contrast(struct bivideo_softc *, int);
116 void bivideo_set_brightness(struct bivideo_softc *, int);
117 void bivideo_set_contrast(struct bivideo_softc *, int);
119 #if defined __mips__ || defined __sh__ || defined __arm__
120 #define __BTOP(x) ((paddr_t)(x) >> PGSHIFT)
121 #define __PTOB(x) ((paddr_t)(x) << PGSHIFT)
122 #else
123 #error "define btop, ptob."
124 #endif
127 * static variables
129 CFATTACH_DECL(bivideo, sizeof(struct bivideo_softc),
130 bivideomatch, bivideoattach, NULL, NULL);
132 struct hpcfb_accessops bivideo_ha = {
133 bivideo_ioctl, bivideo_mmap
136 static int console_flag = 0;
137 static int attach_flag = 0;
140 * function bodies
143 bivideomatch(device_t parent, cfdata_t match, void *aux)
145 struct mainbus_attach_args *ma = aux;
147 if (bivideo_dont_attach ||
148 strcmp(ma->ma_name, match->cf_name))
149 return 0;
151 return (1);
154 void
155 bivideoattach(device_t parent, device_t self, void *aux)
157 struct bivideo_softc *sc = device_private(self);
158 struct hpcfb_attach_args ha;
160 if (attach_flag) {
161 panic("%s(%d): bivideo attached twice", __FILE__, __LINE__);
163 attach_flag = 1;
165 printf(": ");
166 if (bivideo_init(&sc->sc_fbconf) != 0) {
167 /* just return so that hpcfb will not be attached */
168 return;
171 printf("pseudo video controller");
172 if (console_flag) {
173 printf(", console");
175 printf("\n");
176 printf("%s: framebuffer address: 0x%08lx\n",
177 device_xname(&sc->sc_dev), (u_long)bootinfo->fb_addr);
179 /* Add a suspend hook to power saving */
180 sc->sc_powerstate = 0;
181 sc->sc_powerhook = powerhook_establish(device_xname(&sc->sc_dev),
182 bivideo_power, sc);
183 if (sc->sc_powerhook == NULL)
184 aprint_error_dev(&sc->sc_dev, "WARNING: unable to establish power hook\n");
186 /* initialize backlight brightness and lcd contrast */
187 sc->sc_lcd_inited = 0;
188 bivideo_init_brightness(sc, 1);
189 bivideo_init_contrast(sc, 1);
190 bivideo_init_backlight(sc, 1);
192 ha.ha_console = console_flag;
193 ha.ha_accessops = &bivideo_ha;
194 ha.ha_accessctx = sc;
195 ha.ha_curfbconf = 0;
196 ha.ha_nfbconf = 1;
197 ha.ha_fbconflist = &sc->sc_fbconf;
198 ha.ha_curdspconf = 0;
199 ha.ha_ndspconf = 1;
200 ha.ha_dspconflist = &sc->sc_dspconf;
202 config_found(self, &ha, hpcfbprint);
206 bivideo_getcnfb(struct hpcfb_fbconf *fb)
208 console_flag = 1;
210 return bivideo_init(fb);
213 static int
214 bivideo_init(struct hpcfb_fbconf *fb)
217 * get fb settings from bootinfo
219 if (bootinfo == NULL ||
220 bootinfo->fb_addr == 0 ||
221 bootinfo->fb_line_bytes == 0 ||
222 bootinfo->fb_width == 0 ||
223 bootinfo->fb_height == 0) {
224 printf("no frame buffer information.\n");
225 return (-1);
228 /* zero fill */
229 memset(fb, 0, sizeof(*fb));
231 fb->hf_conf_index = 0; /* configuration index */
232 fb->hf_nconfs = 1; /* how many configurations */
233 strcpy(fb->hf_name, "built-in video");
234 /* frame buffer name */
235 strcpy(fb->hf_conf_name, "default");
236 /* configuration name */
237 fb->hf_height = bootinfo->fb_height;
238 fb->hf_width = bootinfo->fb_width;
239 fb->hf_baseaddr = (u_long)bootinfo->fb_addr;
240 fb->hf_offset = (u_long)bootinfo->fb_addr -
241 __PTOB(__BTOP(bootinfo->fb_addr));
242 /* frame buffer start offset */
243 fb->hf_bytes_per_line = bootinfo->fb_line_bytes;
244 fb->hf_nplanes = 1;
245 fb->hf_bytes_per_plane = bootinfo->fb_height *
246 bootinfo->fb_line_bytes;
248 fb->hf_access_flags |= HPCFB_ACCESS_BYTE;
249 fb->hf_access_flags |= HPCFB_ACCESS_WORD;
250 fb->hf_access_flags |= HPCFB_ACCESS_DWORD;
252 switch (bootinfo->fb_type) {
254 * gray scale
256 case BIFB_D2_M2L_3:
257 case BIFB_D2_M2L_3x2:
258 fb->hf_access_flags |= HPCFB_ACCESS_REVERSE;
259 /* fall through */
260 case BIFB_D2_M2L_0:
261 case BIFB_D2_M2L_0x2:
262 fb->hf_class = HPCFB_CLASS_GRAYSCALE;
263 fb->hf_access_flags |= HPCFB_ACCESS_STATIC;
264 fb->hf_pack_width = 8;
265 fb->hf_pixels_per_pack = 4;
266 fb->hf_pixel_width = 2;
267 fb->hf_class_data_length = sizeof(struct hf_gray_tag);
268 fb->hf_u.hf_gray.hf_flags = 0; /* reserved for future use */
269 break;
271 case BIFB_D4_M2L_F:
272 case BIFB_D4_M2L_Fx2:
273 fb->hf_access_flags |= HPCFB_ACCESS_REVERSE;
274 /* fall through */
275 case BIFB_D4_M2L_0:
276 case BIFB_D4_M2L_0x2:
277 fb->hf_class = HPCFB_CLASS_GRAYSCALE;
278 fb->hf_access_flags |= HPCFB_ACCESS_STATIC;
279 fb->hf_pack_width = 8;
280 fb->hf_pixels_per_pack = 2;
281 fb->hf_pixel_width = 4;
282 fb->hf_class_data_length = sizeof(struct hf_gray_tag);
283 fb->hf_u.hf_gray.hf_flags = 0; /* reserved for future use */
284 break;
287 * indexed color
289 case BIFB_D8_FF:
290 fb->hf_access_flags |= HPCFB_ACCESS_REVERSE;
291 /* fall through */
292 case BIFB_D8_00:
293 fb->hf_class = HPCFB_CLASS_INDEXCOLOR;
294 fb->hf_access_flags |= HPCFB_ACCESS_STATIC;
295 fb->hf_pack_width = 8;
296 fb->hf_pixels_per_pack = 1;
297 fb->hf_pixel_width = 8;
298 fb->hf_class_data_length = sizeof(struct hf_indexed_tag);
299 fb->hf_u.hf_indexed.hf_flags = 0; /* reserved for future use */
300 break;
303 * RGB color
305 case BIFB_D16_FFFF:
306 fb->hf_access_flags |= HPCFB_ACCESS_REVERSE;
307 /* fall through */
308 case BIFB_D16_0000:
309 fb->hf_class = HPCFB_CLASS_RGBCOLOR;
310 fb->hf_access_flags |= HPCFB_ACCESS_STATIC;
311 #if BYTE_ORDER == LITTLE_ENDIAN
312 fb->hf_order_flags = HPCFB_REVORDER_BYTE;
313 #endif
314 fb->hf_pack_width = 16;
315 fb->hf_pixels_per_pack = 1;
316 fb->hf_pixel_width = 16;
318 fb->hf_class_data_length = sizeof(struct hf_rgb_tag);
319 fb->hf_u.hf_rgb.hf_flags = 0; /* reserved for future use */
321 fb->hf_u.hf_rgb.hf_red_width = 5;
322 fb->hf_u.hf_rgb.hf_red_shift = 11;
323 fb->hf_u.hf_rgb.hf_green_width = 6;
324 fb->hf_u.hf_rgb.hf_green_shift = 5;
325 fb->hf_u.hf_rgb.hf_blue_width = 5;
326 fb->hf_u.hf_rgb.hf_blue_shift = 0;
327 fb->hf_u.hf_rgb.hf_alpha_width = 0;
328 fb->hf_u.hf_rgb.hf_alpha_shift = 0;
329 break;
331 default:
332 printf("unsupported type %d.\n", bootinfo->fb_type);
333 return (-1);
334 break;
337 return (0); /* no error */
340 static void
341 bivideo_power(int why, void *arg)
343 struct bivideo_softc *sc = arg;
345 switch (why) {
346 case PWR_SUSPEND:
347 case PWR_STANDBY:
348 sc->sc_powerstate |= PWRSTAT_SUSPEND;
349 bivideo_update_powerstate(sc, PWRSTAT_ALL);
350 break;
351 case PWR_RESUME:
352 sc->sc_powerstate &= ~PWRSTAT_SUSPEND;
353 bivideo_update_powerstate(sc, PWRSTAT_ALL);
354 break;
358 static void
359 bivideo_update_powerstate(struct bivideo_softc *sc, int updates)
361 if (updates & PWRSTAT_LCD)
362 config_hook_call(CONFIG_HOOK_POWERCONTROL,
363 CONFIG_HOOK_POWERCONTROL_LCD,
364 (void*)!(sc->sc_powerstate &
365 (PWRSTAT_VIDEOOFF|PWRSTAT_SUSPEND)));
367 if (updates & PWRSTAT_BACKLIGHT)
368 config_hook_call(CONFIG_HOOK_POWERCONTROL,
369 CONFIG_HOOK_POWERCONTROL_LCDLIGHT,
370 (void*)(!(sc->sc_powerstate &
371 (PWRSTAT_VIDEOOFF|PWRSTAT_SUSPEND)) &&
372 (sc->sc_powerstate & PWRSTAT_BACKLIGHT)));
376 bivideo_ioctl(void *v, u_long cmd, void *data, int flag, struct lwp *l)
378 struct bivideo_softc *sc = (struct bivideo_softc *)v;
379 struct hpcfb_fbconf *fbconf;
380 struct hpcfb_dspconf *dspconf;
381 struct wsdisplay_cmap *cmap;
382 struct wsdisplay_param *dispparam;
383 int error;
385 switch (cmd) {
386 case WSDISPLAYIO_GETCMAP:
387 cmap = (struct wsdisplay_cmap *)data;
389 if (sc->sc_fbconf.hf_class != HPCFB_CLASS_INDEXCOLOR ||
390 sc->sc_fbconf.hf_pack_width != 8 ||
391 256 <= cmap->index ||
392 256 < (cmap->index + cmap->count))
393 return (EINVAL);
395 error = copyout(&bivideo_cmap_r[cmap->index], cmap->red,
396 cmap->count);
397 if (error)
398 return error;
399 error = copyout(&bivideo_cmap_g[cmap->index], cmap->green,
400 cmap->count);
401 if (error)
402 return error;
403 error = copyout(&bivideo_cmap_b[cmap->index], cmap->blue,
404 cmap->count);
405 return error;
407 case WSDISPLAYIO_PUTCMAP:
409 * This driver can't set color map.
411 return (EINVAL);
413 case WSDISPLAYIO_SVIDEO:
414 if (*(int *)data == WSDISPLAYIO_VIDEO_OFF)
415 sc->sc_powerstate |= PWRSTAT_VIDEOOFF;
416 else
417 sc->sc_powerstate &= ~PWRSTAT_VIDEOOFF;
418 bivideo_update_powerstate(sc, PWRSTAT_ALL);
419 return 0;
421 case WSDISPLAYIO_GVIDEO:
422 *(int *)data = (sc->sc_powerstate&PWRSTAT_VIDEOOFF) ?
423 WSDISPLAYIO_VIDEO_OFF:WSDISPLAYIO_VIDEO_ON;
424 return 0;
427 case WSDISPLAYIO_GETPARAM:
428 dispparam = (struct wsdisplay_param*)data;
429 switch (dispparam->param) {
430 case WSDISPLAYIO_PARAM_BACKLIGHT:
431 VPRINTF(("bivideo_ioctl: GET:BACKLIGHT\n"));
432 bivideo_init_brightness(sc, 0);
433 bivideo_init_backlight(sc, 0);
434 VPRINTF(("bivideo_ioctl: GET:(real)BACKLIGHT %d\n",
435 (sc->sc_powerstate&PWRSTAT_BACKLIGHT)? 1: 0));
436 dispparam->min = 0;
437 dispparam->max = 1;
438 if (sc->sc_max_brightness > 0)
439 dispparam->curval = sc->sc_brightness > 0? 1: 0;
440 else
441 dispparam->curval =
442 (sc->sc_powerstate&PWRSTAT_BACKLIGHT) ? 1: 0;
443 VPRINTF(("bivideo_ioctl: GET:BACKLIGHT:%d(%s)\n",
444 dispparam->curval,
445 sc->sc_max_brightness > 0? "brightness": "light"));
446 return 0;
447 break;
448 case WSDISPLAYIO_PARAM_CONTRAST:
449 VPRINTF(("bivideo_ioctl: GET:CONTRAST\n"));
450 bivideo_init_contrast(sc, 0);
451 if (sc->sc_max_contrast > 0) {
452 dispparam->min = 0;
453 dispparam->max = sc->sc_max_contrast;
454 dispparam->curval = sc->sc_contrast;
455 VPRINTF(("bivideo_ioctl: GET:CONTRAST max=%d, current=%d\n", sc->sc_max_contrast, sc->sc_contrast));
456 return 0;
457 } else {
458 VPRINTF(("bivideo_ioctl: GET:CONTRAST EINVAL\n"));
459 return (EINVAL);
461 break;
462 case WSDISPLAYIO_PARAM_BRIGHTNESS:
463 VPRINTF(("bivideo_ioctl: GET:BRIGHTNESS\n"));
464 bivideo_init_brightness(sc, 0);
465 if (sc->sc_max_brightness > 0) {
466 dispparam->min = 0;
467 dispparam->max = sc->sc_max_brightness;
468 dispparam->curval = sc->sc_brightness;
469 VPRINTF(("bivideo_ioctl: GET:BRIGHTNESS max=%d, current=%d\n", sc->sc_max_brightness, sc->sc_brightness));
470 return 0;
471 } else {
472 VPRINTF(("bivideo_ioctl: GET:BRIGHTNESS EINVAL\n"));
473 return (EINVAL);
475 return (EINVAL);
476 default:
477 return (EINVAL);
479 return (0);
481 case WSDISPLAYIO_SETPARAM:
482 dispparam = (struct wsdisplay_param*)data;
483 switch (dispparam->param) {
484 case WSDISPLAYIO_PARAM_BACKLIGHT:
485 VPRINTF(("bivideo_ioctl: SET:BACKLIGHT\n"));
486 if (dispparam->curval < 0 ||
487 1 < dispparam->curval)
488 return (EINVAL);
489 bivideo_init_brightness(sc, 0);
490 VPRINTF(("bivideo_ioctl: SET:max brightness=%d\n", sc->sc_max_brightness));
491 if (sc->sc_max_brightness > 0) { /* dimmer */
492 if (dispparam->curval == 0){
493 sc->sc_brightness_save = sc->sc_brightness;
494 bivideo_set_brightness(sc, 0); /* min */
495 } else {
496 if (sc->sc_brightness_save == 0)
497 sc->sc_brightness_save = sc->sc_max_brightness;
498 bivideo_set_brightness(sc, sc->sc_brightness_save);
500 VPRINTF(("bivideo_ioctl: SET:BACKLIGHT:brightness=%d\n", sc->sc_brightness));
501 } else { /* off */
502 if (dispparam->curval == 0)
503 sc->sc_powerstate &= ~PWRSTAT_BACKLIGHT;
504 else
505 sc->sc_powerstate |= PWRSTAT_BACKLIGHT;
506 VPRINTF(("bivideo_ioctl: SET:BACKLIGHT:powerstate %d\n",
507 (sc->sc_powerstate & PWRSTAT_BACKLIGHT)?1:0));
508 bivideo_update_powerstate(sc, PWRSTAT_BACKLIGHT);
509 VPRINTF(("bivideo_ioctl: SET:BACKLIGHT:%d\n",
510 (sc->sc_powerstate & PWRSTAT_BACKLIGHT)?1:0));
512 return 0;
513 break;
514 case WSDISPLAYIO_PARAM_CONTRAST:
515 VPRINTF(("bivideo_ioctl: SET:CONTRAST\n"));
516 bivideo_init_contrast(sc, 0);
517 if (dispparam->curval < 0 ||
518 sc->sc_max_contrast < dispparam->curval)
519 return (EINVAL);
520 if (sc->sc_max_contrast > 0) {
521 #ifdef FBDEBUG
522 int org = sc->sc_contrast;
523 #endif
524 bivideo_set_contrast(sc, dispparam->curval);
525 VPRINTF(("bivideo_ioctl: SET:CONTRAST org=%d, current=%d\n", org, sc->sc_contrast));
526 return 0;
527 } else {
528 VPRINTF(("bivideo_ioctl: SET:CONTRAST EINVAL\n"));
529 return (EINVAL);
531 break;
532 case WSDISPLAYIO_PARAM_BRIGHTNESS:
533 VPRINTF(("bivideo_ioctl: SET:BRIGHTNESS\n"));
534 bivideo_init_brightness(sc, 0);
535 if (dispparam->curval < 0 ||
536 sc->sc_max_brightness < dispparam->curval)
537 return (EINVAL);
538 if (sc->sc_max_brightness > 0) {
539 #ifdef FBDEBUG
540 int org = sc->sc_brightness;
541 #endif
542 bivideo_set_brightness(sc, dispparam->curval);
543 VPRINTF(("bivideo_ioctl: SET:BRIGHTNESS org=%d, current=%d\n", org, sc->sc_brightness));
544 return 0;
545 } else {
546 VPRINTF(("bivideo_ioctl: SET:BRIGHTNESS EINVAL\n"));
547 return (EINVAL);
549 break;
550 default:
551 return (EINVAL);
553 return (0);
555 case HPCFBIO_GCONF:
556 fbconf = (struct hpcfb_fbconf *)data;
557 if (fbconf->hf_conf_index != 0 &&
558 fbconf->hf_conf_index != HPCFB_CURRENT_CONFIG) {
559 return (EINVAL);
561 *fbconf = sc->sc_fbconf; /* structure assignment */
562 return (0);
563 case HPCFBIO_SCONF:
564 fbconf = (struct hpcfb_fbconf *)data;
565 if (fbconf->hf_conf_index != 0 &&
566 fbconf->hf_conf_index != HPCFB_CURRENT_CONFIG) {
567 return (EINVAL);
570 * nothing to do because we have only one configuration
572 return (0);
573 case HPCFBIO_GDSPCONF:
574 dspconf = (struct hpcfb_dspconf *)data;
575 if ((dspconf->hd_unit_index != 0 &&
576 dspconf->hd_unit_index != HPCFB_CURRENT_UNIT) ||
577 (dspconf->hd_conf_index != 0 &&
578 dspconf->hd_conf_index != HPCFB_CURRENT_CONFIG)) {
579 return (EINVAL);
581 *dspconf = sc->sc_dspconf; /* structure assignment */
582 return (0);
583 case HPCFBIO_SDSPCONF:
584 dspconf = (struct hpcfb_dspconf *)data;
585 if ((dspconf->hd_unit_index != 0 &&
586 dspconf->hd_unit_index != HPCFB_CURRENT_UNIT) ||
587 (dspconf->hd_conf_index != 0 &&
588 dspconf->hd_conf_index != HPCFB_CURRENT_CONFIG)) {
589 return (EINVAL);
592 * nothing to do
593 * because we have only one unit and one configuration
595 return (0);
596 case HPCFBIO_GOP:
597 case HPCFBIO_SOP:
599 * curently not implemented...
601 return (EINVAL);
604 return (EPASSTHROUGH);
607 paddr_t
608 bivideo_mmap(void *ctx, off_t offset, int prot)
610 struct bivideo_softc *sc = (struct bivideo_softc *)ctx;
612 if (offset < 0 ||
613 (sc->sc_fbconf.hf_bytes_per_plane +
614 sc->sc_fbconf.hf_offset) < offset)
615 return -1;
617 return __BTOP((u_long)bootinfo->fb_addr + offset);
621 void
622 bivideo_init_backlight(struct bivideo_softc *sc, int inattach)
624 int val = -1;
626 if (sc->sc_lcd_inited&BACKLIGHT_INITED)
627 return;
629 if (config_hook_call(CONFIG_HOOK_GET,
630 CONFIG_HOOK_POWER_LCDLIGHT, &val) != -1) {
631 /* we can get real light state */
632 VPRINTF(("bivideo_init_backlight: real backlight=%d\n", val));
633 if (val == 0)
634 sc->sc_powerstate &= ~PWRSTAT_BACKLIGHT;
635 else
636 sc->sc_powerstate |= PWRSTAT_BACKLIGHT;
637 sc->sc_lcd_inited |= BACKLIGHT_INITED;
638 } else if (inattach) {
640 we cannot get real light state in attach time
641 because light device not yet attached.
642 we will retry in !inattach.
643 temporary assume light is on.
645 sc->sc_powerstate |= PWRSTAT_BACKLIGHT;
646 } else {
647 /* we cannot get real light state, so work by myself state */
648 sc->sc_lcd_inited |= BACKLIGHT_INITED;
652 void
653 bivideo_init_brightness(struct bivideo_softc *sc, int inattach)
655 int val = -1;
657 if (sc->sc_lcd_inited&BRIGHTNESS_INITED)
658 return;
660 VPRINTF(("bivideo_init_brightness\n"));
661 if (config_hook_call(CONFIG_HOOK_GET,
662 CONFIG_HOOK_BRIGHTNESS_MAX, &val) != -1) {
663 /* we can get real brightness max */
664 VPRINTF(("bivideo_init_brightness: real brightness max=%d\n", val));
665 sc->sc_max_brightness = val;
666 val = -1;
667 if (config_hook_call(CONFIG_HOOK_GET,
668 CONFIG_HOOK_BRIGHTNESS, &val) != -1) {
669 /* we can get real brightness */
670 VPRINTF(("bivideo_init_brightness: real brightness=%d\n", val));
671 sc->sc_brightness_save = sc->sc_brightness = val;
672 } else {
673 sc->sc_brightness_save =
674 sc->sc_brightness = sc->sc_max_brightness;
676 sc->sc_lcd_inited |= BRIGHTNESS_INITED;
677 } else if (inattach) {
679 we cannot get real brightness in attach time
680 because brightness device not yet attached.
681 we will retry in !inattach.
683 sc->sc_max_brightness = -1;
684 sc->sc_brightness = -1;
685 sc->sc_brightness_save = -1;
686 } else {
687 /* we cannot get real brightness */
688 sc->sc_lcd_inited |= BRIGHTNESS_INITED;
691 return;
694 void
695 bivideo_init_contrast(struct bivideo_softc *sc, int inattach)
697 int val = -1;
699 if (sc->sc_lcd_inited&CONTRAST_INITED)
700 return;
702 VPRINTF(("bivideo_init_contrast\n"));
703 if (config_hook_call(CONFIG_HOOK_GET,
704 CONFIG_HOOK_CONTRAST_MAX, &val) != -1) {
705 /* we can get real contrast max */
706 VPRINTF(("bivideo_init_contrast: real contrast max=%d\n", val));
707 sc->sc_max_contrast = val;
708 val = -1;
709 if (config_hook_call(CONFIG_HOOK_GET,
710 CONFIG_HOOK_CONTRAST, &val) != -1) {
711 /* we can get real contrast */
712 VPRINTF(("bivideo_init_contrast: real contrast=%d\n", val));
713 sc->sc_contrast = val;
714 } else {
715 sc->sc_contrast = sc->sc_max_contrast;
717 sc->sc_lcd_inited |= CONTRAST_INITED;
718 } else if (inattach) {
720 we cannot get real contrast in attach time
721 because contrast device not yet attached.
722 we will retry in !inattach.
724 sc->sc_max_contrast = -1;
725 sc->sc_contrast = -1;
726 } else {
727 /* we cannot get real contrast */
728 sc->sc_lcd_inited |= CONTRAST_INITED;
731 return;
734 void
735 bivideo_set_brightness(struct bivideo_softc *sc, int val)
737 sc->sc_brightness = val;
739 config_hook_call(CONFIG_HOOK_SET, CONFIG_HOOK_BRIGHTNESS, &val);
740 if (config_hook_call(CONFIG_HOOK_GET,
741 CONFIG_HOOK_BRIGHTNESS, &val) != -1) {
742 sc->sc_brightness = val;
746 void
747 bivideo_set_contrast(struct bivideo_softc *sc, int val)
749 sc->sc_contrast = val;
751 config_hook_call(CONFIG_HOOK_SET, CONFIG_HOOK_CONTRAST, &val);
752 if (config_hook_call(CONFIG_HOOK_GET,
753 CONFIG_HOOK_CONTRAST, &val) != -1) {
754 sc->sc_contrast = val;