acpi_ibm: add per-model default events mask.

Add support for the hotkeys on a Lenovo X1 3rd gen. This also enables
event reporting by default.
This commit is contained in:
Rui Paulo 2015-05-29 05:28:24 +00:00
parent d917e7d549
commit 78fd538146

View File

@ -39,6 +39,7 @@ __FBSDID("$FreeBSD$");
#include "opt_acpi.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/bus.h>
#include <machine/cpufunc.h>
@ -261,6 +262,37 @@ static struct {
{ NULL, 0, NULL, 0 }
};
/*
* Per-model default list of event mask.
*/
#define ACPI_IBM_HKEY_RFKILL_MASK (1 << 4)
#define ACPI_IBM_HKEY_DSWITCH_MASK (1 << 6)
#define ACPI_IBM_HKEY_BRIGHTNESS_UP_MASK (1 << 15)
#define ACPI_IBM_HKEY_BRIGHTNESS_DOWN_MASK (1 << 16)
#define ACPI_IBM_HKEY_SEARCH_MASK (1 << 18)
#define ACPI_IBM_HKEY_MICMUTE_MASK (1 << 26)
#define ACPI_IBM_HKEY_SETTINGS_MASK (1 << 28)
#define ACPI_IBM_HKEY_VIEWOPEN_MASK (1 << 30)
#define ACPI_IBM_HKEY_VIEWALL_MASK (1 << 31)
struct acpi_ibm_models {
const char *maker;
const char *product;
uint32_t eventmask;
} acpi_ibm_models[] = {
{ "LENOVO", "20BSCTO1WW",
ACPI_IBM_HKEY_RFKILL_MASK |
ACPI_IBM_HKEY_DSWITCH_MASK |
ACPI_IBM_HKEY_BRIGHTNESS_UP_MASK |
ACPI_IBM_HKEY_BRIGHTNESS_DOWN_MASK |
ACPI_IBM_HKEY_SEARCH_MASK |
ACPI_IBM_HKEY_MICMUTE_MASK |
ACPI_IBM_HKEY_SETTINGS_MASK |
ACPI_IBM_HKEY_VIEWOPEN_MASK |
ACPI_IBM_HKEY_VIEWALL_MASK
}
};
ACPI_SERIAL_DECL(ibm, "ACPI IBM extras");
static int acpi_ibm_probe(device_t dev);
@ -354,7 +386,9 @@ acpi_ibm_probe(device_t dev)
static int
acpi_ibm_attach(device_t dev)
{
int i;
struct acpi_ibm_softc *sc;
char *maker, *product;
devclass_t ec_devclass;
ACPI_FUNCTION_TRACE((char *)(uintptr_t) __func__);
@ -448,6 +482,27 @@ acpi_ibm_attach(device_t dev)
sc->led_dev = led_create_state(ibm_led, sc, "thinklight",
(sc->light_val ? 1 : 0));
/* Enable per-model events. */
maker = kern_getenv("smbios.system.maker");
product = kern_getenv("smbios.system.product");
for (i = 0; i < nitems(acpi_ibm_models); i++) {
if (strcmp(maker, acpi_ibm_models[i].maker) == 0 &&
strcmp(product, acpi_ibm_models[i].product) == 0) {
ACPI_SERIAL_BEGIN(ibm);
acpi_ibm_sysctl_set(sc, ACPI_IBM_METHOD_EVENTMASK,
acpi_ibm_models[i].eventmask);
ACPI_SERIAL_END(ibm);
}
}
freeenv(maker);
freeenv(product);
/* Enable events by default. */
ACPI_SERIAL_BEGIN(ibm);
acpi_ibm_sysctl_set(sc, ACPI_IBM_METHOD_EVENTS, 1);
ACPI_SERIAL_END(ibm);
return (0);
}
@ -770,7 +825,6 @@ acpi_ibm_sysctl_init(struct acpi_ibm_softc *sc, int method)
switch (method) {
case ACPI_IBM_METHOD_EVENTS:
/* Events are disabled by default */
return (TRUE);
case ACPI_IBM_METHOD_EVENTMASK:
@ -1229,7 +1283,6 @@ acpi_ibm_notify(ACPI_HANDLE h, UINT32 notify, void *context)
for (;;) {
acpi_GetInteger(acpi_get_handle(dev), IBM_NAME_EVENTS_GET, &event);
if (event == 0)
break;