Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys Add valz(4), a simple driver to handle the backlight key...
details: https://anonhg.NetBSD.org/src/rev/c920ff0d8f64
branches: trunk
changeset: 753836:c920ff0d8f64
user: jakllsch <jakllsch%NetBSD.org@localhost>
date: Sun Apr 11 22:42:30 2010 +0000
description:
Add valz(4), a simple driver to handle the backlight keys on some
Toshiba laptops. As of yet only tested on a Satellite A135-S4527.
diffstat:
sys/arch/i386/conf/ALL | 7 +-
sys/dev/acpi/files.acpi | 7 +-
sys/dev/acpi/valz_acpi.c | 221 +++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 232 insertions(+), 3 deletions(-)
diffs (274 lines):
diff -r 61eca7103366 -r c920ff0d8f64 sys/arch/i386/conf/ALL
--- a/sys/arch/i386/conf/ALL Sun Apr 11 21:34:18 2010 +0000
+++ b/sys/arch/i386/conf/ALL Sun Apr 11 22:42:30 2010 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: ALL,v 1.253 2010/04/08 17:50:34 jruoho Exp $
+# $NetBSD: ALL,v 1.254 2010/04/11 22:42:30 jakllsch Exp $
# From NetBSD: GENERIC,v 1.787 2006/10/01 18:37:54 bouyer Exp
#
# ALL machine description file
@@ -17,7 +17,7 @@
options INCLUDE_CONFIG_FILE # embed config file in kernel binary
-#ident "ALL-$Revision: 1.253 $"
+#ident "ALL-$Revision: 1.254 $"
maxusers 64 # estimated number of users
@@ -406,6 +406,9 @@
# Toshiba Libretto devices
vald* at acpi?
+# Toshiba LCD brightness
+valz* at acpi?
+
# Plug-and-Play BIOS and attached devices
pnpbios* at mainbus?
diff -r 61eca7103366 -r c920ff0d8f64 sys/dev/acpi/files.acpi
--- a/sys/dev/acpi/files.acpi Sun Apr 11 21:34:18 2010 +0000
+++ b/sys/dev/acpi/files.acpi Sun Apr 11 22:42:30 2010 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: files.acpi,v 1.71 2010/04/10 17:55:24 jruoho Exp $
+# $NetBSD: files.acpi,v 1.72 2010/04/11 22:42:30 jakllsch Exp $
include "dev/acpi/acpica/files.acpica"
@@ -132,6 +132,11 @@
attach vald at acpinodebus with vald_acpi
file dev/acpi/vald_acpi.c vald_acpi
+# Toshiba backlight hotkeys
+device valz
+attach valz at acpinodebus
+file dev/acpi/valz_acpi.c valz
+
# Sony SPIC (jog dial etc.)
attach spic at acpinodebus with spic_acpi
file dev/acpi/spic_acpi.c spic_acpi
diff -r 61eca7103366 -r c920ff0d8f64 sys/dev/acpi/valz_acpi.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/dev/acpi/valz_acpi.c Sun Apr 11 22:42:30 2010 +0000
@@ -0,0 +1,221 @@
+/* $NetBSD: valz_acpi.c,v 1.1 2010/04/11 22:42:30 jakllsch Exp $ */
+
+/*
+ * Copyright (c) 2010 Jonathan A. Kollasch
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 COPYRIGHT HOLDER OR
+ * CONTRIBUTORS 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.
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: valz_acpi.c,v 1.1 2010/04/11 22:42:30 jakllsch Exp $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/syslog.h>
+
+#include <dev/acpi/acpireg.h>
+#include <dev/acpi/acpivar.h>
+
+struct valz_softc {
+ device_t sc_dev;
+ ACPI_HANDLE sc_lcd;
+};
+
+enum valz_action {
+ VALZ_BACKLIGHT_NOCHANGE,
+ VALZ_BACKLIGHT_DECREASE,
+ VALZ_BACKLIGHT_INCREASE,
+};
+
+static const char * const valz_hids[] = {
+ "TOS1900",
+ NULL
+};
+
+static int valz_match(device_t, cfdata_t, void *);
+static void valz_attach(device_t, device_t, void *);
+static ACPI_STATUS valz_check_bcl(ACPI_HANDLE, UINT32, void*, void **);
+static void valz_locate_lcd(struct valz_softc *);
+static void valz_lcd_notify_handler(ACPI_HANDLE, UINT32, void *);
+static void valz_adjust_backlight(struct valz_softc *, enum valz_action);
+static void valz_pmf_brightness_decrease(device_t);
+static void valz_pmf_brightness_increase(device_t);
+
+CFATTACH_DECL_NEW(valz, sizeof(struct valz_softc),
+ valz_match, valz_attach, NULL, NULL);
+
+static int
+valz_match(device_t parent, cfdata_t match, void *aux)
+{
+ struct acpi_attach_args *aa = aux;
+
+ if (aa->aa_node->ad_type != ACPI_TYPE_DEVICE)
+ return 0;
+
+ return acpi_match_hid(aa->aa_node->ad_devinfo, valz_hids);
+}
+
+static void
+valz_attach(device_t parent, device_t self, void *aux)
+{
+ struct valz_softc *sc;
+ ACPI_STATUS rv;
+
+ aprint_naive("\n");
+ aprint_normal("\n");
+
+ sc = device_private(self);
+ sc->sc_dev = self;
+ sc->sc_lcd = NULL;
+
+ valz_locate_lcd(sc);
+
+ if (sc->sc_lcd == NULL) {
+ aprint_error_dev(self, "failed to find a usable LCD\n");
+ return;
+ }
+
+ if(!pmf_event_register(self, PMFE_DISPLAY_BRIGHTNESS_DOWN,
+ valz_pmf_brightness_decrease, false))
+ aprint_error_dev(self, "failed to register event handler\n");
+
+ if(!pmf_event_register(self, PMFE_DISPLAY_BRIGHTNESS_UP,
+ valz_pmf_brightness_increase, false))
+ aprint_error_dev(self, "failed to register event handler\n");
+
+ rv = AcpiInstallNotifyHandler(sc->sc_lcd, ACPI_DEVICE_NOTIFY,
+ valz_lcd_notify_handler, sc);
+ if (ACPI_FAILURE(rv))
+ aprint_error_dev(self, "failed to install notify handler; %s\n",
+ AcpiFormatException(rv));
+}
+
+static void
+valz_lcd_notify_handler(ACPI_HANDLE handle, UINT32 notify, void *context)
+{
+ struct valz_softc *sc = context;
+
+ /* XXX magic */
+ switch (notify) {
+ case 0x86:
+ pmf_event_inject(sc->sc_dev, PMFE_DISPLAY_BRIGHTNESS_UP);
+ break;
+ case 0x87:
+ pmf_event_inject(sc->sc_dev, PMFE_DISPLAY_BRIGHTNESS_DOWN);
+ break;
+ default:
+ log(LOG_INFO, "%s: unknown notify: 0x%x\n",
+ device_xname(sc->sc_dev), notify);
+ break;
+ }
+}
+
+static void
+valz_locate_lcd(struct valz_softc *sc)
+{
+ ACPI_HANDLE parent;
+ ACPI_STATUS rv;
+
+ rv = AcpiGetHandle(ACPI_ROOT_OBJECT, "\\_SB_", &parent);
+ if (ACPI_FAILURE(rv))
+ return;
+
+ AcpiWalkNamespace(ACPI_TYPE_DEVICE, parent, 100,
+ valz_check_bcl, NULL, sc, NULL);
+}
+
+static ACPI_STATUS
+valz_check_bcl(ACPI_HANDLE handle, UINT32 level, void *context, void **status)
+{
+ struct valz_softc *sc = context;
+ ACPI_STATUS rv;
+ ACPI_BUFFER buf;
+
+ rv = acpi_eval_struct(handle, "_BCL", &buf);
+ if (ACPI_FAILURE(rv))
+ return AE_OK;
+
+ sc->sc_lcd = handle;
+
+ if (buf.Pointer)
+ AcpiOsFree(buf.Pointer);
+
+ return AE_OK;
+}
+
+static void
+valz_adjust_backlight(struct valz_softc *sc, enum valz_action action)
+{
+ ACPI_STATUS rv;
+ ACPI_INTEGER old_level, new_level;
+
+ if (sc->sc_lcd == NULL)
+ return;
+
+ /* Get current backlight level. */
+ rv = acpi_eval_integer(sc->sc_lcd, "_BQC", &old_level);
+ if (ACPI_FAILURE(rv)) {
+ log(LOG_CRIT, "%s: _BQC failed evaluation: %s\n",
+ device_xname(sc->sc_dev), AcpiFormatException(rv));
+ return;
+ }
+
+ new_level = old_level;
+
+ switch (action) {
+ case VALZ_BACKLIGHT_DECREASE:
+ if(old_level >= 10)
+ new_level -= 10;
+ break;
+ case VALZ_BACKLIGHT_INCREASE:
+ if(old_level <= 60)
+ new_level += 10;
+ break;
+ default:
+ return;
+ }
+
+ if (new_level == old_level)
+ return;
+
+ rv = acpi_eval_set_integer(sc->sc_lcd, "_BCM", new_level);
+ if (ACPI_FAILURE(rv))
+ log(LOG_CRIT, "%s: _BCM failed evaluation: %s\n",
+ device_xname(sc->sc_dev), AcpiFormatException(rv));
+}
+
+static void
+valz_pmf_brightness_decrease(device_t self)
+{
+ struct valz_softc *sc;
+ sc = device_private(self);
+ valz_adjust_backlight(sc, VALZ_BACKLIGHT_DECREASE);
+}
+
+static void
+valz_pmf_brightness_increase(device_t self)
+{
+ struct valz_softc *sc;
+ sc = device_private(self);
+ valz_adjust_backlight(sc, VALZ_BACKLIGHT_INCREASE);
+}
Home |
Main Index |
Thread Index |
Old Index