diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2020-06-04 06:59:38 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2020-06-04 06:59:38 +0300 |
commit | a98f670e41a99f53acb1fb33cee9c6abbb2e6f23 (patch) | |
tree | f8ae10a4cb91758ad7f9422053753a8c5d0f04dc /Documentation/driver-api/media/v4l2-event.rst | |
parent | ee01c4d72adffb7d424535adf630f2955748fa8b (diff) | |
parent | 938b29db3aa9c293c7c1366b16e55e308f1a1ddd (diff) | |
download | linux-a98f670e41a99f53acb1fb33cee9c6abbb2e6f23.tar.xz |
Merge tag 'media/v5.8-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media
Pull media updates from Mauro Carvalho Chehab:
- Media documentation is now split into admin-guide, driver-api and
userspace-api books (a longstanding request from Jon);
- The media Kconfig was reorganized, in order to make easier to select
drivers and their dependencies;
- The testing drivers now has a separate directory;
- added a new driver for Rockchip Video Decoder IP;
- The atomisp staging driver was resurrected. It is meant to work with
4 generations of cameras on Atom-based laptops, tablets and cell
phones. So, it seems worth investing time to cleanup this driver and
making it in good shape.
- Added some V4L2 core ancillary routines to help with h264 codecs;
- Added an ov2740 image sensor driver;
- The si2157 gained support for Analog TV, which, in turn, added
support for some cx231xx and cx23885 boards to also support analog
standards;
- Added some V4L2 controls (V4L2_CID_CAMERA_ORIENTATION and
V4L2_CID_CAMERA_SENSOR_ROTATION) to help identifying where the camera
is located at the device;
- VIDIOC_ENUM_FMT was extended to support MC-centric devices;
- Lots of drivers improvements and cleanups.
* tag 'media/v5.8-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (503 commits)
media: Documentation: media: Refer to mbus format documentation from CSI-2 docs
media: s5k5baf: Replace zero-length array with flexible-array
media: i2c: imx219: Drop <linux/clk-provider.h> and <linux/clkdev.h>
media: i2c: Add ov2740 image sensor driver
media: ov8856: Implement sensor module revision identification
media: ov8856: Add devicetree support
media: dt-bindings: ov8856: Document YAML bindings
media: dvb-usb: Add Cinergy S2 PCIe Dual Port support
media: dvbdev: Fix tuner->demod media controller link
media: dt-bindings: phy: phy-rockchip-dphy-rx0: move rockchip dphy rx0 bindings out of staging
media: staging: dt-bindings: phy-rockchip-dphy-rx0: remove non-used reg property
media: atomisp: unify the version for isp2401 a0 and b0 versions
media: atomisp: update TODO with the current data
media: atomisp: adjust some code at sh_css that could be broken
media: atomisp: don't produce errs for ignored IRQs
media: atomisp: print IRQ when debugging
media: atomisp: isp_mmu: don't use kmem_cache
media: atomisp: add a notice about possible leak resources
media: atomisp: disable the dynamic and reserved pools
media: atomisp: turn on camera before setting it
...
Diffstat (limited to 'Documentation/driver-api/media/v4l2-event.rst')
-rw-r--r-- | Documentation/driver-api/media/v4l2-event.rst | 181 |
1 files changed, 181 insertions, 0 deletions
diff --git a/Documentation/driver-api/media/v4l2-event.rst b/Documentation/driver-api/media/v4l2-event.rst new file mode 100644 index 000000000000..a4b7ae2b94d8 --- /dev/null +++ b/Documentation/driver-api/media/v4l2-event.rst @@ -0,0 +1,181 @@ +.. SPDX-License-Identifier: GPL-2.0 + +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 subscribed per-filehandle. An event specification consists of a +``type`` and is optionally associated with an object identified through the +``id`` field. If unused, then the ``id`` is 0. So an event is uniquely +identified by the ``(type, id)`` tuple. + +The :c:type:`v4l2_fh` struct has a list of subscribed events on its +``subscribed`` field. + +When the user subscribes to an event, a :c:type:`v4l2_subscribed_event` +struct is added to :c:type:`v4l2_fh`\ ``.subscribed``, one for every +subscribed event. + +Each :c:type:`v4l2_subscribed_event` struct ends with a +:c:type:`v4l2_kevent` ringbuffer, with the size given by the caller +of :c:func:`v4l2_event_subscribe`. This ringbuffer is used to store any events +raised by the driver. + +So every ``(type, ID)`` event tuple will have its own +:c:type:`v4l2_kevent` ringbuffer. 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 size of the +:c:type:`v4l2_kevent` ringbuffer, then the oldest event will be dropped +and the new one added. + +The :c:type:`v4l2_kevent` struct links into the ``available`` +list of the :c:type:`v4l2_fh` struct so :ref:`VIDIOC_DQEVENT` will +know which event to dequeue first. + +Finally, if the event subscription is associated with a particular object +such as a V4L2 control, then that object needs to know about that as well +so that an event can be raised by that object. So the ``node`` field can +be used to link the :c:type:`v4l2_subscribed_event` struct into a list of +such objects. + +So to summarize: + +- struct :c:type:`v4l2_fh` has two lists: one of the ``subscribed`` events, + and one of the ``available`` events. + +- struct :c:type:`v4l2_subscribed_event` has a ringbuffer of raised + (pending) events of that particular type. + +- If struct :c:type:`v4l2_subscribed_event` is associated with a specific + object, then that object will have an internal list of + struct :c:type:`v4l2_subscribed_event` so it knows who subscribed an + event to that object. + +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 +a ringbuffer with size is one, i.e. only one event can be stored in the +ringbuffer. + +The ``merge()`` callback allows you to merge the oldest event payload into +that of the second-oldest event payload. It is called when +the ringbuffer has size is greater than one. + +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: + +.. tabularcolumns:: |p{1.5cm}|p{16.0cm}| + +======== ============================================================== +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 + |