code:
.. SPDX-License-Identifier: GPL-2.0
.. Copyright © 2017-2020 Mickaël Salaün <mic@digikod.net>
.. Copyright © 2019-2020 ANSSI
.. Copyright © 2021-2022 Microsoft Corporation

=====================================
Landlock: unprivileged access control
=====================================

:Author: Mickaël Salaün
:Date: October 2022

The goal of Landlock is to enable to restrict ambient rights (e.g. global
filesystem access) for a set of processes.  Because Landlock is a stackable
LSM, it makes possible to create safe security sandboxes as new security layers
in addition to the existing system-wide access-controls. This kind of sandbox
is expected to help mitigate the security impact of bugs or
unexpected/malicious behaviors in user space applications.  Landlock empowers
any process, including unprivileged ones, to securely restrict themselves.

We can quickly make sure that Landlock is enabled in the running system by
looking for "landlock: Up and running" in kernel logs (as root): ``dmesg | grep
landlock || journalctl -kg landlock`` .  Developers can also easily check for
Landlock support with a :ref:`related system call <landlock_abi_versions>`.  If
Landlock is not currently supported, we need to :ref:`configure the kernel
appropriately <kernel_support>`.

Landlock rules
==============

A Landlock rule describes an action on an object.  An object is currently a
file hierarchy, and the related filesystem actions are defined with `access
rights`_.  A set of rules is aggregated in a ruleset, which can then restrict
the thread enforcing it, and its future children.

Defining and enforcing a security policy
----------------------------------------

We first need to define the ruleset that will contain our rules.  For this
example, the ruleset will contain rules that only allow read actions, but write
actions will be denied.  The ruleset then needs to handle both of these kind of
actions.  This is required for backward and forward compatibility (i.e. the
kernel and user space may not know each other's supported restrictions), hence
the need to be explicit about the denied-by-default access rights.

.. code-block:: c

    struct landlock_ruleset_attr ruleset_attr = {
        .handled_access_fs =
            LANDLOCK_ACCESS_FS_EXECUTE |
            LANDLOCK_ACCESS_FS_WRITE_FILE |
            LANDLOCK_ACCESS_FS_READ_FILE |
            LANDLOCK_ACCESS_FS_READ_DIR |
            LANDLOCK_ACCESS_FS_REMOVE_DIR |
            LANDLOCK_ACCESS_FS_REMOVE_FILE |
            LANDLOCK_ACCESS_FS_MAKE_CHAR |
            LANDLOCK_ACCESS_FS_MAKE_DIR |
            LANDLOCK_ACCESS_FS_MAKE_REG |
            LANDLOCK_ACCESS_FS_MAKE_SOCK |
            LANDLOCK_ACCESS_FS_MAKE_FIFO |
            LANDLOCK_ACCESS_FS_MAKE_BLOCK |
            LANDLOCK_ACCESS_FS_MAKE_SYM |
            LANDLOCK_ACCESS_FS_REFER |
            LANDLOCK_ACCESS_FS_TRUNCATE,
    };

Because we may not know on which kernel version an application will be
executed, it is safer to follow a best-effort security approach.  Indeed, we
should try to protect users as much as possible whatever the kernel they are
using.  To avoid binary enforcement (i.e. either all security features or
none), we can leverage a dedicated Landlock command to get the current version
of the Landlock ABI and adapt the handled accesses.  Let's check if we should
remove the ``LANDLOCK_ACCESS_FS_REFER`` or ``LANDLOCK_ACCESS_FS_TRUNCATE``
access rights, which are only supported starting with the second and third
version of the ABI.

.. code-block:: c

    int abi;

    abi = landlock_create_ruleset(NULL, 0, LANDLOCK_CREATE_RULESET_VERSION);
    if (abi < 0) {
        /* Degrades gracefully if Landlock is not handled. */
        perror("The running kernel does not enable to use Landlock");
        return 0;
    }
    switch (abi) {
    case 1:
        /* Removes LANDLOCK_ACCESS_FS_REFER for ABI < 2 */
        ruleset_attr.handled_access_fs &= ~LANDLOCK_ACCESS_FS_REFER;
        __attribute__((fallthrough));
    case 2:
        /* Removes LANDLOCK_ACCESS_FS_TRUNCATE for ABI < 3 */
        ruleset_attr.handled_access_fs &= ~LANDLOCK_ACCESS_FS_TRUNCATE;
    }

This enables to create an inclusive ruleset that will contain our rules.

.. code-block:: c

    int ruleset_fd;

    ruleset_fd = landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0);
    if (ruleset_fd < 0) {
        perror("Failed to create a ruleset");
        return 1;
    }

We can now add a new rule to this ruleset thanks to the returned file
descriptor referring to this ruleset.  The rule will only allow reading the
file hierarchy ``/usr``.  Without another rule, write actions would then be
denied by the ruleset.  To add ``/usr`` to the ruleset, we open it with the
``O_PATH`` flag and fill the &struct landlock_path_beneath_attr with this file
descriptor.

.. code-block:: c

    int err;
    struct landlock_path_beneath_attr path_beneath = {
        .allowed_access =
            LANDLOCK_ACCESS_FS_EXECUTE |
            LANDLOCK_ACCESS_FS_READ_FILE |
            LANDLOCK_ACCESS_FS_READ_DIR,
    };

    path_beneath.parent_fd = open("/usr", O_PATH | O_CLOEXEC);
    if (path_beneath.parent_fd < 0) {
        perror("Failed to open file");
        close(ruleset_fd);
        return 1;
    }
    err = landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH,
                            &path_beneath, 0);
    close(path_beneath.parent_fd);
    if (err) {
        perror("Failed to update ruleset");
        close(ruleset_fd);
        return 1;
    }

It may also be required to create rules following the same logic as explained
for the ruleset creation, by filtering access rights according to the Landlock
ABI version.  In this example, this is not required because all of the requested
``allowed_access`` rights are already available in ABI 1.

We now have a ruleset with one rule allowing read access to ``/usr`` while
denying all other handled accesses for the filesystem.  The next step is to
restrict the current thread from gaining more privileges (e.g. thanks to a SUID
binary).

.. code-block:: c

    if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) {
        perror("Failed to restrict privileges");
        close(ruleset_fd);
        return 1;
    }

The current thread is now ready to sandbox itself with the ruleset.

.. code-block:: c

    if (landlock_restrict_self(ruleset_fd, 0)) {
        perror("Failed to enforce ruleset");
        close(ruleset_fd);
        return 1;
    }
    close(ruleset_fd);

If the ``landlock_restrict_self`` system call succeeds, the current thread is
now restricted and this policy will be enforced on all its subsequently created
children as well.  Once a thread is landlocked, there is no way to remove its
security policy; only adding more restrictions is allowed.  These threads are
now in a new Landlock domain, merge of their parent one (if any) with the new
ruleset.

Full working code can be found in `samples/landlock/sandboxer.c`_.

Good practices
--------------

