]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
media: v4l2-subdev: Refactor events
authorTommaso Merciai <tomm.merciai@gmail.com>
Sun, 20 Oct 2024 16:35:32 +0000 (18:35 +0200)
committerHans Verkuil <hverkuil@xs4all.nl>
Thu, 7 Nov 2024 08:05:57 +0000 (09:05 +0100)
Controls can be exposed to userspace via a v4l-subdevX device, and
userspace has to be able to subscribe to control events so that it is
notified when the control changes value. If a control handler is set for
the subdev then set the HAS_EVENTS flag automatically into
v4l2_subdev_init_finalize() and use v4l2_ctrl_subdev_subscribe_event() and
v4l2_event_subdev_unsubscribe() as default if subdev don't have
.(un)subscribe control operations. This simplifies subdev drivers by
avoiding the need to set the V4L2_SUBDEV_FL_HAS_EVENTS flag and plug the
event handlers, and ensures consistency of the API exposed to userspace.

Signed-off-by: Tommaso Merciai <tomm.merciai@gmail.com>
Suggested-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
drivers/media/v4l2-core/v4l2-subdev.c

index 827b3b8918cb94ec9cd6b4acd3aed45662e63cee..cde1774c9098dd0bf2f1232bd3e929f4c9026612 100644 (file)
@@ -696,10 +696,25 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg,
                return v4l2_event_dequeue(vfh, arg, file->f_flags & O_NONBLOCK);
 
        case VIDIOC_SUBSCRIBE_EVENT:
-               return v4l2_subdev_call(sd, core, subscribe_event, vfh, arg);
+               if (v4l2_subdev_has_op(sd, core, subscribe_event))
+                       return v4l2_subdev_call(sd, core, subscribe_event,
+                                               vfh, arg);
+
+               if ((sd->flags & V4L2_SUBDEV_FL_HAS_EVENTS) &&
+                   vfh->ctrl_handler)
+                       return v4l2_ctrl_subdev_subscribe_event(sd, vfh, arg);
+
+               return -ENOIOCTLCMD;
 
        case VIDIOC_UNSUBSCRIBE_EVENT:
-               return v4l2_subdev_call(sd, core, unsubscribe_event, vfh, arg);
+               if (v4l2_subdev_has_op(sd, core, unsubscribe_event))
+                       return v4l2_subdev_call(sd, core, unsubscribe_event,
+                                               vfh, arg);
+
+               if (sd->flags & V4L2_SUBDEV_FL_HAS_EVENTS)
+                       return v4l2_event_subdev_unsubscribe(sd, vfh, arg);
+
+               return -ENOIOCTLCMD;
 
 #ifdef CONFIG_VIDEO_ADV_DEBUG
        case VIDIOC_DBG_G_REGISTER:
@@ -1646,6 +1661,9 @@ int __v4l2_subdev_init_finalize(struct v4l2_subdev *sd, const char *name,
                }
        }
 
+       if (sd->ctrl_handler)
+               sd->flags |= V4L2_SUBDEV_FL_HAS_EVENTS;
+
        state = __v4l2_subdev_state_alloc(sd, name, key);
        if (IS_ERR(state))
                return PTR_ERR(state);