Index: sys/dev/acpi_support/acpi_ibm.c =================================================================== --- sys/dev/acpi_support/acpi_ibm.c +++ sys/dev/acpi_support/acpi_ibm.c @@ -129,6 +129,7 @@ #define IBM_NAME_EVENTS_MASK_SET "MHKM" #define IBM_NAME_EVENTS_GET "MHKP" #define IBM_NAME_EVENTS_AVAILMASK "MHKA" +#define IBM_NAME_EVENTS_VERSION "MHKV" /* Event Code */ #define IBM_EVENT_LCD_BACKLIGHT 0x03 @@ -340,7 +341,7 @@ DRIVER_MODULE(acpi_ibm, acpi, acpi_ibm_driver, acpi_ibm_devclass, 0, 0); MODULE_DEPEND(acpi_ibm, acpi, 1, 1, 1); -static char *ibm_ids[] = {"IBM0068", "LEN0068", NULL}; +static char *ibm_ids[] = {"IBM0068", "LEN0068", "LEN0268", NULL}; static void ibm_led(void *softc, int onoff) @@ -386,7 +387,10 @@ static int acpi_ibm_attach(device_t dev) { - int i; + ACPI_OBJECT p, *bufp; + ACPI_OBJECT_LIST args; + ACPI_BUFFER buf; + int hkey_version; struct acpi_ibm_softc *sc; char *maker, *product; devclass_t ec_devclass; @@ -424,11 +428,41 @@ "initialmask", CTLFLAG_RD, &sc->events_initialmask, 0, "Initial eventmask"); - /* The availmask is the bitmask of supported events */ + /* + * The availmask is the bitmask of supported events, it's determined + * by calling MHKA. Old pre-0x100 versions of the hkey interface (MKHV) + * take no parameter to determine the hotkey mask. Newer models + * (post-2015, like T460, T470s, Carbon X1) take one integer parameter: + * 1: Retrieve availmask like before + * 2: Retrieve adaptive keyboard mask (currently not supported + * by this driver), only supported on models featuring + * the adaptive keyboard, otherwise returns 0 + */ if (ACPI_FAILURE(acpi_GetInteger(sc->handle, - IBM_NAME_EVENTS_AVAILMASK, &sc->events_availmask))) - sc->events_availmask = 0xffffffff; + IBM_NAME_EVENTS_VERSION, &hkey_version))) + hkey_version = 0x100; /* default to version 1 of the hkey interface */ + if ((hkey_version >> 8) < 2) { + if (ACPI_FAILURE(acpi_GetInteger(sc->handle, + IBM_NAME_EVENTS_AVAILMASK, &sc->events_availmask))) + sc->events_availmask = 0xffffffff; + } else { + p.Type = ACPI_TYPE_INTEGER; + p.Integer.Value = 1; + args.Count = 1; + args.Pointer = &p; + buf.Length = ACPI_ALLOCATE_BUFFER; + if (ACPI_FAILURE(AcpiEvaluateObjectTyped(sc->handle, + IBM_NAME_EVENTS_AVAILMASK, &args, &buf, + ACPI_TYPE_INTEGER))) + sc->events_availmask = 0xffffffff; + else { + bufp = buf.Pointer; + sc->events_availmask= bufp->Integer.Value; + AcpiOsFree(buf.Pointer); + } + } + SYSCTL_ADD_UINT(sc->sysctl_ctx, SYSCTL_CHILDREN(sc->sysctl_tree), OID_AUTO, "availmask", CTLFLAG_RD, @@ -488,7 +522,7 @@ if (maker == NULL || product == NULL) goto nosmbios; - for (i = 0; i < nitems(acpi_ibm_models); i++) { + for (int 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);