diff options
Diffstat (limited to 'drivers/media/video/v4l2-subdev.c')
-rw-r--r-- | drivers/media/video/v4l2-subdev.c | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/drivers/media/video/v4l2-subdev.c b/drivers/media/video/v4l2-subdev.c index 268d80584101..db6e859b93d4 100644 --- a/drivers/media/video/v4l2-subdev.c +++ b/drivers/media/video/v4l2-subdev.c | |||
@@ -387,6 +387,70 @@ const struct v4l2_file_operations v4l2_subdev_fops = { | |||
387 | .poll = subdev_poll, | 387 | .poll = subdev_poll, |
388 | }; | 388 | }; |
389 | 389 | ||
390 | #ifdef CONFIG_MEDIA_CONTROLLER | ||
391 | int v4l2_subdev_link_validate_default(struct v4l2_subdev *sd, | ||
392 | struct media_link *link, | ||
393 | struct v4l2_subdev_format *source_fmt, | ||
394 | struct v4l2_subdev_format *sink_fmt) | ||
395 | { | ||
396 | if (source_fmt->format.width != sink_fmt->format.width | ||
397 | || source_fmt->format.height != sink_fmt->format.height | ||
398 | || source_fmt->format.code != sink_fmt->format.code) | ||
399 | return -EINVAL; | ||
400 | |||
401 | return 0; | ||
402 | } | ||
403 | EXPORT_SYMBOL_GPL(v4l2_subdev_link_validate_default); | ||
404 | |||
405 | static int | ||
406 | v4l2_subdev_link_validate_get_format(struct media_pad *pad, | ||
407 | struct v4l2_subdev_format *fmt) | ||
408 | { | ||
409 | switch (media_entity_type(pad->entity)) { | ||
410 | case MEDIA_ENT_T_V4L2_SUBDEV: | ||
411 | fmt->which = V4L2_SUBDEV_FORMAT_ACTIVE; | ||
412 | fmt->pad = pad->index; | ||
413 | return v4l2_subdev_call(media_entity_to_v4l2_subdev( | ||
414 | pad->entity), | ||
415 | pad, get_fmt, NULL, fmt); | ||
416 | default: | ||
417 | WARN(1, "Driver bug! Wrong media entity type %d, entity %s\n", | ||
418 | media_entity_type(pad->entity), pad->entity->name); | ||
419 | /* Fall through */ | ||
420 | case MEDIA_ENT_T_DEVNODE_V4L: | ||
421 | return -EINVAL; | ||
422 | } | ||
423 | } | ||
424 | |||
425 | int v4l2_subdev_link_validate(struct media_link *link) | ||
426 | { | ||
427 | struct v4l2_subdev *sink; | ||
428 | struct v4l2_subdev_format sink_fmt, source_fmt; | ||
429 | int rval; | ||
430 | |||
431 | rval = v4l2_subdev_link_validate_get_format( | ||
432 | link->source, &source_fmt); | ||
433 | if (rval < 0) | ||
434 | return 0; | ||
435 | |||
436 | rval = v4l2_subdev_link_validate_get_format( | ||
437 | link->sink, &sink_fmt); | ||
438 | if (rval < 0) | ||
439 | return 0; | ||
440 | |||
441 | sink = media_entity_to_v4l2_subdev(link->sink->entity); | ||
442 | |||
443 | rval = v4l2_subdev_call(sink, pad, link_validate, link, | ||
444 | &source_fmt, &sink_fmt); | ||
445 | if (rval != -ENOIOCTLCMD) | ||
446 | return rval; | ||
447 | |||
448 | return v4l2_subdev_link_validate_default( | ||
449 | sink, link, &source_fmt, &sink_fmt); | ||
450 | } | ||
451 | EXPORT_SYMBOL_GPL(v4l2_subdev_link_validate); | ||
452 | #endif /* CONFIG_MEDIA_CONTROLLER */ | ||
453 | |||
390 | void v4l2_subdev_init(struct v4l2_subdev *sd, const struct v4l2_subdev_ops *ops) | 454 | void v4l2_subdev_init(struct v4l2_subdev *sd, const struct v4l2_subdev_ops *ops) |
391 | { | 455 | { |
392 | INIT_LIST_HEAD(&sd->list); | 456 | INIT_LIST_HEAD(&sd->list); |