Add support for fixed event buttons defined in the DSDT (HID "ACPI_FSB"
and "ACPI_FPB"). Pointed out by: Linux
This commit is contained in:
parent
f8363bdee9
commit
be8dca590c
@ -43,9 +43,10 @@ ACPI_MODULE_NAME("BUTTON")
|
||||
struct acpi_button_softc {
|
||||
device_t button_dev;
|
||||
ACPI_HANDLE button_handle;
|
||||
boolean_t button_type; /* Power or Sleep Button */
|
||||
boolean_t button_type;
|
||||
#define ACPI_POWER_BUTTON 0
|
||||
#define ACPI_SLEEP_BUTTON 1
|
||||
boolean_t fixed;
|
||||
};
|
||||
|
||||
#define ACPI_NOTIFY_BUTTON_PRESSED_FOR_SLEEP 0x80
|
||||
@ -57,6 +58,8 @@ static int acpi_button_suspend(device_t dev);
|
||||
static int acpi_button_resume(device_t dev);
|
||||
static void acpi_button_notify_handler(ACPI_HANDLE h, UINT32 notify,
|
||||
void *context);
|
||||
static ACPI_STATUS
|
||||
acpi_button_fixed_handler(void *context);
|
||||
static void acpi_button_notify_pressed_for_sleep(void *arg);
|
||||
static void acpi_button_notify_pressed_for_wakeup(void *arg);
|
||||
|
||||
@ -85,23 +88,31 @@ static int
|
||||
acpi_button_probe(device_t dev)
|
||||
{
|
||||
struct acpi_button_softc *sc;
|
||||
int ret = ENXIO;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
if (acpi_get_type(dev) == ACPI_TYPE_DEVICE) {
|
||||
if (!acpi_disabled("button")) {
|
||||
if (acpi_MatchHid(dev, "PNP0C0C")) {
|
||||
device_set_desc(dev, "Power Button");
|
||||
sc->button_type = ACPI_POWER_BUTTON;
|
||||
return (0);
|
||||
}
|
||||
if (acpi_MatchHid(dev, "PNP0C0E")) {
|
||||
device_set_desc(dev, "Sleep Button");
|
||||
sc->button_type = ACPI_SLEEP_BUTTON;
|
||||
return (0);
|
||||
}
|
||||
if (acpi_get_type(dev) == ACPI_TYPE_DEVICE && !acpi_disabled("button")) {
|
||||
if (acpi_MatchHid(dev, "PNP0C0C")) {
|
||||
device_set_desc(dev, "Power Button");
|
||||
sc->button_type = ACPI_POWER_BUTTON;
|
||||
ret = 0;
|
||||
} else if (acpi_MatchHid(dev, "ACPI_FPB")) {
|
||||
device_set_desc(dev, "Power Button (fixed)");
|
||||
sc->button_type = ACPI_POWER_BUTTON;
|
||||
sc->fixed = 1;
|
||||
ret = 0;
|
||||
} else if (acpi_MatchHid(dev, "PNP0C0E")) {
|
||||
device_set_desc(dev, "Sleep Button");
|
||||
sc->button_type = ACPI_SLEEP_BUTTON;
|
||||
ret = 0;
|
||||
} else if (acpi_MatchHid(dev, "ACPI_FSB")) {
|
||||
device_set_desc(dev, "Sleep Button (fixed)");
|
||||
sc->button_type = ACPI_SLEEP_BUTTON;
|
||||
sc->fixed = 1;
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
return (ENXIO);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -109,6 +120,7 @@ acpi_button_attach(device_t dev)
|
||||
{
|
||||
struct acpi_button_softc *sc;
|
||||
ACPI_STATUS status;
|
||||
int event;
|
||||
|
||||
ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
|
||||
|
||||
@ -116,10 +128,17 @@ acpi_button_attach(device_t dev)
|
||||
sc->button_dev = dev;
|
||||
sc->button_handle = acpi_get_handle(dev);
|
||||
|
||||
status = AcpiInstallNotifyHandler(sc->button_handle, ACPI_DEVICE_NOTIFY,
|
||||
acpi_button_notify_handler, sc);
|
||||
if (sc->fixed) {
|
||||
event = (sc->button_type == ACPI_SLEEP_BUTTON) ?
|
||||
ACPI_EVENT_SLEEP_BUTTON : ACPI_EVENT_POWER_BUTTON;
|
||||
status = AcpiInstallFixedEventHandler(event,
|
||||
acpi_button_fixed_handler, sc);
|
||||
} else {
|
||||
status = AcpiInstallNotifyHandler(sc->button_handle,
|
||||
ACPI_DEVICE_NOTIFY, acpi_button_notify_handler, sc);
|
||||
}
|
||||
if (ACPI_FAILURE(status)) {
|
||||
device_printf(sc->button_dev, "couldn't install Notify handler - %s\n",
|
||||
device_printf(sc->button_dev, "couldn't install notify handler - %s\n",
|
||||
AcpiFormatException(status));
|
||||
return_VALUE (ENXIO);
|
||||
}
|
||||
@ -217,3 +236,16 @@ acpi_button_notify_handler(ACPI_HANDLE h, UINT32 notify, void *context)
|
||||
break; /* unknown notification value */
|
||||
}
|
||||
}
|
||||
|
||||
static ACPI_STATUS
|
||||
acpi_button_fixed_handler(void *context)
|
||||
{
|
||||
struct acpi_button_softc *sc = (struct acpi_button_softc *)context;
|
||||
|
||||
if (context == NULL)
|
||||
return_ACPI_STATUS (AE_BAD_PARAMETER);
|
||||
|
||||
acpi_button_notify_handler(sc->button_handle,
|
||||
ACPI_NOTIFY_BUTTON_PRESSED_FOR_SLEEP, sc);
|
||||
return_VALUE (AE_OK);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user