diff options
author | Miod Vallat <miod@cvs.openbsd.org> | 2002-05-22 21:00:04 +0000 |
---|---|---|
committer | Miod Vallat <miod@cvs.openbsd.org> | 2002-05-22 21:00:04 +0000 |
commit | 41cf0fa328c7323b4f7f81f7fd5159ca0a925277 (patch) | |
tree | 95c3268e1aed8955381977d794079cde0ce98548 /sys | |
parent | 425d37fb7bc54822402ff5adbf93bb07ba12d041 (diff) |
- in the OpenFirmware console initialisation, check if the console device
has support for backlight control (laptops do, and probably machines with
a built-in monitor do as well).
- provide a function to set the screen brightness as well.
- use both changes above to add a screen blanker to the vgafb driver
- let the screen brightness and backlight be controlled via wsconsctl
- clean dust, KNF, and more symbolic names in the vgafb driver to make it
better readable
Initial code by myself, with some hacks from drahn@ later.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/arch/macppc/macppc/ofw_machdep.c | 46 | ||||
-rw-r--r-- | sys/arch/macppc/macppc/ofw_machdep.h | 54 | ||||
-rw-r--r-- | sys/arch/macppc/pci/vgafb.c | 156 | ||||
-rw-r--r-- | sys/arch/macppc/pci/vgafb_pci.c | 13 | ||||
-rw-r--r-- | sys/arch/macppc/pci/vgafbvar.h | 8 |
5 files changed, 217 insertions, 60 deletions
diff --git a/sys/arch/macppc/macppc/ofw_machdep.c b/sys/arch/macppc/macppc/ofw_machdep.c index 300785be0a7..1624d159b57 100644 --- a/sys/arch/macppc/macppc/ofw_machdep.c +++ b/sys/arch/macppc/macppc/ofw_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ofw_machdep.c,v 1.9 2002/04/29 01:34:58 drahn Exp $ */ +/* $OpenBSD: ofw_machdep.c,v 1.10 2002/05/22 21:00:00 miod Exp $ */ /* $NetBSD: ofw_machdep.c,v 1.1 1996/09/30 16:34:50 ws Exp $ */ /* @@ -50,6 +50,8 @@ #include <dev/ofw/openfirm.h> +#include <macppc/macppc/ofw_machdep.h> + #include <ukbd.h> #include <akbd.h> #include <dev/usb/ukbdvar.h> @@ -332,6 +334,8 @@ bus_space_handle_t cons_display_ctl_h; int cons_height, cons_width, cons_linebytes, cons_depth; int cons_display_ofh; u_int32_t cons_addr; +int cons_brightness; +int cons_backlight_available; #include "vgafb_pci.h" @@ -482,7 +486,9 @@ of_display_console() char name[32]; int len; int stdout_node; + int display_node; int err; + int backlight_control[2]; u_int32_t memtag, iotag; struct ppc_pci_chipset pa; struct { @@ -521,20 +527,25 @@ of_display_console() ofw_find_keyboard(); + display_node = stdout_node; len = OF_getprop(stdout_node, "assigned-addresses", addr, sizeof(addr)); if (len == -1) { - int node; - node = OF_parent(stdout_node); - len = OF_getprop(node, "name", name, 20); + display_node = OF_parent(stdout_node); + len = OF_getprop(display_node, "name", name, 20); name[len] = 0; printf("using parent %s:", name); - len = OF_getprop(node, "assigned-addresses", + len = OF_getprop(display_node, "assigned-addresses", addr, sizeof(addr)); if (len < sizeof(addr[0])) { panic(": no address\n"); } } + len = OF_getprop(display_node, "backlight-control", + backlight_control, sizeof(backlight_control)); + if (len > 0) + cons_backlight_available = 1; + memtag = ofw_make_tag(NULL, pcibus(addr[0].phys_hi), pcidev(addr[0].phys_hi), pcifunc(addr[0].phys_hi)); @@ -579,5 +590,30 @@ of_display_console() } #endif } + + of_setbrightness(DEFAULT_BRIGHTNESS); +#endif +} + +void +of_setbrightness(brightness) + int brightness; +{ + +#if NVGAFB_PCI > 0 + if (cons_backlight_available == 0) + return; + + if (brightness < MIN_BRIGHTNESS) + brightness = MIN_BRIGHTNESS; + else if (brightness > MAX_BRIGHTNESS) + brightness = MAX_BRIGHTNESS; + + cons_brightness = brightness; + + /* The OF method is called "set-contrast" but affects brightness. Don't ask. */ + OF_call_method_1("set-contrast", cons_display_ofh, 1, cons_brightness); + + /* XXX this routine should also save the brightness settings in the nvram */ #endif } diff --git a/sys/arch/macppc/macppc/ofw_machdep.h b/sys/arch/macppc/macppc/ofw_machdep.h new file mode 100644 index 00000000000..2d1d202b435 --- /dev/null +++ b/sys/arch/macppc/macppc/ofw_machdep.h @@ -0,0 +1,54 @@ +/* $OpenBSD: ofw_machdep.h,v 1.1 2002/05/22 21:00:00 miod Exp $ */ + +/* + * Copyright (c) 2002, Miodrag Vallat. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +/* + * Various console variables... + */ +extern int cons_displaytype; +extern bus_space_tag_t cons_membus; +extern bus_space_handle_t cons_display_mem_h; +extern bus_space_handle_t cons_display_ctl_h; +extern int cons_height, cons_width, cons_linebytes, cons_depth; +extern int cons_display_ofh; +extern u_int32_t cons_addr; +extern int cons_backlight_available; + +/* + * For some reason, setting the brightness under 0x29 from OF switches the + * backlight off, and it won't be switched on again until you set the + * brightness above 0x33. All hail hysteresis! -- miod + */ +#define MIN_BRIGHTNESS 0x34 +#define MAX_BRIGHTNESS 0xff +#define STEP_BRIGHTNESS 8 +#define DEFAULT_BRIGHTNESS 0x80 +extern int cons_brightness; + +void of_setbrightness(int); diff --git a/sys/arch/macppc/pci/vgafb.c b/sys/arch/macppc/pci/vgafb.c index 1a83b75f3b5..5e51da48f7a 100644 --- a/sys/arch/macppc/pci/vgafb.c +++ b/sys/arch/macppc/pci/vgafb.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vgafb.c,v 1.12 2002/05/18 20:20:17 drahn Exp $ */ +/* $OpenBSD: vgafb.c,v 1.13 2002/05/22 21:00:03 miod Exp $ */ /* $NetBSD: vga.c,v 1.3 1996/12/02 22:24:54 cgd Exp $ */ /* @@ -40,6 +40,13 @@ #include <dev/cons.h> #include <dev/ofw/openfirm.h> +#include <macppc/macppc/ofw_machdep.h> + +#if 0 +#include <dev/ic/mc6845.h> +#include <dev/ic/mc6845reg.h> +#include <dev/ic/vgareg.h> +#endif #include <dev/wscons/wsconsio.h> #include <dev/wscons/wsdisplayvar.h> @@ -47,18 +54,7 @@ #include <dev/rasops/rasops.h> #include <dev/wsfont/wsfont.h> -#include <arch/macppc/pci/vgafbvar.h> - -/* parameters set by OF to detect console */ -extern int cons_displaytype; -extern bus_space_tag_t cons_membus; -extern bus_space_handle_t cons_display_mem_h; -extern bus_space_handle_t cons_display_ctl_h; -extern int cons_width; -extern int cons_linebytes; -extern int cons_height; -extern int cons_depth; -extern int cons_display_ofh; +#include <macppc/pci/vgafbvar.h> struct cfdriver vgafb_cd = { NULL, "vgafb", DV_DULL, @@ -81,7 +77,7 @@ struct wsscreen_descr vgafb_stdscreen = { 0, 0, 0, WSSCREEN_UNDERLINE | WSSCREEN_HILIT | - WSSCREEN_REVERSE|WSSCREEN_WSCOLORS + WSSCREEN_REVERSE | WSSCREEN_WSCOLORS }; const struct wsscreen_descr *vgafb_scrlist[] = { &vgafb_stdscreen, @@ -92,15 +88,16 @@ struct wsscreen_list vgafb_screenlist = { sizeof(vgafb_scrlist) / sizeof(struct wsscreen_descr *), vgafb_scrlist }; - struct wsdisplay_accessops vgafb_accessops = { vgafb_ioctl, vgafb_mmap, vgafb_alloc_screen, vgafb_free_screen, vgafb_show_screen, - 0, /* load_font */ - 0 /* scrollback */ + NULL, /* load_font */ + NULL, /* scrollback */ + NULL, /* getchar */ + vgafb_burn, /* burner */ }; int vgafb_getcmap(struct vgafb_config *vc, struct wsdisplay_cmap *cm); @@ -136,8 +133,10 @@ vgafb_common_probe(iot, memt, iobase, iosize, membase, memsize, mmiobase, mmiosi gotio_d = 1; } if (mmiosize != 0) { +#if 0 printf("vgafb_common_probe, mmio base %x size %x\n", mmiobase, mmiosize); +#endif if (bus_space_map(iot, mmiobase, mmiosize, 0, &mmioh)) goto bad; printf("vgafb_common_probe, mmio done\n"); @@ -154,8 +153,8 @@ vgafb_common_probe(iot, memt, iobase, iosize, membase, memsize, mmiobase, mmiosi gotmem = 1; /* CR1 - Horiz. Display End */ - bus_space_write_1(iot, ioh_d, 4, 0x1); - width = bus_space_read_1(iot, ioh_d, 5); + bus_space_write_1(iot, ioh_d, MC6845_INDEX, CRTC_HDISPLE); + width = bus_space_read_1(iot, ioh_d, MC6845_DATA); /* this is not bit width yet */ /* use CR17 - mode control for this?? */ @@ -197,7 +196,6 @@ vgafb_common_setup(iot, memt, vc, iobase, iosize, membase, memsize, mmiobase, mm u_int32_t iobase, membase, mmiobase; size_t iosize, memsize, mmiosize; { - vc->vc_iot = iot; vc->vc_memt = memt; vc->vc_paddr = membase; @@ -217,7 +215,7 @@ vgafb_common_setup(iot, memt, vc, iobase, iosize, membase, memsize, mmiobase, mm #if 0 printf("commons setup mapping mem base %x size %x\n", membase, memsize); #endif - /* memsize should only be visable region for console */ + /* memsize should only be visible region for console */ memsize = cons_height * cons_linebytes; if (bus_space_map(vc->vc_memt, membase, memsize, 1, &vc->vc_memh)) panic("vgafb_common_setup: couldn't map memory"); @@ -230,24 +228,23 @@ vgafb_common_setup(iot, memt, vc, iobase, iosize, membase, memsize, mmiobase, mm #if 0 if (iosize != 0) { /* CR1 - Horiz. Display End */ - bus_space_write_1(iot, vc->vc_ioh_d, 4, 0x1); - width = bus_space_read_1(iot, vc->vc_ioh_d, 5); + bus_space_write_1(iot, vc->vc_ioh_d, MC6845_INDEX, CRTC_HDISPLE); + width = bus_space_read_1(iot, vc->vc_ioh_d, MC6845_DATA); /* (stored value + 1) * depth -> pixel width */ - width = ( width + 1 ) * 8; + width = (width + 1) * 8; /* CR1 - Horiz. Display End */ - bus_space_write_1(iot, vc->vc_ioh_d, 4, 0x12); { u_int8_t t1, t2, t3; - bus_space_write_1(iot, vc->vc_ioh_d, 4, 0x12); - t1 = bus_space_read_1(iot, vc->vc_ioh_d, 5); + bus_space_write_1(iot, vc->vc_ioh_d, MC6845_INDEX, CRTC_VDE); + t1 = bus_space_read_1(iot, vc->vc_ioh_d, MC6845_DATA); - bus_space_write_1(iot, vc->vc_ioh_d, 4, 0x7); - t2 = bus_space_read_1(iot, vc->vc_ioh_d, 5); + bus_space_write_1(iot, vc->vc_ioh_d, MC6845_INDEX, CRTC_OVERFLL); + t2 = bus_space_read_1(iot, vc->vc_ioh_d, MC6845_DATA); height = t1 + ((t2&0x40) << 3) + ((t2&0x02) << 7) + 1; - bus_space_write_1(iot, vc->vc_ioh_d, 4, 0x17); - t3 = bus_space_read_1(iot, vc->vc_ioh_d, 5); + bus_space_write_1(iot, vc->vc_ioh_d, MC6845_INDEX, CRTC_MODE); + t3 = bus_space_read_1(iot, vc->vc_ioh_d, MC6845_DATA); if (t3 & 0x04) { height *= 2; } @@ -298,9 +295,11 @@ void vgafb_restore_default_colors(struct vgafb_config *vc) { int i; + for (i = 0; i < 256; i++) { const u_char *color; - color = &rasops_cmap[i*3]; + + color = &rasops_cmap[i * 3]; vgafb_setcolor(vc, i, color[0], color[1], color[2]); } } @@ -317,6 +316,14 @@ vgafb_wsdisplay_attach(parent, vc, console) aa.scrdata = &vgafb_screenlist; aa.accessops = &vgafb_accessops; aa.accesscookie = vc; + + /* no need to keep the burner function if no hw support */ + if (cons_backlight_available == 0) + vgafb_accessops.burn_screen = NULL; + else { + vc->vc_backlight_on = WSDISPLAYIO_VIDEO_OFF; + vgafb_burn(vc, WSDISPLAYIO_VIDEO_ON, 0); /* paranoia */ + } config_found(parent, &aa, wsemuldisplaydevprint); } @@ -368,6 +375,49 @@ vgafb_ioctl(v, cmd, data, flag, p) * layer handle this ioctl */ return -1; + + case WSDISPLAYIO_GETPARAM: + { + struct wsdisplay_param *dp = (struct wsdisplay_param *)data; + + switch (dp->param) { + case WSDISPLAYIO_PARAM_BRIGHTNESS: + dp->min = MIN_BRIGHTNESS; + dp->max = MAX_BRIGHTNESS; + dp->curval = cons_brightness; + return 0; + case WSDISPLAYIO_PARAM_BACKLIGHT: + if (cons_backlight_available != 0) { + dp->min = 0; + dp->max = 1; + dp->curval = vc->vc_backlight_on; + return 0; + } else + return -1; + } + } + return -1; + + case WSDISPLAYIO_SETPARAM: + { + struct wsdisplay_param *dp = (struct wsdisplay_param *)data; + + switch (dp->param) { + case WSDISPLAYIO_PARAM_BRIGHTNESS: + of_setbrightness(dp->curval); + return 0; + case WSDISPLAYIO_PARAM_BACKLIGHT: + if (cons_backlight_available != 0) { + vgafb_burn(vc, + dp->curval ? WSDISPLAYIO_VIDEO_ON : + WSDISPLAYIO_VIDEO_OFF, 0); + return 0; + } else + return -1; + } + } + return -1; + case WSDISPLAYIO_SVIDEO: case WSDISPLAYIO_GVIDEO: case WSDISPLAYIO_GCURPOS: @@ -448,7 +498,7 @@ vgafb_cnprobe(cp) } cp->cn_pri = CN_REMOTE; - #if 0 +#if 0 for (j = 0; j < 2; j++) { for (i = 0; i < cons_width * cons_height; i++) { bus_space_write_1(cons_membus, @@ -456,13 +506,13 @@ vgafb_cnprobe(cp) } } - #endif +#endif } void vgafb_cnattach(iot, memt, pc, bus, device, function) - void * pc; + void *pc; bus_space_tag_t iot, memt; int bus, device, function; { @@ -476,7 +526,7 @@ vgafb_cnattach(iot, memt, pc, bus, device, function) ri->rc_sp->width = cons_width; ri->rc_sp->height = cons_height; ri->rc_sp->depth = cons_depth; - ri->rc_sp->linelongs = cons_linebytes /4; /* XXX */ + ri->rc_sp->linelongs = cons_linebytes / 4; /* XXX */ ri->rc_sp->pixels = (void *)cons_display_mem_h; ri->rc_crow = ri->rc_ccol = -1; @@ -491,7 +541,7 @@ vgafb_cnattach(iot, memt, pc, bus, device, function) ri->ri_stride = cons_linebytes; ri->ri_hw = dc; - rasops_init(ri, 160, 160); + rasops_init(ri, 160, 160); /* XXX */ vgafb_stdscreen.nrows = ri->ri_rows; vgafb_stdscreen.ncols = ri->ri_cols; @@ -557,14 +607,13 @@ vgafb_putcmap(vc, cm) int index = cm->index; int count = cm->count; int i; - u_char *r, *g, *b; + u_int8_t *r, *g, *b; - if (cm->index >= 256 || cm->count > 256 || - (cm->index + cm->count) > 256) + if (index >= 256 || count > 256 || index + count > 256) return EINVAL; - if (!uvm_useracc(cm->red, cm->count, B_READ) || - !uvm_useracc(cm->green, cm->count, B_READ) || - !uvm_useracc(cm->blue, cm->count, B_READ)) + if (!uvm_useracc(cm->red, count, B_READ) || + !uvm_useracc(cm->green, count, B_READ) || + !uvm_useracc(cm->blue, count, B_READ)) return EFAULT; copyin(cm->red, &(vc->vc_cmap_red[index]), count); copyin(cm->green, &(vc->vc_cmap_green[index]), count); @@ -578,9 +627,26 @@ vgafb_putcmap(vc, cm) vgafb_color[i].r = *r; vgafb_color[i].g = *g; vgafb_color[i].b = *b; - r++, g++, b++, index++; + r++, g++, b++; } OF_call_method_1("set-colors", cons_display_ofh, 3, - &vgafb_color, cm->index, count); + &vgafb_color, index, count); return 0; } + +void +vgafb_burn(v, on, flags) + void *v; + u_int on, flags; +{ + struct vgafb_config *vc = v; + + if (vc->vc_backlight_on != on) { + if (on == WSDISPLAYIO_VIDEO_ON) { + OF_call_method_1("backlight-on", cons_display_ofh, 0); + } else { + OF_call_method_1("backlight-off", cons_display_ofh, 0); + } + vc->vc_backlight_on = on; + } +} diff --git a/sys/arch/macppc/pci/vgafb_pci.c b/sys/arch/macppc/pci/vgafb_pci.c index 817b75ed218..362bbd0a3a1 100644 --- a/sys/arch/macppc/pci/vgafb_pci.c +++ b/sys/arch/macppc/pci/vgafb_pci.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vgafb_pci.c,v 1.7 2002/04/29 01:34:58 drahn Exp $ */ +/* $OpenBSD: vgafb_pci.c,v 1.8 2002/05/22 21:00:03 miod Exp $ */ /* $NetBSD: vga_pci.c,v 1.4 1996/12/05 01:39:38 cgd Exp $ */ /* @@ -115,8 +115,11 @@ vgafb_pci_probe(pa, id, ioaddr, iosize, memaddr, memsize, cacheable, mmioaddr, m PCI_MAPREG_TYPE_IO) { retval = pci_io_find(pc, pa->pa_tag, i, &addr, &size); - if (retval) { +#ifdef DEBUG_VGAFB printf("vgafb_pci_probe: io %x addr %x size %x\n", i, addr, size); +#endif + + if (retval) { return 0; } if (*iosize == 0) { @@ -132,12 +135,11 @@ vgafb_pci_probe(pa, id, ioaddr, iosize, memaddr, memsize, cacheable, mmioaddr, m #endif if (retval) { - printf("vgafb_pci_probe: mem %x addr %x size %x\n", i, addr, size); return 0; } if (size == 0) { /* ignore this entry */ - }else if (size <= (1024 * 1024)) { + } else if (size <= (1024 * 1024)) { #ifdef DEBUG_VGAFB printf("vgafb_pci_probe: mem %x addr %x size %x iosize %x\n", i, addr, size, *iosize); @@ -211,6 +213,7 @@ vgafb_pci_probe(pa, id, ioaddr, iosize, memaddr, memsize, cacheable, mmioaddr, m #endif return 1; } + int vgafb_pci_match(parent, match, aux) struct device *parent; @@ -325,8 +328,6 @@ vgafb_pci_attach(parent, self, aux) } vc->vc_mmap = vgafbpcimmap; vc->vc_ioctl = vgafbpciioctl; - vc->iobase = ioaddr; - vc->iosize = iosize; vc->membase = memaddr; vc->memsize = memsize; vc->mmiobase = mmioaddr; diff --git a/sys/arch/macppc/pci/vgafbvar.h b/sys/arch/macppc/pci/vgafbvar.h index 2cdb95a9af6..2ea89b9690b 100644 --- a/sys/arch/macppc/pci/vgafbvar.h +++ b/sys/arch/macppc/pci/vgafbvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: vgafbvar.h,v 1.6 2002/04/29 01:34:58 drahn Exp $ */ +/* $OpenBSD: vgafbvar.h,v 1.7 2002/05/22 21:00:03 miod Exp $ */ /* $NetBSD: vgavar.h,v 1.2 1996/11/23 06:06:43 cgd Exp $ */ /* @@ -57,14 +57,13 @@ struct vgafb_config { struct rasops_info dc_rinfo; /* raster display data*/ - bus_addr_t iobase; - bus_size_t iosize; - bus_addr_t membase; bus_size_t memsize; bus_addr_t mmiobase; bus_size_t mmiosize; + + int vc_backlight_on; }; int vgafb_common_probe(bus_space_tag_t, bus_space_tag_t, @@ -88,3 +87,4 @@ int vgafb_alloc_screen(void *v, const struct wsscreen_descr *type, void vgafb_free_screen(void *v, void *cookie); int vgafb_show_screen(void *v, void *cookie, int waitok, void (*cb)(void *, int, int), void *cbarg); +void vgafb_burn(void *v, u_int on, u_int flags); |