Commit 02ca08b8 authored by Mauro Carvalho Chehab's avatar Mauro Carvalho Chehab

[media] v4l2-device.rst: do cross references with kernel-doc

This document describes the main kAPI interfaces for the
v4l2-device.h header. Add cross references to the documentation
produced via kernel-doc.

While here, also use monotonic font for constants.
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@s-opensource.com>
parent 5de379a2
V4L2 Device register logic V4L2 Device register logic
-------------------------- --------------------------
Each device instance is represented by a struct v4l2_device (v4l2-device.h). Each device instance is represented by a struct :c:type:`v4l2_device`.
Very simple devices can just allocate this struct, but most of the time you Very simple devices can just allocate this struct, but most of the time you
would embed this struct inside a larger struct. would embed this struct inside a larger struct.
You must register the device instance: You must register the device instance by calling:
.. code-block:: none :cpp:func:`v4l2_device_register <v4l2_device_register>`
(dev, :c:type:`v4l2_dev <v4l2_device>`).
v4l2_device_register(struct device *dev, struct v4l2_device *v4l2_dev); Registration will initialize the :c:type:`v4l2_device` struct. If the
dev->driver_data field is ``NULL``, it will be linked to
Registration will initialize the v4l2_device struct. If the dev->driver_data :c:type:`v4l2_dev <v4l2_device>` argument.
field is NULL, it will be linked to v4l2_dev.
Drivers that want integration with the media device framework need to set Drivers that want integration with the media device framework need to set
dev->driver_data manually to point to the driver-specific device structure dev->driver_data manually to point to the driver-specific device structure
that embed the struct v4l2_device instance. This is achieved by a that embed the struct :c:type:`v4l2_device` instance. This is achieved by a
dev_set_drvdata() call before registering the V4L2 device instance. They must ``dev_set_drvdata()`` call before registering the V4L2 device instance.
also set the struct v4l2_device mdev field to point to a properly initialized They must also set the struct :c:type:`v4l2_device` mdev field to point to a
and registered media_device instance. properly initialized and registered :c:type:`media_device` instance.
If v4l2_dev->name is empty then it will be set to a value derived from dev If :c:type:`v4l2_dev <v4l2_device>`\ ->name is empty then it will be set to a
(driver name followed by the bus_id, to be precise). If you set it up before value derived from dev (driver name followed by the bus_id, to be precise).
calling v4l2_device_register then it will be untouched. If dev is NULL, then If you set it up before calling :cpp:func:`v4l2_device_register` then it will
you **must** setup v4l2_dev->name before calling v4l2_device_register. be untouched. If dev is ``NULL``, then you **must** setup
:c:type:`v4l2_dev <v4l2_device>`\ ->name before calling
You can use v4l2_device_set_name() to set the name based on a driver name and :cpp:func:`v4l2_device_register`.
a driver-global atomic_t instance. This will generate names like ivtv0, ivtv1,
etc. If the name ends with a digit, then it will insert a dash: cx18-0, You can use :cpp:func:`v4l2_device_set_name` to set the name based on a driver
cx18-1, etc. This function returns the instance number. name and a driver-global atomic_t instance. This will generate names like
``ivtv0``, ``ivtv1``, etc. If the name ends with a digit, then it will insert
The first 'dev' argument is normally the struct device pointer of a pci_dev, a dash: ``cx18-0``, ``cx18-1``, etc. This function returns the instance number.
usb_interface or platform_device. It is rare for dev to be NULL, but it happens
with ISA devices or when one device creates multiple PCI devices, thus making The first ``dev`` argument is normally the ``struct device`` pointer of a
it impossible to associate v4l2_dev with a particular parent. ``pci_dev``, ``usb_interface`` or ``platform_device``. It is rare for dev to
be ``NULL``, but it happens with ISA devices or when one device creates
You can also supply a notify() callback that can be called by sub-devices to multiple PCI devices, thus making it impossible to associate
notify you of events. Whether you need to set this depends on the sub-device. :c:type:`v4l2_dev <v4l2_device>` with a particular parent.
Any notifications a sub-device supports must be defined in a header in
include/media/<subdevice>.h. You can also supply a ``notify()`` callback that can be called by sub-devices
to notify you of events. Whether you need to set this depends on the
You unregister with: sub-device. Any notifications a sub-device supports must be defined in a header
in ``include/media/subdevice.h``.
.. code-block:: none
V4L2 devices are unregistered by calling:
v4l2_device_unregister(struct v4l2_device *v4l2_dev);
:cpp:func:`v4l2_device_unregister`
If the dev->driver_data field points to v4l2_dev, it will be reset to NULL. (:c:type:`v4l2_dev <v4l2_device>`).
Unregistering will also automatically unregister all subdevs from the device.
If the dev->driver_data field points to :c:type:`v4l2_dev <v4l2_device>`,
it will be reset to ``NULL``. Unregistering will also automatically unregister
all subdevs from the device.
If you have a hotpluggable device (e.g. a USB device), then when a disconnect If you have a hotpluggable device (e.g. a USB device), then when a disconnect
happens the parent device becomes invalid. Since v4l2_device has a pointer to happens the parent device becomes invalid. Since :c:type:`v4l2_device` has a
that parent device it has to be cleared as well to mark that the parent is pointer to that parent device it has to be cleared as well to mark that the
gone. To do this call: parent is gone. To do this call:
.. code-block:: none :cpp:func:`v4l2_device_disconnect`
(:c:type:`v4l2_dev <v4l2_device>`).
v4l2_device_disconnect(struct v4l2_device *v4l2_dev);
This does *not* unregister the subdevs, so you still need to call the This does *not* unregister the subdevs, so you still need to call the
v4l2_device_unregister() function for that. If your driver is not hotpluggable, :cpp:func:`v4l2_device_unregister` function for that. If your driver is not
then there is no need to call v4l2_device_disconnect(). hotpluggable, then there is no need to call :cpp:func:`v4l2_device_disconnect`.
Sometimes you need to iterate over all devices registered by a specific Sometimes you need to iterate over all devices registered by a specific
driver. This is usually the case if multiple device drivers use the same driver. This is usually the case if multiple device drivers use the same
...@@ -70,7 +72,7 @@ hardware. The same is true for alsa drivers for example. ...@@ -70,7 +72,7 @@ hardware. The same is true for alsa drivers for example.
You can iterate over all registered devices as follows: You can iterate over all registered devices as follows:
.. code-block:: none .. code-block:: c
static int callback(struct device *dev, void *p) static int callback(struct device *dev, void *p)
{ {
...@@ -102,7 +104,7 @@ commonly used to map a device instance to an index of a module option array. ...@@ -102,7 +104,7 @@ commonly used to map a device instance to an index of a module option array.
The recommended approach is as follows: The recommended approach is as follows:
.. code-block:: none .. code-block:: c
static atomic_t drv_instance = ATOMIC_INIT(0); static atomic_t drv_instance = ATOMIC_INIT(0);
...@@ -113,28 +115,28 @@ The recommended approach is as follows: ...@@ -113,28 +115,28 @@ The recommended approach is as follows:
} }
If you have multiple device nodes then it can be difficult to know when it is If you have multiple device nodes then it can be difficult to know when it is
safe to unregister v4l2_device for hotpluggable devices. For this purpose safe to unregister :c:type:`v4l2_device` for hotpluggable devices. For this
v4l2_device has refcounting support. The refcount is increased whenever purpose :c:type:`v4l2_device` has refcounting support. The refcount is
video_register_device is called and it is decreased whenever that device node increased whenever :cpp:func:`video_register_device` is called and it is
is released. When the refcount reaches zero, then the v4l2_device release() decreased whenever that device node is released. When the refcount reaches
callback is called. You can do your final cleanup there. zero, then the :c:type:`v4l2_device` release() callback is called. You can
do your final cleanup there.
If other device nodes (e.g. ALSA) are created, then you can increase and If other device nodes (e.g. ALSA) are created, then you can increase and
decrease the refcount manually as well by calling: decrease the refcount manually as well by calling:
.. code-block:: none :cpp:func:`v4l2_device_get`
(:c:type:`v4l2_dev <v4l2_device>`).
void v4l2_device_get(struct v4l2_device *v4l2_dev);
or: or:
.. code-block:: none :cpp:func:`v4l2_device_put`
(:c:type:`v4l2_dev <v4l2_device>`).
int v4l2_device_put(struct v4l2_device *v4l2_dev);
Since the initial refcount is 1 you also need to call v4l2_device_put in the Since the initial refcount is 1 you also need to call
disconnect() callback (for USB devices) or in the remove() callback (for e.g. :cpp:func:`v4l2_device_put` in the ``disconnect()`` callback (for USB devices)
PCI devices), otherwise the refcount will never reach 0. or in the ``remove()`` callback (for e.g. PCI devices), otherwise the refcount
will never reach 0.
V4L2 device kAPI V4L2 device kAPI
^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment