From owner-acpi-jp@jp.freebsd.org  Sat Oct  7 16:10:52 2000
Received: (from daemon@localhost)
	by castle.jp.freebsd.org (8.9.3+3.2W/8.7.3) id QAA01303;
	Sat, 7 Oct 2000 16:10:52 +0900 (JST)
	(envelope-from owner-acpi-jp@jp.FreeBSD.org)
Received: from tasogare.imasy.or.jp (daemon@tasogare.imasy.or.jp [202.227.24.5])
	by castle.jp.freebsd.org (8.9.3+3.2W/8.7.3) with ESMTP id QAA01298
	for <acpi-jp@jp.freebsd.org>; Sat, 7 Oct 2000 16:10:51 +0900 (JST)
	(envelope-from iwasaki@jp.FreeBSD.org)
Received: from localhost (iwasaki.imasy.or.jp [202.227.24.92])
	by tasogare.imasy.or.jp (8.10.2+3.3W/3.7W-tasogare/smtpfeed 1.07) with ESMTP id e977Anr77686
	for <acpi-jp@jp.freebsd.org>; Sat, 7 Oct 2000 16:10:49 +0900 (JST)
	(envelope-from iwasaki@jp.FreeBSD.org)
To: acpi-jp@jp.freebsd.org
In-Reply-To: <20001007160232T.iwasaki@jp.FreeBSD.org>
References: <200010061900.e96J0Uh06929@mass.osd.bsdi.com>
	<20001007042124G.iwasaki@jp.FreeBSD.org>
	<20001007160232T.iwasaki@jp.FreeBSD.org>
X-Mailer: Mew version 1.94.1 on Emacs 19.34 / Mule 2.3 (SUETSUMUHANA)
Mime-Version: 1.0
Content-Type: Text/Plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Message-Id: <20001007161048M.iwasaki@jp.FreeBSD.org>
Date: Sat, 07 Oct 2000 16:10:48 +0900
From: Mitsuru IWASAKI <iwasaki@jp.freebsd.org>
X-Dispatcher: imput version 20000228(IM140)
Lines: 198
Reply-To: acpi-jp@jp.freebsd.org
Precedence: list
X-Distribute: distribute version 2.1 (Alpha) patchlevel 24e+000315
X-Sequence: acpi-jp 814
Subject: [acpi-jp 814] Re: acpi_lid patch 
Errors-To: owner-acpi-jp@jp.freebsd.org
Sender: owner-acpi-jp@jp.freebsd.org
X-Originator: iwasaki@jp.freebsd.org

Oops, I didn't attach acpi_button.c (^^;

/*-
 * Copyright (c) 2000 Michael Smith
 * Copyright (c) 2000 BSDi
 * 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.
 *
 *	$FreeBSD$
 */

#include "opt_acpi.h"		/* XXX trim includes */
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/bus.h>
#include <sys/conf.h>
#include <sys/ioccom.h>
#include <sys/reboot.h>
#include <sys/sysctl.h>
#include <sys/eventhandler.h>

#include <machine/clock.h>
#include <sys/kthread.h>

#include <machine/bus.h>
#include <machine/resource.h>
#include <sys/rman.h>

#include "acpi.h"	/* cheat and get them all */

#include <dev/acpica/acpivar.h>
#include <dev/acpica/acpieventhandler.h>

struct acpi_button_softc {
    device_t	button_dev;
    ACPI_HANDLE	button_handle;
#define ACPI_POWER_BUTTON	0
#define ACPI_SLEEP_BUTTON	1
    boolean_t	button_type;	/* Power or Sleep Button */
};

static int	acpi_button_probe(device_t dev);
static int	acpi_button_attach(device_t dev);
static void 	acpi_button_notify_handler(ACPI_HANDLE h,UINT32 notify, void *context);
static void	acpi_button_notify_pressed_for_sleep(void *arg);
static void	acpi_button_notify_pressed_for_wakeup(void *arg);

static device_method_t acpi_button_methods[] = {
    /* Device interface */
    DEVMETHOD(device_probe,	acpi_button_probe),
    DEVMETHOD(device_attach,	acpi_button_attach),

    {0, 0}
};

