1 /* $NetBSD: bivideo.c,v 1.29 2009/05/12 12:13:49 cegger Exp $ */
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
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
37 #include <sys/cdefs.h>
38 __KERNEL_RCSID(0, "$NetBSD: bivideo.c,v 1.29 2009/05/12 12:13:49 cegger Exp $");
41 #include "opt_hpcfb.h"
44 #include <sys/param.h>
45 #include <sys/systm.h>
46 #include <sys/device.h>
48 #include <sys/ioctl.h>
49 #include <sys/reboot.h>
51 #include <uvm/uvm_extern.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>
69 #define VPRINTF(arg) do { if (bootverbose) printf arg; } while (0)
71 #define VPRINTF(arg) /* nothing */
77 int bivideo_dont_attach
= 0;
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
{
89 struct hpcfb_fbconf sc_fbconf
;
90 struct hpcfb_dspconf sc_dspconf
;
91 void *sc_powerhook
; /* power management hook */
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)
99 #define BACKLIGHT_INITED (1<<0)
100 #define BRIGHTNESS_INITED (1<<1)
101 #define CONTRAST_INITED (1<<2)
103 int sc_brightness_save
;
104 int sc_max_brightness
;
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)
123 #error "define btop, ptob."
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;
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
))
155 bivideoattach(device_t parent
, device_t self
, void *aux
)
157 struct bivideo_softc
*sc
= device_private(self
);
158 struct hpcfb_attach_args ha
;
161 panic("%s(%d): bivideo attached twice", __FILE__
, __LINE__
);
166 if (bivideo_init(&sc
->sc_fbconf
) != 0) {
167 /* just return so that hpcfb will not be attached */
171 printf("pseudo video controller");
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
),
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
;
197 ha
.ha_fbconflist
= &sc
->sc_fbconf
;
198 ha
.ha_curdspconf
= 0;
200 ha
.ha_dspconflist
= &sc
->sc_dspconf
;
202 config_found(self
, &ha
, hpcfbprint
);
206 bivideo_getcnfb(struct hpcfb_fbconf
*fb
)
210 return bivideo_init(fb
);
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");
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
;
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
) {
257 case BIFB_D2_M2L_3x2
:
258 fb
->hf_access_flags
|= HPCFB_ACCESS_REVERSE
;
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 */
272 case BIFB_D4_M2L_Fx2
:
273 fb
->hf_access_flags
|= HPCFB_ACCESS_REVERSE
;
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 */
290 fb
->hf_access_flags
|= HPCFB_ACCESS_REVERSE
;
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 */
306 fb
->hf_access_flags
|= HPCFB_ACCESS_REVERSE
;
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
;
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;
332 printf("unsupported type %d.\n", bootinfo
->fb_type
);
337 return (0); /* no error */
341 bivideo_power(int why
, void *arg
)
343 struct bivideo_softc
*sc
= arg
;
348 sc
->sc_powerstate
|= PWRSTAT_SUSPEND
;
349 bivideo_update_powerstate(sc
, PWRSTAT_ALL
);
352 sc
->sc_powerstate
&= ~PWRSTAT_SUSPEND
;
353 bivideo_update_powerstate(sc
, PWRSTAT_ALL
);
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
;
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
))
395 error
= copyout(&bivideo_cmap_r
[cmap
->index
], cmap
->red
,
399 error
= copyout(&bivideo_cmap_g
[cmap
->index
], cmap
->green
,
403 error
= copyout(&bivideo_cmap_b
[cmap
->index
], cmap
->blue
,
407 case WSDISPLAYIO_PUTCMAP
:
409 * This driver can't set color map.
413 case WSDISPLAYIO_SVIDEO
:
414 if (*(int *)data
== WSDISPLAYIO_VIDEO_OFF
)
415 sc
->sc_powerstate
|= PWRSTAT_VIDEOOFF
;
417 sc
->sc_powerstate
&= ~PWRSTAT_VIDEOOFF
;
418 bivideo_update_powerstate(sc
, PWRSTAT_ALL
);
421 case WSDISPLAYIO_GVIDEO
:
422 *(int *)data
= (sc
->sc_powerstate
&PWRSTAT_VIDEOOFF
) ?
423 WSDISPLAYIO_VIDEO_OFF
:WSDISPLAYIO_VIDEO_ON
;
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));
438 if (sc
->sc_max_brightness
> 0)
439 dispparam
->curval
= sc
->sc_brightness
> 0? 1: 0;
442 (sc
->sc_powerstate
&PWRSTAT_BACKLIGHT
) ? 1: 0;
443 VPRINTF(("bivideo_ioctl: GET:BACKLIGHT:%d(%s)\n",
445 sc
->sc_max_brightness
> 0? "brightness": "light"));
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) {
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
));
458 VPRINTF(("bivideo_ioctl: GET:CONTRAST EINVAL\n"));
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) {
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
));
472 VPRINTF(("bivideo_ioctl: GET:BRIGHTNESS EINVAL\n"));
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
)
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 */
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
));
502 if (dispparam
->curval
== 0)
503 sc
->sc_powerstate
&= ~PWRSTAT_BACKLIGHT
;
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));
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
)
520 if (sc
->sc_max_contrast
> 0) {
522 int org
= sc
->sc_contrast
;
524 bivideo_set_contrast(sc
, dispparam
->curval
);
525 VPRINTF(("bivideo_ioctl: SET:CONTRAST org=%d, current=%d\n", org
, sc
->sc_contrast
));
528 VPRINTF(("bivideo_ioctl: SET:CONTRAST EINVAL\n"));
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
)
538 if (sc
->sc_max_brightness
> 0) {
540 int org
= sc
->sc_brightness
;
542 bivideo_set_brightness(sc
, dispparam
->curval
);
543 VPRINTF(("bivideo_ioctl: SET:BRIGHTNESS org=%d, current=%d\n", org
, sc
->sc_brightness
));
546 VPRINTF(("bivideo_ioctl: SET:BRIGHTNESS EINVAL\n"));
556 fbconf
= (struct hpcfb_fbconf
*)data
;
557 if (fbconf
->hf_conf_index
!= 0 &&
558 fbconf
->hf_conf_index
!= HPCFB_CURRENT_CONFIG
) {
561 *fbconf
= sc
->sc_fbconf
; /* structure assignment */
564 fbconf
= (struct hpcfb_fbconf
*)data
;
565 if (fbconf
->hf_conf_index
!= 0 &&
566 fbconf
->hf_conf_index
!= HPCFB_CURRENT_CONFIG
) {
570 * nothing to do because we have only one configuration
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
)) {
581 *dspconf
= sc
->sc_dspconf
; /* structure assignment */
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
)) {
593 * because we have only one unit and one configuration
599 * curently not implemented...
604 return (EPASSTHROUGH
);
608 bivideo_mmap(void *ctx
, off_t offset
, int prot
)
610 struct bivideo_softc
*sc
= (struct bivideo_softc
*)ctx
;
613 (sc
->sc_fbconf
.hf_bytes_per_plane
+
614 sc
->sc_fbconf
.hf_offset
) < offset
)
617 return __BTOP((u_long
)bootinfo
->fb_addr
+ offset
);
622 bivideo_init_backlight(struct bivideo_softc
*sc
, int inattach
)
626 if (sc
->sc_lcd_inited
&BACKLIGHT_INITED
)
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
));
634 sc
->sc_powerstate
&= ~PWRSTAT_BACKLIGHT
;
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
;
647 /* we cannot get real light state, so work by myself state */
648 sc
->sc_lcd_inited
|= BACKLIGHT_INITED
;
653 bivideo_init_brightness(struct bivideo_softc
*sc
, int inattach
)
657 if (sc
->sc_lcd_inited
&BRIGHTNESS_INITED
)
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
;
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
;
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;
687 /* we cannot get real brightness */
688 sc
->sc_lcd_inited
|= BRIGHTNESS_INITED
;
695 bivideo_init_contrast(struct bivideo_softc
*sc
, int inattach
)
699 if (sc
->sc_lcd_inited
&CONTRAST_INITED
)
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
;
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
;
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;
727 /* we cannot get real contrast */
728 sc
->sc_lcd_inited
|= CONTRAST_INITED
;
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
;
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
;