Page MenuHomeFreeBSD

D14103.id38655.diff
No OneTemporary

D14103.id38655.diff

Index: sys/dev/acpi_support/acpi_ibm.c
===================================================================
--- sys/dev/acpi_support/acpi_ibm.c
+++ sys/dev/acpi_support/acpi_ibm.c
@@ -1,6 +1,7 @@
/*-
* Copyright (c) 2004 Takanori Watanabe
* Copyright (c) 2005 Markus Brueffer <markus@FreeBSD.org>
+ * Copyright (c) 2018 Michael Gmelin <grembo@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -74,6 +75,9 @@
#define ACPI_IBM_METHOD_FANSTATUS 12
#define ACPI_IBM_METHOD_THERMAL 13
#define ACPI_IBM_METHOD_HANDLEREVENTS 14
+#define ACPI_IBM_METHOD_KBD_BACKLIGHT 15
+#define ACPI_IBM_METHOD_KBD_BL_LEDON 16
+#define ACPI_IBM_METHOD_KBD_BL_LEDOFF 17
/* Hotkeys/Buttons */
#define IBM_RTC_HOTKEY1 0x64
@@ -129,7 +133,13 @@
#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"
+#define IBM_NAME_KBD_BACKLIGHT_GET "MLCG"
+#define IBM_NAME_MASK_KBD_BL_SUPPORT (1 << 9)
+#define IBM_NAME_MASK_KBD_BL_LEVEL 0x3
+#define IBM_NAME_KBD_BACKLIGHT_SET "MLCS"
+
/* Event Code */
#define IBM_EVENT_LCD_BACKLIGHT 0x03
#define IBM_EVENT_SUSPEND_TO_RAM 0x04
@@ -170,11 +180,22 @@
int light_get_supported;
int light_set_supported;
- /* led(4) interface */
+ /* led(4) interface for thinklight */
struct cdev *led_dev;
int led_busy;
int led_state;
+ /* Keyboard backlight support */
+ int kbd_backlight_supported;
+ int kbd_backlight_val;
+
+ /* led(4) interface for keyboard backlight */
+ struct cdev *kbd_backlight_led_dev;
+ int kbd_backlight_led_busy;
+ int kbd_backlight_led_state;
+ int kbd_backlight_ledon;
+ int kbd_backlight_ledoff;
+
int wlan_bt_flags;
int thermal_updt_supported;
@@ -258,6 +279,21 @@
.method = ACPI_IBM_METHOD_FANSTATUS,
.description = "Fan enable",
},
+ {
+ .name = "kbd_backlight",
+ .method = ACPI_IBM_METHOD_KBD_BACKLIGHT,
+ .description = "Keyboard backlight level",
+ },
+ {
+ .name = "kbd_backlight_ledon",
+ .method = ACPI_IBM_METHOD_KBD_BL_LEDON,
+ .description = "Keyboard backlight led-on level",
+ },
+ {
+ .name = "kbd_backlight_ledoff",
+ .method = ACPI_IBM_METHOD_KBD_BL_LEDOFF,
+ .description = "Keyboard backlight led-off level",
+ },
{ NULL, 0, NULL, 0 }
};
@@ -303,6 +339,10 @@
static void ibm_led(void *softc, int onoff);
static void ibm_led_task(struct acpi_ibm_softc *sc, int pending __unused);
+static void ibm_kbd_backlight_led(void *softc, int onoff);
+static void ibm_kbd_backlight_led_task(struct acpi_ibm_softc *sc,
+ int pending __unused);
+
static int acpi_ibm_sysctl(SYSCTL_HANDLER_ARGS);
static int acpi_ibm_sysctl_init(struct acpi_ibm_softc *sc, int method);
static int acpi_ibm_sysctl_get(struct acpi_ibm_softc *sc, int method);
@@ -318,6 +358,7 @@
static int acpi_ibm_thinklight_set(struct acpi_ibm_softc *sc, int arg);
static int acpi_ibm_volume_set(struct acpi_ibm_softc *sc, int arg);
static int acpi_ibm_mute_set(struct acpi_ibm_softc *sc, int arg);
+static int acpi_ibm_kbd_backlight_set(struct acpi_ibm_softc *sc, int arg);
static device_method_t acpi_ibm_methods[] = {
/* Device interface */
@@ -340,7 +381,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)
@@ -370,6 +411,37 @@
sc->led_busy = 0;
}
+static void
+ibm_kbd_backlight_led(void *softc, int onoff)
+{
+ struct acpi_ibm_softc* sc = (struct acpi_ibm_softc*) softc;
+
+ ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
+
+ if (sc->kbd_backlight_led_busy)
+ return;
+
+ sc->kbd_backlight_led_busy = 1;
+ sc->kbd_backlight_led_state = onoff;
+
+ AcpiOsExecute(OSL_NOTIFY_HANDLER, (void *)ibm_kbd_backlight_led_task,
+ sc);
+}
+
+static void
+ibm_kbd_backlight_led_task(struct acpi_ibm_softc *sc, int pending __unused)
+{
+ ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
+
+ ACPI_SERIAL_BEGIN(ibm);
+ acpi_ibm_sysctl_set(sc, ACPI_IBM_METHOD_KBD_BACKLIGHT,
+ sc->kbd_backlight_led_state ?
+ sc->kbd_backlight_ledon : sc->kbd_backlight_ledoff);
+ ACPI_SERIAL_END(ibm);
+
+ sc->kbd_backlight_led_busy = 0;
+}
+
static int
acpi_ibm_probe(device_t dev)
{
@@ -386,7 +458,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 +499,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,
@@ -482,13 +587,19 @@
sc->led_dev = led_create_state(ibm_led, sc, "thinklight",
(sc->light_val ? 1 : 0));
+ /* Hook up keyboard backlight to led(4) */
+ if (sc->kbd_backlight_supported)
+ sc->kbd_backlight_led_dev = led_create_state(
+ ibm_kbd_backlight_led, sc, "kbd_backlight",
+ (sc->kbd_backlight_val ? 1 : 0));
+
/* Enable per-model events. */
maker = kern_getenv("smbios.system.maker");
product = kern_getenv("smbios.system.product");
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);
@@ -529,6 +640,9 @@
if (sc->led_dev != NULL)
led_destroy(sc->led_dev);
+ if (sc->kbd_backlight_led_dev != NULL)
+ led_destroy(sc->kbd_backlight_led_dev);
+
return (0);
}
@@ -739,6 +853,22 @@
else
val = -1;
break;
+
+ case ACPI_IBM_METHOD_KBD_BACKLIGHT:
+ if (sc->kbd_backlight_supported)
+ acpi_GetInteger(sc->handle, IBM_NAME_KBD_BACKLIGHT_GET, &val);
+ else
+ val = sc->kbd_backlight_val;
+ val &= IBM_NAME_MASK_KBD_BL_LEVEL;
+ break;
+
+ case ACPI_IBM_METHOD_KBD_BL_LEDON:
+ val = sc->kbd_backlight_ledon;
+ break;
+
+ case ACPI_IBM_METHOD_KBD_BL_LEDOFF:
+ val = sc->kbd_backlight_ledoff;
+ break;
}
return (val);
@@ -816,6 +946,24 @@
(arg == 1) ? (val_ec | IBM_EC_MASK_FANSTATUS) : (val_ec & (~IBM_EC_MASK_FANSTATUS)), 1);
}
break;
+
+ case ACPI_IBM_METHOD_KBD_BACKLIGHT:
+ return acpi_ibm_kbd_backlight_set(sc, arg);
+ break;
+
+ case ACPI_IBM_METHOD_KBD_BL_LEDON:
+ if (arg < 0 || arg > 2)
+ return (EINVAL);
+
+ sc->kbd_backlight_ledon = arg;
+ break;
+
+ case ACPI_IBM_METHOD_KBD_BL_LEDOFF:
+ if (arg < 0 || arg > 2)
+ return (EINVAL);
+
+ sc->kbd_backlight_ledoff = arg;
+ break;
}
return (0);
@@ -911,6 +1059,29 @@
case ACPI_IBM_METHOD_HANDLEREVENTS:
return (TRUE);
+
+ case ACPI_IBM_METHOD_KBD_BACKLIGHT:
+ if (ACPI_FAILURE(acpi_GetInteger(sc->handle, IBM_NAME_KBD_BACKLIGHT_GET,
+ &sc->kbd_backlight_val)))
+ sc->kbd_backlight_val = 0;
+ sc->kbd_backlight_supported = sc->kbd_backlight_val &
+ IBM_NAME_MASK_KBD_BL_SUPPORT;
+ sc->kbd_backlight_val &= IBM_NAME_MASK_KBD_BL_LEVEL;
+ if (sc->kbd_backlight_supported)
+ return (TRUE);
+ return (FALSE);
+
+ case ACPI_IBM_METHOD_KBD_BL_LEDON:
+ sc->kbd_backlight_ledon = 1;
+ if (sc->kbd_backlight_supported)
+ return (TRUE);
+ return (FALSE);
+
+ case ACPI_IBM_METHOD_KBD_BL_LEDOFF:
+ sc->kbd_backlight_ledoff = 0;
+ if (sc->kbd_backlight_supported)
+ return (TRUE);
+ return (FALSE);
}
return (FALSE);
}
@@ -1210,6 +1381,27 @@
val_ec = (arg == 1) ? val_ec | IBM_EC_MASK_MUTE :
val_ec & (~IBM_EC_MASK_MUTE);
return ACPI_EC_WRITE(sc->ec_dev, IBM_EC_VOLUME, val_ec, 1);
+}
+
+static int
+acpi_ibm_kbd_backlight_set(struct acpi_ibm_softc *sc, int arg)
+{
+ ACPI_STATUS status;
+
+ ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
+ ACPI_SERIAL_ASSERT(ibm);
+
+ if (arg < 0 || arg > 2)
+ return (EINVAL);
+
+ if (sc->kbd_backlight_supported) {
+ status = acpi_SetInteger(sc->handle, IBM_NAME_KBD_BACKLIGHT_SET, arg);
+ if (ACPI_SUCCESS(status))
+ sc->kbd_backlight_val = arg;
+ return (status);
+ }
+
+ return (0);
}
static void

File Metadata

Mime Type
text/plain
Expires
Thu, Jan 15, 10:59 PM (14 h, 18 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
27655658
Default Alt Text
D14103.id38655.diff (9 KB)

Event Timeline