| xj | b04a402 | 2021-11-25 15:01:52 +0800 | [diff] [blame] | 1 |  | 
|  | 2 | V4L2 events | 
|  | 3 | ----------- | 
|  | 4 |  | 
|  | 5 | The V4L2 events provide a generic way to pass events to user space. | 
|  | 6 | The driver must use :c:type:`v4l2_fh` to be able to support V4L2 events. | 
|  | 7 |  | 
|  | 8 | Events are subscribed per-filehandle. An event specification consists of a | 
|  | 9 | ``type`` and is optionally associated with an object identified through the | 
|  | 10 | ``id`` field. If unused, then the ``id`` is 0. So an event is uniquely | 
|  | 11 | identified by the ``(type, id)`` tuple. | 
|  | 12 |  | 
|  | 13 | The :c:type:`v4l2_fh` struct has a list of subscribed events on its | 
|  | 14 | ``subscribed`` field. | 
|  | 15 |  | 
|  | 16 | When the user subscribes to an event, a :c:type:`v4l2_subscribed_event` | 
|  | 17 | struct is added to :c:type:`v4l2_fh`\ ``.subscribed``, one for every | 
|  | 18 | subscribed event. | 
|  | 19 |  | 
|  | 20 | Each :c:type:`v4l2_subscribed_event` struct ends with a | 
|  | 21 | :c:type:`v4l2_kevent` ringbuffer, with the size given by the caller | 
|  | 22 | of :c:func:`v4l2_event_subscribe`. This ringbuffer is used to store any events | 
|  | 23 | raised by the driver. | 
|  | 24 |  | 
|  | 25 | So every ``(type, ID)`` event tuple will have its own | 
|  | 26 | :c:type:`v4l2_kevent` ringbuffer. This guarantees that if a driver is | 
|  | 27 | generating lots of events of one type in a short time, then that will | 
|  | 28 | not overwrite events of another type. | 
|  | 29 |  | 
|  | 30 | But if you get more events of one type than the size of the | 
|  | 31 | :c:type:`v4l2_kevent` ringbuffer, then the oldest event will be dropped | 
|  | 32 | and the new one added. | 
|  | 33 |  | 
|  | 34 | The :c:type:`v4l2_kevent` struct links into the ``available`` | 
|  | 35 | list of the :c:type:`v4l2_fh` struct so :ref:`VIDIOC_DQEVENT` will | 
|  | 36 | know which event to dequeue first. | 
|  | 37 |  | 
|  | 38 | Finally, if the event subscription is associated with a particular object | 
|  | 39 | such as a V4L2 control, then that object needs to know about that as well | 
|  | 40 | so that an event can be raised by that object. So the ``node`` field can | 
|  | 41 | be used to link the :c:type:`v4l2_subscribed_event` struct into a list of | 
|  | 42 | such objects. | 
|  | 43 |  | 
|  | 44 | So to summarize: | 
|  | 45 |  | 
|  | 46 | - struct :c:type:`v4l2_fh` has two lists: one of the ``subscribed`` events, | 
|  | 47 | and one of the ``available`` events. | 
|  | 48 |  | 
|  | 49 | - struct :c:type:`v4l2_subscribed_event` has a ringbuffer of raised | 
|  | 50 | (pending) events of that particular type. | 
|  | 51 |  | 
|  | 52 | - If struct :c:type:`v4l2_subscribed_event` is associated with a specific | 
|  | 53 | object, then that object will have an internal list of | 
|  | 54 | struct :c:type:`v4l2_subscribed_event` so it knows who subscribed an | 
|  | 55 | event to that object. | 
|  | 56 |  | 
|  | 57 | Furthermore, the internal struct :c:type:`v4l2_subscribed_event` has | 
|  | 58 | ``merge()`` and ``replace()`` callbacks which drivers can set. These | 
|  | 59 | callbacks are called when a new event is raised and there is no more room. | 
|  | 60 |  | 
|  | 61 | The ``replace()`` callback allows you to replace the payload of the old event | 
|  | 62 | with that of the new event, merging any relevant data from the old payload | 
|  | 63 | into the new payload that replaces it. It is called when this event type has | 
|  | 64 | a ringbuffer with size is one, i.e. only one event can be stored in the | 
|  | 65 | ringbuffer. | 
|  | 66 |  | 
|  | 67 | The ``merge()`` callback allows you to merge the oldest event payload into | 
|  | 68 | that of the second-oldest event payload. It is called when | 
|  | 69 | the ringbuffer has size is greater than one. | 
|  | 70 |  | 
|  | 71 | This way no status information is lost, just the intermediate steps leading | 
|  | 72 | up to that state. | 
|  | 73 |  | 
|  | 74 | A good example of these ``replace``/``merge`` callbacks is in v4l2-event.c: | 
|  | 75 | ``ctrls_replace()`` and ``ctrls_merge()`` callbacks for the control event. | 
|  | 76 |  | 
|  | 77 | .. note:: | 
|  | 78 | these callbacks can be called from interrupt context, so they must | 
|  | 79 | be fast. | 
|  | 80 |  | 
|  | 81 | In order to queue events to video device, drivers should call: | 
|  | 82 |  | 
|  | 83 | :c:func:`v4l2_event_queue <v4l2_event_queue>` | 
|  | 84 | (:c:type:`vdev <video_device>`, :c:type:`ev <v4l2_event>`) | 
|  | 85 |  | 
|  | 86 | The driver's only responsibility is to fill in the type and the data fields. | 
|  | 87 | The other fields will be filled in by V4L2. | 
|  | 88 |  | 
|  | 89 | Event subscription | 
|  | 90 | ~~~~~~~~~~~~~~~~~~ | 
|  | 91 |  | 
|  | 92 | Subscribing to an event is via: | 
|  | 93 |  | 
|  | 94 | :c:func:`v4l2_event_subscribe <v4l2_event_subscribe>` | 
|  | 95 | (:c:type:`fh <v4l2_fh>`, :c:type:`sub <v4l2_event_subscription>` , | 
|  | 96 | elems, :c:type:`ops <v4l2_subscribed_event_ops>`) | 
|  | 97 |  | 
|  | 98 |  | 
|  | 99 | This function is used to implement :c:type:`video_device`-> | 
|  | 100 | :c:type:`ioctl_ops <v4l2_ioctl_ops>`-> ``vidioc_subscribe_event``, | 
|  | 101 | but the driver must check first if the driver is able to produce events | 
|  | 102 | with specified event id, and then should call | 
|  | 103 | :c:func:`v4l2_event_subscribe` to subscribe the event. | 
|  | 104 |  | 
|  | 105 | The elems argument is the size of the event queue for this event. If it is 0, | 
|  | 106 | then the framework will fill in a default value (this depends on the event | 
|  | 107 | type). | 
|  | 108 |  | 
|  | 109 | The ops argument allows the driver to specify a number of callbacks: | 
|  | 110 |  | 
|  | 111 | .. tabularcolumns:: |p{1.5cm}|p{16.0cm}| | 
|  | 112 |  | 
|  | 113 | ======== ============================================================== | 
|  | 114 | Callback Description | 
|  | 115 | ======== ============================================================== | 
|  | 116 | add      called when a new listener gets added (subscribing to the same | 
|  | 117 | event twice will only cause this callback to get called once) | 
|  | 118 | del      called when a listener stops listening | 
|  | 119 | replace  replace event 'old' with event 'new'. | 
|  | 120 | merge    merge event 'old' into event 'new'. | 
|  | 121 | ======== ============================================================== | 
|  | 122 |  | 
|  | 123 | All 4 callbacks are optional, if you don't want to specify any callbacks | 
|  | 124 | the ops argument itself maybe ``NULL``. | 
|  | 125 |  | 
|  | 126 | Unsubscribing an event | 
|  | 127 | ~~~~~~~~~~~~~~~~~~~~~~ | 
|  | 128 |  | 
|  | 129 | Unsubscribing to an event is via: | 
|  | 130 |  | 
|  | 131 | :c:func:`v4l2_event_unsubscribe <v4l2_event_unsubscribe>` | 
|  | 132 | (:c:type:`fh <v4l2_fh>`, :c:type:`sub <v4l2_event_subscription>`) | 
|  | 133 |  | 
|  | 134 | This function is used to implement :c:type:`video_device`-> | 
|  | 135 | :c:type:`ioctl_ops <v4l2_ioctl_ops>`-> ``vidioc_unsubscribe_event``. | 
|  | 136 | A driver may call :c:func:`v4l2_event_unsubscribe` directly unless it | 
|  | 137 | wants to be involved in unsubscription process. | 
|  | 138 |  | 
|  | 139 | The special type ``V4L2_EVENT_ALL`` may be used to unsubscribe all events. The | 
|  | 140 | drivers may want to handle this in a special way. | 
|  | 141 |  | 
|  | 142 | Check if there's a pending event | 
|  | 143 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 
|  | 144 |  | 
|  | 145 | Checking if there's a pending event is via: | 
|  | 146 |  | 
|  | 147 | :c:func:`v4l2_event_pending <v4l2_event_pending>` | 
|  | 148 | (:c:type:`fh <v4l2_fh>`) | 
|  | 149 |  | 
|  | 150 |  | 
|  | 151 | This function returns the number of pending events. Useful when implementing | 
|  | 152 | poll. | 
|  | 153 |  | 
|  | 154 | How events work | 
|  | 155 | ~~~~~~~~~~~~~~~ | 
|  | 156 |  | 
|  | 157 | Events are delivered to user space through the poll system call. The driver | 
|  | 158 | can use :c:type:`v4l2_fh`->wait (a wait_queue_head_t) as the argument for | 
|  | 159 | ``poll_wait()``. | 
|  | 160 |  | 
|  | 161 | There are standard and private events. New standard events must use the | 
|  | 162 | smallest available event type. The drivers must allocate their events from | 
|  | 163 | their own class starting from class base. Class base is | 
|  | 164 | ``V4L2_EVENT_PRIVATE_START`` + n * 1000 where n is the lowest available number. | 
|  | 165 | The first event type in the class is reserved for future use, so the first | 
|  | 166 | available event type is 'class base + 1'. | 
|  | 167 |  | 
|  | 168 | An example on how the V4L2 events may be used can be found in the OMAP | 
|  | 169 | 3 ISP driver (``drivers/media/platform/omap3isp``). | 
|  | 170 |  | 
|  | 171 | A subdev can directly send an event to the :c:type:`v4l2_device` notify | 
|  | 172 | function with ``V4L2_DEVICE_NOTIFY_EVENT``. This allows the bridge to map | 
|  | 173 | the subdev that sends the event to the video node(s) associated with the | 
|  | 174 | subdev that need to be informed about such an event. | 
|  | 175 |  | 
|  | 176 | V4L2 event functions and data structures | 
|  | 177 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | 
|  | 178 |  | 
|  | 179 | .. kernel-doc:: include/media/v4l2-event.h | 
|  | 180 |  |