summaryrefslogtreecommitdiff
path: root/sys/dev/acpi
diff options
context:
space:
mode:
authorriastradh <riastradh@NetBSD.org>2021-12-30 14:40:06 +0000
committerriastradh <riastradh@NetBSD.org>2021-12-30 14:40:06 +0000
commit53534a3f77d443d2aaae8aab58267ebebae1ee27 (patch)
treef208555551c47c381f9a9b1c43463db533f4b293 /sys/dev/acpi
parent118da34c33176ca6395c148c170c648b168b0714 (diff)
acpiout(4): Work around firmware that doesn't like some brightnesses.
Instead of just asking for cur - 5 or cur + 5, repeatedly ask for that increment, check whether we actually made progress in that direction, and if not keep going with another increment, until we hit the bounds of brightness levels. I can't find anything in the ACPI spec about this, but my laptop seems to have trouble with certain levels: 15, 75, 85, 95. It goes in all other increments of 5 from 5 to 100, just not those ones -- acts as if the change just never happened, so with the old logic the brightness up/down would get stuck unable to move in either direction. This should have no impact on machines where the first increment actually takes.
Diffstat (limited to 'sys/dev/acpi')
-rw-r--r--sys/dev/acpi/acpi_display.c60
1 files changed, 36 insertions, 24 deletions
diff --git a/sys/dev/acpi/acpi_display.c b/sys/dev/acpi/acpi_display.c
index 1e1a0db8d2e..026627b7e2a 100644
--- a/sys/dev/acpi/acpi_display.c
+++ b/sys/dev/acpi/acpi_display.c
@@ -1,4 +1,4 @@
-/* $NetBSD: acpi_display.c,v 1.20 2021/08/07 16:19:09 thorpej Exp $ */
+/* $NetBSD: acpi_display.c,v 1.21 2021/12/30 14:40:06 riastradh Exp $ */
/*-
* Copyright (c) 2010 The NetBSD Foundation, Inc.
@@ -66,7 +66,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: acpi_display.c,v 1.20 2021/08/07 16:19:09 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: acpi_display.c,v 1.21 2021/12/30 14:40:06 riastradh Exp $");
#include <sys/param.h>
#include <sys/device.h>
@@ -1010,7 +1010,8 @@ acpidisp_out_increase_brightness_callback(void *arg)
{
struct acpidisp_out_softc *osc = arg;
struct acpidisp_brctl *bc = osc->sc_brctl;
- uint8_t lo, up;
+ uint8_t max, lo, up;
+ int cur;
if (bc == NULL) {
/* Fallback to pmf(9). */
@@ -1019,16 +1020,21 @@ acpidisp_out_increase_brightness_callback(void *arg)
}
mutex_enter(osc->sc_mtx);
-
- (void)acpidisp_get_brightness(osc, &bc->bc_current);
-
- acpidisp_array_search(bc->bc_level, bc->bc_level_count,
- bc->bc_current + ACPI_DISP_BRCTL_STEP, &lo, &up);
-
- bc->bc_current = up;
- (void)acpidisp_set_brightness(osc, bc->bc_current);
-
- mutex_exit(osc->sc_mtx);
+ max = bc->bc_level[bc->bc_level_count - 1];
+ if (acpidisp_get_brightness(osc, &bc->bc_current))
+ goto out;
+ for (cur = bc->bc_current; (cur += ACPI_DISP_BRCTL_STEP) <= max;) {
+ acpidisp_array_search(bc->bc_level, bc->bc_level_count, cur,
+ &lo, &up);
+ bc->bc_current = up;
+ if (acpidisp_set_brightness(osc, bc->bc_current))
+ goto out;
+ if (acpidisp_get_brightness(osc, &bc->bc_current))
+ goto out;
+ if (bc->bc_current >= cur)
+ break;
+ }
+out: mutex_exit(osc->sc_mtx);
}
static void
@@ -1036,7 +1042,8 @@ acpidisp_out_decrease_brightness_callback(void *arg)
{
struct acpidisp_out_softc *osc = arg;
struct acpidisp_brctl *bc = osc->sc_brctl;
- uint8_t lo, up;
+ uint8_t min, lo, up;
+ int cur;
if (bc == NULL) {
/* Fallback to pmf(9). */
@@ -1045,16 +1052,21 @@ acpidisp_out_decrease_brightness_callback(void *arg)
}
mutex_enter(osc->sc_mtx);
-
- (void)acpidisp_get_brightness(osc, &bc->bc_current);
-
- acpidisp_array_search(bc->bc_level, bc->bc_level_count,
- bc->bc_current - ACPI_DISP_BRCTL_STEP, &lo, &up);
-
- bc->bc_current = lo;
- (void)acpidisp_set_brightness(osc, bc->bc_current);
-
- mutex_exit(osc->sc_mtx);
+ min = bc->bc_level[0];
+ if (acpidisp_get_brightness(osc, &bc->bc_current))
+ goto out;
+ for (cur = bc->bc_current; (cur -= ACPI_DISP_BRCTL_STEP) >= min;) {
+ acpidisp_array_search(bc->bc_level, bc->bc_level_count, cur,
+ &lo, &up);
+ bc->bc_current = lo;
+ if (acpidisp_set_brightness(osc, bc->bc_current))
+ goto out;
+ if (acpidisp_get_brightness(osc, &bc->bc_current))
+ goto out;
+ if (bc->bc_current <= cur)
+ break;
+ }
+out: mutex_exit(osc->sc_mtx);
}
static void