Signed-off-by: Leonid Bloch <[email protected]>
---
 MAINTAINERS           |   5 ++
 docs/specs/button.rst | 131 ++++++++++++++++++++++++++++++++++++++++++
 docs/specs/index.rst  |   1 +
 3 files changed, 137 insertions(+)
 create mode 100644 docs/specs/button.rst

diff --git a/MAINTAINERS b/MAINTAINERS
index 90941519e3..42179aba95 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3050,6 +3050,11 @@ F: docs/specs/acad.rst
 F: hw/acpi/acad*
 F: include/hw/acpi/acad.h
 
+Button
+M: Leonid Bloch <[email protected]>
+S: Maintained
+F: docs/specs/button.rst
+
 Subsystems
 ----------
 Overall Audio backends
diff --git a/docs/specs/button.rst b/docs/specs/button.rst
new file mode 100644
index 0000000000..10e57a380e
--- /dev/null
+++ b/docs/specs/button.rst
@@ -0,0 +1,131 @@
+.. SPDX-License-Identifier: GPL-2.0-or-later
+
+========================
+Laptop Lid Button Device
+========================
+
+The button device provides laptop lid button state information to the guest via
+ACPI. Lid state is controlled via QMP commands, providing deterministic control
+for testing and migration safety.
+
+Configuration
+-------------
+
+The lid button device is created as an ISA device using ``-device button``.
+
+Properties
+~~~~~~~~~~
+
+``ioport`` (default: 0x53d)
+  I/O port base address for the lid button device register.
+
+ACPI Interface
+--------------
+
+The lid button device is exposed to the guest as an ACPI device with:
+
+* **HID**: ``PNP0C0D`` (Lid Device)
+* **Device Path**: ``\_SB.LID0``
+* **Notification Values**:
+
+  * ``0x80``: Status change (lid opened/closed)
+
+ACPI Methods
+~~~~~~~~~~~~
+
+``_LID`` (Lid Status)
+  Returns the current lid state (0 = closed, 1 = open).
+
+I/O Interface
+-------------
+
+The device uses a single I/O port register:
+
+* **Port**: ``ioport`` property value (default 0x53d)
+* **Size**: 1 byte
+* **Access**: Read-only
+
+Register Layout
+~~~~~~~~~~~~~~~
+
+**LIDS** (offset 0x00, 1 byte)
+  Current lid state:
+
+  * ``0x00``: Lid closed
+  * ``0x01``: Lid open
+
+QMP Commands
+------------
+
+The following QMP commands control the lid button state:
+
+``lid-button-set-state``
+  Set the lid button state.
+
+  * ``open``: Whether the lid is open (boolean)
+
+  Example::
+
+    -> { "execute": "lid-button-set-state",
+         "arguments": { "open": true }}
+    <- { "return": {} }
+
+``query-lid-button``
+  Query the current lid button state.
+
+  Example::
+
+    -> { "execute": "query-lid-button" }
+    <- { "return": { "open": true }}
+
+Examples
+--------
+
+Basic usage::
+
+  # Start VM with lid button
+  qemu-system-x86_64 -device button -qmp tcp:localhost:4444,server,wait=off
+
+  # From another terminal, set lid state via QMP:
+  echo '{"execute":"qmp_capabilities"}
+        {"execute":"lid-button-set-state",
+         "arguments":{"open":false}}' | \
+  nc -N localhost 4444
+
+Simulate closing lid::
+
+  # Start with lid open (default)
+  # Close the lid
+  echo '{"execute":"lid-button-set-state",
+         "arguments":{"open":false}}' | nc -N localhost 4444
+
+  # Later, open the lid
+  echo '{"execute":"lid-button-set-state",
+         "arguments":{"open":true}}' | nc -N localhost 4444
+
+Test suspend on lid close::
+
+  # Start VM with ACPI support
+  qemu-system-x86_64 -device button
+
+  # Close lid - guest OS should detect this and may suspend
+  echo '{"execute":"lid-button-set-state",
+         "arguments":{"open":false}}' | nc -N localhost 4444
+
+  # Open lid - guest OS should wake or detect lid open
+  echo '{"execute":"lid-button-set-state",
+         "arguments":{"open":true}}' | nc -N localhost 4444
+
+Combined with other laptop devices::
+
+  # Create a complete laptop environment
+  qemu-system-x86_64 -device battery -device acad -device button
+
+  # Simulate closing lid while on battery power
+  echo '{"execute":"battery-set-state",
+         "arguments":{"state":{"present":true,"charging":false,
+                               "discharging":true,"charge-percent":60}}}
+        {"execute":"ac-adapter-set-state",
+         "arguments":{"connected":false}}
+        {"execute":"lid-button-set-state",
+         "arguments":{"open":false}}' | nc -N localhost 4444
diff --git a/docs/specs/index.rst b/docs/specs/index.rst
index a19c75384c..54d8f5f7c5 100644
--- a/docs/specs/index.rst
+++ b/docs/specs/index.rst
@@ -24,6 +24,7 @@ guest hardware that is specific to QEMU.
    acpi_erst
    acad
    battery
+   button
    sev-guest-firmware
    fw_cfg
    fsi
-- 
2.54.0


Reply via email to