Qonfused / ASUS-ZenBook-Duo-14-UX481-Hackintosh

OpenCore configuration for the ASUS ZenBook Duo 14" (UX481FA/FL)
https://github.com/Qonfused/ASUS-ZenBook-Duo-14-UX481-Hackintosh
BSD 3-Clause "New" or "Revised" License
31 stars 1 forks source link

Screenpad Plus Backlight Control #6

Closed Qonfused closed 1 year ago

Qonfused commented 2 years ago

Backlight is set by ACPI calls exposed through a WMI driver. For reference, there is a linux module that probes ACPI for methods controlling backlight of the screenpad. Below details basic methods for the display's backlight control implemented similarly to keyboard backlight control in AsusSMC:

asus-wmi.h#L50-L74 ```c 50 | struct asus_wmi_driver { 51 | int brightness; 52 | int panel_power; 53 | int wlan_ctrl_by_user; 54 | 55 | const char *name; 56 | struct module *owner; 57 | 58 | const char *event_guid; 59 | 60 | const struct key_entry *keymap; 61 | const char *input_name; 62 | const char *input_phys; 63 | struct quirk_entry *quirks; 64 | /* Returns new code, value, and autorelease values in arguments. 65 | * Return ASUS_WMI_KEY_IGNORE in code if event should be ignored. */ 66 | void (*key_filter) (struct asus_wmi_driver *driver, int *code, 67 | unsigned int *value, bool *autorelease); 68 | 69 | int (*probe) (struct platform_device *device); 70 | void (*detect_quirks) (struct asus_wmi_driver *driver); 71 | 72 | struct platform_driver platform_driver; 73 | struct platform_device *platform_device; 74 | }; ```
asus-wmi.c#L819-L831 ```c 819 | if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_SCREENPAD) 820 | && !screenpad_led_read(asus, &led_val)) { 821 | asus->screenpad_led_wk = led_val; 822 | INIT_WORK(&asus->screenpad_led_work, screenpad_led_update); 823 | 824 | asus->screenpad_led.name = "asus::screenpad"; 825 | asus->screenpad_led.brightness_set = screenpad_led_set; 826 | asus->screenpad_led.brightness_get = screenpad_led_get; 827 | asus->screenpad_led.max_brightness = 0xff; 828 | 829 | rv = led_classdev_register(&asus->platform_device->dev, 830 | &asus->screenpad_led); 831 | } ```

If it can't be controlled in the same submenu as the primary display, then mapping Screenpad backlight brightness in a control center slider like keyboard brightness may be a good alternative UX implementation:

image

Qonfused commented 1 year ago

For reference, @shiecldk has a breakdown of EC events for the UX582 in https://github.com/hieplpvip/AsusSMC/issues/102#issue-962381803.

It's worth mentioning that SSDT-ASUSFN.aml in the original repo only has control logic for the primary display's backlight, and SSDT-AsusSMC.aml has logic for the ambient light sensor and keyboard backlight.

Qonfused commented 1 year ago

Continuing on the screenpad plus backlight discussion in https://github.com/Qonfused/ASUS-ZenBook-Duo-14-UX481-Hackintosh/issues/4#issuecomment-1328165864

In another thread, I also found mention of a WMNB method that controls backlight (refers to \_SB.ATKD.WMNB, which seems to be what wern-apfel was mentioning?): s-light/ASUS-ZenBook-Pro-Duo-UX581GV#1 (comment)

* Control backlight: `echo '\_SB.ATKD.WMNB 0x0 0x53564544 b32000500xx000000' | sudo tee /proc/acpi/call` (xx is a hex value from `00` to `FF`).

* Disable backlight: `echo '\_SB.ATKD.WMNB 0x0 0x53564544 b3100050000000000' | sudo tee /proc/acpi/call`

^^^ They're using the acpi_call linux kernel module to call this method, though assumedly an SSDT could also call the same method with these values to change backlight (and in your case disable backlight).