It is recommended setting access rights to file hierarchy leaves as much as
possible.  For instance, it is better to be able to have ``~/doc/`` as a
read-only hierarchy and ``~/tmp/`` as a read-write hierarchy, compared to
``~/`` as a read-only hierarchy and ``~/tmp/`` as a read-write hierarchy.
Following this good practice leads to self-sufficient hierarchies that do not
depend on their location (i.e. parent directories).  This is particularly
relevant when we want to allow linking or renaming.  Indeed, having consistent
access rights per directory enables to change the location of such directory
without relying on the destination directory access rights (except those that
are required for this operation, see ``LANDLOCK_ACCESS_FS_REFER``
documentation).
Having self-sufficient hierarchies also helps to tighten the required access
rights to the minimal set of data.  This also helps avoid sinkhole directories,
i.e.  directories where data can be linked to but not linked from.  However,
this depends on data organization, which might not be controlled by developers.
In this case, granting read-write access to ``~/tmp/``, instead of write-only
access, would potentially allow to move ``~/tmp/`` to a non-readable directory
and still keep the ability to list the content of ``~/tmp/``.

Layers of file path access rights
---------------------------------

Each time a thread enforces a ruleset on itself, it updates its Landlock domain
with a new layer of policy.  Indeed, this complementary policy is stacked with
the potentially other rulesets already restricting this thread.  A sandboxed
thread can then safely add more constraints to itself with a new enforced
ruleset.

One policy layer grants access to a file path if at least one of its rules
encountered on the path grants the access.  A sandboxed thread can only access
a file path if all its enforced policy layers grant the access as well as all
the other system access controls (e.g. filesystem DAC, other LSM policies,
etc.).

Bind mounts and OverlayFS
-------------------------

Landlock enables to restrict access to file hierarchies, which means that these
access rights can be propagated with bind mounts (cf.
Documentation/filesystems/sharedsubtree.rst) but not with
Documentation/filesystems/overlayfs.rst.

A bind mount mirrors a source file hierarchy to a destination.  The destination
hierarchy is then composed of the exact same files, on which Landlock rules can
be tied, either via the source or the destination path.  These rules restrict
access when they are encountered on a path, which means that they can restrict
access to multiple file hierarchies at the same time, whether these hierarchies
are the result of bind mounts or not.

An OverlayFS mount point consists of upper and lower layers.  These layers are
combined in a merge directory, result of the mount point.  This merge hierarchy
may include files from the upper and lower layers, but modifications performed
on the merge hierarchy only reflects on the upper layer.  From a Landlock
policy point of view, each OverlayFS layers and merge hierarchies are
standalone and contains their own set of files and directories, which is
different from bind mounts.  A policy restricting an OverlayFS layer will not
restrict the resulted merged hierarchy, and vice versa.  Landlock users should
then only think about file hierarchies they want to allow access to, regardless
of the underlying filesystem.

Inheritance
-----------

Every new thread resulting from a :manpage:`clone(2)` inherits Landlock domain
restrictions from its parent.  This is similar to the seccomp inheritance (cf.
Documentation/userspace-api/seccomp_filter.rst) or any other LSM dealing with
task's :manpage:`credentials(7)`.  For instance, one process's thread may apply
Landlock rules to itself, but they will not be automatically applied to other
sibling threads (unlike POSIX thread credential changes, cf.
:manpage:`nptl(7)`).

When a thread sandboxes itself, we have the guarantee that the related security
policy will stay enforced on all this thread's descendants.  This allows
creating standalone and modular security policies per application, which will
automatically be composed between themselves according to their runtime parent
policies.

Ptrace restrictions
-------------------

A sandboxed process has less privileges than a non-sandboxed process and must
then be subject to additional restrictions when manipulating another process.
To be allowed to use :manpage:`ptrace(2)` and related syscalls on a target
process, a sandboxed process should have a subset of the target process rules,
which means the tracee must be in a sub-domain of the tracer.

Truncating files
----------------

The operations covered by ``LANDLOCK_ACCESS_FS_WRITE_FILE`` and
``LANDLOCK_ACCESS_FS_TRUNCATE`` both change the contents of a file and sometimes
overlap in non-intuitive ways.  It is recommended to always specify both of
these together.

A particularly surprising example is :manpage:`creat(2)`.  The name suggests
that this system call requires the rights to create and write files.  However,
it also requires the truncate right if an existing file under the same name is
already present.

It should also be noted that truncating files does not require the
``LANDLOCK_ACCESS_FS_WRITE_FILE`` right.  Apart from the :manpage:`truncate(2)`
system call, this can also be done through :manpage:`open(2)` with the flags
``O_RDONLY | O_TRUNC``.

When opening a file, the availability of the ``LANDLOCK_ACCESS_FS_TRUNCATE``
right is associated with the newly created file descriptor and will be used for
subsequent truncation attempts using :manpage:`ftruncate(2)`.  The behavior is
similar to opening a file for reading or writing, where permissions are checked
during :manpage:`open(2)`, but not during the subsequent :manpage:`read(2)` and
:manpage:`write(2)` calls.

As a consequence, it is possible to have multiple open file descriptors for the
same file, where one grants the right to truncate the file and the other does
not.  It is also possible to pass such file descriptors between processes,
keeping their Landlock properties, even when these processes do not have an
enforced Landlock ruleset.

Compatibility
=============

Backward and forward compatibility
----------------------------------

Landlock is designed to be compatible with past and future versions of the
kernel.  This is achieved thanks to the system call attributes and the
associated bitflags, particularly the ruleset's ``handled_access_fs``.  Making
handled access right explicit enables the kernel and user space to have a clear
contract with each other.  This is required to make sure sandboxing will not
get stricter with a system update, which could break applications.

Developers can subscribe to the `Landlock mailing list
<https://subspace.kernel.org/lists.linux.dev.html>`_ to knowingly update and
test their applications with the latest available features.  In the interest of
users, and because they may use different kernel versions, it is strongly
encouraged to follow a best-effort security approach by checking the Landlock
ABI version at runtime and only enforcing the supported features.

.. _landlock_abi_versions:

Landlock ABI versions
---------------------

The Landlock ABI version can be read with the sys_landlock_create_ruleset()
system call:

.. code-block:: c

    int abi;

    abi = landlock_create_ruleset(NULL, 0, LANDLOCK_CREATE_RULESET_VERSION);
    if (abi < 0) {
        switch (errno) {
        case ENOSYS:
            printf("Landlock is not supported by the current kernel.\n");
            break;
        case EOPNOTSUPP:
            printf("Landlock is currently disabled.\n");
            break;
        }
        return 0;
    }
    if (abi >= 2) {
        printf("Landlock supports LANDLOCK_ACCESS_FS_REFER.\n");
    }

The following kernel interfaces are implicitly supported by the first ABI
version.  Features only supported from a specific version are explicitly marked
as such.

Kernel interface
================

Access rights
-------------

.. kernel-doc:: include/uapi/linux/landlock.h
    :identifiers: fs_access

Creating a new ruleset
----------------------

.. kernel-doc:: security/landlock/syscalls.c
    :identifiers: sys_landlock_create_ruleset

.. kernel-doc:: include/uapi/linux/landlock.h
    :identifiers: landlock_ruleset_attr

Extending a ruleset
-------------------

.. kernel-doc:: security/landlock/syscalls.c
    :identifiers: sys_landlock_add_rule

.. kernel-doc:: include/uapi/linux/landlock.h
    :identifiers: landlock_rule_type landlock_path_beneath_attr

