| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Samsung S5P/EXYNOS4 SoC series camera interface (camera capture) driver |
|---|
| 3 | 4 | * |
|---|
| 4 | 5 | * Copyright (C) 2010 - 2012 Samsung Electronics Co., Ltd. |
|---|
| 5 | 6 | * Sylwester Nawrocki <s.nawrocki@samsung.com> |
|---|
| 6 | | - * |
|---|
| 7 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 8 | | - * it under the terms of the GNU General Public License version 2 as |
|---|
| 9 | | - * published by the Free Software Foundation. |
|---|
| 10 | 7 | */ |
|---|
| 11 | 8 | |
|---|
| 12 | 9 | #include <linux/module.h> |
|---|
| .. | .. |
|---|
| 24 | 21 | #include <media/v4l2-device.h> |
|---|
| 25 | 22 | #include <media/v4l2-ioctl.h> |
|---|
| 26 | 23 | #include <media/v4l2-mem2mem.h> |
|---|
| 24 | +#include <media/v4l2-rect.h> |
|---|
| 27 | 25 | #include <media/videobuf2-v4l2.h> |
|---|
| 28 | 26 | #include <media/videobuf2-dma-contig.h> |
|---|
| 29 | 27 | |
|---|
| .. | .. |
|---|
| 480 | 478 | goto unlock; |
|---|
| 481 | 479 | |
|---|
| 482 | 480 | set_bit(ST_CAPT_BUSY, &fimc->state); |
|---|
| 483 | | - ret = pm_runtime_get_sync(&fimc->pdev->dev); |
|---|
| 481 | + ret = pm_runtime_resume_and_get(&fimc->pdev->dev); |
|---|
| 484 | 482 | if (ret < 0) |
|---|
| 485 | 483 | goto unlock; |
|---|
| 486 | 484 | |
|---|
| .. | .. |
|---|
| 495 | 493 | |
|---|
| 496 | 494 | ret = fimc_pipeline_call(ve, open, &ve->vdev.entity, true); |
|---|
| 497 | 495 | |
|---|
| 498 | | - if (ret == 0 && vc->user_subdev_api && vc->inh_sensor_ctrls) { |
|---|
| 499 | | - /* |
|---|
| 500 | | - * Recreate controls of the the video node to drop |
|---|
| 501 | | - * any controls inherited from the sensor subdev. |
|---|
| 502 | | - */ |
|---|
| 503 | | - fimc_ctrls_delete(vc->ctx); |
|---|
| 504 | | - |
|---|
| 505 | | - ret = fimc_ctrls_create(vc->ctx); |
|---|
| 506 | | - if (ret == 0) |
|---|
| 507 | | - vc->inh_sensor_ctrls = false; |
|---|
| 508 | | - } |
|---|
| 509 | 496 | if (ret == 0) |
|---|
| 510 | 497 | ve->vdev.entity.use_count++; |
|---|
| 511 | 498 | |
|---|
| .. | .. |
|---|
| 728 | 715 | { |
|---|
| 729 | 716 | struct fimc_dev *fimc = video_drvdata(file); |
|---|
| 730 | 717 | |
|---|
| 731 | | - __fimc_vidioc_querycap(&fimc->pdev->dev, cap, V4L2_CAP_STREAMING | |
|---|
| 732 | | - V4L2_CAP_VIDEO_CAPTURE_MPLANE); |
|---|
| 718 | + __fimc_vidioc_querycap(&fimc->pdev->dev, cap); |
|---|
| 733 | 719 | return 0; |
|---|
| 734 | 720 | } |
|---|
| 735 | 721 | |
|---|
| 736 | | -static int fimc_cap_enum_fmt_mplane(struct file *file, void *priv, |
|---|
| 737 | | - struct v4l2_fmtdesc *f) |
|---|
| 722 | +static int fimc_cap_enum_fmt(struct file *file, void *priv, |
|---|
| 723 | + struct v4l2_fmtdesc *f) |
|---|
| 738 | 724 | { |
|---|
| 739 | 725 | struct fimc_fmt *fmt; |
|---|
| 740 | 726 | |
|---|
| .. | .. |
|---|
| 742 | 728 | f->index); |
|---|
| 743 | 729 | if (!fmt) |
|---|
| 744 | 730 | return -EINVAL; |
|---|
| 745 | | - strncpy(f->description, fmt->name, sizeof(f->description) - 1); |
|---|
| 746 | 731 | f->pixelformat = fmt->fourcc; |
|---|
| 747 | | - if (fmt->fourcc == MEDIA_BUS_FMT_JPEG_1X8) |
|---|
| 748 | | - f->flags |= V4L2_FMT_FLAG_COMPRESSED; |
|---|
| 749 | 732 | return 0; |
|---|
| 750 | 733 | } |
|---|
| 751 | 734 | |
|---|
| .. | .. |
|---|
| 1087 | 1070 | fimc_md_graph_unlock(ve); |
|---|
| 1088 | 1071 | |
|---|
| 1089 | 1072 | if (sd) |
|---|
| 1090 | | - strlcpy(i->name, sd->name, sizeof(i->name)); |
|---|
| 1073 | + strscpy(i->name, sd->name, sizeof(i->name)); |
|---|
| 1091 | 1074 | |
|---|
| 1092 | 1075 | return 0; |
|---|
| 1093 | 1076 | } |
|---|
| .. | .. |
|---|
| 1250 | 1233 | if (ret < 0) |
|---|
| 1251 | 1234 | return ret; |
|---|
| 1252 | 1235 | |
|---|
| 1253 | | - media_pipeline_stop(&vc->ve.vdev.entity); |
|---|
| 1254 | | - vc->streaming = false; |
|---|
| 1236 | + if (vc->streaming) { |
|---|
| 1237 | + media_pipeline_stop(&vc->ve.vdev.entity); |
|---|
| 1238 | + vc->streaming = false; |
|---|
| 1239 | + } |
|---|
| 1240 | + |
|---|
| 1255 | 1241 | return 0; |
|---|
| 1256 | 1242 | } |
|---|
| 1257 | 1243 | |
|---|
| .. | .. |
|---|
| 1283 | 1269 | case V4L2_SEL_TGT_COMPOSE_DEFAULT: |
|---|
| 1284 | 1270 | case V4L2_SEL_TGT_COMPOSE_BOUNDS: |
|---|
| 1285 | 1271 | f = &ctx->d_frame; |
|---|
| 1286 | | - /* fall through */ |
|---|
| 1272 | + fallthrough; |
|---|
| 1287 | 1273 | case V4L2_SEL_TGT_CROP_BOUNDS: |
|---|
| 1288 | 1274 | case V4L2_SEL_TGT_CROP_DEFAULT: |
|---|
| 1289 | 1275 | s->r.left = 0; |
|---|
| .. | .. |
|---|
| 1294 | 1280 | |
|---|
| 1295 | 1281 | case V4L2_SEL_TGT_COMPOSE: |
|---|
| 1296 | 1282 | f = &ctx->d_frame; |
|---|
| 1297 | | - /* fall through */ |
|---|
| 1283 | + fallthrough; |
|---|
| 1298 | 1284 | case V4L2_SEL_TGT_CROP: |
|---|
| 1299 | 1285 | s->r.left = f->offs_h; |
|---|
| 1300 | 1286 | s->r.top = f->offs_v; |
|---|
| .. | .. |
|---|
| 1304 | 1290 | } |
|---|
| 1305 | 1291 | |
|---|
| 1306 | 1292 | return -EINVAL; |
|---|
| 1307 | | -} |
|---|
| 1308 | | - |
|---|
| 1309 | | -/* Return 1 if rectangle a is enclosed in rectangle b, or 0 otherwise. */ |
|---|
| 1310 | | -static int enclosed_rectangle(struct v4l2_rect *a, struct v4l2_rect *b) |
|---|
| 1311 | | -{ |
|---|
| 1312 | | - if (a->left < b->left || a->top < b->top) |
|---|
| 1313 | | - return 0; |
|---|
| 1314 | | - if (a->left + a->width > b->left + b->width) |
|---|
| 1315 | | - return 0; |
|---|
| 1316 | | - if (a->top + a->height > b->top + b->height) |
|---|
| 1317 | | - return 0; |
|---|
| 1318 | | - |
|---|
| 1319 | | - return 1; |
|---|
| 1320 | 1293 | } |
|---|
| 1321 | 1294 | |
|---|
| 1322 | 1295 | static int fimc_cap_s_selection(struct file *file, void *fh, |
|---|
| .. | .. |
|---|
| 1341 | 1314 | fimc_capture_try_selection(ctx, &rect, s->target); |
|---|
| 1342 | 1315 | |
|---|
| 1343 | 1316 | if (s->flags & V4L2_SEL_FLAG_LE && |
|---|
| 1344 | | - !enclosed_rectangle(&rect, &s->r)) |
|---|
| 1317 | + !v4l2_rect_enclosed(&rect, &s->r)) |
|---|
| 1345 | 1318 | return -ERANGE; |
|---|
| 1346 | 1319 | |
|---|
| 1347 | 1320 | if (s->flags & V4L2_SEL_FLAG_GE && |
|---|
| 1348 | | - !enclosed_rectangle(&s->r, &rect)) |
|---|
| 1321 | + !v4l2_rect_enclosed(&s->r, &rect)) |
|---|
| 1349 | 1322 | return -ERANGE; |
|---|
| 1350 | 1323 | |
|---|
| 1351 | 1324 | s->r = rect; |
|---|
| .. | .. |
|---|
| 1361 | 1334 | static const struct v4l2_ioctl_ops fimc_capture_ioctl_ops = { |
|---|
| 1362 | 1335 | .vidioc_querycap = fimc_cap_querycap, |
|---|
| 1363 | 1336 | |
|---|
| 1364 | | - .vidioc_enum_fmt_vid_cap_mplane = fimc_cap_enum_fmt_mplane, |
|---|
| 1337 | + .vidioc_enum_fmt_vid_cap = fimc_cap_enum_fmt, |
|---|
| 1365 | 1338 | .vidioc_try_fmt_vid_cap_mplane = fimc_cap_try_fmt_mplane, |
|---|
| 1366 | 1339 | .vidioc_s_fmt_vid_cap_mplane = fimc_cap_s_fmt_mplane, |
|---|
| 1367 | 1340 | .vidioc_g_fmt_vid_cap_mplane = fimc_cap_g_fmt_mplane, |
|---|
| .. | .. |
|---|
| 1415 | 1388 | |
|---|
| 1416 | 1389 | vc->input = sd->grp_id; |
|---|
| 1417 | 1390 | |
|---|
| 1418 | | - if (vc->user_subdev_api || vc->inh_sensor_ctrls) |
|---|
| 1391 | + if (vc->user_subdev_api) |
|---|
| 1419 | 1392 | return 0; |
|---|
| 1420 | 1393 | |
|---|
| 1421 | 1394 | /* Inherit V4L2 controls from the image sensor subdev. */ |
|---|
| .. | .. |
|---|
| 1424 | 1397 | return 0; |
|---|
| 1425 | 1398 | |
|---|
| 1426 | 1399 | return v4l2_ctrl_add_handler(&vc->ctx->ctrls.handler, |
|---|
| 1427 | | - sensor->ctrl_handler, NULL); |
|---|
| 1400 | + sensor->ctrl_handler, NULL, true); |
|---|
| 1428 | 1401 | } |
|---|
| 1429 | 1402 | |
|---|
| 1430 | 1403 | static const struct media_entity_operations fimc_sd_media_ops = { |
|---|
| .. | .. |
|---|
| 1618 | 1591 | switch (sel->target) { |
|---|
| 1619 | 1592 | case V4L2_SEL_TGT_COMPOSE_BOUNDS: |
|---|
| 1620 | 1593 | f = &ctx->d_frame; |
|---|
| 1621 | | - /* fall through */ |
|---|
| 1594 | + fallthrough; |
|---|
| 1622 | 1595 | case V4L2_SEL_TGT_CROP_BOUNDS: |
|---|
| 1623 | 1596 | r->width = f->o_width; |
|---|
| 1624 | 1597 | r->height = f->o_height; |
|---|
| .. | .. |
|---|
| 1765 | 1738 | vfd->release = video_device_release_empty; |
|---|
| 1766 | 1739 | vfd->queue = q; |
|---|
| 1767 | 1740 | vfd->lock = &fimc->lock; |
|---|
| 1741 | + vfd->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_CAPTURE_MPLANE; |
|---|
| 1768 | 1742 | |
|---|
| 1769 | 1743 | video_set_drvdata(vfd, fimc); |
|---|
| 1770 | 1744 | vid_cap = &fimc->vid_cap; |
|---|
| .. | .. |
|---|
| 1814 | 1788 | if (ret) |
|---|
| 1815 | 1789 | goto err_me_cleanup; |
|---|
| 1816 | 1790 | |
|---|
| 1817 | | - ret = video_register_device(vfd, VFL_TYPE_GRABBER, -1); |
|---|
| 1791 | + ret = video_register_device(vfd, VFL_TYPE_VIDEO, -1); |
|---|
| 1818 | 1792 | if (ret) |
|---|
| 1819 | 1793 | goto err_ctrl_free; |
|---|
| 1820 | 1794 | |
|---|
| .. | .. |
|---|
| 1904 | 1878 | return ret; |
|---|
| 1905 | 1879 | |
|---|
| 1906 | 1880 | sd->entity.ops = &fimc_sd_media_ops; |
|---|
| 1881 | + sd->entity.function = MEDIA_ENT_F_PROC_VIDEO_SCALER; |
|---|
| 1907 | 1882 | sd->internal_ops = &fimc_capture_sd_internal_ops; |
|---|
| 1908 | 1883 | v4l2_set_subdevdata(sd, fimc); |
|---|
| 1909 | 1884 | return 0; |
|---|