NetBSD Problem Report #46870

From www@NetBSD.org  Wed Aug 29 08:38:10 2012
Return-Path: <www@NetBSD.org>
Received: from mail.netbsd.org (mail.netbsd.org [149.20.53.66])
	by www.NetBSD.org (Postfix) with ESMTP id DC38E63B8E6
	for <gnats-bugs@gnats.NetBSD.org>; Wed, 29 Aug 2012 08:38:09 +0000 (UTC)
Message-Id: <20120829083809.424CE63B86D@www.NetBSD.org>
Date: Wed, 29 Aug 2012 08:38:09 +0000 (UTC)
From: nathanialsloss@yahoo.com.au
Reply-To: nathanialsloss@yahoo.com.au
To: gnats-bugs@NetBSD.org
Subject: acpi support for panasonic toughbook computers.
X-Send-Pr-Version: www-1.0

>Number:         46870
>Category:       kern
>Synopsis:       acpi support for panasonic toughbook computers.
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    nat
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Wed Aug 29 08:40:00 +0000 2012
>Last-Modified:  Tue Nov 08 19:32:55 +0000 2016
>Originator:     Nat Sloss
>Release:        NetBSD Current 6.99.7
>Organization:
>Environment:
NetBSD beast 6.99.7 NetBSD 6.99.7 (LOCKDEBUG) #186: Wed Jul  4 05:47:37 EST 2012  build@beast:/usr/src/sys/arch/i386/compile/obj/LOCKDEBUG i386

>Description:
No Support exists for Panasonic Toughbook computers, although support exists in Linux and FreeBSD.
>How-To-Repeat:
Use NetBSD with a toughbook computer and you'll find most of the hotkeys and tablet buttons (applicable models) don't work.
>Fix:
I found support for it in FreeBSD in 2006 and ported it to NetBSD 3.0.1.  I made many changes since then adding and removing support for hw registers and sysctls to suit.  Only to finally simplify it for submission.

Also in 2008 I added support for the tablet buttons on the CF18/19 models.  Modified it further this year to make it a separate file.

I don't think there is support for tablet buttons in other OSs except Windows.

I'll add the drivers and manual pages to this PR.

Regards,

Nat.

>Release-Note:

