4 * Copyright (C) 2010 Nokia Corporation
6 * Contact: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
7 * Sakari Ailus <sakari.ailus@iki.fi>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
19 #include <linux/ioctl.h>
21 #include <linux/slab.h>
22 #include <linux/types.h>
23 #include <linux/videodev2.h>
24 #include <linux/export.h>
26 #include <media/v4l2-ctrls.h>
27 #include <media/v4l2-device.h>
28 #include <media/v4l2-ioctl.h>
29 #include <media/v4l2-fh.h>
30 #include <media/v4l2-event.h>
32 static int subdev_fh_init(struct v4l2_subdev_fh
*fh
, struct v4l2_subdev
*sd
)
34 #if defined(CONFIG_VIDEO_V4L2_SUBDEV_API)
35 if (sd
->entity
.num_pads
) {
36 fh
->pad
= v4l2_subdev_alloc_pad_config(sd
);
44 static void subdev_fh_free(struct v4l2_subdev_fh
*fh
)
46 #if defined(CONFIG_VIDEO_V4L2_SUBDEV_API)
47 v4l2_subdev_free_pad_config(fh
->pad
);
52 static int subdev_open(struct file
*file
)
54 struct video_device
*vdev
= video_devdata(file
);
55 struct v4l2_subdev
*sd
= vdev_to_v4l2_subdev(vdev
);
56 struct v4l2_subdev_fh
*subdev_fh
;
57 #if defined(CONFIG_MEDIA_CONTROLLER)
58 struct media_entity
*entity
= NULL
;
62 subdev_fh
= kzalloc(sizeof(*subdev_fh
), GFP_KERNEL
);
63 if (subdev_fh
== NULL
)
66 ret
= subdev_fh_init(subdev_fh
, sd
);
72 v4l2_fh_init(&subdev_fh
->vfh
, vdev
);
73 v4l2_fh_add(&subdev_fh
->vfh
);
74 file
->private_data
= &subdev_fh
->vfh
;
75 #if defined(CONFIG_MEDIA_CONTROLLER)
76 if (sd
->v4l2_dev
->mdev
) {
77 entity
= media_entity_get(&sd
->entity
);
85 if (sd
->internal_ops
&& sd
->internal_ops
->open
) {
86 ret
= sd
->internal_ops
->open(sd
, subdev_fh
);
94 #if defined(CONFIG_MEDIA_CONTROLLER)
95 media_entity_put(entity
);
97 v4l2_fh_del(&subdev_fh
->vfh
);
98 v4l2_fh_exit(&subdev_fh
->vfh
);
99 subdev_fh_free(subdev_fh
);
105 static int subdev_close(struct file
*file
)
107 struct video_device
*vdev
= video_devdata(file
);
108 struct v4l2_subdev
*sd
= vdev_to_v4l2_subdev(vdev
);
109 struct v4l2_fh
*vfh
= file
->private_data
;
110 struct v4l2_subdev_fh
*subdev_fh
= to_v4l2_subdev_fh(vfh
);
112 if (sd
->internal_ops
&& sd
->internal_ops
->close
)
113 sd
->internal_ops
->close(sd
, subdev_fh
);
114 #if defined(CONFIG_MEDIA_CONTROLLER)
115 if (sd
->v4l2_dev
->mdev
)
116 media_entity_put(&sd
->entity
);
120 subdev_fh_free(subdev_fh
);
122 file
->private_data
= NULL
;
127 #if defined(CONFIG_VIDEO_V4L2_SUBDEV_API)
128 static int check_format(struct v4l2_subdev
*sd
,
129 struct v4l2_subdev_format
*format
)
131 if (format
->which
!= V4L2_SUBDEV_FORMAT_TRY
&&
132 format
->which
!= V4L2_SUBDEV_FORMAT_ACTIVE
)
135 if (format
->pad
>= sd
->entity
.num_pads
)
141 static int check_crop(struct v4l2_subdev
*sd
, struct v4l2_subdev_crop
*crop
)
143 if (crop
->which
!= V4L2_SUBDEV_FORMAT_TRY
&&
144 crop
->which
!= V4L2_SUBDEV_FORMAT_ACTIVE
)
147 if (crop
->pad
>= sd
->entity
.num_pads
)
153 static int check_selection(struct v4l2_subdev
*sd
,
154 struct v4l2_subdev_selection
*sel
)
156 if (sel
->which
!= V4L2_SUBDEV_FORMAT_TRY
&&
157 sel
->which
!= V4L2_SUBDEV_FORMAT_ACTIVE
)
160 if (sel
->pad
>= sd
->entity
.num_pads
)
166 static int check_edid(struct v4l2_subdev
*sd
, struct v4l2_subdev_edid
*edid
)
168 if (edid
->pad
>= sd
->entity
.num_pads
)
171 if (edid
->blocks
&& edid
->edid
== NULL
)
178 static long subdev_do_ioctl(struct file
*file
, unsigned int cmd
, void *arg
)
180 struct video_device
*vdev
= video_devdata(file
);
181 struct v4l2_subdev
*sd
= vdev_to_v4l2_subdev(vdev
);
182 struct v4l2_fh
*vfh
= file
->private_data
;
183 #if defined(CONFIG_VIDEO_V4L2_SUBDEV_API)
184 struct v4l2_subdev_fh
*subdev_fh
= to_v4l2_subdev_fh(vfh
);
189 case VIDIOC_QUERYCTRL
:
191 * TODO: this really should be folded into v4l2_queryctrl (this
192 * currently returns -EINVAL for NULL control handlers).
193 * However, v4l2_queryctrl() is still called directly by
194 * drivers as well and until that has been addressed I believe
195 * it is safer to do the check here. The same is true for the
196 * other control ioctls below.
198 if (!vfh
->ctrl_handler
)
200 return v4l2_queryctrl(vfh
->ctrl_handler
, arg
);
202 case VIDIOC_QUERY_EXT_CTRL
:
203 if (!vfh
->ctrl_handler
)
205 return v4l2_query_ext_ctrl(vfh
->ctrl_handler
, arg
);
207 case VIDIOC_QUERYMENU
:
208 if (!vfh
->ctrl_handler
)
210 return v4l2_querymenu(vfh
->ctrl_handler
, arg
);
213 if (!vfh
->ctrl_handler
)
215 return v4l2_g_ctrl(vfh
->ctrl_handler
, arg
);
218 if (!vfh
->ctrl_handler
)
220 return v4l2_s_ctrl(vfh
, vfh
->ctrl_handler
, arg
);
222 case VIDIOC_G_EXT_CTRLS
:
223 if (!vfh
->ctrl_handler
)
225 return v4l2_g_ext_ctrls(vfh
->ctrl_handler
, arg
);
227 case VIDIOC_S_EXT_CTRLS
:
228 if (!vfh
->ctrl_handler
)
230 return v4l2_s_ext_ctrls(vfh
, vfh
->ctrl_handler
, arg
);
232 case VIDIOC_TRY_EXT_CTRLS
:
233 if (!vfh
->ctrl_handler
)
235 return v4l2_try_ext_ctrls(vfh
->ctrl_handler
, arg
);
238 if (!(sd
->flags
& V4L2_SUBDEV_FL_HAS_EVENTS
))
241 return v4l2_event_dequeue(vfh
, arg
, file
->f_flags
& O_NONBLOCK
);
243 case VIDIOC_SUBSCRIBE_EVENT
:
244 return v4l2_subdev_call(sd
, core
, subscribe_event
, vfh
, arg
);
246 case VIDIOC_UNSUBSCRIBE_EVENT
:
247 return v4l2_subdev_call(sd
, core
, unsubscribe_event
, vfh
, arg
);
249 #ifdef CONFIG_VIDEO_ADV_DEBUG
250 case VIDIOC_DBG_G_REGISTER
:
252 struct v4l2_dbg_register
*p
= arg
;
254 if (!capable(CAP_SYS_ADMIN
))
256 return v4l2_subdev_call(sd
, core
, g_register
, p
);
258 case VIDIOC_DBG_S_REGISTER
:
260 struct v4l2_dbg_register
*p
= arg
;
262 if (!capable(CAP_SYS_ADMIN
))
264 return v4l2_subdev_call(sd
, core
, s_register
, p
);
266 case VIDIOC_DBG_G_CHIP_INFO
:
268 struct v4l2_dbg_chip_info
*p
= arg
;
270 if (p
->match
.type
!= V4L2_CHIP_MATCH_SUBDEV
|| p
->match
.addr
)
272 if (sd
->ops
->core
&& sd
->ops
->core
->s_register
)
273 p
->flags
|= V4L2_CHIP_FL_WRITABLE
;
274 if (sd
->ops
->core
&& sd
->ops
->core
->g_register
)
275 p
->flags
|= V4L2_CHIP_FL_READABLE
;
276 strlcpy(p
->name
, sd
->name
, sizeof(p
->name
));
281 case VIDIOC_LOG_STATUS
: {
284 pr_info("%s: ================= START STATUS =================\n",
286 ret
= v4l2_subdev_call(sd
, core
, log_status
);
287 pr_info("%s: ================== END STATUS ==================\n",
292 #if defined(CONFIG_VIDEO_V4L2_SUBDEV_API)
293 case VIDIOC_SUBDEV_G_FMT
: {
294 struct v4l2_subdev_format
*format
= arg
;
296 rval
= check_format(sd
, format
);
300 memset(format
->reserved
, 0, sizeof(format
->reserved
));
301 memset(format
->format
.reserved
, 0, sizeof(format
->format
.reserved
));
302 return v4l2_subdev_call(sd
, pad
, get_fmt
, subdev_fh
->pad
, format
);
305 case VIDIOC_SUBDEV_S_FMT
: {
306 struct v4l2_subdev_format
*format
= arg
;
308 rval
= check_format(sd
, format
);
312 memset(format
->reserved
, 0, sizeof(format
->reserved
));
313 memset(format
->format
.reserved
, 0, sizeof(format
->format
.reserved
));
314 return v4l2_subdev_call(sd
, pad
, set_fmt
, subdev_fh
->pad
, format
);
317 case VIDIOC_SUBDEV_G_CROP
: {
318 struct v4l2_subdev_crop
*crop
= arg
;
319 struct v4l2_subdev_selection sel
;
321 rval
= check_crop(sd
, crop
);
325 memset(crop
->reserved
, 0, sizeof(crop
->reserved
));
326 memset(&sel
, 0, sizeof(sel
));
327 sel
.which
= crop
->which
;
329 sel
.target
= V4L2_SEL_TGT_CROP
;
331 rval
= v4l2_subdev_call(
332 sd
, pad
, get_selection
, subdev_fh
->pad
, &sel
);
339 case VIDIOC_SUBDEV_S_CROP
: {
340 struct v4l2_subdev_crop
*crop
= arg
;
341 struct v4l2_subdev_selection sel
;
343 memset(crop
->reserved
, 0, sizeof(crop
->reserved
));
344 rval
= check_crop(sd
, crop
);
348 memset(&sel
, 0, sizeof(sel
));
349 sel
.which
= crop
->which
;
351 sel
.target
= V4L2_SEL_TGT_CROP
;
354 rval
= v4l2_subdev_call(
355 sd
, pad
, set_selection
, subdev_fh
->pad
, &sel
);
362 case VIDIOC_SUBDEV_ENUM_MBUS_CODE
: {
363 struct v4l2_subdev_mbus_code_enum
*code
= arg
;
365 if (code
->which
!= V4L2_SUBDEV_FORMAT_TRY
&&
366 code
->which
!= V4L2_SUBDEV_FORMAT_ACTIVE
)
369 if (code
->pad
>= sd
->entity
.num_pads
)
372 memset(code
->reserved
, 0, sizeof(code
->reserved
));
373 return v4l2_subdev_call(sd
, pad
, enum_mbus_code
, subdev_fh
->pad
,
377 case VIDIOC_SUBDEV_ENUM_FRAME_SIZE
: {
378 struct v4l2_subdev_frame_size_enum
*fse
= arg
;
380 if (fse
->which
!= V4L2_SUBDEV_FORMAT_TRY
&&
381 fse
->which
!= V4L2_SUBDEV_FORMAT_ACTIVE
)
384 if (fse
->pad
>= sd
->entity
.num_pads
)
387 memset(fse
->reserved
, 0, sizeof(fse
->reserved
));
388 return v4l2_subdev_call(sd
, pad
, enum_frame_size
, subdev_fh
->pad
,
392 case VIDIOC_SUBDEV_G_FRAME_INTERVAL
: {
393 struct v4l2_subdev_frame_interval
*fi
= arg
;
395 if (fi
->pad
>= sd
->entity
.num_pads
)
398 memset(fi
->reserved
, 0, sizeof(fi
->reserved
));
399 return v4l2_subdev_call(sd
, video
, g_frame_interval
, arg
);
402 case VIDIOC_SUBDEV_S_FRAME_INTERVAL
: {
403 struct v4l2_subdev_frame_interval
*fi
= arg
;
405 if (fi
->pad
>= sd
->entity
.num_pads
)
408 memset(fi
->reserved
, 0, sizeof(fi
->reserved
));
409 return v4l2_subdev_call(sd
, video
, s_frame_interval
, arg
);
412 case VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL
: {
413 struct v4l2_subdev_frame_interval_enum
*fie
= arg
;
415 if (fie
->which
!= V4L2_SUBDEV_FORMAT_TRY
&&
416 fie
->which
!= V4L2_SUBDEV_FORMAT_ACTIVE
)
419 if (fie
->pad
>= sd
->entity
.num_pads
)
422 memset(fie
->reserved
, 0, sizeof(fie
->reserved
));
423 return v4l2_subdev_call(sd
, pad
, enum_frame_interval
, subdev_fh
->pad
,
427 case VIDIOC_SUBDEV_G_SELECTION
: {
428 struct v4l2_subdev_selection
*sel
= arg
;
430 rval
= check_selection(sd
, sel
);
434 memset(sel
->reserved
, 0, sizeof(sel
->reserved
));
435 return v4l2_subdev_call(
436 sd
, pad
, get_selection
, subdev_fh
->pad
, sel
);
439 case VIDIOC_SUBDEV_S_SELECTION
: {
440 struct v4l2_subdev_selection
*sel
= arg
;
442 rval
= check_selection(sd
, sel
);
446 memset(sel
->reserved
, 0, sizeof(sel
->reserved
));
447 return v4l2_subdev_call(
448 sd
, pad
, set_selection
, subdev_fh
->pad
, sel
);
451 case VIDIOC_G_EDID
: {
452 struct v4l2_subdev_edid
*edid
= arg
;
454 rval
= check_edid(sd
, edid
);
458 return v4l2_subdev_call(sd
, pad
, get_edid
, edid
);
461 case VIDIOC_S_EDID
: {
462 struct v4l2_subdev_edid
*edid
= arg
;
464 rval
= check_edid(sd
, edid
);
468 return v4l2_subdev_call(sd
, pad
, set_edid
, edid
);
471 case VIDIOC_SUBDEV_DV_TIMINGS_CAP
: {
472 struct v4l2_dv_timings_cap
*cap
= arg
;
474 if (cap
->pad
>= sd
->entity
.num_pads
)
477 return v4l2_subdev_call(sd
, pad
, dv_timings_cap
, cap
);
480 case VIDIOC_SUBDEV_ENUM_DV_TIMINGS
: {
481 struct v4l2_enum_dv_timings
*dvt
= arg
;
483 if (dvt
->pad
>= sd
->entity
.num_pads
)
486 return v4l2_subdev_call(sd
, pad
, enum_dv_timings
, dvt
);
489 case VIDIOC_SUBDEV_QUERY_DV_TIMINGS
:
490 return v4l2_subdev_call(sd
, video
, query_dv_timings
, arg
);
492 case VIDIOC_SUBDEV_G_DV_TIMINGS
:
493 return v4l2_subdev_call(sd
, video
, g_dv_timings
, arg
);
495 case VIDIOC_SUBDEV_S_DV_TIMINGS
:
496 return v4l2_subdev_call(sd
, video
, s_dv_timings
, arg
);
498 case VIDIOC_SUBDEV_G_STD
:
499 return v4l2_subdev_call(sd
, video
, g_std
, arg
);
501 case VIDIOC_SUBDEV_S_STD
: {
502 v4l2_std_id
*std
= arg
;
504 return v4l2_subdev_call(sd
, video
, s_std
, *std
);
507 case VIDIOC_SUBDEV_ENUMSTD
: {
508 struct v4l2_standard
*p
= arg
;
511 if (v4l2_subdev_call(sd
, video
, g_tvnorms
, &id
))
514 return v4l_video_std_enumstd(p
, id
);
517 case VIDIOC_SUBDEV_QUERYSTD
:
518 return v4l2_subdev_call(sd
, video
, querystd
, arg
);
521 return v4l2_subdev_call(sd
, core
, ioctl
, cmd
, arg
);
527 static long subdev_do_ioctl_lock(struct file
*file
, unsigned int cmd
, void *arg
)
529 struct video_device
*vdev
= video_devdata(file
);
530 struct mutex
*lock
= vdev
->lock
;
533 if (lock
&& mutex_lock_interruptible(lock
))
535 if (video_is_registered(vdev
))
536 ret
= subdev_do_ioctl(file
, cmd
, arg
);
542 static long subdev_ioctl(struct file
*file
, unsigned int cmd
,
545 return video_usercopy(file
, cmd
, arg
, subdev_do_ioctl_lock
);
549 static long subdev_compat_ioctl32(struct file
*file
, unsigned int cmd
,
552 struct video_device
*vdev
= video_devdata(file
);
553 struct v4l2_subdev
*sd
= vdev_to_v4l2_subdev(vdev
);
555 return v4l2_subdev_call(sd
, core
, compat_ioctl32
, cmd
, arg
);
559 static __poll_t
subdev_poll(struct file
*file
, poll_table
*wait
)
561 struct video_device
*vdev
= video_devdata(file
);
562 struct v4l2_subdev
*sd
= vdev_to_v4l2_subdev(vdev
);
563 struct v4l2_fh
*fh
= file
->private_data
;
565 if (!(sd
->flags
& V4L2_SUBDEV_FL_HAS_EVENTS
))
568 poll_wait(file
, &fh
->wait
, wait
);
570 if (v4l2_event_pending(fh
))
576 const struct v4l2_file_operations v4l2_subdev_fops
= {
577 .owner
= THIS_MODULE
,
579 .unlocked_ioctl
= subdev_ioctl
,
581 .compat_ioctl32
= subdev_compat_ioctl32
,
583 .release
= subdev_close
,
587 #ifdef CONFIG_MEDIA_CONTROLLER
588 int v4l2_subdev_link_validate_default(struct v4l2_subdev
*sd
,
589 struct media_link
*link
,
590 struct v4l2_subdev_format
*source_fmt
,
591 struct v4l2_subdev_format
*sink_fmt
)
593 /* The width, height and code must match. */
594 if (source_fmt
->format
.width
!= sink_fmt
->format
.width
595 || source_fmt
->format
.height
!= sink_fmt
->format
.height
596 || source_fmt
->format
.code
!= sink_fmt
->format
.code
)
599 /* The field order must match, or the sink field order must be NONE
600 * to support interlaced hardware connected to bridges that support
601 * progressive formats only.
603 if (source_fmt
->format
.field
!= sink_fmt
->format
.field
&&
604 sink_fmt
->format
.field
!= V4L2_FIELD_NONE
)
609 EXPORT_SYMBOL_GPL(v4l2_subdev_link_validate_default
);
612 v4l2_subdev_link_validate_get_format(struct media_pad
*pad
,
613 struct v4l2_subdev_format
*fmt
)
615 if (is_media_entity_v4l2_subdev(pad
->entity
)) {
616 struct v4l2_subdev
*sd
=
617 media_entity_to_v4l2_subdev(pad
->entity
);
619 fmt
->which
= V4L2_SUBDEV_FORMAT_ACTIVE
;
620 fmt
->pad
= pad
->index
;
621 return v4l2_subdev_call(sd
, pad
, get_fmt
, NULL
, fmt
);
624 WARN(pad
->entity
->function
!= MEDIA_ENT_F_IO_V4L
,
625 "Driver bug! Wrong media entity type 0x%08x, entity %s\n",
626 pad
->entity
->function
, pad
->entity
->name
);
631 int v4l2_subdev_link_validate(struct media_link
*link
)
633 struct v4l2_subdev
*sink
;
634 struct v4l2_subdev_format sink_fmt
, source_fmt
;
637 rval
= v4l2_subdev_link_validate_get_format(
638 link
->source
, &source_fmt
);
642 rval
= v4l2_subdev_link_validate_get_format(
643 link
->sink
, &sink_fmt
);
647 sink
= media_entity_to_v4l2_subdev(link
->sink
->entity
);
649 rval
= v4l2_subdev_call(sink
, pad
, link_validate
, link
,
650 &source_fmt
, &sink_fmt
);
651 if (rval
!= -ENOIOCTLCMD
)
654 return v4l2_subdev_link_validate_default(
655 sink
, link
, &source_fmt
, &sink_fmt
);
657 EXPORT_SYMBOL_GPL(v4l2_subdev_link_validate
);
659 struct v4l2_subdev_pad_config
*
660 v4l2_subdev_alloc_pad_config(struct v4l2_subdev
*sd
)
662 struct v4l2_subdev_pad_config
*cfg
;
665 if (!sd
->entity
.num_pads
)
668 cfg
= kvmalloc_array(sd
->entity
.num_pads
, sizeof(*cfg
),
669 GFP_KERNEL
| __GFP_ZERO
);
673 ret
= v4l2_subdev_call(sd
, pad
, init_cfg
, cfg
);
674 if (ret
< 0 && ret
!= -ENOIOCTLCMD
) {
681 EXPORT_SYMBOL_GPL(v4l2_subdev_alloc_pad_config
);
683 void v4l2_subdev_free_pad_config(struct v4l2_subdev_pad_config
*cfg
)
687 EXPORT_SYMBOL_GPL(v4l2_subdev_free_pad_config
);
688 #endif /* CONFIG_MEDIA_CONTROLLER */
690 void v4l2_subdev_init(struct v4l2_subdev
*sd
, const struct v4l2_subdev_ops
*ops
)
692 INIT_LIST_HEAD(&sd
->list
);
700 sd
->host_priv
= NULL
;
701 #if defined(CONFIG_MEDIA_CONTROLLER)
702 sd
->entity
.name
= sd
->name
;
703 sd
->entity
.obj_type
= MEDIA_ENTITY_TYPE_V4L2_SUBDEV
;
704 sd
->entity
.function
= MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN
;
707 EXPORT_SYMBOL(v4l2_subdev_init
);
709 void v4l2_subdev_notify_event(struct v4l2_subdev
*sd
,
710 const struct v4l2_event
*ev
)
712 v4l2_event_queue(sd
->devnode
, ev
);
713 v4l2_subdev_notify(sd
, V4L2_DEVICE_NOTIFY_EVENT
, (void *)ev
);
715 EXPORT_SYMBOL_GPL(v4l2_subdev_notify_event
);