Resguardo inicial

This commit is contained in:
lastdragon
2026-09-06 12:53:21 -06:00
parent 662efe3c2a
commit ad2088d178
94853 changed files with 43200404 additions and 0 deletions
@@ -0,0 +1,204 @@
.. SPDX-License-Identifier: GPL-2.0+
.. |ssam_cdev_request| replace:: :c:type:`struct ssam_cdev_request <ssam_cdev_request>`
.. |ssam_cdev_request_flags| replace:: :c:type:`enum ssam_cdev_request_flags <ssam_cdev_request_flags>`
.. |ssam_cdev_event| replace:: :c:type:`struct ssam_cdev_event <ssam_cdev_event>`
==============================
User-Space EC Interface (cdev)
==============================
The ``surface_aggregator_cdev`` module provides a misc-device for the SSAM
controller to allow for a (more or less) direct connection from user-space to
the SAM EC. It is intended to be used for development and debugging, and
therefore should not be used or relied upon in any other way. Note that this
module is not loaded automatically, but instead must be loaded manually.
The provided interface is accessible through the ``/dev/surface/aggregator``
device-file. All functionality of this interface is provided via IOCTLs.
These IOCTLs and their respective input/output parameter structs are defined in
``include/uapi/linux/surface_aggregator/cdev.h``.
A small python library and scripts for accessing this interface can be found
at https://github.com/linux-surface/surface-aggregator-module/tree/master/scripts/ssam.
.. contents::
Receiving Events
================
Events can be received by reading from the device-file. The are represented by
the |ssam_cdev_event| datatype.
Before events are available to be read, however, the desired notifiers must be
registered via the ``SSAM_CDEV_NOTIF_REGISTER`` IOCTL. Notifiers are, in
essence, callbacks, called when the EC sends an event. They are, in this
interface, associated with a specific target category and device-file-instance.
They forward any event of this category to the buffer of the corresponding
instance, from which it can then be read.
Notifiers themselves do not enable events on the EC. Thus, it may additionally
be necessary to enable events via the ``SSAM_CDEV_EVENT_ENABLE`` IOCTL. While
notifiers work per-client (i.e. per-device-file-instance), events are enabled
globally, for the EC and all of its clients (regardless of userspace or
non-userspace). The ``SSAM_CDEV_EVENT_ENABLE`` and ``SSAM_CDEV_EVENT_DISABLE``
IOCTLs take care of reference counting the events, such that an event is
enabled as long as there is a client that has requested it.
Note that enabled events are not automatically disabled once the client
instance is closed. Therefore any client process (or group of processes) should
balance their event enable calls with the corresponding event disable calls. It
is, however, perfectly valid to enable and disable events on different client
instances. For example, it is valid to set up notifiers and read events on
client instance ``A``, enable those events on instance ``B`` (note that these
will also be received by A since events are enabled/disabled globally), and
after no more events are desired, disable the previously enabled events via
instance ``C``.
Controller IOCTLs
=================
The following IOCTLs are provided:
.. flat-table:: Controller IOCTLs
:widths: 1 1 1 1 4
:header-rows: 1
* - Type
- Number
- Direction
- Name
- Description
* - ``0xA5``
- ``1``
- ``WR``
- ``REQUEST``
- Perform synchronous SAM request.
* - ``0xA5``
- ``2``
- ``W``
- ``NOTIF_REGISTER``
- Register event notifier.
* - ``0xA5``
- ``3``
- ``W``
- ``NOTIF_UNREGISTER``
- Unregister event notifier.
* - ``0xA5``
- ``4``
- ``W``
- ``EVENT_ENABLE``
- Enable event source.
* - ``0xA5``
- ``5``
- ``W``
- ``EVENT_DISABLE``
- Disable event source.
``SSAM_CDEV_REQUEST``
---------------------
Defined as ``_IOWR(0xA5, 1, struct ssam_cdev_request)``.
Executes a synchronous SAM request. The request specification is passed in
as argument of type |ssam_cdev_request|, which is then written to/modified
by the IOCTL to return status and result of the request.
Request payload data must be allocated separately and is passed in via the
``payload.data`` and ``payload.length`` members. If a response is required,
the response buffer must be allocated by the caller and passed in via the
``response.data`` member. The ``response.length`` member must be set to the
capacity of this buffer, or if no response is required, zero. Upon
completion of the request, the call will write the response to the response
buffer (if its capacity allows it) and overwrite the length field with the
actual size of the response, in bytes.
Additionally, if the request has a response, this must be indicated via the
request flags, as is done with in-kernel requests. Request flags can be set
via the ``flags`` member and the values correspond to the values found in
|ssam_cdev_request_flags|.
Finally, the status of the request itself is returned in the ``status``
member (a negative errno value indicating failure). Note that failure
indication of the IOCTL is separated from failure indication of the request:
The IOCTL returns a negative status code if anything failed during setup of
the request (``-EFAULT``) or if the provided argument or any of its fields
are invalid (``-EINVAL``). In this case, the status value of the request
argument may be set, providing more detail on what went wrong (e.g.
``-ENOMEM`` for out-of-memory), but this value may also be zero. The IOCTL
will return with a zero status code in case the request has been set up,
submitted, and completed (i.e. handed back to user-space) successfully from
inside the IOCTL, but the request ``status`` member may still be negative in
case the actual execution of the request failed after it has been submitted.
A full definition of the argument struct is provided below.
``SSAM_CDEV_NOTIF_REGISTER``
----------------------------
Defined as ``_IOW(0xA5, 2, struct ssam_cdev_notifier_desc)``.
Register a notifier for the event target category specified in the given
notifier description with the specified priority. Notifiers registration is
required to receive events, but does not enable events themselves. After a
notifier for a specific target category has been registered, all events of that
category will be forwarded to the userspace client and can then be read from
the device file instance. Note that events may have to be enabled, e.g. via the
``SSAM_CDEV_EVENT_ENABLE`` IOCTL, before the EC will send them.
Only one notifier can be registered per target category and client instance. If
a notifier has already been registered, this IOCTL will fail with ``-EEXIST``.
Notifiers will automatically be removed when the device file instance is
closed.
``SSAM_CDEV_NOTIF_UNREGISTER``
------------------------------
Defined as ``_IOW(0xA5, 3, struct ssam_cdev_notifier_desc)``.
Unregisters the notifier associated with the specified target category. The
priority field will be ignored by this IOCTL. If no notifier has been
registered for this client instance and the given category, this IOCTL will
fail with ``-ENOENT``.
``SSAM_CDEV_EVENT_ENABLE``
--------------------------
Defined as ``_IOW(0xA5, 4, struct ssam_cdev_event_desc)``.
Enable the event associated with the given event descriptor.
Note that this call will not register a notifier itself, it will only enable
events on the controller. If you want to receive events by reading from the
device file, you will need to register the corresponding notifier(s) on that
instance.
Events are not automatically disabled when the device file is closed. This must
be done manually, via a call to the ``SSAM_CDEV_EVENT_DISABLE`` IOCTL.
``SSAM_CDEV_EVENT_DISABLE``
---------------------------
Defined as ``_IOW(0xA5, 5, struct ssam_cdev_event_desc)``.
Disable the event associated with the given event descriptor.
Note that this will not unregister any notifiers. Events may still be received
and forwarded to user-space after this call. The only safe way of stopping
events from being received is unregistering all previously registered
notifiers.
Structures and Enums
====================
.. kernel-doc:: include/uapi/linux/surface_aggregator/cdev.h
@@ -0,0 +1,718 @@
.. SPDX-License-Identifier: GPL-2.0+
.. |__u16| replace:: :c:type:`__u16 <__u16>`
.. |sdtx_event| replace:: :c:type:`struct sdtx_event <sdtx_event>`
.. |sdtx_event_code| replace:: :c:type:`enum sdtx_event_code <sdtx_event_code>`
.. |sdtx_base_info| replace:: :c:type:`struct sdtx_base_info <sdtx_base_info>`
.. |sdtx_device_mode| replace:: :c:type:`struct sdtx_device_mode <sdtx_device_mode>`
======================================================
User-Space DTX (Clipboard Detachment System) Interface
======================================================
The ``surface_dtx`` driver is responsible for proper clipboard detachment
and re-attachment handling. To this end, it provides the ``/dev/surface/dtx``
device file, through which it can interface with a user-space daemon. This
daemon is then ultimately responsible for determining and taking necessary
actions, such as unmounting devices attached to the base,
unloading/reloading the graphics-driver, user-notifications, etc.
There are two basic communication principles used in this driver: Commands
(in other parts of the documentation also referred to as requests) and
events. Commands are sent to the EC and may have a different implications in
different contexts. Events are sent by the EC upon some internal state
change. Commands are always driver-initiated, whereas events are always
initiated by the EC.
.. contents::
Nomenclature
============
* **Clipboard:**
The detachable upper part of the Surface Book, housing the screen and CPU.
* **Base:**
The lower part of the Surface Book from which the clipboard can be
detached, optionally (model dependent) housing the discrete GPU (dGPU).
* **Latch:**
The mechanism keeping the clipboard attached to the base in normal
operation and allowing it to be detached when requested.
* **Silently ignored commands:**
The command is accepted by the EC as a valid command and acknowledged
(following the standard communication protocol), but the EC does not act
upon it, i.e. ignores it.e upper part of the
Detachment Process
==================
Warning: This part of the documentation is based on reverse engineering and
testing and thus may contain errors or be incomplete.
Latch States
------------
The latch mechanism has two major states: *open* and *closed*. In the
*closed* state (default), the clipboard is secured to the base, whereas in
the *open* state, the clipboard can be removed by a user.
The latch can additionally be locked and, correspondingly, unlocked, which
can influence the detachment procedure. Specifically, this locking mechanism
is intended to prevent the dGPU, positioned in the base of the device, from
being hot-unplugged while in use. More details can be found in the
documentation for the detachment procedure below. By default, the latch is
unlocked.
Detachment Procedure
--------------------
Note that the detachment process is governed fully by the EC. The
``surface_dtx`` driver only relays events from the EC to user-space and
commands from user-space to the EC, i.e. it does not influence this process.
The detachment process is started with the user pressing the *detach* button
on the base of the device or executing the ``SDTX_IOCTL_LATCH_REQUEST`` IOCTL.
Following that:
1. The EC turns on the indicator led on the detach-button, sends a
*detach-request* event (``SDTX_EVENT_REQUEST``), and awaits further
instructions/commands. In case the latch is unlocked, the led will flash
green. If the latch has been locked, the led will be solid red
2. The event is, via the ``surface_dtx`` driver, relayed to user-space, where
an appropriate user-space daemon can handle it and send instructions back
to the EC via IOCTLs provided by this driver.
3. The EC waits for instructions from user-space and acts according to them.
If the EC does not receive any instructions in a given period, it will
time out and continue as follows:
- If the latch is unlocked, the EC will open the latch and the clipboard
can be detached from the base. This is the exact behavior as without
this driver or any user-space daemon. See the ``SDTX_IOCTL_LATCH_CONFIRM``
description below for more details on the follow-up behavior of the EC.
- If the latch is locked, the EC will *not* open the latch, meaning the
clipboard cannot be detached from the base. Furthermore, the EC sends
an cancel event (``SDTX_EVENT_CANCEL``) detailing this with the cancel
reason ``SDTX_DETACH_TIMEDOUT`` (see :ref:`events` for details).
Valid responses by a user-space daemon to a detachment request event are:
- Execute ``SDTX_IOCTL_LATCH_REQUEST``. This will immediately abort the
detachment process. Furthermore, the EC will send a detach-request event,
similar to the user pressing the detach-button to cancel said process (see
below).
- Execute ``SDTX_IOCTL_LATCH_CONFIRM``. This will cause the EC to open the
latch, after which the user can separate clipboard and base.
As this changes the latch state, a *latch-status* event
(``SDTX_EVENT_LATCH_STATUS``) will be sent once the latch has been opened
successfully. If the EC fails to open the latch, e.g. due to hardware
error or low battery, a latch-cancel event (``SDTX_EVENT_CANCEL``) will be
sent with the cancel reason indicating the specific failure.
If the latch is currently locked, the latch will automatically be
unlocked before it is opened.
- Execute ``SDTX_IOCTL_LATCH_HEARTBEAT``. This will reset the internal timeout.
No other actions will be performed, i.e. the detachment process will neither
be completed nor canceled, and the EC will still be waiting for further
responses.
- Execute ``SDTX_IOCTL_LATCH_CANCEL``. This will abort the detachment process,
similar to ``SDTX_IOCTL_LATCH_REQUEST``, described above, or the button
press, described below. A *generic request* event (``SDTX_EVENT_REQUEST``)
is send in response to this. In contrast to those, however, this command
does not trigger a new detachment process if none is currently in
progress.
- Do nothing. The detachment process eventually times out as described in
point 3.
See :ref:`ioctls` for more details on these responses.
It is important to note that, if the user presses the detach button at any
point when a detachment operation is in progress (i.e. after the EC has sent
the initial *detach-request* event (``SDTX_EVENT_REQUEST``) and before it
received the corresponding response concluding the process), the detachment
process is canceled on the EC-level and an identical event is being sent.
Thus a *detach-request* event, by itself, does not signal the start of the
detachment process.
The detachment process may further be canceled by the EC due to hardware
failures or a low clipboard battery. This is done via a cancel event
(``SDTX_EVENT_CANCEL``) with the corresponding cancel reason.
User-Space Interface Documentation
==================================
Error Codes and Status Values
-----------------------------
Error and status codes are divided into different categories, which can be
used to determine if the status code is an error, and, if it is, the
severity and type of that error. The current categories are:
.. flat-table:: Overview of Status/Error Categories.
:widths: 2 1 3
:header-rows: 1
* - Name
- Value
- Short Description
* - ``STATUS``
- ``0x0000``
- Non-error status codes.
* - ``RUNTIME_ERROR``
- ``0x1000``
- Non-critical runtime errors.
* - ``HARDWARE_ERROR``
- ``0x2000``
- Critical hardware failures.
* - ``UNKNOWN``
- ``0xF000``
- Unknown error codes.
Other categories are reserved for future use. The ``SDTX_CATEGORY()`` macro
can be used to determine the category of any status value. The
``SDTX_SUCCESS()`` macro can be used to check if the status value is a
success value (``SDTX_CATEGORY_STATUS``) or if it indicates a failure.
Unknown status or error codes sent by the EC are assigned to the ``UNKNOWN``
category by the driver and may be implemented via their own code in the
future.
Currently used error codes are:
.. flat-table:: Overview of Error Codes.
:widths: 2 1 1 3
:header-rows: 1
* - Name
- Category
- Value
- Short Description
* - ``SDTX_DETACH_NOT_FEASIBLE``
- ``RUNTIME``
- ``0x1001``
- Detachment not feasible due to low clipboard battery.
* - ``SDTX_DETACH_TIMEDOUT``
- ``RUNTIME``
- ``0x1002``
- Detachment process timed out while the latch was locked.
* - ``SDTX_ERR_FAILED_TO_OPEN``
- ``HARDWARE``
- ``0x2001``
- Failed to open latch.
* - ``SDTX_ERR_FAILED_TO_REMAIN_OPEN``
- ``HARDWARE``
- ``0x2002``
- Failed to keep latch open.
* - ``SDTX_ERR_FAILED_TO_CLOSE``
- ``HARDWARE``
- ``0x2003``
- Failed to close latch.
Other error codes are reserved for future use. Non-error status codes may
overlap and are generally only unique within their use-case:
.. flat-table:: Latch Status Codes.
:widths: 2 1 1 3
:header-rows: 1
* - Name
- Category
- Value
- Short Description
* - ``SDTX_LATCH_CLOSED``
- ``STATUS``
- ``0x0000``
- Latch is closed/has been closed.
* - ``SDTX_LATCH_OPENED``
- ``STATUS``
- ``0x0001``
- Latch is open/has been opened.
.. flat-table:: Base State Codes.
:widths: 2 1 1 3
:header-rows: 1
* - Name
- Category
- Value
- Short Description
* - ``SDTX_BASE_DETACHED``
- ``STATUS``
- ``0x0000``
- Base has been detached/is not present.
* - ``SDTX_BASE_ATTACHED``
- ``STATUS``
- ``0x0001``
- Base has been attached/is present.
Again, other codes are reserved for future use.
.. _events:
Events
------
Events can be received by reading from the device file. They are disabled by
default and have to be enabled by executing ``SDTX_IOCTL_EVENTS_ENABLE``
first. All events follow the layout prescribed by |sdtx_event|. Specific
event types can be identified by their event code, described in
|sdtx_event_code|. Note that other event codes are reserved for future use,
thus an event parser must be able to handle any unknown/unsupported event
types gracefully, by relying on the payload length given in the event header.
Currently provided event types are:
.. flat-table:: Overview of DTX events.
:widths: 2 1 1 3
:header-rows: 1
* - Name
- Code
- Payload
- Short Description
* - ``SDTX_EVENT_REQUEST``
- ``1``
- ``0`` bytes
- Detachment process initiated/aborted.
* - ``SDTX_EVENT_CANCEL``
- ``2``
- ``2`` bytes
- EC canceled detachment process.
* - ``SDTX_EVENT_BASE_CONNECTION``
- ``3``
- ``4`` bytes
- Base connection state changed.
* - ``SDTX_EVENT_LATCH_STATUS``
- ``4``
- ``2`` bytes
- Latch status changed.
* - ``SDTX_EVENT_DEVICE_MODE``
- ``5``
- ``2`` bytes
- Device mode changed.
Individual events in more detail:
``SDTX_EVENT_REQUEST``
^^^^^^^^^^^^^^^^^^^^^^
Sent when a detachment process is started or, if in progress, aborted by the
user, either via a detach button press or a detach request
(``SDTX_IOCTL_LATCH_REQUEST``) being sent from user-space.
Does not have any payload.
``SDTX_EVENT_CANCEL``
^^^^^^^^^^^^^^^^^^^^^
Sent when a detachment process is canceled by the EC due to unfulfilled
preconditions (e.g. clipboard battery too low to detach) or hardware
failure. The reason for cancellation is given in the event payload detailed
below and can be one of
* ``SDTX_DETACH_TIMEDOUT``: Detachment timed out while the latch was locked.
The latch has neither been opened nor unlocked.
* ``SDTX_DETACH_NOT_FEASIBLE``: Detachment not feasible due to low clipboard
battery.
* ``SDTX_ERR_FAILED_TO_OPEN``: Could not open the latch (hardware failure).
* ``SDTX_ERR_FAILED_TO_REMAIN_OPEN``: Could not keep the latch open (hardware
failure).
* ``SDTX_ERR_FAILED_TO_CLOSE``: Could not close the latch (hardware failure).
Other error codes in this context are reserved for future use.
These codes can be classified via the ``SDTX_CATEGORY()`` macro to discern
between critical hardware errors (``SDTX_CATEGORY_HARDWARE_ERROR``) or
runtime errors (``SDTX_CATEGORY_RUNTIME_ERROR``), the latter of which may
happen during normal operation if certain preconditions for detachment are
not given.
.. flat-table:: Detachment Cancel Event Payload
:widths: 1 1 4
:header-rows: 1
* - Field
- Type
- Description
* - ``reason``
- |__u16|
- Reason for cancellation.
``SDTX_EVENT_BASE_CONNECTION``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Sent when the base connection state has changed, i.e. when the base has been
attached, detached, or detachment has become infeasible due to low clipboard
battery. The new state and, if a base is connected, ID of the base is
provided as payload of type |sdtx_base_info| with its layout presented
below:
.. flat-table:: Base-Connection-Change Event Payload
:widths: 1 1 4
:header-rows: 1
* - Field
- Type
- Description
* - ``state``
- |__u16|
- Base connection state.
* - ``base_id``
- |__u16|
- Type of base connected (zero if none).
Possible values for ``state`` are:
* ``SDTX_BASE_DETACHED``,
* ``SDTX_BASE_ATTACHED``, and
* ``SDTX_DETACH_NOT_FEASIBLE``.
Other values are reserved for future use.
``SDTX_EVENT_LATCH_STATUS``
^^^^^^^^^^^^^^^^^^^^^^^^^^^
Sent when the latch status has changed, i.e. when the latch has been opened,
closed, or an error occurred. The current status is provided as payload:
.. flat-table:: Latch-Status-Change Event Payload
:widths: 1 1 4
:header-rows: 1
* - Field
- Type
- Description
* - ``status``
- |__u16|
- Latch status.
Possible values for ``status`` are:
* ``SDTX_LATCH_CLOSED``,
* ``SDTX_LATCH_OPENED``,
* ``SDTX_ERR_FAILED_TO_OPEN``,
* ``SDTX_ERR_FAILED_TO_REMAIN_OPEN``, and
* ``SDTX_ERR_FAILED_TO_CLOSE``.
Other values are reserved for future use.
``SDTX_EVENT_DEVICE_MODE``
^^^^^^^^^^^^^^^^^^^^^^^^^^
Sent when the device mode has changed. The new device mode is provided as
payload:
.. flat-table:: Device-Mode-Change Event Payload
:widths: 1 1 4
:header-rows: 1
* - Field
- Type
- Description
* - ``mode``
- |__u16|
- Device operation mode.
Possible values for ``mode`` are:
* ``SDTX_DEVICE_MODE_TABLET``,
* ``SDTX_DEVICE_MODE_LAPTOP``, and
* ``SDTX_DEVICE_MODE_STUDIO``.
Other values are reserved for future use.
.. _ioctls:
IOCTLs
------
The following IOCTLs are provided:
.. flat-table:: Overview of DTX IOCTLs
:widths: 1 1 1 1 4
:header-rows: 1
* - Type
- Number
- Direction
- Name
- Description
* - ``0xA5``
- ``0x21``
- ``-``
- ``EVENTS_ENABLE``
- Enable events for the current file descriptor.
* - ``0xA5``
- ``0x22``
- ``-``
- ``EVENTS_DISABLE``
- Disable events for the current file descriptor.
* - ``0xA5``
- ``0x23``
- ``-``
- ``LATCH_LOCK``
- Lock the latch.
* - ``0xA5``
- ``0x24``
- ``-``
- ``LATCH_UNLOCK``
- Unlock the latch.
* - ``0xA5``
- ``0x25``
- ``-``
- ``LATCH_REQUEST``
- Request clipboard detachment.
* - ``0xA5``
- ``0x26``
- ``-``
- ``LATCH_CONFIRM``
- Confirm clipboard detachment request.
* - ``0xA5``
- ``0x27``
- ``-``
- ``LATCH_HEARTBEAT``
- Send heartbeat signal to EC.
* - ``0xA5``
- ``0x28``
- ``-``
- ``LATCH_CANCEL``
- Cancel detachment process.
* - ``0xA5``
- ``0x29``
- ``R``
- ``GET_BASE_INFO``
- Get current base/connection information.
* - ``0xA5``
- ``0x2A``
- ``R``
- ``GET_DEVICE_MODE``
- Get current device operation mode.
* - ``0xA5``
- ``0x2B``
- ``R``
- ``GET_LATCH_STATUS``
- Get current device latch status.
``SDTX_IOCTL_EVENTS_ENABLE``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Defined as ``_IO(0xA5, 0x22)``.
Enable events for the current file descriptor. Events can be obtained by
reading from the device, if enabled. Events are disabled by default.
``SDTX_IOCTL_EVENTS_DISABLE``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Defined as ``_IO(0xA5, 0x22)``.
Disable events for the current file descriptor. Events can be obtained by
reading from the device, if enabled. Events are disabled by default.
``SDTX_IOCTL_LATCH_LOCK``
^^^^^^^^^^^^^^^^^^^^^^^^^
Defined as ``_IO(0xA5, 0x23)``.
Locks the latch, causing the detachment procedure to abort without opening
the latch on timeout. The latch is unlocked by default. This command will be
silently ignored if the latch is already locked.
``SDTX_IOCTL_LATCH_UNLOCK``
^^^^^^^^^^^^^^^^^^^^^^^^^^^
Defined as ``_IO(0xA5, 0x24)``.
Unlocks the latch, causing the detachment procedure to open the latch on
timeout. The latch is unlocked by default. This command will not open the
latch when sent during an ongoing detachment process. It will be silently
ignored if the latch is already unlocked.
``SDTX_IOCTL_LATCH_REQUEST``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Defined as ``_IO(0xA5, 0x25)``.
Generic latch request. Behavior depends on the context: If no
detachment-process is active, detachment is requested. Otherwise the
currently active detachment-process will be aborted.
If a detachment process is canceled by this operation, a generic detachment
request event (``SDTX_EVENT_REQUEST``) will be sent.
This essentially behaves the same as a detachment button press.
``SDTX_IOCTL_LATCH_CONFIRM``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Defined as ``_IO(0xA5, 0x26)``.
Acknowledges and confirms a latch request. If sent during an ongoing
detachment process, this command causes the latch to be opened immediately.
The latch will also be opened if it has been locked. In this case, the latch
lock is reset to the unlocked state.
This command will be silently ignored if there is currently no detachment
procedure in progress.
``SDTX_IOCTL_LATCH_HEARTBEAT``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Defined as ``_IO(0xA5, 0x27)``.
Sends a heartbeat, essentially resetting the detachment timeout. This
command can be used to keep the detachment process alive while work required
for the detachment to succeed is still in progress.
This command will be silently ignored if there is currently no detachment
procedure in progress.
``SDTX_IOCTL_LATCH_CANCEL``
^^^^^^^^^^^^^^^^^^^^^^^^^^^
Defined as ``_IO(0xA5, 0x28)``.
Cancels detachment in progress (if any). If a detachment process is canceled
by this operation, a generic detachment request event
(``SDTX_EVENT_REQUEST``) will be sent.
This command will be silently ignored if there is currently no detachment
procedure in progress.
``SDTX_IOCTL_GET_BASE_INFO``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Defined as ``_IOR(0xA5, 0x29, struct sdtx_base_info)``.
Get the current base connection state (i.e. attached/detached) and the type
of the base connected to the clipboard. This is command essentially provides
a way to query the information provided by the base connection change event
(``SDTX_EVENT_BASE_CONNECTION``).
Possible values for ``struct sdtx_base_info.state`` are:
* ``SDTX_BASE_DETACHED``,
* ``SDTX_BASE_ATTACHED``, and
* ``SDTX_DETACH_NOT_FEASIBLE``.
Other values are reserved for future use.
``SDTX_IOCTL_GET_DEVICE_MODE``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Defined as ``_IOR(0xA5, 0x2A, __u16)``.
Returns the device operation mode, indicating if and how the base is
attached to the clipboard. This is command essentially provides a way to
query the information provided by the device mode change event
(``SDTX_EVENT_DEVICE_MODE``).
Returned values are:
* ``SDTX_DEVICE_MODE_LAPTOP``
* ``SDTX_DEVICE_MODE_TABLET``
* ``SDTX_DEVICE_MODE_STUDIO``
See |sdtx_device_mode| for details. Other values are reserved for future
use.
``SDTX_IOCTL_GET_LATCH_STATUS``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Defined as ``_IOR(0xA5, 0x2B, __u16)``.
Get the current latch status or (presumably) the last error encountered when
trying to open/close the latch. This is command essentially provides a way
to query the information provided by the latch status change event
(``SDTX_EVENT_LATCH_STATUS``).
Returned values are:
* ``SDTX_LATCH_CLOSED``,
* ``SDTX_LATCH_OPENED``,
* ``SDTX_ERR_FAILED_TO_OPEN``,
* ``SDTX_ERR_FAILED_TO_REMAIN_OPEN``, and
* ``SDTX_ERR_FAILED_TO_CLOSE``.
Other values are reserved for future use.
A Note on Base IDs
------------------
Base types/IDs provided via ``SDTX_EVENT_BASE_CONNECTION`` or
``SDTX_IOCTL_GET_BASE_INFO`` are directly forwarded from the EC in the lower
byte of the combined |__u16| value, with the driver storing the EC type from
which this ID comes in the high byte (without this, base IDs over different
types of ECs may be overlapping).
The ``SDTX_DEVICE_TYPE()`` macro can be used to determine the EC device
type. This can be one of
* ``SDTX_DEVICE_TYPE_HID``, for Surface Aggregator Module over HID, and
* ``SDTX_DEVICE_TYPE_SSH``, for Surface Aggregator Module over Surface Serial
Hub.
Note that currently only the ``SSH`` type EC is supported, however ``HID``
type is reserved for future use.
Structures and Enums
--------------------
.. kernel-doc:: include/uapi/linux/surface_aggregator/dtx.h
API Users
=========
A user-space daemon utilizing this API can be found at
https://github.com/linux-surface/surface-dtx-daemon.
@@ -0,0 +1,16 @@
.. SPDX-License-Identifier: GPL-2.0+
===========================
Client Driver Documentation
===========================
This is the documentation for client drivers themselves. Refer to
Documentation/driver-api/surface_aggregator/client.rst for documentation
on how to write client drivers.
.. toctree::
:maxdepth: 1
cdev
dtx
san
@@ -0,0 +1,44 @@
.. SPDX-License-Identifier: GPL-2.0+
.. |san_client_link| replace:: :c:func:`san_client_link`
.. |san_dgpu_notifier_register| replace:: :c:func:`san_dgpu_notifier_register`
.. |san_dgpu_notifier_unregister| replace:: :c:func:`san_dgpu_notifier_unregister`
===================
Surface ACPI Notify
===================
The Surface ACPI Notify (SAN) device provides the bridge between ACPI and
SAM controller. Specifically, ACPI code can execute requests and handle
battery and thermal events via this interface. In addition to this, events
relating to the discrete GPU (dGPU) of the Surface Book 2 can be sent from
ACPI code (note: the Surface Book 3 uses a different method for this). The
only currently known event sent via this interface is a dGPU power-on
notification. While this driver handles the former part internally, it only
relays the dGPU events to any other driver interested via its public API and
does not handle them.
The public interface of this driver is split into two parts: Client
registration and notifier-block registration.
A client to the SAN interface can be linked as consumer to the SAN device
via |san_client_link|. This can be used to ensure that the a client
receiving dGPU events does not miss any events due to the SAN interface not
being set up as this forces the client driver to unbind once the SAN driver
is unbound.
Notifier-blocks can be registered by any device for as long as the module is
loaded, regardless of being linked as client or not. Registration is done
with |san_dgpu_notifier_register|. If the notifier is not needed any more, it
should be unregistered via |san_dgpu_notifier_unregister|.
Consult the API documentation below for more details.
API Documentation
=================
.. kernel-doc:: include/linux/surface_acpi_notify.h
.. kernel-doc:: drivers/platform/surface/surface_acpi_notify.c
:export: