Re: acpivout: try to consistently adjust brightness by 5%

2020-01-14 Thread Klemens Nanni
On Mon, Jan 13, 2020 at 12:20:10PM +0100, Patrick Wildt wrote:
> The problem is that the last two values are 67 and 100.  If you go
> 5% down, it's 95.  The nearest will still be 100.  The code then
> realizes that it's the same level as before, and does nlevel--.
> But nlevel-- is 99, and not 67, because nlevel is the value and
> not the index of the bcl array.  So in essence the change needed
> is to decrease the index, not the value, and then look up the value.
Disucssing this over dinner again, patrick and I independently came up
with the very same diff below.

It makes acpivout_find_brightness() return an index instead a level for
the selected brightness.

Just works on my X230;  I can go through every level with the function
keys and verify with xbacklight(1) that I am indeed not skipping any of
the 16 levels in either direction.

OK?


Index: acpivout.c
===
RCS file: /cvs/src/sys/dev/acpi/acpivout.c,v
retrieving revision 1.16
diff -u -p -r1.16 acpivout.c
--- acpivout.c  14 Dec 2019 10:57:48 -  1.16
+++ acpivout.c  14 Jan 2020 18:50:23 -
@@ -165,7 +165,7 @@ acpivout_brightness_cycle(struct acpivou
 void
 acpivout_brightness_step(struct acpivout_softc *sc, int dir)
 {
-   int level, nlevel;
+   int level, nindex;
 
if (sc->sc_bcl_len == 0)
return;
@@ -173,17 +173,17 @@ acpivout_brightness_step(struct acpivout
if (level == -1)
return;
 
-   nlevel = acpivout_find_brightness(sc, level + (dir * BRIGHTNESS_STEP));
-   if (nlevel == level) {
-   if (dir == 1 && (nlevel + 1 < sc->sc_bcl_len))
-   nlevel++;
-   else if (dir == -1 && (nlevel - 1 >= 0))
-   nlevel--;
+   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--;
}
-   if (nlevel == level)
+   if (sc->sc_bcl[nindex] == level)
return;
 
-   acpivout_set_brightness(sc, nlevel);
+   acpivout_set_brightness(sc, sc->sc_bcl[nindex]);
 }
 
 void
@@ -219,14 +219,14 @@ acpivout_find_brightness(struct acpivout
for (i = 0; i < sc->sc_bcl_len - 1; i++) {
mid = sc->sc_bcl[i] + (sc->sc_bcl[i + 1] - sc->sc_bcl[i]) / 2;
if (sc->sc_bcl[i] <= level && level <=  mid)
-   return sc->sc_bcl[i];
+   return i;
if  (mid < level && level <= sc->sc_bcl[i + 1])
-   return sc->sc_bcl[i + 1];
+   return i + 1;
}
if (level < sc->sc_bcl[0])
-   return sc->sc_bcl[0];
+   return 0;
else
-   return sc->sc_bcl[i];
+   return i;
 }
 
 void
@@ -321,7 +321,7 @@ int
 acpivout_set_param(struct wsdisplay_param *dp)
 {
struct acpivout_softc   *sc = NULL;
-   int i, exact;
+   int i, nindex;
 
switch (dp->param) {
case WSDISPLAYIO_PARAM_BRIGHTNESS:
@@ -335,8 +335,8 @@ acpivout_set_param(struct wsdisplay_para
}
if (sc != NULL && sc->sc_bcl_len != 0) {
rw_enter_write(>sc_acpi->sc_lck);
-   exact = acpivout_find_brightness(sc, dp->curval);
-   acpivout_set_brightness(sc, exact);
+   nindex = acpivout_find_brightness(sc, dp->curval);
+   acpivout_set_brightness(sc, sc->sc_bcl[nindex]);
rw_exit_write(>sc_acpi->sc_lck);
return 0;
}



Re: acpivout: try to consistently adjust brightness by 5%

2020-01-14 Thread Klemens Nanni
On Mon, Jan 13, 2020 at 12:20:10PM +0100, Patrick Wildt wrote:
> The problem is that the last two values are 67 and 100.  If you go
> 5% down, it's 95.  The nearest will still be 100.  The code then
> realizes that it's the same level as before, and does nlevel--.
> But nlevel-- is 99, and not 67, because nlevel is the value and
> not the index of the bcl array.  So in essence the change needed
> is to decrease the index, not the value, and then look up the value.
That's what happens, but the problem isn't that my machine is lacking
levels between 67 and 100.

Rather, acpivout_find_brightness() seems to linear scale in levels
(which presumably is the case on newer machines), but my machine's
levels scale exponentially.

Diff below comments on this and hilights the two relevant checks:

Given an initial brightness of 100% (the last level), pressing the
function key to decrease the level eventually calls
acpivout_find_brightness() with `level = 100 + (-1 * 5) = 95', it then
iterates over the levels starting with the smallest.

Reaching the second last level (67 on my machine), the loop's body does

mid = 67 + (100 - 67) / 2 = 83;
if (67 <= 95 && 95 <= 83)
return 67;
if (83 <= 95 and 95 <= 100)
return 100;

So for requesting level below 100 it always returns 100 itself because
the next level has a value of 67 which is way out of the 5% threshold
this algorithm assumes.

I suppose a better heuristic is required to make both linearly and
exponentially scaling machines happy, but this is currently too finicky
for me so I just reverted 1.14 in my tree.

Index: acpivout.c
===
RCS file: /cvs/src/sys/dev/acpi/acpivout.c,v
retrieving revision 1.16
diff -u -p -r1.16 acpivout.c
--- acpivout.c  14 Dec 2019 10:57:48 -  1.16
+++ acpivout.c  14 Jan 2020 14:19:08 -
@@ -218,6 +218,11 @@ acpivout_find_brightness(struct acpivout
 
for (i = 0; i < sc->sc_bcl_len - 1; i++) {
mid = sc->sc_bcl[i] + (sc->sc_bcl[i + 1] - sc->sc_bcl[i]) / 2;
+   /*
+* XXX these checks assume levels to be on a linear scale,
+* but some hardware provides exponentially scaled brightness
+* levels (ThinkPad X230, T420).
+*/
if (sc->sc_bcl[i] <= level && level <=  mid)
return sc->sc_bcl[i];
if  (mid < level && level <= sc->sc_bcl[i + 1])



Re: acpivout: try to consistently adjust brightness by 5%

2020-01-13 Thread Patrick Wildt
On Mon, Jan 13, 2020 at 11:58:11AM +0100, Klemens Nanni wrote:
> On Sun, Oct 13, 2019 at 09:28:26PM -0500, joshua stein wrote:
> > When responding to hardware keys to increment or decrement screen 
> > brightness, don't just adjust by 1 BCL level as there may be 100 
> > levels.  Find the next brightness level that is at least 5% up or 
> > down, and use that.
>   revision 1.14
>   date: 2019/10/21 16:32:51;  author: jcs;  state: Exp;  lines: +20 -33;
>   When incrementing or decrementing screen brightness, don't just
>   adjust by 1 BCL level as there may be 100 levels.  Find the next
>   brightness level that is at least 5% up or down and use that.
> 
>   ok kettenis
> 
> This diff broke backlight adjustment on my X230:  With 100% screen
> brightness, pressing the function keys to *de*crease it won't do
> anything.  Booting a kernel with ACPIVIDEO_DEBUG suggests that
> acpivout_find_brightness() is unable to find the next level below 100%
> that is at least 5% less than the full brightness, hence it returns
> something above 95% such that acpivout_brightness_step() gets stuck and
> will set brightness to 100% again.
> 
> `xbacklight -50' will properly decrease brightness to 50%, then the
> function keys also work and I can decrease to 44% as the immediate lower
> level, however increasing it again never works and is stuck at 44%.
> 
> In general, setting a lower brightness level with xbacklight(1) makes
> the function keys work but only ever in the range of [0, n) -- I can
> never reach a higher level than set with xbacklight.
> 
> `xbacklight +100' works and reverting avpivout.c revision 1.14 makes
> everything work again for me.
> 
> tobhe has the exact same issues on his T420.
> 
> Below is diff to show my X230 brightness levels, dmesg as well.

The problem is that the last two values are 67 and 100.  If you go
5% down, it's 95.  The nearest will still be 100.  The code then
realizes that it's the same level as before, and does nlevel--.
But nlevel-- is 99, and not 67, because nlevel is the value and
not the index of the bcl array.  So in essence the change needed
is to decrease the index, not the value, and then look up the value.

Patrick



Re: acpivout: try to consistently adjust brightness by 5%

2020-01-13 Thread Klemens Nanni
On Sun, Oct 13, 2019 at 09:28:26PM -0500, joshua stein wrote:
> When responding to hardware keys to increment or decrement screen 
> brightness, don't just adjust by 1 BCL level as there may be 100 
> levels.  Find the next brightness level that is at least 5% up or 
> down, and use that.
revision 1.14
date: 2019/10/21 16:32:51;  author: jcs;  state: Exp;  lines: +20 -33;
When incrementing or decrementing screen brightness, don't just
adjust by 1 BCL level as there may be 100 levels.  Find the next
brightness level that is at least 5% up or down and use that.

ok kettenis

This diff broke backlight adjustment on my X230:  With 100% screen
brightness, pressing the function keys to *de*crease it won't do
anything.  Booting a kernel with ACPIVIDEO_DEBUG suggests that
acpivout_find_brightness() is unable to find the next level below 100%
that is at least 5% less than the full brightness, hence it returns
something above 95% such that acpivout_brightness_step() gets stuck and
will set brightness to 100% again.

`xbacklight -50' will properly decrease brightness to 50%, then the
function keys also work and I can decrease to 44% as the immediate lower
level, however increasing it again never works and is stuck at 44%.

In general, setting a lower brightness level with xbacklight(1) makes
the function keys work but only ever in the range of [0, n) -- I can
never reach a higher level than set with xbacklight.

`xbacklight +100' works and reverting avpivout.c revision 1.14 makes
everything work again for me.

tobhe has the exact same issues on his T420.

Below is diff to show my X230 brightness levels, dmesg as well.


Index: dev/acpi/acpivout.c
===
RCS file: /cvs/src/sys/dev/acpi/acpivout.c,v
retrieving revision 1.16
diff -u -p -r1.16 acpivout.c
--- dev/acpi/acpivout.c 14 Dec 2019 10:57:48 -  1.16
+++ dev/acpi/acpivout.c 13 Jan 2020 10:47:13 -
@@ -34,6 +34,7 @@ int   acpivout_match(struct device *, void
 void   acpivout_attach(struct device *, struct device *, void *);
 intacpivout_notify(struct aml_node *, int, void *);
 
+#define ACPIVIDEO_DEBUG
 #ifdef ACPIVIDEO_DEBUG
 #define DPRINTF(x) printf x
 #else
@@ -215,6 +216,9 @@ int
 acpivout_find_brightness(struct acpivout_softc *sc, int level)
 {
int i, mid;
+
+   for (i = 0; i < sc->sc_bcl_len; i++)
+   printf("%s: sc->sc_bcl[%d]: %d\n", __func__, i, sc->sc_bcl[i]);
 
for (i = 0; i < sc->sc_bcl_len - 1; i++) {
mid = sc->sc_bcl[i] + (sc->sc_bcl[i + 1] - sc->sc_bcl[i]) / 2;


OpenBSD 6.6-current (GENERIC.MP) #3: Mon Jan 13 11:47:31 CET 2020
k...@eru.my.domain:/sys/arch/amd64/compile/GENERIC.MP
real mem = 17118126080 (16325MB)
avail mem = 16586883072 (15818MB)
mpath0 at root
scsibus0 at mpath0: 256 targets
mainbus0 at root
bios0 at mainbus0: SMBIOS rev. 2.8 @ 0xbff31020 (17 entries)
bios0: vendor coreboot version "CBET4000 x230-seabios" date 01/07/2020
bios0: LENOVO 2325A95
acpi0 at bios0: ACPI 4.0
acpi0: sleep states S0 S3 S4 S5
acpi0: tables DSDT FACP SSDT MCFG TCPA APIC DMAR HPET
acpi0: wakeup devices HDEF(S4) EHC1(S4) EHC2(S4) XHC_(S4) SLPB(S3) LID_(S3)
acpitimer0 at acpi0: 3579545 Hz, 24 bits
acpimcfg0 at acpi0
acpimcfg0: addr 0xf000, bus 0-63
acpimadt0 at acpi0 addr 0xfee0: PC-AT compat
cpu0 at mainbus0: apid 0 (boot processor)
cpu0: Intel(R) Core(TM) i5-3320M CPU @ 2.60GHz, 2594.47 MHz, 06-3a-09
cpu0: 
FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,DS,ACPI,MMX,FXSR,SSE,SSE2,SS,HTT,TM,PBE,SSE3,PCLMUL,DTES64,MWAIT,DS-CPL,VMX,SMX,EST,TM2,SSSE3,CX16,xTPR,PDCM,PCID,SSE4.1,SSE4.2,x2APIC,POPCNT,DEADLINE,AES,XSAVE,AVX,F16C,RDRAND,NXE,RDTSCP,LONG,LAHF,PERF,ITSC,FSGSBASE,SMEP,ERMS,MD_CLEAR,IBRS,IBPB,STIBP,L1DF,SSBD,SENSOR,ARAT,XSAVEOPT,MELTDOWN
cpu0: 256KB 64b/line 8-way L2 cache
cpu0: smt 0, core 0, package 0
mtrr: Pentium Pro MTRR support, 10 var ranges, 88 fixed ranges
cpu0: apic clock running at 99MHz
cpu0: mwait min=64, max=64, C-substates=0.2.1.1.2, IBE
cpu1 at mainbus0: apid 1 (application processor)
cpu1: Intel(R) Core(TM) i5-3320M CPU @ 2.60GHz, 2594.11 MHz, 06-3a-09
cpu1: 
FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,DS,ACPI,MMX,FXSR,SSE,SSE2,SS,HTT,TM,PBE,SSE3,PCLMUL,DTES64,MWAIT,DS-CPL,VMX,SMX,EST,TM2,SSSE3,CX16,xTPR,PDCM,PCID,SSE4.1,SSE4.2,x2APIC,POPCNT,DEADLINE,AES,XSAVE,AVX,F16C,RDRAND,NXE,RDTSCP,LONG,LAHF,PERF,ITSC,FSGSBASE,SMEP,ERMS,MD_CLEAR,IBRS,IBPB,STIBP,L1DF,SSBD,SENSOR,ARAT,XSAVEOPT,MELTDOWN
cpu1: 256KB 64b/line 8-way L2 cache
cpu1: smt 1, core 0, package 0
cpu2 at mainbus0: apid 2 (application processor)
cpu2: Intel(R) Core(TM) i5-3320M CPU @ 2.60GHz, 2594.12 MHz, 06-3a-09
cpu2: 

Re: acpivout: try to consistently adjust brightness by 5%

2019-10-14 Thread Mark Kettenis
> Date: Sun, 13 Oct 2019 21:28:26 -0500
> From: joshua stein 
> 
> When responding to hardware keys to increment or decrement screen 
> brightness, don't just adjust by 1 BCL level as there may be 100 
> levels.  Find the next brightness level that is at least 5% up or 
> down, and use that.

I suspect we want the same behaviour in wskbd(4) as well if the
hardware supports a lot of steps.  But this is a step forward in
itself.

ok kettenis@

> Index: dev/acpi/acpivout.c
> ===
> RCS file: /cvs/src/sys/dev/acpi/acpivout.c,v
> retrieving revision 1.13
> diff -u -p -u -p -r1.13 acpivout.c
> --- dev/acpi/acpivout.c   13 Oct 2019 10:56:31 -  1.13
> +++ dev/acpi/acpivout.c   14 Oct 2019 02:26:12 -
> @@ -47,6 +47,8 @@ int acpivout_notify(struct aml_node *, i
>  #define NOTIFY_BRIGHTNESS_ZERO   0x88
>  #define NOTIFY_DISPLAY_OFF   0x89
>  
> +#define BRIGHTNESS_STEP  5
> +
>  struct acpivout_softc {
>   struct device   sc_dev;
>  
> @@ -61,8 +63,7 @@ struct acpivout_softc {
>  };
>  
>  void acpivout_brightness_cycle(struct acpivout_softc *);
> -void acpivout_brightness_up(struct acpivout_softc *);
> -void acpivout_brightness_down(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_find_brightness(struct acpivout_softc *, int);
> @@ -128,10 +129,10 @@ acpivout_notify(struct aml_node *node, i
>   acpivout_brightness_cycle(sc);
>   break;
>   case NOTIFY_BRIGHTNESS_UP:
> - acpivout_brightness_up(sc);
> + acpivout_brightness_step(sc, 1);
>   break;
>   case NOTIFY_BRIGHTNESS_DOWN:
> - acpivout_brightness_down(sc);
> + acpivout_brightness_step(sc, -1);
>   break;
>   case NOTIFY_BRIGHTNESS_ZERO:
>   acpivout_brightness_zero(sc);
> @@ -158,45 +159,31 @@ acpivout_brightness_cycle(struct acpivou
>   if (cur_level == sc->sc_bcl[sc->sc_bcl_len - 1])
>   acpivout_brightness_zero(sc);
>   else
> - acpivout_brightness_up(sc);
> -}
> -
> -void
> -acpivout_brightness_up(struct acpivout_softc *sc)
> -{
> - int i, cur_level;
> -
> - if (sc->sc_bcl_len == 0)
> - return;
> - cur_level = acpivout_get_brightness(sc);
> - if (cur_level == -1)
> - return;
> -
> - /* check for max brightness level */
> - if (cur_level == sc->sc_bcl[sc->sc_bcl_len - 1])
> - return;
> -
> - for (i = 0; i < sc->sc_bcl_len && cur_level != sc->sc_bcl[i]; i++);
> - acpivout_set_brightness(sc, sc->sc_bcl[i + 1]);
> + acpivout_brightness_step(sc, 1);
>  }
>  
>  void
> -acpivout_brightness_down(struct acpivout_softc *sc)
> +acpivout_brightness_step(struct acpivout_softc *sc, int dir)
>  {
> - int i, cur_level;
> + int level, nlevel;
>  
>   if (sc->sc_bcl_len == 0)
>   return;
> - cur_level = acpivout_get_brightness(sc);
> - if (cur_level == -1)
> + level = acpivout_get_brightness(sc);
> + if (level == -1)
>   return;
>  
> - /* check for min brightness level */
> - if (cur_level == sc->sc_bcl[0])
> + nlevel = acpivout_find_brightness(sc, level + (dir * BRIGHTNESS_STEP));
> + if (nlevel == level) {
> + if (dir == 1 && (nlevel + 1 < sc->sc_bcl_len))
> + nlevel++;
> + else if (dir == -1 && (nlevel - 1 >= 0))
> + nlevel--;
> + }
> + if (nlevel == level)
>   return;
>  
> - for (i = 0; i < sc->sc_bcl_len && cur_level != sc->sc_bcl[i]; i++);
> - acpivout_set_brightness(sc, sc->sc_bcl[i - 1]);
> + acpivout_set_brightness(sc, nlevel);
>  }
>  
>  void
> 
> 



Re: acpivout: try to consistently adjust brightness by 5%

2019-10-14 Thread Tracey Emery
Patch works well on a T470s. Stepping is better in the larger
increments. No ill effects from the patch here.

Thanks,

Tracey

On Sun, Oct 13, 2019 at 09:28:26PM -0500, joshua stein wrote:
> When responding to hardware keys to increment or decrement screen 
> brightness, don't just adjust by 1 BCL level as there may be 100 
> levels.  Find the next brightness level that is at least 5% up or 
> down, and use that.
> 
> 
> Index: dev/acpi/acpivout.c
> ===
> RCS file: /cvs/src/sys/dev/acpi/acpivout.c,v
> retrieving revision 1.13
> diff -u -p -u -p -r1.13 acpivout.c
> --- dev/acpi/acpivout.c   13 Oct 2019 10:56:31 -  1.13
> +++ dev/acpi/acpivout.c   14 Oct 2019 02:26:12 -
> @@ -47,6 +47,8 @@ int acpivout_notify(struct aml_node *, i
>  #define NOTIFY_BRIGHTNESS_ZERO   0x88
>  #define NOTIFY_DISPLAY_OFF   0x89
>  
> +#define BRIGHTNESS_STEP  5
> +
>  struct acpivout_softc {
>   struct device   sc_dev;
>  
> @@ -61,8 +63,7 @@ struct acpivout_softc {
>  };
>  
>  void acpivout_brightness_cycle(struct acpivout_softc *);
> -void acpivout_brightness_up(struct acpivout_softc *);
> -void acpivout_brightness_down(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_find_brightness(struct acpivout_softc *, int);
> @@ -128,10 +129,10 @@ acpivout_notify(struct aml_node *node, i
>   acpivout_brightness_cycle(sc);
>   break;
>   case NOTIFY_BRIGHTNESS_UP:
> - acpivout_brightness_up(sc);
> + acpivout_brightness_step(sc, 1);
>   break;
>   case NOTIFY_BRIGHTNESS_DOWN:
> - acpivout_brightness_down(sc);
> + acpivout_brightness_step(sc, -1);
>   break;
>   case NOTIFY_BRIGHTNESS_ZERO:
>   acpivout_brightness_zero(sc);
> @@ -158,45 +159,31 @@ acpivout_brightness_cycle(struct acpivou
>   if (cur_level == sc->sc_bcl[sc->sc_bcl_len - 1])
>   acpivout_brightness_zero(sc);
>   else
> - acpivout_brightness_up(sc);
> -}
> -
> -void
> -acpivout_brightness_up(struct acpivout_softc *sc)
> -{
> - int i, cur_level;
> -
> - if (sc->sc_bcl_len == 0)
> - return;
> - cur_level = acpivout_get_brightness(sc);
> - if (cur_level == -1)
> - return;
> -
> - /* check for max brightness level */
> - if (cur_level == sc->sc_bcl[sc->sc_bcl_len - 1])
> - return;
> -
> - for (i = 0; i < sc->sc_bcl_len && cur_level != sc->sc_bcl[i]; i++);
> - acpivout_set_brightness(sc, sc->sc_bcl[i + 1]);
> + acpivout_brightness_step(sc, 1);
>  }
>  
>  void
> -acpivout_brightness_down(struct acpivout_softc *sc)
> +acpivout_brightness_step(struct acpivout_softc *sc, int dir)
>  {
> - int i, cur_level;
> + int level, nlevel;
>  
>   if (sc->sc_bcl_len == 0)
>   return;
> - cur_level = acpivout_get_brightness(sc);
> - if (cur_level == -1)
> + level = acpivout_get_brightness(sc);
> + if (level == -1)
>   return;
>  
> - /* check for min brightness level */
> - if (cur_level == sc->sc_bcl[0])
> + nlevel = acpivout_find_brightness(sc, level + (dir * BRIGHTNESS_STEP));
> + if (nlevel == level) {
> + if (dir == 1 && (nlevel + 1 < sc->sc_bcl_len))
> + nlevel++;
> + else if (dir == -1 && (nlevel - 1 >= 0))
> + nlevel--;
> + }
> + if (nlevel == level)
>   return;
>  
> - for (i = 0; i < sc->sc_bcl_len && cur_level != sc->sc_bcl[i]; i++);
> - acpivout_set_brightness(sc, sc->sc_bcl[i - 1]);
> + acpivout_set_brightness(sc, nlevel);
>  }
>  
>  void

-- 

Tracey Emery



acpivout: try to consistently adjust brightness by 5%

2019-10-13 Thread joshua stein
When responding to hardware keys to increment or decrement screen 
brightness, don't just adjust by 1 BCL level as there may be 100 
levels.  Find the next brightness level that is at least 5% up or 
down, and use that.


Index: dev/acpi/acpivout.c
===
RCS file: /cvs/src/sys/dev/acpi/acpivout.c,v
retrieving revision 1.13
diff -u -p -u -p -r1.13 acpivout.c
--- dev/acpi/acpivout.c 13 Oct 2019 10:56:31 -  1.13
+++ dev/acpi/acpivout.c 14 Oct 2019 02:26:12 -
@@ -47,6 +47,8 @@ int   acpivout_notify(struct aml_node *, i
 #define NOTIFY_BRIGHTNESS_ZERO 0x88
 #define NOTIFY_DISPLAY_OFF 0x89
 
+#define BRIGHTNESS_STEP5
+
 struct acpivout_softc {
struct device   sc_dev;
 
@@ -61,8 +63,7 @@ struct acpivout_softc {
 };
 
 void   acpivout_brightness_cycle(struct acpivout_softc *);
-void   acpivout_brightness_up(struct acpivout_softc *);
-void   acpivout_brightness_down(struct acpivout_softc *);
+void   acpivout_brightness_step(struct acpivout_softc *, int);
 void   acpivout_brightness_zero(struct acpivout_softc *);
 intacpivout_get_brightness(struct acpivout_softc *);
 intacpivout_find_brightness(struct acpivout_softc *, int);
@@ -128,10 +129,10 @@ acpivout_notify(struct aml_node *node, i
acpivout_brightness_cycle(sc);
break;
case NOTIFY_BRIGHTNESS_UP:
-   acpivout_brightness_up(sc);
+   acpivout_brightness_step(sc, 1);
break;
case NOTIFY_BRIGHTNESS_DOWN:
-   acpivout_brightness_down(sc);
+   acpivout_brightness_step(sc, -1);
break;
case NOTIFY_BRIGHTNESS_ZERO:
acpivout_brightness_zero(sc);
@@ -158,45 +159,31 @@ acpivout_brightness_cycle(struct acpivou
if (cur_level == sc->sc_bcl[sc->sc_bcl_len - 1])
acpivout_brightness_zero(sc);
else
-   acpivout_brightness_up(sc);
-}
-
-void
-acpivout_brightness_up(struct acpivout_softc *sc)
-{
-   int i, cur_level;
-
-   if (sc->sc_bcl_len == 0)
-   return;
-   cur_level = acpivout_get_brightness(sc);
-   if (cur_level == -1)
-   return;
-
-   /* check for max brightness level */
-   if (cur_level == sc->sc_bcl[sc->sc_bcl_len - 1])
-   return;
-
-   for (i = 0; i < sc->sc_bcl_len && cur_level != sc->sc_bcl[i]; i++);
-   acpivout_set_brightness(sc, sc->sc_bcl[i + 1]);
+   acpivout_brightness_step(sc, 1);
 }
 
 void
-acpivout_brightness_down(struct acpivout_softc *sc)
+acpivout_brightness_step(struct acpivout_softc *sc, int dir)
 {
-   int i, cur_level;
+   int level, nlevel;
 
if (sc->sc_bcl_len == 0)
return;
-   cur_level = acpivout_get_brightness(sc);
-   if (cur_level == -1)
+   level = acpivout_get_brightness(sc);
+   if (level == -1)
return;
 
-   /* check for min brightness level */
-   if (cur_level == sc->sc_bcl[0])
+   nlevel = acpivout_find_brightness(sc, level + (dir * BRIGHTNESS_STEP));
+   if (nlevel == level) {
+   if (dir == 1 && (nlevel + 1 < sc->sc_bcl_len))
+   nlevel++;
+   else if (dir == -1 && (nlevel - 1 >= 0))
+   nlevel--;
+   }
+   if (nlevel == level)
return;
 
-   for (i = 0; i < sc->sc_bcl_len && cur_level != sc->sc_bcl[i]; i++);
-   acpivout_set_brightness(sc, sc->sc_bcl[i - 1]);
+   acpivout_set_brightness(sc, nlevel);
 }
 
 void