Contribute
Register

New Brightness kext, IntelBacklight.kext

Status
Not open for further replies.
Hello! Please have patience and bear with me - I have a specific question:

In search for a method to adust the PWM frequency of laptop displays, I stumbled accross this code and it sounds like it modifies the backlights programme run by Intel Graphics cards, which, I have read, also influence PWM (since the intergrated Intel cards runs when on battery mode). Since I completely lack any related knowledge, I would like to ask you the following:

Can one increase PWM freqeuncy with this code?
Does it work on a new Windows 10 64-bit machine with Intel HD 530 dedicated graphics (and dedicated NVidia), too? If I am completely wrong here, I am sorry - my relevant technical knowledge is not good enough to notice.
The readme didn't help me much, either....

Thank you for reading and thank you even more for any answers!

The PWMMax used by this kext can be changed with an SSDT. Customizing the configuration this way is covered in the README.

This kext is only for OS X.
 
Hello to all, this work with Chamaleon?
I simple install kext and no work, anymore i try apply any DSDT i lost my system.

Thanks!
 
Hello to all, this work with Chamaleon?
I simple install kext and no work, anymore i try apply any DSDT i lost my system.

Thanks!

It works with any bootloader. But you still must patch ACPI correctly.
 
Thanks for this new opportunity, that seems like a neater solution compared to what we have been using for ages!

I have a question in regards to getting to the data from the ACPI config. I used to use the SAVE method with ACPIBacklight to properly store the backlight level for soft/cold boot in EC. It used to rely on getting the index from _BCL for the current level, divided by the number of steps (smooth transitions) per level to determine which value has to be written to EC regs. Now with the BacklightLevels being in a package within a package with a dumpy package in the way, I'm having a hard time coming up with an ACPI code snippet that would allow me to find the index within this array. Any tips, please ?

Code:
            Method (RMCF)
            {
                Return(Package()
                {
                    "PWMMax", 4882, // PWMMax as returned by BIOS PWM Max
                    "PCHLInit", Zero, // some computers will need this zero
                    "LEVWInit", 0x80000000, // you can use 0 to skip writing LEVW
                    "Options", 0, // setting bit0 turns off smooth transitions
                    "BacklightMin", 128,
                    "BacklightMax", 4882,
                    "BacklightLevelsScale", 4882,
                    "BacklightLevels", Package()
                    {
                        Package(){}, // empty package indicates array follows (instead of dictionary)
                        0, // display off
                        618, 685, 753, 820,     //0x00 level group
                        888, 955, 1023, 1090,   //0x01 level group
                        1158, 1225, 1293, 1360, //0x02 level group
                        1428, 1495, 1563, 1630, //0x03 level group
                        1698, 1765, 1833, 1900, //0x04 level group
                        1968, 2035, 2103, 2170, //0x05 level group
                        2238, 2305, 2373, 2441, //0x06 level group
                        2508, 2576, 2643, 2711, //0x07 level group
                        2778, 2846, 2913, 2981, //0x08 level group
                        3048, 3116, 3183, 3251, //0x09 level group
                        3318, 3386, 3453, 3521, //0x0a level group
                        3588, 3656, 3723, 3791, //0x0b level group
                        3858, 3926, 3993, 4061, //0x0c level group
                        4128, 4196, 4263, 4331, //0x0d level group
                        4398, 4466, 4533, 4601, //0x0e level group
                        4668, 4736, 4803, 4882  //0x0f level group
                    },
                })
            }

I do realize I will have to start the matching at 0 index opposed to 2 below, but I've no idea how to get to the levels returned by RMCF?
Code:
            Name (STPS, 0x04)  // Number of steps in between for one level  
            Name (ECAR, Package ()  // EC Backlight Levels
            {
                0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 
                0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F 
            })

            // preserve brightness level for EC
            Method (SAVE, 1, NotSerialized)
            {
                // get level position in _BCL
                Store (Match (_BCL, MGE, Arg0, MTR, Zero, 0x02), Local0)
                If (LEqual (Local0,Ones))
                {
                    Subtract (SizeOf (_BCL), One, Local0)
                }
               
                // determine reg values - ensures cold boot level consistency
                Divide (Local0, STPS,, Local0) // divide index by the number of steps for one level
                Store (DerefOf (Index (ECAR, Local0)), Local1)
               
                // determine power source used, different regs for ac/dc power
                If (PWRS)
                {
                    Store (Local1,BRGA)
                }
                Else 
                {
                    Store (Local1,BRGD)
                }
            }
 
Thanks for this new opportunity, that seems like a neater solution compared to what we have been using for ages!

I have a question in regards to getting to the data from the ACPI config. I used to use the SAVE method with ACPIBacklight to properly store the backlight level for soft/cold boot in EC. It used to rely on getting the index from _BCL for the current level, divided by the number of steps (smooth transitions) per level to determine which value has to be written to EC regs. Now with the BacklightLevels being in a package within a package with a dumpy package in the way, I'm having a hard time coming up with an ACPI code snippet that would allow me to find the index within this array. Any tips, please ?

