1 /* 2 * v4l2-event.h 3 * 4 * V4L2 events. 5 * 6 * Copyright (C) 2009--2010 Nokia Corporation. 7 * 8 * Contact: Sakari Ailus <sakari.ailus@iki.fi> 9 * 10 * This program is free software; you can redistribute it and/or 11 * modify it under the terms of the GNU General Public License 12 * version 2 as published by the Free Software Foundation. 13 * 14 * This program is distributed in the hope that it will be useful, but 15 * WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 * General Public License for more details. 18 */ 19 20 #ifndef V4L2_EVENT_H 21 #define V4L2_EVENT_H 22 23 #include <linux/types.h> 24 #include <linux/videodev2.h> 25 #include <linux/wait.h> 26 27 /* 28 * Overview: 29 * 30 * Events are subscribed per-filehandle. An event specification consists of a 31 * type and is optionally associated with an object identified through the 32 * 'id' field. So an event is uniquely identified by the (type, id) tuple. 33 * 34 * The v4l2-fh struct has a list of subscribed events. The v4l2_subscribed_event 35 * struct is added to that list, one for every subscribed event. 36 * 37 * Each v4l2_subscribed_event struct ends with an array of v4l2_kevent structs. 38 * This array (ringbuffer, really) is used to store any events raised by the 39 * driver. The v4l2_kevent struct links into the 'available' list of the 40 * v4l2_fh struct so VIDIOC_DQEVENT will know which event to dequeue first. 41 * 42 * Finally, if the event subscription is associated with a particular object 43 * such as a V4L2 control, then that object needs to know about that as well 44 * so that an event can be raised by that object. So the 'node' field can 45 * be used to link the v4l2_subscribed_event struct into a list of that 46 * object. 47 * 48 * So to summarize: 49 * 50 * struct v4l2_fh has two lists: one of the subscribed events, and one of the 51 * pending events. 52 * 53 * struct v4l2_subscribed_event has a ringbuffer of raised (pending) events of 54 * that particular type. 55 * 56 * If struct v4l2_subscribed_event is associated with a specific object, then 57 * that object will have an internal list of struct v4l2_subscribed_event so 58 * it knows who subscribed an event to that object. 59 */ 60 61 struct v4l2_fh; 62 struct v4l2_subdev; 63 struct v4l2_subscribed_event; 64 struct video_device; 65 66 /** 67 * struct v4l2_kevent - Internal kernel event struct. 68 * @list: List node for the v4l2_fh->available list. 69 * @sev: Pointer to parent v4l2_subscribed_event. 70 * @event: The event itself. 71 */ 72 struct v4l2_kevent { 73 struct list_head list; 74 struct v4l2_subscribed_event *sev; 75 struct v4l2_event event; 76 }; 77 78 /** 79 * struct v4l2_subscribed_event_ops - Subscribed event operations. 80 * 81 * @add: Optional callback, called when a new listener is added 82 * @del: Optional callback, called when a listener stops listening 83 * @replace: Optional callback that can replace event 'old' with event 'new'. 84 * @merge: Optional callback that can merge event 'old' into event 'new'. 85 */ 86 struct v4l2_subscribed_event_ops { 87 int (*add)(struct v4l2_subscribed_event *sev, unsigned int elems); 88 void (*del)(struct v4l2_subscribed_event *sev); 89 void (*replace)(struct v4l2_event *old, const struct v4l2_event *new); 90 void (*merge)(const struct v4l2_event *old, struct v4l2_event *new); 91 }; 92 93 /** 94 * struct v4l2_subscribed_event - Internal struct representing a subscribed 95 * event. 96 * 97 * @list: List node for the v4l2_fh->subscribed list. 98 * @type: Event type. 99 * @id: Associated object ID (e.g. control ID). 0 if there isn't any. 100 * @flags: Copy of v4l2_event_subscription->flags. 101 * @fh: Filehandle that subscribed to this event. 102 * @node: List node that hooks into the object's event list 103 * (if there is one). 104 * @ops: v4l2_subscribed_event_ops 105 * @elems: The number of elements in the events array. 106 * @first: The index of the events containing the oldest available event. 107 * @in_use: The number of queued events. 108 * @events: An array of @elems events. 109 */ 110 struct v4l2_subscribed_event { 111 struct list_head list; 112 u32 type; 113 u32 id; 114 u32 flags; 115 struct v4l2_fh *fh; 116 struct list_head node; 117 const struct v4l2_subscribed_event_ops *ops; 118 unsigned int elems; 119 unsigned int first; 120 unsigned int in_use; 121 struct v4l2_kevent events[]; 122 }; 123 124 /** 125 * v4l2_event_dequeue - Dequeue events from video device. 126 * 127 * @fh: pointer to struct v4l2_fh 128 * @event: pointer to struct v4l2_event 129 * @nonblocking: if not zero, waits for an event to arrive 130 */ 131 int v4l2_event_dequeue(struct v4l2_fh *fh, struct v4l2_event *event, 132 int nonblocking); 133 134 /** 135 * v4l2_event_queue - Queue events to video device. 136 * 137 * @vdev: pointer to &struct video_device 138 * @ev: pointer to &struct v4l2_event 139 * 140 * The event will be queued for all &struct v4l2_fh file handlers. 141 * 142 * .. note:: 143 * The driver's only responsibility is to fill in the type and the data 144 * fields.The other fields will be filled in by V4L2. 145 */ 146 void v4l2_event_queue(struct video_device *vdev, const struct v4l2_event *ev); 147 148 /** 149 * v4l2_event_queue_fh - Queue events to video device. 150 * 151 * @fh: pointer to &struct v4l2_fh 152 * @ev: pointer to &struct v4l2_event 153 * 154 * 155 * The event will be queued only for the specified &struct v4l2_fh file handler. 156 * 157 * .. note:: 158 * The driver's only responsibility is to fill in the type and the data 159 * fields.The other fields will be filled in by V4L2. 160 */ 161 void v4l2_event_queue_fh(struct v4l2_fh *fh, const struct v4l2_event *ev); 162 163 /** 164 * v4l2_event_pending - Check if an event is available 165 * 166 * @fh: pointer to &struct v4l2_fh 167 * 168 * Returns the number of pending events. 169 */ 170 int v4l2_event_pending(struct v4l2_fh *fh); 171 172 /** 173 * v4l2_event_subscribe - Subscribes to an event 174 * 175 * @fh: pointer to &struct v4l2_fh 176 * @sub: pointer to &struct v4l2_event_subscription 177 * @elems: size of the events queue 178 * @ops: pointer to &v4l2_subscribed_event_ops 179 * 180 * .. note:: 181 * 182 * if @elems is zero, the framework will fill in a default value, 183 * with is currently 1 element. 184 */ 185 int v4l2_event_subscribe(struct v4l2_fh *fh, 186 const struct v4l2_event_subscription *sub, 187 unsigned int elems, 188 const struct v4l2_subscribed_event_ops *ops); 189 /** 190 * v4l2_event_unsubscribe - Unsubscribes to an event 191 * 192 * @fh: pointer to &struct v4l2_fh 193 * @sub: pointer to &struct v4l2_event_subscription 194 */ 195 int v4l2_event_unsubscribe(struct v4l2_fh *fh, 196 const struct v4l2_event_subscription *sub); 197 /** 198 * v4l2_event_unsubscribe_all - Unsubscribes to all events 199 * 200 * @fh: pointer to &struct v4l2_fh 201 */ 202 void v4l2_event_unsubscribe_all(struct v4l2_fh *fh); 203 204 /** 205 * v4l2_event_subdev_unsubscribe - Subdev variant of v4l2_event_unsubscribe() 206 * 207 * @sd: pointer to &struct v4l2_subdev 208 * @fh: pointer to &struct v4l2_fh 209 * @sub: pointer to &struct v4l2_event_subscription 210 * 211 * .. note:: 212 * 213 * This function should be used for the &struct v4l2_subdev_core_ops 214 * %unsubscribe_event field. 215 */ 216 int v4l2_event_subdev_unsubscribe(struct v4l2_subdev *sd, 217 struct v4l2_fh *fh, 218 struct v4l2_event_subscription *sub); 219 /** 220 * v4l2_src_change_event_subscribe - helper function that calls 221 * v4l2_event_subscribe() if the event is %V4L2_EVENT_SOURCE_CHANGE. 222 * 223 * @fh: pointer to struct v4l2_fh 224 * @sub: pointer to &struct v4l2_event_subscription 225 */ 226 int v4l2_src_change_event_subscribe(struct v4l2_fh *fh, 227 const struct v4l2_event_subscription *sub); 228 /** 229 * v4l2_src_change_event_subdev_subscribe - Variant of v4l2_event_subscribe(), 230 * meant to subscribe only events of the type %V4L2_EVENT_SOURCE_CHANGE. 231 * 232 * @sd: pointer to &struct v4l2_subdev 233 * @fh: pointer to &struct v4l2_fh 234 * @sub: pointer to &struct v4l2_event_subscription 235 */ 236 int v4l2_src_change_event_subdev_subscribe(struct v4l2_subdev *sd, 237 struct v4l2_fh *fh, 238 struct v4l2_event_subscription *sub); 239 #endif /* V4L2_EVENT_H */ 240