static driver_t acpi_button_driver = {
    "acpi_button",
    acpi_button_methods,
    sizeof(struct acpi_button_softc),
};

devclass_t acpi_button_devclass;
DRIVER_MODULE(acpi_button, acpi, acpi_button_driver, acpi_button_devclass, 0, 0);

static int
acpi_button_probe(device_t dev)
{
    struct acpi_button_softc	*sc;

    sc = device_get_softc(dev);
    if (acpi_get_type(dev) == ACPI_TYPE_DEVICE) {
	if (acpi_MatchHid(dev, "PNP0C0C")) {
	    device_set_desc(dev, "Control Method Power Button Device");
	    sc->button_type = ACPI_POWER_BUTTON;
	    return(0);
	}
	if (acpi_MatchHid(dev, "PNP0C0E")) {
	    device_set_desc(dev, "Control Method Sleep Button Device");
	    sc->button_type = ACPI_SLEEP_BUTTON;
	    return(0);
	}
	return(ENXIO);
    }
    return(ENXIO);
}

static int
acpi_button_attach(device_t dev)
{
    struct acpi_button_softc	*sc;

    sc = device_get_softc(dev);
    bzero(sc, sizeof(*sc));
    sc->button_dev = dev;
    sc->button_handle = acpi_get_handle(dev);

    /*
     * Evaluate _INI
     */
    AcpiEvaluateObject(sc->button_handle, "_INI", NULL, NULL);
    
    AcpiInstallNotifyHandler(sc->button_handle, ACPI_DEVICE_NOTIFY, acpi_button_notify_handler, sc);

    return(0);
}

static void
acpi_button_notify_pressed_for_sleep(void *arg)
{
    struct acpi_button_softc	*sc;
    struct acpi_softc		*acpi_sc;

    sc = (struct acpi_button_softc *)arg;
    acpi_sc = acpi_device_get_parent_softc(sc->button_dev);
    if (acpi_sc == NULL) {
	return;
    }

    switch (sc->button_type) {
    case ACPI_POWER_BUTTON:
	acpi_eventhandler_power_button_for_sleep((void *)acpi_sc);
	break;
    case ACPI_SLEEP_BUTTON:
	acpi_eventhandler_sleep_button_for_sleep((void *)acpi_sc);
	break;
    default:
	return;		/* unknown button type */
    }
}

static void
acpi_button_notify_pressed_for_wakeup(void *arg)
{
    struct acpi_button_softc	*sc;
    struct acpi_softc		*acpi_sc;

    sc = (struct acpi_button_softc *)arg;
    acpi_sc = acpi_device_get_parent_softc(sc->button_dev);
    if (acpi_sc == NULL) {
	return;
    }

    switch (sc->button_type) {
    case ACPI_POWER_BUTTON:
	acpi_eventhandler_power_button_for_wakeup((void *)acpi_sc);
	break;
    case ACPI_SLEEP_BUTTON:
	acpi_eventhandler_sleep_button_for_wakeup((void *)acpi_sc);
	break;
    default:
	return;		/* unknown button type */
    }
}

/* XXX maybe not here */
#define ACPI_NOTIFY_BUTTON_PRESSED_FOR_SLEEP	0x80
#define ACPI_NOTIFY_BUTTON_PRESSED_FOR_WAKEUP	0x02

static void 
acpi_button_notify_handler(ACPI_HANDLE h, UINT32 notify, void *context)
{
    struct acpi_button_softc	*sc = (struct acpi_button_softc *)context;

    switch (notify) {
    case ACPI_NOTIFY_BUTTON_PRESSED_FOR_SLEEP:
	timeout(acpi_button_notify_pressed_for_sleep, (void *)sc, hz/2);
	device_printf(sc->button_dev, "pressed for sleep, button type: %d\n", sc->button_type);
	break;   
    case ACPI_NOTIFY_BUTTON_PRESSED_FOR_WAKEUP:
	timeout(acpi_button_notify_pressed_for_wakeup, (void *)sc, hz/2);
	device_printf(sc->button_dev, "pressed for wakeup, button type: %d\n", sc->button_type);
	break;   
    default:
	return;		/* unknown notification value */
    }
}

