Contribute
Register

Keyboard backlight control flashes

Status
Not open for further replies.
Joined
Dec 11, 2015
Messages
17
Motherboard
Dell Latitude 3330-Clover
CPU
i5-3337U/HM77
Graphics
HD4000 1366x768
Mac
  1. MacBook Pro
I have updated my Latitude 3330 to High Sierra and almost everything is working correctly. It has working backlight control (using AppleBacklightInjector.kext).

The problem is with the backlight control keys. Though they are working, the BIOS also responds to them. Upon a key press the BIOS set the backlight level and a split second later macOS sets the backlight to another (the correct) level, causing backlight "flashes".

The problem seems to be exactly like described under "Disabling Automatic Brightness Changes by the BIOS" in:
https://docs.microsoft.com/en-us/wi...ghtness-controls-on-integrated-display-panels

So my first try is to call ^^VID._DOS(0x0004) in _SB.PCI0.IGPU._DSM however, that does not work. So how to proceed?

Below is the patch that makes my backlight keys work. This seems to extract information from the Windows Management Instrumentation interface?
Is there an equivalent of _DOS with bit 2 in the WMI interface? Or is there an other method to make the BIOS stop listening to the key events?

Code:
    Method (NEVT, 0, NotSerialized)
    {
        Store (ECG1 (), Local0)
        Store (ECGD (), Local1)

        ...

        If (And (Local0, 0x0800))
        {
            // WAS:
            // EV4 (0x0800, Zero)
          
            //
            // get WMI command buffer from EC
            Acquire(\_SB.AMW0.WMIX, 0xFFFF)
            Store(Buffer(6) { 0, 0, 0, 0, 0, 0}, Local2)
            Store(ECRB(0x2b), Local1)
            Store(0, Local0)
            while (LLess(Local0, Local1))
            {
                if (LGreaterEqual(Local0, SizeOf(Local2)))
                {
                    // error: buffer overflow, make buffer not match
                    Store(0, Index(Local2, 0))
                    break
                }
                Store(ECRB(0x2c), Index(Local2, Local0))
                Increment(Local0)
            }
            Release(\_SB.AMW0.WMIX)
      
            // compare
            if (LEqual(Local2, Buffer() { 0x02, 0x00, 0x10, 0x00, 0x3E, 0x00 }))
            {
                // brightness down

                Notify(\_SB.PCI0.LPCB.PS2K, 0x0365) //F14
                // Notify(\_SB.PCI0.LPCB.PS2K, 0x0205)
                // Notify(\_SB.PCI0.LPCB.PS2K, 0x0285)
            }
            if (LEqual(Local2, Buffer() { 0x02, 0x00, 0x10, 0x00, 0x3F, 0x00 }))
            {
                // brightness up

                Notify(\_SB.PCI0.LPCB.PS2K, 0x0366) //F15
                // Notify(\_SB.PCI0.LPCB.PS2K, 0x0206)
                // Notify(\_SB.PCI0.LPCB.PS2K, 0x0286)
            }
        }

        ...
    }
 

Attachments

  • hackbook-jan.zip
    2.5 MB · Views: 115
I have updated my Latitude 3330 to High Sierra and almost everything is working correctly. It has working backlight control (using AppleBacklightInjector.kext).

The problem is with the backlight control keys. Though they are working, the BIOS also responds to them. Upon a key press the BIOS set the backlight level and a split second later macOS sets the backlight to another (the correct) level, causing backlight "flashes".

The problem seems to be exactly like described under "Disabling Automatic Brightness Changes by the BIOS" in:
https://docs.microsoft.com/en-us/wi...ghtness-controls-on-integrated-display-panels

So my first try is to call ^^VID._DOS(0x0004) in _SB.PCI0.IGPU._DSM however, that does not work. So how to proceed?

Below is the patch that makes my backlight keys work. This seems to extract information from the Windows Management Instrumentation interface?
Is there an equivalent of _DOS with bit 2 in the WMI interface? Or is there an other method to make the BIOS stop listening to the key events?

