diff options
Diffstat (limited to 'Documentation/userspace-api/media/cec')
16 files changed, 2339 insertions, 0 deletions
diff --git a/Documentation/userspace-api/media/cec/cec-api.rst b/Documentation/userspace-api/media/cec/cec-api.rst new file mode 100644 index 000000000..4d229ed8a --- /dev/null +++ b/Documentation/userspace-api/media/cec/cec-api.rst @@ -0,0 +1,46 @@ +.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later +.. include:: <isonum.txt> + +.. _cec: + +######################################### +Part V - Consumer Electronics Control API +######################################### + +This part describes the CEC: Consumer Electronics Control + + +.. only:: html + + .. class:: toc-title + + Table of Contents + +.. toctree:: + :maxdepth: 5 + :numbered: + + cec-intro + cec-funcs + cec-pin-error-inj + cec-header + + +********************** +Revision and Copyright +********************** +Authors: + +- Verkuil, Hans <hverkuil-cisco@xs4all.nl> + + - Initial version. + +**Copyright** |copy| 2016 : Hans Verkuil + +**************** +Revision History +**************** + +:revision: 1.0.0 / 2016-03-17 (*hv*) + +Initial revision diff --git a/Documentation/userspace-api/media/cec/cec-func-close.rst b/Documentation/userspace-api/media/cec/cec-func-close.rst new file mode 100644 index 000000000..409e70a5f --- /dev/null +++ b/Documentation/userspace-api/media/cec/cec-func-close.rst @@ -0,0 +1,43 @@ +.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later +.. c:namespace:: CEC + +.. _cec-func-close: + +*********** +cec close() +*********** + +Name +==== + +cec-close - Close a cec device + +Synopsis +======== + +.. code-block:: c + + #include <unistd.h> + +.. c:function:: int close( int fd ) + +Arguments +========= + +``fd`` + File descriptor returned by :c:func:`open()`. + +Description +=========== + +Closes the cec device. Resources associated with the file descriptor are +freed. The device configuration remain unchanged. + +Return Value +============ + +:c:func:`close()` returns 0 on success. On error, -1 is returned, and +``errno`` is set appropriately. Possible error codes are: + +``EBADF`` + ``fd`` is not a valid open file descriptor. diff --git a/Documentation/userspace-api/media/cec/cec-func-ioctl.rst b/Documentation/userspace-api/media/cec/cec-func-ioctl.rst new file mode 100644 index 000000000..7c93f86de --- /dev/null +++ b/Documentation/userspace-api/media/cec/cec-func-ioctl.rst @@ -0,0 +1,63 @@ +.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later +.. c:namespace:: CEC + +.. _cec-func-ioctl: + +*********** +cec ioctl() +*********** + +Name +==== + +cec-ioctl - Control a cec device + +Synopsis +======== + +.. code-block:: c + + #include <sys/ioctl.h> + +``int ioctl(int fd, int request, void *argp)`` + +Arguments +========= + +``fd`` + File descriptor returned by :c:func:`open()`. + +``request`` + CEC ioctl request code as defined in the cec.h header file, for + example :ref:`CEC_ADAP_G_CAPS <CEC_ADAP_G_CAPS>`. + +``argp`` + Pointer to a request-specific structure. + +Description +=========== + +The :c:func:`ioctl()` function manipulates cec device parameters. The +argument ``fd`` must be an open file descriptor. + +The ioctl ``request`` code specifies the cec function to be called. It +has encoded in it whether the argument is an input, output or read/write +parameter, and the size of the argument ``argp`` in bytes. + +Macros and structures definitions specifying cec ioctl requests and +their parameters are located in the cec.h header file. All cec ioctl +requests, their respective function and parameters are specified in +:ref:`cec-user-func`. + +Return Value +============ + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes <gen-errors>` chapter. + +Request-specific error codes are listed in the individual requests +descriptions. + +When an ioctl that takes an output or read/write parameter fails, the +parameter remains unmodified. diff --git a/Documentation/userspace-api/media/cec/cec-func-open.rst b/Documentation/userspace-api/media/cec/cec-func-open.rst new file mode 100644 index 000000000..d86563a34 --- /dev/null +++ b/Documentation/userspace-api/media/cec/cec-func-open.rst @@ -0,0 +1,74 @@ +.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later +.. c:namespace:: CEC + +.. _cec-func-open: + +********** +cec open() +********** + +Name +==== + +cec-open - Open a cec device + +Synopsis +======== + +.. code-block:: c + + #include <fcntl.h> + +.. c:function:: int open( const char *device_name, int flags ) + +Arguments +========= + +``device_name`` + Device to be opened. + +``flags`` + Open flags. Access mode must be ``O_RDWR``. + + When the ``O_NONBLOCK`` flag is given, the + :ref:`CEC_RECEIVE <CEC_RECEIVE>` and :ref:`CEC_DQEVENT <CEC_DQEVENT>` ioctls + will return the ``EAGAIN`` error code when no message or event is available, and + ioctls :ref:`CEC_TRANSMIT <CEC_TRANSMIT>`, + :ref:`CEC_ADAP_S_PHYS_ADDR <CEC_ADAP_S_PHYS_ADDR>` and + :ref:`CEC_ADAP_S_LOG_ADDRS <CEC_ADAP_S_LOG_ADDRS>` + all return 0. + + Other flags have no effect. + +Description +=========== + +To open a cec device applications call :c:func:`open()` with the +desired device name. The function has no side effects; the device +configuration remain unchanged. + +When the device is opened in read-only mode, attempts to modify its +configuration will result in an error, and ``errno`` will be set to +EBADF. + +Return Value +============ + +:c:func:`open()` returns the new file descriptor on success. On error, +-1 is returned, and ``errno`` is set appropriately. Possible error codes +include: + +``EACCES`` + The requested access to the file is not allowed. + +``EMFILE`` + The process already has the maximum number of files open. + +``ENFILE`` + The system limit on the total number of open files has been reached. + +``ENOMEM`` + Insufficient kernel memory was available. + +``ENXIO`` + No device corresponding to this device special file exists. diff --git a/Documentation/userspace-api/media/cec/cec-func-poll.rst b/Documentation/userspace-api/media/cec/cec-func-poll.rst new file mode 100644 index 000000000..980bbfc0b --- /dev/null +++ b/Documentation/userspace-api/media/cec/cec-func-poll.rst @@ -0,0 +1,74 @@ +.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later +.. c:namespace:: CEC + +.. _cec-func-poll: + +********** +cec poll() +********** + +Name +==== + +cec-poll - Wait for some event on a file descriptor + +Synopsis +======== + +.. code-block:: c + + #include <sys/poll.h> + +.. c:function:: int poll( struct pollfd *ufds, unsigned int nfds, int timeout ) + +Arguments +========= + +``ufds`` + List of FD events to be watched + +``nfds`` + Number of FD events at the \*ufds array + +``timeout`` + Timeout to wait for events + +Description +=========== + +With the :c:func:`poll()` function applications can wait for CEC +events. + +On success :c:func:`poll()` returns the number of file descriptors +that have been selected (that is, file descriptors for which the +``revents`` field of the respective struct :c:type:`pollfd` +is non-zero). CEC devices set the ``POLLIN`` and ``POLLRDNORM`` flags in +the ``revents`` field if there are messages in the receive queue. If the +transmit queue has room for new messages, the ``POLLOUT`` and +``POLLWRNORM`` flags are set. If there are events in the event queue, +then the ``POLLPRI`` flag is set. When the function times out it returns +a value of zero, on failure it returns -1 and the ``errno`` variable is +set appropriately. + +For more details see the :c:func:`poll()` manual page. + +Return Value +============ + +On success, :c:func:`poll()` returns the number structures which have +non-zero ``revents`` fields, or zero if the call timed out. On error -1 +is returned, and the ``errno`` variable is set appropriately: + +``EBADF`` + One or more of the ``ufds`` members specify an invalid file + descriptor. + +``EFAULT`` + ``ufds`` references an inaccessible memory area. + +``EINTR`` + The call was interrupted by a signal. + +``EINVAL`` + The ``nfds`` value exceeds the ``RLIMIT_NOFILE`` value. Use + ``getrlimit()`` to obtain this value. diff --git a/Documentation/userspace-api/media/cec/cec-funcs.rst b/Documentation/userspace-api/media/cec/cec-funcs.rst new file mode 100644 index 000000000..aa6b790e8 --- /dev/null +++ b/Documentation/userspace-api/media/cec/cec-funcs.rst @@ -0,0 +1,23 @@ +.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later + +.. _cec-user-func: + +****************** +Function Reference +****************** + + +.. toctree:: + :maxdepth: 1 + + cec-func-open + cec-func-close + cec-func-ioctl + cec-func-poll + cec-ioc-adap-g-caps + cec-ioc-adap-g-log-addrs + cec-ioc-adap-g-phys-addr + cec-ioc-adap-g-conn-info + cec-ioc-dqevent + cec-ioc-g-mode + cec-ioc-receive diff --git a/Documentation/userspace-api/media/cec/cec-header.rst b/Documentation/userspace-api/media/cec/cec-header.rst new file mode 100644 index 000000000..d70736ac2 --- /dev/null +++ b/Documentation/userspace-api/media/cec/cec-header.rst @@ -0,0 +1,10 @@ +.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later + +.. _cec_header: + +*************** +CEC Header File +*************** + +.. kernel-include:: $BUILDDIR/cec.h.rst + diff --git a/Documentation/userspace-api/media/cec/cec-intro.rst b/Documentation/userspace-api/media/cec/cec-intro.rst new file mode 100644 index 000000000..1884ea090 --- /dev/null +++ b/Documentation/userspace-api/media/cec/cec-intro.rst @@ -0,0 +1,42 @@ +.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later + +.. _cec-intro: + +Introduction +============ + +HDMI connectors provide a single pin for use by the Consumer Electronics +Control protocol. This protocol allows different devices connected by an +HDMI cable to communicate. The protocol for CEC version 1.4 is defined +in supplements 1 (CEC) and 2 (HEAC or HDMI Ethernet and Audio Return +Channel) of the HDMI 1.4a (:ref:`hdmi`) specification and the +extensions added to CEC version 2.0 are defined in chapter 11 of the +HDMI 2.0 (:ref:`hdmi2`) specification. + +The bitrate is very slow (effectively no more than 36 bytes per second) +and is based on the ancient AV.link protocol used in old SCART +connectors. The protocol closely resembles a crazy Rube Goldberg +contraption and is an unholy mix of low and high level messages. Some +messages, especially those part of the HEAC protocol layered on top of +CEC, need to be handled by the kernel, others can be handled either by +the kernel or by userspace. + +In addition, CEC can be implemented in HDMI receivers, transmitters and +in USB devices that have an HDMI input and an HDMI output and that +control just the CEC pin. + +Drivers that support CEC will create a CEC device node (/dev/cecX) to +give userspace access to the CEC adapter. The +:ref:`CEC_ADAP_G_CAPS` ioctl will tell userspace what it is allowed to do. + +In order to check the support and test it, it is suggested to download +the `v4l-utils <https://git.linuxtv.org/v4l-utils.git/>`_ package. It +provides three tools to handle CEC: + +- cec-ctl: the Swiss army knife of CEC. Allows you to configure, transmit + and monitor CEC messages. + +- cec-compliance: does a CEC compliance test of a remote CEC device to + determine how compliant the CEC implementation is. + +- cec-follower: emulates a CEC follower. diff --git a/Documentation/userspace-api/media/cec/cec-ioc-adap-g-caps.rst b/Documentation/userspace-api/media/cec/cec-ioc-adap-g-caps.rst new file mode 100644 index 000000000..d5e014ce1 --- /dev/null +++ b/Documentation/userspace-api/media/cec/cec-ioc-adap-g-caps.rst @@ -0,0 +1,146 @@ +.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later +.. c:namespace:: CEC + +.. _CEC_ADAP_G_CAPS: + +********************* +ioctl CEC_ADAP_G_CAPS +********************* + +Name +==== + +CEC_ADAP_G_CAPS - Query device capabilities + +Synopsis +======== + +.. c:macro:: CEC_ADAP_G_CAPS + +``int ioctl(int fd, CEC_ADAP_G_CAPS, struct cec_caps *argp)`` + +Arguments +========= + +``fd`` + File descriptor returned by :c:func:`open()`. + +``argp`` + +Description +=========== + +All cec devices must support :ref:`ioctl CEC_ADAP_G_CAPS <CEC_ADAP_G_CAPS>`. To query +device information, applications call the ioctl with a pointer to a +struct :c:type:`cec_caps`. The driver fills the structure and +returns the information to the application. The ioctl never fails. + +.. tabularcolumns:: |p{1.2cm}|p{2.5cm}|p{13.6cm}| + +.. c:type:: cec_caps + +.. flat-table:: struct cec_caps + :header-rows: 0 + :stub-columns: 0 + :widths: 1 1 16 + + * - char + - ``driver[32]`` + - The name of the cec adapter driver. + * - char + - ``name[32]`` + - The name of this CEC adapter. The combination ``driver`` and + ``name`` must be unique. + * - __u32 + - ``available_log_addrs`` + - The maximum number of logical addresses that can be configured. + * - __u32 + - ``capabilities`` + - The capabilities of the CEC adapter, see + :ref:`cec-capabilities`. + * - __u32 + - ``version`` + - CEC Framework API version, formatted with the ``KERNEL_VERSION()`` + macro. + +.. tabularcolumns:: |p{4.4cm}|p{2.5cm}|p{10.4cm}| + +.. _cec-capabilities: + +.. flat-table:: CEC Capabilities Flags + :header-rows: 0 + :stub-columns: 0 + :widths: 3 1 8 + + * .. _`CEC-CAP-PHYS-ADDR`: + + - ``CEC_CAP_PHYS_ADDR`` + - 0x00000001 + - Userspace has to configure the physical address by calling + :ref:`ioctl CEC_ADAP_S_PHYS_ADDR <CEC_ADAP_S_PHYS_ADDR>`. If + this capability isn't set, then setting the physical address is + handled by the kernel whenever the EDID is set (for an HDMI + receiver) or read (for an HDMI transmitter). + * .. _`CEC-CAP-LOG-ADDRS`: + + - ``CEC_CAP_LOG_ADDRS`` + - 0x00000002 + - Userspace has to configure the logical addresses by calling + :ref:`ioctl CEC_ADAP_S_LOG_ADDRS <CEC_ADAP_S_LOG_ADDRS>`. If + this capability isn't set, then the kernel will have configured + this. + * .. _`CEC-CAP-TRANSMIT`: + + - ``CEC_CAP_TRANSMIT`` + - 0x00000004 + - Userspace can transmit CEC messages by calling + :ref:`ioctl CEC_TRANSMIT <CEC_TRANSMIT>`. This implies that + userspace can be a follower as well, since being able to transmit + messages is a prerequisite of becoming a follower. If this + capability isn't set, then the kernel will handle all CEC + transmits and process all CEC messages it receives. + * .. _`CEC-CAP-PASSTHROUGH`: + + - ``CEC_CAP_PASSTHROUGH`` + - 0x00000008 + - Userspace can use the passthrough mode by calling + :ref:`ioctl CEC_S_MODE <CEC_S_MODE>`. + * .. _`CEC-CAP-RC`: + + - ``CEC_CAP_RC`` + - 0x00000010 + - This adapter supports the remote control protocol. + * .. _`CEC-CAP-MONITOR-ALL`: + + - ``CEC_CAP_MONITOR_ALL`` + - 0x00000020 + - The CEC hardware can monitor all messages, not just directed and + broadcast messages. + * .. _`CEC-CAP-NEEDS-HPD`: + + - ``CEC_CAP_NEEDS_HPD`` + - 0x00000040 + - The CEC hardware is only active if the HDMI Hotplug Detect pin is + high. This makes it impossible to use CEC to wake up displays that + set the HPD pin low when in standby mode, but keep the CEC bus + alive. + * .. _`CEC-CAP-MONITOR-PIN`: + + - ``CEC_CAP_MONITOR_PIN`` + - 0x00000080 + - The CEC hardware can monitor CEC pin changes from low to high voltage + and vice versa. When in pin monitoring mode the application will + receive ``CEC_EVENT_PIN_CEC_LOW`` and ``CEC_EVENT_PIN_CEC_HIGH`` events. + * .. _`CEC-CAP-CONNECTOR-INFO`: + + - ``CEC_CAP_CONNECTOR_INFO`` + - 0x00000100 + - If this capability is set, then :ref:`CEC_ADAP_G_CONNECTOR_INFO` can + be used. + +Return Value +============ + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes <gen-errors>` chapter. diff --git a/Documentation/userspace-api/media/cec/cec-ioc-adap-g-conn-info.rst b/Documentation/userspace-api/media/cec/cec-ioc-adap-g-conn-info.rst new file mode 100644 index 000000000..0e1985573 --- /dev/null +++ b/Documentation/userspace-api/media/cec/cec-ioc-adap-g-conn-info.rst @@ -0,0 +1,106 @@ +.. SPDX-License-Identifier: GPL-2.0 +.. +.. Copyright 2019 Google LLC +.. +.. c:namespace:: CEC + +.. _CEC_ADAP_G_CONNECTOR_INFO: + +******************************* +ioctl CEC_ADAP_G_CONNECTOR_INFO +******************************* + +Name +==== + +CEC_ADAP_G_CONNECTOR_INFO - Query HDMI connector information + +Synopsis +======== + +.. c:macro:: CEC_ADAP_G_CONNECTOR_INFO + +``int ioctl(int fd, CEC_ADAP_G_CONNECTOR_INFO, struct cec_connector_info *argp)`` + +Arguments +========= + +``fd`` + File descriptor returned by :c:func:`open()`. + +``argp`` + +Description +=========== + +Using this ioctl an application can learn which HDMI connector this CEC +device corresponds to. While calling this ioctl the application should +provide a pointer to a cec_connector_info struct which will be populated +by the kernel with the info provided by the adapter's driver. This ioctl +is only available if the ``CEC_CAP_CONNECTOR_INFO`` capability is set. + +.. tabularcolumns:: |p{1.0cm}|p{4.4cm}|p{2.5cm}|p{9.2cm}| + +.. c:type:: cec_connector_info + +.. flat-table:: struct cec_connector_info + :header-rows: 0 + :stub-columns: 0 + :widths: 1 1 8 + + * - __u32 + - ``type`` + - The type of connector this adapter is associated with. + * - union { + - ``(anonymous)`` + * - ``struct cec_drm_connector_info`` + - drm + - :ref:`cec-drm-connector-info` + * - } + - + +.. tabularcolumns:: |p{4.4cm}|p{2.5cm}|p{10.4cm}| + +.. _connector-type: + +.. flat-table:: Connector types + :header-rows: 0 + :stub-columns: 0 + :widths: 3 1 8 + + * .. _`CEC-CONNECTOR-TYPE-NO-CONNECTOR`: + + - ``CEC_CONNECTOR_TYPE_NO_CONNECTOR`` + - 0 + - No connector is associated with the adapter/the information is not + provided by the driver. + * .. _`CEC-CONNECTOR-TYPE-DRM`: + + - ``CEC_CONNECTOR_TYPE_DRM`` + - 1 + - Indicates that a DRM connector is associated with this adapter. + Information about the connector can be found in + :ref:`cec-drm-connector-info`. + +.. tabularcolumns:: |p{4.4cm}|p{2.5cm}|p{10.4cm}| + +.. c:type:: cec_drm_connector_info + +.. _cec-drm-connector-info: + +.. flat-table:: struct cec_drm_connector_info + :header-rows: 0 + :stub-columns: 0 + :widths: 3 1 8 + + * .. _`CEC-DRM-CONNECTOR-TYPE-CARD-NO`: + + - __u32 + - ``card_no`` + - DRM card number: the number from a card's path, e.g. 0 in case of + /dev/card0. + * .. _`CEC-DRM-CONNECTOR-TYPE-CONNECTOR_ID`: + + - __u32 + - ``connector_id`` + - DRM connector ID. diff --git a/Documentation/userspace-api/media/cec/cec-ioc-adap-g-log-addrs.rst b/Documentation/userspace-api/media/cec/cec-ioc-adap-g-log-addrs.rst new file mode 100644 index 000000000..f3293a589 --- /dev/null +++ b/Documentation/userspace-api/media/cec/cec-ioc-adap-g-log-addrs.rst @@ -0,0 +1,367 @@ +.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later +.. c:namespace:: CEC + +.. _CEC_ADAP_LOG_ADDRS: +.. _CEC_ADAP_G_LOG_ADDRS: +.. _CEC_ADAP_S_LOG_ADDRS: + +**************************************************** +ioctls CEC_ADAP_G_LOG_ADDRS and CEC_ADAP_S_LOG_ADDRS +**************************************************** + +Name +==== + +CEC_ADAP_G_LOG_ADDRS, CEC_ADAP_S_LOG_ADDRS - Get or set the logical addresses + +Synopsis +======== + +.. c:macro:: CEC_ADAP_G_LOG_ADDRS + +``int ioctl(int fd, CEC_ADAP_G_LOG_ADDRS, struct cec_log_addrs *argp)`` + +.. c:macro:: CEC_ADAP_S_LOG_ADDRS + +``int ioctl(int fd, CEC_ADAP_S_LOG_ADDRS, struct cec_log_addrs *argp)`` + +Arguments +========= + +``fd`` + File descriptor returned by :c:func:`open()`. + +``argp`` + Pointer to struct :c:type:`cec_log_addrs`. + +Description +=========== + +To query the current CEC logical addresses, applications call +:ref:`ioctl CEC_ADAP_G_LOG_ADDRS <CEC_ADAP_G_LOG_ADDRS>` with a pointer to a +struct :c:type:`cec_log_addrs` where the driver stores the logical addresses. + +To set new logical addresses, applications fill in +struct :c:type:`cec_log_addrs` and call :ref:`ioctl CEC_ADAP_S_LOG_ADDRS <CEC_ADAP_S_LOG_ADDRS>` +with a pointer to this struct. The :ref:`ioctl CEC_ADAP_S_LOG_ADDRS <CEC_ADAP_S_LOG_ADDRS>` +is only available if ``CEC_CAP_LOG_ADDRS`` is set (the ``ENOTTY`` error code is +returned otherwise). The :ref:`ioctl CEC_ADAP_S_LOG_ADDRS <CEC_ADAP_S_LOG_ADDRS>` +can only be called by a file descriptor in initiator mode (see :ref:`CEC_S_MODE`), if not +the ``EBUSY`` error code will be returned. + +To clear existing logical addresses set ``num_log_addrs`` to 0. All other fields +will be ignored in that case. The adapter will go to the unconfigured state and the +``cec_version``, ``vendor_id`` and ``osd_name`` fields are all reset to their default +values (CEC version 2.0, no vendor ID and an empty OSD name). + +If the physical address is valid (see :ref:`ioctl CEC_ADAP_S_PHYS_ADDR <CEC_ADAP_S_PHYS_ADDR>`), +then this ioctl will block until all requested logical +addresses have been claimed. If the file descriptor is in non-blocking mode then it will +not wait for the logical addresses to be claimed, instead it just returns 0. + +A :ref:`CEC_EVENT_STATE_CHANGE <CEC-EVENT-STATE-CHANGE>` event is sent when the +logical addresses are claimed or cleared. + +Attempting to call :ref:`ioctl CEC_ADAP_S_LOG_ADDRS <CEC_ADAP_S_LOG_ADDRS>` when +logical address types are already defined will return with error ``EBUSY``. + +.. c:type:: cec_log_addrs + +.. tabularcolumns:: |p{1.0cm}|p{8.0cm}|p{8.0cm}| + +.. cssclass:: longtable + +.. flat-table:: struct cec_log_addrs + :header-rows: 0 + :stub-columns: 0 + :widths: 1 1 16 + + * - __u8 + - ``log_addr[CEC_MAX_LOG_ADDRS]`` + - The actual logical addresses that were claimed. This is set by the + driver. If no logical address could be claimed, then it is set to + ``CEC_LOG_ADDR_INVALID``. If this adapter is Unregistered, then + ``log_addr[0]`` is set to 0xf and all others to + ``CEC_LOG_ADDR_INVALID``. + * - __u16 + - ``log_addr_mask`` + - The bitmask of all logical addresses this adapter has claimed. If + this adapter is Unregistered then ``log_addr_mask`` sets bit 15 + and clears all other bits. If this adapter is not configured at + all, then ``log_addr_mask`` is set to 0. Set by the driver. + * - __u8 + - ``cec_version`` + - The CEC version that this adapter shall use. See + :ref:`cec-versions`. Used to implement the + ``CEC_MSG_CEC_VERSION`` and ``CEC_MSG_REPORT_FEATURES`` messages. + Note that :ref:`CEC_OP_CEC_VERSION_1_3A <CEC-OP-CEC-VERSION-1-3A>` is not allowed by the CEC + framework. + * - __u8 + - ``num_log_addrs`` + - Number of logical addresses to set up. Must be ≤ + ``available_log_addrs`` as returned by + :ref:`CEC_ADAP_G_CAPS`. All arrays in + this structure are only filled up to index + ``available_log_addrs``-1. The remaining array elements will be + ignored. Note that the CEC 2.0 standard allows for a maximum of 2 + logical addresses, although some hardware has support for more. + ``CEC_MAX_LOG_ADDRS`` is 4. The driver will return the actual + number of logical addresses it could claim, which may be less than + what was requested. If this field is set to 0, then the CEC + adapter shall clear all claimed logical addresses and all other + fields will be ignored. + * - __u32 + - ``vendor_id`` + - The vendor ID is a 24-bit number that identifies the specific + vendor or entity. Based on this ID vendor specific commands may be + defined. If you do not want a vendor ID then set it to + ``CEC_VENDOR_ID_NONE``. + * - __u32 + - ``flags`` + - Flags. See :ref:`cec-log-addrs-flags` for a list of available flags. + * - char + - ``osd_name[15]`` + - The On-Screen Display name as is returned by the + ``CEC_MSG_SET_OSD_NAME`` message. + * - __u8 + - ``primary_device_type[CEC_MAX_LOG_ADDRS]`` + - Primary device type for each logical address. See + :ref:`cec-prim-dev-types` for possible types. + * - __u8 + - ``log_addr_type[CEC_MAX_LOG_ADDRS]`` + - Logical address types. See :ref:`cec-log-addr-types` for + possible types. The driver will update this with the actual + logical address type that it claimed (e.g. it may have to fallback + to :ref:`CEC_LOG_ADDR_TYPE_UNREGISTERED <CEC-LOG-ADDR-TYPE-UNREGISTERED>`). + * - __u8 + - ``all_device_types[CEC_MAX_LOG_ADDRS]`` + - CEC 2.0 specific: the bit mask of all device types. See + :ref:`cec-all-dev-types-flags`. It is used in the CEC 2.0 + ``CEC_MSG_REPORT_FEATURES`` message. For CEC 1.4 you can either leave + this field to 0, or fill it in according to the CEC 2.0 guidelines to + give the CEC framework more information about the device type, even + though the framework won't use it directly in the CEC message. + * - __u8 + - ``features[CEC_MAX_LOG_ADDRS][12]`` + - Features for each logical address. It is used in the CEC 2.0 + ``CEC_MSG_REPORT_FEATURES`` message. The 12 bytes include both the + RC Profile and the Device Features. For CEC 1.4 you can either leave + this field to all 0, or fill it in according to the CEC 2.0 guidelines to + give the CEC framework more information about the device type, even + though the framework won't use it directly in the CEC message. + +.. tabularcolumns:: |p{7.8cm}|p{1.0cm}|p{8.5cm}| + +.. _cec-log-addrs-flags: + +.. flat-table:: Flags for struct cec_log_addrs + :header-rows: 0 + :stub-columns: 0 + :widths: 3 1 4 + + * .. _`CEC-LOG-ADDRS-FL-ALLOW-UNREG-FALLBACK`: + + - ``CEC_LOG_ADDRS_FL_ALLOW_UNREG_FALLBACK`` + - 1 + - By default if no logical address of the requested type can be claimed, then + it will go back to the unconfigured state. If this flag is set, then it will + fallback to the Unregistered logical address. Note that if the Unregistered + logical address was explicitly requested, then this flag has no effect. + * .. _`CEC-LOG-ADDRS-FL-ALLOW-RC-PASSTHRU`: + + - ``CEC_LOG_ADDRS_FL_ALLOW_RC_PASSTHRU`` + - 2 + - By default the ``CEC_MSG_USER_CONTROL_PRESSED`` and ``CEC_MSG_USER_CONTROL_RELEASED`` + messages are only passed on to the follower(s), if any. If this flag is set, + then these messages are also passed on to the remote control input subsystem + and will appear as keystrokes. This features needs to be enabled explicitly. + If CEC is used to enter e.g. passwords, then you may not want to enable this + to avoid trivial snooping of the keystrokes. + * .. _`CEC-LOG-ADDRS-FL-CDC-ONLY`: + + - ``CEC_LOG_ADDRS_FL_CDC_ONLY`` + - 4 + - If this flag is set, then the device is CDC-Only. CDC-Only CEC devices + are CEC devices that can only handle CDC messages. + + All other messages are ignored. + +.. tabularcolumns:: |p{7.8cm}|p{1.0cm}|p{8.5cm}| + +.. _cec-versions: + +.. flat-table:: CEC Versions + :header-rows: 0 + :stub-columns: 0 + :widths: 3 1 4 + + * .. _`CEC-OP-CEC-VERSION-1-3A`: + + - ``CEC_OP_CEC_VERSION_1_3A`` + - 4 + - CEC version according to the HDMI 1.3a standard. + * .. _`CEC-OP-CEC-VERSION-1-4B`: + + - ``CEC_OP_CEC_VERSION_1_4B`` + - 5 + - CEC version according to the HDMI 1.4b standard. + * .. _`CEC-OP-CEC-VERSION-2-0`: + + - ``CEC_OP_CEC_VERSION_2_0`` + - 6 + - CEC version according to the HDMI 2.0 standard. + +.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.5cm}| + +.. _cec-prim-dev-types: + +.. flat-table:: CEC Primary Device Types + :header-rows: 0 + :stub-columns: 0 + :widths: 3 1 4 + + * .. _`CEC-OP-PRIM-DEVTYPE-TV`: + + - ``CEC_OP_PRIM_DEVTYPE_TV`` + - 0 + - Use for a TV. + * .. _`CEC-OP-PRIM-DEVTYPE-RECORD`: + + - ``CEC_OP_PRIM_DEVTYPE_RECORD`` + - 1 + - Use for a recording device. + * .. _`CEC-OP-PRIM-DEVTYPE-TUNER`: + + - ``CEC_OP_PRIM_DEVTYPE_TUNER`` + - 3 + - Use for a device with a tuner. + * .. _`CEC-OP-PRIM-DEVTYPE-PLAYBACK`: + + - ``CEC_OP_PRIM_DEVTYPE_PLAYBACK`` + - 4 + - Use for a playback device. + * .. _`CEC-OP-PRIM-DEVTYPE-AUDIOSYSTEM`: + + - ``CEC_OP_PRIM_DEVTYPE_AUDIOSYSTEM`` + - 5 + - Use for an audio system (e.g. an audio/video receiver). + * .. _`CEC-OP-PRIM-DEVTYPE-SWITCH`: + + - ``CEC_OP_PRIM_DEVTYPE_SWITCH`` + - 6 + - Use for a CEC switch. + * .. _`CEC-OP-PRIM-DEVTYPE-VIDEOPROC`: + + - ``CEC_OP_PRIM_DEVTYPE_VIDEOPROC`` + - 7 + - Use for a video processor device. + +.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.5cm}| + +.. _cec-log-addr-types: + +.. flat-table:: CEC Logical Address Types + :header-rows: 0 + :stub-columns: 0 + :widths: 3 1 16 + + * .. _`CEC-LOG-ADDR-TYPE-TV`: + + - ``CEC_LOG_ADDR_TYPE_TV`` + - 0 + - Use for a TV. + * .. _`CEC-LOG-ADDR-TYPE-RECORD`: + + - ``CEC_LOG_ADDR_TYPE_RECORD`` + - 1 + - Use for a recording device. + * .. _`CEC-LOG-ADDR-TYPE-TUNER`: + + - ``CEC_LOG_ADDR_TYPE_TUNER`` + - 2 + - Use for a tuner device. + * .. _`CEC-LOG-ADDR-TYPE-PLAYBACK`: + + - ``CEC_LOG_ADDR_TYPE_PLAYBACK`` + - 3 + - Use for a playback device. + * .. _`CEC-LOG-ADDR-TYPE-AUDIOSYSTEM`: + + - ``CEC_LOG_ADDR_TYPE_AUDIOSYSTEM`` + - 4 + - Use for an audio system device. + * .. _`CEC-LOG-ADDR-TYPE-SPECIFIC`: + + - ``CEC_LOG_ADDR_TYPE_SPECIFIC`` + - 5 + - Use for a second TV or for a video processor device. + * .. _`CEC-LOG-ADDR-TYPE-UNREGISTERED`: + + - ``CEC_LOG_ADDR_TYPE_UNREGISTERED`` + - 6 + - Use this if you just want to remain unregistered. Used for pure + CEC switches or CDC-only devices (CDC: Capability Discovery and + Control). + + +.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.5cm}| + +.. _cec-all-dev-types-flags: + +.. flat-table:: CEC All Device Types Flags + :header-rows: 0 + :stub-columns: 0 + :widths: 3 1 4 + + * .. _`CEC-OP-ALL-DEVTYPE-TV`: + + - ``CEC_OP_ALL_DEVTYPE_TV`` + - 0x80 + - This supports the TV type. + * .. _`CEC-OP-ALL-DEVTYPE-RECORD`: + + - ``CEC_OP_ALL_DEVTYPE_RECORD`` + - 0x40 + - This supports the Recording type. + * .. _`CEC-OP-ALL-DEVTYPE-TUNER`: + + - ``CEC_OP_ALL_DEVTYPE_TUNER`` + - 0x20 + - This supports the Tuner type. + * .. _`CEC-OP-ALL-DEVTYPE-PLAYBACK`: + + - ``CEC_OP_ALL_DEVTYPE_PLAYBACK`` + - 0x10 + - This supports the Playback type. + * .. _`CEC-OP-ALL-DEVTYPE-AUDIOSYSTEM`: + + - ``CEC_OP_ALL_DEVTYPE_AUDIOSYSTEM`` + - 0x08 + - This supports the Audio System type. + * .. _`CEC-OP-ALL-DEVTYPE-SWITCH`: + + - ``CEC_OP_ALL_DEVTYPE_SWITCH`` + - 0x04 + - This supports the CEC Switch or Video Processing type. + + +Return Value +============ + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes <gen-errors>` chapter. + +The :ref:`ioctl CEC_ADAP_S_LOG_ADDRS <CEC_ADAP_S_LOG_ADDRS>` can return the following +error codes: + +ENOTTY + The ``CEC_CAP_LOG_ADDRS`` capability wasn't set, so this ioctl is not supported. + +EBUSY + The CEC adapter is currently configuring itself, or it is already configured and + ``num_log_addrs`` is non-zero, or another filehandle is in exclusive follower or + initiator mode, or the filehandle is in mode ``CEC_MODE_NO_INITIATOR``. + +EINVAL + The contents of struct :c:type:`cec_log_addrs` is invalid. diff --git a/Documentation/userspace-api/media/cec/cec-ioc-adap-g-phys-addr.rst b/Documentation/userspace-api/media/cec/cec-ioc-adap-g-phys-addr.rst new file mode 100644 index 000000000..fb22f6894 --- /dev/null +++ b/Documentation/userspace-api/media/cec/cec-ioc-adap-g-phys-addr.rst @@ -0,0 +1,94 @@ +.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later +.. c:namespace:: CEC + +.. _CEC_ADAP_PHYS_ADDR: +.. _CEC_ADAP_G_PHYS_ADDR: +.. _CEC_ADAP_S_PHYS_ADDR: + +**************************************************** +ioctls CEC_ADAP_G_PHYS_ADDR and CEC_ADAP_S_PHYS_ADDR +**************************************************** + +Name +==== + +CEC_ADAP_G_PHYS_ADDR, CEC_ADAP_S_PHYS_ADDR - Get or set the physical address + +Synopsis +======== + +.. c:macro:: CEC_ADAP_G_PHYS_ADDR + +``int ioctl(int fd, CEC_ADAP_G_PHYS_ADDR, __u16 *argp)`` + +.. c:macro:: CEC_ADAP_S_PHYS_ADDR + +``int ioctl(int fd, CEC_ADAP_S_PHYS_ADDR, __u16 *argp)`` + +Arguments +========= + +``fd`` + File descriptor returned by :c:func:`open()`. + +``argp`` + Pointer to the CEC address. + +Description +=========== + +To query the current physical address applications call +:ref:`ioctl CEC_ADAP_G_PHYS_ADDR <CEC_ADAP_G_PHYS_ADDR>` with a pointer to a __u16 where the +driver stores the physical address. + +To set a new physical address applications store the physical address in +a __u16 and call :ref:`ioctl CEC_ADAP_S_PHYS_ADDR <CEC_ADAP_S_PHYS_ADDR>` with a pointer to +this integer. The :ref:`ioctl CEC_ADAP_S_PHYS_ADDR <CEC_ADAP_S_PHYS_ADDR>` is only available if +``CEC_CAP_PHYS_ADDR`` is set (the ``ENOTTY`` error code will be returned +otherwise). The :ref:`ioctl CEC_ADAP_S_PHYS_ADDR <CEC_ADAP_S_PHYS_ADDR>` can only be called +by a file descriptor in initiator mode (see :ref:`CEC_S_MODE`), if not +the ``EBUSY`` error code will be returned. + +To clear an existing physical address use ``CEC_PHYS_ADDR_INVALID``. +The adapter will go to the unconfigured state. + +If logical address types have been defined (see :ref:`ioctl CEC_ADAP_S_LOG_ADDRS <CEC_ADAP_S_LOG_ADDRS>`), +then this ioctl will block until all +requested logical addresses have been claimed. If the file descriptor is in non-blocking mode +then it will not wait for the logical addresses to be claimed, instead it just returns 0. + +A :ref:`CEC_EVENT_STATE_CHANGE <CEC-EVENT-STATE-CHANGE>` event is sent when the physical address +changes. + +The physical address is a 16-bit number where each group of 4 bits +represent a digit of the physical address a.b.c.d where the most +significant 4 bits represent 'a'. The CEC root device (usually the TV) +has address 0.0.0.0. Every device that is hooked up to an input of the +TV has address a.0.0.0 (where 'a' is ≥ 1), devices hooked up to those in +turn have addresses a.b.0.0, etc. So a topology of up to 5 devices deep +is supported. The physical address a device shall use is stored in the +EDID of the sink. + +For example, the EDID for each HDMI input of the TV will have a +different physical address of the form a.0.0.0 that the sources will +read out and use as their physical address. + +Return Value +============ + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes <gen-errors>` chapter. + +The :ref:`ioctl CEC_ADAP_S_PHYS_ADDR <CEC_ADAP_S_PHYS_ADDR>` can return the following +error codes: + +ENOTTY + The ``CEC_CAP_PHYS_ADDR`` capability wasn't set, so this ioctl is not supported. + +EBUSY + Another filehandle is in exclusive follower or initiator mode, or the filehandle + is in mode ``CEC_MODE_NO_INITIATOR``. + +EINVAL + The physical address is malformed. diff --git a/Documentation/userspace-api/media/cec/cec-ioc-dqevent.rst b/Documentation/userspace-api/media/cec/cec-ioc-dqevent.rst new file mode 100644 index 000000000..71d6a9e81 --- /dev/null +++ b/Documentation/userspace-api/media/cec/cec-ioc-dqevent.rst @@ -0,0 +1,245 @@ +.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later +.. c:namespace:: CEC + +.. _CEC_DQEVENT: + +***************** +ioctl CEC_DQEVENT +***************** + +Name +==== + +CEC_DQEVENT - Dequeue a CEC event + +Synopsis +======== + +.. c:macro:: CEC_DQEVENT + +``int ioctl(int fd, CEC_DQEVENT, struct cec_event *argp)`` + +Arguments +========= + +``fd`` + File descriptor returned by :c:func:`open()`. + +``argp`` + +Description +=========== + +CEC devices can send asynchronous events. These can be retrieved by +calling :c:func:`CEC_DQEVENT`. If the file descriptor is in +non-blocking mode and no event is pending, then it will return -1 and +set errno to the ``EAGAIN`` error code. + +The internal event queues are per-filehandle and per-event type. If +there is no more room in a queue then the last event is overwritten with +the new one. This means that intermediate results can be thrown away but +that the latest event is always available. This also means that is it +possible to read two successive events that have the same value (e.g. +two :ref:`CEC_EVENT_STATE_CHANGE <CEC-EVENT-STATE-CHANGE>` events with +the same state). In that case the intermediate state changes were lost but +it is guaranteed that the state did change in between the two events. + +.. tabularcolumns:: |p{1.2cm}|p{2.9cm}|p{13.2cm}| + +.. c:type:: cec_event_state_change + +.. flat-table:: struct cec_event_state_change + :header-rows: 0 + :stub-columns: 0 + :widths: 1 1 8 + + * - __u16 + - ``phys_addr`` + - The current physical address. This is ``CEC_PHYS_ADDR_INVALID`` if no + valid physical address is set. + * - __u16 + - ``log_addr_mask`` + - The current set of claimed logical addresses. This is 0 if no logical + addresses are claimed or if ``phys_addr`` is ``CEC_PHYS_ADDR_INVALID``. + If bit 15 is set (``1 << CEC_LOG_ADDR_UNREGISTERED``) then this device + has the unregistered logical address. In that case all other bits are 0. + * - __u16 + - ``have_conn_info`` + - If non-zero, then HDMI connector information is available. + This field is only valid if ``CEC_CAP_CONNECTOR_INFO`` is set. If that + capability is set and ``have_conn_info`` is zero, then that indicates + that the HDMI connector device is not instantiated, either because + the HDMI driver is still configuring the device or because the HDMI + device was unbound. + +.. c:type:: cec_event_lost_msgs + +.. tabularcolumns:: |p{1.0cm}|p{2.0cm}|p{14.3cm}| + +.. flat-table:: struct cec_event_lost_msgs + :header-rows: 0 + :stub-columns: 0 + :widths: 1 1 16 + + * - __u32 + - ``lost_msgs`` + - Set to the number of lost messages since the filehandle was opened + or since the last time this event was dequeued for this + filehandle. The messages lost are the oldest messages. So when a + new message arrives and there is no more room, then the oldest + message is discarded to make room for the new one. The internal + size of the message queue guarantees that all messages received in + the last two seconds will be stored. Since messages should be + replied to within a second according to the CEC specification, + this is more than enough. + +.. tabularcolumns:: |p{1.0cm}|p{4.4cm}|p{2.5cm}|p{9.2cm}| + +.. c:type:: cec_event + +.. flat-table:: struct cec_event + :header-rows: 0 + :stub-columns: 0 + :widths: 1 1 8 + + * - __u64 + - ``ts`` + - Timestamp of the event in ns. + + The timestamp has been taken from the ``CLOCK_MONOTONIC`` clock. + + To access the same clock from userspace use :c:func:`clock_gettime`. + * - __u32 + - ``event`` + - The CEC event type, see :ref:`cec-events`. + * - __u32 + - ``flags`` + - Event flags, see :ref:`cec-event-flags`. + * - union { + - (anonymous) + * - struct cec_event_state_change + - ``state_change`` + - The new adapter state as sent by the :ref:`CEC_EVENT_STATE_CHANGE <CEC-EVENT-STATE-CHANGE>` + event. + * - struct cec_event_lost_msgs + - ``lost_msgs`` + - The number of lost messages as sent by the :ref:`CEC_EVENT_LOST_MSGS <CEC-EVENT-LOST-MSGS>` + event. + * - } + - + +.. tabularcolumns:: |p{5.6cm}|p{0.9cm}|p{10.8cm}| + +.. _cec-events: + +.. flat-table:: CEC Events Types + :header-rows: 0 + :stub-columns: 0 + :widths: 3 1 16 + + * .. _`CEC-EVENT-STATE-CHANGE`: + + - ``CEC_EVENT_STATE_CHANGE`` + - 1 + - Generated when the CEC Adapter's state changes. When open() is + called an initial event will be generated for that filehandle with + the CEC Adapter's state at that time. + * .. _`CEC-EVENT-LOST-MSGS`: + + - ``CEC_EVENT_LOST_MSGS`` + - 2 + - Generated if one or more CEC messages were lost because the + application didn't dequeue CEC messages fast enough. + * .. _`CEC-EVENT-PIN-CEC-LOW`: + + - ``CEC_EVENT_PIN_CEC_LOW`` + - 3 + - Generated if the CEC pin goes from a high voltage to a low voltage. + Only applies to adapters that have the ``CEC_CAP_MONITOR_PIN`` + capability set. + * .. _`CEC-EVENT-PIN-CEC-HIGH`: + + - ``CEC_EVENT_PIN_CEC_HIGH`` + - 4 + - Generated if the CEC pin goes from a low voltage to a high voltage. + Only applies to adapters that have the ``CEC_CAP_MONITOR_PIN`` + capability set. + * .. _`CEC-EVENT-PIN-HPD-LOW`: + + - ``CEC_EVENT_PIN_HPD_LOW`` + - 5 + - Generated if the HPD pin goes from a high voltage to a low voltage. + Only applies to adapters that have the ``CEC_CAP_MONITOR_PIN`` + capability set. When open() is called, the HPD pin can be read and + if the HPD is low, then an initial event will be generated for that + filehandle. + * .. _`CEC-EVENT-PIN-HPD-HIGH`: + + - ``CEC_EVENT_PIN_HPD_HIGH`` + - 6 + - Generated if the HPD pin goes from a low voltage to a high voltage. + Only applies to adapters that have the ``CEC_CAP_MONITOR_PIN`` + capability set. When open() is called, the HPD pin can be read and + if the HPD is high, then an initial event will be generated for that + filehandle. + * .. _`CEC-EVENT-PIN-5V-LOW`: + + - ``CEC_EVENT_PIN_5V_LOW`` + - 6 + - Generated if the 5V pin goes from a high voltage to a low voltage. + Only applies to adapters that have the ``CEC_CAP_MONITOR_PIN`` + capability set. When open() is called, the 5V pin can be read and + if the 5V is low, then an initial event will be generated for that + filehandle. + * .. _`CEC-EVENT-PIN-5V-HIGH`: + + - ``CEC_EVENT_PIN_5V_HIGH`` + - 7 + - Generated if the 5V pin goes from a low voltage to a high voltage. + Only applies to adapters that have the ``CEC_CAP_MONITOR_PIN`` + capability set. When open() is called, the 5V pin can be read and + if the 5V is high, then an initial event will be generated for that + filehandle. + +.. tabularcolumns:: |p{6.0cm}|p{0.6cm}|p{10.7cm}| + +.. _cec-event-flags: + +.. flat-table:: CEC Event Flags + :header-rows: 0 + :stub-columns: 0 + :widths: 3 1 8 + + * .. _`CEC-EVENT-FL-INITIAL-STATE`: + + - ``CEC_EVENT_FL_INITIAL_STATE`` + - 1 + - Set for the initial events that are generated when the device is + opened. See the table above for which events do this. This allows + applications to learn the initial state of the CEC adapter at + open() time. + * .. _`CEC-EVENT-FL-DROPPED-EVENTS`: + + - ``CEC_EVENT_FL_DROPPED_EVENTS`` + - 2 + - Set if one or more events of the given event type have been dropped. + This is an indication that the application cannot keep up. + + +Return Value +============ + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes <gen-errors>` chapter. + +The :ref:`ioctl CEC_DQEVENT <CEC_DQEVENT>` can return the following +error codes: + +EAGAIN + This is returned when the filehandle is in non-blocking mode and there + are no pending events. + +ERESTARTSYS + An interrupt (e.g. Ctrl-C) arrived while in blocking mode waiting for + events to arrive. diff --git a/Documentation/userspace-api/media/cec/cec-ioc-g-mode.rst b/Documentation/userspace-api/media/cec/cec-ioc-g-mode.rst new file mode 100644 index 000000000..5fe105a13 --- /dev/null +++ b/Documentation/userspace-api/media/cec/cec-ioc-g-mode.rst @@ -0,0 +1,294 @@ +.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later +.. c:namespace:: CEC + +.. _CEC_MODE: +.. _CEC_G_MODE: +.. _CEC_S_MODE: + +******************************** +ioctls CEC_G_MODE and CEC_S_MODE +******************************** + +CEC_G_MODE, CEC_S_MODE - Get or set exclusive use of the CEC adapter + +Synopsis +======== + +.. c:macro:: CEC_G_MODE + +``int ioctl(int fd, CEC_G_MODE, __u32 *argp)`` + +.. c:macro:: CEC_S_MODE + +``int ioctl(int fd, CEC_S_MODE, __u32 *argp)`` + +Arguments +========= + +``fd`` + File descriptor returned by :c:func:`open()`. + +``argp`` + Pointer to CEC mode. + +Description +=========== + +By default any filehandle can use :ref:`CEC_TRANSMIT`, but in order to prevent +applications from stepping on each others toes it must be possible to +obtain exclusive access to the CEC adapter. This ioctl sets the +filehandle to initiator and/or follower mode which can be exclusive +depending on the chosen mode. The initiator is the filehandle that is +used to initiate messages, i.e. it commands other CEC devices. The +follower is the filehandle that receives messages sent to the CEC +adapter and processes them. The same filehandle can be both initiator +and follower, or this role can be taken by two different filehandles. + +When a CEC message is received, then the CEC framework will decide how +it will be processed. If the message is a reply to an earlier +transmitted message, then the reply is sent back to the filehandle that +is waiting for it. In addition the CEC framework will process it. + +If the message is not a reply, then the CEC framework will process it +first. If there is no follower, then the message is just discarded and a +feature abort is sent back to the initiator if the framework couldn't +process it. If there is a follower, then the message is passed on to the +follower who will use :ref:`ioctl CEC_RECEIVE <CEC_RECEIVE>` to dequeue +the new message. The framework expects the follower to make the right +decisions. + +The CEC framework will process core messages unless requested otherwise +by the follower. The follower can enable the passthrough mode. In that +case, the CEC framework will pass on most core messages without +processing them and the follower will have to implement those messages. +There are some messages that the core will always process, regardless of +the passthrough mode. See :ref:`cec-core-processing` for details. + +If there is no initiator, then any CEC filehandle can use +:ref:`ioctl CEC_TRANSMIT <CEC_TRANSMIT>`. If there is an exclusive +initiator then only that initiator can call +:ref:`CEC_TRANSMIT`. The follower can of course +always call :ref:`ioctl CEC_TRANSMIT <CEC_TRANSMIT>`. + +Available initiator modes are: + +.. tabularcolumns:: |p{5.6cm}|p{0.9cm}|p{10.8cm}| + +.. _cec-mode-initiator_e: + +.. flat-table:: Initiator Modes + :header-rows: 0 + :stub-columns: 0 + :widths: 3 1 16 + + * .. _`CEC-MODE-NO-INITIATOR`: + + - ``CEC_MODE_NO_INITIATOR`` + - 0x0 + - This is not an initiator, i.e. it cannot transmit CEC messages or + make any other changes to the CEC adapter. + * .. _`CEC-MODE-INITIATOR`: + + - ``CEC_MODE_INITIATOR`` + - 0x1 + - This is an initiator (the default when the device is opened) and + it can transmit CEC messages and make changes to the CEC adapter, + unless there is an exclusive initiator. + * .. _`CEC-MODE-EXCL-INITIATOR`: + + - ``CEC_MODE_EXCL_INITIATOR`` + - 0x2 + - This is an exclusive initiator and this file descriptor is the + only one that can transmit CEC messages and make changes to the + CEC adapter. If someone else is already the exclusive initiator + then an attempt to become one will return the ``EBUSY`` error code + error. + +Available follower modes are: + +.. tabularcolumns:: |p{6.6cm}|p{0.9cm}|p{9.8cm}| + +.. _cec-mode-follower_e: + +.. cssclass:: longtable + +.. flat-table:: Follower Modes + :header-rows: 0 + :stub-columns: 0 + :widths: 3 1 16 + + * .. _`CEC-MODE-NO-FOLLOWER`: + + - ``CEC_MODE_NO_FOLLOWER`` + - 0x00 + - This is not a follower (the default when the device is opened). + * .. _`CEC-MODE-FOLLOWER`: + + - ``CEC_MODE_FOLLOWER`` + - 0x10 + - This is a follower and it will receive CEC messages unless there + is an exclusive follower. You cannot become a follower if + :ref:`CEC_CAP_TRANSMIT <CEC-CAP-TRANSMIT>` is not set or if :ref:`CEC_MODE_NO_INITIATOR <CEC-MODE-NO-INITIATOR>` + was specified, the ``EINVAL`` error code is returned in that case. + * .. _`CEC-MODE-EXCL-FOLLOWER`: + + - ``CEC_MODE_EXCL_FOLLOWER`` + - 0x20 + - This is an exclusive follower and only this file descriptor will + receive CEC messages for processing. If someone else is already + the exclusive follower then an attempt to become one will return + the ``EBUSY`` error code. You cannot become a follower if + :ref:`CEC_CAP_TRANSMIT <CEC-CAP-TRANSMIT>` is not set or if :ref:`CEC_MODE_NO_INITIATOR <CEC-MODE-NO-INITIATOR>` + was specified, the ``EINVAL`` error code is returned in that case. + * .. _`CEC-MODE-EXCL-FOLLOWER-PASSTHRU`: + + - ``CEC_MODE_EXCL_FOLLOWER_PASSTHRU`` + - 0x30 + - This is an exclusive follower and only this file descriptor will + receive CEC messages for processing. In addition it will put the + CEC device into passthrough mode, allowing the exclusive follower + to handle most core messages instead of relying on the CEC + framework for that. If someone else is already the exclusive + follower then an attempt to become one will return the ``EBUSY`` error + code. You cannot become a follower if :ref:`CEC_CAP_TRANSMIT <CEC-CAP-TRANSMIT>` + is not set or if :ref:`CEC_MODE_NO_INITIATOR <CEC-MODE-NO-INITIATOR>` was specified, + the ``EINVAL`` error code is returned in that case. + * .. _`CEC-MODE-MONITOR-PIN`: + + - ``CEC_MODE_MONITOR_PIN`` + - 0xd0 + - Put the file descriptor into pin monitoring mode. Can only be used in + combination with :ref:`CEC_MODE_NO_INITIATOR <CEC-MODE-NO-INITIATOR>`, + otherwise the ``EINVAL`` error code will be returned. + This mode requires that the :ref:`CEC_CAP_MONITOR_PIN <CEC-CAP-MONITOR-PIN>` + capability is set, otherwise the ``EINVAL`` error code is returned. + While in pin monitoring mode this file descriptor can receive the + ``CEC_EVENT_PIN_CEC_LOW`` and ``CEC_EVENT_PIN_CEC_HIGH`` events to see the + low-level CEC pin transitions. This is very useful for debugging. + This mode is only allowed if the process has the ``CAP_NET_ADMIN`` + capability. If that is not set, then the ``EPERM`` error code is returned. + * .. _`CEC-MODE-MONITOR`: + + - ``CEC_MODE_MONITOR`` + - 0xe0 + - Put the file descriptor into monitor mode. Can only be used in + combination with :ref:`CEC_MODE_NO_INITIATOR <CEC-MODE-NO-INITIATOR>`, + otherwise the ``EINVAL`` error code will be returned. + In monitor mode all messages this CEC + device transmits and all messages it receives (both broadcast + messages and directed messages for one its logical addresses) will + be reported. This is very useful for debugging. This is only + allowed if the process has the ``CAP_NET_ADMIN`` capability. If + that is not set, then the ``EPERM`` error code is returned. + * .. _`CEC-MODE-MONITOR-ALL`: + + - ``CEC_MODE_MONITOR_ALL`` + - 0xf0 + - Put the file descriptor into 'monitor all' mode. Can only be used + in combination with :ref:`CEC_MODE_NO_INITIATOR <CEC-MODE-NO-INITIATOR>`, otherwise + the ``EINVAL`` error code will be returned. In 'monitor all' mode all messages + this CEC device transmits and all messages it receives, including + directed messages for other CEC devices, will be reported. This is + very useful for debugging, but not all devices support this. This + mode requires that the :ref:`CEC_CAP_MONITOR_ALL <CEC-CAP-MONITOR-ALL>` capability is set, + otherwise the ``EINVAL`` error code is returned. This is only allowed if + the process has the ``CAP_NET_ADMIN`` capability. If that is not + set, then the ``EPERM`` error code is returned. + +Core message processing details: + +.. tabularcolumns:: |p{6.6cm}|p{10.9cm}| + +.. _cec-core-processing: + +.. flat-table:: Core Message Processing + :header-rows: 0 + :stub-columns: 0 + :widths: 1 8 + + * .. _`CEC-MSG-GET-CEC-VERSION`: + + - ``CEC_MSG_GET_CEC_VERSION`` + - The core will return the CEC version that was set with + :ref:`ioctl CEC_ADAP_S_LOG_ADDRS <CEC_ADAP_S_LOG_ADDRS>`, + except when in passthrough mode. In passthrough mode the core + does nothing and this message has to be handled by a follower + instead. + * .. _`CEC-MSG-GIVE-DEVICE-VENDOR-ID`: + + - ``CEC_MSG_GIVE_DEVICE_VENDOR_ID`` + - The core will return the vendor ID that was set with + :ref:`ioctl CEC_ADAP_S_LOG_ADDRS <CEC_ADAP_S_LOG_ADDRS>`, + except when in passthrough mode. In passthrough mode the core + does nothing and this message has to be handled by a follower + instead. + * .. _`CEC-MSG-ABORT`: + + - ``CEC_MSG_ABORT`` + - The core will return a Feature Abort message with reason + 'Feature Refused' as per the specification, except when in + passthrough mode. In passthrough mode the core does nothing + and this message has to be handled by a follower instead. + * .. _`CEC-MSG-GIVE-PHYSICAL-ADDR`: + + - ``CEC_MSG_GIVE_PHYSICAL_ADDR`` + - The core will report the current physical address, except when + in passthrough mode. In passthrough mode the core does nothing + and this message has to be handled by a follower instead. + * .. _`CEC-MSG-GIVE-OSD-NAME`: + + - ``CEC_MSG_GIVE_OSD_NAME`` + - The core will report the current OSD name that was set with + :ref:`ioctl CEC_ADAP_S_LOG_ADDRS <CEC_ADAP_S_LOG_ADDRS>`, + except when in passthrough mode. In passthrough mode the core + does nothing and this message has to be handled by a follower + instead. + * .. _`CEC-MSG-GIVE-FEATURES`: + + - ``CEC_MSG_GIVE_FEATURES`` + - The core will do nothing if the CEC version is older than 2.0, + otherwise it will report the current features that were set with + :ref:`ioctl CEC_ADAP_S_LOG_ADDRS <CEC_ADAP_S_LOG_ADDRS>`, + except when in passthrough mode. In passthrough mode the core + does nothing (for any CEC version) and this message has to be handled + by a follower instead. + * .. _`CEC-MSG-USER-CONTROL-PRESSED`: + + - ``CEC_MSG_USER_CONTROL_PRESSED`` + - If :ref:`CEC_CAP_RC <CEC-CAP-RC>` is set and if + :ref:`CEC_LOG_ADDRS_FL_ALLOW_RC_PASSTHRU <CEC-LOG-ADDRS-FL-ALLOW-RC-PASSTHRU>` + is set, then generate a remote control key + press. This message is always passed on to the follower(s). + * .. _`CEC-MSG-USER-CONTROL-RELEASED`: + + - ``CEC_MSG_USER_CONTROL_RELEASED`` + - If :ref:`CEC_CAP_RC <CEC-CAP-RC>` is set and if + :ref:`CEC_LOG_ADDRS_FL_ALLOW_RC_PASSTHRU <CEC-LOG-ADDRS-FL-ALLOW-RC-PASSTHRU>` + is set, then generate a remote control key + release. This message is always passed on to the follower(s). + * .. _`CEC-MSG-REPORT-PHYSICAL-ADDR`: + + - ``CEC_MSG_REPORT_PHYSICAL_ADDR`` + - The CEC framework will make note of the reported physical address + and then just pass the message on to the follower(s). + + +Return Value +============ + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes <gen-errors>` chapter. + +The :ref:`ioctl CEC_S_MODE <CEC_S_MODE>` can return the following +error codes: + +EINVAL + The requested mode is invalid. + +EPERM + Monitor mode is requested, but the process does have the ``CAP_NET_ADMIN`` + capability. + +EBUSY + Someone else is already an exclusive follower or initiator. diff --git a/Documentation/userspace-api/media/cec/cec-ioc-receive.rst b/Documentation/userspace-api/media/cec/cec-ioc-receive.rst new file mode 100644 index 000000000..364938ad3 --- /dev/null +++ b/Documentation/userspace-api/media/cec/cec-ioc-receive.rst @@ -0,0 +1,385 @@ +.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later +.. c:namespace:: CEC + +.. _CEC_TRANSMIT: +.. _CEC_RECEIVE: + +*********************************** +ioctls CEC_RECEIVE and CEC_TRANSMIT +*********************************** + +Name +==== + +CEC_RECEIVE, CEC_TRANSMIT - Receive or transmit a CEC message + +Synopsis +======== + +.. c:macro:: CEC_RECEIVE + +``int ioctl(int fd, CEC_RECEIVE, struct cec_msg *argp)`` + +.. c:macro:: CEC_TRANSMIT + +``int ioctl(int fd, CEC_TRANSMIT, struct cec_msg *argp)`` + +Arguments +========= + +``fd`` + File descriptor returned by :c:func:`open()`. + +``argp`` + Pointer to struct cec_msg. + +Description +=========== + +To receive a CEC message the application has to fill in the +``timeout`` field of struct :c:type:`cec_msg` and pass it to +:ref:`ioctl CEC_RECEIVE <CEC_RECEIVE>`. +If the file descriptor is in non-blocking mode and there are no received +messages pending, then it will return -1 and set errno to the ``EAGAIN`` +error code. If the file descriptor is in blocking mode and ``timeout`` +is non-zero and no message arrived within ``timeout`` milliseconds, then +it will return -1 and set errno to the ``ETIMEDOUT`` error code. + +A received message can be: + +1. a message received from another CEC device (the ``sequence`` field will + be 0, ``tx_status`` will be 0 and ``rx_status`` will be non-zero). +2. the transmit result of an earlier non-blocking transmit (the ``sequence`` + field will be non-zero, ``tx_status`` will be non-zero and ``rx_status`` + will be 0). +3. the reply to an earlier non-blocking transmit (the ``sequence`` field will + be non-zero, ``tx_status`` will be 0 and ``rx_status`` will be non-zero). + +To send a CEC message the application has to fill in the struct +:c:type:`cec_msg` and pass it to :ref:`ioctl CEC_TRANSMIT <CEC_TRANSMIT>`. +The :ref:`ioctl CEC_TRANSMIT <CEC_TRANSMIT>` is only available if +``CEC_CAP_TRANSMIT`` is set. If there is no more room in the transmit +queue, then it will return -1 and set errno to the ``EBUSY`` error code. +The transmit queue has enough room for 18 messages (about 1 second worth +of 2-byte messages). Note that the CEC kernel framework will also reply +to core messages (see :ref:`cec-core-processing`), so it is not a good +idea to fully fill up the transmit queue. + +If the file descriptor is in non-blocking mode then the transmit will +return 0 and the result of the transmit will be available via +:ref:`ioctl CEC_RECEIVE <CEC_RECEIVE>` once the transmit has finished. +If a non-blocking transmit also specified waiting for a reply, then +the reply will arrive in a later message. The ``sequence`` field can +be used to associate both transmit results and replies with the original +transmit. + +Normally calling :ref:`ioctl CEC_TRANSMIT <CEC_TRANSMIT>` when the physical +address is invalid (due to e.g. a disconnect) will return ``ENONET``. + +However, the CEC specification allows sending messages from 'Unregistered' to +'TV' when the physical address is invalid since some TVs pull the hotplug detect +pin of the HDMI connector low when they go into standby, or when switching to +another input. + +When the hotplug detect pin goes low the EDID disappears, and thus the +physical address, but the cable is still connected and CEC still works. +In order to detect/wake up the device it is allowed to send poll and 'Image/Text +View On' messages from initiator 0xf ('Unregistered') to destination 0 ('TV'). + +.. tabularcolumns:: |p{1.0cm}|p{3.5cm}|p{12.8cm}| + +.. c:type:: cec_msg + +.. cssclass:: longtable + +.. flat-table:: struct cec_msg + :header-rows: 0 + :stub-columns: 0 + :widths: 1 1 16 + + * - __u64 + - ``tx_ts`` + - Timestamp in ns of when the last byte of the message was transmitted. + The timestamp has been taken from the ``CLOCK_MONOTONIC`` clock. To access + the same clock from userspace use :c:func:`clock_gettime`. + * - __u64 + - ``rx_ts`` + - Timestamp in ns of when the last byte of the message was received. + The timestamp has been taken from the ``CLOCK_MONOTONIC`` clock. To access + the same clock from userspace use :c:func:`clock_gettime`. + * - __u32 + - ``len`` + - The length of the message. For :ref:`ioctl CEC_TRANSMIT <CEC_TRANSMIT>` this is filled in + by the application. The driver will fill this in for + :ref:`ioctl CEC_RECEIVE <CEC_RECEIVE>`. For :ref:`ioctl CEC_TRANSMIT <CEC_TRANSMIT>` it will be + filled in by the driver with the length of the reply message if ``reply`` was set. + * - __u32 + - ``timeout`` + - The timeout in milliseconds. This is the time the device will wait + for a message to be received before timing out. If it is set to 0, + then it will wait indefinitely when it is called by :ref:`ioctl CEC_RECEIVE <CEC_RECEIVE>`. + If it is 0 and it is called by :ref:`ioctl CEC_TRANSMIT <CEC_TRANSMIT>`, + then it will be replaced by 1000 if the ``reply`` is non-zero or + ignored if ``reply`` is 0. + * - __u32 + - ``sequence`` + - A non-zero sequence number is automatically assigned by the CEC framework + for all transmitted messages. It is used by the CEC framework when it queues + the transmit result for a non-blocking transmit. This allows the application + to associate the received message with the original transmit. + + In addition, if a non-blocking transmit will wait for a reply (ii.e. ``timeout`` + was not 0), then the ``sequence`` field of the reply will be set to the sequence + value of the original transmit. This allows the application to associate the + received message with the original transmit. + * - __u32 + - ``flags`` + - Flags. See :ref:`cec-msg-flags` for a list of available flags. + * - __u8 + - ``msg[16]`` + - The message payload. For :ref:`ioctl CEC_TRANSMIT <CEC_TRANSMIT>` this is filled in by the + application. The driver will fill this in for :ref:`ioctl CEC_RECEIVE <CEC_RECEIVE>`. + For :ref:`ioctl CEC_TRANSMIT <CEC_TRANSMIT>` it will be filled in by the driver with + the payload of the reply message if ``timeout`` was set. + * - __u8 + - ``reply`` + - Wait until this message is replied. If ``reply`` is 0 and the + ``timeout`` is 0, then don't wait for a reply but return after + transmitting the message. Ignored by :ref:`ioctl CEC_RECEIVE <CEC_RECEIVE>`. + The case where ``reply`` is 0 (this is the opcode for the Feature Abort + message) and ``timeout`` is non-zero is specifically allowed to make it + possible to send a message and wait up to ``timeout`` milliseconds for a + Feature Abort reply. In this case ``rx_status`` will either be set + to :ref:`CEC_RX_STATUS_TIMEOUT <CEC-RX-STATUS-TIMEOUT>` or + :ref:`CEC_RX_STATUS_FEATURE_ABORT <CEC-RX-STATUS-FEATURE-ABORT>`. + + If the transmitter message is ``CEC_MSG_INITIATE_ARC`` then the ``reply`` + values ``CEC_MSG_REPORT_ARC_INITIATED`` and ``CEC_MSG_REPORT_ARC_TERMINATED`` + are processed differently: either value will match both possible replies. + The reason is that the ``CEC_MSG_INITIATE_ARC`` message is the only CEC + message that has two possible replies other than Feature Abort. The + ``reply`` field will be updated with the actual reply so that it is + synchronized with the contents of the received message. + * - __u8 + - ``rx_status`` + - The status bits of the received message. See + :ref:`cec-rx-status` for the possible status values. + * - __u8 + - ``tx_status`` + - The status bits of the transmitted message. See + :ref:`cec-tx-status` for the possible status values. + When calling :ref:`ioctl CEC_TRANSMIT <CEC_TRANSMIT>` in non-blocking mode, + this field will be 0 if the transmit started, or non-0 if the transmit + result is known immediately. The latter would be the case when attempting + to transmit a Poll message to yourself. That results in a + :ref:`CEC_TX_STATUS_NACK <CEC-TX-STATUS-NACK>` without ever actually + transmitting the Poll message. + * - __u8 + - ``tx_arb_lost_cnt`` + - A counter of the number of transmit attempts that resulted in the + Arbitration Lost error. This is only set if the hardware supports + this, otherwise it is always 0. This counter is only valid if the + :ref:`CEC_TX_STATUS_ARB_LOST <CEC-TX-STATUS-ARB-LOST>` status bit is set. + * - __u8 + - ``tx_nack_cnt`` + - A counter of the number of transmit attempts that resulted in the + Not Acknowledged error. This is only set if the hardware supports + this, otherwise it is always 0. This counter is only valid if the + :ref:`CEC_TX_STATUS_NACK <CEC-TX-STATUS-NACK>` status bit is set. + * - __u8 + - ``tx_low_drive_cnt`` + - A counter of the number of transmit attempts that resulted in the + Arbitration Lost error. This is only set if the hardware supports + this, otherwise it is always 0. This counter is only valid if the + :ref:`CEC_TX_STATUS_LOW_DRIVE <CEC-TX-STATUS-LOW-DRIVE>` status bit is set. + * - __u8 + - ``tx_error_cnt`` + - A counter of the number of transmit errors other than Arbitration + Lost or Not Acknowledged. This is only set if the hardware + supports this, otherwise it is always 0. This counter is only + valid if the :ref:`CEC_TX_STATUS_ERROR <CEC-TX-STATUS-ERROR>` status bit is set. + +.. tabularcolumns:: |p{6.2cm}|p{1.0cm}|p{10.1cm}| + +.. _cec-msg-flags: + +.. flat-table:: Flags for struct cec_msg + :header-rows: 0 + :stub-columns: 0 + :widths: 3 1 4 + + * .. _`CEC-MSG-FL-REPLY-TO-FOLLOWERS`: + + - ``CEC_MSG_FL_REPLY_TO_FOLLOWERS`` + - 1 + - If a CEC transmit expects a reply, then by default that reply is only sent to + the filehandle that called :ref:`ioctl CEC_TRANSMIT <CEC_TRANSMIT>`. If this + flag is set, then the reply is also sent to all followers, if any. If the + filehandle that called :ref:`ioctl CEC_TRANSMIT <CEC_TRANSMIT>` is also a + follower, then that filehandle will receive the reply twice: once as the + result of the :ref:`ioctl CEC_TRANSMIT <CEC_TRANSMIT>`, and once via + :ref:`ioctl CEC_RECEIVE <CEC_RECEIVE>`. + + * .. _`CEC-MSG-FL-RAW`: + + - ``CEC_MSG_FL_RAW`` + - 2 + - Normally CEC messages are validated before transmitting them. If this + flag is set when :ref:`ioctl CEC_TRANSMIT <CEC_TRANSMIT>` is called, + then no validation takes place and the message is transmitted as-is. + This is useful when debugging CEC issues. + This flag is only allowed if the process has the ``CAP_SYS_RAWIO`` + capability. If that is not set, then the ``EPERM`` error code is + returned. + +.. tabularcolumns:: |p{5.6cm}|p{0.9cm}|p{10.8cm}| + +.. _cec-tx-status: + +.. flat-table:: CEC Transmit Status + :header-rows: 0 + :stub-columns: 0 + :widths: 3 1 16 + + * .. _`CEC-TX-STATUS-OK`: + + - ``CEC_TX_STATUS_OK`` + - 0x01 + - The message was transmitted successfully. This is mutually + exclusive with :ref:`CEC_TX_STATUS_MAX_RETRIES <CEC-TX-STATUS-MAX-RETRIES>`. + Other bits can still be set if earlier attempts met with failure before + the transmit was eventually successful. + * .. _`CEC-TX-STATUS-ARB-LOST`: + + - ``CEC_TX_STATUS_ARB_LOST`` + - 0x02 + - CEC line arbitration was lost, i.e. another transmit started at the + same time with a higher priority. Optional status, not all hardware + can detect this error condition. + * .. _`CEC-TX-STATUS-NACK`: + + - ``CEC_TX_STATUS_NACK`` + - 0x04 + - Message was not acknowledged. Note that some hardware cannot tell apart + a 'Not Acknowledged' status from other error conditions, i.e. the result + of a transmit is just OK or FAIL. In that case this status will be + returned when the transmit failed. + * .. _`CEC-TX-STATUS-LOW-DRIVE`: + + - ``CEC_TX_STATUS_LOW_DRIVE`` + - 0x08 + - Low drive was detected on the CEC bus. This indicates that a + follower detected an error on the bus and requests a + retransmission. Optional status, not all hardware can detect this + error condition. + * .. _`CEC-TX-STATUS-ERROR`: + + - ``CEC_TX_STATUS_ERROR`` + - 0x10 + - Some error occurred. This is used for any errors that do not fit + ``CEC_TX_STATUS_ARB_LOST`` or ``CEC_TX_STATUS_LOW_DRIVE``, either because + the hardware could not tell which error occurred, or because the hardware + tested for other conditions besides those two. Optional status. + * .. _`CEC-TX-STATUS-MAX-RETRIES`: + + - ``CEC_TX_STATUS_MAX_RETRIES`` + - 0x20 + - The transmit failed after one or more retries. This status bit is + mutually exclusive with :ref:`CEC_TX_STATUS_OK <CEC-TX-STATUS-OK>`. + Other bits can still be set to explain which failures were seen. + * .. _`CEC-TX-STATUS-ABORTED`: + + - ``CEC_TX_STATUS_ABORTED`` + - 0x40 + - The transmit was aborted due to an HDMI disconnect, or the adapter + was unconfigured, or a transmit was interrupted, or the driver + returned an error when attempting to start a transmit. + * .. _`CEC-TX-STATUS-TIMEOUT`: + + - ``CEC_TX_STATUS_TIMEOUT`` + - 0x80 + - The transmit timed out. This should not normally happen and this + indicates a driver problem. + +.. tabularcolumns:: |p{5.6cm}|p{0.9cm}|p{10.8cm}| + +.. _cec-rx-status: + +.. flat-table:: CEC Receive Status + :header-rows: 0 + :stub-columns: 0 + :widths: 3 1 16 + + * .. _`CEC-RX-STATUS-OK`: + + - ``CEC_RX_STATUS_OK`` + - 0x01 + - The message was received successfully. + * .. _`CEC-RX-STATUS-TIMEOUT`: + + - ``CEC_RX_STATUS_TIMEOUT`` + - 0x02 + - The reply to an earlier transmitted message timed out. + * .. _`CEC-RX-STATUS-FEATURE-ABORT`: + + - ``CEC_RX_STATUS_FEATURE_ABORT`` + - 0x04 + - The message was received successfully but the reply was + ``CEC_MSG_FEATURE_ABORT``. This status is only set if this message + was the reply to an earlier transmitted message. + * .. _`CEC-RX-STATUS-ABORTED`: + + - ``CEC_RX_STATUS_ABORTED`` + - 0x08 + - The wait for a reply to an earlier transmitted message was aborted + because the HDMI cable was disconnected, the adapter was unconfigured + or the :ref:`CEC_TRANSMIT <CEC_RECEIVE>` that waited for a + reply was interrupted. + + +Return Value +============ + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes <gen-errors>` chapter. + +The :ref:`ioctl CEC_RECEIVE <CEC_RECEIVE>` can return the following +error codes: + +EAGAIN + No messages are in the receive queue, and the filehandle is in non-blocking mode. + +ETIMEDOUT + The ``timeout`` was reached while waiting for a message. + +ERESTARTSYS + The wait for a message was interrupted (e.g. by Ctrl-C). + +The :ref:`ioctl CEC_TRANSMIT <CEC_TRANSMIT>` can return the following +error codes: + +ENOTTY + The ``CEC_CAP_TRANSMIT`` capability wasn't set, so this ioctl is not supported. + +EPERM + The CEC adapter is not configured, i.e. :ref:`ioctl CEC_ADAP_S_LOG_ADDRS <CEC_ADAP_S_LOG_ADDRS>` + has never been called, or ``CEC_MSG_FL_RAW`` was used from a process that + did not have the ``CAP_SYS_RAWIO`` capability. + +ENONET + The CEC adapter is not configured, i.e. :ref:`ioctl CEC_ADAP_S_LOG_ADDRS <CEC_ADAP_S_LOG_ADDRS>` + was called, but the physical address is invalid so no logical address was claimed. + An exception is made in this case for transmits from initiator 0xf ('Unregistered') + to destination 0 ('TV'). In that case the transmit will proceed as usual. + +EBUSY + Another filehandle is in exclusive follower or initiator mode, or the filehandle + is in mode ``CEC_MODE_NO_INITIATOR``. This is also returned if the transmit + queue is full. + +EINVAL + The contents of struct :c:type:`cec_msg` is invalid. + +ERESTARTSYS + The wait for a successful transmit was interrupted (e.g. by Ctrl-C). diff --git a/Documentation/userspace-api/media/cec/cec-pin-error-inj.rst b/Documentation/userspace-api/media/cec/cec-pin-error-inj.rst new file mode 100644 index 000000000..b0efce404 --- /dev/null +++ b/Documentation/userspace-api/media/cec/cec-pin-error-inj.rst @@ -0,0 +1,327 @@ +.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later + +CEC Pin Framework Error Injection +================================= + +The CEC Pin Framework is a core CEC framework for CEC hardware that only +has low-level support for the CEC bus. Most hardware today will have +high-level CEC support where the hardware deals with driving the CEC bus, +but some older devices aren't that fancy. However, this framework also +allows you to connect the CEC pin to a GPIO on e.g. a Raspberry Pi and +you have now made a CEC adapter. + +What makes doing this so interesting is that since we have full control +over the bus it is easy to support error injection. This is ideal to +test how well CEC adapters can handle error conditions. + +Currently only the cec-gpio driver (when the CEC line is directly +connected to a pull-up GPIO line) and the AllWinner A10/A20 drm driver +support this framework. + +If ``CONFIG_CEC_PIN_ERROR_INJ`` is enabled, then error injection is available +through debugfs. Specifically, in ``/sys/kernel/debug/cec/cecX/`` there is +now an ``error-inj`` file. + +.. note:: + + The error injection commands are not a stable ABI and may change in the + future. + +With ``cat error-inj`` you can see both the possible commands and the current +error injection status:: + + $ cat /sys/kernel/debug/cec/cec0/error-inj + # Clear error injections: + # clear clear all rx and tx error injections + # rx-clear clear all rx error injections + # tx-clear clear all tx error injections + # <op> clear clear all rx and tx error injections for <op> + # <op> rx-clear clear all rx error injections for <op> + # <op> tx-clear clear all tx error injections for <op> + # + # RX error injection: + # <op>[,<mode>] rx-nack NACK the message instead of sending an ACK + # <op>[,<mode>] rx-low-drive <bit> force a low-drive condition at this bit position + # <op>[,<mode>] rx-add-byte add a spurious byte to the received CEC message + # <op>[,<mode>] rx-remove-byte remove the last byte from the received CEC message + # any[,<mode>] rx-arb-lost [<poll>] generate a POLL message to trigger an arbitration lost + # + # TX error injection settings: + # tx-ignore-nack-until-eom ignore early NACKs until EOM + # tx-custom-low-usecs <usecs> define the 'low' time for the custom pulse + # tx-custom-high-usecs <usecs> define the 'high' time for the custom pulse + # tx-custom-pulse transmit the custom pulse once the bus is idle + # + # TX error injection: + # <op>[,<mode>] tx-no-eom don't set the EOM bit + # <op>[,<mode>] tx-early-eom set the EOM bit one byte too soon + # <op>[,<mode>] tx-add-bytes <num> append <num> (1-255) spurious bytes to the message + # <op>[,<mode>] tx-remove-byte drop the last byte from the message + # <op>[,<mode>] tx-short-bit <bit> make this bit shorter than allowed + # <op>[,<mode>] tx-long-bit <bit> make this bit longer than allowed + # <op>[,<mode>] tx-custom-bit <bit> send the custom pulse instead of this bit + # <op>[,<mode>] tx-short-start send a start pulse that's too short + # <op>[,<mode>] tx-long-start send a start pulse that's too long + # <op>[,<mode>] tx-custom-start send the custom pulse instead of the start pulse + # <op>[,<mode>] tx-last-bit <bit> stop sending after this bit + # <op>[,<mode>] tx-low-drive <bit> force a low-drive condition at this bit position + # + # <op> CEC message opcode (0-255) or 'any' + # <mode> 'once' (default), 'always', 'toggle' or 'off' + # <bit> CEC message bit (0-159) + # 10 bits per 'byte': bits 0-7: data, bit 8: EOM, bit 9: ACK + # <poll> CEC poll message used to test arbitration lost (0x00-0xff, default 0x0f) + # <usecs> microseconds (0-10000000, default 1000) + + clear + +You can write error injection commands to ``error-inj`` using +``echo 'cmd' >error-inj`` or ``cat cmd.txt >error-inj``. The ``cat error-inj`` +output contains the current error commands. You can save the output to a file +and use it as an input to ``error-inj`` later. + +Basic Syntax +------------ + +Leading spaces/tabs are ignored. If the next character is a ``#`` or the end +of the line was reached, then the whole line is ignored. Otherwise a command +is expected. + +The error injection commands fall in two main groups: those relating to +receiving CEC messages and those relating to transmitting CEC messages. In +addition, there are commands to clear existing error injection commands and +to create custom pulses on the CEC bus. + +Most error injection commands can be executed for specific CEC opcodes or for +all opcodes (``any``). Each command also has a 'mode' which can be ``off`` +(can be used to turn off an existing error injection command), ``once`` +(the default) which will trigger the error injection only once for the next +received or transmitted message, ``always`` to always trigger the error +injection and ``toggle`` to toggle the error injection on or off for every +transmit or receive. + +So '``any rx-nack``' will NACK the next received CEC message, +'``any,always rx-nack``' will NACK all received CEC messages and +'``0x82,toggle rx-nack``' will only NACK if an Active Source message was +received and do that only for every other received message. + +After an error was injected with mode ``once`` the error injection command +is cleared automatically, so ``once`` is a one-time deal. + +All combinations of ``<op>`` and error injection commands can co-exist. So +this is fine:: + + 0x9e tx-add-bytes 1 + 0x9e tx-early-eom + 0x9f tx-add-bytes 2 + any rx-nack + +All four error injection commands will be active simultaneously. + +However, if the same ``<op>`` and command combination is specified, +but with different arguments:: + + 0x9e tx-add-bytes 1 + 0x9e tx-add-bytes 2 + +Then the second will overwrite the first. + +Clear Error Injections +---------------------- + +``clear`` + Clear all error injections. + +``rx-clear`` + Clear all receive error injections + +``tx-clear`` + Clear all transmit error injections + +``<op> clear`` + Clear all error injections for the given opcode. + +``<op> rx-clear`` + Clear all receive error injections for the given opcode. + +``<op> tx-clear`` + Clear all transmit error injections for the given opcode. + +Receive Messages +---------------- + +``<op>[,<mode>] rx-nack`` + NACK broadcast messages and messages directed to this CEC adapter. + Every byte of the message will be NACKed in case the transmitter + keeps transmitting after the first byte was NACKed. + +``<op>[,<mode>] rx-low-drive <bit>`` + Force a Low Drive condition at this bit position. If <op> specifies + a specific CEC opcode then the bit position must be at least 18, + otherwise the opcode hasn't been received yet. This tests if the + transmitter can handle the Low Drive condition correctly and reports + the error correctly. Note that a Low Drive in the first 4 bits can also + be interpreted as an Arbitration Lost condition by the transmitter. + This is implementation dependent. + +``<op>[,<mode>] rx-add-byte`` + Add a spurious 0x55 byte to the received CEC message, provided + the message was 15 bytes long or less. This is useful to test + the high-level protocol since spurious bytes should be ignored. + +``<op>[,<mode>] rx-remove-byte`` + Remove the last byte from the received CEC message, provided it + was at least 2 bytes long. This is useful to test the high-level + protocol since messages that are too short should be ignored. + +``<op>[,<mode>] rx-arb-lost <poll>`` + Generate a POLL message to trigger an Arbitration Lost condition. + This command is only allowed for ``<op>`` values of ``next`` or ``all``. + As soon as a start bit has been received the CEC adapter will switch + to transmit mode and it will transmit a POLL message. By default this is + 0x0f, but it can also be specified explicitly via the ``<poll>`` argument. + + This command can be used to test the Arbitration Lost condition in + the remote CEC transmitter. Arbitration happens when two CEC adapters + start sending a message at the same time. In that case the initiator + with the most leading zeroes wins and the other transmitter has to + stop transmitting ('Arbitration Lost'). This is very hard to test, + except by using this error injection command. + + This does not work if the remote CEC transmitter has logical address + 0 ('TV') since that will always win. + +Transmit Messages +----------------- + +``tx-ignore-nack-until-eom`` + This setting changes the behavior of transmitting CEC messages. Normally + as soon as the receiver NACKs a byte the transmit will stop, but the + specification also allows that the full message is transmitted and only + at the end will the transmitter look at the ACK bit. This is not + recommended behavior since there is no point in keeping the CEC bus busy + for longer than is strictly needed. Especially given how slow the bus is. + + This setting can be used to test how well a receiver deals with + transmitters that ignore NACKs until the very end of the message. + +``<op>[,<mode>] tx-no-eom`` + Don't set the EOM bit. Normally the last byte of the message has the EOM + (End-Of-Message) bit set. With this command the transmit will just stop + without ever sending an EOM. This can be used to test how a receiver + handles this case. Normally receivers have a time-out after which + they will go back to the Idle state. + +``<op>[,<mode>] tx-early-eom`` + Set the EOM bit one byte too soon. This obviously only works for messages + of two bytes or more. The EOM bit will be set for the second-to-last byte + and not for the final byte. The receiver should ignore the last byte in + this case. Since the resulting message is likely to be too short for this + same reason the whole message is typically ignored. The receiver should be + in Idle state after the last byte was transmitted. + +``<op>[,<mode>] tx-add-bytes <num>`` + Append ``<num>`` (1-255) spurious bytes to the message. The extra bytes + have the value of the byte position in the message. So if you transmit a + two byte message (e.g. a Get CEC Version message) and add 2 bytes, then + the full message received by the remote CEC adapter is + ``0x40 0x9f 0x02 0x03``. + + This command can be used to test buffer overflows in the receiver. E.g. + what does it do when it receives more than the maximum message size of 16 + bytes. + +``<op>[,<mode>] tx-remove-byte`` + Drop the last byte from the message, provided the message is at least + two bytes long. The receiver should ignore messages that are too short. + +``<op>[,<mode>] tx-short-bit <bit>`` + Make this bit period shorter than allowed. The bit position cannot be + an Ack bit. If <op> specifies a specific CEC opcode then the bit position + must be at least 18, otherwise the opcode hasn't been received yet. + Normally the period of a data bit is between 2.05 and 2.75 milliseconds. + With this command the period of this bit is 1.8 milliseconds, this is + done by reducing the time the CEC bus is high. This bit period is less + than is allowed and the receiver should respond with a Low Drive + condition. + + This command is ignored for 0 bits in bit positions 0 to 3. This is + because the receiver also looks for an Arbitration Lost condition in + those first four bits and it is undefined what will happen if it + sees a too-short 0 bit. + +``<op>[,<mode>] tx-long-bit <bit>`` + Make this bit period longer than is valid. The bit position cannot be + an Ack bit. If <op> specifies a specific CEC opcode then the bit position + must be at least 18, otherwise the opcode hasn't been received yet. + Normally the period of a data bit is between 2.05 and 2.75 milliseconds. + With this command the period of this bit is 2.9 milliseconds, this is + done by increasing the time the CEC bus is high. + + Even though this bit period is longer than is valid it is undefined what + a receiver will do. It might just accept it, or it might time out and + return to Idle state. Unfortunately the CEC specification is silent about + this. + + This command is ignored for 0 bits in bit positions 0 to 3. This is + because the receiver also looks for an Arbitration Lost condition in + those first four bits and it is undefined what will happen if it + sees a too-long 0 bit. + +``<op>[,<mode>] tx-short-start`` + Make this start bit period shorter than allowed. Normally the period of + a start bit is between 4.3 and 4.7 milliseconds. With this command the + period of the start bit is 4.1 milliseconds, this is done by reducing + the time the CEC bus is high. This start bit period is less than is + allowed and the receiver should return to Idle state when this is detected. + +``<op>[,<mode>] tx-long-start`` + Make this start bit period longer than is valid. Normally the period of + a start bit is between 4.3 and 4.7 milliseconds. With this command the + period of the start bit is 5 milliseconds, this is done by increasing + the time the CEC bus is high. This start bit period is more than is + valid and the receiver should return to Idle state when this is detected. + + Even though this start bit period is longer than is valid it is undefined + what a receiver will do. It might just accept it, or it might time out and + return to Idle state. Unfortunately the CEC specification is silent about + this. + +``<op>[,<mode>] tx-last-bit <bit>`` + Just stop transmitting after this bit. If <op> specifies a specific CEC + opcode then the bit position must be at least 18, otherwise the opcode + hasn't been received yet. This command can be used to test how the receiver + reacts when a message just suddenly stops. It should time out and go back + to Idle state. + +``<op>[,<mode>] tx-low-drive <bit>`` + Force a Low Drive condition at this bit position. If <op> specifies a + specific CEC opcode then the bit position must be at least 18, otherwise + the opcode hasn't been received yet. This can be used to test how the + receiver handles Low Drive conditions. Note that if this happens at bit + positions 0-3 the receiver can interpret this as an Arbitration Lost + condition. This is implementation dependent. + +Custom Pulses +------------- + +``tx-custom-low-usecs <usecs>`` + This defines the duration in microseconds that the custom pulse pulls + the CEC line low. The default is 1000 microseconds. + +``tx-custom-high-usecs <usecs>`` + This defines the duration in microseconds that the custom pulse keeps the + CEC line high (unless another CEC adapter pulls it low in that time). + The default is 1000 microseconds. The total period of the custom pulse is + ``tx-custom-low-usecs + tx-custom-high-usecs``. + +``<op>[,<mode>] tx-custom-bit <bit>`` + Send the custom bit instead of a regular data bit. The bit position cannot + be an Ack bit. If <op> specifies a specific CEC opcode then the bit + position must be at least 18, otherwise the opcode hasn't been received yet. + +``<op>[,<mode>] tx-custom-start`` + Send the custom bit instead of a regular start bit. + +``tx-custom-pulse`` + Transmit a single custom pulse as soon as the CEC bus is idle. |