summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2020-04-19 15:05:16 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2020-04-19 15:05:16 +0000
commit665e49b26083d06d142bf33b45c1aded7d6bb815 (patch)
tree85d5381f94d35fdb4dfd6a145ddf207ccd92f5bf
parent4d85d754528985a769e7754fc22f6a0c3c7f3608 (diff)
Move logic to change brightness level in reasonable steps from acpivout(4)
into wsdisplay(4). This code is now exposed through wsdisplay_brightness_{step,zero,cycle} functions that can be called by any driver that handles brightnes "hotkeys". These functions take a wsdisplay(4) device pointer as their first argument, which should be provided if a clear association between events and a particular display exist. This is used in wskbd(4). Otherwise NULL can be passed and the code will direct the request at the first wsdisplay(4) that implements brightness adjustment. Tested by many. Fixes brightness keys on x395 and other thinkpads with AMD graphics. ok patrick@
-rw-r--r--sys/dev/acpi/acpivout.c74
-rw-r--r--sys/dev/wscons/wsdisplay.c114
-rw-r--r--sys/dev/wscons/wsdisplayvar.h6
-rw-r--r--sys/dev/wscons/wskbd.c10
4 files changed, 129 insertions, 75 deletions
diff --git a/sys/dev/acpi/acpivout.c b/sys/dev/acpi/acpivout.c
index 016cb89c6df..86d60b259e9 100644
--- a/sys/dev/acpi/acpivout.c
+++ b/sys/dev/acpi/acpivout.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: acpivout.c,v 1.21 2020/04/06 00:01:08 pirofti Exp $ */
+/* $OpenBSD: acpivout.c,v 1.22 2020/04/19 15:05:14 kettenis Exp $ */
/*
* Copyright (c) 2009 Paul Irofti <paul@irofti.net>
*
@@ -64,9 +64,6 @@ struct acpivout_softc {
int sc_brightness;
};
-void acpivout_brightness_cycle(struct acpivout_softc *);
-void acpivout_brightness_step(struct acpivout_softc *, int);
-void acpivout_brightness_zero(struct acpivout_softc *);
int acpivout_get_brightness(struct acpivout_softc *);
int acpivout_select_brightness(struct acpivout_softc *, int);
int acpivout_find_brightness(struct acpivout_softc *, int);
@@ -130,21 +127,18 @@ acpivout_notify(struct aml_node *node, int notify, void *arg)
{
struct acpivout_softc *sc = arg;
- if (ws_get_param == NULL || ws_set_param == NULL)
- return (0);
-
switch (notify) {
case NOTIFY_BRIGHTNESS_CYCLE:
- acpivout_brightness_cycle(sc);
+ wsdisplay_brightness_cycle(NULL);
break;
case NOTIFY_BRIGHTNESS_UP:
- acpivout_brightness_step(sc, 1);
+ wsdisplay_brightness_step(NULL, 1);
break;
case NOTIFY_BRIGHTNESS_DOWN:
- acpivout_brightness_step(sc, -1);
+ wsdisplay_brightness_step(NULL, -1);
break;
case NOTIFY_BRIGHTNESS_ZERO:
- acpivout_brightness_zero(sc);
+ wsdisplay_brightness_zero(NULL);
break;
case NOTIFY_DISPLAY_OFF:
/* TODO: D3 state change */
@@ -157,64 +151,6 @@ acpivout_notify(struct aml_node *node, int notify, void *arg)
return (0);
}
-void
-acpivout_brightness_cycle(struct acpivout_softc *sc)
-{
- struct wsdisplay_param dp;
-
- dp.param = WSDISPLAYIO_PARAM_BRIGHTNESS;
- if (ws_get_param(&dp))
- return;
-
- if (dp.curval == dp.max)
- acpivout_brightness_zero(sc);
- else
- acpivout_brightness_step(sc, 1);
-}
-
-void
-acpivout_brightness_step(struct acpivout_softc *sc, int dir)
-{
- struct wsdisplay_param dp;
- int delta, new;
-
- dp.param = WSDISPLAYIO_PARAM_BRIGHTNESS;
- if (ws_get_param(&dp))
- return;
-
- new = dp.curval;
- delta = ((dp.max - dp.min) * BRIGHTNESS_STEP) / 100;
- if (dir > 0) {
- if (delta > dp.max - dp.curval)
- new = dp.max;
- else
- new += delta;
- } else if (dir < 0) {
- if (delta > dp.curval - dp.min)
- new = dp.min;
- else
- new -= delta;
- }
-
- if (dp.curval == new)
- return;
-
- dp.curval = new;
- ws_set_param(&dp);
-}
-
-void
-acpivout_brightness_zero(struct acpivout_softc *sc)
-{
- struct wsdisplay_param dp;
-
- dp.param = WSDISPLAYIO_PARAM_BRIGHTNESS;
- if (ws_get_param(&dp))
- return;
-
- dp.curval = dp.min;
- ws_set_param(&dp);
-}
int
acpivout_get_brightness(struct acpivout_softc *sc)
diff --git a/sys/dev/wscons/wsdisplay.c b/sys/dev/wscons/wsdisplay.c
index 7bf8c016238..e0f16514133 100644
--- a/sys/dev/wscons/wsdisplay.c
+++ b/sys/dev/wscons/wsdisplay.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: wsdisplay.c,v 1.136 2020/03/22 07:59:59 anton Exp $ */
+/* $OpenBSD: wsdisplay.c,v 1.137 2020/04/19 15:05:14 kettenis Exp $ */
/* $NetBSD: wsdisplay.c,v 1.82 2005/02/27 00:27:52 perry Exp $ */
/*
@@ -2368,6 +2368,118 @@ wsdisplay_burner(void *v)
}
#endif
+int
+wsdisplay_get_param(struct wsdisplay_softc *sc, struct wsdisplay_param *dp)
+{
+ int error = ENXIO;
+ int i;
+
+ if (sc != NULL)
+ return wsdisplay_param(&sc->sc_dv, WSDISPLAYIO_GETPARAM, dp);
+
+ for (i = 0; i < wsdisplay_cd.cd_ndevs; i++) {
+ sc = wsdisplay_cd.cd_devs[i];
+ if (sc == NULL)
+ continue;
+ error = wsdisplay_param(&sc->sc_dv, WSDISPLAYIO_GETPARAM, dp);
+ if (error == 0)
+ break;
+ }
+
+ if (error && ws_get_param)
+ error = ws_get_param(dp);
+
+ return error;
+}
+
+int
+wsdisplay_set_param(struct wsdisplay_softc *sc, struct wsdisplay_param *dp)
+{
+ int error = ENXIO;
+ int i;
+
+ if (sc != NULL)
+ return wsdisplay_param(&sc->sc_dv, WSDISPLAYIO_SETPARAM, dp);
+
+ for (i = 0; i < wsdisplay_cd.cd_ndevs; i++) {
+ sc = wsdisplay_cd.cd_devs[i];
+ if (sc == NULL)
+ continue;
+ error = wsdisplay_param(&sc->sc_dv, WSDISPLAYIO_SETPARAM, dp);
+ if (error == 0)
+ break;
+ }
+
+ if (error && ws_set_param)
+ error = ws_set_param(dp);
+
+ return error;
+}
+
+void
+wsdisplay_brightness_step(struct device *dev, int dir)
+{
+ struct wsdisplay_softc *sc = (struct wsdisplay_softc *)dev;
+ struct wsdisplay_param dp;
+ int delta, new;
+
+ dp.param = WSDISPLAYIO_PARAM_BRIGHTNESS;
+ if (wsdisplay_get_param(sc, &dp))
+ return;
+
+ /* Use a step size of approximately 5%. */
+ delta = max(1, ((dp.max - dp.min) * 5) / 100);
+ new = dp.curval;
+
+ if (dir > 0) {
+ if (delta > dp.max - dp.curval)
+ new = dp.max;
+ else
+ new += delta;
+ } else if (dir < 0) {
+ if (delta > dp.curval - dp.min)
+ new = dp.min;
+ else
+ new -= delta;
+ }
+
+ if (dp.curval == new)
+ return;
+
+ dp.curval = new;
+ wsdisplay_set_param(sc, &dp);
+}
+
+void
+wsdisplay_brightness_zero(struct device *dev)
+{
+ struct wsdisplay_softc *sc = (struct wsdisplay_softc *)dev;
+ struct wsdisplay_param dp;
+
+ dp.param = WSDISPLAYIO_PARAM_BRIGHTNESS;
+ if (wsdisplay_get_param(sc, &dp))
+ return;
+
+ dp.curval = dp.min;
+ wsdisplay_set_param(sc, &dp);
+}
+
+void
+wsdisplay_brightness_cycle(struct device *dev)
+{
+ struct wsdisplay_softc *sc = (struct wsdisplay_softc *)dev;
+ struct wsdisplay_param dp;
+
+ dp.param = WSDISPLAYIO_PARAM_BRIGHTNESS;
+ if (wsdisplay_get_param(sc, &dp))
+ return;
+
+ if (dp.curval == dp.max)
+ wsdisplay_brightness_zero(dev);
+ else
+ wsdisplay_brightness_step(dev, 1);
+}
+
#ifdef HAVE_WSMOUSED_SUPPORT
/*
* wsmoused(8) support functions
diff --git a/sys/dev/wscons/wsdisplayvar.h b/sys/dev/wscons/wsdisplayvar.h
index ee36ac26a08..170180a7363 100644
--- a/sys/dev/wscons/wsdisplayvar.h
+++ b/sys/dev/wscons/wsdisplayvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: wsdisplayvar.h,v 1.34 2019/10/13 10:56:31 kettenis Exp $ */
+/* $OpenBSD: wsdisplayvar.h,v 1.35 2020/04/19 15:05:14 kettenis Exp $ */
/* $NetBSD: wsdisplayvar.h,v 1.30 2005/02/04 02:10:49 perry Exp $ */
/*
@@ -244,6 +244,10 @@ struct wsdisplay_param;
extern int (*ws_get_param)(struct wsdisplay_param *);
extern int (*ws_set_param)(struct wsdisplay_param *);
+void wsdisplay_brightness_step(struct device *, int);
+void wsdisplay_brightness_zero(struct device *);
+void wsdisplay_brightness_cycle(struct device *);
+
/*
* for use by wskbd
*/
diff --git a/sys/dev/wscons/wskbd.c b/sys/dev/wscons/wskbd.c
index e18173ab5c7..36680fab624 100644
--- a/sys/dev/wscons/wskbd.c
+++ b/sys/dev/wscons/wskbd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: wskbd.c,v 1.103 2020/03/24 08:11:59 anton Exp $ */
+/* $OpenBSD: wskbd.c,v 1.104 2020/04/19 15:05:15 kettenis Exp $ */
/* $NetBSD: wskbd.c,v 1.80 2005/05/04 01:52:16 augustss Exp $ */
/*
@@ -1559,11 +1559,13 @@ internal_command(struct wskbd_softc *sc, u_int *type, keysym_t ksym,
ksym == KS_Cmd_BacklightToggle ? 1 : 0);
return (1);
case KS_Cmd_BrightnessUp:
+ wsdisplay_brightness_step(sc->sc_displaydv, 1);
+ return (1);
case KS_Cmd_BrightnessDown:
+ wsdisplay_brightness_step(sc->sc_displaydv, -1);
+ return (1);
case KS_Cmd_BrightnessRotate:
- change_displayparam(sc, WSDISPLAYIO_PARAM_BRIGHTNESS,
- ksym == KS_Cmd_BrightnessDown ? -1 : 1,
- ksym == KS_Cmd_BrightnessRotate ? 1 : 0);
+ wsdisplay_brightness_cycle(sc->sc_displaydv);
return (1);
case KS_Cmd_ContrastUp:
case KS_Cmd_ContrastDown: