On Thu, Jan 23, 2020 at 11:25:51PM +0100, Mark Kettenis wrote:
> Since acpi_set_brightness() can be called from anywhere, it should really
> use the acpi task queue to do its thing instead of calling AML directly.
I didn't know there's an acpi task queue, so that's awesome! I just saw
that acpithinkpad(4) also uses that. Changing this diff to do it that
way was also quite easy, so this should read much better. Feel free to
give it a go.
ok?
Patrick
diff --git a/sys/dev/acpi/acpivout.c b/sys/dev/acpi/acpivout.c
index 58e8e3d431c..89922f4723b 100644
--- a/sys/dev/acpi/acpivout.c
+++ b/sys/dev/acpi/acpivout.c
@@ -60,14 +60,17 @@ struct acpivout_softc {
int *sc_bcl;
size_t sc_bcl_len;
+
+ 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);
-void acpivout_set_brightness(struct acpivout_softc *, int);
+void acpivout_set_brightness(void *, int);
void acpivout_get_bcl(struct acpivout_softc *);
/* wconsole hook functions */
@@ -117,6 +120,8 @@ acpivout_attach(struct device *parent, struct device *self,
void *aux)
ws_set_param = acpivout_set_param;
acpivout_get_bcl(sc);
+
+ sc->sc_brightness = acpivout_get_brightness(sc);
}
int
@@ -124,6 +129,9 @@ 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);
@@ -151,12 +159,13 @@ acpivout_notify(struct aml_node *node, int notify, void
*arg)
void
acpivout_brightness_cycle(struct acpivout_softc *sc)
{
- int cur_level;
+ struct wsdisplay_param dp;
- if (sc->sc_bcl_len == 0)
+ dp.param = WSDISPLAYIO_PARAM_BRIGHTNESS;
+ if (ws_get_param(&dp))
return;
- cur_level = acpivout_get_brightness(sc);
- if (cur_level == sc->sc_bcl[sc->sc_bcl_len - 1])
+
+ if (dp.curval == dp.max)
acpivout_brightness_zero(sc);
else
acpivout_brightness_step(sc, 1);
@@ -165,33 +174,45 @@ acpivout_brightness_cycle(struct acpivout_softc *sc)
void
acpivout_brightness_step(struct acpivout_softc *sc, int dir)
{
- int level, nindex;
+ struct wsdisplay_param dp;
+ int delta, new;
- if (sc->sc_bcl_len == 0)
- return;
- level = acpivout_get_brightness(sc);
- if (level == -1)
+ dp.param = WSDISPLAYIO_PARAM_BRIGHTNESS;
+ if (ws_get_param(&dp))
return;
- nindex = acpivout_find_brightness(sc, level + (dir * BRIGHTNESS_STEP));
- if (sc->sc_bcl[nindex] == level) {
- if (dir == 1 && (nindex + 1 < sc->sc_bcl_len))
- nindex++;
- else if (dir == -1 && (nindex - 1 >= 0))
- nindex--;
+ 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 (sc->sc_bcl[nindex] == level)
+
+ if (dp.curval == new)
return;
- acpivout_set_brightness(sc, sc->sc_bcl[nindex]);
+ dp.curval = new;
+ ws_set_param(&dp);
}
void
acpivout_brightness_zero(struct acpivout_softc *sc)
{
- if (sc->sc_bcl_len == 0)
+ struct wsdisplay_param dp;
+
+ dp.param = WSDISPLAYIO_PARAM_BRIGHTNESS;
+ if (ws_get_param(&dp))
return;
- acpivout_set_brightness(sc, sc->sc_bcl[0]);
+
+ dp.curval = dp.min;
+ ws_set_param(&dp);
}
int
@@ -211,6 +232,26 @@ acpivout_get_brightness(struct acpivout_softc *sc)
return (level);
}
+int
+acpivout_select_brightness(struct acpivout_softc *sc, int nlevel)
+{
+ int nindex, level;
+
+ level = sc->sc_brightness;
+ if (level == -1)
+ return level;
+
+ nindex = acpivout_find_brightness(sc, nlevel);
+ if (sc->sc_bcl[nindex] == level) {
+ if (nlevel > level && (nindex + 1 < sc->sc_bcl_len))
+ nindex++;
+ else if (nlevel < level && (nindex - 1 >= 0))
+ nindex--;
+ }
+
+ return nindex;
+}
+
int
acpivout_find_brightness(struct acpivout_softc *sc, int level)
{
@@ -230,15 +271,16 @@ acpivout_find_brightness(struct acpivout_softc *sc, int
level)
}
void
-acpivout_set_brightness(struct acpivout_softc *sc, int level)
+acpivout_set_brightness(void *arg0, int arg1)
{
+ struct acpivout_softc *sc = arg0;
struct aml_value args, res;
memset(&args, 0, sizeof(args));
- args.v_integer = level;
+ args.v_integer = sc->sc_brightness;
args.type = AML_OBJTYPE_INTEGER;
- DPRINTF(("%s: BCM = %d\n", DEVNAME(sc), level));
+ DPRINTF(("%s: BCM = %d\n", DEVNAME(sc), sc->sc_brightness));
aml_evalname(sc->sc_acpi, sc->sc_devnode, "_BCM", 1, &args, &res);
aml_freevalue(&res);
@@ -304,12 +346,9 @@ acpivout_get_param(struct wsdisplay_param *dp)
}
if (sc != NULL && sc->sc_bcl_len != 0) {
dp->min = 0;
- dp->max = sc->sc_bcl[sc->sc_bcl_len - 1];
- rw_enter_write(&sc->sc_acpi->sc_lck);
- dp->curval = acpivout_get_brightness(sc);
- rw_exit_write(&sc->sc_acpi->sc_lck);
- if (dp->curval != -1)
- return 0;
+ dp->max = sc->sc_bcl[sc->sc_bcl_len - 1];
+ dp->curval = sc->sc_brightness;
+ return 0;
}
return -1;
default:
@@ -334,11 +373,14 @@ acpivout_set_param(struct wsdisplay_param *dp)
break;
}
if (sc != NULL && sc->sc_bcl_len != 0) {
- rw_enter_write(&sc->sc_acpi->sc_lck);
- nindex = acpivout_find_brightness(sc, dp->curval);
- acpivout_set_brightness(sc, sc->sc_bcl[nindex]);
- rw_exit_write(&sc->sc_acpi->sc_lck);
- return 0;
+ nindex = acpivout_select_brightness(sc, dp->curval);
+ if (nindex != -1) {
+ sc->sc_brightness = sc->sc_bcl[nindex];
+ acpi_addtask(sc->sc_acpi,
+ acpivout_set_brightness, sc, 0);
+ acpi_wakeup(sc->sc_acpi);
+ return 0;
+ }
}
return -1;
default: