Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F142014932
D14103.id38655.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
9 KB
Referenced Files
None
Subscribers
None
D14103.id38655.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D14103: Support post-2015 Lenovo models in acpi_ibm / support keyboard backlight (also led(4)) / support micmute led(4)
Attached
Detach File
Event Timeline
Log In to Comment