Code:
    Method (NEVT, 0, NotSerialized)
    {
        Store (ECG1 (), Local0)
        Store (ECGD (), Local1)

        ...

        If (And (Local0, 0x0800))
        {
            // WAS:
            // EV4 (0x0800, Zero)
         
            //
            // get WMI command buffer from EC
            Acquire(\_SB.AMW0.WMIX, 0xFFFF)
            Store(Buffer(6) { 0, 0, 0, 0, 0, 0}, Local2)
            Store(ECRB(0x2b), Local1)
            Store(0, Local0)
            while (LLess(Local0, Local1))
            {
                if (LGreaterEqual(Local0, SizeOf(Local2)))
                {
                    // error: buffer overflow, make buffer not match
                    Store(0, Index(Local2, 0))
                    break
                }
                Store(ECRB(0x2c), Index(Local2, Local0))
                Increment(Local0)
            }
            Release(\_SB.AMW0.WMIX)
     
            // compare
            if (LEqual(Local2, Buffer() { 0x02, 0x00, 0x10, 0x00, 0x3E, 0x00 }))
            {
                // brightness down

                Notify(\_SB.PCI0.LPCB.PS2K, 0x0365) //F14
                // Notify(\_SB.PCI0.LPCB.PS2K, 0x0205)
                // Notify(\_SB.PCI0.LPCB.PS2K, 0x0285)
            }
            if (LEqual(Local2, Buffer() { 0x02, 0x00, 0x10, 0x00, 0x3F, 0x00 }))
            {
                // brightness up

                Notify(\_SB.PCI0.LPCB.PS2K, 0x0366) //F15
                // Notify(\_SB.PCI0.LPCB.PS2K, 0x0206)
                // Notify(\_SB.PCI0.LPCB.PS2K, 0x0286)
            }
        }

        ...
    }

You have some _OSI checks in your DSDT that are not accounting for _OSI("Darwin").
For example, look at the OSID method.
You can fix it too (like you did with _INI before), or you can use hotpatch:
OSID->XSID
_OSI->XOSI
SSDT-XOSI.aml

Also, you should really be patching BRT6 for your brightness notifies (and use the "one shot" notify instead of separate ones for make/break).
 
Thank you! Fixing the _OSI checks with SSDT-XOSI.aml fixes the issue. (On a side note:
https://github.com/RehabMan/OS-X-US...901741587292f565d15a71da44b8/SSDT-XOSI.dsl#L4 should read "Windows 2012")

However what do you mean by:
Also, you should really be patching BRT6 for your brightness notifies (and use the "one shot" notify instead of separate ones for make/break).

I have tested with ACPIDebug.kext: the BRT6 method is not invoked.
And what are one shot and make/break notifies?
 
Thank you! Fixing the _OSI checks with SSDT-XOSI.aml fixes the issue.

So it was likely the OSID code lacking "Darwin" handling.
But XOSI is a better/more complete way.


Thanks. Will fix. Obviously I changed the code at some point and didn't update the comment.

However what do you mean by:

I have tested with ACPIDebug.kext: the BRT6 method is not invoked.
And what are one shot and make/break notifies?

BRT6 will likely be invoked with the correct Windows _OSI spoof.
(eg. maybe it needs Win10).
 
I have tested with ACPIDebug.kext: the BRT6 method is not invoked.
Due to my previous fix the EV4 invocation was still out-commented, so the BRT6 method was not invoked (doh!). It is working now with:

Code:
            Method (BRT6, 2, NotSerialized)
            {
                If (LEqual (Arg0, One))
                {
                    Notify (LCD, 0x86)
                    // Brightness up (F15)
                    Notify (\_SB.PCI0.LPCB.PS2K, 0x0366)
                }

                If (And (Arg0, 0x02))
                {
                    Notify (LCD, 0x87)
                    // Brightness down (F14)
                    Notify (\_SB.PCI0.LPCB.PS2K, 0x0365)
                }
            }

Thanks!

And what are one shot and make/break notifies?
??
 
Last edited:
Status
Not open for further replies.
Back
Top