Code:
            Method (RMCF)
            {
                Return(Package()
                {
                    "PWMMax", 4882, // PWMMax as returned by BIOS PWM Max
                    "PCHLInit", Zero, // some computers will need this zero
                    "LEVWInit", 0x80000000, // you can use 0 to skip writing LEVW
                    "Options", 0, // setting bit0 turns off smooth transitions
                    "BacklightMin", 128,
                    "BacklightMax", 4882,
                    "BacklightLevelsScale", 4882,
                    "BacklightLevels", Package()
                    {
                        Package(){}, // empty package indicates array follows (instead of dictionary)
                        0, // display off
                        618, 685, 753, 820,     //0x00 level group
                        888, 955, 1023, 1090,   //0x01 level group
                        1158, 1225, 1293, 1360, //0x02 level group
                        1428, 1495, 1563, 1630, //0x03 level group
                        1698, 1765, 1833, 1900, //0x04 level group
                        1968, 2035, 2103, 2170, //0x05 level group
                        2238, 2305, 2373, 2441, //0x06 level group
                        2508, 2576, 2643, 2711, //0x07 level group
                        2778, 2846, 2913, 2981, //0x08 level group
                        3048, 3116, 3183, 3251, //0x09 level group
                        3318, 3386, 3453, 3521, //0x0a level group
                        3588, 3656, 3723, 3791, //0x0b level group
                        3858, 3926, 3993, 4061, //0x0c level group
                        4128, 4196, 4263, 4331, //0x0d level group
                        4398, 4466, 4533, 4601, //0x0e level group
                        4668, 4736, 4803, 4882  //0x0f level group
                    },
                })
            }

I do realize I will have to start the matching at 0 index opposed to 2 below, but I've no idea how to get to the levels returned by RMCF?
Code:
            Name (STPS, 0x04)  // Number of steps in between for one level
            Name (ECAR, Package ()  // EC Backlight Levels
            {
                0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
                0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
            })

            // preserve brightness level for EC
            Method (SAVE, 1, NotSerialized)
            {
                // get level position in _BCL
                Store (Match (_BCL, MGE, Arg0, MTR, Zero, 0x02), Local0)
                If (LEqual (Local0,Ones))
                {
                    Subtract (SizeOf (_BCL), One, Local0)
                }
             
                // determine reg values - ensures cold boot level consistency
                Divide (Local0, STPS,, Local0) // divide index by the number of steps for one level
                Store (DerefOf (Index (ECAR, Local0)), Local1)
             
                // determine power source used, different regs for ac/dc power
                If (PWRS)
                {
                    Store (Local1,BRGA)
                }
                Else
                {
                    Store (Local1,BRGD)
                }
            }

IntelBacklight.kext does not use _BCL. You can call RMCF yourself to retrieve all the data, then match against the "BacklightLevels" package.

I would place the "BacklightLevels" at the beginning to make it easier to find.

Code:
            Method (RMCF)
            {
                Return(Package()
                {
                    "BacklightLevels", Package()
                    {
                        Package(){}, // empty package indicates array follows (instead of dictionary)
                        0, // display off
                        618, 685, 753, 820,     //0x00 level group
                        888, 955, 1023, 1090,   //0x01 level group
                        1158, 1225, 1293, 1360, //0x02 level group
                        1428, 1495, 1563, 1630, //0x03 level group
                        1698, 1765, 1833, 1900, //0x04 level group
                        1968, 2035, 2103, 2170, //0x05 level group
                        2238, 2305, 2373, 2441, //0x06 level group
                        2508, 2576, 2643, 2711, //0x07 level group
                        2778, 2846, 2913, 2981, //0x08 level group
                        3048, 3116, 3183, 3251, //0x09 level group
                        3318, 3386, 3453, 3521, //0x0a level group
                        3588, 3656, 3723, 3791, //0x0b level group
                        3858, 3926, 3993, 4061, //0x0c level group
                        4128, 4196, 4263, 4331, //0x0d level group
                        4398, 4466, 4533, 4601, //0x0e level group
                        4668, 4736, 4803, 4882  //0x0f level group
                    },
                    "PWMMax", 4882, // PWMMax as returned by BIOS PWM Max
                    "PCHLInit", Zero, // some computers will need this zero
                    "LEVWInit", 0x80000000, // you can use 0 to skip writing LEVW
                    "Options", 0, // setting bit0 turns off smooth transitions
                    "BacklightMin", 128,
                    "BacklightMax", 4882,
                    "BacklightLevelsScale", 4882,
                })
            }

Then the array of values is at Local0[1]. You have to ignore the first entry as it is an empty package (signals to RMCF related code in IntelBacklight.kext that the data which follows is an array, since without it it is a dictionary with key/value pairs).

So, following your previous example...
Code:
Local0 = RMCF()
Local1 = DerefOf(Local0[1]) // retrieves the "BacklightLevels" package
Local2 = Match(Local1, MGE, Arg0, MTR, 0, 1) // ignore the empty package at the beginning
 
Last edited:
IntelBacklight.kext does not use _BCL. You can call RMCF yourself to retrieve all the data, then match against the "BacklightLevels" package.
Yeah, that I was aware of. Was just giving an example of how it was written prior to switching to the new kext. Was after a way of getting the data from RMCF

Then the array of values is at Local0[1]. You have to ignore the first entry as it is an empty package (signals to RMCF related code in IntelBacklight.kext that the data which follows is an array, since without it it is a dictionary with key/value pairs).
...
So, following your previous example...
That worked wonders, thanks!
Looking at your code snipped I've realized that I've managed to miss ACPI spec 6.0 completely .. need to skim things through to get acquired. Had no idea they finally made local var initialization sensible and you can get to the package indices using square braces.
 
Looking at your code snipped I've realized that I've managed to miss ACPI spec 6.0 completely .. need to skim things through to get acquired. Had no idea they finally made local var initialization sensible and you can get to the package indices using square braces.

Some of that is actually ACPI 6.1.
 
Status
Not open for further replies.
Back
Top