Below is the WMNB method that executes the above ACPI calls ```dsl // \_SB.ATKD.WMNB 54953 | Method (WMNB, 3, Serialized) 54954 | { 54955 | CreateDWordField (Arg2, Zero, IIA0) 54956 | CreateDWordField (Arg2, 0x04, IIA1) 54957 | Local0 = (Arg1 & 0xFFFFFFFF) ... 55362 | If ((Local0 == 0x53564544)) 55363 | { ... 55524 | Name (TMBF, Buffer (0x02) 55525 | { 55526 | 0x00, 0x00 55527 | }) 55528 | If ((IIA0 == 0x00050031)) 55529 | { 55530 | TMBF [Zero] = Zero 55531 | Local0 = ^^PCI0.LPCB.EC0.REBC (0x12, 0x02) 55532 | Local1 = DerefOf (Local0 [Zero]) 55533 | If ((IIA1 == One)) 55534 | { 55535 | Local1 &= 0xFD 55536 | } 55537 | Else 55538 | { 55539 | Local1 |= 0x02 55540 | } 55541 | 55542 | TMBF [One] = Local1 55543 | Return (^^PCI0.LPCB.EC0.WEBC (0x13, 0x02, TMBF)) 55544 | Return (Zero) 55545 | } 55546 | 55547 | If ((IIA0 == 0x00050032)) 55548 | { 55549 | TMBF [One] = IIA1 /* \_SB_.ATKD.WMNB.IIA1 */ 55550 | TMBF [Zero] = One 55551 | Return (^^PCI0.LPCB.EC0.WEBC (0x13, 0x02, TMBF)) 55552 | Return (Zero) 55553 | } 55554 | 55555 | If ((IIA0 == 0x00050035)) 55556 | { 55557 | TMBF [Zero] = Zero 55558 | Local0 = ^^PCI0.LPCB.EC0.REBC (0x12, 0x02) 55559 | Local1 = DerefOf (Local0 [Zero]) 55560 | If ((IIA1 == Zero)) 55561 | { 55562 | Local1 &= 0xF7 55563 | } 55564 | ElseIf ((IIA1 == One)) 55565 | { 55566 | Local1 |= 0x08 55567 | } 55568 | 55569 | TMBF [One] = Local1 55570 | Return (^^PCI0.LPCB.EC0.WEBC (0x13, 0x02, TMBF)) 55571 | Return (Zero) 55572 | } ```

I have an example SSDT for disabling the screenpad plus display connector that writes to the EC's memory instead (based on @wern-apfel's SSDT-UX481FA.aml):

DISABLE-SCREENPAD.dsl Disable the Screenpad Plus display connector

Rather than reading or writing to the embedded controller's memory directly (REBC/WEBC), the WMNB method (which handles all asus wmi functions) should be called instead:

External (\_SB.ATKD.WMNB, MethodObj)
// Sets the screenpad plus backlight intensity,
// where 'xx' is a hex value between 00 and FF.
\_SB.ATKD.WMNB(0x0, 0x53564544, /*b32000500xx000000*/)
// Disables screenpad plus until next backlight change.
\_SB.ATKD.WMNB(0x0, 0x53564544, /*b3100050000000000*/)

Some behavior can be ported to AsusSMC from the asus-wmi-screenpad repo.

Qonfused commented 1 year ago

Added refactor in https://github.com/Qonfused/ASUS-ZenBook-Duo-14-UX481-Hackintosh/commit/9de3d053fa7704d16a94a4466b66e14553afe70f.

shiecldk commented 1 year ago

Do you solve this with SSDT-SPLC.aml?

Qonfused commented 1 year ago

Yes. Its been fully implemented since the above PR, though an idea for #21 is to use an additional fake PNLF device to store and buffer backlight data to manipulate WMI methods. It should work more natively with those changes.

shiecldk commented 1 month ago

@Qonfused It looks like @wern-apfel updated the UX481FA and UX434 repo for FN keys. Maybe you can check what new key implementations are if there are any new updates.

Qonfused commented 1 month ago

My implementation in #21 is more up-to-date for the keyboard (KBLC) and screenpad (SPLC) backlight controls. I realized Wern's was too fragile when trying to refactor his implementation in #19 and instead based the implementation on the Linux asus-wmi module.

Since ASUS hasn't released any updated firmware for the UX481 so there isn't anything to update.

shiecldk commented 1 month ago

Gotcha. Also AsusSMC.kext hasn't been updated for a while. I was thinking using AI to check what needs to be updated at this date.

Qonfused commented 1 month ago

I was working on refactoring the OSD controls and porting the keyboard + screenpad backlight controls in https://github.com/Qonfused/AsusSMC/pull/2. This is based on the WMI controls in the ASUS driver so its compatible with all types of screenpad devices.

At the time I couldn't figure out how to integrate it w/ EC events (from VirtualSMC); this is how the event gets communicated with AsusSMC's OSD daemon, which is not necessary for ACPI-based events. The idea is to get the same brightness indicator on-screen when updating the screenpad brightness.