On Fri, Jan 24, 2020 at 01:04:41AM +0100, Patrick Wildt wrote:
> 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

Looking for some more testing on this.  Successful test results would
help to get this diff in, so I can start sending the next diffs to
finally enable X395 backlight keys support.

Expected behaviour:  Backlight keys continue to change the backlight
as well as they did before.

Machines:  All those where acpivout(4) attaches.

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:

Reply via email to