Enforcing a ruleset
-------------------

.. kernel-doc:: security/landlock/syscalls.c
    :identifiers: sys_landlock_restrict_self

Current limitations
===================

Filesystem topology modification
--------------------------------

As for file renaming and linking, a sandboxed thread cannot modify its
filesystem topology, whether via :manpage:`mount(2)` or
:manpage:`pivot_root(2)`.  However, :manpage:`chroot(2)` calls are not denied.

Special filesystems
-------------------

Access to regular files and directories can be restricted by Landlock,
according to the handled accesses of a ruleset.  However, files that do not
come from a user-visible filesystem (e.g. pipe, socket), but can still be
accessed through ``/proc/<pid>/fd/*``, cannot currently be explicitly
restricted.  Likewise, some special kernel filesystems such as nsfs, which can
be accessed through ``/proc/<pid>/ns/*``, cannot currently be explicitly
restricted.  However, thanks to the `ptrace restrictions`_, access to such
sensitive ``/proc`` files are automatically restricted according to domain
hierarchies.  Future Landlock evolutions could still enable to explicitly
restrict such paths with dedicated ruleset flags.

Ruleset layers
--------------

There is a limit of 16 layers of stacked rulesets.  This can be an issue for a
task willing to enforce a new ruleset in complement to its 16 inherited
rulesets.  Once this limit is reached, sys_landlock_restrict_self() returns
E2BIG.  It is then strongly suggested to carefully build rulesets once in the
life of a thread, especially for applications able to launch other applications
that may also want to sandbox themselves (e.g. shells, container managers,
etc.).

Memory usage
------------

Kernel memory allocated to create rulesets is accounted and can be restricted
by the Documentation/admin-guide/cgroup-v1/memory.rst.

Previous limitations
====================

File renaming and linking (ABI < 2)
-----------------------------------

Because Landlock targets unprivileged access controls, it needs to properly
handle composition of rules.  Such property also implies rules nesting.
Properly handling multiple layers of rulesets, each one of them able to
restrict access to files, also implies inheritance of the ruleset restrictions
from a parent to its hierarchy.  Because files are identified and restricted by
their hierarchy, moving or linking a file from one directory to another implies
propagation of the hierarchy constraints, or restriction of these actions
according to the potentially lost constraints.  To protect against privilege
escalations through renaming or linking, and for the sake of simplicity,
Landlock previously limited linking and renaming to the same directory.
Starting with the Landlock ABI version 2, it is now possible to securely
control renaming and linking thanks to the new ``LANDLOCK_ACCESS_FS_REFER``
access right.

File truncation (ABI < 3)
-------------------------

File truncation could not be denied before the third Landlock ABI, so it is
always allowed when using a kernel that only supports the first or second ABI.

Starting with the Landlock ABI version 3, it is now possible to securely control
truncation thanks to the new ``LANDLOCK_ACCESS_FS_TRUNCATE`` access right.

.. _kernel_support:

Kernel support
==============

Landlock was first introduced in Linux 5.13 but it must be configured at build
time with ``CONFIG_SECURITY_LANDLOCK=y``.  Landlock must also be enabled at boot
time as the other security modules.  The list of security modules enabled by
default is set with ``CONFIG_LSM``.  The kernel configuration should then
contains ``CONFIG_LSM=landlock,[...]`` with ``[...]``  as the list of other
potentially useful security modules for the running system (see the
``CONFIG_LSM`` help).

If the running kernel does not have ``landlock`` in ``CONFIG_LSM``, then we can
still enable it by adding ``lsm=landlock,[...]`` to
Documentation/admin-guide/kernel-parameters.rst thanks to the bootloader
configuration.

Questions and answers
=====================

What about user space sandbox managers?
---------------------------------------

Using user space process to enforce restrictions on kernel resources can lead
to race conditions or inconsistent evaluations (i.e. `Incorrect mirroring of
the OS code and state
<https://www.ndss-symposium.org/ndss2003/traps-and-pitfalls-practical-problems-system-call-interposition-based-security-tools/>`_).

What about namespaces and containers?
-------------------------------------

Namespaces can help create sandboxes but they are not designed for
access-control and then miss useful features for such use case (e.g. no
fine-grained restrictions).  Moreover, their complexity can lead to security
issues, especially when untrusted processes can manipulate them (cf.
`Controlling access to user namespaces <https://lwn.net/Articles/673597/>`_).

Additional documentation
========================

* Documentation/security/landlock.rst
* https://landlock.io

.. Links
.. _samples/landlock/sandboxer.c:
   https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/samples/landlock/sandboxer.c


code:
# SPDX-License-Identifier: GPL-2.0

# Rules to convert a .h file to inline RST documentation

SRC_DIR=$(srctree)/Documentation/userspace-api/media
PARSER = $(srctree)/Documentation/sphinx/parse-headers.pl
UAPI = $(srctree)/include/uapi/linux
KAPI = $(srctree)/include/linux

FILES = ca.h.rst dmx.h.rst frontend.h.rst net.h.rst \
	videodev2.h.rst media.h.rst cec.h.rst lirc.h.rst

TARGETS := $(addprefix $(BUILDDIR)/, $(FILES))

gen_rst = \
	echo ${PARSER} $< $@ $(SRC_DIR)/$(notdir $@).exceptions; \
	${PARSER} $< $@ $(SRC_DIR)/$(notdir $@).exceptions

quiet_gen_rst = echo '  PARSE   $(patsubst $(srctree)/%,%,$<)'; \
	${PARSER} $< $@ $(SRC_DIR)/$(notdir $@).exceptions

silent_gen_rst = ${gen_rst}

$(BUILDDIR)/ca.h.rst: ${UAPI}/dvb/ca.h ${PARSER} $(SRC_DIR)/ca.h.rst.exceptions
	@$($(quiet)gen_rst)

$(BUILDDIR)/dmx.h.rst: ${UAPI}/dvb/dmx.h ${PARSER} $(SRC_DIR)/dmx.h.rst.exceptions
	@$($(quiet)gen_rst)

$(BUILDDIR)/frontend.h.rst: ${UAPI}/dvb/frontend.h ${PARSER} $(SRC_DIR)/frontend.h.rst.exceptions
	@$($(quiet)gen_rst)

$(BUILDDIR)/net.h.rst: ${UAPI}/dvb/net.h ${PARSER} $(SRC_DIR)/net.h.rst.exceptions
	@$($(quiet)gen_rst)

$(BUILDDIR)/videodev2.h.rst: ${UAPI}/videodev2.h ${PARSER} $(SRC_DIR)/videodev2.h.rst.exceptions
	@$($(quiet)gen_rst)

$(BUILDDIR)/media.h.rst: ${UAPI}/media.h ${PARSER} $(SRC_DIR)/media.h.rst.exceptions
	@$($(quiet)gen_rst)

$(BUILDDIR)/cec.h.rst: ${UAPI}/cec.h ${PARSER} $(SRC_DIR)/cec.h.rst.exceptions
	@$($(quiet)gen_rst)

$(BUILDDIR)/lirc.h.rst: ${UAPI}/lirc.h ${PARSER} $(SRC_DIR)/lirc.h.rst.exceptions
	@$($(quiet)gen_rst)

# Media build rules

.PHONY: all html texinfo epub xml latex

all: $(IMGDOT) $(BUILDDIR) ${TARGETS}
html: all
texinfo: all
epub: all
xml: all
latex: $(IMGPDF) all
linkcheck:

clean:
	-rm -f $(DOTTGT) $(IMGTGT) ${TARGETS} 2>/dev/null

$(BUILDDIR):
	$(Q)mkdir -p $@

repo_name: angery/linux


code:
# SPDX-License-Identifier: GPL-2.0

# Ignore header name
ignore define _DVBCA_H_

# struct ca_slot_info defines
replace define CA_CI :c:type:`ca_slot_info`
replace define CA_CI_LINK :c:type:`ca_slot_info`
replace define CA_CI_PHYS :c:type:`ca_slot_info`
replace define CA_DESCR :c:type:`ca_slot_info`
replace define CA_SC :c:type:`ca_slot_info`
replace define CA_CI_MODULE_PRESENT :c:type:`ca_slot_info`
replace define CA_CI_MODULE_READY :c:type:`ca_slot_info`

# struct ca_descr_info defines
replace define CA_ECD :c:type:`ca_descr_info`
replace define CA_NDS :c:type:`ca_descr_info`
replace define CA_DSS :c:type:`ca_descr_info`

# some typedefs should point to struct/enums
replace typedef ca_slot_info_t :c:type:`ca_slot_info`
replace typedef ca_descr_info_t :c:type:`ca_descr_info`
replace typedef ca_caps_t :c:type:`ca_caps`
replace typedef ca_msg_t :c:type:`ca_msg`
replace typedef ca_descr_t :c:type:`ca_descr`


code:
# SPDX-License-Identifier: GPL-2.0

# Ignore header name
ignore define _CEC_UAPI_H

# define macros to ignore

ignore define CEC_MAX_MSG_SIZE
ignore define CEC_MAX_LOG_ADDRS

ignore define CEC_LOG_ADDR_MASK_TV
ignore define CEC_LOG_ADDR_MASK_RECORD
ignore define CEC_LOG_ADDR_MASK_TUNER
ignore define CEC_LOG_ADDR_MASK_PLAYBACK
ignore define CEC_LOG_ADDR_MASK_AUDIOSYSTEM
ignore define CEC_LOG_ADDR_MASK_BACKUP
ignore define CEC_LOG_ADDR_MASK_SPECIFIC
ignore define CEC_LOG_ADDR_MASK_UNREGISTERED

# Shouldn't them be documented?
ignore define CEC_LOG_ADDR_INVALID
ignore define CEC_PHYS_ADDR_INVALID

ignore define CEC_VENDOR_ID_NONE

ignore define CEC_MODE_INITIATOR_MSK
ignore define CEC_MODE_FOLLOWER_MSK

# Part of CEC 2.0 spec - shouldn't be documented too?
ignore define CEC_LOG_ADDR_TV
ignore define CEC_LOG_ADDR_RECORD_1
ignore define CEC_LOG_ADDR_RECORD_2
ignore define CEC_LOG_ADDR_TUNER_1
ignore define CEC_LOG_ADDR_PLAYBACK_1
ignore define CEC_LOG_ADDR_AUDIOSYSTEM
ignore define CEC_LOG_ADDR_TUNER_2
ignore define CEC_LOG_ADDR_TUNER_3
ignore define CEC_LOG_ADDR_PLAYBACK_2
ignore define CEC_LOG_ADDR_RECORD_3
ignore define CEC_LOG_ADDR_TUNER_4
ignore define CEC_LOG_ADDR_PLAYBACK_3
ignore define CEC_LOG_ADDR_BACKUP_1
ignore define CEC_LOG_ADDR_BACKUP_2
ignore define CEC_LOG_ADDR_SPECIFIC
ignore define CEC_LOG_ADDR_UNREGISTERED
ignore define CEC_LOG_ADDR_BROADCAST

# IMHO, those should also be documented

ignore define CEC_MSG_ACTIVE_SOURCE
ignore define CEC_MSG_IMAGE_VIEW_ON
ignore define CEC_MSG_TEXT_VIEW_ON

ignore define CEC_MSG_INACTIVE_SOURCE
ignore define CEC_MSG_REQUEST_ACTIVE_SOURCE
ignore define CEC_MSG_ROUTING_CHANGE
ignore define CEC_MSG_ROUTING_INFORMATION
ignore define CEC_MSG_SET_STREAM_PATH

ignore define CEC_MSG_STANDBY

ignore define CEC_MSG_RECORD_OFF
ignore define CEC_MSG_RECORD_ON

ignore define CEC_OP_RECORD_SRC_OWN
ignore define CEC_OP_RECORD_SRC_DIGITAL
ignore define CEC_OP_RECORD_SRC_ANALOG
ignore define CEC_OP_RECORD_SRC_EXT_PLUG
ignore define CEC_OP_RECORD_SRC_EXT_PHYS_ADDR

ignore define CEC_OP_SERVICE_ID_METHOD_BY_DIG_ID
ignore define CEC_OP_SERVICE_ID_METHOD_BY_CHANNEL

ignore define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ARIB_GEN
ignore define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ATSC_GEN
ignore define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_DVB_GEN
ignore define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ARIB_BS
ignore define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ARIB_CS
ignore define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ARIB_T
ignore define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ATSC_CABLE
ignore define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ATSC_SAT
ignore define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ATSC_T
ignore define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_DVB_C
ignore define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_DVB_S
ignore define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_DVB_S2
ignore define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_DVB_T

ignore define CEC_OP_ANA_BCAST_TYPE_CABLE
ignore define CEC_OP_ANA_BCAST_TYPE_SATELLITE
ignore define CEC_OP_ANA_BCAST_TYPE_TERRESTRIAL

ignore define CEC_OP_BCAST_SYSTEM_PAL_BG
ignore define CEC_OP_BCAST_SYSTEM_SECAM_LQ
ignore define CEC_OP_BCAST_SYSTEM_PAL_M
ignore define CEC_OP_BCAST_SYSTEM_NTSC_M
ignore define CEC_OP_BCAST_SYSTEM_PAL_I
ignore define CEC_OP_BCAST_SYSTEM_SECAM_DK
ignore define CEC_OP_BCAST_SYSTEM_SECAM_BG
ignore define CEC_OP_BCAST_SYSTEM_SECAM_L
ignore define CEC_OP_BCAST_SYSTEM_PAL_DK
ignore define CEC_OP_BCAST_SYSTEM_OTHER

ignore define CEC_OP_CHANNEL_NUMBER_FMT_1_PART
ignore define CEC_OP_CHANNEL_NUMBER_FMT_2_PART

ignore define CEC_MSG_RECORD_STATUS

ignore define CEC_OP_RECORD_STATUS_CUR_SRC
ignore define CEC_OP_RECORD_STATUS_DIG_SERVICE
ignore define CEC_OP_RECORD_STATUS_ANA_SERVICE
ignore define CEC_OP_RECORD_STATUS_EXT_INPUT
ignore define CEC_OP_RECORD_STATUS_NO_DIG_SERVICE
ignore define CEC_OP_RECORD_STATUS_NO_ANA_SERVICE
ignore define CEC_OP_RECORD_STATUS_NO_SERVICE
ignore define CEC_OP_RECORD_STATUS_INVALID_EXT_PLUG
ignore define CEC_OP_RECORD_STATUS_INVALID_EXT_PHYS_ADDR
ignore define CEC_OP_RECORD_STATUS_UNSUP_CA
ignore define CEC_OP_RECORD_STATUS_NO_CA_ENTITLEMENTS
ignore define CEC_OP_RECORD_STATUS_CANT_COPY_SRC
ignore define CEC_OP_RECORD_STATUS_NO_MORE_COPIES
ignore define CEC_OP_RECORD_STATUS_NO_MEDIA
ignore define CEC_OP_RECORD_STATUS_PLAYING
ignore define CEC_OP_RECORD_STATUS_ALREADY_RECORDING
ignore define CEC_OP_RECORD_STATUS_MEDIA_PROT
ignore define CEC_OP_RECORD_STATUS_NO_SIGNAL
ignore define CEC_OP_RECORD_STATUS_MEDIA_PROBLEM
ignore define CEC_OP_RECORD_STATUS_NO_SPACE
ignore define CEC_OP_RECORD_STATUS_PARENTAL_LOCK
ignore define CEC_OP_RECORD_STATUS_TERMINATED_OK
ignore define CEC_OP_RECORD_STATUS_ALREADY_TERM
ignore define CEC_OP_RECORD_STATUS_OTHER

ignore define CEC_MSG_RECORD_TV_SCREEN

ignore define CEC_MSG_CLEAR_ANALOGUE_TIMER

ignore define CEC_OP_REC_SEQ_SUNDAY
ignore define CEC_OP_REC_SEQ_MONDAY
ignore define CEC_OP_REC_SEQ_TUESDAY
ignore define CEC_OP_REC_SEQ_WEDNESDAY
ignore define CEC_OP_REC_SEQ_THURSDAY
ignore define CEC_OP_REC_SEQ_FRIDAY
ignore define CEC_OP_REC_SEQ_SATURDAY
ignore define CEC_OP_REC_SEQ_ONCE_ONLY

ignore define CEC_MSG_CLEAR_DIGITAL_TIMER

ignore define CEC_MSG_CLEAR_EXT_TIMER

ignore define CEC_OP_EXT_SRC_PLUG
ignore define CEC_OP_EXT_SRC_PHYS_ADDR

ignore define CEC_MSG_SET_ANALOGUE_TIMER
ignore define CEC_MSG_SET_DIGITAL_TIMER
ignore define CEC_MSG_SET_EXT_TIMER

ignore define CEC_MSG_SET_TIMER_PROGRAM_TITLE
ignore define CEC_MSG_TIMER_CLEARED_STATUS

ignore define CEC_OP_TIMER_CLR_STAT_RECORDING
ignore define CEC_OP_TIMER_CLR_STAT_NO_MATCHING
ignore define CEC_OP_TIMER_CLR_STAT_NO_INFO
ignore define CEC_OP_TIMER_CLR_STAT_CLEARED

ignore define CEC_MSG_TIMER_STATUS

ignore define CEC_OP_TIMER_OVERLAP_WARNING_NO_OVERLAP
ignore define CEC_OP_TIMER_OVERLAP_WARNING_OVERLAP

ignore define CEC_OP_MEDIA_INFO_UNPROT_MEDIA
ignore define CEC_OP_MEDIA_INFO_PROT_MEDIA
ignore define CEC_OP_MEDIA_INFO_NO_MEDIA

ignore define CEC_OP_PROG_IND_NOT_PROGRAMMED
ignore define CEC_OP_PROG_IND_PROGRAMMED

ignore define CEC_OP_PROG_INFO_ENOUGH_SPACE
ignore define CEC_OP_PROG_INFO_NOT_ENOUGH_SPACE
ignore define CEC_OP_PROG_INFO_MIGHT_NOT_BE_ENOUGH_SPACE
ignore define CEC_OP_PROG_INFO_NONE_AVAILABLE

ignore define CEC_OP_PROG_ERROR_NO_FREE_TIMER
ignore define CEC_OP_PROG_ERROR_DATE_OUT_OF_RANGE
ignore define CEC_OP_PROG_ERROR_REC_SEQ_ERROR
ignore define CEC_OP_PROG_ERROR_INV_EXT_PLUG
ignore define CEC_OP_PROG_ERROR_INV_EXT_PHYS_ADDR
ignore define CEC_OP_PROG_ERROR_CA_UNSUPP
ignore define CEC_OP_PROG_ERROR_INSUF_CA_ENTITLEMENTS
ignore define CEC_OP_PROG_ERROR_RESOLUTION_UNSUPP
ignore define CEC_OP_PROG_ERROR_PARENTAL_LOCK
ignore define CEC_OP_PROG_ERROR_CLOCK_FAILURE
ignore define CEC_OP_PROG_ERROR_DUPLICATE

ignore define CEC_MSG_CEC_VERSION

ignore define CEC_OP_CEC_VERSION_1_3A
ignore define CEC_OP_CEC_VERSION_1_4
ignore define CEC_OP_CEC_VERSION_2_0

ignore define CEC_MSG_GET_CEC_VERSION
ignore define CEC_MSG_GIVE_PHYSICAL_ADDR
ignore define CEC_MSG_GET_MENU_LANGUAGE
ignore define CEC_MSG_REPORT_PHYSICAL_ADDR

ignore define CEC_OP_PRIM_DEVTYPE_TV
ignore define CEC_OP_PRIM_DEVTYPE_RECORD
ignore define CEC_OP_PRIM_DEVTYPE_TUNER
ignore define CEC_OP_PRIM_DEVTYPE_PLAYBACK
ignore define CEC_OP_PRIM_DEVTYPE_AUDIOSYSTEM
ignore define CEC_OP_PRIM_DEVTYPE_SWITCH
ignore define CEC_OP_PRIM_DEVTYPE_PROCESSOR

ignore define CEC_MSG_SET_MENU_LANGUAGE
ignore define CEC_MSG_REPORT_FEATURES

ignore define CEC_OP_ALL_DEVTYPE_TV
ignore define CEC_OP_ALL_DEVTYPE_RECORD
ignore define CEC_OP_ALL_DEVTYPE_TUNER
ignore define CEC_OP_ALL_DEVTYPE_PLAYBACK
ignore define CEC_OP_ALL_DEVTYPE_AUDIOSYSTEM
ignore define CEC_OP_ALL_DEVTYPE_SWITCH

ignore define CEC_OP_FEAT_EXT

ignore define CEC_OP_FEAT_RC_TV_PROFILE_NONE
ignore define CEC_OP_FEAT_RC_TV_PROFILE_1
ignore define CEC_OP_FEAT_RC_TV_PROFILE_2
ignore define CEC_OP_FEAT_RC_TV_PROFILE_3
ignore define CEC_OP_FEAT_RC_TV_PROFILE_4
ignore define CEC_OP_FEAT_RC_SRC_HAS_DEV_ROOT_MENU
ignore define CEC_OP_FEAT_RC_SRC_HAS_DEV_SETUP_MENU
ignore define CEC_OP_FEAT_RC_SRC_HAS_CONTENTS_MENU
ignore define CEC_OP_FEAT_RC_SRC_HAS_MEDIA_TOP_MENU
ignore define CEC_OP_FEAT_RC_SRC_HAS_MEDIA_CONTEXT_MENU

ignore define CEC_OP_FEAT_DEV_HAS_RECORD_TV_SCREEN
ignore define CEC_OP_FEAT_DEV_HAS_SET_OSD_STRING
ignore define CEC_OP_FEAT_DEV_HAS_DECK_CONTROL
ignore define CEC_OP_FEAT_DEV_HAS_SET_AUDIO_RATE
ignore define CEC_OP_FEAT_DEV_SINK_HAS_ARC_TX
ignore define CEC_OP_FEAT_DEV_SOURCE_HAS_ARC_RX
ignore define CEC_OP_FEAT_DEV_HAS_SET_AUDIO_VOLUME_LEVEL

ignore define CEC_MSG_GIVE_FEATURES

ignore define CEC_MSG_DECK_CONTROL

ignore define CEC_OP_DECK_CTL_MODE_SKIP_FWD
ignore define CEC_OP_DECK_CTL_MODE_SKIP_REV
ignore define CEC_OP_DECK_CTL_MODE_STOP
ignore define CEC_OP_DECK_CTL_MODE_EJECT

ignore define CEC_MSG_DECK_STATUS

ignore define CEC_OP_DECK_INFO_PLAY
ignore define CEC_OP_DECK_INFO_RECORD
ignore define CEC_OP_DECK_INFO_PLAY_REV
ignore define CEC_OP_DECK_INFO_STILL
ignore define CEC_OP_DECK_INFO_SLOW
ignore define CEC_OP_DECK_INFO_SLOW_REV
ignore define CEC_OP_DECK_INFO_FAST_FWD
ignore define CEC_OP_DECK_INFO_FAST_REV
ignore define CEC_OP_DECK_INFO_NO_MEDIA
ignore define CEC_OP_DECK_INFO_STOP
ignore define CEC_OP_DECK_INFO_SKIP_FWD
ignore define CEC_OP_DECK_INFO_SKIP_REV
ignore define CEC_OP_DECK_INFO_INDEX_SEARCH_FWD
ignore define CEC_OP_DECK_INFO_INDEX_SEARCH_REV
ignore define CEC_OP_DECK_INFO_OTHER

ignore define CEC_MSG_GIVE_DECK_STATUS

ignore define CEC_OP_STATUS_REQ_ON
ignore define CEC_OP_STATUS_REQ_OFF
ignore define CEC_OP_STATUS_REQ_ONCE

ignore define CEC_MSG_PLAY

ignore define CEC_OP_PLAY_MODE_PLAY_FWD
ignore define CEC_OP_PLAY_MODE_PLAY_REV
ignore define CEC_OP_PLAY_MODE_PLAY_STILL
ignore define CEC_OP_PLAY_MODE_PLAY_FAST_FWD_MIN
ignore define CEC_OP_PLAY_MODE_PLAY_FAST_FWD_MED
ignore define CEC_OP_PLAY_MODE_PLAY_FAST_FWD_MAX
ignore define CEC_OP_PLAY_MODE_PLAY_FAST_REV_MIN
ignore define CEC_OP_PLAY_MODE_PLAY_FAST_REV_MED
ignore define CEC_OP_PLAY_MODE_PLAY_FAST_REV_MAX
ignore define CEC_OP_PLAY_MODE_PLAY_SLOW_FWD_MIN
ignore define CEC_OP_PLAY_MODE_PLAY_SLOW_FWD_MED
ignore define CEC_OP_PLAY_MODE_PLAY_SLOW_FWD_MAX
ignore define CEC_OP_PLAY_MODE_PLAY_SLOW_REV_MIN
ignore define CEC_OP_PLAY_MODE_PLAY_SLOW_REV_MED
ignore define CEC_OP_PLAY_MODE_PLAY_SLOW_REV_MAX

ignore define CEC_MSG_GIVE_TUNER_DEVICE_STATUS
ignore define CEC_MSG_SELECT_ANALOGUE_SERVICE
ignore define CEC_MSG_SELECT_DIGITAL_SERVICE
ignore define CEC_MSG_TUNER_DEVICE_STATUS

ignore define CEC_OP_REC_FLAG_USED
ignore define CEC_OP_REC_FLAG_NOT_USED

ignore define CEC_OP_TUNER_DISPLAY_INFO_DIGITAL
ignore define CEC_OP_TUNER_DISPLAY_INFO_NONE
ignore define CEC_OP_TUNER_DISPLAY_INFO_ANALOGUE

ignore define CEC_MSG_TUNER_STEP_DECREMENT
ignore define CEC_MSG_TUNER_STEP_INCREMENT

ignore define CEC_MSG_DEVICE_VENDOR_ID
ignore define CEC_MSG_GIVE_DEVICE_VENDOR_ID
ignore define CEC_MSG_VENDOR_COMMAND
ignore define CEC_MSG_VENDOR_COMMAND_WITH_ID
ignore define CEC_MSG_VENDOR_REMOTE_BUTTON_DOWN
ignore define CEC_MSG_VENDOR_REMOTE_BUTTON_UP

ignore define CEC_MSG_SET_OSD_STRING

ignore define CEC_OP_DISP_CTL_DEFAULT
ignore define CEC_OP_DISP_CTL_UNTIL_CLEARED
ignore define CEC_OP_DISP_CTL_CLEAR

ignore define CEC_MSG_GIVE_OSD_NAME
ignore define CEC_MSG_SET_OSD_NAME

ignore define CEC_MSG_MENU_REQUEST

ignore define CEC_OP_MENU_REQUEST_ACTIVATE
ignore define CEC_OP_MENU_REQUEST_DEACTIVATE
ignore define CEC_OP_MENU_REQUEST_QUERY

ignore define CEC_MSG_MENU_STATUS

ignore define CEC_OP_MENU_STATE_ACTIVATED
ignore define CEC_OP_MENU_STATE_DEACTIVATED

ignore define CEC_MSG_USER_CONTROL_PRESSED

ignore define CEC_OP_UI_CMD_SELECT
ignore define CEC_OP_UI_CMD_UP
ignore define CEC_OP_UI_CMD_DOWN
ignore define CEC_OP_UI_CMD_LEFT
ignore define CEC_OP_UI_CMD_RIGHT
ignore define CEC_OP_UI_CMD_RIGHT_UP
ignore define CEC_OP_UI_CMD_RIGHT_DOWN
ignore define CEC_OP_UI_CMD_LEFT_UP
ignore define CEC_OP_UI_CMD_LEFT_DOWN
ignore define CEC_OP_UI_CMD_DEVICE_ROOT_MENU
ignore define CEC_OP_UI_CMD_DEVICE_SETUP_MENU
ignore define CEC_OP_UI_CMD_CONTENTS_MENU
ignore define CEC_OP_UI_CMD_FAVORITE_MENU
ignore define CEC_OP_UI_CMD_BACK
ignore define CEC_OP_UI_CMD_MEDIA_TOP_MENU
ignore define CEC_OP_UI_CMD_MEDIA_CONTEXT_SENSITIVE_MENU
ignore define CEC_OP_UI_CMD_NUMBER_ENTRY_MODE
ignore define CEC_OP_UI_CMD_NUMBER_11
ignore define CEC_OP_UI_CMD_NUMBER_12
ignore define CEC_OP_UI_CMD_NUMBER_0_OR_NUMBER_10
ignore define CEC_OP_UI_CMD_NUMBER_1
ignore define CEC_OP_UI_CMD_NUMBER_2
ignore define CEC_OP_UI_CMD_NUMBER_3
ignore define CEC_OP_UI_CMD_NUMBER_4
ignore define CEC_OP_UI_CMD_NUMBER_5
ignore define CEC_OP_UI_CMD_NUMBER_6
ignore define CEC_OP_UI_CMD_NUMBER_7
ignore define CEC_OP_UI_CMD_NUMBER_8
ignore define CEC_OP_UI_CMD_NUMBER_9
ignore define CEC_OP_UI_CMD_DOT
ignore define CEC_OP_UI_CMD_ENTER
ignore define CEC_OP_UI_CMD_CLEAR
ignore define CEC_OP_UI_CMD_NEXT_FAVORITE
ignore define CEC_OP_UI_CMD_CHANNEL_UP
ignore define CEC_OP_UI_CMD_CHANNEL_DOWN
ignore define CEC_OP_UI_CMD_PREVIOUS_CHANNEL
ignore define CEC_OP_UI_CMD_SOUND_SELECT
ignore define CEC_OP_UI_CMD_INPUT_SELECT
ignore define CEC_OP_UI_CMD_DISPLAY_INFORMATION
ignore define CEC_OP_UI_CMD_HELP
ignore define CEC_OP_UI_CMD_PAGE_UP
ignore define CEC_OP_UI_CMD_PAGE_DOWN
ignore define CEC_OP_UI_CMD_POWER
ignore define CEC_OP_UI_CMD_VOLUME_UP
ignore define CEC_OP_UI_CMD_VOLUME_DOWN
ignore define CEC_OP_UI_CMD_MUTE
ignore define CEC_OP_UI_CMD_PLAY
ignore define CEC_OP_UI_CMD_STOP
ignore define CEC_OP_UI_CMD_PAUSE
ignore define CEC_OP_UI_CMD_RECORD
ignore define CEC_OP_UI_CMD_REWIND
ignore define CEC_OP_UI_CMD_FAST_FORWARD
ignore define CEC_OP_UI_CMD_EJECT
ignore define CEC_OP_UI_CMD_SKIP_FORWARD
ignore define CEC_OP_UI_CMD_SKIP_BACKWARD
ignore define CEC_OP_UI_CMD_STOP_RECORD
ignore define CEC_OP_UI_CMD_PAUSE_RECORD
ignore define CEC_OP_UI_CMD_ANGLE
ignore define CEC_OP_UI_CMD_SUB_PICTURE
ignore define CEC_OP_UI_CMD_VIDEO_ON_DEMAND
ignore define CEC_OP_UI_CMD_ELECTRONIC_PROGRAM_GUIDE
ignore define CEC_OP_UI_CMD_TIMER_PROGRAMMING
ignore define CEC_OP_UI_CMD_INITIAL_CONFIGURATION
ignore define CEC_OP_UI_CMD_SELECT_BROADCAST_TYPE
ignore define CEC_OP_UI_CMD_SELECT_SOUND_PRESENTATION
ignore define CEC_OP_UI_CMD_AUDIO_DESCRIPTION
ignore define CEC_OP_UI_CMD_INTERNET
ignore define CEC_OP_UI_CMD_3D_MODE
ignore define CEC_OP_UI_CMD_PLAY_FUNCTION
ignore define CEC_OP_UI_CMD_PAUSE_PLAY_FUNCTION
ignore define CEC_OP_UI_CMD_RECORD_FUNCTION
ignore define CEC_OP_UI_CMD_PAUSE_RECORD_FUNCTION
ignore define CEC_OP_UI_CMD_STOP_FUNCTION
ignore define CEC_OP_UI_CMD_MUTE_FUNCTION
ignore define CEC_OP_UI_CMD_RESTORE_VOLUME_FUNCTION
ignore define CEC_OP_UI_CMD_TUNE_FUNCTION
ignore define CEC_OP_UI_CMD_SELECT_MEDIA_FUNCTION
ignore define CEC_OP_UI_CMD_SELECT_AV_INPUT_FUNCTION
ignore define CEC_OP_UI_CMD_SELECT_AUDIO_INPUT_FUNCTION
ignore define CEC_OP_UI_CMD_POWER_TOGGLE_FUNCTION
ignore define CEC_OP_UI_CMD_POWER_OFF_FUNCTION
ignore define CEC_OP_UI_CMD_POWER_ON_FUNCTION
ignore define CEC_OP_UI_CMD_F1_BLUE
ignore define CEC_OP_UI_CMD_F2_RED
ignore define CEC_OP_UI_CMD_F3_GREEN
ignore define CEC_OP_UI_CMD_F4_YELLOW
ignore define CEC_OP_UI_CMD_F5
ignore define CEC_OP_UI_CMD_DATA

ignore define CEC_OP_UI_BCAST_TYPE_TOGGLE_ALL
ignore define CEC_OP_UI_BCAST_TYPE_TOGGLE_DIG_ANA
ignore define CEC_OP_UI_BCAST_TYPE_ANALOGUE
ignore define CEC_OP_UI_BCAST_TYPE_ANALOGUE_T
ignore define CEC_OP_UI_BCAST_TYPE_ANALOGUE_CABLE
ignore define CEC_OP_UI_BCAST_TYPE_ANALOGUE_SAT
ignore define CEC_OP_UI_BCAST_TYPE_DIGITAL
ignore define CEC_OP_UI_BCAST_TYPE_DIGITAL_T
ignore define CEC_OP_UI_BCAST_TYPE_DIGITAL_CABLE
ignore define CEC_OP_UI_BCAST_TYPE_DIGITAL_SAT
ignore define CEC_OP_UI_BCAST_TYPE_DIGITAL_COM_SAT
ignore define CEC_OP_UI_BCAST_TYPE_DIGITAL_COM_SAT2
ignore define CEC_OP_UI_BCAST_TYPE_IP

ignore define CEC_OP_UI_SND_PRES_CTL_DUAL_MONO
ignore define CEC_OP_UI_SND_PRES_CTL_KARAOKE
ignore define CEC_OP_UI_SND_PRES_CTL_DOWNMIX
ignore define CEC_OP_UI_SND_PRES_CTL_REVERB
ignore define CEC_OP_UI_SND_PRES_CTL_EQUALIZER
ignore define CEC_OP_UI_SND_PRES_CTL_BASS_UP
ignore define CEC_OP_UI_SND_PRES_CTL_BASS_NEUTRAL
ignore define CEC_OP_UI_SND_PRES_CTL_BASS_DOWN
ignore define CEC_OP_UI_SND_PRES_CTL_TREBLE_UP
ignore define CEC_OP_UI_SND_PRES_CTL_TREBLE_NEUTRAL
ignore define CEC_OP_UI_SND_PRES_CTL_TREBLE_DOWN

ignore define CEC_MSG_USER_CONTROL_RELEASED

ignore define CEC_MSG_GIVE_DEVICE_POWER_STATUS
ignore define CEC_MSG_REPORT_POWER_STATUS

ignore define CEC_OP_POWER_STATUS_ON
ignore define CEC_OP_POWER_STATUS_STANDBY
ignore define CEC_OP_POWER_STATUS_TO_ON
ignore define CEC_OP_POWER_STATUS_TO_STANDBY

ignore define CEC_MSG_FEATURE_ABORT

ignore define CEC_OP_ABORT_UNRECOGNIZED_OP
ignore define CEC_OP_ABORT_INCORRECT_MODE
ignore define CEC_OP_ABORT_NO_SOURCE
ignore define CEC_OP_ABORT_INVALID_OP
ignore define CEC_OP_ABORT_REFUSED
ignore define CEC_OP_ABORT_UNDETERMINED

ignore define CEC_MSG_ABORT

ignore define CEC_MSG_GIVE_AUDIO_STATUS
ignore define CEC_MSG_GIVE_SYSTEM_AUDIO_MODE_STATUS
ignore define CEC_MSG_REPORT_AUDIO_STATUS

ignore define CEC_OP_AUD_MUTE_STATUS_OFF
ignore define CEC_OP_AUD_MUTE_STATUS_ON

ignore define CEC_MSG_REPORT_SHORT_AUDIO_DESCRIPTOR
ignore define CEC_MSG_REQUEST_SHORT_AUDIO_DESCRIPTOR
ignore define CEC_MSG_SET_SYSTEM_AUDIO_MODE

ignore define CEC_OP_SYS_AUD_STATUS_OFF
ignore define CEC_OP_SYS_AUD_STATUS_ON

ignore define CEC_MSG_SYSTEM_AUDIO_MODE_REQUEST
ignore define CEC_MSG_SYSTEM_AUDIO_MODE_STATUS
ignore define CEC_MSG_SET_AUDIO_VOLUME_LEVEL

ignore define CEC_OP_AUD_FMT_ID_CEA861
ignore define CEC_OP_AUD_FMT_ID_CEA861_CXT

ignore define CEC_MSG_SET_AUDIO_RATE

ignore define CEC_OP_AUD_RATE_OFF
ignore define CEC_OP_AUD_RATE_WIDE_STD
ignore define CEC_OP_AUD_RATE_WIDE_FAST
ignore define CEC_OP_AUD_RATE_WIDE_SLOW
ignore define CEC_OP_AUD_RATE_NARROW_STD
ignore define CEC_OP_AUD_RATE_NARROW_FAST
ignore define CEC_OP_AUD_RATE_NARROW_SLOW

ignore define CEC_MSG_INITIATE_ARC
ignore define CEC_MSG_REPORT_ARC_INITIATED
ignore define CEC_MSG_REPORT_ARC_TERMINATED
ignore define CEC_MSG_REQUEST_ARC_INITIATION
ignore define CEC_MSG_REQUEST_ARC_TERMINATION
ignore define CEC_MSG_TERMINATE_ARC

ignore define CEC_MSG_REQUEST_CURRENT_LATENCY
ignore define CEC_MSG_REPORT_CURRENT_LATENCY

ignore define CEC_OP_LOW_LATENCY_MODE_OFF
ignore define CEC_OP_LOW_LATENCY_MODE_ON

ignore define CEC_OP_AUD_OUT_COMPENSATED_NA
ignore define CEC_OP_AUD_OUT_COMPENSATED_DELAY
ignore define CEC_OP_AUD_OUT_COMPENSATED_NO_DELAY
ignore define CEC_OP_AUD_OUT_COMPENSATED_PARTIAL_DELAY

ignore define CEC_MSG_CDC_MESSAGE

ignore define CEC_MSG_CDC_HEC_INQUIRE_STATE
ignore define CEC_MSG_CDC_HEC_REPORT_STATE

ignore define CEC_OP_HEC_FUNC_STATE_NOT_SUPPORTED
ignore define CEC_OP_HEC_FUNC_STATE_INACTIVE
ignore define CEC_OP_HEC_FUNC_STATE_ACTIVE
ignore define CEC_OP_HEC_FUNC_STATE_ACTIVATION_FIELD

ignore define CEC_OP_HOST_FUNC_STATE_NOT_SUPPORTED
ignore define CEC_OP_HOST_FUNC_STATE_INACTIVE
ignore define CEC_OP_HOST_FUNC_STATE_ACTIVE

ignore define CEC_OP_ENC_FUNC_STATE_EXT_CON_NOT_SUPPORTED
ignore define CEC_OP_ENC_FUNC_STATE_EXT_CON_INACTIVE
ignore define CEC_OP_ENC_FUNC_STATE_EXT_CON_ACTIVE

ignore define CEC_OP_CDC_ERROR_CODE_NONE
ignore define CEC_OP_CDC_ERROR_CODE_CAP_UNSUPPORTED
ignore define CEC_OP_CDC_ERROR_CODE_WRONG_STATE
ignore define CEC_OP_CDC_ERROR_CODE_OTHER

ignore define CEC_OP_HEC_SUPPORT_NO
ignore define CEC_OP_HEC_SUPPORT_YES

ignore define CEC_OP_HEC_ACTIVATION_ON
ignore define CEC_OP_HEC_ACTIVATION_OFF

ignore define CEC_MSG_CDC_HEC_SET_STATE_ADJACENT
ignore define CEC_MSG_CDC_HEC_SET_STATE

ignore define CEC_OP_HEC_SET_STATE_DEACTIVATE
ignore define CEC_OP_HEC_SET_STATE_ACTIVATE

ignore define CEC_MSG_CDC_HEC_REQUEST_DEACTIVATION
ignore define CEC_MSG_CDC_HEC_NOTIFY_ALIVE
ignore define CEC_MSG_CDC_HEC_DISCOVER

ignore define CEC_MSG_CDC_HPD_SET_STATE

ignore define CEC_OP_HPD_STATE_CP_EDID_DISABLE
ignore define CEC_OP_HPD_STATE_CP_EDID_ENABLE
ignore define CEC_OP_HPD_STATE_CP_EDID_DISABLE_ENABLE
ignore define CEC_OP_HPD_STATE_EDID_DISABLE
ignore define CEC_OP_HPD_STATE_EDID_ENABLE
ignore define CEC_OP_HPD_STATE_EDID_DISABLE_ENABLE
ignore define CEC_MSG_CDC_HPD_REPORT_STATE

ignore define CEC_OP_HPD_ERROR_NONE
ignore define CEC_OP_HPD_ERROR_INITIATOR_NOT_CAPABLE
ignore define CEC_OP_HPD_ERROR_INITIATOR_WRONG_STATE
ignore define CEC_OP_HPD_ERROR_OTHER
ignore define CEC_OP_HPD_ERROR_NONE_NO_VIDEO


code:
.. 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


code:
.. 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.


code:
.. 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.


code:
.. 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.


code:
.. 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.


code:
.. 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


code:
.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later

.. _cec_header:

***************
CEC Header File
***************

.. kernel-include:: $BUILDDIR/cec.h.rst


code:
.. 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.


code:
.. 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.


code:
.. 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.


code:
.. 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.


code:
.. 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.


code:
.. 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.


code:
.. 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.