162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * v4l2-event.h
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * V4L2 events.
662306a36Sopenharmony_ci *
762306a36Sopenharmony_ci * Copyright (C) 2009--2010 Nokia Corporation.
862306a36Sopenharmony_ci *
962306a36Sopenharmony_ci * Contact: Sakari Ailus <sakari.ailus@iki.fi>
1062306a36Sopenharmony_ci */
1162306a36Sopenharmony_ci
1262306a36Sopenharmony_ci#ifndef V4L2_EVENT_H
1362306a36Sopenharmony_ci#define V4L2_EVENT_H
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_ci#include <linux/types.h>
1662306a36Sopenharmony_ci#include <linux/videodev2.h>
1762306a36Sopenharmony_ci#include <linux/wait.h>
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_cistruct v4l2_fh;
2062306a36Sopenharmony_cistruct v4l2_subdev;
2162306a36Sopenharmony_cistruct v4l2_subscribed_event;
2262306a36Sopenharmony_cistruct video_device;
2362306a36Sopenharmony_ci
2462306a36Sopenharmony_ci/**
2562306a36Sopenharmony_ci * struct v4l2_kevent - Internal kernel event struct.
2662306a36Sopenharmony_ci * @list:	List node for the v4l2_fh->available list.
2762306a36Sopenharmony_ci * @sev:	Pointer to parent v4l2_subscribed_event.
2862306a36Sopenharmony_ci * @event:	The event itself.
2962306a36Sopenharmony_ci * @ts:		The timestamp of the event.
3062306a36Sopenharmony_ci */
3162306a36Sopenharmony_cistruct v4l2_kevent {
3262306a36Sopenharmony_ci	struct list_head	list;
3362306a36Sopenharmony_ci	struct v4l2_subscribed_event *sev;
3462306a36Sopenharmony_ci	struct v4l2_event	event;
3562306a36Sopenharmony_ci	u64			ts;
3662306a36Sopenharmony_ci};
3762306a36Sopenharmony_ci
3862306a36Sopenharmony_ci/**
3962306a36Sopenharmony_ci * struct v4l2_subscribed_event_ops - Subscribed event operations.
4062306a36Sopenharmony_ci *
4162306a36Sopenharmony_ci * @add:	Optional callback, called when a new listener is added
4262306a36Sopenharmony_ci * @del:	Optional callback, called when a listener stops listening
4362306a36Sopenharmony_ci * @replace:	Optional callback that can replace event 'old' with event 'new'.
4462306a36Sopenharmony_ci * @merge:	Optional callback that can merge event 'old' into event 'new'.
4562306a36Sopenharmony_ci */
4662306a36Sopenharmony_cistruct v4l2_subscribed_event_ops {
4762306a36Sopenharmony_ci	int  (*add)(struct v4l2_subscribed_event *sev, unsigned int elems);
4862306a36Sopenharmony_ci	void (*del)(struct v4l2_subscribed_event *sev);
4962306a36Sopenharmony_ci	void (*replace)(struct v4l2_event *old, const struct v4l2_event *new);
5062306a36Sopenharmony_ci	void (*merge)(const struct v4l2_event *old, struct v4l2_event *new);
5162306a36Sopenharmony_ci};
5262306a36Sopenharmony_ci
5362306a36Sopenharmony_ci/**
5462306a36Sopenharmony_ci * struct v4l2_subscribed_event - Internal struct representing a subscribed
5562306a36Sopenharmony_ci *		event.
5662306a36Sopenharmony_ci *
5762306a36Sopenharmony_ci * @list:	List node for the v4l2_fh->subscribed list.
5862306a36Sopenharmony_ci * @type:	Event type.
5962306a36Sopenharmony_ci * @id:	Associated object ID (e.g. control ID). 0 if there isn't any.
6062306a36Sopenharmony_ci * @flags:	Copy of v4l2_event_subscription->flags.
6162306a36Sopenharmony_ci * @fh:	Filehandle that subscribed to this event.
6262306a36Sopenharmony_ci * @node:	List node that hooks into the object's event list
6362306a36Sopenharmony_ci *		(if there is one).
6462306a36Sopenharmony_ci * @ops:	v4l2_subscribed_event_ops
6562306a36Sopenharmony_ci * @elems:	The number of elements in the events array.
6662306a36Sopenharmony_ci * @first:	The index of the events containing the oldest available event.
6762306a36Sopenharmony_ci * @in_use:	The number of queued events.
6862306a36Sopenharmony_ci * @events:	An array of @elems events.
6962306a36Sopenharmony_ci */
7062306a36Sopenharmony_cistruct v4l2_subscribed_event {
7162306a36Sopenharmony_ci	struct list_head	list;
7262306a36Sopenharmony_ci	u32			type;
7362306a36Sopenharmony_ci	u32			id;
7462306a36Sopenharmony_ci	u32			flags;
7562306a36Sopenharmony_ci	struct v4l2_fh		*fh;
7662306a36Sopenharmony_ci	struct list_head	node;
7762306a36Sopenharmony_ci	const struct v4l2_subscribed_event_ops *ops;
7862306a36Sopenharmony_ci	unsigned int		elems;
7962306a36Sopenharmony_ci	unsigned int		first;
8062306a36Sopenharmony_ci	unsigned int		in_use;
8162306a36Sopenharmony_ci	struct v4l2_kevent	events[];
8262306a36Sopenharmony_ci};
8362306a36Sopenharmony_ci
8462306a36Sopenharmony_ci/**
8562306a36Sopenharmony_ci * v4l2_event_dequeue - Dequeue events from video device.
8662306a36Sopenharmony_ci *
8762306a36Sopenharmony_ci * @fh: pointer to struct v4l2_fh
8862306a36Sopenharmony_ci * @event: pointer to struct v4l2_event
8962306a36Sopenharmony_ci * @nonblocking: if not zero, waits for an event to arrive
9062306a36Sopenharmony_ci */
9162306a36Sopenharmony_ciint v4l2_event_dequeue(struct v4l2_fh *fh, struct v4l2_event *event,
9262306a36Sopenharmony_ci		       int nonblocking);
9362306a36Sopenharmony_ci
9462306a36Sopenharmony_ci/**
9562306a36Sopenharmony_ci * v4l2_event_queue - Queue events to video device.
9662306a36Sopenharmony_ci *
9762306a36Sopenharmony_ci * @vdev: pointer to &struct video_device
9862306a36Sopenharmony_ci * @ev: pointer to &struct v4l2_event
9962306a36Sopenharmony_ci *
10062306a36Sopenharmony_ci * The event will be queued for all &struct v4l2_fh file handlers.
10162306a36Sopenharmony_ci *
10262306a36Sopenharmony_ci * .. note::
10362306a36Sopenharmony_ci *    The driver's only responsibility is to fill in the type and the data
10462306a36Sopenharmony_ci *    fields. The other fields will be filled in by V4L2.
10562306a36Sopenharmony_ci */
10662306a36Sopenharmony_civoid v4l2_event_queue(struct video_device *vdev, const struct v4l2_event *ev);
10762306a36Sopenharmony_ci
10862306a36Sopenharmony_ci/**
10962306a36Sopenharmony_ci * v4l2_event_queue_fh - Queue events to video device.
11062306a36Sopenharmony_ci *
11162306a36Sopenharmony_ci * @fh: pointer to &struct v4l2_fh
11262306a36Sopenharmony_ci * @ev: pointer to &struct v4l2_event
11362306a36Sopenharmony_ci *
11462306a36Sopenharmony_ci *
11562306a36Sopenharmony_ci * The event will be queued only for the specified &struct v4l2_fh file handler.
11662306a36Sopenharmony_ci *
11762306a36Sopenharmony_ci * .. note::
11862306a36Sopenharmony_ci *    The driver's only responsibility is to fill in the type and the data
11962306a36Sopenharmony_ci *    fields. The other fields will be filled in by V4L2.
12062306a36Sopenharmony_ci */
12162306a36Sopenharmony_civoid v4l2_event_queue_fh(struct v4l2_fh *fh, const struct v4l2_event *ev);
12262306a36Sopenharmony_ci
12362306a36Sopenharmony_ci/**
12462306a36Sopenharmony_ci * v4l2_event_wake_all - Wake all filehandles.
12562306a36Sopenharmony_ci *
12662306a36Sopenharmony_ci * Used when unregistering a video device.
12762306a36Sopenharmony_ci *
12862306a36Sopenharmony_ci * @vdev: pointer to &struct video_device
12962306a36Sopenharmony_ci */
13062306a36Sopenharmony_civoid v4l2_event_wake_all(struct video_device *vdev);
13162306a36Sopenharmony_ci
13262306a36Sopenharmony_ci/**
13362306a36Sopenharmony_ci * v4l2_event_pending - Check if an event is available
13462306a36Sopenharmony_ci *
13562306a36Sopenharmony_ci * @fh: pointer to &struct v4l2_fh
13662306a36Sopenharmony_ci *
13762306a36Sopenharmony_ci * Returns the number of pending events.
13862306a36Sopenharmony_ci */
13962306a36Sopenharmony_ciint v4l2_event_pending(struct v4l2_fh *fh);
14062306a36Sopenharmony_ci
14162306a36Sopenharmony_ci/**
14262306a36Sopenharmony_ci * v4l2_event_subscribe - Subscribes to an event
14362306a36Sopenharmony_ci *
14462306a36Sopenharmony_ci * @fh: pointer to &struct v4l2_fh
14562306a36Sopenharmony_ci * @sub: pointer to &struct v4l2_event_subscription
14662306a36Sopenharmony_ci * @elems: size of the events queue
14762306a36Sopenharmony_ci * @ops: pointer to &v4l2_subscribed_event_ops
14862306a36Sopenharmony_ci *
14962306a36Sopenharmony_ci * .. note::
15062306a36Sopenharmony_ci *
15162306a36Sopenharmony_ci *    if @elems is zero, the framework will fill in a default value,
15262306a36Sopenharmony_ci *    with is currently 1 element.
15362306a36Sopenharmony_ci */
15462306a36Sopenharmony_ciint v4l2_event_subscribe(struct v4l2_fh *fh,
15562306a36Sopenharmony_ci			 const struct v4l2_event_subscription *sub,
15662306a36Sopenharmony_ci			 unsigned int elems,
15762306a36Sopenharmony_ci			 const struct v4l2_subscribed_event_ops *ops);
15862306a36Sopenharmony_ci/**
15962306a36Sopenharmony_ci * v4l2_event_unsubscribe - Unsubscribes to an event
16062306a36Sopenharmony_ci *
16162306a36Sopenharmony_ci * @fh: pointer to &struct v4l2_fh
16262306a36Sopenharmony_ci * @sub: pointer to &struct v4l2_event_subscription
16362306a36Sopenharmony_ci */
16462306a36Sopenharmony_ciint v4l2_event_unsubscribe(struct v4l2_fh *fh,
16562306a36Sopenharmony_ci			   const struct v4l2_event_subscription *sub);
16662306a36Sopenharmony_ci/**
16762306a36Sopenharmony_ci * v4l2_event_unsubscribe_all - Unsubscribes to all events
16862306a36Sopenharmony_ci *
16962306a36Sopenharmony_ci * @fh: pointer to &struct v4l2_fh
17062306a36Sopenharmony_ci */
17162306a36Sopenharmony_civoid v4l2_event_unsubscribe_all(struct v4l2_fh *fh);
17262306a36Sopenharmony_ci
17362306a36Sopenharmony_ci/**
17462306a36Sopenharmony_ci * v4l2_event_subdev_unsubscribe - Subdev variant of v4l2_event_unsubscribe()
17562306a36Sopenharmony_ci *
17662306a36Sopenharmony_ci * @sd: pointer to &struct v4l2_subdev
17762306a36Sopenharmony_ci * @fh: pointer to &struct v4l2_fh
17862306a36Sopenharmony_ci * @sub: pointer to &struct v4l2_event_subscription
17962306a36Sopenharmony_ci *
18062306a36Sopenharmony_ci * .. note::
18162306a36Sopenharmony_ci *
18262306a36Sopenharmony_ci *	This function should be used for the &struct v4l2_subdev_core_ops
18362306a36Sopenharmony_ci *	%unsubscribe_event field.
18462306a36Sopenharmony_ci */
18562306a36Sopenharmony_ciint v4l2_event_subdev_unsubscribe(struct v4l2_subdev *sd,
18662306a36Sopenharmony_ci				  struct v4l2_fh *fh,
18762306a36Sopenharmony_ci				  struct v4l2_event_subscription *sub);
18862306a36Sopenharmony_ci/**
18962306a36Sopenharmony_ci * v4l2_src_change_event_subscribe - helper function that calls
19062306a36Sopenharmony_ci *	v4l2_event_subscribe() if the event is %V4L2_EVENT_SOURCE_CHANGE.
19162306a36Sopenharmony_ci *
19262306a36Sopenharmony_ci * @fh: pointer to struct v4l2_fh
19362306a36Sopenharmony_ci * @sub: pointer to &struct v4l2_event_subscription
19462306a36Sopenharmony_ci */
19562306a36Sopenharmony_ciint v4l2_src_change_event_subscribe(struct v4l2_fh *fh,
19662306a36Sopenharmony_ci				    const struct v4l2_event_subscription *sub);
19762306a36Sopenharmony_ci/**
19862306a36Sopenharmony_ci * v4l2_src_change_event_subdev_subscribe - Variant of v4l2_event_subscribe(),
19962306a36Sopenharmony_ci *	meant to subscribe only events of the type %V4L2_EVENT_SOURCE_CHANGE.
20062306a36Sopenharmony_ci *
20162306a36Sopenharmony_ci * @sd: pointer to &struct v4l2_subdev
20262306a36Sopenharmony_ci * @fh: pointer to &struct v4l2_fh
20362306a36Sopenharmony_ci * @sub: pointer to &struct v4l2_event_subscription
20462306a36Sopenharmony_ci */
20562306a36Sopenharmony_ciint v4l2_src_change_event_subdev_subscribe(struct v4l2_subdev *sd,
20662306a36Sopenharmony_ci					   struct v4l2_fh *fh,
20762306a36Sopenharmony_ci					   struct v4l2_event_subscription *sub);
20862306a36Sopenharmony_ci#endif /* V4L2_EVENT_H */
209