2018-08-30 22:20:04 +08:00
|
|
|
.. SPDX-License-Identifier: GPL-2.0
|
|
|
|
|
2016-07-21 02:27:04 +08:00
|
|
|
V4L2 sub-devices
|
|
|
|
----------------
|
|
|
|
|
|
|
|
Many drivers need to communicate with sub-devices. These devices can do all
|
|
|
|
sort of tasks, but most commonly they handle audio and/or video muxing,
|
|
|
|
encoding or decoding. For webcams common sub-devices are sensors and camera
|
|
|
|
controllers.
|
|
|
|
|
|
|
|
Usually these are I2C devices, but not necessarily. In order to provide the
|
2016-07-21 20:09:58 +08:00
|
|
|
driver with a consistent interface to these sub-devices the
|
|
|
|
:c:type:`v4l2_subdev` struct (v4l2-subdev.h) was created.
|
|
|
|
|
|
|
|
Each sub-device driver must have a :c:type:`v4l2_subdev` struct. This struct
|
|
|
|
can be stand-alone for simple sub-devices or it might be embedded in a larger
|
|
|
|
struct if more state information needs to be stored. Usually there is a
|
|
|
|
low-level device struct (e.g. ``i2c_client``) that contains the device data as
|
|
|
|
setup by the kernel. It is recommended to store that pointer in the private
|
2016-07-23 18:21:06 +08:00
|
|
|
data of :c:type:`v4l2_subdev` using :c:func:`v4l2_set_subdevdata`. That makes
|
2016-07-21 20:09:58 +08:00
|
|
|
it easy to go from a :c:type:`v4l2_subdev` to the actual low-level bus-specific
|
|
|
|
device data.
|
|
|
|
|
|
|
|
You also need a way to go from the low-level struct to :c:type:`v4l2_subdev`.
|
|
|
|
For the common i2c_client struct the i2c_set_clientdata() call is used to store
|
2019-02-19 03:29:07 +08:00
|
|
|
a :c:type:`v4l2_subdev` pointer, for other buses you may have to use other
|
2016-07-21 20:09:58 +08:00
|
|
|
methods.
|
2016-07-21 02:27:04 +08:00
|
|
|
|
|
|
|
Bridges might also need to store per-subdev private data, such as a pointer to
|
2016-07-21 20:09:58 +08:00
|
|
|
bridge-specific per-subdev private data. The :c:type:`v4l2_subdev` structure
|
|
|
|
provides host private data for that purpose that can be accessed with
|
2016-08-19 23:00:43 +08:00
|
|
|
:c:func:`v4l2_get_subdev_hostdata` and :c:func:`v4l2_set_subdev_hostdata`.
|
2016-07-21 02:27:04 +08:00
|
|
|
|
2016-07-21 20:09:58 +08:00
|
|
|
From the bridge driver perspective, you load the sub-device module and somehow
|
|
|
|
obtain the :c:type:`v4l2_subdev` pointer. For i2c devices this is easy: you call
|
2019-02-19 03:29:07 +08:00
|
|
|
``i2c_get_clientdata()``. For other buses something similar needs to be done.
|
2016-07-21 02:27:04 +08:00
|
|
|
Helper functions exists for sub-devices on an I2C bus that do most of this
|
|
|
|
tricky work for you.
|
|
|
|
|
2016-07-21 20:09:58 +08:00
|
|
|
Each :c:type:`v4l2_subdev` contains function pointers that sub-device drivers
|
|
|
|
can implement (or leave ``NULL`` if it is not applicable). Since sub-devices can
|
|
|
|
do so many different things and you do not want to end up with a huge ops struct
|
2016-07-21 02:27:04 +08:00
|
|
|
of which only a handful of ops are commonly implemented, the function pointers
|
|
|
|
are sorted according to category and each category has its own ops struct.
|
|
|
|
|
|
|
|
The top-level ops struct contains pointers to the category ops structs, which
|
|
|
|
may be NULL if the subdev driver does not support anything from that category.
|
|
|
|
|
|
|
|
It looks like this:
|
|
|
|
|
2016-07-21 20:09:58 +08:00
|
|
|
.. code-block:: c
|
2016-07-21 02:27:04 +08:00
|
|
|
|
|
|
|
struct v4l2_subdev_core_ops {
|
|
|
|
int (*log_status)(struct v4l2_subdev *sd);
|
|
|
|
int (*init)(struct v4l2_subdev *sd, u32 val);
|
|
|
|
...
|
|
|
|
};
|
|
|
|
|
|
|
|
struct v4l2_subdev_tuner_ops {
|
|
|
|
...
|
|
|
|
};
|
|
|
|
|
|
|
|
struct v4l2_subdev_audio_ops {
|
|
|
|
...
|
|
|
|
};
|
|
|
|
|
|
|
|
struct v4l2_subdev_video_ops {
|
|
|
|
...
|
|
|
|
};
|
|
|
|
|
|
|
|
struct v4l2_subdev_pad_ops {
|
|
|
|
...
|
|
|
|
};
|
|
|
|
|
|
|
|
struct v4l2_subdev_ops {
|
|
|
|
const struct v4l2_subdev_core_ops *core;
|
|
|
|
const struct v4l2_subdev_tuner_ops *tuner;
|
|
|
|
const struct v4l2_subdev_audio_ops *audio;
|
|
|
|
const struct v4l2_subdev_video_ops *video;
|
|
|
|
const struct v4l2_subdev_pad_ops *video;
|
|
|
|
};
|
|
|
|
|
|
|
|
The core ops are common to all subdevs, the other categories are implemented
|
|
|
|
depending on the sub-device. E.g. a video device is unlikely to support the
|
|
|
|
audio ops and vice versa.
|
|
|
|
|
|
|
|
This setup limits the number of function pointers while still making it easy
|
|
|
|
to add new ops and categories.
|
|
|
|
|
2016-07-21 20:09:58 +08:00
|
|
|
A sub-device driver initializes the :c:type:`v4l2_subdev` struct using:
|
2016-07-21 02:27:04 +08:00
|
|
|
|
2016-07-23 18:21:06 +08:00
|
|
|
:c:func:`v4l2_subdev_init <v4l2_subdev_init>`
|
2016-07-21 20:09:58 +08:00
|
|
|
(:c:type:`sd <v4l2_subdev>`, &\ :c:type:`ops <v4l2_subdev_ops>`).
|
2016-07-21 02:27:04 +08:00
|
|
|
|
|
|
|
|
2016-07-21 20:09:58 +08:00
|
|
|
Afterwards you need to initialize :c:type:`sd <v4l2_subdev>`->name with a
|
|
|
|
unique name and set the module owner. This is done for you if you use the
|
|
|
|
i2c helper functions.
|
2016-07-21 02:27:04 +08:00
|
|
|
|
|
|
|
If integration with the media framework is needed, you must initialize the
|
2016-07-21 20:09:58 +08:00
|
|
|
:c:type:`media_entity` struct embedded in the :c:type:`v4l2_subdev` struct
|
2016-07-23 18:21:06 +08:00
|
|
|
(entity field) by calling :c:func:`media_entity_pads_init`, if the entity has
|
2016-07-21 20:09:58 +08:00
|
|
|
pads:
|
2016-07-21 02:27:04 +08:00
|
|
|
|
2016-07-21 20:09:58 +08:00
|
|
|
.. code-block:: c
|
2016-07-21 02:27:04 +08:00
|
|
|
|
|
|
|
struct media_pad *pads = &my_sd->pads;
|
|
|
|
int err;
|
|
|
|
|
|
|
|
err = media_entity_pads_init(&sd->entity, npads, pads);
|
|
|
|
|
|
|
|
The pads array must have been previously initialized. There is no need to
|
2016-07-21 20:09:58 +08:00
|
|
|
manually set the struct :c:type:`media_entity` function and name fields, but the
|
2016-07-21 02:27:04 +08:00
|
|
|
revision field must be initialized if needed.
|
|
|
|
|
|
|
|
A reference to the entity will be automatically acquired/released when the
|
|
|
|
subdev device node (if any) is opened/closed.
|
|
|
|
|
|
|
|
Don't forget to cleanup the media entity before the sub-device is destroyed:
|
|
|
|
|
2016-07-21 20:09:58 +08:00
|
|
|
.. code-block:: c
|
2016-07-21 02:27:04 +08:00
|
|
|
|
|
|
|
media_entity_cleanup(&sd->entity);
|
|
|
|
|
|
|
|
If the subdev driver intends to process video and integrate with the media
|
|
|
|
framework, it must implement format related functionality using
|
2016-07-21 20:09:58 +08:00
|
|
|
:c:type:`v4l2_subdev_pad_ops` instead of :c:type:`v4l2_subdev_video_ops`.
|
2016-07-21 02:27:04 +08:00
|
|
|
|
|
|
|
In that case, the subdev driver may set the link_validate field to provide
|
|
|
|
its own link validation function. The link validation function is called for
|
|
|
|
every link in the pipeline where both of the ends of the links are V4L2
|
|
|
|
sub-devices. The driver is still responsible for validating the correctness
|
|
|
|
of the format configuration between sub-devices and video nodes.
|
|
|
|
|
|
|
|
If link_validate op is not set, the default function
|
2016-07-23 18:21:06 +08:00
|
|
|
:c:func:`v4l2_subdev_link_validate_default` is used instead. This function
|
2016-07-21 20:09:58 +08:00
|
|
|
ensures that width, height and the media bus pixel code are equal on both source
|
|
|
|
and sink of the link. Subdev drivers are also free to use this function to
|
2016-07-21 02:27:04 +08:00
|
|
|
perform the checks mentioned above in addition to their own checks.
|
|
|
|
|
|
|
|
There are currently two ways to register subdevices with the V4L2 core. The
|
|
|
|
first (traditional) possibility is to have subdevices registered by bridge
|
|
|
|
drivers. This can be done when the bridge driver has the complete information
|
|
|
|
about subdevices connected to it and knows exactly when to register them. This
|
|
|
|
is typically the case for internal subdevices, like video data processing units
|
|
|
|
within SoCs or complex PCI(e) boards, camera sensors in USB cameras or connected
|
|
|
|
to SoCs, which pass information about them to bridge drivers, usually in their
|
|
|
|
platform data.
|
|
|
|
|
|
|
|
There are however also situations where subdevices have to be registered
|
|
|
|
asynchronously to bridge devices. An example of such a configuration is a Device
|
|
|
|
Tree based system where information about subdevices is made available to the
|
|
|
|
system independently from the bridge devices, e.g. when subdevices are defined
|
|
|
|
in DT as I2C device nodes. The API used in this second case is described further
|
|
|
|
below.
|
|
|
|
|
|
|
|
Using one or the other registration method only affects the probing process, the
|
|
|
|
run-time bridge-subdevice interaction is in both cases the same.
|
|
|
|
|
|
|
|
In the synchronous case a device (bridge) driver needs to register the
|
2016-07-21 20:09:58 +08:00
|
|
|
:c:type:`v4l2_subdev` with the v4l2_device:
|
2016-07-21 02:27:04 +08:00
|
|
|
|
2016-07-23 18:21:06 +08:00
|
|
|
:c:func:`v4l2_device_register_subdev <v4l2_device_register_subdev>`
|
2016-07-21 20:09:58 +08:00
|
|
|
(:c:type:`v4l2_dev <v4l2_device>`, :c:type:`sd <v4l2_subdev>`).
|
2016-07-21 02:27:04 +08:00
|
|
|
|
|
|
|
This can fail if the subdev module disappeared before it could be registered.
|
|
|
|
After this function was called successfully the subdev->dev field points to
|
2016-07-21 20:09:58 +08:00
|
|
|
the :c:type:`v4l2_device`.
|
2016-07-21 02:27:04 +08:00
|
|
|
|
|
|
|
If the v4l2_device parent device has a non-NULL mdev field, the sub-device
|
|
|
|
entity will be automatically registered with the media device.
|
|
|
|
|
|
|
|
You can unregister a sub-device using:
|
|
|
|
|
2016-07-23 18:21:06 +08:00
|
|
|
:c:func:`v4l2_device_unregister_subdev <v4l2_device_unregister_subdev>`
|
2016-07-21 20:09:58 +08:00
|
|
|
(:c:type:`sd <v4l2_subdev>`).
|
2016-07-21 02:27:04 +08:00
|
|
|
|
|
|
|
|
2016-07-21 20:09:58 +08:00
|
|
|
Afterwards the subdev module can be unloaded and
|
|
|
|
:c:type:`sd <v4l2_subdev>`->dev == ``NULL``.
|
2016-07-21 02:27:04 +08:00
|
|
|
|
|
|
|
You can call an ops function either directly:
|
|
|
|
|
2016-07-21 20:09:58 +08:00
|
|
|
.. code-block:: c
|
2016-07-21 02:27:04 +08:00
|
|
|
|
|
|
|
err = sd->ops->core->g_std(sd, &norm);
|
|
|
|
|
|
|
|
but it is better and easier to use this macro:
|
|
|
|
|
2016-07-21 20:09:58 +08:00
|
|
|
.. code-block:: c
|
2016-07-21 02:27:04 +08:00
|
|
|
|
|
|
|
err = v4l2_subdev_call(sd, core, g_std, &norm);
|
|
|
|
|
2020-09-22 04:21:31 +08:00
|
|
|
The macro will do the right ``NULL`` pointer checks and returns ``-ENODEV``
|
2016-07-21 20:09:58 +08:00
|
|
|
if :c:type:`sd <v4l2_subdev>` is ``NULL``, ``-ENOIOCTLCMD`` if either
|
|
|
|
:c:type:`sd <v4l2_subdev>`->core or :c:type:`sd <v4l2_subdev>`->core->g_std is ``NULL``, or the actual result of the
|
|
|
|
:c:type:`sd <v4l2_subdev>`->ops->core->g_std ops.
|
2016-07-21 02:27:04 +08:00
|
|
|
|
|
|
|
It is also possible to call all or a subset of the sub-devices:
|
|
|
|
|
2016-07-21 20:09:58 +08:00
|
|
|
.. code-block:: c
|
2016-07-21 02:27:04 +08:00
|
|
|
|
|
|
|
v4l2_device_call_all(v4l2_dev, 0, core, g_std, &norm);
|
|
|
|
|
|
|
|
Any subdev that does not support this ops is skipped and error results are
|
|
|
|
ignored. If you want to check for errors use this:
|
|
|
|
|
2016-07-21 20:09:58 +08:00
|
|
|
.. code-block:: c
|
2016-07-21 02:27:04 +08:00
|
|
|
|
|
|
|
err = v4l2_device_call_until_err(v4l2_dev, 0, core, g_std, &norm);
|
|
|
|
|
2016-07-21 20:09:58 +08:00
|
|
|
Any error except ``-ENOIOCTLCMD`` will exit the loop with that error. If no
|
|
|
|
errors (except ``-ENOIOCTLCMD``) occurred, then 0 is returned.
|
2016-07-21 02:27:04 +08:00
|
|
|
|
|
|
|
The second argument to both calls is a group ID. If 0, then all subdevs are
|
|
|
|
called. If non-zero, then only those whose group ID match that value will
|
2016-07-21 20:09:58 +08:00
|
|
|
be called. Before a bridge driver registers a subdev it can set
|
|
|
|
:c:type:`sd <v4l2_subdev>`->grp_id to whatever value it wants (it's 0 by
|
|
|
|
default). This value is owned by the bridge driver and the sub-device driver
|
|
|
|
will never modify or use it.
|
2016-07-21 02:27:04 +08:00
|
|
|
|
|
|
|
The group ID gives the bridge driver more control how callbacks are called.
|
|
|
|
For example, there may be multiple audio chips on a board, each capable of
|
|
|
|
changing the volume. But usually only one will actually be used when the
|
|
|
|
user want to change the volume. You can set the group ID for that subdev to
|
|
|
|
e.g. AUDIO_CONTROLLER and specify that as the group ID value when calling
|
2016-07-21 20:09:58 +08:00
|
|
|
``v4l2_device_call_all()``. That ensures that it will only go to the subdev
|
2016-07-21 02:27:04 +08:00
|
|
|
that needs it.
|
|
|
|
|
|
|
|
If the sub-device needs to notify its v4l2_device parent of an event, then
|
2016-07-21 20:09:58 +08:00
|
|
|
it can call ``v4l2_subdev_notify(sd, notification, arg)``. This macro checks
|
|
|
|
whether there is a ``notify()`` callback defined and returns ``-ENODEV`` if not.
|
|
|
|
Otherwise the result of the ``notify()`` call is returned.
|
2016-07-21 02:27:04 +08:00
|
|
|
|
2016-07-21 20:09:58 +08:00
|
|
|
The advantage of using :c:type:`v4l2_subdev` is that it is a generic struct and
|
|
|
|
does not contain any knowledge about the underlying hardware. So a driver might
|
2016-07-21 02:27:04 +08:00
|
|
|
contain several subdevs that use an I2C bus, but also a subdev that is
|
|
|
|
controlled through GPIO pins. This distinction is only relevant when setting
|
|
|
|
up the device, but once the subdev is registered it is completely transparent.
|
|
|
|
|
|
|
|
In the asynchronous case subdevice probing can be invoked independently of the
|
|
|
|
bridge driver availability. The subdevice driver then has to verify whether all
|
|
|
|
the requirements for a successful probing are satisfied. This can include a
|
|
|
|
check for a master clock availability. If any of the conditions aren't satisfied
|
2016-07-21 20:09:58 +08:00
|
|
|
the driver might decide to return ``-EPROBE_DEFER`` to request further reprobing
|
2016-07-21 02:27:04 +08:00
|
|
|
attempts. Once all conditions are met the subdevice shall be registered using
|
2016-07-23 18:21:06 +08:00
|
|
|
the :c:func:`v4l2_async_register_subdev` function. Unregistration is
|
|
|
|
performed using the :c:func:`v4l2_async_unregister_subdev` call. Subdevices
|
2016-07-21 20:09:58 +08:00
|
|
|
registered this way are stored in a global list of subdevices, ready to be
|
|
|
|
picked up by bridge drivers.
|
2016-07-21 02:27:04 +08:00
|
|
|
|
2018-09-30 03:54:20 +08:00
|
|
|
Bridge drivers in turn have to register a notifier object. This is
|
2016-07-23 18:21:06 +08:00
|
|
|
performed using the :c:func:`v4l2_async_notifier_register` call. To
|
2016-07-21 20:09:58 +08:00
|
|
|
unregister the notifier the driver has to call
|
2016-07-23 18:21:06 +08:00
|
|
|
:c:func:`v4l2_async_notifier_unregister`. The former of the two functions
|
2018-09-30 03:54:20 +08:00
|
|
|
takes two arguments: a pointer to struct :c:type:`v4l2_device` and a
|
|
|
|
pointer to struct :c:type:`v4l2_async_notifier`.
|
|
|
|
|
|
|
|
Before registering the notifier, bridge drivers must do two things:
|
|
|
|
first, the notifier must be initialized using the
|
|
|
|
:c:func:`v4l2_async_notifier_init`. Second, bridge drivers can then
|
|
|
|
begin to form a list of subdevice descriptors that the bridge device
|
|
|
|
needs for its operation. Subdevice descriptors are added to the notifier
|
|
|
|
using the :c:func:`v4l2_async_notifier_add_subdev` call. This function
|
|
|
|
takes two arguments: a pointer to struct :c:type:`v4l2_async_notifier`,
|
|
|
|
and a pointer to the subdevice descripter, which is of type struct
|
|
|
|
:c:type:`v4l2_async_subdev`.
|
|
|
|
|
|
|
|
The V4L2 core will then use these descriptors to match asynchronously
|
|
|
|
registered subdevices to them. If a match is detected the ``.bound()``
|
|
|
|
notifier callback is called. After all subdevices have been located the
|
|
|
|
.complete() callback is called. When a subdevice is removed from the
|
|
|
|
system the .unbind() method is called. All three callbacks are optional.
|
2016-07-21 02:27:04 +08:00
|
|
|
|
2016-07-21 20:27:37 +08:00
|
|
|
V4L2 sub-device userspace API
|
|
|
|
-----------------------------
|
|
|
|
|
2020-05-07 23:12:48 +08:00
|
|
|
Bridge drivers traditionally expose one or multiple video nodes to userspace,
|
|
|
|
and control subdevices through the :c:type:`v4l2_subdev_ops` operations in
|
|
|
|
response to video node operations. This hides the complexity of the underlying
|
|
|
|
hardware from applications. For complex devices, finer-grained control of the
|
|
|
|
device than what the video nodes offer may be required. In those cases, bridge
|
|
|
|
drivers that implement :ref:`the media controller API <media_controller>` may
|
|
|
|
opt for making the subdevice operations directly accessible from userpace.
|
2016-07-21 20:27:37 +08:00
|
|
|
|
2016-07-21 20:49:32 +08:00
|
|
|
Device nodes named ``v4l-subdev``\ *X* can be created in ``/dev`` to access
|
|
|
|
sub-devices directly. If a sub-device supports direct userspace configuration
|
|
|
|
it must set the ``V4L2_SUBDEV_FL_HAS_DEVNODE`` flag before being registered.
|
2016-07-21 20:27:37 +08:00
|
|
|
|
2016-07-21 20:49:32 +08:00
|
|
|
After registering sub-devices, the :c:type:`v4l2_device` driver can create
|
|
|
|
device nodes for all registered sub-devices marked with
|
|
|
|
``V4L2_SUBDEV_FL_HAS_DEVNODE`` by calling
|
2016-07-23 18:21:06 +08:00
|
|
|
:c:func:`v4l2_device_register_subdev_nodes`. Those device nodes will be
|
2016-07-21 20:49:32 +08:00
|
|
|
automatically removed when sub-devices are unregistered.
|
2016-07-21 20:27:37 +08:00
|
|
|
|
|
|
|
The device node handles a subset of the V4L2 API.
|
|
|
|
|
2016-07-21 20:49:32 +08:00
|
|
|
``VIDIOC_QUERYCTRL``,
|
|
|
|
``VIDIOC_QUERYMENU``,
|
|
|
|
``VIDIOC_G_CTRL``,
|
|
|
|
``VIDIOC_S_CTRL``,
|
|
|
|
``VIDIOC_G_EXT_CTRLS``,
|
|
|
|
``VIDIOC_S_EXT_CTRLS`` and
|
|
|
|
``VIDIOC_TRY_EXT_CTRLS``:
|
2016-07-21 20:27:37 +08:00
|
|
|
|
|
|
|
The controls ioctls are identical to the ones defined in V4L2. They
|
|
|
|
behave identically, with the only exception that they deal only with
|
|
|
|
controls implemented in the sub-device. Depending on the driver, those
|
|
|
|
controls can be also be accessed through one (or several) V4L2 device
|
|
|
|
nodes.
|
|
|
|
|
2016-07-21 20:49:32 +08:00
|
|
|
``VIDIOC_DQEVENT``,
|
|
|
|
``VIDIOC_SUBSCRIBE_EVENT`` and
|
|
|
|
``VIDIOC_UNSUBSCRIBE_EVENT``
|
2016-07-21 20:27:37 +08:00
|
|
|
|
|
|
|
The events ioctls are identical to the ones defined in V4L2. They
|
|
|
|
behave identically, with the only exception that they deal only with
|
|
|
|
events generated by the sub-device. Depending on the driver, those
|
|
|
|
events can also be reported by one (or several) V4L2 device nodes.
|
|
|
|
|
|
|
|
Sub-device drivers that want to use events need to set the
|
2020-05-28 00:21:32 +08:00
|
|
|
``V4L2_SUBDEV_FL_HAS_EVENTS`` :c:type:`v4l2_subdev`.flags before registering
|
2016-07-21 20:49:32 +08:00
|
|
|
the sub-device. After registration events can be queued as usual on the
|
|
|
|
:c:type:`v4l2_subdev`.devnode device node.
|
2016-07-21 20:27:37 +08:00
|
|
|
|
2016-07-21 20:49:32 +08:00
|
|
|
To properly support events, the ``poll()`` file operation is also
|
2016-07-21 20:27:37 +08:00
|
|
|
implemented.
|
|
|
|
|
|
|
|
Private ioctls
|
|
|
|
|
|
|
|
All ioctls not in the above list are passed directly to the sub-device
|
|
|
|
driver through the core::ioctl operation.
|
|
|
|
|
2020-05-07 23:12:49 +08:00
|
|
|
Read-only sub-device userspace API
|
|
|
|
----------------------------------
|
|
|
|
|
|
|
|
Bridge drivers that control their connected subdevices through direct calls to
|
|
|
|
the kernel API realized by :c:type:`v4l2_subdev_ops` structure do not usually
|
|
|
|
want userspace to be able to change the same parameters through the subdevice
|
|
|
|
device node and thus do not usually register any.
|
|
|
|
|
|
|
|
It is sometimes useful to report to userspace the current subdevice
|
|
|
|
configuration through a read-only API, that does not permit applications to
|
|
|
|
change to the device parameters but allows interfacing to the subdevice device
|
|
|
|
node to inspect them.
|
|
|
|
|
|
|
|
For instance, to implement cameras based on computational photography, userspace
|
|
|
|
needs to know the detailed camera sensor configuration (in terms of skipping,
|
|
|
|
binning, cropping and scaling) for each supported output resolution. To support
|
|
|
|
such use cases, bridge drivers may expose the subdevice operations to userspace
|
|
|
|
through a read-only API.
|
|
|
|
|
|
|
|
To create a read-only device node for all the subdevices registered with the
|
|
|
|
``V4L2_SUBDEV_FL_HAS_DEVNODE`` set, the :c:type:`v4l2_device` driver should call
|
|
|
|
:c:func:`v4l2_device_register_ro_subdev_nodes`.
|
|
|
|
|
|
|
|
Access to the following ioctls for userspace applications is restricted on
|
|
|
|
sub-device device nodes registered with
|
|
|
|
:c:func:`v4l2_device_register_ro_subdev_nodes`.
|
|
|
|
|
|
|
|
``VIDIOC_SUBDEV_S_FMT``,
|
|
|
|
``VIDIOC_SUBDEV_S_CROP``,
|
|
|
|
``VIDIOC_SUBDEV_S_SELECTION``:
|
|
|
|
|
|
|
|
These ioctls are only allowed on a read-only subdevice device node
|
|
|
|
for the :ref:`V4L2_SUBDEV_FORMAT_TRY <v4l2-subdev-format-whence>`
|
|
|
|
formats and selection rectangles.
|
|
|
|
|
|
|
|
``VIDIOC_SUBDEV_S_FRAME_INTERVAL``,
|
|
|
|
``VIDIOC_SUBDEV_S_DV_TIMINGS``,
|
|
|
|
``VIDIOC_SUBDEV_S_STD``:
|
|
|
|
|
|
|
|
These ioctls are not allowed on a read-only subdevice node.
|
|
|
|
|
|
|
|
In case the ioctl is not allowed, or the format to modify is set to
|
|
|
|
``V4L2_SUBDEV_FORMAT_ACTIVE``, the core returns a negative error code and
|
|
|
|
the errno variable is set to ``-EPERM``.
|
2016-07-21 20:27:37 +08:00
|
|
|
|
|
|
|
I2C sub-device drivers
|
|
|
|
----------------------
|
|
|
|
|
|
|
|
Since these drivers are so common, special helper functions are available to
|
2016-07-21 20:49:32 +08:00
|
|
|
ease the use of these drivers (``v4l2-common.h``).
|
2016-07-21 20:27:37 +08:00
|
|
|
|
2016-07-21 20:49:32 +08:00
|
|
|
The recommended method of adding :c:type:`v4l2_subdev` support to an I2C driver
|
|
|
|
is to embed the :c:type:`v4l2_subdev` struct into the state struct that is
|
|
|
|
created for each I2C device instance. Very simple devices have no state
|
|
|
|
struct and in that case you can just create a :c:type:`v4l2_subdev` directly.
|
2016-07-21 20:27:37 +08:00
|
|
|
|
|
|
|
A typical state struct would look like this (where 'chipname' is replaced by
|
|
|
|
the name of the chip):
|
|
|
|
|
2016-07-21 20:49:32 +08:00
|
|
|
.. code-block:: c
|
2016-07-21 20:27:37 +08:00
|
|
|
|
|
|
|
struct chipname_state {
|
|
|
|
struct v4l2_subdev sd;
|
|
|
|
... /* additional state fields */
|
|
|
|
};
|
|
|
|
|
2016-07-21 20:49:32 +08:00
|
|
|
Initialize the :c:type:`v4l2_subdev` struct as follows:
|
2016-07-21 20:27:37 +08:00
|
|
|
|
2016-07-21 20:49:32 +08:00
|
|
|
.. code-block:: c
|
2016-07-21 20:27:37 +08:00
|
|
|
|
|
|
|
v4l2_i2c_subdev_init(&state->sd, client, subdev_ops);
|
|
|
|
|
2016-07-21 20:49:32 +08:00
|
|
|
This function will fill in all the fields of :c:type:`v4l2_subdev` ensure that
|
|
|
|
the :c:type:`v4l2_subdev` and i2c_client both point to one another.
|
2016-07-21 20:27:37 +08:00
|
|
|
|
2016-07-21 20:49:32 +08:00
|
|
|
You should also add a helper inline function to go from a :c:type:`v4l2_subdev`
|
|
|
|
pointer to a chipname_state struct:
|
2016-07-21 20:27:37 +08:00
|
|
|
|
2016-07-21 20:49:32 +08:00
|
|
|
.. code-block:: c
|
2016-07-21 20:27:37 +08:00
|
|
|
|
|
|
|
static inline struct chipname_state *to_state(struct v4l2_subdev *sd)
|
|
|
|
{
|
|
|
|
return container_of(sd, struct chipname_state, sd);
|
|
|
|
}
|
|
|
|
|
2016-07-21 20:49:32 +08:00
|
|
|
Use this to go from the :c:type:`v4l2_subdev` struct to the ``i2c_client``
|
|
|
|
struct:
|
2016-07-21 20:27:37 +08:00
|
|
|
|
2016-07-21 20:49:32 +08:00
|
|
|
.. code-block:: c
|
2016-07-21 20:27:37 +08:00
|
|
|
|
|
|
|
struct i2c_client *client = v4l2_get_subdevdata(sd);
|
|
|
|
|
2016-07-21 20:49:32 +08:00
|
|
|
And this to go from an ``i2c_client`` to a :c:type:`v4l2_subdev` struct:
|
2016-07-21 20:27:37 +08:00
|
|
|
|
2016-07-21 20:49:32 +08:00
|
|
|
.. code-block:: c
|
2016-07-21 20:27:37 +08:00
|
|
|
|
|
|
|
struct v4l2_subdev *sd = i2c_get_clientdata(client);
|
|
|
|
|
2016-07-21 20:49:32 +08:00
|
|
|
Make sure to call
|
2016-07-23 18:21:06 +08:00
|
|
|
:c:func:`v4l2_device_unregister_subdev`\ (:c:type:`sd <v4l2_subdev>`)
|
2016-07-21 20:49:32 +08:00
|
|
|
when the ``remove()`` callback is called. This will unregister the sub-device
|
|
|
|
from the bridge driver. It is safe to call this even if the sub-device was
|
|
|
|
never registered.
|
2016-07-21 20:27:37 +08:00
|
|
|
|
|
|
|
You need to do this because when the bridge driver destroys the i2c adapter
|
2016-07-21 20:49:32 +08:00
|
|
|
the ``remove()`` callbacks are called of the i2c devices on that adapter.
|
2016-07-21 20:27:37 +08:00
|
|
|
After that the corresponding v4l2_subdev structures are invalid, so they
|
2016-07-21 20:49:32 +08:00
|
|
|
have to be unregistered first. Calling
|
2016-07-23 18:21:06 +08:00
|
|
|
:c:func:`v4l2_device_unregister_subdev`\ (:c:type:`sd <v4l2_subdev>`)
|
2016-07-21 20:49:32 +08:00
|
|
|
from the ``remove()`` callback ensures that this is always done correctly.
|
2016-07-21 20:27:37 +08:00
|
|
|
|
|
|
|
|
|
|
|
The bridge driver also has some helper functions it can use:
|
|
|
|
|
2016-07-21 20:49:32 +08:00
|
|
|
.. code-block:: c
|
2016-07-21 20:27:37 +08:00
|
|
|
|
|
|
|
struct v4l2_subdev *sd = v4l2_i2c_new_subdev(v4l2_dev, adapter,
|
|
|
|
"module_foo", "chipid", 0x36, NULL);
|
|
|
|
|
2016-07-21 20:49:32 +08:00
|
|
|
This loads the given module (can be ``NULL`` if no module needs to be loaded)
|
2020-06-15 15:58:14 +08:00
|
|
|
and calls :c:func:`i2c_new_client_device` with the given ``i2c_adapter`` and
|
2016-07-21 20:49:32 +08:00
|
|
|
chip/address arguments. If all goes well, then it registers the subdev with
|
|
|
|
the v4l2_device.
|
2016-07-21 20:27:37 +08:00
|
|
|
|
2016-07-23 18:21:06 +08:00
|
|
|
You can also use the last argument of :c:func:`v4l2_i2c_new_subdev` to pass
|
2016-07-21 20:49:32 +08:00
|
|
|
an array of possible I2C addresses that it should probe. These probe addresses
|
|
|
|
are only used if the previous argument is 0. A non-zero argument means that you
|
2016-07-21 20:27:37 +08:00
|
|
|
know the exact i2c address so in that case no probing will take place.
|
|
|
|
|
2016-07-21 20:49:32 +08:00
|
|
|
Both functions return ``NULL`` if something went wrong.
|
2016-07-21 20:27:37 +08:00
|
|
|
|
2016-07-23 18:21:06 +08:00
|
|
|
Note that the chipid you pass to :c:func:`v4l2_i2c_new_subdev` is usually
|
2016-07-21 20:27:37 +08:00
|
|
|
the same as the module name. It allows you to specify a chip variant, e.g.
|
|
|
|
"saa7114" or "saa7115". In general though the i2c driver autodetects this.
|
|
|
|
The use of chipid is something that needs to be looked at more closely at a
|
|
|
|
later date. It differs between i2c drivers and as such can be confusing.
|
|
|
|
To see which chip variants are supported you can look in the i2c driver code
|
|
|
|
for the i2c_device_id table. This lists all the possibilities.
|
|
|
|
|
2016-08-31 08:01:57 +08:00
|
|
|
There are one more helper function:
|
2016-07-21 20:27:37 +08:00
|
|
|
|
2016-07-23 18:21:06 +08:00
|
|
|
:c:func:`v4l2_i2c_new_subdev_board` uses an :c:type:`i2c_board_info` struct
|
2016-07-21 20:49:32 +08:00
|
|
|
which is passed to the i2c driver and replaces the irq, platform_data and addr
|
|
|
|
arguments.
|
2016-07-21 20:27:37 +08:00
|
|
|
|
|
|
|
If the subdev supports the s_config core ops, then that op is called with
|
2016-07-21 20:49:32 +08:00
|
|
|
the irq and platform_data arguments after the subdev was setup.
|
|
|
|
|
2016-08-31 08:01:57 +08:00
|
|
|
The :c:func:`v4l2_i2c_new_subdev` function will call
|
|
|
|
:c:func:`v4l2_i2c_new_subdev_board`, internally filling a
|
|
|
|
:c:type:`i2c_board_info` structure using the ``client_type`` and the
|
|
|
|
``addr`` to fill it.
|
2016-07-21 20:49:32 +08:00
|
|
|
|
|
|
|
V4L2 sub-device functions and data structures
|
|
|
|
---------------------------------------------
|
2016-07-21 20:27:37 +08:00
|
|
|
|
2016-07-21 01:14:37 +08:00
|
|
|
.. kernel-doc:: include/media/v4l2-subdev.h
|
2016-07-21 20:13:11 +08:00
|
|
|
|
|
|
|
.. kernel-doc:: include/media/v4l2-async.h
|