Just to follow this up, it's not (just?) an acpi issue, the driver isn't doing what it needs to do - if there is a driver for the hardware at all. I'm still looking into what is necessary. I did write the value to the CMMD variable, but calling the _Q2E function does not cause the ^HKEY.MHKQ (0x60C0) to be sent. If I understand this correctly, that's what should happen. Thanks, Liam On Mon, Jul 22, 2024 at 11:30 PM Liam Howlett <howlett@xxxxxxxxx> wrote: > > ..resend in plaintext, apologies if this is the second copy you are reading. > > Hello, > > I'd like to say first, thanks for the support of thinkpads in linux. > As a kernel maintainer, I understand this is a lot of work and I > appreciate you doing a fine job with supporting the hardware. > > I am working on patching the thinkpad_acpi driver to support the > keyboard rotation and keyboard lock-out in tablet mode for the L13 > Yoga Gen 3. I believe it needs just one bit extra to get working and > I'm struggling to figure out how to do what I believe is necessary. > > It looks like _SB.PCI0.LPC0.EC0.CMMD needs an initial value of 0x01 to > 0x06, but I don't see a way to trigger this to happen. Alternatively, > is there a way to write PMMD? > > Right now, I get the following message on boot: > thinkpad_acpi: Unknown/reserved multi mode value 0x0000 for type 4, > please report this to ibm-acpi-devel@xxxxxxxxxxxxxxxxxxxxx > > It looks like the value of 0 indicates that the keyboard rotate > monitoring is disabled, but I cannot seem to find an ACPI table way of > modifying EC0's contents (or set CMMD/PMMD) > > The functions of interest seem to be as follows: > Method (_Q2E, 0, NotSerialized) // _Qxx: EC > Query, xx=0x00-0xFF > { > Local0 = CMMD /* \_SB_.PCI0.LPC0.EC0_.CMMD */ > If (((Local0 != 0x00) && (Local0 <= 0x06))) > { > If ((Local0 != PMMD)) > { > PMMD = Local0 > ^HKEY.MHKQ (0x60C0) > If ((PMMD >= 0x04)) > { > WFIO (0x0B, 0x01) > } > ElseIf (CPLS) > { > WFIO (0x0B, 0x00) > } > Else > { > WFIO (0x0B, 0x01) > } > } > } > > If (((Local0 == 0x00) || (Local0 >= 0x07))) > { > Local1 = 0x01 > } > ElseIf (((Local0 == 0x02) || (Local0 == > 0x03))) > { > Local1 = 0x02 > } > Else > { > Local1 = 0x03 > } > > If ((Local1 != LVMD)) > { > LVMD = Local1 > Sleep (0x0A) > ^HKEY.MHKQ (0x60F0) > } > } > ... and ... > Method (GMMS, 1, NotSerialized) > { > Local0 = 0x00040000 > Local1 = PMMD /* \PMMD */ > If ((Local1 >= 0x06)) > { > Local0 |= 0x03 > } > ElseIf ((Local1 >= 0x05)) > { > Local0 |= 0x05 > } > ElseIf ((Local1 >= 0x04)) > { > Local0 |= 0x04 > } > ElseIf ((Local1 >= 0x03)) > { > Local0 |= 0x02 > } > ElseIf ((Local1 >= 0x01)) > { > Local0 |= 0x01 > } > > Return (Local0) > } > ... > and this portion of the _WAK code: > PMMD = \_SB.PCI0.LPC0.EC0.CMMD > If ((PMMD >= 0x07)) > { > PMMD = 0x00 > } > > LVMD = \_SB.PCI0.LPC0.EC0.CMMD > If (((LVMD == 0x00) || (LVMD >= 0x07))) > { > LVMD = 0x01 > } > ElseIf (((LVMD == 0x02) || (LVMD == 0x03))) > { > LVMD = 0x02 > } > Else > { > LVMD = 0x03 > } > > From this, and running acpiexec on the dumped tables, I can see that > the CMMD value is always 0. I don't see another function that > modifies or touches CMMD or PMMD directly, so it seems that this value > is read but never written by the ACPI itself. I also see that these > are the functions that your driver often uses and is trying to > interact with. I tried to set the CMMD value in the acpiexec, but it > won't set RegionField: > - dump _SB.PCI0.LPC0.EC0.CMMD > Object 0x55c5a3389490: Namespace Node - Pathname: \_SB.PCI0.LPC0.EC0.CMMD > 0000: B0 D9 38 A3 C5 55 00 00 0F 11 00 00 43 4D 4D 44 // ..8..U......CMMD > 0010: E0 3B 38 A3 C5 55 00 00 00 00 00 00 00 00 00 00 // .;8..U.......... > 0020: 00 95 38 A3 C5 55 00 00 01 00 00 00 00 00 00 00 // ..8..U.......... > Name : CMMD > Type : 11 [RegionField] > Flags : 0000 > Owner Id : 0001 > Object List : 0x55c5a338d9b0 RegionField (Type 11) > Parent : 0x55c5a3383be0 [EC0_] > Child : (nil) > Peer : 0x55c5a3389500 [WFDK] > > Attached Object 0x55c5a338d9b0: > 0000: 00 00 00 00 00 00 00 00 0E 11 01 00 00 01 00 01 // ................ > 0010: 90 94 38 A3 C5 55 00 00 08 00 00 00 C1 00 00 00 // ..8..U.......... > 0020: 00 00 00 00 00 00 00 00 10 3F 38 A3 C5 55 00 00 // .........?8..U.. > 0030: 00 00 00 00 00 00 00 00 80 00 00 00 00 00 00 00 // ................ > 0040: 00 00 00 00 00 00 00 00 // ........ > Type : 11 [RegionField] > Reference Count : 0001 > Flags : 00 > Object List : (nil) - No attached objects > Field Flags : 01 > Access Byte Width : 01 > Bit Length : 00000008 > Field Bit Offset : 00 > Base Byte Offset : 000000C1 > Parent Node : 0x55c5a3389490 [CMMD] > AccessLength : 00 > Region Object : 0x55c5a3383f10 > ResourceBuffer : (nil) > > I am nervous about adding a call to write that region field to the > thinkpad_acpi driver, but there does not appear to be another way to > modify the entry. I've searched for CMMD and PMMD in the dsdt.dsl and > haven't found a way to modify them. > > Any help would be appreciated. > > Thanks, > Liam R. Howlett