>Audit-Trail:
From: Nat Sloss <nathanialsloss@yahoo.com.au>
To: gnats-bugs@netbsd.org
Cc: 
Subject: Re: kern/46870
Date: Wed, 29 Aug 2012 18:40:38 +1000

 Hi.

 Here are the files:

 --- /dev/null	2012-08-29 17:38:04.000000000 +1000
 +++ ../../sys/dev/acpi/panasonic_acpi.c	2012-08-29 16:55:51.000000000 +1000
 @@ -0,0 +1,626 @@
 +/*-
 + * Copyright (c) 2006-2012 Nathanial Sloss <nathanialsloss@yahoo.com.au>
 + * 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
 + */
 +
 +/*-
 + * Copyright (c) 2003 OGAWA Takaya <t-ogawa@triaez.kaisei.org>
 + * Copyright (c) 2004 Yoshihiro TAKAHASHI <nyan@FreeBSD.org>
 + * 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 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>
 +
 +#include <sys/types.h>
 +#include <sys/param.h>
 +#include <sys/buf.h>
 +#include <sys/callout.h>
 +#include <sys/device.h>
 +#include <sys/kernel.h>
 +#include <sys/malloc.h>
 +#include <sys/pmf.h>
 +#include <sys/sysctl.h>
 +
 +#include <dev/acpi/acpivar.h>
 +#include <dev/acpi/acpireg.h>
 +
 +#include <dev/sysmon/sysmonvar.h>
 +
 +#include <sys/fcntl.h>
 +
 +typedef struct panasonic_softc {
 +	device_t		sc_dev;
 +	struct acpi_devnode	*sc_node;
 +
 +	int			sc_brightness;
 +	int			sc_brightness_min;
 +	int			sc_brightness_max;
 +
 +#define PANASONIC_PSW_SLEEP			0
 +#define	PANASONIC_PSW_HIBERNATE			1
 +#define	PANASONIC_PSW_DISPLAY_CYCLE		2
 +#define	PANASONIC_PSW_BATTERY_INFO		3
 +#define PANASONIC_PSW_LAST			4
 +
 +	struct sysmon_pswitch	sc_smpsw[PANASONIC_PSW_LAST];
 +	bool			sc_smpsw_valid;
 +
 +	struct sysctllog	*sc_log;
 +	int			sc_brightness_mib;
 +
 +} panasonic_softc_t;
 +
 +/* Hotkey buttons (HKEY) */
 +#define PANASONIC_NOTIFY_BrightnessDownPRESSED	0x81
 +#define PANASONIC_NOTIFY_BrightnessDownRELEASED	0x01
 +
 +#define	PANASONIC_NOTIFY_BrightnessUpPRESSED	0x82
 +#define	PANASONIC_NOTIFY_BrightnessUpRELEASED	0x02
 +
 +#define PANASONIC_NOTIFY_DisplayCyclePRESSED	0x83
 +#define PANASONIC_NOTIFY_DisplayCycleRELEASED	0x03
 +
 +#define PANASONIC_NOTIFY_VolumeMutePRESSED	0x84
 +#define PANASONIC_NOTIFY_VolumeMuteRELEASED	0x04
 +
 +#define PANASONIC_NOTIFY_VolumeDownPRESSED	0x85
 +#define PANASONIC_NOTIFY_VolumeDownRELEASED	0x05
 +
 +#define PANASONIC_NOTIFY_VolumeUpPRESSED	0x86
 +#define PANASONIC_NOTIFY_VolumeUpRELEASED	0x06
 +
 +#define PANASONIC_NOTIFY_SuspendToRamPRESSED	0x07
 +
 +#define PANASONIC_NOTIFY_BatteryInfoPRESSED	0x89
 +#define PANASONIC_NOTIFY_BatteryInfoRELEASED	0x09
 +
 +#define PANASONIC_NOTIFY_SuspendToHddPRESSED	0x0A
 +
 +#define ACPI_SERIAL_BEGIN(x)
 +#define ACPI_SERIAL_END(x)
 +#define ACPI_SERIAL_ASSERT(x)
 +
 +#define HKEY_SET        0
 +#define HKEY_GET        1
 +
 +/* Registers */
 +#define HKEY_REG_LCD_BRIGHTNESS_MAX_AC  0x02
 +#define HKEY_REG_LCD_BRIGHTNESS_MIN_AC  0x03
 +#define HKEY_REG_LCD_BRIGHTNESS_AC      0x04
 +#define HKEY_REG_LCD_BRIGHTNESS_MAX_DC  0x05
 +#define HKEY_REG_LCD_BRIGHTNESS_MIN_DC  0x06
 +#define HKEY_REG_LCD_BRIGHTNESS_DC      0x07
 +#define HKEY_REG_SOUND_MUTE		0x08
 +
 +/* Field definitions */
 +#define HKEY_LCD_BRIGHTNESS_BITS        4
 +#define HKEY_LCD_BRIGHTNESS_DIV         ((1 << HKEY_LCD_BRIGHTNESS_BITS) - 1)
 +
 +#define LCD_BRIGHTNESS_DOWN		0
 +#define LCD_BRIGHTNESS_UP		1
 +
 +#define LCD_BRIGHTNESS_MIN		0
 +#define LCD_BRIGHTNESS_MAX		1
 +
 +#define HARDWARE_UNMUTE			0
 +#define HARDWARE_MUTE			1
 +
 +static int	panasonic_match(device_t, cfdata_t, void *);
 +static void	panasonic_attach(device_t, device_t, void *);
 +static int	panasonic_detach(device_t, int);
 +
 +static void	panasonic_notify_handler(ACPI_HANDLE, UINT32, void *);
 +
 +static void	panasonic_init(struct panasonic_softc *);
 +static void	panasonic_sysctl_setup(struct panasonic_softc *);
 +
 +static int
 +acpi_panasonic_hkey_event(device_t, ACPI_INTEGER *);
 +
 +static void
 +acpi_panasonic_hkey_action(device_t, ACPI_INTEGER);
 +
 +static void panasonic_acpi_brightness_up(device_t);
 +
 +static void panasonic_acpi_brightness_down(device_t);
 +
 +static void hkey_lcd_brightness_action(struct panasonic_softc *, int);
 +
 +static int
 +hkey_lcd_brightness(struct panasonic_softc *, int, ACPI_INTEGER *);
 +
 +static ACPI_INTEGER 
 +acpi_panasonic_sinf(ACPI_HANDLE, ACPI_INTEGER);
 +
 +static void
 +acpi_panasonic_sset(ACPI_HANDLE, ACPI_INTEGER, ACPI_INTEGER);
 +
 +static int
 +hkey_sound_mute(ACPI_HANDLE, int, ACPI_INTEGER *);
 +
 +CFATTACH_DECL_NEW(panasonic, sizeof(panasonic_softc_t),
 +    panasonic_match, panasonic_attach, panasonic_detach, NULL);
 +
 +static const char * const panasonic_ids[] = {
 +	"MAT0019",
 +	NULL
 +};
 +
 +static int
 +panasonic_match(device_t parent, cfdata_t match, void *opaque)
 +{
 +	struct acpi_attach_args *aa = opaque;
 +
 +	if (aa->aa_node->ad_type != ACPI_TYPE_DEVICE)
 +		return 0;
 +
 +	return acpi_match_hid(aa->aa_node->ad_devinfo, panasonic_ids);
 +}
 +
 +static void
 +panasonic_attach(device_t parent, device_t self, void *opaque)
 +{
 +	panasonic_softc_t *sc = device_private(self);
 +	struct acpi_attach_args *aa = opaque;
 +	struct sysmon_pswitch *psw;
 +	ACPI_STATUS rv;
 +
 +	sc->sc_node = aa->aa_node;
 +	sc->sc_dev = self;
 +
 +	aprint_naive(": Panasonic Hotkeys\n");
 +	aprint_normal(": Panasonic Hotkeys\n");
 +
 +	rv = AcpiInstallNotifyHandler(sc->sc_node->ad_handle, ACPI_ALL_NOTIFY,
 +	    panasonic_notify_handler, sc);
 +	if (ACPI_FAILURE(rv))
 +		aprint_error_dev(self, "couldn't install notify handler: %s\n",
 +		    AcpiFormatException(rv));
 +
 +	/* Register power switches with sysmon */
 +	psw = sc->sc_smpsw;
 +	sc->sc_smpsw_valid = true;
 +
 +	psw[PANASONIC_PSW_SLEEP].smpsw_name = device_xname(self);
 +	psw[PANASONIC_PSW_SLEEP].smpsw_type = PSWITCH_TYPE_SLEEP;
 +#if notyet
 +	psw[PANASONIC_PSW_HIBERNATE].smpsw_name = device_xname(self);
 +	mpsw[PANASONIC_PSW_HIBERNATE].smpsw_type = PSWITCH_TYPE_HIBERNATE;
 +#endif
 +	int i;
 +	for (i = PANASONIC_PSW_DISPLAY_CYCLE; i < PANASONIC_PSW_LAST; i++)
 +		psw[i].smpsw_type = PSWITCH_TYPE_HOTKEY;
 +	psw[PANASONIC_PSW_DISPLAY_CYCLE].smpsw_name = PSWITCH_HK_DISPLAY_CYCLE;
 +	psw[PANASONIC_PSW_BATTERY_INFO].smpsw_name = PSWITCH_HK_BATTERY_INFO;
 +
 +	for (i = 0; i < PANASONIC_PSW_LAST; i++) {
 +		if (sysmon_pswitch_register(&sc->sc_smpsw[i]) != 0) {
 +			aprint_error_dev(self,
 +			    "couldn't register with sysmon\n");
 +			sc->sc_smpsw_valid = false;
 +			break;
 +		}
 +	}
 +	if (!pmf_event_register(self, PMFE_DISPLAY_BRIGHTNESS_UP,
 +	    panasonic_acpi_brightness_up, true))
 +		aprint_error_dev(self,
 +		    "couldn't register BRIGHTNESS UP handler\n");
 +
 +	if (!pmf_event_register(self, PMFE_DISPLAY_BRIGHTNESS_DOWN,
 +	    panasonic_acpi_brightness_down, true))
 +		aprint_error_dev(self,
 +		    "couldn't register BRIGHTNESS DOWN handler\n");
 +
 +	if (!pmf_device_register(self, NULL, NULL))
 +		aprint_error_dev(self, "couldn't establish power handler\n");
 +
 +	panasonic_init(sc);
 +	panasonic_sysctl_setup(sc);
 +}
 +
 +static int
 +panasonic_detach(device_t self, int flags)
 +{
 +	struct panasonic_softc *sc = device_private(self);
 +	int i;
 +
 +	if (sc->sc_smpsw_valid)
 +		for (i = 0; i < PANASONIC_PSW_LAST; i++)
 +			sysmon_pswitch_unregister(&sc->sc_smpsw[i]);
 +
 +	if (sc->sc_log)
 +		sysctl_teardown(&sc->sc_log);
 +	pmf_device_deregister(self);
 +
 +	return 0;
 +}
 +
 +static void
 +panasonic_notify_handler(ACPI_HANDLE hdl, UINT32 notify, void *opaque)
 +{
 +	panasonic_softc_t *sc = opaque;
 +
 +        ACPI_INTEGER key;
 +	key = 0;
 +
 +	switch (notify) {
 +	case 0x80:
 +		ACPI_SERIAL_BEGIN(panasonic);
 +                if (acpi_panasonic_hkey_event(sc->sc_dev, &key) == 0) {
 +                        acpi_panasonic_hkey_action(sc->sc_dev, key);
 +		}
 +
 +		ACPI_SERIAL_END(panasonic);
 +		break;
 +	default:
 +		aprint_debug_dev(sc->sc_dev, "unknown notify: %#x\n", notify);
 +		break;
 +	}
 +}
 +
 +static void
 +panasonic_init(struct panasonic_softc *sc)
 +{
 +	ACPI_INTEGER val;
 +	ACPI_HANDLE hdl;
 +
 +	hdl = sc->sc_node->ad_handle;
 +	val = HARDWARE_UNMUTE;
 +
 +	/* Unmute the speaker - Hardware */
 +	hkey_sound_mute(hdl, HKEY_SET, &val);
 +
 +	/* Initialise variables */
 +	sc->sc_brightness_min = acpi_panasonic_sinf(hdl,
 +	    HKEY_REG_LCD_BRIGHTNESS_MIN_AC);
 +	sc->sc_brightness_max = acpi_panasonic_sinf(hdl,
 +	    HKEY_REG_LCD_BRIGHTNESS_MAX_AC);
 +	if (sc->sc_brightness_max <= 0)
 +		sc->sc_brightness_max = 100;
 +	sc->sc_brightness = (acpi_panasonic_sinf(hdl,
 +	    HKEY_REG_LCD_BRIGHTNESS_AC) * 100) / sc->sc_brightness_max;
 +}
 +
 +static int
 +panasonic_sysctl_verify(SYSCTLFN_ARGS)
 +{
 +	struct sysctlnode node;
 +	struct panasonic_softc *sc;
 +	ACPI_INTEGER val;
 +	int err, tmp;
 +
 +	node = *rnode;
 +	sc = rnode->sysctl_data;
 +
 +	if (node.sysctl_num == sc->sc_brightness_mib) { 
 +		err = hkey_lcd_brightness(sc, HKEY_GET, &val);
 +		if (err) 
 +			val = sc->sc_brightness_min;
 +		tmp = (val * 100) / sc->sc_brightness_max;
 +		node.sysctl_data = &tmp;
 +		err = sysctl_lookup(SYSCTLFN_CALL(&node));
 +		if (err || newp == NULL)
 +			return err;
 +
 +		if (tmp < 0 || tmp > 100)
 +			return EINVAL;
 +		val = (tmp * sc->sc_brightness_max) / 100;
 +		if (val == 0)
 +			val = sc->sc_brightness_min;
 +		err = hkey_lcd_brightness(sc, HKEY_SET, &val);
 +		if (err) 
 +			return err;
 +		tmp = (val * 100) / sc->sc_brightness_max;
 +		sc->sc_brightness = tmp;
 +	}
 +
 +	return 0;
 +}
 +
 +static void
 +panasonic_sysctl_setup(struct panasonic_softc *sc)
 +{
 +	const struct sysctlnode *node, *node_brightness; 
 +	int err;
 +
 +	err = sysctl_createv(&sc->sc_log, 0, NULL, NULL, 0,
 +	    CTLTYPE_NODE, "hw", NULL, NULL, 0, NULL, 0, CTL_HW, CTL_EOL);
 +	if (err)
 +		goto sysctl_err;
 +
 +	err = sysctl_createv(&sc->sc_log, 0, NULL, &node, 0,
 +	    CTLTYPE_NODE, "panasonic",
 +	    SYSCTL_DESCR("Toughbook controls"), NULL, 0,
 +	    NULL, 0, CTL_HW, CTL_CREATE, CTL_EOL);
 +	if (err)
 +		goto sysctl_err;
 +
 +	err = sysctl_createv(&sc->sc_log, 0, &node, &node_brightness,
 +	    CTLFLAG_READWRITE | CTLFLAG_ANYWRITE, CTLTYPE_INT, "brightness",
 +	    SYSCTL_DESCR("Screen brightness (Percent)"),
 +	    panasonic_sysctl_verify, 0, sc, 0,
 +	    CTL_CREATE, CTL_EOL);
 +	if (err)
 +		goto sysctl_err;
 +	sc->sc_brightness_mib = node_brightness->sysctl_num;
 +
 +	return;
 +sysctl_err:
 +	aprint_error_dev(sc->sc_dev, "failed to add sysctl nodes. (%d)\n", err);
 +}
 +
 +static int
 +acpi_panasonic_hkey_event(device_t self, ACPI_INTEGER *arg) {
 +
 +	struct panasonic_softc *sc = device_private(self);
 +
 +        ACPI_BUFFER buf;
 +        ACPI_OBJECT *res;
 +        ACPI_INTEGER val;
 +        int status;
 +
 +        ACPI_SERIAL_ASSERT(panasonic);
 +        status = ENXIO;
 +
 +        buf.Length = ACPI_ALLOCATE_BUFFER;
 +        buf.Pointer = NULL;
 +        AcpiEvaluateObject(sc->sc_node->ad_handle, "HINF", NULL, &buf);
 +        res = (ACPI_OBJECT *)buf.Pointer;
 +        if (res->Type != ACPI_TYPE_INTEGER) {
 +                aprint_error_dev(self, "HINF returned non-integer\n");
 +                goto end;
 +        }
 +        val = res->Integer.Value;
 +
 +	*arg = val;
 +        status = 0;
 +end:
 +        if (buf.Pointer)
 +                AcpiOsFree(buf.Pointer);
 +
 +        return (status);
 +}
 +
 +static void
 +acpi_panasonic_hkey_action(device_t self, ACPI_INTEGER key)
 +{
 +
 +	struct panasonic_softc *sc = device_private(self);
 +
 +        ACPI_SERIAL_ASSERT(panasonic);
 +
 +        switch (key) {
 +        case PANASONIC_NOTIFY_BrightnessDownPRESSED:
 +		pmf_event_inject(NULL, PMFE_DISPLAY_BRIGHTNESS_DOWN);
 +       		break;
 +        case PANASONIC_NOTIFY_BrightnessDownRELEASED:
 +		break;
 +	case PANASONIC_NOTIFY_BrightnessUpPRESSED:
 +		pmf_event_inject(NULL, PMFE_DISPLAY_BRIGHTNESS_UP);
 +        	break;
 +	case PANASONIC_NOTIFY_BrightnessUpRELEASED:
 +		break;
 +	case PANASONIC_NOTIFY_DisplayCyclePRESSED:
 +		if (sc->sc_smpsw_valid == false)
 +			break;
 +		sysmon_pswitch_event(&sc->sc_smpsw[PANASONIC_PSW_DISPLAY_CYCLE],
 +		    PSWITCH_EVENT_PRESSED);
 +		break;
 +	case PANASONIC_NOTIFY_DisplayCycleRELEASED:
 +		if (sc->sc_smpsw_valid == false)
 +			break;
 +		sysmon_pswitch_event(&sc->sc_smpsw[PANASONIC_PSW_DISPLAY_CYCLE],
 +		    PSWITCH_EVENT_RELEASED);
 +		break;
 +	case PANASONIC_NOTIFY_VolumeMutePRESSED:
 +		pmf_event_inject(NULL, PMFE_AUDIO_VOLUME_TOGGLE);
 +		break;
 +	case PANASONIC_NOTIFY_VolumeMuteRELEASED:
 +		break;
 +	case PANASONIC_NOTIFY_VolumeDownPRESSED:
 +		pmf_event_inject(NULL, PMFE_AUDIO_VOLUME_DOWN);
 +		break;
 +	case PANASONIC_NOTIFY_VolumeDownRELEASED:
 +		break;
 +	case PANASONIC_NOTIFY_VolumeUpPRESSED:
 +		pmf_event_inject(NULL, PMFE_AUDIO_VOLUME_UP);
 +		break;
 +	case PANASONIC_NOTIFY_VolumeUpRELEASED:
 +		break;
 +	case PANASONIC_NOTIFY_SuspendToRamPRESSED:
 +        	/* Suspend. */
 +		if (sc->sc_smpsw_valid == false)
 +			break;
 +		sysmon_pswitch_event(&sc->sc_smpsw[PANASONIC_PSW_SLEEP],
 +		    PSWITCH_EVENT_PRESSED);
 +        	break;
 +	case PANASONIC_NOTIFY_BatteryInfoPRESSED:
 +		if (sc->sc_smpsw_valid == false)
 +			break;
 +		sysmon_pswitch_event(&sc->sc_smpsw[PANASONIC_PSW_BATTERY_INFO],
 +		    PSWITCH_EVENT_PRESSED);
 +		break;
 +	case PANASONIC_NOTIFY_BatteryInfoRELEASED:
 +		if (sc->sc_smpsw_valid == false)
 +			break;
 +		sysmon_pswitch_event(&sc->sc_smpsw[PANASONIC_PSW_BATTERY_INFO],
 +		    PSWITCH_EVENT_RELEASED);
 +		break;
 +	case PANASONIC_NOTIFY_SuspendToHddPRESSED:
 +#if notyet
 +        	/* Hibernate. */
 +		if (sc->sc_smpsw_valid == false)
 +			break;
 +		sysmon_pswitch_event(&sc->sc_smpsw[PANASONIC_PSW_HIBERNATE],
 +		    PSWITCH_EVENT_PRESSED);
 +#endif
 +        	break;
 +	default:
 +		aprint_error_dev(sc->sc_dev, "Unknown Key 0x%X\n", (int)key);
 +		break;
 +        }
 +}
 +
 +static void
 +panasonic_acpi_brightness_up(device_t self){
 +
 +	struct panasonic_softc *sc = device_private(self);
 +
 +	hkey_lcd_brightness_action(sc, LCD_BRIGHTNESS_UP);
 +
 +}
 +
 +static void
 +panasonic_acpi_brightness_down(device_t self){
 +
 +	struct panasonic_softc *sc = device_private(self);
 +
 +	hkey_lcd_brightness_action(sc, LCD_BRIGHTNESS_DOWN);
 +
 +}
 +
 +static void
 +hkey_lcd_brightness_action(struct panasonic_softc *sc, int direction){
 +
 +	ACPI_INTEGER arg;
 + 
 +    	hkey_lcd_brightness(sc, HKEY_GET, &arg);
 +
 +    	if (direction == LCD_BRIGHTNESS_UP)
 +	   	arg += sc->sc_brightness_max / HKEY_LCD_BRIGHTNESS_DIV;
 +    	else
 +	    	arg -= sc->sc_brightness_max / HKEY_LCD_BRIGHTNESS_DIV;
 +
 +    	if (arg < sc->sc_brightness_min)
 +	    	arg = sc->sc_brightness_min;
 +    	else if (arg > sc->sc_brightness_max)
 +	    	arg = sc->sc_brightness_max;
 +
 +    	hkey_lcd_brightness(sc, HKEY_SET, &arg);
 +
 +}
 +
 +static int
 +hkey_lcd_brightness(struct panasonic_softc *sc, int op, ACPI_INTEGER *val)
 +{
 +	ACPI_HANDLE hdl;
 +	ACPI_INTEGER reg;
 +
 +	hdl = sc->sc_node->ad_handle;
 +
 +	reg = HKEY_REG_LCD_BRIGHTNESS_AC;
 +
 +	ACPI_SERIAL_ASSERT(panasonic);
 +        switch (op) {
 +        case HKEY_SET:
 +                if (*val < sc->sc_brightness_min ||
 +		    *val > sc->sc_brightness_max)
 +                        return (EINVAL);
 +                acpi_panasonic_sset(hdl, reg, *val);
 +                break;
 +        case HKEY_GET:
 +                *val = acpi_panasonic_sinf(hdl, reg);
 +                break;
 +        }
 +
 +	return (0);
 +}
 +
 +static ACPI_INTEGER
 +acpi_panasonic_sinf(ACPI_HANDLE hdl, ACPI_INTEGER index)
 +{
 +        ACPI_BUFFER buf;
 +        ACPI_OBJECT *res;
 +        ACPI_INTEGER ret;
 +
 +        ACPI_SERIAL_ASSERT(panasonic);
 +        ret = -1;
 +        buf.Length = ACPI_ALLOCATE_BUFFER;
 +        buf.Pointer = NULL;
 +        AcpiEvaluateObject(hdl, "SINF", NULL, &buf);
 +        res = (ACPI_OBJECT *)buf.Pointer;
 +        if (res->Type == ACPI_TYPE_PACKAGE)
 +                ret = res->Package.Elements[index].Integer.Value;
 +        AcpiOsFree(buf.Pointer);
 +
 +        return (ret);
 +}
 +
 +static void
 +acpi_panasonic_sset(ACPI_HANDLE hdl, ACPI_INTEGER index, ACPI_INTEGER val)
 +{
 +	ACPI_OBJECT_LIST args;
 +        ACPI_OBJECT obj[2];
 +
 +        ACPI_SERIAL_ASSERT(panasonic);
 +        obj[0].Type = ACPI_TYPE_INTEGER;
 +        obj[0].Integer.Value = index;
 +        obj[1].Type = ACPI_TYPE_INTEGER;
 +        obj[1].Integer.Value = val;
 +        args.Count = 2;
 +        args.Pointer = obj;
 +        AcpiEvaluateObject(hdl, "SSET", &args, NULL);
 +}
 +
 +static int
 +hkey_sound_mute(ACPI_HANDLE hdl, int op, ACPI_INTEGER *val)
 +{
 +
 +	ACPI_SERIAL_ASSERT(panasonic);
 +        switch (op) {
 +        case HKEY_SET:
 +        	if (*val != 0 && *val != 1)
 +			return (EINVAL);
 +          	acpi_panasonic_sset(hdl, HKEY_REG_SOUND_MUTE, *val);
 +            	break;
 +        case HKEY_GET:
 +        	*val = acpi_panasonic_sinf(hdl, HKEY_REG_SOUND_MUTE);
 +           	break;
 +        }
 +
 +       return (0);
 +}
 +
 --- /dev/null	2012-08-29 17:38:04.000000000 +1000
 +++ man4/panasonic.4	2012-08-29 18:04:06.000000000 +1000
 @@ -0,0 +1,74 @@
 +.\"
 +.\" Copyright (c) 2012 Nathanial Sloss <nathanialsloss@yahoo.com.au>
 +.\" 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
 +.\"
 +.Dd August 29, 2012
 +.Dt PANASONIC 4
 +.Os
 +.Sh NAME
 +.Nm panasonic
 +.Nd Panasonic TOUGHBOOK laptop features support
 +.Sh SYNOPSIS
 +.Cd "panasonic* at acpi?"
 +.Sh DESCRIPTION
 +The
 +.Nm
 +driver provides support for hotkey handling and screen brightness found on
 +Panasonic TOUGHBOOK laptop computers.
 +.Pp
 +The
 +.Nm
 +driver provides support for modifying the screen brightness via the
 +.Xr sysctl 8
 +interface.
 +.Pp
 +The following
 +.Xr sysctl 8
 +variables are available:
 +.Pp
 +.Bl -tag -width "hw.panasonic.brightness [R/W]" -compact
 +.It Em hw.panasonic.brightness Bq R/W
 +Controls current LCD brightness.
 +Range [0-100].
 +.El
 +.Sh SEE ALSO
 +.Xr acpi 4 ,
 +.Xr acpivga 4 ,
 +.Xr pmf 9 ,
 +.Xr sysmon_envsys 9 ,
 +.Xr toughbook_hbtn 4
 +.Sh HISTORY
 +The
 +.Nm
 +device driver appeared in FreeBSD and was extended and ported to
 +.Nx 3.0.1 by Nathanial Sloss.
 +.Sh AUTHORS
 +.An OGAWA Takaya Aq t-ogawa@triaez.kaisei.org
 +.An Yoshihiro TAKAHASHI Aq nyan@FreeBSD.org
 +.An Nathanial Sloss
 +.Sh BUGS
 +If the computer is fully supported by
 +.Xr acpivga 4 then a different method
 +for controlling the screen brightness is used and the above mentioned 
 +.Xr sysctl 8 variable may not work.
 --- /dev/null	2012-08-29 17:38:04.000000000 +1000
 +++ ../../sys/dev/acpi/toughbook_hbtn_acpi.c	2012-07-02 19:34:35.000000000 
 +1000
 @@ -0,0 +1,287 @@
 +/*-
 + * Copyright (c)2008 - 2012 Nathanial Sloss <nathanialsloss@yahoo.com.au>
 + * 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
 + */
 +
 +/* Panasonic Toughbook CF-18/19 (and possibly others) tablet button driver. 
 */
 +
 +#include <sys/cdefs.h>
 +
 +#include <sys/types.h>
 +#include <sys/param.h>
 +#include <sys/device.h>
 +#include <sys/kernel.h>
 +#include <sys/pmf.h>
 +
 +#include <dev/sysmon/sysmonvar.h>
 +
 +#include <dev/acpi/acpivar.h>
 +#include <dev/acpi/acpireg.h>
 +
 +typedef struct toughbook_hbtn_softc {
 +	device_t		sc_dev;
 +	struct acpi_devnode	*sc_node;
 +
 +#define	PANASONIC_PSW_SECURITY			0
 +#define PANASONIC_PSW_ROTATION			1
 +#define PANASONIC_PSW_ENTER			2
 +#define PANASONIC_PSW_INPUT_PANEL		3
 +#define PANASONIC_PSW_LAST			4
 +
 +	struct sysmon_pswitch	sc_smpsw[PANASONIC_PSW_LAST];
 +	bool			sc_smpsw_valid;
 +
 +} toughbook_hbtn_softc_t;
 +
 +/* Tablet buttons (HBTN) */
 +#define PANASONIC_NOTIFY_SecurityPRESSED	0x34
 +#define PANASONIC_NOTIFY_SecurityRELEASED	0x35
 +
 +#define PANASONIC_NOTIFY_RotationPRESSED	0x36
 +#define PANASONIC_NOTIFY_RotationRELEASED	0x37
 +
 +#define PANASONIC_NOTIFY_EnterPRESSED		0x38
 +#define PANASONIC_NOTIFY_EnterRELEASED		0x39
 +
 +#define PANASONIC_NOTIFY_InputPanelPRESSED	0x3A
 +#define PANASONIC_NOTIFY_InputPanelRELEASED	0x3B
 +
 +#define ACPI_SERIAL_BEGIN(x)
 +#define ACPI_SERIAL_END(x)
 +#define ACPI_SERIAL_ASSERT(x)
 +
 +#define HKEY_SET        0
 +#define HKEY_GET        1
 +
 +static int	hbtn_match(device_t, cfdata_t, void *);
 +static void	hbtn_attach(device_t, device_t, void *);
 +static int	hbtn_detach(device_t, int);
 +
 +static void	hbtn_notify_handler(ACPI_HANDLE, UINT32, void *);
 +
 +static int
 +acpi_hbtn_event(device_t, ACPI_INTEGER *);
 +
 +static void
 +acpi_hbtn_action(device_t, ACPI_INTEGER);
 +
 +CFATTACH_DECL_NEW(toughbook_hbtn, sizeof(toughbook_hbtn_softc_t),
 +    hbtn_match, hbtn_attach, hbtn_detach, NULL);
 +
 +static const char * const toughbook_hbtn_ids[] = {
 +	"MAT001F",
 +	"MAT0020",
 +	NULL
 +};
 +
 +static int
 +hbtn_match(device_t parent, cfdata_t match, void *opaque)
 +{
 +	struct acpi_attach_args *aa = opaque;
 +
 +	if (aa->aa_node->ad_type != ACPI_TYPE_DEVICE)
 +		return 0;
 +
 +	return acpi_match_hid(aa->aa_node->ad_devinfo, toughbook_hbtn_ids);
 +}
 +
 +static void
 +hbtn_attach(device_t parent, device_t self, void *opaque)
 +{
 +	toughbook_hbtn_softc_t *sc = device_private(self);
 +	struct acpi_attach_args *aa = opaque;
 +	struct sysmon_pswitch *psw;
 +	ACPI_STATUS rv;
 +
 +	sc->sc_node = aa->aa_node;
 +	sc->sc_dev = self;
 +
 +	aprint_naive(": Toughbook tablet buttons\n");
 +	aprint_normal(": Toughbook tablet buttons\n");
 +
 +	rv = AcpiInstallNotifyHandler(sc->sc_node->ad_handle, ACPI_ALL_NOTIFY,
 +	    hbtn_notify_handler, sc);
 +	if (ACPI_FAILURE(rv))
 +		aprint_error_dev(self, "couldn't install notify handler: %s\n",
 +		    AcpiFormatException(rv));
 +
 +	/* Register power switches with sysmon */
 +	psw = sc->sc_smpsw;
 +	sc->sc_smpsw_valid = true;
 +
 +	int i;
 +	for (i = PANASONIC_PSW_SECURITY; i < PANASONIC_PSW_LAST; i++)
 +		psw[i].smpsw_type = PSWITCH_TYPE_HOTKEY;
 +	psw[PANASONIC_PSW_SECURITY].smpsw_name = "security";
 +	psw[PANASONIC_PSW_ROTATION].smpsw_name = "rotation-button";
 +	psw[PANASONIC_PSW_ENTER].smpsw_name = "enter-button";
 +	psw[PANASONIC_PSW_INPUT_PANEL].smpsw_name = "input_panel-button";
 +
 +	for (i = 0; i < PANASONIC_PSW_LAST; i++) {
 +		if (sysmon_pswitch_register(&sc->sc_smpsw[i]) != 0) {
 +			aprint_error_dev(self,
 +			    "couldn't register with sysmon\n");
 +			sc->sc_smpsw_valid = false;
 +			break;
 +		}
 +	}
 +
 +	if (!pmf_device_register(self, NULL, NULL))
 +		aprint_error_dev(self, "couldn't establish power handler\n");
 +
 +}
 +
 +static int
 +hbtn_detach(device_t self, int flags)
 +{
 +	toughbook_hbtn_softc_t *sc = device_private(self);
 +	int i;
 +
 +	if (sc->sc_smpsw_valid)
 +		for (i = 0; i < PANASONIC_PSW_LAST; i++)
 +			sysmon_pswitch_unregister(&sc->sc_smpsw[i]);
 +
 +	pmf_device_deregister(self);
 +
 +	return 0;
 +}
 +
 +static void
 +hbtn_notify_handler(ACPI_HANDLE hdl, UINT32 notify, void *opaque)
 +{
 +	toughbook_hbtn_softc_t *sc = opaque;
 +
 +        ACPI_INTEGER key;
 +	key = 0;
 +
 +	switch (notify) {
 +	case 0x80:
 +		ACPI_SERIAL_BEGIN(panasonic);
 +                if (acpi_hbtn_event(sc->sc_dev, &key) == 0) {
 +                        acpi_hbtn_action(sc->sc_dev, key);
 +		}
 +
 +		ACPI_SERIAL_END(panasonic);
 +		break;
 +	default:
 +		aprint_debug_dev(sc->sc_dev, "unknown notify: %#x\n", notify);
 +		break;
 +	}
 +
 +}
 +
 +static int
 +acpi_hbtn_event(device_t self, ACPI_INTEGER *arg) {
 +
 +	toughbook_hbtn_softc_t *sc = device_private(self);
 +
 +        ACPI_BUFFER buf;
 +        ACPI_OBJECT *res;
 +        ACPI_INTEGER val;
 +        int status;
 +
 +        ACPI_SERIAL_ASSERT(panasonic);
 +        status = ENXIO;
 +
 +        buf.Length = ACPI_ALLOCATE_BUFFER;
 +        buf.Pointer = NULL;
 +        AcpiEvaluateObject(sc->sc_node->ad_handle, "HINF", NULL, &buf);
 +        res = (ACPI_OBJECT *)buf.Pointer;
 +        if (res->Type != ACPI_TYPE_INTEGER) {
 +                aprint_error_dev(self, "HINF returned non-integer\n");
 +                goto end;
 +        }
 +        val = res->Integer.Value;
 +
 +	*arg = val;
 +        status = 0;
 +end:
 +        if (buf.Pointer)
 +                AcpiOsFree(buf.Pointer);
 +
 +        return status;
 +}
 +
 +static void
 +acpi_hbtn_action(device_t self, ACPI_INTEGER key)
 +{
 +
 +	toughbook_hbtn_softc_t *sc = device_private(self);
 +
 +        ACPI_SERIAL_ASSERT(panasonic);
 +
 +        switch (key) {
 +	case PANASONIC_NOTIFY_SecurityPRESSED:
 +		if (sc->sc_smpsw_valid == false)
 +			break;
 +		sysmon_pswitch_event(&sc->sc_smpsw[PANASONIC_PSW_SECURITY],
 +		    PSWITCH_EVENT_PRESSED);
 +		break;
 +	case PANASONIC_NOTIFY_SecurityRELEASED:
 +		if (sc->sc_smpsw_valid == false)
 +			break;
 +		sysmon_pswitch_event(&sc->sc_smpsw[PANASONIC_PSW_SECURITY],
 +		    PSWITCH_EVENT_RELEASED);
 +		break;
 +	case PANASONIC_NOTIFY_RotationPRESSED:
 +		if (sc->sc_smpsw_valid == false)
 +			break;
 +	    	sysmon_pswitch_event(&sc->sc_smpsw[PANASONIC_PSW_ROTATION],
 +	            PSWITCH_EVENT_PRESSED);
 +		break;
 +	case PANASONIC_NOTIFY_RotationRELEASED:
 +		if (sc->sc_smpsw_valid == false)
 +			break;
 +		sysmon_pswitch_event(&sc->sc_smpsw[PANASONIC_PSW_ROTATION],
 +	            PSWITCH_EVENT_RELEASED);
 +		break;
 +	case PANASONIC_NOTIFY_EnterPRESSED:
 +		if (sc->sc_smpsw_valid == false)
 +			break;
 +		sysmon_pswitch_event(&sc->sc_smpsw[PANASONIC_PSW_ENTER],
 +		    PSWITCH_EVENT_PRESSED);
 +		break;
 +	case PANASONIC_NOTIFY_EnterRELEASED:
 +		if (sc->sc_smpsw_valid == false)
 +			break;
 +		sysmon_pswitch_event(&sc->sc_smpsw[PANASONIC_PSW_ENTER],
 +		    PSWITCH_EVENT_RELEASED);
 +		break;
 +	case PANASONIC_NOTIFY_InputPanelPRESSED:
 +		if (sc->sc_smpsw_valid == false)
 +			break;
 +		sysmon_pswitch_event(&sc->sc_smpsw[PANASONIC_PSW_INPUT_PANEL],
 +		    PSWITCH_EVENT_PRESSED);
 +		break;
 +	case PANASONIC_NOTIFY_InputPanelRELEASED:
 +		if (sc->sc_smpsw_valid == false)
 +			break;
 +		sysmon_pswitch_event(&sc->sc_smpsw[PANASONIC_PSW_INPUT_PANEL],
 +		    PSWITCH_EVENT_RELEASED);
 +		break;
 +	default:
 +		aprint_error_dev(sc->sc_dev, "Unknown Key 0x%X\n", (int)key);
 +        }
 +}
 +
 --- /dev/null	2012-08-29 17:38:04.000000000 +1000
 +++ ./man4/toughbook_hbtn.4	2012-07-02 20:39:29.000000000 +1000
 @@ -0,0 +1,63 @@
 +.\"
 +.\" Copyright (c) 2012 Nathanial Sloss <nathanialsloss@yahoo.com.au>
 +.\" 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
 +.\"
 +.Dd July 2, 2012
 +.Dt TOUGHBOOK_HBTN 4
 +.Os
 +.Sh NAME
 +.Nm toughbook_hbtn
 +.Nd Panasonic Toughbook CF-18/19 Tablet Buttons
 +.Sh SYNOPSIS
 +.Cd "toughbook_hbtn* at acpi?"
 +.Sh DESCRIPTION
 +The
 +.Nm
 +driver supports the tablet buttons found on CF-18/19 Toughbook computers:
 +.Bl -column -offset indent "Button         " "/etc/powerd/actions/button"
 +.It Sy Button Ta Sy Script
 +.It Li Input (Keyboard) Ta Pa /etc/powerd/actions/input_panel-button
 +.It Li Enter (Target) Ta Pa /etc/powerd/actions/enter-button
 +.It Li Rotation Ta Pa /etc/powerd/actions/rotation-button
 +.It Li Security (Key) Ta Pa /etc/powerd/actions/security
 +.El
 +.Pp
 +When a button is pressed, the
 +.Xr powerd 8
 +daemon, if running,
 +will execute the corresponding script.
 +.Sh SEE ALSO
 +.Xr acpi 4 ,
 +.Xr panasonic 4 ,
 +.Xr powerd 8
 +.Sh AUTHORS
 +Software and manual page written by Nathanial Sloss
 +.Sh HISTORY
 +The
 +.Nm
 +driver
 +was an addition to
 +.Xr panasonic 4
 +which was ported to
 +.Nx 3.0.1 but was never released .


 I hope this software is useful.

 Regards,

 Nat.

Responsible-Changed-From-To: kern-bug-people->jruoho
Responsible-Changed-By: jruoho@NetBSD.org
Responsible-Changed-When: Wed, 29 Aug 2012 13:07:41 +0000
Responsible-Changed-Why:


Take. There are few issues with this driver, but I'll deal with those before
the code hits the tree



Responsible-Changed-From-To: jruoho->nat
Responsible-Changed-By: maya@NetBSD.org
Responsible-Changed-When: Tue, 08 Nov 2016 19:32:55 +0000
Responsible-Changed-Why:
ping


>Unformatted:

NetBSD Home
NetBSD PR Database Search

(Contact us) $NetBSD: query-full-pr,v 1.39 2013/11/01 18:47:49 spz Exp $
$NetBSD: gnats_config.sh,v 1.8 2006/05/07 09:23:38 tsutsui Exp $
Copyright © 1994-2014 The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.