Re: Tablet mode on L13 Yoga Gen 3

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Am 24.07.24 um 01:35 schrieb Liam Howlett:

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

Hi,

can you share the output of "acpidump"? This will make it easier to figure
out what the ACPI code is doing.

Thanks,
Armin Wolf

(Also, please do not top-post, thank you).

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





[Index of Archives]     [Linux Kernel Development]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux