X86 platform drivers
 help / color / mirror / Atom feed
From: Armin Wolf <W_Armin@gmx.de>
To: Hridesh MG <hridesh699@gmail.com>
Cc: platform-driver-x86@vger.kernel.org
Subject: Re: acer-wmi: Nitro button doesn't produce a WMI event
Date: Wed, 25 Dec 2024 21:51:58 +0100	[thread overview]
Message-ID: <ecb60ee5-3df7-4d7e-8ebf-8c162b339ade@gmx.de> (raw)
In-Reply-To: <CALiyAomaT5y10Bawth3X44WB9Cie1fhW0GyBZgASo7ySK6g9zQ@mail.gmail.com>

Am 24.12.24 um 19:45 schrieb Hridesh MG:

>> Am 24.12.24 um 00:06 schrieb Armin Wolf:
>> This WMI call is already supported by the driver and exposed to userspace using the platform profile interface.
>> It seems however that your device:
>>
>> - does only support the turbo profile and not the other OC settings
>>
>> - only supports a subset of the platform profile choices
>>
>> - uses a different EC address for storing the current platform profile
>>
>> Can you test kernel patches? I can prepare a patch for you which:
>>
>> - puts your device on the necessary whitelists
>>
>> - fixes the platform profile handling
>>
>> Thanks,
>> Armin Wolf
> Oh I see, thank you for your work! Actually, could I work on the patch
> myself? I'd like to take this as an opportunity to learn something
> new, I'm also a mentee under the LFX kernel bug fixing mentorship
> program and was hoping to create a patch which could count towards my
> graduation requirements out of this issue.
>
> I understood the rest, but if it isn't too much of a bother, could you
> tell me how you found out the EC address? (or the fact that it was
> different)
>
> Thanks,
> Hridesh MG

This is the full definition of the Acer gaming WMI interface on your machine:

[WMI, Dynamic, Provider("WmiProv"), Locale("MS\\0x409"), Description("Class used to Gaming Function, Version 2.88"), guid("{7A4DDFE7-5B5D-40B4-8595-4408E0CC7F56}")]
class AcerGamingFunction {
   [key, read] string InstanceName;
   [read] boolean Active;

