JafarAkhondali / acer-predator-turbo-and-rgb-keyboard-linux-module

Linux kernel module to support Turbo mode and RGB Keyboard for Acer Predator notebook series
GNU General Public License v3.0
342 stars 59 forks source link

Call GetGamingSysInfo WMI method to enable Nitro5 keyboard LEDs #69

Closed hornc closed 1 year ago

hornc commented 1 year ago

closes #21

This now works for me on Ubuntu 22.04.1 on my Acer Nitro AN515-57 laptop, using the install.sh script (I haven't tested the install_service.sh method yet but it should work the same).

I am hoping that this might fix other Nitro models and maybe even some Predator ones -- and any model that 'works' after starting Windows first.

I'm happy to make changes to this PR to put the query in a better place. I couldn't decide if it fit into 'quirks' or not. The WMI call is a GET method, and I'm not even using the returned result for anything.

Initially I added this as a debugging line to see if the Acer Gaming Profile Setting or Acer Gaming System Information was different between booting into Windows first, and booting straight into Ubuntu, but getting the Gaming System Info was sufficient to make it work.

I had used the Windows WMI event logging and saw the initial sufficient WMI calls were:

GetGamingSysInfo SetGamingLED

and maybe one other call (my notes are on the Windows system). I wasn't expecting the Get method to be the one that changed something in the device though. Using a Get to modify something is strange, but that looks like what's happening.

I'd be very interested to know if this gets any other models working, if there is anyone else out there who wants to test this.

@JafarAkhondali you might have a better idea of where to put this call. I'm happy to make changes and follow any advice you have. Thanks for creating this module!

@Aeres-u99 -- thanks for your comments on #21 , I'm not sure if you have a Nitro 5 now to test this on, but this works for me.

EDIT: Here are some test cases I ran using this branch running as a service: # CASE Off state Init GRUB Bootmenu Login welcome Login mid Login wait Logged in
A.1 static: Windows (R-G-B-Y) -> Windows Off Red sweep: 1-2-3-4 Red Red R-G-B-Y R-G-B-Y R-G-B-Y
My Acer Nitro branch:
B.1 static: Windows (R-G-B-Y) -> Linux Off Red sweep: 1-2-3-4 Red R-G-B-Y R-G-B-Y R-G-B-Y R-G-B-Y
B.2 dynamic: W (Green Shift LTR) -> L Off Red sweep: 1-2-3-4 Red Green Shift Green Shift Green Shift Green Shift
B.3 static: L (Y-B-G-R) -> W Off Red sweep: 1-2-3-4 Red Red Y-B-G-R (from keyb last saved state, under Linux) R-G-B-R (loaded from Windows registry config) R-G-B-R
B.4 dynamic: L (Blue shift RTL) -> W Off Red sweep: 1-2-3-4 Red Red Blue shift RTL from keyb last saved state, under Linux) Green shift LTR (loaded from last saved Windows registry config) Green shift LTR

For me, with this branch, facer.py works to change the LEDs everytime I boot into Linux now. I have it installed as a service.

Points to note:

I'm happy to keep working on this if anyone wants me to dig further into uncovering whether the Windows Nitro app is performing any one time device intitialization, which might be a factor. I'll probably need some info about your device state though. The red-sweep on initial boot and constant red illumination looks like confirmation that the keyboard device is 'initialised' and my branch will work with it. I can't remember ever not seeing this on my laptop though.

I accept that calling a GET method to make this work seems strange, but that's what I'm seeing. I used DotPeek to view the Nitrosense app, and couldn't see any other obvious calls early in the process, which threw me off for a while. I was using the WMI event monitor, but trying to link it back to what I could see within the DotPeek decompilation.

I feel like I've fixed my keyboard problems, but I think it'd be nice to have this work without requiring a Windows boot to initialize the keyboard (at this stage I don't even know this is required -- I'm just suspecting it might be the case if it's not working for other AN515-57s).

It looks like this has helped getting a PH315-55 working, which is great! https://github.com/JafarAkhondali/acer-predator-turbo-and-rgb-keyboard-linux-module/issues/53#issuecomment-1304608901 --

@JafarAkhondali I'm happy to help make more sense of all the different Nitro and Predator model complexity, since I've already invested some time here :)

hornc commented 1 year ago

It's possible the LED groups need to be explicitly turned on with something like:

WMI_gaming_execute_u64(ACER_WMID_SET_GAMING_LED_METHODID, 8L | (15UL<<40), NULL);

I've managed to switch off my zone 3 using this command in a testing branch I made (deliberately, because I was trying to prove I was using WMI from Linux), and now there is no way to switch it back on using the python tool or by writing to the character device (AFAICT).

