1 // SPDX-License-Identifier: GPL-2.0-only
5 * Copyright (C) 2010 Nokia Corporation
7 * Contact: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
8 * Sakari Ailus <sakari.ailus@iki.fi>
11 #include <linux/ioctl.h>
13 #include <linux/module.h>
14 #include <linux/slab.h>
15 #include <linux/types.h>
16 #include <linux/videodev2.h>
17 #include <linux/export.h>
18 #include <linux/version.h>
20 #include <media/v4l2-ctrls.h>
21 #include <media/v4l2-device.h>
22 #include <media/v4l2-ioctl.h>
23 #include <media/v4l2-fh.h>
24 #include <media/v4l2-event.h>
26 #if defined(CONFIG_VIDEO_V4L2_SUBDEV_API)
27 static int subdev_fh_init(struct v4l2_subdev_fh
*fh
, struct v4l2_subdev
*sd
)
29 if (sd
->entity
.num_pads
) {
30 fh
->pad
= v4l2_subdev_alloc_pad_config(sd
);
38 static void subdev_fh_free(struct v4l2_subdev_fh
*fh
)
40 v4l2_subdev_free_pad_config(fh
->pad
);
44 static int subdev_open(struct file
*file
)
46 struct video_device
*vdev
= video_devdata(file
);
47 struct v4l2_subdev
*sd
= vdev_to_v4l2_subdev(vdev
);
48 struct v4l2_subdev_fh
*subdev_fh
;
51 subdev_fh
= kzalloc(sizeof(*subdev_fh
), GFP_KERNEL
);
52 if (subdev_fh
== NULL
)
55 ret
= subdev_fh_init(subdev_fh
, sd
);
61 v4l2_fh_init(&subdev_fh
->vfh
, vdev
);
62 v4l2_fh_add(&subdev_fh
->vfh
);
63 file
->private_data
= &subdev_fh
->vfh
;
64 #if defined(CONFIG_MEDIA_CONTROLLER)
65 if (sd
->v4l2_dev
->mdev
&& sd
->entity
.graph_obj
.mdev
->dev
) {
68 owner
= sd
->entity
.graph_obj
.mdev
->dev
->driver
->owner
;
69 if (!try_module_get(owner
)) {
73 subdev_fh
->owner
= owner
;
77 if (sd
->internal_ops
&& sd
->internal_ops
->open
) {
78 ret
= sd
->internal_ops
->open(sd
, subdev_fh
);
86 module_put(subdev_fh
->owner
);
87 v4l2_fh_del(&subdev_fh
->vfh
);
88 v4l2_fh_exit(&subdev_fh
->vfh
);
89 subdev_fh_free(subdev_fh
);
95 static int subdev_close(struct file
*file
)
97 struct video_device
*vdev
= video_devdata(file
);
98 struct v4l2_subdev
*sd
= vdev_to_v4l2_subdev(vdev
);
99 struct v4l2_fh
*vfh
= file
->private_data
;
100 struct v4l2_subdev_fh
*subdev_fh
= to_v4l2_subdev_fh(vfh
);
102 if (sd
->internal_ops
&& sd
->internal_ops
->close
)
103 sd
->internal_ops
->close(sd
, subdev_fh
);
104 module_put(subdev_fh
->owner
);
107 subdev_fh_free(subdev_fh
);
109 file
->private_data
= NULL
;
113 #else /* CONFIG_VIDEO_V4L2_SUBDEV_API */
114 static int subdev_open(struct file
*file
)
119 static int subdev_close(struct file
*file
)
123 #endif /* CONFIG_VIDEO_V4L2_SUBDEV_API */
125 static inline int check_which(u32 which
)
127 if (which
!= V4L2_SUBDEV_FORMAT_TRY
&&
128 which
!= V4L2_SUBDEV_FORMAT_ACTIVE
)
134 static inline int check_pad(struct v4l2_subdev
*sd
, u32 pad
)
136 #if defined(CONFIG_MEDIA_CONTROLLER)
137 if (sd
->entity
.num_pads
) {
138 if (pad
>= sd
->entity
.num_pads
)
143 /* allow pad 0 on subdevices not registered as media entities */
149 static int check_cfg(u32 which
, struct v4l2_subdev_pad_config
*cfg
)
151 if (which
== V4L2_SUBDEV_FORMAT_TRY
&& !cfg
)
157 static inline int check_format(struct v4l2_subdev
*sd
,
158 struct v4l2_subdev_pad_config
*cfg
,
159 struct v4l2_subdev_format
*format
)
164 return check_which(format
->which
) ? : check_pad(sd
, format
->pad
) ? :
165 check_cfg(format
->which
, cfg
);
168 static int call_get_fmt(struct v4l2_subdev
*sd
,
169 struct v4l2_subdev_pad_config
*cfg
,
170 struct v4l2_subdev_format
*format
)
172 return check_format(sd
, cfg
, format
) ? :
173 sd
->ops
->pad
->get_fmt(sd
, cfg
, format
);
176 static int call_set_fmt(struct v4l2_subdev
*sd
,
177 struct v4l2_subdev_pad_config
*cfg
,
178 struct v4l2_subdev_format
*format
)
180 return check_format(sd
, cfg
, format
) ? :
181 sd
->ops
->pad
->set_fmt(sd
, cfg
, format
);
184 static int call_enum_mbus_code(struct v4l2_subdev
*sd
,
185 struct v4l2_subdev_pad_config
*cfg
,
186 struct v4l2_subdev_mbus_code_enum
*code
)
191 return check_which(code
->which
) ? : check_pad(sd
, code
->pad
) ? :
192 check_cfg(code
->which
, cfg
) ? :
193 sd
->ops
->pad
->enum_mbus_code(sd
, cfg
, code
);
196 static int call_enum_frame_size(struct v4l2_subdev
*sd
,
197 struct v4l2_subdev_pad_config
*cfg
,
198 struct v4l2_subdev_frame_size_enum
*fse
)
203 return check_which(fse
->which
) ? : check_pad(sd
, fse
->pad
) ? :
204 check_cfg(fse
->which
, cfg
) ? :
205 sd
->ops
->pad
->enum_frame_size(sd
, cfg
, fse
);
208 static inline int check_frame_interval(struct v4l2_subdev
*sd
,
209 struct v4l2_subdev_frame_interval
*fi
)
214 return check_pad(sd
, fi
->pad
);
217 static int call_g_frame_interval(struct v4l2_subdev
*sd
,
218 struct v4l2_subdev_frame_interval
*fi
)
220 return check_frame_interval(sd
, fi
) ? :
221 sd
->ops
->video
->g_frame_interval(sd
, fi
);
224 static int call_s_frame_interval(struct v4l2_subdev
*sd
,
225 struct v4l2_subdev_frame_interval
*fi
)
227 return check_frame_interval(sd
, fi
) ? :
228 sd
->ops
->video
->s_frame_interval(sd
, fi
);
231 static int call_enum_frame_interval(struct v4l2_subdev
*sd
,
232 struct v4l2_subdev_pad_config
*cfg
,
233 struct v4l2_subdev_frame_interval_enum
*fie
)
238 return check_which(fie
->which
) ? : check_pad(sd
, fie
->pad
) ? :
239 check_cfg(fie
->which
, cfg
) ? :
240 sd
->ops
->pad
->enum_frame_interval(sd
, cfg
, fie
);
243 static inline int check_selection(struct v4l2_subdev
*sd
,
244 struct v4l2_subdev_pad_config
*cfg
,
245 struct v4l2_subdev_selection
*sel
)
250 return check_which(sel
->which
) ? : check_pad(sd
, sel
->pad
) ? :
251 check_cfg(sel
->which
, cfg
);
254 static int call_get_selection(struct v4l2_subdev
*sd
,
255 struct v4l2_subdev_pad_config
*cfg
,
256 struct v4l2_subdev_selection
*sel
)
258 return check_selection(sd
, cfg
, sel
) ? :
259 sd
->ops
->pad
->get_selection(sd
, cfg
, sel
);
262 static int call_set_selection(struct v4l2_subdev
*sd
,
263 struct v4l2_subdev_pad_config
*cfg
,
264 struct v4l2_subdev_selection
*sel
)
266 return check_selection(sd
, cfg
, sel
) ? :
267 sd
->ops
->pad
->set_selection(sd
, cfg
, sel
);
270 static inline int check_edid(struct v4l2_subdev
*sd
,
271 struct v4l2_subdev_edid
*edid
)
276 if (edid
->blocks
&& edid
->edid
== NULL
)
279 return check_pad(sd
, edid
->pad
);
282 static int call_get_edid(struct v4l2_subdev
*sd
, struct v4l2_subdev_edid
*edid
)
284 return check_edid(sd
, edid
) ? : sd
->ops
->pad
->get_edid(sd
, edid
);
287 static int call_set_edid(struct v4l2_subdev
*sd
, struct v4l2_subdev_edid
*edid
)
289 return check_edid(sd
, edid
) ? : sd
->ops
->pad
->set_edid(sd
, edid
);
292 static int call_dv_timings_cap(struct v4l2_subdev
*sd
,
293 struct v4l2_dv_timings_cap
*cap
)
298 return check_pad(sd
, cap
->pad
) ? :
299 sd
->ops
->pad
->dv_timings_cap(sd
, cap
);
302 static int call_enum_dv_timings(struct v4l2_subdev
*sd
,
303 struct v4l2_enum_dv_timings
*dvt
)
308 return check_pad(sd
, dvt
->pad
) ? :
309 sd
->ops
->pad
->enum_dv_timings(sd
, dvt
);
312 static const struct v4l2_subdev_pad_ops v4l2_subdev_call_pad_wrappers
= {
313 .get_fmt
= call_get_fmt
,
314 .set_fmt
= call_set_fmt
,
315 .enum_mbus_code
= call_enum_mbus_code
,
316 .enum_frame_size
= call_enum_frame_size
,
317 .enum_frame_interval
= call_enum_frame_interval
,
318 .get_selection
= call_get_selection
,
319 .set_selection
= call_set_selection
,
320 .get_edid
= call_get_edid
,
321 .set_edid
= call_set_edid
,
322 .dv_timings_cap
= call_dv_timings_cap
,
323 .enum_dv_timings
= call_enum_dv_timings
,
326 static const struct v4l2_subdev_video_ops v4l2_subdev_call_video_wrappers
= {
327 .g_frame_interval
= call_g_frame_interval
,
328 .s_frame_interval
= call_s_frame_interval
,
331 const struct v4l2_subdev_ops v4l2_subdev_call_wrappers
= {
332 .pad
= &v4l2_subdev_call_pad_wrappers
,
333 .video
= &v4l2_subdev_call_video_wrappers
,
335 EXPORT_SYMBOL(v4l2_subdev_call_wrappers
);
337 #if defined(CONFIG_VIDEO_V4L2_SUBDEV_API)
338 static long subdev_do_ioctl(struct file
*file
, unsigned int cmd
, void *arg
)
340 struct video_device
*vdev
= video_devdata(file
);
341 struct v4l2_subdev
*sd
= vdev_to_v4l2_subdev(vdev
);
342 struct v4l2_fh
*vfh
= file
->private_data
;
343 struct v4l2_subdev_fh
*subdev_fh
= to_v4l2_subdev_fh(vfh
);
344 bool ro_subdev
= test_bit(V4L2_FL_SUBDEV_RO_DEVNODE
, &vdev
->flags
);
348 case VIDIOC_SUBDEV_QUERYCAP
: {
349 struct v4l2_subdev_capability
*cap
= arg
;
351 memset(cap
->reserved
, 0, sizeof(cap
->reserved
));
352 cap
->version
= LINUX_VERSION_CODE
;
353 cap
->capabilities
= ro_subdev
? V4L2_SUBDEV_CAP_RO_SUBDEV
: 0;
358 case VIDIOC_QUERYCTRL
:
360 * TODO: this really should be folded into v4l2_queryctrl (this
361 * currently returns -EINVAL for NULL control handlers).
362 * However, v4l2_queryctrl() is still called directly by
363 * drivers as well and until that has been addressed I believe
364 * it is safer to do the check here. The same is true for the
365 * other control ioctls below.
367 if (!vfh
->ctrl_handler
)
369 return v4l2_queryctrl(vfh
->ctrl_handler
, arg
);
371 case VIDIOC_QUERY_EXT_CTRL
:
372 if (!vfh
->ctrl_handler
)
374 return v4l2_query_ext_ctrl(vfh
->ctrl_handler
, arg
);
376 case VIDIOC_QUERYMENU
:
377 if (!vfh
->ctrl_handler
)
379 return v4l2_querymenu(vfh
->ctrl_handler
, arg
);
382 if (!vfh
->ctrl_handler
)
384 return v4l2_g_ctrl(vfh
->ctrl_handler
, arg
);
387 if (!vfh
->ctrl_handler
)
389 return v4l2_s_ctrl(vfh
, vfh
->ctrl_handler
, arg
);
391 case VIDIOC_G_EXT_CTRLS
:
392 if (!vfh
->ctrl_handler
)
394 return v4l2_g_ext_ctrls(vfh
->ctrl_handler
,
395 vdev
, sd
->v4l2_dev
->mdev
, arg
);
397 case VIDIOC_S_EXT_CTRLS
:
398 if (!vfh
->ctrl_handler
)
400 return v4l2_s_ext_ctrls(vfh
, vfh
->ctrl_handler
,
401 vdev
, sd
->v4l2_dev
->mdev
, arg
);
403 case VIDIOC_TRY_EXT_CTRLS
:
404 if (!vfh
->ctrl_handler
)
406 return v4l2_try_ext_ctrls(vfh
->ctrl_handler
,
407 vdev
, sd
->v4l2_dev
->mdev
, arg
);
410 if (!(sd
->flags
& V4L2_SUBDEV_FL_HAS_EVENTS
))
413 return v4l2_event_dequeue(vfh
, arg
, file
->f_flags
& O_NONBLOCK
);
415 case VIDIOC_DQEVENT_TIME32
: {
416 struct v4l2_event_time32
*ev32
= arg
;
417 struct v4l2_event ev
= { };
419 if (!(sd
->flags
& V4L2_SUBDEV_FL_HAS_EVENTS
))
422 rval
= v4l2_event_dequeue(vfh
, &ev
, file
->f_flags
& O_NONBLOCK
);
424 *ev32
= (struct v4l2_event_time32
) {
426 .pending
= ev
.pending
,
427 .sequence
= ev
.sequence
,
428 .timestamp
.tv_sec
= ev
.timestamp
.tv_sec
,
429 .timestamp
.tv_nsec
= ev
.timestamp
.tv_nsec
,
433 memcpy(&ev32
->u
, &ev
.u
, sizeof(ev
.u
));
434 memcpy(&ev32
->reserved
, &ev
.reserved
, sizeof(ev
.reserved
));
439 case VIDIOC_SUBSCRIBE_EVENT
:
440 return v4l2_subdev_call(sd
, core
, subscribe_event
, vfh
, arg
);
442 case VIDIOC_UNSUBSCRIBE_EVENT
:
443 return v4l2_subdev_call(sd
, core
, unsubscribe_event
, vfh
, arg
);
445 #ifdef CONFIG_VIDEO_ADV_DEBUG
446 case VIDIOC_DBG_G_REGISTER
:
448 struct v4l2_dbg_register
*p
= arg
;
450 if (!capable(CAP_SYS_ADMIN
))
452 return v4l2_subdev_call(sd
, core
, g_register
, p
);
454 case VIDIOC_DBG_S_REGISTER
:
456 struct v4l2_dbg_register
*p
= arg
;
458 if (!capable(CAP_SYS_ADMIN
))
460 return v4l2_subdev_call(sd
, core
, s_register
, p
);
462 case VIDIOC_DBG_G_CHIP_INFO
:
464 struct v4l2_dbg_chip_info
*p
= arg
;
466 if (p
->match
.type
!= V4L2_CHIP_MATCH_SUBDEV
|| p
->match
.addr
)
468 if (sd
->ops
->core
&& sd
->ops
->core
->s_register
)
469 p
->flags
|= V4L2_CHIP_FL_WRITABLE
;
470 if (sd
->ops
->core
&& sd
->ops
->core
->g_register
)
471 p
->flags
|= V4L2_CHIP_FL_READABLE
;
472 strscpy(p
->name
, sd
->name
, sizeof(p
->name
));
477 case VIDIOC_LOG_STATUS
: {
480 pr_info("%s: ================= START STATUS =================\n",
482 ret
= v4l2_subdev_call(sd
, core
, log_status
);
483 pr_info("%s: ================== END STATUS ==================\n",
488 case VIDIOC_SUBDEV_G_FMT
: {
489 struct v4l2_subdev_format
*format
= arg
;
491 memset(format
->reserved
, 0, sizeof(format
->reserved
));
492 memset(format
->format
.reserved
, 0, sizeof(format
->format
.reserved
));
493 return v4l2_subdev_call(sd
, pad
, get_fmt
, subdev_fh
->pad
, format
);
496 case VIDIOC_SUBDEV_S_FMT
: {
497 struct v4l2_subdev_format
*format
= arg
;
499 if (format
->which
!= V4L2_SUBDEV_FORMAT_TRY
&& ro_subdev
)
502 memset(format
->reserved
, 0, sizeof(format
->reserved
));
503 memset(format
->format
.reserved
, 0, sizeof(format
->format
.reserved
));
504 return v4l2_subdev_call(sd
, pad
, set_fmt
, subdev_fh
->pad
, format
);
507 case VIDIOC_SUBDEV_G_CROP
: {
508 struct v4l2_subdev_crop
*crop
= arg
;
509 struct v4l2_subdev_selection sel
;
511 memset(crop
->reserved
, 0, sizeof(crop
->reserved
));
512 memset(&sel
, 0, sizeof(sel
));
513 sel
.which
= crop
->which
;
515 sel
.target
= V4L2_SEL_TGT_CROP
;
517 rval
= v4l2_subdev_call(
518 sd
, pad
, get_selection
, subdev_fh
->pad
, &sel
);
525 case VIDIOC_SUBDEV_S_CROP
: {
526 struct v4l2_subdev_crop
*crop
= arg
;
527 struct v4l2_subdev_selection sel
;
529 if (crop
->which
!= V4L2_SUBDEV_FORMAT_TRY
&& ro_subdev
)
532 memset(crop
->reserved
, 0, sizeof(crop
->reserved
));
533 memset(&sel
, 0, sizeof(sel
));
534 sel
.which
= crop
->which
;
536 sel
.target
= V4L2_SEL_TGT_CROP
;
539 rval
= v4l2_subdev_call(
540 sd
, pad
, set_selection
, subdev_fh
->pad
, &sel
);
547 case VIDIOC_SUBDEV_ENUM_MBUS_CODE
: {
548 struct v4l2_subdev_mbus_code_enum
*code
= arg
;
550 memset(code
->reserved
, 0, sizeof(code
->reserved
));
551 return v4l2_subdev_call(sd
, pad
, enum_mbus_code
, subdev_fh
->pad
,
555 case VIDIOC_SUBDEV_ENUM_FRAME_SIZE
: {
556 struct v4l2_subdev_frame_size_enum
*fse
= arg
;
558 memset(fse
->reserved
, 0, sizeof(fse
->reserved
));
559 return v4l2_subdev_call(sd
, pad
, enum_frame_size
, subdev_fh
->pad
,
563 case VIDIOC_SUBDEV_G_FRAME_INTERVAL
: {
564 struct v4l2_subdev_frame_interval
*fi
= arg
;
566 memset(fi
->reserved
, 0, sizeof(fi
->reserved
));
567 return v4l2_subdev_call(sd
, video
, g_frame_interval
, arg
);
570 case VIDIOC_SUBDEV_S_FRAME_INTERVAL
: {
571 struct v4l2_subdev_frame_interval
*fi
= arg
;
576 memset(fi
->reserved
, 0, sizeof(fi
->reserved
));
577 return v4l2_subdev_call(sd
, video
, s_frame_interval
, arg
);
580 case VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL
: {
581 struct v4l2_subdev_frame_interval_enum
*fie
= arg
;
583 memset(fie
->reserved
, 0, sizeof(fie
->reserved
));
584 return v4l2_subdev_call(sd
, pad
, enum_frame_interval
, subdev_fh
->pad
,
588 case VIDIOC_SUBDEV_G_SELECTION
: {
589 struct v4l2_subdev_selection
*sel
= arg
;
591 memset(sel
->reserved
, 0, sizeof(sel
->reserved
));
592 return v4l2_subdev_call(
593 sd
, pad
, get_selection
, subdev_fh
->pad
, sel
);
596 case VIDIOC_SUBDEV_S_SELECTION
: {
597 struct v4l2_subdev_selection
*sel
= arg
;
599 if (sel
->which
!= V4L2_SUBDEV_FORMAT_TRY
&& ro_subdev
)
602 memset(sel
->reserved
, 0, sizeof(sel
->reserved
));
603 return v4l2_subdev_call(
604 sd
, pad
, set_selection
, subdev_fh
->pad
, sel
);
607 case VIDIOC_G_EDID
: {
608 struct v4l2_subdev_edid
*edid
= arg
;
610 return v4l2_subdev_call(sd
, pad
, get_edid
, edid
);
613 case VIDIOC_S_EDID
: {
614 struct v4l2_subdev_edid
*edid
= arg
;
616 return v4l2_subdev_call(sd
, pad
, set_edid
, edid
);
619 case VIDIOC_SUBDEV_DV_TIMINGS_CAP
: {
620 struct v4l2_dv_timings_cap
*cap
= arg
;
622 return v4l2_subdev_call(sd
, pad
, dv_timings_cap
, cap
);
625 case VIDIOC_SUBDEV_ENUM_DV_TIMINGS
: {
626 struct v4l2_enum_dv_timings
*dvt
= arg
;
628 return v4l2_subdev_call(sd
, pad
, enum_dv_timings
, dvt
);
631 case VIDIOC_SUBDEV_QUERY_DV_TIMINGS
:
632 return v4l2_subdev_call(sd
, video
, query_dv_timings
, arg
);
634 case VIDIOC_SUBDEV_G_DV_TIMINGS
:
635 return v4l2_subdev_call(sd
, video
, g_dv_timings
, arg
);
637 case VIDIOC_SUBDEV_S_DV_TIMINGS
:
641 return v4l2_subdev_call(sd
, video
, s_dv_timings
, arg
);
643 case VIDIOC_SUBDEV_G_STD
:
644 return v4l2_subdev_call(sd
, video
, g_std
, arg
);
646 case VIDIOC_SUBDEV_S_STD
: {
647 v4l2_std_id
*std
= arg
;
652 return v4l2_subdev_call(sd
, video
, s_std
, *std
);
655 case VIDIOC_SUBDEV_ENUMSTD
: {
656 struct v4l2_standard
*p
= arg
;
659 if (v4l2_subdev_call(sd
, video
, g_tvnorms
, &id
))
662 return v4l_video_std_enumstd(p
, id
);
665 case VIDIOC_SUBDEV_QUERYSTD
:
666 return v4l2_subdev_call(sd
, video
, querystd
, arg
);
669 return v4l2_subdev_call(sd
, core
, ioctl
, cmd
, arg
);
675 static long subdev_do_ioctl_lock(struct file
*file
, unsigned int cmd
, void *arg
)
677 struct video_device
*vdev
= video_devdata(file
);
678 struct mutex
*lock
= vdev
->lock
;
681 if (lock
&& mutex_lock_interruptible(lock
))
683 if (video_is_registered(vdev
))
684 ret
= subdev_do_ioctl(file
, cmd
, arg
);
690 static long subdev_ioctl(struct file
*file
, unsigned int cmd
,
693 return video_usercopy(file
, cmd
, arg
, subdev_do_ioctl_lock
);
697 static long subdev_compat_ioctl32(struct file
*file
, unsigned int cmd
,
700 struct video_device
*vdev
= video_devdata(file
);
701 struct v4l2_subdev
*sd
= vdev_to_v4l2_subdev(vdev
);
703 return v4l2_subdev_call(sd
, core
, compat_ioctl32
, cmd
, arg
);
707 #else /* CONFIG_VIDEO_V4L2_SUBDEV_API */
708 static long subdev_ioctl(struct file
*file
, unsigned int cmd
,
715 static long subdev_compat_ioctl32(struct file
*file
, unsigned int cmd
,
721 #endif /* CONFIG_VIDEO_V4L2_SUBDEV_API */
723 static __poll_t
subdev_poll(struct file
*file
, poll_table
*wait
)
725 struct video_device
*vdev
= video_devdata(file
);
726 struct v4l2_subdev
*sd
= vdev_to_v4l2_subdev(vdev
);
727 struct v4l2_fh
*fh
= file
->private_data
;
729 if (!(sd
->flags
& V4L2_SUBDEV_FL_HAS_EVENTS
))
732 poll_wait(file
, &fh
->wait
, wait
);
734 if (v4l2_event_pending(fh
))
740 const struct v4l2_file_operations v4l2_subdev_fops
= {
741 .owner
= THIS_MODULE
,
743 .unlocked_ioctl
= subdev_ioctl
,
745 .compat_ioctl32
= subdev_compat_ioctl32
,
747 .release
= subdev_close
,
751 #ifdef CONFIG_MEDIA_CONTROLLER
753 int v4l2_subdev_get_fwnode_pad_1_to_1(struct media_entity
*entity
,
754 struct fwnode_endpoint
*endpoint
)
756 struct fwnode_handle
*fwnode
;
757 struct v4l2_subdev
*sd
;
759 if (!is_media_entity_v4l2_subdev(entity
))
762 sd
= media_entity_to_v4l2_subdev(entity
);
764 fwnode
= fwnode_graph_get_port_parent(endpoint
->local_fwnode
);
765 fwnode_handle_put(fwnode
);
767 if (dev_fwnode(sd
->dev
) == fwnode
)
768 return endpoint
->port
;
772 EXPORT_SYMBOL_GPL(v4l2_subdev_get_fwnode_pad_1_to_1
);
774 int v4l2_subdev_link_validate_default(struct v4l2_subdev
*sd
,
775 struct media_link
*link
,
776 struct v4l2_subdev_format
*source_fmt
,
777 struct v4l2_subdev_format
*sink_fmt
)
779 /* The width, height and code must match. */
780 if (source_fmt
->format
.width
!= sink_fmt
->format
.width
781 || source_fmt
->format
.height
!= sink_fmt
->format
.height
782 || source_fmt
->format
.code
!= sink_fmt
->format
.code
)
785 /* The field order must match, or the sink field order must be NONE
786 * to support interlaced hardware connected to bridges that support
787 * progressive formats only.
789 if (source_fmt
->format
.field
!= sink_fmt
->format
.field
&&
790 sink_fmt
->format
.field
!= V4L2_FIELD_NONE
)
795 EXPORT_SYMBOL_GPL(v4l2_subdev_link_validate_default
);
798 v4l2_subdev_link_validate_get_format(struct media_pad
*pad
,
799 struct v4l2_subdev_format
*fmt
)
801 if (is_media_entity_v4l2_subdev(pad
->entity
)) {
802 struct v4l2_subdev
*sd
=
803 media_entity_to_v4l2_subdev(pad
->entity
);
805 fmt
->which
= V4L2_SUBDEV_FORMAT_ACTIVE
;
806 fmt
->pad
= pad
->index
;
807 return v4l2_subdev_call(sd
, pad
, get_fmt
, NULL
, fmt
);
810 WARN(pad
->entity
->function
!= MEDIA_ENT_F_IO_V4L
,
811 "Driver bug! Wrong media entity type 0x%08x, entity %s\n",
812 pad
->entity
->function
, pad
->entity
->name
);
817 int v4l2_subdev_link_validate(struct media_link
*link
)
819 struct v4l2_subdev
*sink
;
820 struct v4l2_subdev_format sink_fmt
, source_fmt
;
823 rval
= v4l2_subdev_link_validate_get_format(
824 link
->source
, &source_fmt
);
828 rval
= v4l2_subdev_link_validate_get_format(
829 link
->sink
, &sink_fmt
);
833 sink
= media_entity_to_v4l2_subdev(link
->sink
->entity
);
835 rval
= v4l2_subdev_call(sink
, pad
, link_validate
, link
,
836 &source_fmt
, &sink_fmt
);
837 if (rval
!= -ENOIOCTLCMD
)
840 return v4l2_subdev_link_validate_default(
841 sink
, link
, &source_fmt
, &sink_fmt
);
843 EXPORT_SYMBOL_GPL(v4l2_subdev_link_validate
);
845 struct v4l2_subdev_pad_config
*
846 v4l2_subdev_alloc_pad_config(struct v4l2_subdev
*sd
)
848 struct v4l2_subdev_pad_config
*cfg
;
851 if (!sd
->entity
.num_pads
)
854 cfg
= kvmalloc_array(sd
->entity
.num_pads
, sizeof(*cfg
),
855 GFP_KERNEL
| __GFP_ZERO
);
859 ret
= v4l2_subdev_call(sd
, pad
, init_cfg
, cfg
);
860 if (ret
< 0 && ret
!= -ENOIOCTLCMD
) {
867 EXPORT_SYMBOL_GPL(v4l2_subdev_alloc_pad_config
);
869 void v4l2_subdev_free_pad_config(struct v4l2_subdev_pad_config
*cfg
)
873 EXPORT_SYMBOL_GPL(v4l2_subdev_free_pad_config
);
874 #endif /* CONFIG_MEDIA_CONTROLLER */
876 void v4l2_subdev_init(struct v4l2_subdev
*sd
, const struct v4l2_subdev_ops
*ops
)
878 INIT_LIST_HEAD(&sd
->list
);
886 sd
->host_priv
= NULL
;
887 #if defined(CONFIG_MEDIA_CONTROLLER)
888 sd
->entity
.name
= sd
->name
;
889 sd
->entity
.obj_type
= MEDIA_ENTITY_TYPE_V4L2_SUBDEV
;
890 sd
->entity
.function
= MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN
;
893 EXPORT_SYMBOL(v4l2_subdev_init
);
895 void v4l2_subdev_notify_event(struct v4l2_subdev
*sd
,
896 const struct v4l2_event
*ev
)
898 v4l2_event_queue(sd
->devnode
, ev
);
899 v4l2_subdev_notify(sd
, V4L2_DEVICE_NOTIFY_EVENT
, (void *)ev
);
901 EXPORT_SYMBOL_GPL(v4l2_subdev_notify_event
);