162306a36Sopenharmony_ci.. SPDX-License-Identifier: GPL-2.0+
262306a36Sopenharmony_ci
362306a36Sopenharmony_ci.. |ssam_cdev_request| replace:: :c:type:`struct ssam_cdev_request <ssam_cdev_request>`
462306a36Sopenharmony_ci.. |ssam_cdev_request_flags| replace:: :c:type:`enum ssam_cdev_request_flags <ssam_cdev_request_flags>`
562306a36Sopenharmony_ci.. |ssam_cdev_event| replace:: :c:type:`struct ssam_cdev_event <ssam_cdev_event>`
662306a36Sopenharmony_ci
762306a36Sopenharmony_ci==============================
862306a36Sopenharmony_ciUser-Space EC Interface (cdev)
962306a36Sopenharmony_ci==============================
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ciThe ``surface_aggregator_cdev`` module provides a misc-device for the SSAM
1262306a36Sopenharmony_cicontroller to allow for a (more or less) direct connection from user-space to
1362306a36Sopenharmony_cithe SAM EC. It is intended to be used for development and debugging, and
1462306a36Sopenharmony_citherefore should not be used or relied upon in any other way. Note that this
1562306a36Sopenharmony_cimodule is not loaded automatically, but instead must be loaded manually.
1662306a36Sopenharmony_ci
1762306a36Sopenharmony_ciThe provided interface is accessible through the ``/dev/surface/aggregator``
1862306a36Sopenharmony_cidevice-file. All functionality of this interface is provided via IOCTLs.
1962306a36Sopenharmony_ciThese IOCTLs and their respective input/output parameter structs are defined in
2062306a36Sopenharmony_ci``include/uapi/linux/surface_aggregator/cdev.h``.
2162306a36Sopenharmony_ci
2262306a36Sopenharmony_ciA small python library and scripts for accessing this interface can be found
2362306a36Sopenharmony_ciat https://github.com/linux-surface/surface-aggregator-module/tree/master/scripts/ssam.
2462306a36Sopenharmony_ci
2562306a36Sopenharmony_ci.. contents::
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_ci
2862306a36Sopenharmony_ciReceiving Events
2962306a36Sopenharmony_ci================
3062306a36Sopenharmony_ci
3162306a36Sopenharmony_ciEvents can be received by reading from the device-file. The are represented by
3262306a36Sopenharmony_cithe |ssam_cdev_event| datatype.
3362306a36Sopenharmony_ci
3462306a36Sopenharmony_ciBefore events are available to be read, however, the desired notifiers must be
3562306a36Sopenharmony_ciregistered via the ``SSAM_CDEV_NOTIF_REGISTER`` IOCTL. Notifiers are, in
3662306a36Sopenharmony_ciessence, callbacks, called when the EC sends an event. They are, in this
3762306a36Sopenharmony_ciinterface, associated with a specific target category and device-file-instance.
3862306a36Sopenharmony_ciThey forward any event of this category to the buffer of the corresponding
3962306a36Sopenharmony_ciinstance, from which it can then be read.
4062306a36Sopenharmony_ci
4162306a36Sopenharmony_ciNotifiers themselves do not enable events on the EC. Thus, it may additionally
4262306a36Sopenharmony_cibe necessary to enable events via the ``SSAM_CDEV_EVENT_ENABLE`` IOCTL. While
4362306a36Sopenharmony_cinotifiers work per-client (i.e. per-device-file-instance), events are enabled
4462306a36Sopenharmony_ciglobally, for the EC and all of its clients (regardless of userspace or
4562306a36Sopenharmony_cinon-userspace). The ``SSAM_CDEV_EVENT_ENABLE`` and ``SSAM_CDEV_EVENT_DISABLE``
4662306a36Sopenharmony_ciIOCTLs take care of reference counting the events, such that an event is
4762306a36Sopenharmony_cienabled as long as there is a client that has requested it.
4862306a36Sopenharmony_ci
4962306a36Sopenharmony_ciNote that enabled events are not automatically disabled once the client
5062306a36Sopenharmony_ciinstance is closed. Therefore any client process (or group of processes) should
5162306a36Sopenharmony_cibalance their event enable calls with the corresponding event disable calls. It
5262306a36Sopenharmony_ciis, however, perfectly valid to enable and disable events on different client
5362306a36Sopenharmony_ciinstances. For example, it is valid to set up notifiers and read events on
5462306a36Sopenharmony_ciclient instance ``A``, enable those events on instance ``B`` (note that these
5562306a36Sopenharmony_ciwill also be received by A since events are enabled/disabled globally), and
5662306a36Sopenharmony_ciafter no more events are desired, disable the previously enabled events via
5762306a36Sopenharmony_ciinstance ``C``.
5862306a36Sopenharmony_ci
5962306a36Sopenharmony_ci
6062306a36Sopenharmony_ciController IOCTLs
6162306a36Sopenharmony_ci=================
6262306a36Sopenharmony_ci
6362306a36Sopenharmony_ciThe following IOCTLs are provided:
6462306a36Sopenharmony_ci
6562306a36Sopenharmony_ci.. flat-table:: Controller IOCTLs
6662306a36Sopenharmony_ci   :widths: 1 1 1 1 4
6762306a36Sopenharmony_ci   :header-rows: 1
6862306a36Sopenharmony_ci
6962306a36Sopenharmony_ci   * - Type
7062306a36Sopenharmony_ci     - Number
7162306a36Sopenharmony_ci     - Direction
7262306a36Sopenharmony_ci     - Name
7362306a36Sopenharmony_ci     - Description
7462306a36Sopenharmony_ci
7562306a36Sopenharmony_ci   * - ``0xA5``
7662306a36Sopenharmony_ci     - ``1``
7762306a36Sopenharmony_ci     - ``WR``
7862306a36Sopenharmony_ci     - ``REQUEST``
7962306a36Sopenharmony_ci     - Perform synchronous SAM request.
8062306a36Sopenharmony_ci
8162306a36Sopenharmony_ci   * - ``0xA5``
8262306a36Sopenharmony_ci     - ``2``
8362306a36Sopenharmony_ci     - ``W``
8462306a36Sopenharmony_ci     - ``NOTIF_REGISTER``
8562306a36Sopenharmony_ci     - Register event notifier.
8662306a36Sopenharmony_ci
8762306a36Sopenharmony_ci   * - ``0xA5``
8862306a36Sopenharmony_ci     - ``3``
8962306a36Sopenharmony_ci     - ``W``
9062306a36Sopenharmony_ci     - ``NOTIF_UNREGISTER``
9162306a36Sopenharmony_ci     - Unregister event notifier.
9262306a36Sopenharmony_ci
9362306a36Sopenharmony_ci   * - ``0xA5``
9462306a36Sopenharmony_ci     - ``4``
9562306a36Sopenharmony_ci     - ``W``
9662306a36Sopenharmony_ci     - ``EVENT_ENABLE``
9762306a36Sopenharmony_ci     - Enable event source.
9862306a36Sopenharmony_ci
9962306a36Sopenharmony_ci   * - ``0xA5``
10062306a36Sopenharmony_ci     - ``5``
10162306a36Sopenharmony_ci     - ``W``
10262306a36Sopenharmony_ci     - ``EVENT_DISABLE``
10362306a36Sopenharmony_ci     - Disable event source.
10462306a36Sopenharmony_ci
10562306a36Sopenharmony_ci
10662306a36Sopenharmony_ci``SSAM_CDEV_REQUEST``
10762306a36Sopenharmony_ci---------------------
10862306a36Sopenharmony_ci
10962306a36Sopenharmony_ciDefined as ``_IOWR(0xA5, 1, struct ssam_cdev_request)``.
11062306a36Sopenharmony_ci
11162306a36Sopenharmony_ciExecutes a synchronous SAM request. The request specification is passed in
11262306a36Sopenharmony_cias argument of type |ssam_cdev_request|, which is then written to/modified
11362306a36Sopenharmony_ciby the IOCTL to return status and result of the request.
11462306a36Sopenharmony_ci
11562306a36Sopenharmony_ciRequest payload data must be allocated separately and is passed in via the
11662306a36Sopenharmony_ci``payload.data`` and ``payload.length`` members. If a response is required,
11762306a36Sopenharmony_cithe response buffer must be allocated by the caller and passed in via the
11862306a36Sopenharmony_ci``response.data`` member. The ``response.length`` member must be set to the
11962306a36Sopenharmony_cicapacity of this buffer, or if no response is required, zero. Upon
12062306a36Sopenharmony_cicompletion of the request, the call will write the response to the response
12162306a36Sopenharmony_cibuffer (if its capacity allows it) and overwrite the length field with the
12262306a36Sopenharmony_ciactual size of the response, in bytes.
12362306a36Sopenharmony_ci
12462306a36Sopenharmony_ciAdditionally, if the request has a response, this must be indicated via the
12562306a36Sopenharmony_cirequest flags, as is done with in-kernel requests. Request flags can be set
12662306a36Sopenharmony_civia the ``flags`` member and the values correspond to the values found in
12762306a36Sopenharmony_ci|ssam_cdev_request_flags|.
12862306a36Sopenharmony_ci
12962306a36Sopenharmony_ciFinally, the status of the request itself is returned in the ``status``
13062306a36Sopenharmony_cimember (a negative errno value indicating failure). Note that failure
13162306a36Sopenharmony_ciindication of the IOCTL is separated from failure indication of the request:
13262306a36Sopenharmony_ciThe IOCTL returns a negative status code if anything failed during setup of
13362306a36Sopenharmony_cithe request (``-EFAULT``) or if the provided argument or any of its fields
13462306a36Sopenharmony_ciare invalid (``-EINVAL``). In this case, the status value of the request
13562306a36Sopenharmony_ciargument may be set, providing more detail on what went wrong (e.g.
13662306a36Sopenharmony_ci``-ENOMEM`` for out-of-memory), but this value may also be zero. The IOCTL
13762306a36Sopenharmony_ciwill return with a zero status code in case the request has been set up,
13862306a36Sopenharmony_cisubmitted, and completed (i.e. handed back to user-space) successfully from
13962306a36Sopenharmony_ciinside the IOCTL, but the request ``status`` member may still be negative in
14062306a36Sopenharmony_cicase the actual execution of the request failed after it has been submitted.
14162306a36Sopenharmony_ci
14262306a36Sopenharmony_ciA full definition of the argument struct is provided below.
14362306a36Sopenharmony_ci
14462306a36Sopenharmony_ci``SSAM_CDEV_NOTIF_REGISTER``
14562306a36Sopenharmony_ci----------------------------
14662306a36Sopenharmony_ci
14762306a36Sopenharmony_ciDefined as ``_IOW(0xA5, 2, struct ssam_cdev_notifier_desc)``.
14862306a36Sopenharmony_ci
14962306a36Sopenharmony_ciRegister a notifier for the event target category specified in the given
15062306a36Sopenharmony_cinotifier description with the specified priority. Notifiers registration is
15162306a36Sopenharmony_cirequired to receive events, but does not enable events themselves. After a
15262306a36Sopenharmony_cinotifier for a specific target category has been registered, all events of that
15362306a36Sopenharmony_cicategory will be forwarded to the userspace client and can then be read from
15462306a36Sopenharmony_cithe device file instance. Note that events may have to be enabled, e.g. via the
15562306a36Sopenharmony_ci``SSAM_CDEV_EVENT_ENABLE`` IOCTL, before the EC will send them.
15662306a36Sopenharmony_ci
15762306a36Sopenharmony_ciOnly one notifier can be registered per target category and client instance. If
15862306a36Sopenharmony_cia notifier has already been registered, this IOCTL will fail with ``-EEXIST``.
15962306a36Sopenharmony_ci
16062306a36Sopenharmony_ciNotifiers will automatically be removed when the device file instance is
16162306a36Sopenharmony_ciclosed.
16262306a36Sopenharmony_ci
16362306a36Sopenharmony_ci``SSAM_CDEV_NOTIF_UNREGISTER``
16462306a36Sopenharmony_ci------------------------------
16562306a36Sopenharmony_ci
16662306a36Sopenharmony_ciDefined as ``_IOW(0xA5, 3, struct ssam_cdev_notifier_desc)``.
16762306a36Sopenharmony_ci
16862306a36Sopenharmony_ciUnregisters the notifier associated with the specified target category. The
16962306a36Sopenharmony_cipriority field will be ignored by this IOCTL. If no notifier has been
17062306a36Sopenharmony_ciregistered for this client instance and the given category, this IOCTL will
17162306a36Sopenharmony_cifail with ``-ENOENT``.
17262306a36Sopenharmony_ci
17362306a36Sopenharmony_ci``SSAM_CDEV_EVENT_ENABLE``
17462306a36Sopenharmony_ci--------------------------
17562306a36Sopenharmony_ci
17662306a36Sopenharmony_ciDefined as ``_IOW(0xA5, 4, struct ssam_cdev_event_desc)``.
17762306a36Sopenharmony_ci
17862306a36Sopenharmony_ciEnable the event associated with the given event descriptor.
17962306a36Sopenharmony_ci
18062306a36Sopenharmony_ciNote that this call will not register a notifier itself, it will only enable
18162306a36Sopenharmony_cievents on the controller. If you want to receive events by reading from the
18262306a36Sopenharmony_cidevice file, you will need to register the corresponding notifier(s) on that
18362306a36Sopenharmony_ciinstance.
18462306a36Sopenharmony_ci
18562306a36Sopenharmony_ciEvents are not automatically disabled when the device file is closed. This must
18662306a36Sopenharmony_cibe done manually, via a call to the ``SSAM_CDEV_EVENT_DISABLE`` IOCTL.
18762306a36Sopenharmony_ci
18862306a36Sopenharmony_ci``SSAM_CDEV_EVENT_DISABLE``
18962306a36Sopenharmony_ci---------------------------
19062306a36Sopenharmony_ci
19162306a36Sopenharmony_ciDefined as ``_IOW(0xA5, 5, struct ssam_cdev_event_desc)``.
19262306a36Sopenharmony_ci
19362306a36Sopenharmony_ciDisable the event associated with the given event descriptor.
19462306a36Sopenharmony_ci
19562306a36Sopenharmony_ciNote that this will not unregister any notifiers. Events may still be received
19662306a36Sopenharmony_ciand forwarded to user-space after this call. The only safe way of stopping
19762306a36Sopenharmony_cievents from being received is unregistering all previously registered
19862306a36Sopenharmony_cinotifiers.
19962306a36Sopenharmony_ci
20062306a36Sopenharmony_ci
20162306a36Sopenharmony_ciStructures and Enums
20262306a36Sopenharmony_ci====================
20362306a36Sopenharmony_ci
20462306a36Sopenharmony_ci.. kernel-doc:: include/uapi/linux/surface_aggregator/cdev.h
205