Module Name:    src
Committed By:   jruoho
Date:           Thu Apr  8 09:35:15 UTC 2010

Added Files:
        src/sys/dev/acpi/wmi: files.wmi wmi_dell.c

Log Message:
Add WMI mappings for Dell laptops. Requested and tested by m...@.


To generate a diff of this commit:
cvs rdiff -u -r0 -r1.1 src/sys/dev/acpi/wmi/files.wmi \
    src/sys/dev/acpi/wmi/wmi_dell.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Added files:

Index: src/sys/dev/acpi/wmi/files.wmi
diff -u /dev/null src/sys/dev/acpi/wmi/files.wmi:1.1
--- /dev/null	Thu Apr  8 09:35:15 2010
+++ src/sys/dev/acpi/wmi/files.wmi	Thu Apr  8 09:35:15 2010
@@ -0,0 +1,6 @@
+#	$NetBSD: files.wmi,v 1.1 2010/04/08 09:35:15 jruoho Exp $
+
+# Dell WMI mappings
+device	wmidell: sysmon_power
+attach	wmidell at acpiwmibus
+file	dev/acpi/wmi/wmi_dell.c		wmidell
Index: src/sys/dev/acpi/wmi/wmi_dell.c
diff -u /dev/null src/sys/dev/acpi/wmi/wmi_dell.c:1.1
--- /dev/null	Thu Apr  8 09:35:15 2010
+++ src/sys/dev/acpi/wmi/wmi_dell.c	Thu Apr  8 09:35:15 2010
@@ -0,0 +1,231 @@
+/*	$NetBSD: wmi_dell.c,v 1.1 2010/04/08 09:35:15 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2009, 2010 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * 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 AUTHOR 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 AUTHOR 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: wmi_dell.c,v 1.1 2010/04/08 09:35:15 jruoho Exp $");
+
+#include <sys/param.h>
+#include <sys/device.h>
+
+#include <dev/acpi/acpireg.h>
+#include <dev/acpi/acpivar.h>
+#include <dev/acpi/wmi_acpivar.h>
+
+#include <dev/sysmon/sysmonvar.h>
+
+#define _COMPONENT			ACPI_RESOURCE_COMPONENT
+ACPI_MODULE_NAME			("wmi_dell")
+
+#define WMI_DELL_HOTKEY_BRIGHTNESS_DOWN	0xE005
+#define WMI_DELL_HOTKEY_BRIGHTNESS_UP	0xE006
+#define WMI_DELL_HOTKEY_DISPLAY_CYCLE	0xE00B
+#define WMI_DELL_HOTKEY_VOLUME_MUTE	0xE020
+#define WMI_DELL_HOTKEY_VOLUME_DOWN	0xE02E
+#define WMI_DELL_HOTKEY_VOLUME_UP	0xE030
+/*      WMI_DELL_HOTKEY_UNKNOWN		0xXXXX */
+
+#define WMI_DELL_PSW_DISPLAY_CYCLE	0
+#define WMI_DELL_PSW_COUNT		1
+
+#define WMI_DELL_GUID_EVENT		"9DBB5994-A997-11DA-B012-B622A1EF5492"
+
+struct wmi_dell_softc {
+	device_t		sc_dev;
+	device_t		sc_parent;
+	struct sysmon_pswitch	sc_smpsw[WMI_DELL_PSW_COUNT];
+	bool			sc_smpsw_valid;
+};
+
+static int	wmi_dell_match(device_t, cfdata_t, void *);
+static void	wmi_dell_attach(device_t, device_t, void *);
+static int	wmi_dell_detach(device_t, int);
+static void	wmi_dell_notify_handler(ACPI_HANDLE, uint32_t, void *);
+static bool	wmi_dell_suspend(device_t, const pmf_qual_t *);
+static bool	wmi_dell_resume(device_t, const pmf_qual_t *);
+
+CFATTACH_DECL_NEW(wmidell, sizeof(struct wmi_dell_softc),
+    wmi_dell_match, wmi_dell_attach, wmi_dell_detach, NULL);
+
+static int
+wmi_dell_match(device_t parent, cfdata_t match, void *aux)
+{
+	return acpi_wmi_guid_match(parent, WMI_DELL_GUID_EVENT);
+}
+
+static void
+wmi_dell_attach(device_t parent, device_t self, void *aux)
+{
+	struct wmi_dell_softc *sc = device_private(self);
+	ACPI_STATUS rv;
+	int e;
+
+	sc->sc_dev = self;
+	sc->sc_parent = parent;
+	sc->sc_smpsw_valid = true;
+
+	rv = acpi_wmi_event_register(parent, wmi_dell_notify_handler);
+
+	if (ACPI_FAILURE(rv)) {
+		aprint_error(": failed to install WMI notify handler\n");
+		return;
+	}
+
+	aprint_naive("\n");
+	aprint_normal(": Dell WMI mappings\n");
+
+	sc->sc_smpsw[WMI_DELL_PSW_DISPLAY_CYCLE].smpsw_name =
+	    PSWITCH_HK_DISPLAY_CYCLE;
+
+	sc->sc_smpsw[WMI_DELL_PSW_DISPLAY_CYCLE].smpsw_type =
+	    PSWITCH_TYPE_HOTKEY;
+
+	e = sysmon_pswitch_register(&sc->sc_smpsw[WMI_DELL_PSW_DISPLAY_CYCLE]);
+
+	if (e != 0)
+		sc->sc_smpsw_valid = false;
+
+	(void)pmf_device_register(self, wmi_dell_suspend, wmi_dell_resume);
+}
+
+static int
+wmi_dell_detach(device_t self, int flags)
+{
+	struct wmi_dell_softc *sc = device_private(self);
+	device_t parent = sc->sc_parent;
+	int i;
+
+	(void)pmf_device_deregister(self);
+	(void)acpi_wmi_event_register(parent, NULL);
+
+	if (sc->sc_smpsw_valid != true)
+		return 0;
+
+	for (i = 0; i < __arraycount(sc->sc_smpsw); i++)
+		sysmon_pswitch_unregister(&sc->sc_smpsw[i]);
+
+	return 0;
+}
+
+static bool
+wmi_dell_suspend(device_t self, const pmf_qual_t *qual)
+{
+	struct wmi_dell_softc *sc = device_private(self);
+	device_t parent = sc->sc_parent;
+
+	(void)acpi_wmi_event_register(parent, NULL);
+
+	return true;
+}
+
+static bool
+wmi_dell_resume(device_t self, const pmf_qual_t *qual)
+{
+	struct wmi_dell_softc *sc = device_private(self);
+	device_t parent = sc->sc_parent;
+
+	(void)acpi_wmi_event_register(parent, wmi_dell_notify_handler);
+
+	return true;
+}
+
+static void
+wmi_dell_notify_handler(ACPI_HANDLE hdl, uint32_t evt, void *aux)
+{
+	struct wmi_dell_softc *sc;
+	device_t self = aux;
+	ACPI_OBJECT *obj;
+	ACPI_BUFFER buf;
+	ACPI_STATUS rv;
+	uint32_t val;
+
+	sc = device_private(self);
+	rv = acpi_wmi_event_get(sc->sc_parent, evt, &buf);
+
+	if (ACPI_FAILURE(rv))
+		goto out;
+
+	obj = buf.Pointer;
+
+	if (obj->Type != ACPI_TYPE_BUFFER) {
+		rv = AE_TYPE;
+		goto out;
+	}
+
+	val = obj->Buffer.Pointer[1] & 0xFFFF;
+
+	switch (val) {
+
+	case WMI_DELL_HOTKEY_BRIGHTNESS_DOWN:
+		pmf_event_inject(NULL, PMFE_DISPLAY_BRIGHTNESS_DOWN);
+		break;
+
+	case WMI_DELL_HOTKEY_BRIGHTNESS_UP:
+		pmf_event_inject(NULL, PMFE_DISPLAY_BRIGHTNESS_UP);
+		break;
+
+	case WMI_DELL_HOTKEY_DISPLAY_CYCLE:
+
+		if (sc->sc_smpsw_valid != true) {
+			rv = AE_ABORT_METHOD;
+			break;
+		}
+
+		sysmon_pswitch_event(&sc->sc_smpsw[WMI_DELL_PSW_DISPLAY_CYCLE],
+		    PSWITCH_EVENT_PRESSED);
+		break;
+
+	case WMI_DELL_HOTKEY_VOLUME_MUTE:
+		pmf_event_inject(NULL, PMFE_AUDIO_VOLUME_TOGGLE);
+		break;
+
+	case WMI_DELL_HOTKEY_VOLUME_DOWN:
+		pmf_event_inject(NULL, PMFE_AUDIO_VOLUME_DOWN);
+		break;
+
+	case WMI_DELL_HOTKEY_VOLUME_UP:
+		pmf_event_inject(NULL, PMFE_AUDIO_VOLUME_UP);
+		break;
+
+	default:
+		aprint_debug_dev(sc->sc_dev,
+		    "unknown key 0x%02X for event 0x%02X\n", val, evt);
+		break;
+	}
+
+out:
+	if (buf.Pointer != NULL)
+		ACPI_FREE(buf.Pointer);
+
+	if (ACPI_FAILURE(rv))
+		aprint_error_dev(sc->sc_dev, "failed to get data for "
+		    "event 0x%02X: %s\n", evt, AcpiFormatException(rv));
+}

Reply via email to