mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Rong Zhang <i@rong.moe>
To: Marco Giunta <marco_giunta@outlook.it>
Cc: derekjohn.clark@gmail.com, hansg@kernel.org, huangwei@kylinos.cn,
	 ikepanhc@gmail.com, ilpo.jarvinen@linux.intel.com,
	linux-kernel@vger.kernel.org, 	mpearson-lenovo@squebb.ca,
	platform-driver-x86@vger.kernel.org
Subject: Re: [PATCH v2] platform/x86: ideapad-laptop: Report camera switch as SW_CAMERA_LENS_COVER
Date: Wed, 23 Sep 2026 20:39:53 +0800	[thread overview]
Message-ID: <356cc2817ce72c4f2d7b4f623ae73b979d314ac8.camel@rong.moe> (raw)
In-Reply-To: <SN6PR19MB230365BE74C6A502EBB4F35DFC822@SN6PR19MB2303.namprd19.prod.outlook.com>

Hi Marco,

Thanks for the detailed information.

On Wed, 2026-09-23 at 13:17 +0200, Marco Giunta wrote:
> Hi Rong & Mark,
> 
> thanks a lot for the impressively detailed and informative replies
> (as always). Here's an update from me.
> 
> 1. overall I changed my mind regarding the conditional switch registration.
> I no longer really see it as particularly problematic in practice; as Rong
> said earlier, in practice it's mostly a theoretical concern given the
> typical userspace usage of this switch.
> 
> I do agree that if we can find a smart way to filter for switch presence
> based on a good criterion, like a suitable wmi method, it would
> definitively be an improvement to patch v3. And I also appreciate that
> gaining a better understanding of these issues may improve other lenovo
> drivers. Finally, in general, I am certainly not trying to stifle the
> useful discussion going on here; what I'm trying to say is: as far as the
> camera switch patch is concerned, I am perfectly fine with the simple
> approach of v3 (at least for now, we can add more complexity later IMO).

Agreed. More comments below.

> 
> 2. here https://github.com/marco-giunta/lenovo-acpi-dump you can find
> all raw & decompiled ACPI tables and bmof files from both my yoga and my
> legion. Feel free to ask for more data.

Good job. They are exactly what I want to cross-check with. They'll also
be useful when I develop future patches for lenovo-wmi-*.

