acpivout(4): backlights without method to query current level

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

acpivout(4): backlights without method to query current level

Patrick Wildt-3
Hi,

some machines have no _BQC method, which is used to query the
current display backlight level.  We can still work on those by
starting with the highest level (when there's no _BQC method)
and keeping track of the current level.

Patrick

diff --git a/sys/dev/acpi/acpivideo.c b/sys/dev/acpi/acpivideo.c
index 9498465a418..a46a99a67f7 100644
--- a/sys/dev/acpi/acpivideo.c
+++ b/sys/dev/acpi/acpivideo.c
@@ -149,7 +149,7 @@ acpi_foundvout(struct aml_node *node, void *arg)
  if (node->parent != sc->sc_devnode)
  return (0);
 
- if (aml_searchname(node, "_BCM") && aml_searchname(node, "_BQC")) {
+ if (aml_searchname(node, "_BCM")) {
  memset(&aaa, 0, sizeof(aaa));
  aaa.aaa_iot = sc->sc_acpi->sc_iot;
  aaa.aaa_memt = sc->sc_acpi->sc_memt;
diff --git a/sys/dev/acpi/acpivout.c b/sys/dev/acpi/acpivout.c
index 5fb6973f595..b63ab5a08f3 100644
--- a/sys/dev/acpi/acpivout.c
+++ b/sys/dev/acpi/acpivout.c
@@ -60,6 +60,7 @@ struct acpivout_softc {
 
  int *sc_bcl;
  size_t sc_bcl_len;
+ int sc_bcl_cur;
 };
 
 void acpivout_brightness_cycle(struct acpivout_softc *);
@@ -113,10 +114,16 @@ acpivout_attach(struct device *parent, struct device *self, void *aux)
  aml_register_notify(sc->sc_devnode, aaa->aaa_dev,
     acpivout_notify, sc, ACPIDEV_NOPOLL);
 
+ acpivout_get_bcl(sc);
+ if (!sc->sc_bcl_len)
+ return;
+
+ sc->sc_bcl_cur = sc->sc_bcl[sc->sc_bcl_len - 1];
+ sc->sc_bcl_cur = acpivout_get_brightness(sc);
+ acpivout_set_brightness(sc, sc->sc_bcl_cur);
+
  ws_get_param = acpivout_get_param;
  ws_set_param = acpivout_set_param;
-
- acpivout_get_bcl(sc);
 }
 
 int
@@ -200,7 +207,9 @@ acpivout_get_brightness(struct acpivout_softc *sc)
  struct aml_value res;
  int level;
 
- aml_evalname(sc->sc_acpi, sc->sc_devnode, "_BQC", 0, NULL, &res);
+ if (aml_evalname(sc->sc_acpi, sc->sc_devnode, "_BQC", 0, NULL, &res))
+ return sc->sc_bcl_cur;
+
  level = aml_val2int(&res);
  aml_freevalue(&res);
  DPRINTF(("%s: BQC = %d\n", DEVNAME(sc), level));
@@ -242,6 +251,7 @@ acpivout_set_brightness(struct acpivout_softc *sc, int level)
  aml_evalname(sc->sc_acpi, sc->sc_devnode, "_BCM", 1, &args, &res);
 
  aml_freevalue(&res);
+ sc->sc_bcl_cur = level;
 }
 
 void

Reply | Threaded
Open this post in threaded view
|

Re: acpivout(4): backlights without method to query current level

Mark Kettenis
> Date: Thu, 31 Oct 2019 11:31:50 +0100
> From: Patrick Wildt <[hidden email]>
>
> Hi,
>
> some machines have no _BQC method, which is used to query the
> current display backlight level.  We can still work on those by
> starting with the highest level (when there's no _BQC method)
> and keeping track of the current level.

That makes (some) sense.  I had never noticed this, but the ACPI
standard does document _BQC as "optional".

That said, picking 100% is probably not what we want here.  The _BCM
method returns a list whose first two elements are the default
brightness with AC connected and the brightness when on battery.  We
should use those instead.

Now checking whether AC has been plugged in probably can't be done
within the attach function.  But maybe that can be done in a mountroot
hook.

> diff --git a/sys/dev/acpi/acpivideo.c b/sys/dev/acpi/acpivideo.c
> index 9498465a418..a46a99a67f7 100644
> --- a/sys/dev/acpi/acpivideo.c
> +++ b/sys/dev/acpi/acpivideo.c
> @@ -149,7 +149,7 @@ acpi_foundvout(struct aml_node *node, void *arg)
>   if (node->parent != sc->sc_devnode)
>   return (0);
>  
> - if (aml_searchname(node, "_BCM") && aml_searchname(node, "_BQC")) {
> + if (aml_searchname(node, "_BCM")) {
>   memset(&aaa, 0, sizeof(aaa));
>   aaa.aaa_iot = sc->sc_acpi->sc_iot;
>   aaa.aaa_memt = sc->sc_acpi->sc_memt;
> diff --git a/sys/dev/acpi/acpivout.c b/sys/dev/acpi/acpivout.c
> index 5fb6973f595..b63ab5a08f3 100644
> --- a/sys/dev/acpi/acpivout.c
> +++ b/sys/dev/acpi/acpivout.c
> @@ -60,6 +60,7 @@ struct acpivout_softc {
>  
>   int *sc_bcl;
>   size_t sc_bcl_len;
> + int sc_bcl_cur;
>  };
>  
>  void acpivout_brightness_cycle(struct acpivout_softc *);
> @@ -113,10 +114,16 @@ acpivout_attach(struct device *parent, struct device *self, void *aux)
>   aml_register_notify(sc->sc_devnode, aaa->aaa_dev,
>      acpivout_notify, sc, ACPIDEV_NOPOLL);
>  
> + acpivout_get_bcl(sc);
> + if (!sc->sc_bcl_len)
> + return;
> +
> + sc->sc_bcl_cur = sc->sc_bcl[sc->sc_bcl_len - 1];
> + sc->sc_bcl_cur = acpivout_get_brightness(sc);
> + acpivout_set_brightness(sc, sc->sc_bcl_cur);
> +
>   ws_get_param = acpivout_get_param;
>   ws_set_param = acpivout_set_param;
> -
> - acpivout_get_bcl(sc);
>  }
>  
>  int
> @@ -200,7 +207,9 @@ acpivout_get_brightness(struct acpivout_softc *sc)
>   struct aml_value res;
>   int level;
>  
> - aml_evalname(sc->sc_acpi, sc->sc_devnode, "_BQC", 0, NULL, &res);
> + if (aml_evalname(sc->sc_acpi, sc->sc_devnode, "_BQC", 0, NULL, &res))
> + return sc->sc_bcl_cur;
> +
>   level = aml_val2int(&res);
>   aml_freevalue(&res);
>   DPRINTF(("%s: BQC = %d\n", DEVNAME(sc), level));
> @@ -242,6 +251,7 @@ acpivout_set_brightness(struct acpivout_softc *sc, int level)
>   aml_evalname(sc->sc_acpi, sc->sc_devnode, "_BCM", 1, &args, &res);
>  
>   aml_freevalue(&res);
> + sc->sc_bcl_cur = level;
>  }
>  
>  void
>
>