acpi_button.c revision 67761
167761Smsmith/*-
267761Smsmith * Copyright (c) 2000 Mitsaru IWASAKI <iwasaki@jp.freebsd.org>
367761Smsmith * Copyright (c) 2000 Michael Smith <msmith@freebsd.org>
467761Smsmith * Copyright (c) 2000 BSDi
567761Smsmith * All rights reserved.
667761Smsmith *
767761Smsmith * Redistribution and use in source and binary forms, with or without
867761Smsmith * modification, are permitted provided that the following conditions
967761Smsmith * are met:
1067761Smsmith * 1. Redistributions of source code must retain the above copyright
1167761Smsmith *    notice, this list of conditions and the following disclaimer.
1267761Smsmith * 2. Redistributions in binary form must reproduce the above copyright
1367761Smsmith *    notice, this list of conditions and the following disclaimer in the
1467761Smsmith *    documentation and/or other materials provided with the distribution.
1567761Smsmith *
1667761Smsmith * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1767761Smsmith * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1867761Smsmith * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1967761Smsmith * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
2067761Smsmith * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2167761Smsmith * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2267761Smsmith * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2367761Smsmith * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2467761Smsmith * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2567761Smsmith * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2667761Smsmith * SUCH DAMAGE.
2767761Smsmith *
2867761Smsmith *	$FreeBSD: head/sys/dev/acpica/acpi_button.c 67761 2000-10-28 06:59:48Z msmith $
2967761Smsmith */
3067761Smsmith
3167761Smsmith#include "opt_acpi.h"
3267761Smsmith#include <sys/param.h>
3367761Smsmith#include <sys/kernel.h>
3467761Smsmith#include <sys/bus.h>
3567761Smsmith
3667761Smsmith#include "acpi.h"
3767761Smsmith
3867761Smsmith#include <dev/acpica/acpivar.h>
3967761Smsmith
4067761Smsmithstruct acpi_button_softc {
4167761Smsmith    device_t	button_dev;
4267761Smsmith    ACPI_HANDLE	button_handle;
4367761Smsmith#define ACPI_POWER_BUTTON	0
4467761Smsmith#define ACPI_SLEEP_BUTTON	1
4567761Smsmith    boolean_t	button_type;	/* Power or Sleep Button */
4667761Smsmith};
4767761Smsmith
4867761Smsmithstatic int	acpi_button_probe(device_t dev);
4967761Smsmithstatic int	acpi_button_attach(device_t dev);
5067761Smsmithstatic void 	acpi_button_notify_handler(ACPI_HANDLE h,UINT32 notify, void *context);
5167761Smsmithstatic void	acpi_button_notify_pressed_for_sleep(void *arg);
5267761Smsmithstatic void	acpi_button_notify_pressed_for_wakeup(void *arg);
5367761Smsmith
5467761Smsmithstatic device_method_t acpi_button_methods[] = {
5567761Smsmith    /* Device interface */
5667761Smsmith    DEVMETHOD(device_probe,	acpi_button_probe),
5767761Smsmith    DEVMETHOD(device_attach,	acpi_button_attach),
5867761Smsmith
5967761Smsmith    {0, 0}
6067761Smsmith};
6167761Smsmith
6267761Smsmithstatic driver_t acpi_button_driver = {
6367761Smsmith    "acpi_button",
6467761Smsmith    acpi_button_methods,
6567761Smsmith    sizeof(struct acpi_button_softc),
6667761Smsmith};
6767761Smsmith
6867761Smsmithdevclass_t acpi_button_devclass;
6967761SmsmithDRIVER_MODULE(acpi_button, acpi, acpi_button_driver, acpi_button_devclass, 0, 0);
7067761Smsmith
7167761Smsmithstatic int
7267761Smsmithacpi_button_probe(device_t dev)
7367761Smsmith{
7467761Smsmith    struct acpi_button_softc	*sc;
7567761Smsmith
7667761Smsmith    sc = device_get_softc(dev);
7767761Smsmith    if (acpi_get_type(dev) == ACPI_TYPE_DEVICE) {
7867761Smsmith	if (acpi_MatchHid(dev, "PNP0C0C")) {
7967761Smsmith	    device_set_desc(dev, "Control Method Power Button Device");
8067761Smsmith	    sc->button_type = ACPI_POWER_BUTTON;
8167761Smsmith	    return(0);
8267761Smsmith	}
8367761Smsmith	if (acpi_MatchHid(dev, "PNP0C0E")) {
8467761Smsmith	    device_set_desc(dev, "Control Method Sleep Button Device");
8567761Smsmith	    sc->button_type = ACPI_SLEEP_BUTTON;
8667761Smsmith	    return(0);
8767761Smsmith	}
8867761Smsmith	return(ENXIO);
8967761Smsmith    }
9067761Smsmith    return(ENXIO);
9167761Smsmith}
9267761Smsmith
9367761Smsmithstatic int
9467761Smsmithacpi_button_attach(device_t dev)
9567761Smsmith{
9667761Smsmith    struct acpi_button_softc	*sc;
9767761Smsmith    ACPI_STATUS			status;
9867761Smsmith
9967761Smsmith    sc = device_get_softc(dev);
10067761Smsmith    sc->button_dev = dev;
10167761Smsmith    sc->button_handle = acpi_get_handle(dev);
10267761Smsmith
10367761Smsmith    if ((status = AcpiInstallNotifyHandler(sc->button_handle, ACPI_DEVICE_NOTIFY,
10467761Smsmith					   acpi_button_notify_handler, sc)) != AE_OK) {
10567761Smsmith	device_printf(sc->button_dev, "couldn't install Notify handler - %s\n", acpi_strerror(status));
10667761Smsmith	return(ENXIO);
10767761Smsmith    }
10867761Smsmith    return(0);
10967761Smsmith}
11067761Smsmith
11167761Smsmithstatic void
11267761Smsmithacpi_button_notify_pressed_for_sleep(void *arg)
11367761Smsmith{
11467761Smsmith    struct acpi_button_softc	*sc;
11567761Smsmith    struct acpi_softc		*acpi_sc;
11667761Smsmith
11767761Smsmith    sc = (struct acpi_button_softc *)arg;
11867761Smsmith    acpi_sc = acpi_device_get_parent_softc(sc->button_dev);
11967761Smsmith    if (acpi_sc == NULL) {
12067761Smsmith	return;
12167761Smsmith    }
12267761Smsmith
12367761Smsmith    switch (sc->button_type) {
12467761Smsmith    case ACPI_POWER_BUTTON:
12567761Smsmith	acpi_eventhandler_power_button_for_sleep((void *)acpi_sc);
12667761Smsmith	break;
12767761Smsmith    case ACPI_SLEEP_BUTTON:
12867761Smsmith	acpi_eventhandler_sleep_button_for_sleep((void *)acpi_sc);
12967761Smsmith	break;
13067761Smsmith    default:
13167761Smsmith	return;		/* unknown button type */
13267761Smsmith    }
13367761Smsmith}
13467761Smsmith
13567761Smsmithstatic void
13667761Smsmithacpi_button_notify_pressed_for_wakeup(void *arg)
13767761Smsmith{
13867761Smsmith    struct acpi_button_softc	*sc;
13967761Smsmith    struct acpi_softc		*acpi_sc;
14067761Smsmith
14167761Smsmith    sc = (struct acpi_button_softc *)arg;
14267761Smsmith    acpi_sc = acpi_device_get_parent_softc(sc->button_dev);
14367761Smsmith    if (acpi_sc == NULL) {
14467761Smsmith	return;
14567761Smsmith    }
14667761Smsmith
14767761Smsmith    switch (sc->button_type) {
14867761Smsmith    case ACPI_POWER_BUTTON:
14967761Smsmith	acpi_eventhandler_power_button_for_wakeup((void *)acpi_sc);
15067761Smsmith	break;
15167761Smsmith    case ACPI_SLEEP_BUTTON:
15267761Smsmith	acpi_eventhandler_sleep_button_for_wakeup((void *)acpi_sc);
15367761Smsmith	break;
15467761Smsmith    default:
15567761Smsmith	return;		/* unknown button type */
15667761Smsmith    }
15767761Smsmith}
15867761Smsmith
15967761Smsmith/* XXX maybe not here */
16067761Smsmith#define ACPI_NOTIFY_BUTTON_PRESSED_FOR_SLEEP	0x80
16167761Smsmith#define ACPI_NOTIFY_BUTTON_PRESSED_FOR_WAKEUP	0x02
16267761Smsmith
16367761Smsmithstatic void
16467761Smsmithacpi_button_notify_handler(ACPI_HANDLE h, UINT32 notify, void *context)
16567761Smsmith{
16667761Smsmith    struct acpi_button_softc	*sc = (struct acpi_button_softc *)context;
16767761Smsmith
16867761Smsmith    switch (notify) {
16967761Smsmith    case ACPI_NOTIFY_BUTTON_PRESSED_FOR_SLEEP:
17067761Smsmith	AcpiOsQueueForExecution(OSD_PRIORITY_LO, acpi_button_notify_pressed_for_sleep, sc);
17167761Smsmith	device_printf(sc->button_dev, "pressed for sleep, button type: %d\n", sc->button_type);
17267761Smsmith	break;
17367761Smsmith    case ACPI_NOTIFY_BUTTON_PRESSED_FOR_WAKEUP:
17467761Smsmith	AcpiOsQueueForExecution(OSD_PRIORITY_LO, acpi_button_notify_pressed_for_wakeup, sc);
17567761Smsmith	device_printf(sc->button_dev, "pressed for wakeup, button type: %d\n", sc->button_type);
17667761Smsmith	break;
17767761Smsmith    default:
17867761Smsmith	return;		/* unknown notification value */
17967761Smsmith    }
18067761Smsmith}
18167761Smsmith
18267761Smsmith
183