> 
> 3. Let me clarify what I meant when I said that the yoga and the lenovo
> handle the switch differently (and more generally report some highlights
> from the above files).
> 
> The yoga's SSDT2 table contains:
> 
> Device (WMIU)
> {
>     Name (_HID, "PNP0C14" /* Windows Management Instrumentation Device */)  // _HID: Hardware ID
>     Name (_UID, "LSK20")  // _UID: Unique ID
>     Name (LSKE, 0x02)
>     Name (_WDG, Buffer (0x3C)
>     {
>         /* 0000 */  0x74, 0x09, 0x6C, 0xCE, 0x07, 0x04, 0x50, 0x4F,  // t.l...PO
>         /* 0008 */  0x88, 0xBA, 0x4F, 0xC3, 0xB6, 0x55, 0x9A, 0xD8,  // ..O..U..
>         /* 0010 */  0x53, 0x4B, 0x01, 0x02, 0x21, 0x12, 0x90, 0x05,  // SK..!...
>         /* 0018 */  0x66, 0xD5, 0xD1, 0x11, 0xB2, 0xF0, 0x00, 0xA0,  // f.......
>         /* 0020 */  0xC9, 0x06, 0x29, 0x10, 0x44, 0x41, 0x01, 0x00,  // ..).DA..
>         /* 0028 */  0x0C, 0xDE, 0xC0, 0x8F, 0xE4, 0xB4, 0xFD, 0x43,  // .......C
>         /* 0030 */  0xB0, 0xF3, 0x88, 0x71, 0x71, 0x1C, 0x12, 0x94,  // ...qq...
>         /* 0038 */  0xD0, 0x00, 0x01, 0x08                           // ....
>     })
> 
> so GUID 8FC0DE0C-B4E4-43FD-B0F3-8871711C1294 on device WMIU, event (0x08)
> with notify value 0xD0, no surprises here.
> 
> Its _WED method is:
> 
> Method (_WED, 1, NotSerialized)  // _Wxx: Wake Event, xx=0x00-0xFF
> {
>     If ((Arg0 == 0xD0))
>     {
>         Return (PSD1) /* \PSD1 */
>     }
> }
> 
> so "notify" = "return PSD1". Then below:
> 
> Scope (\_SB.PCI0.LPC0.EC0)
> {
> ...
>     Method (_Q29, 0, NotSerialized)  // _Qxx: EC Query, xx=0x00-0xFF
>         {
>             If ((\_SB.PCI0.LPC0.EC0.COSD == 0x02))
>             {
>                 PSD1 = 0x0C
>             }
>             ElseIf ((\_SB.PCI0.LPC0.EC0.COSD == Zero))
>             {
>                 PSD1 = 0x0D
>             }
> 
>             Notify (\_SB.WMIU, 0xD0) // Hardware-Specific
>         }
> }
> 
> So the camera on/off 0x0c/0x0d events are sent based on the COSD memory
> register in the EC.
> 
> This COSD variable is never referred to again anywhere else in the ACPI tables.

Then we can't query the switch's state via WMI on the Yoga.

> 
> On the Legion:
> 
> Device (WMIU)
>     {
>         Name (_HID, "PNP0C14" /* Windows Management Instrumentation Device */)  // _HID: Hardware ID
>         Name (_UID, "LSK20")  // _UID: Unique ID
>         Name (_WDG, Buffer (0x3C)
>         {
>             /* 0000 */  0x74, 0x09, 0x6C, 0xCE, 0x07, 0x04, 0x50, 0x4F,  // t.l...PO
>             /* 0008 */  0x88, 0xBA, 0x4F, 0xC3, 0xB6, 0x55, 0x9A, 0xD8,  // ..O..U..
>             /* 0010 */  0x53, 0x4B, 0x01, 0x02, 0x0C, 0xDE, 0xC0, 0x8F,  // SK......
>             /* 0018 */  0xE4, 0xB4, 0xFD, 0x43, 0xB0, 0xF3, 0x88, 0x71,  // ...C...q
>             /* 0020 */  0x71, 0x1C, 0x12, 0x94, 0xD0, 0x00, 0x01, 0x08,  // q.......
>             /* 0028 */  0x21, 0x12, 0x90, 0x05, 0x66, 0xD5, 0xD1, 0x11,  // !...f...
>             /* 0030 */  0xB2, 0xF0, 0x00, 0xA0, 0xC9, 0x06, 0x29, 0x10,  // ......).
>             /* 0038 */  0x44, 0x41, 0x01, 0x00                           // DA..
> 
>             })
> 
> Same 8fc0... GUID, same [0xD0, 0x00, 0x01, 0x08] sequence. Then:
> 
> Method (_WED, 1, NotSerialized)  // _Wxx: Wake Event, xx=0x00-0xFF
>     {
>         If ((Arg0 == 0xD0))
>         {
>             Return (LSKD) /* External reference */
>         }
>     }
> 
> But here this LSKD variable is written to with different logic. The relevant
> EC query handler is:
> 
> Method (_QDF, 0, NotSerialized)  // _Qxx: EC Query, xx=0x00-0xFF
>     {
>         P80B = 0xDF
>         Sleep (0x05)
>         LSKD = Zero
>         If ((LSKV != Zero))
>         {
>             LSKD = LSKV /* \_SB_.PCI0.LPC0.EC0_.LSKV */
>             If ((LSKD == 0x02)){}
>             If ((LSKD == 0x03)){}
>             LSKV = Zero
>         }
> 
>         Notify (WMIU, 0xD0) // Hardware-Specific
>         Notify (GZFD, 0xE8) // Hardware-Specific
>     }
> 
> so there are no assignments of 0x0c/0x0d like on the Yoga: the EC itself
> writes the event code into LSKV (a byte at offset 0x1F of the ERAX region,
> SystemMemory 0xFEEC2400), and the AML only copies it to LSKD and clears
> the mailbox.
> 
> The constants therefore appear to live in the EC firmware rather than
> in the ACPI tables, and no AML-visible object keeps the switch state,
> unlike COSD on the Yoga (which is at least readable in principle, even if
> nothing else reads it).
> 
> Overall, the firmware appears to work differently internally, and I wasn't
> able to find a common interface that a driver could use for this without
> resorting to per-model EC details (see below), though I may be missing
> something.
> 
> 4. Unless I'm missing something, the IDs Mark mentioned don't really apply
> here.
> 
> 0x00201000 does not appear anywhere in either machine's tables - consistent
> with Mark's point that this ID is new; both of my devices were released in
> 2025.
> 
> 0x00200000 appears a few times in SSDT2 (yoga)/SSDT5 (legion) in contexts that
> look unrelated (bitmask arithmetic in DYTC on the Yoga, and in the GPS
> method on the Legion), plus once in the Yoga's capability data, see below.
> 
> LENOVO_OTHER_METHOD is implemented on both machines as \_SB.GZFD.WMAE
> (object "AE" in the GZFD _WDG, flags 0x02 = method). Since the MOF
> declares GetFeatureValue as WmiMethodId(17), the relevant branch is
> Arg1 == 0x11, the same one as in Rong's 83JR snippet. As far as I can
> tell neither machine handles the two shutter IDs there: the Yoga has logic
> to dispatch based on device/feature bytes (and covers device 0 features
> 0x02 and 0x08, device 4 feature 0x03, and device 8 feature 0x01); instead
> the Legion compares whole IDs and its device-0 list goes from
> 0x001F0000 straight to 0x00210000. Unhandled IDs return Zero in both
> cases, which, if 0 means "closed", would make those IDs report a closed
> shutter regardless of the switch position. I would appreciate a second
> opinion on this reading, though.
> 
> As for the capability data, the Yoga implements LENOVO_CAPABILITY_DATA_00,
> defined in the bmof as
> 
> [WMI, Dynamic, Provider("WmiProv"), Locale("MS\\0x409"), Description("LENOVO CAPABILITY DATA 00"), guid("{362a3afe-3d96-4665-8530-96dad5bb300e}")]
> class LENOVO_CAPABILITY_DATA_00 {
>   [key, read] string InstanceName;
>   [read] boolean Active;
>   [WmiDataId(1), read, Description(" IDs.")] uint32 IDs;
>   [WmiDataId(2), read, Description("Capability.")] uint32 Capability;
>   [WmiDataId(3), read, Description("Capability Default Value.")] uint32 DefaultValue;
> };
> 
> This object is implemented in the acpi tables with GUID
> 362A3AFE-3D96-4665-8530-96DAD5BB300E, object id "B0", as WQB0 -> GCD0,
> which returns the three dwords of each element of the CD00 package.
> CD00 enumerates the feature IDs in ascending order, and includes
> 
>     { 0x001F0000, Zero, Zero },
>     { 0x00200000, Zero, Zero },
>     { 0x00210000, Zero, Zero },
> 
> while other entries in the same table have capability values such as
> 0x07, 0x09, 0x05, 0x03 and One. If the capability field is the bitmask
> from Mark's table, this would mean the CV DSP Camera Shutter is enumerated
> but declared as not supported on this model. (and again there is no
> 0x00201000 entry)

Just checked the SSDT2 table of Yoga, and I found the implementation of
WMIU very similar to my device (ThinkBook 14 G7+ ASP). Mine has no
0x00200000 package though, which makes some sense as it has a passive
shutter that physically covers the camera.

Perhaps the Yoga Pro 7 14ASP10 was developed in the direction of
supporting 0x00200000, but the dev team eventually removed it before
releasing.

> 
> The Legion's capability data (same 362a... GUID) is built by WQA9 from
> hardcoded buffers rather than from a package, and has no entry for
> 0x00200000 at all.

Then we can't query the switch's state via WMI on the Legion.

> 
> So while these interfaces look like the right way to expose
> SW_CAMERA_LENS_COVER conditionally on firmware that implements them
> (like on the 83JR platform), they do not seem usable on these two models.

Agreed.

> 
> 5. I have basically no experience parsing WMI data and very little with
> ACPI tables in general. Please feel free to correct me! And in general
> take the above with a pinch of salt.
> I hope the linked files will prove more useful than me in this regard.

Your interpretation is well done and impressive!

In conclusion, I agreed that we should take the simple approach, i.e.,
exposing KEY_SW unconditionally. If we see a report for a 0x00200000-
capable device, we can add support for it then. For the time being, let's
focus on what we have first.

> 
> 
> Thanks again for your work on this, I am learning a lot from this thread.

Thanks a lot for your help, too.

I will submit my patch with your C-d-b, S-o-b, and T-b.

Thanks,
Rong

> 
> Best regards,
> Marco

  reply	other threads:[~2026-09-23 12:45 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-19  8:41 [PATCH] " Marco Giunta
2026-09-20  6:42 ` Huang Wei
2026-09-20  9:58   ` Marco Giunta
2026-09-20 10:29     ` Huang Wei
2026-09-20 10:58       ` Marco Giunta
2026-09-20 20:28 ` [PATCH v2] " Marco Giunta
2026-09-21  2:36   ` Huang Wei
2026-09-21 14:50   ` Rong Zhang
2026-09-21 15:03     ` Rong Zhang
2026-09-21 19:00     ` Marco Giunta
2026-09-22 11:08       ` Huang Wei
2026-09-22 12:18       ` Rong Zhang
2026-09-22 15:52         ` Mark Pearson
2026-09-22 15:58           ` Rong Zhang
2026-09-22 16:42             ` Rong Zhang
2026-09-22 17:32               ` Mark Pearson
2026-09-22 18:47                 ` Rong Zhang
2026-09-23 11:17                   ` Marco Giunta
2026-09-23 12:39                     ` Rong Zhang [this message]
2026-09-23 13:11                       ` Marco Giunta

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=356cc2817ce72c4f2d7b4f623ae73b979d314ac8.camel@rong.moe \
    --to=i@rong.moe \
    --cc=derekjohn.clark@gmail.com \
    --cc=hansg@kernel.org \
    --cc=huangwei@kylinos.cn \
    --cc=ikepanhc@gmail.com \
    --cc=ilpo.jarvinen@linux.intel.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=marco_giunta@outlook.it \
    --cc=mpearson-lenovo@squebb.ca \
    --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

all inboxes | Powered by JetHome®