On Tue, Mar 05, 2019 at 02:03:13PM -0600, joshua stein wrote: > Here we go again... > > On at least the ThinkPad X1C6, the screen brightness keys (F5 and > F6) do not work and "wsconsctl keyboard.backlight" doesn't report > the correct value when the keyboard backlight is adjusted with > Fn+Space. > > These are both caused by the default event mask not including these > events, so explicitly enable them. > > But then acpithinkpad has to actually do something for the screen > brightness keys, but it tries the very old CMOS method which doesn't > work on these newer machines[0]. So make it use the ACPI method. > > I renamed thinkpad_[gs]et_backlight to thinkpad_[gs]et_kbd_backlight > because it was confusing that they have nothing to do with screen > backlight. > > > 0. "newer machines" being those with MHKV reporting version 2. If > this diff breaks on older "newer machines", this metric will have to > be changed to something else. >
Tested on an x240 and x270. Both work fine (actually fixes the x270). Diff reads ok to me. OK claudio@ > Index: sys/dev/acpi/acpithinkpad.c > =================================================================== > RCS file: /cvs/src/sys/dev/acpi/acpithinkpad.c,v > retrieving revision 1.61 > diff -u -p -u -p -r1.61 acpithinkpad.c > --- sys/dev/acpi/acpithinkpad.c 1 Jul 2018 19:40:49 -0000 1.61 > +++ sys/dev/acpi/acpithinkpad.c 5 Mar 2019 20:00:23 -0000 > @@ -124,6 +124,10 @@ > #define THINKPAD_ADAPTIVE_MODE_HOME 1 > #define THINKPAD_ADAPTIVE_MODE_FUNCTION 3 > > +#define THINKPAD_MASK_BRIGHTNESS_UP (1 << 15) > +#define THINKPAD_MASK_BRIGHTNESS_DOWN (1 << 16) > +#define THINKPAD_MASK_KBD_BACKLIGHT (1 << 17) > + > struct acpithinkpad_softc { > struct device sc_dev; > > @@ -134,6 +138,8 @@ struct acpithinkpad_softc { > struct ksensor sc_sens[THINKPAD_NSENSORS]; > struct ksensordev sc_sensdev; > > + uint64_t sc_hkey_version; > + > uint64_t sc_thinklight; > const char *sc_thinklight_get; > const char *sc_thinklight_set; > @@ -161,8 +167,8 @@ int thinkpad_activate(struct device *, i > /* wscons hook functions */ > void thinkpad_get_thinklight(struct acpithinkpad_softc *); > void thinkpad_set_thinklight(void *, int); > -int thinkpad_get_backlight(struct wskbd_backlight *); > -int thinkpad_set_backlight(struct wskbd_backlight *); > +int thinkpad_get_kbd_backlight(struct wskbd_backlight *); > +int thinkpad_set_kbd_backlight(struct wskbd_backlight *); > extern int (*wskbd_get_backlight)(struct wskbd_backlight *); > extern int (*wskbd_set_backlight)(struct wskbd_backlight *); > void thinkpad_get_brightness(struct acpithinkpad_softc *); > @@ -284,6 +290,10 @@ thinkpad_attach(struct device *parent, s > > printf("\n"); > > + if (aml_evalinteger(sc->sc_acpi, sc->sc_devnode, "MHKV", 0, NULL, > + &sc->sc_hkey_version)) > + sc->sc_hkey_version = THINKPAD_HKEY_VERSION1; > + > #if NAUDIO > 0 && NWSKBD > 0 > /* Defer speaker mute */ > if (thinkpad_get_volume_mute(sc) == 1) > @@ -299,14 +309,14 @@ thinkpad_attach(struct device *parent, s > 0, NULL, &sc->sc_thinklight) == 0) { > sc->sc_thinklight_get = "KLCG"; > sc->sc_thinklight_set = "KLCS"; > - wskbd_get_backlight = thinkpad_get_backlight; > - wskbd_set_backlight = thinkpad_set_backlight; > + wskbd_get_backlight = thinkpad_get_kbd_backlight; > + wskbd_set_backlight = thinkpad_set_kbd_backlight; > } else if (aml_evalinteger(sc->sc_acpi, sc->sc_devnode, "MLCG", > 0, NULL, &sc->sc_thinklight) == 0) { > sc->sc_thinklight_get = "MLCG"; > sc->sc_thinklight_set = "MLCS"; > - wskbd_get_backlight = thinkpad_get_backlight; > - wskbd_set_backlight = thinkpad_set_backlight; > + wskbd_get_backlight = thinkpad_get_kbd_backlight; > + wskbd_set_backlight = thinkpad_set_kbd_backlight; > } > > if (aml_evalinteger(sc->sc_acpi, sc->sc_devnode, "PBLG", > @@ -327,13 +337,19 @@ thinkpad_enable_events(struct acpithinkp > int64_t mask; > int i; > > - /* Get the supported event mask */ > + /* Get the default event mask */ > if (aml_evalinteger(sc->sc_acpi, sc->sc_devnode, "MHKA", > 0, NULL, &mask)) { > printf("%s: no MHKA\n", DEVNAME(sc)); > return (1); > } > > + /* Enable events we need to know about */ > + mask |= (THINKPAD_MASK_BRIGHTNESS_UP | THINKPAD_MASK_BRIGHTNESS_DOWN | > + THINKPAD_MASK_KBD_BACKLIGHT); > + > + DPRINTF(("%s: setting event mask to 0x%llx\n", DEVNAME(sc), mask)); > + > /* Update hotkey mask */ > bzero(args, sizeof(args)); > args[0].type = args[1].type = AML_OBJTYPE_INTEGER; > @@ -380,6 +396,8 @@ thinkpad_hotkey(struct aml_node *node, i > if (aml_evalinteger(sc->sc_acpi, sc->sc_devnode, "MHKP", > 0, NULL, &event)) > break; > + > + DPRINTF(("%s: event 0x%03llx\n", DEVNAME(sc), event)); > if (event == 0) > break; > > @@ -535,13 +553,37 @@ thinkpad_volume_mute(struct acpithinkpad > int > thinkpad_brightness_up(struct acpithinkpad_softc *sc) > { > - return (thinkpad_cmos(sc, THINKPAD_CMOS_BRIGHTNESS_UP)); > + int b; > + > + if (sc->sc_hkey_version == THINKPAD_HKEY_VERSION2) { > + thinkpad_get_brightness(sc); > + b = sc->sc_brightness & 0xff; > + if (b < ((sc->sc_brightness >> 8) & 0xff)) { > + sc->sc_brightness = b + 1; > + thinkpad_set_brightness(sc, 0); > + } > + > + return (0); > + } else > + return (thinkpad_cmos(sc, THINKPAD_CMOS_BRIGHTNESS_UP)); > } > > int > thinkpad_brightness_down(struct acpithinkpad_softc *sc) > { > - return (thinkpad_cmos(sc, THINKPAD_CMOS_BRIGHTNESS_DOWN)); > + int b; > + > + if (sc->sc_hkey_version == THINKPAD_HKEY_VERSION2) { > + thinkpad_get_brightness(sc); > + b = sc->sc_brightness & 0xff; > + if (b > 0) { > + sc->sc_brightness = b - 1; > + thinkpad_set_brightness(sc, 0); > + } > + > + return (0); > + } else > + return (thinkpad_cmos(sc, THINKPAD_CMOS_BRIGHTNESS_DOWN)); > } > > int > @@ -620,7 +662,7 @@ thinkpad_set_thinklight(void *arg0, int > } > > int > -thinkpad_get_backlight(struct wskbd_backlight *kbl) > +thinkpad_get_kbd_backlight(struct wskbd_backlight *kbl) > { > struct acpithinkpad_softc *sc = acpithinkpad_cd.cd_devs[0]; > > @@ -637,7 +679,7 @@ thinkpad_get_backlight(struct wskbd_back > } > > int > -thinkpad_set_backlight(struct wskbd_backlight *kbl) > +thinkpad_set_kbd_backlight(struct wskbd_backlight *kbl) > { > struct acpithinkpad_softc *sc = acpithinkpad_cd.cd_devs[0]; > int maxval; > @@ -664,6 +706,8 @@ thinkpad_get_brightness(struct acpithink > { > aml_evalinteger(sc->sc_acpi, sc->sc_devnode, > "PBLG", 0, NULL, &sc->sc_brightness); > + > + DPRINTF(("%s: %s: 0x%llx\n", DEVNAME(sc), __func__, sc->sc_brightness)); > } > > void > @@ -672,11 +716,15 @@ thinkpad_set_brightness(void *arg0, int > struct acpithinkpad_softc *sc = arg0; > struct aml_value arg; > > + DPRINTF(("%s: %s: 0x%llx\n", DEVNAME(sc), __func__, sc->sc_brightness)); > + > memset(&arg, 0, sizeof(arg)); > arg.type = AML_OBJTYPE_INTEGER; > arg.v_integer = sc->sc_brightness & 0xff; > aml_evalname(sc->sc_acpi, sc->sc_devnode, > "PBLS", 1, &arg, NULL); > + > + thinkpad_get_brightness(sc); > } > > int > -- :wq Claudio