   [WmiMethodId(1), Implemented, read, write, Description("Set Acer Gaming Profile Configuration.")] void SetGamingProfile([in] uint64 gmInput, [out] uint32 gmOutput);
   [WmiMethodId(2), Implemented, read, write, Description("Set Acer Gaming LED Behavior.")] void SetGamingLED([in] uint8 gmInput[12], [out] uint32 gmOutput);
   [WmiMethodId(3), Implemented, read, write, Description("Get Acer Gaming Profile Configuration.")] void GetGamingProfile([in] uint32 gmInput, [out] uint64 gmOutput);
   [WmiMethodId(4), Implemented, read, write, Description("Get Acer Gaming LED Behavior.")] void GetGamingLED([in] uint32 gmInput, [out] uint8 gmReturn, [out] uint8 gmOutput[11]);
   [WmiMethodId(5), Implemented, read, write, Description("Get Acer Gaming System Information.")] void GetGamingSysInfo([in] uint32 gmInput, [out] uint64 gmOutput);
   [WmiMethodId(6), Implemented, read, write, Description("Set Acer Gaming RGB Keyboard Setting.")] void SetGamingRgbKb([in] uint64 gmInput, [out] uint32 gmOutput);
   [WmiMethodId(7), Implemented, read, write, Description("Get Acer Gaming RGB Keyboard Setting.")] void GetGamingRgbKb([in] uint32 gmInput, [out] uint64 gmOutput);
   [WmiMethodId(8), Implemented, read, write, Description("Set Acer Gaming Profile Setting.")] void SetGamingProfileSetting([in] uint64 gmInput, [out] uint32 gmOutput);
   [WmiMethodId(9), Implemented, read, write, Description("Get Acer Gaming Profile Setting.")] void GetGamingProfileSetting([in] uint32 gmInput, [out] uint64 gmOutput);
   [WmiMethodId(10), Implemented, read, write, Description("Set Acer Gaming LED Group Behavior.")] void SetGamingLEDBehavior([in] uint64 gmInput, [out] uint32 gmOutput);
   [WmiMethodId(11), Implemented, read, write, Description("Get Acer Gaming LED Group Behavior.")] void GetGamingLEDBehavior([in] uint32 gmInput, [out] uint64 gmOutput);
   [WmiMethodId(12), Implemented, read, write, Description("Set Acer Gaming LED Group Color.")] void SetGamingLEDColor([in] uint64 gmInput, [out] uint32 gmOutput);
   [WmiMethodId(13), Implemented, read, write, Description("Get Acer Gaming LED Group Color.")] void GetGamingLEDColor([in] uint32 gmInput, [out] uint64 gmOutput);
   [WmiMethodId(14), Implemented, read, write, Description("Set Acer Gaming Fan Group Behavior.")] void SetGamingFanBehavior([in] uint64 gmInput, [out] uint32 gmOutput);
   [WmiMethodId(15), Implemented, read, write, Description("Get Acer Gaming Fan Group Behavior.")] void GetGamingFanBehavior([in] uint32 gmInput, [out] uint64 gmOutput);
   [WmiMethodId(16), Implemented, read, write, Description("Set Acer Gaming Fan Group Speed.")] void SetGamingFanSpeed([in] uint64 gmInput, [out] uint32 gmOutput);
   [WmiMethodId(17), Implemented, read, write, Description("Get Acer Gaming Fan Group Speed.")] void GetGamingFanSpeed([in] uint32 gmInput, [out] uint64 gmOutput);
   [WmiMethodId(18), Implemented, read, write, Description("Set Acer Gaming Fan Table.")] void SetGamingFanTable([in] uint64 gmInput, [out] uint32 gmOutput);
   [WmiMethodId(19), Implemented, read, write, Description("Get Acer Gaming Fan Table.")] void GetGamingFanTable([out] uint64 gmOutput);
   [WmiMethodId(20), Implemented, read, write, Description("Set Acer Gaming Keyboard Backlight Behavior.")] void SetGamingKBBacklight([in] uint8 gmInput[16], [out] uint32 gmOutput);
   [WmiMethodId(21), Implemented, read, write, Description("Get Acer Gaming Keyboard Backlight Behavior.")] void GetGamingKBBacklight([in] uint32 gmInput, [out] uint8 gmReturn, [out] uint8 gmOutput[15]);
   [WmiMethodId(22), Implemented, read, write, Description("Set Acer Gaming Miscellaneous Setting.")] void SetGamingMiscSetting([in] uint64 gmInput, [out] uint32 gmOutput);
   [WmiMethodId(23), Implemented, read, write, Description("Get Acer Gaming Miscellaneous Setting.")] void GetGamingMiscSetting([in] uint32 gmInput, [out] uint64 gmOutput);
   [WmiMethodId(24), Implemented, read, write, Description("Set CPU Overclocking Profile.")] void SetCPUOverclockingProfile([in] uint8 OCProfile, [in] uint8 OCStructure[512], [out] uint8 ReturnCode, [out] uint8 Reserved[3]);
   [WmiMethodId(25), Implemented, read, write, Description("Get CPU Overclocking Profile.")] void GetCPUOverclockingProfile([in] uint8 Reserved[4], [out] uint8 ReturnCode, [out] uint8 ReturnOCProfile, [out] uint8 OCStructure[512]);
};

The method "SetGamingMiscSetting"  is used to set the platform profile. For reading however the EC is accessed by the acer-wmi driver.

