summaryrefslogtreecommitdiff
path: root/sys/dev/acpi
diff options
context:
space:
mode:
authorjoshua stein <jcs@cvs.openbsd.org>2008-12-23 16:56:15 +0000
committerjoshua stein <jcs@cvs.openbsd.org>2008-12-23 16:56:15 +0000
commit21a9cc4ff82916910a584c9ffd8dd1efda0d8db3 (patch)
tree2e976953793667d6fddf058eaec0027ac0f6bd8b /sys/dev/acpi
parentfc96378261a86e53aa8810c04c588826c578d28f (diff)
only a small number of thinkpads need the brightness adjustments
done in this driver, so for everything other than the x61s and t61, tell the bios to adjust brightness itself. fixes the double adjustment problem on newer models. tested on quite a few different models.
Diffstat (limited to 'sys/dev/acpi')
-rw-r--r--sys/dev/acpi/acpithinkpad.c69
1 files changed, 56 insertions, 13 deletions
diff --git a/sys/dev/acpi/acpithinkpad.c b/sys/dev/acpi/acpithinkpad.c
index 24f79f76af8..7f6134732a6 100644
--- a/sys/dev/acpi/acpithinkpad.c
+++ b/sys/dev/acpi/acpithinkpad.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: acpithinkpad.c,v 1.13 2008/11/06 23:41:28 marco Exp $ */
+/* $OpenBSD: acpithinkpad.c,v 1.14 2008/12/23 16:56:14 jcs Exp $ */
/*
* Copyright (c) 2008 joshua stein <jcs@openbsd.org>
*
@@ -32,6 +32,9 @@
#define THINKPAD_CMOS_BRIGHTNESS_UP 0x04
#define THINKPAD_CMOS_BRIGHTNESS_DOWN 0x05
+#define THINKPAD_EC_BRIGHTNESS_OFFSET 0x31
+#define THINKPAD_EC_BRIGHTNESS_LEVEL_MASK 0x1f
+
#define THINKPAD_BLUETOOTH_PRESENT 0x01
#define THINKPAD_BLUETOOTH_ENABLED 0x02
@@ -82,6 +85,17 @@ struct acpithinkpad_softc {
struct aml_node *sc_devnode;
};
+/* from bios.c */
+extern char *hw_ver;
+
+/* models (according to smbios info version) that need a brightness helper */
+const char *acpithinkpad_models_to_help[] = {
+ "ThinkPad X61s",
+ "ThinkPad T61",
+};
+
+int thinkpad_need_helper = 0;
+
int thinkpad_match(struct device *, void *, void *);
void thinkpad_attach(struct device *, struct device *, void *);
int thinkpad_hotkey(struct aml_node *, int, void *);
@@ -92,8 +106,9 @@ int thinkpad_cmos(struct acpithinkpad_softc *sc, uint8_t);
int thinkpad_volume_down(struct acpithinkpad_softc *);
int thinkpad_volume_up(struct acpithinkpad_softc *);
int thinkpad_volume_mute(struct acpithinkpad_softc *);
-int thinkpad_brightness_up(struct acpithinkpad_softc *);
+int thinkpad_brightness_get(struct acpithinkpad_softc *);
int thinkpad_brightness_down(struct acpithinkpad_softc *);
+int thinkpad_brightness_up(struct acpithinkpad_softc *);
struct cfattach acpithinkpad_ca = {
sizeof(struct acpithinkpad_softc), thinkpad_match, thinkpad_attach
@@ -132,11 +147,22 @@ thinkpad_attach(struct device *parent, struct device *self, void *aux)
{
struct acpithinkpad_softc *sc = (struct acpithinkpad_softc *)self;
struct acpi_attach_args *aa = aux;
+ int i;
sc->sc_acpi = (struct acpi_softc *)parent;
sc->sc_devnode = aa->aaa_node;
- printf("\n");
+ for (i = 0; i < nitems(acpithinkpad_models_to_help); i++)
+ if (strcmp(hw_ver, acpithinkpad_models_to_help[i]) == 0) {
+ printf(": activating brightness helper");
+ thinkpad_need_helper = 1;
+ break;
+ }
+
+ /* for models that don't need a brightness helper, tell the bios to
+ * adjust brightness it self */
+ if (!thinkpad_need_helper)
+ thinkpad_brightness_get(sc);
/* set event mask to receive everything */
thinkpad_enable_events(sc);
@@ -144,6 +170,8 @@ thinkpad_attach(struct device *parent, struct device *self, void *aux)
/* run thinkpad_hotkey on button presses */
aml_register_notify(sc->sc_devnode, aa->aaa_dev,
thinkpad_hotkey, sc, ACPIDEV_NOPOLL);
+
+ printf("\n");
}
int
@@ -203,6 +231,7 @@ thinkpad_hotkey(struct aml_node *node, int notify_type, void *arg)
if (aml_evalname(sc->sc_acpi, sc->sc_devnode, "MHKP", 0, NULL,
&res))
goto done;
+
val = aml_val2int(&res);
aml_freevalue(&res);
if (val == 0)
@@ -215,25 +244,27 @@ thinkpad_hotkey(struct aml_node *node, int notify_type, void *arg)
switch (type) {
case 1:
switch (event) {
- case THINKPAD_BUTTON_BRIGHTNESS_UP:
- thinkpad_brightness_up(sc);
- handled = 1;
- break;
- case THINKPAD_BUTTON_BRIGHTNESS_DOWN:
- thinkpad_brightness_down(sc);
- handled = 1;
- break;
case THINKPAD_BUTTON_WIRELESS:
thinkpad_toggle_bluetooth(sc);
handled = 1;
break;
case THINKPAD_BUTTON_SUSPEND:
handled = 1;
- /*
+ /*
acpi_enter_sleep_state(sc->sc_acpi,
ACPI_STATE_S3);
*/
break;
+ case THINKPAD_BUTTON_BRIGHTNESS_UP:
+ if (thinkpad_need_helper)
+ thinkpad_brightness_up(sc);
+ handled = 1;
+ break;
+ case THINKPAD_BUTTON_BRIGHTNESS_DOWN:
+ if (thinkpad_need_helper)
+ thinkpad_brightness_down(sc);
+ handled = 1;
+ break;
case THINKPAD_BUTTON_HIBERNATE:
case THINKPAD_BUTTON_FN_F1:
case THINKPAD_BUTTON_LOCK_SCREEN:
@@ -338,7 +369,7 @@ int
thinkpad_toggle_wan(struct acpithinkpad_softc *sc)
{
struct aml_value res, arg;
- int wan, rv = 1;;
+ int wan, rv = 1;
if (aml_evalname(sc->sc_acpi, sc->sc_devnode, "GWAN", 0, NULL, &res))
goto fail;
@@ -398,6 +429,18 @@ thinkpad_volume_mute(struct acpithinkpad_softc *sc)
}
int
+thinkpad_brightness_get(struct acpithinkpad_softc *sc)
+{
+ uint8_t val;
+ int level;
+
+ acpiec_read(sc->sc_acpi->sc_ec, THINKPAD_EC_BRIGHTNESS_OFFSET, 1, &val);
+ level = val & THINKPAD_EC_BRIGHTNESS_LEVEL_MASK;
+
+ return level;
+}
+
+int
thinkpad_brightness_up(struct acpithinkpad_softc *sc)
{
return (thinkpad_cmos(sc, THINKPAD_CMOS_BRIGHTNESS_UP));