Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d3d7c963 authored by Sakari Ailus's avatar Sakari Ailus Committed by Mauro Carvalho Chehab
Browse files

V4L/DVB: V4L: Events: Support event handling in do_ioctl



Add support for event handling to do_ioctl.

Signed-off-by: default avatarSakari Ailus <sakari.ailus@maxwell.research.nokia.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent c3b5b024
Loading
Loading
Loading
Loading
+10 −1
Original line number Original line Diff line number Diff line
@@ -34,7 +34,16 @@ int v4l2_fh_init(struct v4l2_fh *fh, struct video_device *vdev)
	INIT_LIST_HEAD(&fh->list);
	INIT_LIST_HEAD(&fh->list);
	set_bit(V4L2_FL_USES_V4L2_FH, &fh->vdev->flags);
	set_bit(V4L2_FL_USES_V4L2_FH, &fh->vdev->flags);


	/*
	 * fh->events only needs to be initialized if the driver
	 * supports the VIDIOC_SUBSCRIBE_EVENT ioctl.
	 */
	if (vdev->ioctl_ops && vdev->ioctl_ops->vidioc_subscribe_event)
		return v4l2_event_init(fh);
		return v4l2_event_init(fh);

	fh->events = NULL;

	return 0;
}
}
EXPORT_SYMBOL_GPL(v4l2_fh_init);
EXPORT_SYMBOL_GPL(v4l2_fh_init);


+50 −0
Original line number Original line Diff line number Diff line
@@ -26,6 +26,8 @@
#endif
#endif
#include <media/v4l2-common.h>
#include <media/v4l2-common.h>
#include <media/v4l2-ioctl.h>
#include <media/v4l2-ioctl.h>
#include <media/v4l2-fh.h>
#include <media/v4l2-event.h>
#include <media/v4l2-chip-ident.h>
#include <media/v4l2-chip-ident.h>


#define dbgarg(cmd, fmt, arg...) \
#define dbgarg(cmd, fmt, arg...) \
@@ -1951,7 +1953,55 @@ static long __video_do_ioctl(struct file *file,
		}
		}
		break;
		break;
	}
	}
	case VIDIOC_DQEVENT:
	{
		struct v4l2_event *ev = arg;

		if (!ops->vidioc_subscribe_event)
			break;

		ret = v4l2_event_dequeue(fh, ev, file->f_flags & O_NONBLOCK);
		if (ret < 0) {
			dbgarg(cmd, "no pending events?");
			break;
		}
		dbgarg(cmd,
		       "pending=%d, type=0x%8.8x, sequence=%d, "
		       "timestamp=%lu.%9.9lu ",
		       ev->pending, ev->type, ev->sequence,
		       ev->timestamp.tv_sec, ev->timestamp.tv_nsec);
		break;
	}
	case VIDIOC_SUBSCRIBE_EVENT:
	{
		struct v4l2_event_subscription *sub = arg;


		if (!ops->vidioc_subscribe_event)
			break;

		ret = ops->vidioc_subscribe_event(fh, sub);
		if (ret < 0) {
			dbgarg(cmd, "failed, ret=%ld", ret);
			break;
		}
		dbgarg(cmd, "type=0x%8.8x", sub->type);
		break;
	}
	case VIDIOC_UNSUBSCRIBE_EVENT:
	{
		struct v4l2_event_subscription *sub = arg;

		if (!ops->vidioc_unsubscribe_event)
			break;

		ret = ops->vidioc_unsubscribe_event(fh, sub);
		if (ret < 0) {
			dbgarg(cmd, "failed, ret=%ld", ret);
			break;
		}
		dbgarg(cmd, "type=0x%8.8x", sub->type);
		break;
	}
	default:
	default:
	{
	{
		if (!ops->vidioc_default)
		if (!ops->vidioc_default)
+7 −0
Original line number Original line Diff line number Diff line
@@ -21,6 +21,8 @@
#include <linux/videodev2.h>
#include <linux/videodev2.h>
#endif
#endif


struct v4l2_fh;

struct v4l2_ioctl_ops {
struct v4l2_ioctl_ops {
	/* ioctl callbacks */
	/* ioctl callbacks */


@@ -254,6 +256,11 @@ struct v4l2_ioctl_ops {
	int (*vidioc_g_dv_timings) (struct file *file, void *fh,
	int (*vidioc_g_dv_timings) (struct file *file, void *fh,
				    struct v4l2_dv_timings *timings);
				    struct v4l2_dv_timings *timings);


	int (*vidioc_subscribe_event)  (struct v4l2_fh *fh,
					struct v4l2_event_subscription *sub);
	int (*vidioc_unsubscribe_event)(struct v4l2_fh *fh,
					struct v4l2_event_subscription *sub);

	/* For other private ioctls */
	/* For other private ioctls */
	long (*vidioc_default)	       (struct file *file, void *fh,
	long (*vidioc_default)	       (struct file *file, void *fh,
					int cmd, void *arg);
					int cmd, void *arg);