This is the ACPI code responsible for handling "SetGamingMiscSetting" and "GetGamingMiscSetting" (Arg1 is the WMI method id, Arg2 contains the input arguments):

                 If ((Arg1 == 0x16))
                 {
                     BHSK = Arg2
                     Local0 = DerefOf (BHSK [Zero])
                     Local1 = DerefOf (BHSK [One])
                     BHSK [Zero] = 0x03
                     If ((Local0 == One))
                     {
                         \_SB.PC00.LPCB.EC0.TKST = Local1
                         BHSK [Zero] = Zero
                     }
                     ElseIf ((Local0 == 0x02))
                     {
                         WSMI (Arg1, Arg2)
                         BHSK = WMIB /* \_SB_.PC00.WMID.WMIB */
                     }
                     ElseIf ((Local0 == 0x05)){}
                     ElseIf ((Local0 == 0x06))
                     {
                         WSMI (Arg1, Arg2)
                         BHSK = WMIB /* \_SB_.PC00.WMID.WMIB */
                     }
                     ElseIf ((Local0 == 0x07)){}
                     ElseIf ((Local0 == 0x08))
                     {
                         WSMI (Arg1, Arg2)
                         BHSK = WMIB /* \_SB_.PC00.WMID.WMIB */
                     }
                     ElseIf ((Local0 == 0x09))
                     {
                         BHSK [Zero] = One
                     }
                     ElseIf ((Local0 == 0x0A))
                     {
                         BHSK [Zero] = 0x03
                     }
                     ElseIf ((Local0 == 0x0B))
                     {

This code in particular is responsible for setting the platform profile. Noticed the OPMS field here which is used to
store the current platform profile set by the driver.

                         \_SB.PC00.LPCB.EC0.OPMS = Local1
                         If ((OG00 == Zero))
                         {
                             If ((\_SB.GGIV (0x090E000A) == Zero))
                             {
                                 If ((Local1 == Zero))
                                 {
                                     \ODV0 = Zero
                                 }
                                 ElseIf ((Local1 == One))
                                 {
                                     \ODV0 = One
                                 }
                                 ElseIf ((Local1 == 0x04))
                                 {
                                     \ODV0 = 0x02
                                 }
                             }
                             ElseIf ((Local1 == Zero))
                             {
                                 \ODV0 = 0x03
                             }
                             ElseIf ((Local1 == One))
                             {
                                 \ODV0 = 0x04
                             }
                             ElseIf ((Local1 == 0x04))
                             {
                                 If (((CMSR (0x77) == 0x05) || (CMSR (0x77) == 0x04)))
                                 {
                                     \ODV0 = 0x06
                                 }
                                 Else
                                 {
                                     \ODV0 = 0x05
                                 }
                             }
                         }

                         If ((OG00 == One))
                         {
                             If ((\_SB.GGIV (0x090E000A) == Zero))
                             {
                                 If ((Local1 == Zero))
                                 {
                                     \ODV0 = 0x07
                                 }
                                 ElseIf ((Local1 == One))
                                 {
                                     \ODV0 = 0x08
                                 }
                                 ElseIf ((Local1 == 0x04))
                                 {
                                     \ODV0 = 0x09
                                 }
                             }
                             ElseIf ((Local1 == Zero))
                             {
                                 \ODV0 = 0x0A
                             }
                             ElseIf ((Local1 == One))
                             {
                                 \ODV0 = 0x0B
                             }
                             ElseIf ((Local1 == 0x04))
                             {
                                 If (((CMSR (0x77) == 0x05) || (CMSR (0x77) == 0x04)))
                                 {
                                     \ODV0 = 0x0D
                                 }
                                 Else
                                 {
                                     \ODV0 = 0x0C
                                 }
                             }
                         }

                         \_SB.IETM.ODVP ()
                         Notify (\_SB.IETM, 0x88) // Device-Specific
                         Notify (\_SB.NPCF, 0xC0) // Hardware-Specific
                         Notify (\_SB.NPCF, 0xC1) // Hardware-Specific
                         BHSK [Zero] = Zero
                     }
                     ElseIf ((Local0 == 0x0D))
                     {
                         BHSK [Zero] = 0x03
                     }
                     ElseIf ((Local0 == 0x0E))
                     {
                         BHSK [Zero] = 0x03
                     }
                     ElseIf ((Local0 == 0x0F))
                     {
                         If ((Local1 == One))
                         {
                             BHSK [Zero] = Zero
                             \_SB.PC00.LPCB.EC0.FMKY = One
                         }
                         ElseIf ((Local1 == 0x02))
                         {
                             BHSK [Zero] = Zero
                             \_SB.PC00.LPCB.EC0.FMKY = Zero
                         }
                     }
                     Else
                     {
                         BHSK [Zero] = 0x03
                         BHSK [One] = Zero
                         BHSK [0x02] = Zero
                         BHSK [0x03] = Zero
                     }

                     Return (BHSK) /* \_SB_.PC00.WMID.BHSK */
                 }

                 If ((Arg1 == 0x17))
                 {
                     BHSK = Arg2
                     Local0 = DerefOf (BHSK [Zero])
                     BHGK [Zero] = Zero
                     BHGK [One] = 0xFF
                     If ((Local0 == One))
                     {
                         BHGK [One] = \_SB.PC00.LPCB.EC0.TKST /* External reference */
                         BHGK [Zero] = Zero
                     }
                     ElseIf ((Local0 == 0x02))
                     {
                         WSMI (Arg1, Arg2)
                         BHGK = WMIB /* \_SB_.PC00.WMID.WMIB */
                     }
                     ElseIf ((Local0 == 0x05)){}
                     ElseIf ((Local0 == 0x06))
                     {
                         WSMI (Arg1, Arg2)
                         BHGK = WMIB /* \_SB_.PC00.WMID.WMIB */
                     }
                     ElseIf ((Local0 == 0x07)){}
                     ElseIf ((Local0 == 0x08))
                     {
                         WSMI (Arg1, Arg2)
                         BHGK = WMIB /* \_SB_.PC00.WMID.WMIB */
                     }
                     ElseIf ((Local0 == 0x09))
                     {
                         WSMI (Arg1, Arg2)
                         BHGK = WMIB /* \_SB_.PC00.WMID.WMIB */
                     }
                     ElseIf ((Local0 == 0x0A))
                     {
                         BHGK [Zero] = Zero
                         BHGK [One] = 0x13

Side note: this field seems to contain a bitmap of the supported platform profiles on this machine.

                     }
                     ElseIf ((Local0 == 0x0B))
                     {

Calling this method ("GetGamingMiscSetting") with the same command (0x0B) would return the current platform
profile by using the OPMS field.

                         BHGK [Zero] = Zero
                         BHGK [One] = \_SB.PC00.LPCB.EC0.OPMS /* External reference */
                     }
                     ElseIf ((Local0 == 0x0C))
                     {
                         BHGK [One] = Zero
                     }
                     ElseIf ((Local0 == 0x0D))
                     {
                         BHGK [Zero] = 0x03
                     }
                     ElseIf ((Local0 == 0x0E))
                     {
                         BHGK [Zero] = 0x03
                     }
                     ElseIf ((Local0 == 0x0F))
                     {
                         If ((\_SB.PC00.LPCB.EC0.FMKY == One))
                         {
                             BHGK [Zero] = Zero
                             BHGK [One] = One
                         }
                         ElseIf ((\_SB.PC00.LPCB.EC0.FMKY == Zero))
                         {
                             BHGK [Zero] = Zero
                             BHGK [One] = 0x02
                         }
                     }
                     ElseIf ((Local0 == 0x10))
                     {
                         BHGK [Zero] = Zero
                         BHGK [One] = 0xFF
                     }
                     Else
                     {
                         BHGK [Zero] = Zero
                         BHGK [One] = 0xFF
                         BHGK [0x02] = Zero
                         BHGK [0x03] = Zero
                         BHGK [0x04] = Zero
                         BHGK [0x05] = Zero
                         BHGK [0x06] = Zero
                         BHGK [0x07] = Zero
                     }

                     Return (BHGK) /* \_SB_.PC00.WMID.BHGK */
                 }

