[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
backlight control via openfirmware
openbsdと見比べて適当に書きましたが、どうもiBookだとうまく
abtn*君が反応してくれません。ということでtester募集中。
itojun
Index: macppc/dev/abtn.c
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/macppc/dev/abtn.c,v
retrieving revision 1.3
diff -u -r1.3 abtn.c
--- macppc/dev/abtn.c 2001/06/08 00:32:01 1.3
+++ macppc/dev/abtn.c 2002/06/18 06:18:56
@@ -31,11 +31,12 @@
#include <sys/systm.h>
#include <macppc/dev/adbvar.h>
-#include <macppc/dev/pm_direct.h>
-#define NVRAM_BRIGHTNESS 0x140e
#define ABTN_HANDLER_ID 31
+#define STEP_BRIGHTNESS 8
+extern int ofb_setbrightness_console __P((int));
+
struct abtn_softc {
struct device sc_dev;
@@ -43,7 +44,6 @@
int adbaddr; /* current ADB address */
int handler_id;
- int brightness; /* backlight brightness */
int volume; /* speaker volume (not yet) */
};
@@ -78,15 +78,9 @@
struct abtn_softc *sc = (struct abtn_softc *)self;
struct adb_attach_args *aa = aux;
ADBSetInfoBlock adbinfo;
- int bright;
printf("brightness/volume button\n");
- bright = pm_read_nvram(NVRAM_BRIGHTNESS);
- if (bright != 0)
- pm_set_brightness(bright);
- sc->brightness = bright;
-
sc->origaddr = aa->origaddr;
sc->adbaddr = aa->adbaddr;
sc->handler_id = aa->handler_id;
@@ -102,26 +96,17 @@
caddr_t buffer, data;
int adb_command;
{
- struct abtn_softc *sc = (struct abtn_softc *)data;
u_int cmd;
cmd = buffer[1];
switch (cmd) {
case 0x0a:
- sc->brightness -= 8;
- if (sc->brightness < 8)
- sc->brightness = 8;
- pm_set_brightness(sc->brightness);
- pm_write_nvram(NVRAM_BRIGHTNESS, sc->brightness);
+ ofb_setbrightness_console(STEP_BRIGHTNESS);
break;
case 0x09:
- sc->brightness += 8;
- if (sc->brightness > 0x78)
- sc->brightness = 0x78;
- pm_set_brightness(sc->brightness);
- pm_write_nvram(NVRAM_BRIGHTNESS, sc->brightness);
+ ofb_setbrightness_console(-STEP_BRIGHTNESS);
break;
}
}
Index: macppc/dev/ofb.c
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/macppc/dev/ofb.c,v
retrieving revision 1.26
diff -u -r1.26 ofb.c
--- macppc/dev/ofb.c 2002/03/17 19:40:44 1.26
+++ macppc/dev/ofb.c 2002/06/18 06:18:56
@@ -55,6 +55,7 @@
#include <machine/grfioctl.h>
#include <macppc/dev/ofbvar.h>
+#include <macppc/dev/pm_direct.h>
#if OFB_ENABLE_CACHE
int ofb_enable_cache = 1;
@@ -62,6 +63,8 @@
int ofb_enable_cache = 0;
#endif
+#define NVRAM_BRIGHTNESS 0x140e
+
int ofbmatch __P((struct device *, struct cfdata *, void *));
void ofbattach __P((struct device *, struct device *, void *));
int ofbprint __P((void *, const char *));
@@ -97,6 +100,8 @@
static int ofb_show_screen __P((void *, void *, int,
void (*) (void *, int, int), void *));
static int copy_rom_font __P((void));
+static int ofb_setbrightness __P((struct ofb_devconfig *, int));
+static int ofb_burn __P((struct ofb_devconfig *, int));
struct wsdisplay_accessops ofb_accessops = {
ofb_ioctl,
@@ -213,6 +218,7 @@
{
struct rasops_info *ri = &dc->dc_ri;
int32_t addr, width, height, linebytes, depth;
+ int32_t backlight_control[2];
dc->dc_node = node;
if (dc->dc_ih == 0) {
@@ -235,6 +241,9 @@
depth = 8; /* XXX */
if (OF_getprop(node, "address", &addr, 4) != 4)
OF_interpret("frame-buffer-adr", 1, &addr);
+ if (OF_getprop(node, "backlight-control", backlight_control,
+ sizeof(backlight_control)) > 0)
+ dc->dc_backlight_available = 1;
if (width == -1 || height == -1 || addr == 0 || addr == -1)
return;
@@ -290,6 +299,9 @@
ofb_stdscreen.ncols = ri->ri_cols;
ofb_stdscreen.textops = &ri->ri_ops;
ofb_stdscreen.capabilities = ri->ri_caps;
+
+ if (dc->dc_backlight_available)
+ (void)ofb_setbrightness(dc, pm_read_nvram(NVRAM_BRIGHTNESS));
}
int
@@ -320,6 +332,7 @@
struct ofb_devconfig *dc = sc->sc_dc;
struct wsdisplay_fbinfo *wdf;
struct grfinfo *gm;
+ struct wsdisplay_param *dp;
switch (cmd) {
case WSDISPLAYIO_GTYPE:
@@ -347,6 +360,17 @@
gm->gd_fbaddr = (caddr_t)dc->dc_paddr;
gm->gd_fbrowbytes = dc->dc_ri.ri_stride;
return 0;
+
+ case WSDISPLAYIO_SETPARAM:
+ dp = (struct wsdisplay_param *)data;
+ switch (dp->param) {
+ case WSDISPLAYIO_PARAM_BRIGHTNESS:
+ return ofb_setbrightness(dc, dp->curval);
+ case WSDISPLAYIO_PARAM_BACKLIGHT:
+ return ofb_burn(dc, dp->curval ? WSDISPLAYIO_VIDEO_ON :
+ WSDISPLAYIO_VIDEO_OFF);
+ }
+ break;
}
return EPASSTHROUGH;
}
@@ -561,5 +585,57 @@
r++, g++, b++, index++;
}
+ return 0;
+}
+
+int
+ofb_setbrightness_console(step)
+ int step;
+{
+
+ return ofb_setbrightness(&ofb_console_dc,
+ ofb_console_dc.dc_brightness + step);
+}
+
+static int
+ofb_setbrightness(dc, brightness)
+ struct ofb_devconfig *dc;
+ int brightness;
+{
+
+ if (dc->dc_backlight_available == 0)
+ return EOPNOTSUPP;
+
+ if (brightness < MIN_BRIGHTNESS)
+ brightness = MIN_BRIGHTNESS;
+ else if (brightness < MAX_BRIGHTNESS)
+ brightness = MAX_BRIGHTNESS;
+
+ dc->dc_brightness = brightness;
+
+ /* The OF method is called "set-contrast" but affects brightness. Don't ask. */
+ OF_call_method_1("set-contrast", dc->dc_node, 1, dc->dc_brightness);
+
+ pm_write_nvram(NVRAM_BRIGHTNESS, dc->dc_brightness);
+
+ return 0;
+}
+
+static int
+ofb_burn(dc, on)
+ struct ofb_devconfig *dc;
+ int on;
+{
+
+ if (dc->dc_backlight_available == 0)
+ return EOPNOTSUPP;
+
+ if (dc->dc_backlight_on != on) {
+ if (on == WSDISPLAYIO_VIDEO_ON)
+ OF_call_method_1("backlight-on", dc->dc_ih, 0);
+ else
+ OF_call_method_1("backlight-off", dc->dc_ih, 0);
+ dc->dc_backlight_on = on;
+ }
return 0;
}
Index: macppc/dev/ofbvar.h
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/macppc/dev/ofbvar.h,v
retrieving revision 1.5
diff -u -r1.5 ofbvar.h
--- macppc/dev/ofbvar.h 2001/06/10 13:56:13 1.5
+++ macppc/dev/ofbvar.h 2002/06/18 06:18:56
@@ -32,6 +32,10 @@
int dc_node; /* phandle of this node */
int dc_ih; /* ihandle of this node */
struct rasops_info dc_ri;
+
+ int dc_backlight_available;
+ int dc_brightness;
+ int dc_backlight_on;
};
struct ofb_softc {
@@ -44,3 +48,15 @@
u_char sc_cmap_green[256];
u_char sc_cmap_blue[256];
};
+
+/*
+ * 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
+
+int ofb_setbrightness_console __P((int));