[media] v4l2-event.rst: add cross-references and markups
Improve events documentation by adding cross references, sub-titles and other markup elements. Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
This commit is contained in:
parent
9d4ee1ad92
commit
d231685682
@ -3,7 +3,7 @@ V4L2 events
|
|||||||
-----------
|
-----------
|
||||||
|
|
||||||
The V4L2 events provide a generic way to pass events to user space.
|
The V4L2 events provide a generic way to pass events to user space.
|
||||||
The driver must use v4l2_fh to be able to support V4L2 events.
|
The driver must use :c:type:`v4l2_fh` to be able to support V4L2 events.
|
||||||
|
|
||||||
Events are defined by a type and an optional ID. The ID may refer to a V4L2
|
Events are defined by a type and an optional ID. The ID may refer to a V4L2
|
||||||
object such as a control ID. If unused, then the ID is 0.
|
object such as a control ID. If unused, then the ID is 0.
|
||||||
@ -17,93 +17,118 @@ events of another type.
|
|||||||
But if you get more events of one type than the number of kevents that were
|
But if you get more events of one type than the number of kevents that were
|
||||||
reserved, then the oldest event will be dropped and the new one added.
|
reserved, then the oldest event will be dropped and the new one added.
|
||||||
|
|
||||||
Furthermore, the internal struct v4l2_subscribed_event has merge() and
|
Furthermore, the internal struct :c:type:`v4l2_subscribed_event` has
|
||||||
replace() callbacks which drivers can set. These callbacks are called when
|
``merge()`` and ``replace()`` callbacks which drivers can set. These
|
||||||
a new event is raised and there is no more room. The replace() callback
|
callbacks are called when a new event is raised and there is no more room.
|
||||||
allows you to replace the payload of the old event with that of the new event,
|
The ``replace()`` callback allows you to replace the payload of the old event
|
||||||
merging any relevant data from the old payload into the new payload that
|
with that of the new event, merging any relevant data from the old payload
|
||||||
replaces it. It is called when this event type has only one kevent struct
|
into the new payload that replaces it. It is called when this event type has
|
||||||
allocated. The merge() callback allows you to merge the oldest event payload
|
only one kevent struct allocated. The ``merge()`` callback allows you to merge
|
||||||
into that of the second-oldest event payload. It is called when there are two
|
the oldest event payload into that of the second-oldest event payload. It is
|
||||||
or more kevent structs allocated.
|
called when there are two or more kevent structs allocated.
|
||||||
|
|
||||||
This way no status information is lost, just the intermediate steps leading
|
This way no status information is lost, just the intermediate steps leading
|
||||||
up to that state.
|
up to that state.
|
||||||
|
|
||||||
A good example of these replace/merge callbacks is in v4l2-event.c:
|
A good example of these ``replace``/``merge`` callbacks is in v4l2-event.c:
|
||||||
ctrls_replace() and ctrls_merge() callbacks for the control event.
|
``ctrls_replace()`` and ``ctrls_merge()`` callbacks for the control event.
|
||||||
|
|
||||||
Note: these callbacks can be called from interrupt context, so they must be
|
.. note::
|
||||||
fast.
|
these callbacks can be called from interrupt context, so they must
|
||||||
|
be fast.
|
||||||
|
|
||||||
Useful functions:
|
In order to queue events to video device, drivers should call:
|
||||||
|
|
||||||
.. code-block:: none
|
:cpp:func:`v4l2_event_queue <v4l2_event_queue>`
|
||||||
|
(:c:type:`vdev <video_device>`, :ref:`ev <v4l2-event>`)
|
||||||
|
|
||||||
void v4l2_event_queue(struct video_device *vdev, const struct v4l2_event *ev)
|
The driver's only responsibility is to fill in the type and the data fields.
|
||||||
|
The other fields will be filled in by V4L2.
|
||||||
|
|
||||||
Queue events to video device. The driver's only responsibility is to fill
|
Event subscription
|
||||||
in the type and the data fields. The other fields will be filled in by
|
~~~~~~~~~~~~~~~~~~
|
||||||
V4L2.
|
|
||||||
|
|
||||||
.. code-block:: none
|
Subscribing to an event is via:
|
||||||
|
|
||||||
int v4l2_event_subscribe(struct v4l2_fh *fh,
|
:cpp:func:`v4l2_event_subscribe <v4l2_event_subscribe>`
|
||||||
struct v4l2_event_subscription *sub, unsigned elems,
|
(:c:type:`fh <v4l2_fh>`, :ref:`sub <v4l2-event-subscription>` ,
|
||||||
const struct v4l2_subscribed_event_ops *ops)
|
elems, :c:type:`ops <v4l2_subscribed_event_ops>`)
|
||||||
|
|
||||||
The video_device->ioctl_ops->vidioc_subscribe_event must check the driver
|
|
||||||
is able to produce events with specified event id. Then it calls
|
|
||||||
v4l2_event_subscribe() to subscribe the event.
|
|
||||||
|
|
||||||
The elems argument is the size of the event queue for this event. If it is 0,
|
This function is used to implement :c:type:`video_device`->
|
||||||
then the framework will fill in a default value (this depends on the event
|
:c:type:`ioctl_ops <v4l2_ioctl_ops>`-> ``vidioc_subscribe_event``,
|
||||||
type).
|
but the driver must check first if the driver is able to produce events
|
||||||
|
with specified event id, and then should call
|
||||||
|
:cpp:func:`v4l2_event_subscribe` to subscribe the event.
|
||||||
|
|
||||||
The ops argument allows the driver to specify a number of callbacks:
|
The elems argument is the size of the event queue for this event. If it is 0,
|
||||||
* add: called when a new listener gets added (subscribing to the same
|
then the framework will fill in a default value (this depends on the event
|
||||||
event twice will only cause this callback to get called once)
|
type).
|
||||||
* del: called when a listener stops listening
|
|
||||||
* replace: replace event 'old' with event 'new'.
|
|
||||||
* merge: merge event 'old' into event 'new'.
|
|
||||||
All 4 callbacks are optional, if you don't want to specify any callbacks
|
|
||||||
the ops argument itself maybe NULL.
|
|
||||||
|
|
||||||
.. code-block:: none
|
The ops argument allows the driver to specify a number of callbacks:
|
||||||
|
|
||||||
int v4l2_event_unsubscribe(struct v4l2_fh *fh,
|
======== ==============================================================
|
||||||
struct v4l2_event_subscription *sub)
|
Callback Description
|
||||||
|
======== ==============================================================
|
||||||
|
add called when a new listener gets added (subscribing to the same
|
||||||
|
event twice will only cause this callback to get called once)
|
||||||
|
del called when a listener stops listening
|
||||||
|
replace replace event 'old' with event 'new'.
|
||||||
|
merge merge event 'old' into event 'new'.
|
||||||
|
======== ==============================================================
|
||||||
|
|
||||||
vidioc_unsubscribe_event in struct v4l2_ioctl_ops. A driver may use
|
All 4 callbacks are optional, if you don't want to specify any callbacks
|
||||||
v4l2_event_unsubscribe() directly unless it wants to be involved in
|
the ops argument itself maybe ``NULL``.
|
||||||
unsubscription process.
|
|
||||||
|
|
||||||
The special type V4L2_EVENT_ALL may be used to unsubscribe all events. The
|
Unsubscribing an event
|
||||||
drivers may want to handle this in a special way.
|
~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
.. code-block:: none
|
Unsubscribing to an event is via:
|
||||||
|
|
||||||
int v4l2_event_pending(struct v4l2_fh *fh)
|
:cpp:func:`v4l2_event_unsubscribe <v4l2_event_unsubscribe>`
|
||||||
|
(:c:type:`fh <v4l2_fh>`, :ref:`sub <v4l2-event-subscription>`)
|
||||||
|
|
||||||
Returns the number of pending events. Useful when implementing poll.
|
This function is used to implement :c:type:`video_device`->
|
||||||
|
:c:type:`ioctl_ops <v4l2_ioctl_ops>`-> ``vidioc_unsubscribe_event``.
|
||||||
|
A driver may call :cpp:func:`v4l2_event_unsubscribe` directly unless it
|
||||||
|
wants to be involved in unsubscription process.
|
||||||
|
|
||||||
|
The special type ``V4L2_EVENT_ALL`` may be used to unsubscribe all events. The
|
||||||
|
drivers may want to handle this in a special way.
|
||||||
|
|
||||||
|
Check if there's a pending event
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Checking if there's a pending event is via:
|
||||||
|
|
||||||
|
:cpp:func:`v4l2_event_pending <v4l2_event_pending>`
|
||||||
|
(:c:type:`fh <v4l2_fh>`)
|
||||||
|
|
||||||
|
|
||||||
|
This function returns the number of pending events. Useful when implementing
|
||||||
|
poll.
|
||||||
|
|
||||||
|
How events work
|
||||||
|
~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
Events are delivered to user space through the poll system call. The driver
|
Events are delivered to user space through the poll system call. The driver
|
||||||
can use v4l2_fh->wait (a wait_queue_head_t) as the argument for poll_wait().
|
can use :c:type:`v4l2_fh`->wait (a wait_queue_head_t) as the argument for
|
||||||
|
``poll_wait()``.
|
||||||
|
|
||||||
There are standard and private events. New standard events must use the
|
There are standard and private events. New standard events must use the
|
||||||
smallest available event type. The drivers must allocate their events from
|
smallest available event type. The drivers must allocate their events from
|
||||||
their own class starting from class base. Class base is
|
their own class starting from class base. Class base is
|
||||||
V4L2_EVENT_PRIVATE_START + n * 1000 where n is the lowest available number.
|
``V4L2_EVENT_PRIVATE_START`` + n * 1000 where n is the lowest available number.
|
||||||
The first event type in the class is reserved for future use, so the first
|
The first event type in the class is reserved for future use, so the first
|
||||||
available event type is 'class base + 1'.
|
available event type is 'class base + 1'.
|
||||||
|
|
||||||
An example on how the V4L2 events may be used can be found in the OMAP
|
An example on how the V4L2 events may be used can be found in the OMAP
|
||||||
3 ISP driver (drivers/media/platform/omap3isp).
|
3 ISP driver (``drivers/media/platform/omap3isp``).
|
||||||
|
|
||||||
A subdev can directly send an event to the v4l2_device notify function with
|
A subdev can directly send an event to the :c:type:`v4l2_device` notify
|
||||||
V4L2_DEVICE_NOTIFY_EVENT. This allows the bridge to map the subdev that sends
|
function with ``V4L2_DEVICE_NOTIFY_EVENT``. This allows the bridge to map
|
||||||
the event to the video node(s) associated with the subdev that need to be
|
the subdev that sends the event to the video node(s) associated with the
|
||||||
informed about such an event.
|
subdev that need to be informed about such an event.
|
||||||
|
|
||||||
V4L2 event kAPI
|
V4L2 event kAPI
|
||||||
^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^
|
||||||
|
Loading…
Reference in New Issue
Block a user