I can provide you with a basic patch which adds support for calling those two WMI methods. You can then wire-up the platform profile code
inside acer-wmi to use those WMI methods instead of trying to access the EC directly.

Thanks,
Armin Wolf


  reply	other threads:[~2024-12-25 20:52 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-12-16  6:15 acer-wmi: Nitro button doesn't produce a WMI event Hridesh MG
2024-12-17  0:47 ` Armin Wolf
2024-12-17  8:33   ` Hridesh MG
2024-12-17 13:28     ` Armin Wolf
2024-12-17 17:41       ` Hridesh MG
2024-12-17 20:12         ` Armin Wolf
2024-12-17 20:52           ` Hridesh MG
2024-12-17 21:44             ` Armin Wolf
     [not found]               ` <CALiyAok0_JKE+BkUQxHHH8Z39FHq5bW0Hb1Gk-MYHgDy0yFoMA@mail.gmail.com>
2024-12-23 23:06                 ` Armin Wolf
2024-12-24 12:55                   ` Armin Wolf
2024-12-24 18:45                     ` Hridesh MG
2024-12-25 20:51                       ` Armin Wolf [this message]
2024-12-26 17:41                         ` Hridesh MG
2024-12-26 23:40                           ` Armin Wolf
2025-01-01 10:48           ` Hridesh MG
2025-01-01 12:37             ` Armin Wolf
2025-01-01 19:53               ` Hridesh MG
2025-01-01 20:21                 ` Armin Wolf
2025-01-02  6:18                   ` Hridesh MG
2025-01-06 16:59                     ` Armin Wolf
2025-01-06 18:33                       ` Hans de Goede
2025-01-06 22:29                         ` Armin Wolf
2025-01-07  9:45                           ` Hans de Goede

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=ecb60ee5-3df7-4d7e-8ebf-8c162b339ade@gmx.de \
    --to=w_armin@gmx.de \
    --cc=hridesh699@gmail.com \
    --cc=platform-driver-x86@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox