I'm trying to fix the brightness hotkeys on my Dell Latitude 3160.
Adjusting the brightness using wsconsctl(1) works, as opposed of the
keys. Turns out it's not possible to move the next or previous BCL level
relative to the current one on this particular machine. Instead four
steps is the minimum required in order for the brightness to actually
change. Attached is a patch which finds the number of steps needed in
order to get the brightness to change. Any feedback would be
appreciated.
Index: acpivout.c
===================================================================
RCS file: /cvs/src/sys/dev/acpi/acpivout.c,v
retrieving revision 1.12
diff -u -p -r1.12 acpivout.c
--- acpivout.c 29 Mar 2016 17:52:04 -0000 1.12
+++ acpivout.c 30 Oct 2016 14:05:52 -0000
@@ -57,6 +57,7 @@ struct acpivout_softc {
int *sc_bcl;
size_t sc_bcl_len;
+ size_t sc_bcl_step;
};
void acpivout_brightness_cycle(struct acpivout_softc *);
@@ -178,8 +179,11 @@ acpivout_brightness_up(struct acpivout_s
if (cur_level == sc->sc_bcl[sc->sc_bcl_len - 1])
return;
- for (i = 0; i < sc->sc_bcl_len && cur_level != sc->sc_bcl[i]; i++);
- acpivout_set_brightness(sc, sc->sc_bcl[i + 1]);
+ for (i = 0; i < sc->sc_bcl_len && cur_level != sc->sc_bcl[i]; i++)
+ continue;
+ KASSERT(i < sc->sc_bcl_len - 1);
+ i += i + sc->sc_bcl_step < sc->sc_bcl_len ? sc->sc_bcl_step : 1;
+ acpivout_set_brightness(sc, sc->sc_bcl[i]);
}
void
@@ -197,8 +201,11 @@ acpivout_brightness_down(struct acpivout
if (cur_level == sc->sc_bcl[0])
return;
- for (i = 0; i < sc->sc_bcl_len && cur_level != sc->sc_bcl[i]; i++);
- acpivout_set_brightness(sc, sc->sc_bcl[i - 1]);
+ for (i = 0; i < sc->sc_bcl_len && cur_level != sc->sc_bcl[i]; i++)
+ continue;
+ KASSERT(i > 0);
+ i -= i > sc->sc_bcl_step ? sc->sc_bcl_step : 1;
+ acpivout_set_brightness(sc, sc->sc_bcl[i]);
}
void
@@ -262,8 +269,8 @@ acpivout_set_brightness(struct acpivout_
void
acpivout_get_bcl(struct acpivout_softc *sc)
{
- int i, j, value;
- struct aml_value res;
+ struct aml_value res;
+ int cur_level, i, inc, j, value;
DPRINTF(("Getting _BCL!"));
aml_evalname(sc->sc_acpi, sc->sc_devnode, "_BCL", 0, NULL, &res);
@@ -295,6 +302,30 @@ acpivout_get_bcl(struct acpivout_softc *
sc->sc_bcl[j] = sc->sc_bcl[j - 1];
sc->sc_bcl[j] = value;
}
+
+ /*
+ * Some implementations doesn't change the brightness when moving to the
+ * next or previous BCL value relative to the current one. Calculate the
+ * step needed by incrementally adjusting the brightness.
+ */
+ cur_level = acpivout_get_brightness(sc);
+ for (i = 0; i < sc->sc_bcl_len && cur_level != sc->sc_bcl[i]; i++)
+ continue;
+ inc = i < sc->sc_bcl_len/2 ? 1 : -1;
+ sc->sc_bcl_step = 1;
+ for (;;) {
+ i += inc;
+ if (i < 0 || i >= sc->sc_bcl_len)
+ break;
+
+ acpivout_set_brightness(sc, sc->sc_bcl[i]);
+ if (acpivout_get_brightness(sc) != cur_level)
+ break;
+
+ sc->sc_bcl_step++;
+ }
+ /* Restore brightness */
+ acpivout_set_brightness(sc, cur_level);
err:
aml_freevalue(&res);