123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137 |
- V4L2 events
- -----------
- The V4L2 events provide a generic way to pass events to user space.
- 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
- object such as a control ID. If unused, then the ID is 0.
- When the user subscribes to an event the driver will allocate a number of
- kevent structs for that event. So every (type, ID) event tuple will have
- its own set of kevent structs. This guarantees that if a driver is generating
- lots of events of one type in a short time, then that will not overwrite
- events of another type.
- 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.
- Furthermore, the internal struct :c:type:`v4l2_subscribed_event` has
- ``merge()`` and ``replace()`` callbacks which drivers can set. These
- callbacks are called when a new event is raised and there is no more room.
- The ``replace()`` callback allows you to replace the payload of the old event
- with that of the new event, merging any relevant data from the old payload
- into the new payload that replaces it. It is called when this event type has
- only one kevent struct allocated. The ``merge()`` callback allows you to merge
- the oldest event payload into that of the second-oldest event payload. It is
- called when there are two or more kevent structs allocated.
- This way no status information is lost, just the intermediate steps leading
- up to that state.
- A good example of these ``replace``/``merge`` callbacks is in v4l2-event.c:
- ``ctrls_replace()`` and ``ctrls_merge()`` callbacks for the control event.
- .. note::
- these callbacks can be called from interrupt context, so they must
- be fast.
- In order to queue events to video device, drivers should call:
- :c:func:`v4l2_event_queue <v4l2_event_queue>`
- (:c:type:`vdev <video_device>`, :c:type:`ev <v4l2_event>`)
- The driver's only responsibility is to fill in the type and the data fields.
- The other fields will be filled in by V4L2.
- Event subscription
- ~~~~~~~~~~~~~~~~~~
- Subscribing to an event is via:
- :c:func:`v4l2_event_subscribe <v4l2_event_subscribe>`
- (:c:type:`fh <v4l2_fh>`, :c:type:`sub <v4l2_event_subscription>` ,
- elems, :c:type:`ops <v4l2_subscribed_event_ops>`)
- This function is used to implement :c:type:`video_device`->
- :c:type:`ioctl_ops <v4l2_ioctl_ops>`-> ``vidioc_subscribe_event``,
- but the driver must check first if the driver is able to produce events
- with specified event id, and then should call
- :c:func:`v4l2_event_subscribe` to subscribe the event.
- The elems argument is the size of the event queue for this event. If it is 0,
- then the framework will fill in a default value (this depends on the event
- type).
- The ops argument allows the driver to specify a number of callbacks:
- ======== ==============================================================
- 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'.
- ======== ==============================================================
- All 4 callbacks are optional, if you don't want to specify any callbacks
- the ops argument itself maybe ``NULL``.
- Unsubscribing an event
- ~~~~~~~~~~~~~~~~~~~~~~
- Unsubscribing to an event is via:
- :c:func:`v4l2_event_unsubscribe <v4l2_event_unsubscribe>`
- (:c:type:`fh <v4l2_fh>`, :c:type:`sub <v4l2_event_subscription>`)
- This function is used to implement :c:type:`video_device`->
- :c:type:`ioctl_ops <v4l2_ioctl_ops>`-> ``vidioc_unsubscribe_event``.
- A driver may call :c: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:
- :c: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
- 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
- smallest available event type. The drivers must allocate their events from
- their own class starting from class base. Class base is
- ``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
- available event type is 'class base + 1'.
- An example on how the V4L2 events may be used can be found in the OMAP
- 3 ISP driver (``drivers/media/platform/omap3isp``).
- A subdev can directly send an event to the :c:type:`v4l2_device` notify
- function with ``V4L2_DEVICE_NOTIFY_EVENT``. This allows the bridge to map
- the subdev that sends the event to the video node(s) associated with the
- subdev that need to be informed about such an event.
- V4L2 event functions and data structures
- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- .. kernel-doc:: include/media/v4l2-event.h
|