diff options
Diffstat (limited to 'drivers/media/platform/vimc/vimc-capture.c')
| -rw-r--r-- | drivers/media/platform/vimc/vimc-capture.c | 78 |
1 files changed, 11 insertions, 67 deletions
diff --git a/drivers/media/platform/vimc/vimc-capture.c b/drivers/media/platform/vimc/vimc-capture.c index 93f6a0916329..5bdecd103d55 100644 --- a/drivers/media/platform/vimc/vimc-capture.c +++ b/drivers/media/platform/vimc/vimc-capture.c | |||
| @@ -64,6 +64,15 @@ static int vimc_cap_querycap(struct file *file, void *priv, | |||
| 64 | return 0; | 64 | return 0; |
| 65 | } | 65 | } |
| 66 | 66 | ||
| 67 | static void vimc_cap_get_format(struct vimc_ent_device *ved, | ||
| 68 | struct v4l2_pix_format *fmt) | ||
| 69 | { | ||
| 70 | struct vimc_cap_device *vcap = container_of(ved, struct vimc_cap_device, | ||
| 71 | ved); | ||
| 72 | |||
| 73 | *fmt = vcap->format; | ||
| 74 | } | ||
| 75 | |||
| 67 | static int vimc_cap_fmt_vid_cap(struct file *file, void *priv, | 76 | static int vimc_cap_fmt_vid_cap(struct file *file, void *priv, |
| 68 | struct v4l2_format *f) | 77 | struct v4l2_format *f) |
| 69 | { | 78 | { |
| @@ -231,74 +240,8 @@ static const struct vb2_ops vimc_cap_qops = { | |||
| 231 | .wait_finish = vb2_ops_wait_finish, | 240 | .wait_finish = vb2_ops_wait_finish, |
| 232 | }; | 241 | }; |
| 233 | 242 | ||
| 234 | /* | ||
| 235 | * NOTE: this function is a copy of v4l2_subdev_link_validate_get_format | ||
| 236 | * maybe the v4l2 function should be public | ||
| 237 | */ | ||
| 238 | static int vimc_cap_v4l2_subdev_link_validate_get_format(struct media_pad *pad, | ||
| 239 | struct v4l2_subdev_format *fmt) | ||
| 240 | { | ||
| 241 | struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(pad->entity); | ||
| 242 | |||
| 243 | fmt->which = V4L2_SUBDEV_FORMAT_ACTIVE; | ||
| 244 | fmt->pad = pad->index; | ||
| 245 | |||
| 246 | return v4l2_subdev_call(sd, pad, get_fmt, NULL, fmt); | ||
| 247 | } | ||
| 248 | |||
| 249 | static int vimc_cap_link_validate(struct media_link *link) | ||
| 250 | { | ||
| 251 | struct v4l2_subdev_format source_fmt; | ||
| 252 | const struct vimc_pix_map *vpix; | ||
| 253 | struct vimc_cap_device *vcap = container_of(link->sink->entity, | ||
| 254 | struct vimc_cap_device, | ||
| 255 | vdev.entity); | ||
| 256 | struct v4l2_pix_format *sink_fmt = &vcap->format; | ||
| 257 | int ret; | ||
| 258 | |||
| 259 | /* | ||
| 260 | * if it is a raw node from vimc-core, ignore the link for now | ||
| 261 | * TODO: remove this when there are no more raw nodes in the | ||
| 262 | * core and return error instead | ||
| 263 | */ | ||
| 264 | if (link->source->entity->obj_type == MEDIA_ENTITY_TYPE_BASE) | ||
| 265 | return 0; | ||
| 266 | |||
| 267 | /* Get the the format of the subdev */ | ||
| 268 | ret = vimc_cap_v4l2_subdev_link_validate_get_format(link->source, | ||
| 269 | &source_fmt); | ||
| 270 | if (ret) | ||
| 271 | return ret; | ||
| 272 | |||
| 273 | dev_dbg(vcap->vdev.v4l2_dev->dev, | ||
| 274 | "%s: link validate formats src:%dx%d %d sink:%dx%d %d\n", | ||
| 275 | vcap->vdev.name, | ||
| 276 | source_fmt.format.width, source_fmt.format.height, | ||
| 277 | source_fmt.format.code, | ||
| 278 | sink_fmt->width, sink_fmt->height, | ||
| 279 | sink_fmt->pixelformat); | ||
| 280 | |||
| 281 | /* The width, height and code must match. */ | ||
| 282 | vpix = vimc_pix_map_by_pixelformat(sink_fmt->pixelformat); | ||
| 283 | if (source_fmt.format.width != sink_fmt->width | ||
| 284 | || source_fmt.format.height != sink_fmt->height | ||
| 285 | || vpix->code != source_fmt.format.code) | ||
| 286 | return -EPIPE; | ||
| 287 | |||
| 288 | /* | ||
| 289 | * The field order must match, or the sink field order must be NONE | ||
| 290 | * to support interlaced hardware connected to bridges that support | ||
| 291 | * progressive formats only. | ||
| 292 | */ | ||
| 293 | if (source_fmt.format.field != sink_fmt->field && | ||
| 294 | sink_fmt->field != V4L2_FIELD_NONE) | ||
| 295 | return -EPIPE; | ||
| 296 | |||
| 297 | return 0; | ||
| 298 | } | ||
| 299 | |||
| 300 | static const struct media_entity_operations vimc_cap_mops = { | 243 | static const struct media_entity_operations vimc_cap_mops = { |
| 301 | .link_validate = vimc_cap_link_validate, | 244 | .link_validate = vimc_link_validate, |
| 302 | }; | 245 | }; |
| 303 | 246 | ||
| 304 | static void vimc_cap_destroy(struct vimc_ent_device *ved) | 247 | static void vimc_cap_destroy(struct vimc_ent_device *ved) |
| @@ -434,6 +377,7 @@ struct vimc_ent_device *vimc_cap_create(struct v4l2_device *v4l2_dev, | |||
| 434 | vcap->ved.destroy = vimc_cap_destroy; | 377 | vcap->ved.destroy = vimc_cap_destroy; |
| 435 | vcap->ved.ent = &vcap->vdev.entity; | 378 | vcap->ved.ent = &vcap->vdev.entity; |
| 436 | vcap->ved.process_frame = vimc_cap_process_frame; | 379 | vcap->ved.process_frame = vimc_cap_process_frame; |
| 380 | vcap->ved.vdev_get_format = vimc_cap_get_format; | ||
| 437 | 381 | ||
| 438 | /* Initialize the video_device struct */ | 382 | /* Initialize the video_device struct */ |
| 439 | vdev = &vcap->vdev; | 383 | vdev = &vcap->vdev; |
