diff --git a/include/libcamera/internal/v4l2_device.h b/include/libcamera/internal/v4l2_device.h
index 1a63fc547eac579fabf50421b719d07ddb2d6639..cc8116874e9eeecac76f5c25e8b5719c07976781 100644
--- a/include/libcamera/internal/v4l2_device.h
+++ b/include/libcamera/internal/v4l2_device.h
@@ -24,6 +24,7 @@
 #include <libcamera/controls.h>
 
 #include "libcamera/internal/formats.h"
+#include "libcamera/internal/v4l2_event.h"
 #include "libcamera/internal/v4l2_request.h"
 
 namespace libcamera {
@@ -46,7 +47,7 @@ public:
 	const std::string &deviceNode() const { return deviceNode_; }
 	std::string devicePath() const;
 
-	bool supportsFrameStartEvent();
+	bool supportsEvents(V4L2EventSubscription &sub);
 	int setFrameStartEnabled(bool enable);
 	Signal<uint32_t> frameStart;
 
diff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp
index 35c29ceca1bb1f9fb09e8c547b603ee8a2b67774..4d70d50ce50bb1b94e4c30c3fecfb78af678e592 100644
--- a/src/libcamera/pipeline/simple/simple.cpp
+++ b/src/libcamera/pipeline/simple/simple.cpp
@@ -45,6 +45,7 @@
 #include "libcamera/internal/pipeline_handler.h"
 #include "libcamera/internal/request.h"
 #include "libcamera/internal/software_isp/software_isp.h"
+#include "libcamera/internal/v4l2_event.h"
 #include "libcamera/internal/v4l2_subdevice.h"
 #include "libcamera/internal/v4l2_videodevice.h"
 
@@ -668,7 +669,8 @@ int SimpleCameraData::init()
 	frameStartEmitter_ = nullptr;
 	for (const Entity &entity : entities_) {
 		V4L2Subdevice *sd = pipe->subdev(entity.entity);
-		if (!sd || !sd->supportsFrameStartEvent())
+		V4L2EventSubscription sub(V4L2Event::Type::FrameSync);
+		if (!sd || !sd->supportsEvents(sub))
 			continue;
 
 		LOG(SimplePipeline, Debug)
diff --git a/src/libcamera/v4l2_device.cpp b/src/libcamera/v4l2_device.cpp
index 258c82b8d238156038909a4b7b7aa842c99bd677..654472286d4645ff96a404a09ff8de382a49678c 100644
--- a/src/libcamera/v4l2_device.cpp
+++ b/src/libcamera/v4l2_device.cpp
@@ -25,6 +25,7 @@
 
 #include "libcamera/internal/formats.h"
 #include "libcamera/internal/sysfs.h"
+#include "libcamera/internal/v4l2_event.h"
 
 /**
  * \file v4l2_device.h
@@ -470,18 +471,24 @@ std::string V4L2Device::devicePath() const
 }
 
 /**
- * \brief Check if frame start event is supported
+ * \brief Check if an event subscription is supported
  *
- * Due to limitations in the kernel API, this function may disable the frame
- * start event as a side effect. It should only be called during initialization,
- * before enabling the frame start event with setFrameStartEnabled().
+ * Due to limitations in the kernel API, this function may disable the events as
+ * a side effect. It should only be called during initialization, before
+ * enabling the events explicitly.
  *
- * \return True if frame start event is supported, false otherwise
+ * \return True if the subscription is supported, false otherwise
  */
-bool V4L2Device::supportsFrameStartEvent()
+bool V4L2Device::supportsEvents(V4L2EventSubscription &sub)
 {
 	struct v4l2_event_subscription event{};
-	event.type = V4L2_EVENT_FRAME_SYNC;
+
+	auto v4l2Type = V4L2Event::typeToV4L2(sub.type());
+	if (!v4l2Type)
+		return false;
+
+	event.type = *v4l2Type;
+	event.id = sub.id();
 
 	int ret = ioctl(VIDIOC_SUBSCRIBE_EVENT, &event);
 	if (ret)