The Windows Predator / Nitro exes set these using

  int result = (int) WMIFunction.WMISetGamingLEDBehavior((ulong) (8L | (this.Zone_Status[0] ? 1099511627776L : 0L) | (this.Zone_Status[1] ? 2199023255552L : 0L) | (this.Zone_Status[2] ? 4398046511104L : 0L) | (this.Zone_Status[3] ? 8796093022208L : 0L))).GetAwaiter().GetResult(); 

The true test would be for someone who has never booted into Windows to get the LEDs working.

Aeres-u99 commented 1 year ago

@hornc I am unable to replicate the same, steps I did were as follows:

  1. sudo ./install.sh
  2. sudo ./facer_rgb.py -m 2 -s 3 -b 100 -> no result
  3. sudo ./facer_rgb.py -m 1 -s 4 -b 100 -cR 255 -cG 0 -cB 255 -> no results

Could you tell me the steps to replicate, and also try to see if it persists/resets after reboot. That is

  1. replicate, turn off one of the zones
  2. reboot
  3. boot again into linux
  4. replicate.

As I had mentioned, its kinda weird that somehow along the line windows is setting up few registers that kinda change thiings and make it usable on windows.

How were you able to setup the WMI event logging, can you try monitoring the windows registry changes along with windows events, could be a bit overwhelming but its quite possible that windows is making some changes in other places too that might not be wmi.

Maybe the GET method is technically a verification (get and verify) and put is being made somewhere else. Last time I booted into my windows partition it broke my boot record, its a trivial issue and can be resolved, but since I have been working on few other things, I will be truly grateful if you could perform the debugging steps

hornc commented 1 year ago

@Aeres-u99 Thanks for testing!

I tried another test: powered off booted to Windows, turned off zones 2 and 4 powered off booted to Linux, ran my original branch code => result zones 1 and 3 were controllable using facer_rgb.py , but 2 and 3 weren't

So I think the zones need to be turned on . I've pushed that change to this branch for you to try again.

With that change, repeating the above gives me all 4 zones.

I'm testing with static zones,

./facer_rgb.py -m 0 -b 100 -z1 -cR 255 -cB 0 -cG 0
./facer_rgb.py -m 0 -b 100 -z2 -cR 0 -cB 255 -cG 0
./facer_rgb.py -m 0 -b 100 -z3 -cR 0 -cB 0 -cG 255

etc to set z1 to red, z2 to blue, and z3 to green, but when I try your dynamic commands they work too, but then I have booted into windows in the past and played with the dynamic settings too, so maybe there was another init change that was written.

It's tricky having to fully power off between tests, and still not being sure there was something I changed in the past that is affecting behaviour.

hornc commented 1 year ago

@Aeres-u99 does commit https://github.com/JafarAkhondali/acer-predator-turbo-and-rgb-keyboard-linux-module/pull/69/commits/6aabf6ba582e55e03aba4c736cab93e2034df469 make a difference? It forces on all of the zones if Windows has switched them off (or they have never been switched on)

If that doesn't work for you then there may be something else to do with dynamic modes that is required, and I'll dig further into the WMI debugging. There are some registry settings too, but I didn't think they were being used for the minimal enabling of LEDs.

I have to break for the day. I'll pick up later. My problem now seems to be that now I have it working, I can't reset to a clean device state.

Here's the instructions to test whether this PR makes a difference on Nitro 5 systems:

git fetch origin pull/69/head && git checkout FETCH_HEAD
sudo ./install.sh

Test:

# Static check:
./facer_rgb.py -m 0 -z 1 -cR 0 -cB 255 -cG 0

# Dynamic example:
./facer_rgb.py -m 1 -s 4 -b 100 -cR 255 -cG 0 -cB 255

Reset git to origin/main afterwards:

git checkout main

🤞🏽

JafarAkhondali commented 1 year ago

@hornc Thanks for the PR.
I'm not sure if simply calling a GET method would make any difference. Perhaps the GET request is an initial request to adjust other settings if they are not valid? If @Aeres-u99 owns a model similar to you, he can verify it.
Maybe enabling WMI event logging for longer periods and monitor loading a whole profile from NitroSense could help us understand the functionality better. I do also suggest to use DotPeek for de-compiling NitroSense and understand the program flow.

JafarAkhondali commented 1 year ago

@hornc Can you please create a function that calls the WMI methods, and then call that function after this line? the caller should be inside if (wmi_has_guid(WMID_GUID4)) {

hornc commented 1 year ago

@JafarAkhondali Ok, I'll try to get something in the next day or so.

JafarAkhondali commented 1 year ago

Thanks @hornc