.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * Samsung EXYNOS FIMC-LITE (camera host interface) driver |
---|
3 | 4 | * |
---|
4 | 5 | * Copyright (C) 2012 - 2013 Samsung Electronics Co., Ltd. |
---|
5 | 6 | * Author: 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 | #define pr_fmt(fmt) "%s:%d " fmt, __func__, __LINE__ |
---|
12 | 9 | |
---|
.. | .. |
---|
28 | 25 | #include <media/v4l2-device.h> |
---|
29 | 26 | #include <media/v4l2-ioctl.h> |
---|
30 | 27 | #include <media/v4l2-mem2mem.h> |
---|
| 28 | +#include <media/v4l2-rect.h> |
---|
31 | 29 | #include <media/videobuf2-v4l2.h> |
---|
32 | 30 | #include <media/videobuf2-dma-contig.h> |
---|
33 | 31 | #include <media/drv-intf/exynos-fimc.h> |
---|
.. | .. |
---|
42 | 40 | |
---|
43 | 41 | static const struct fimc_fmt fimc_lite_formats[] = { |
---|
44 | 42 | { |
---|
45 | | - .name = "YUV 4:2:2 packed, YCbYCr", |
---|
46 | 43 | .fourcc = V4L2_PIX_FMT_YUYV, |
---|
47 | 44 | .colorspace = V4L2_COLORSPACE_JPEG, |
---|
48 | 45 | .depth = { 16 }, |
---|
.. | .. |
---|
51 | 48 | .mbus_code = MEDIA_BUS_FMT_YUYV8_2X8, |
---|
52 | 49 | .flags = FMT_FLAGS_YUV, |
---|
53 | 50 | }, { |
---|
54 | | - .name = "YUV 4:2:2 packed, CbYCrY", |
---|
55 | 51 | .fourcc = V4L2_PIX_FMT_UYVY, |
---|
56 | 52 | .colorspace = V4L2_COLORSPACE_JPEG, |
---|
57 | 53 | .depth = { 16 }, |
---|
.. | .. |
---|
60 | 56 | .mbus_code = MEDIA_BUS_FMT_UYVY8_2X8, |
---|
61 | 57 | .flags = FMT_FLAGS_YUV, |
---|
62 | 58 | }, { |
---|
63 | | - .name = "YUV 4:2:2 packed, CrYCbY", |
---|
64 | 59 | .fourcc = V4L2_PIX_FMT_VYUY, |
---|
65 | 60 | .colorspace = V4L2_COLORSPACE_JPEG, |
---|
66 | 61 | .depth = { 16 }, |
---|
.. | .. |
---|
69 | 64 | .mbus_code = MEDIA_BUS_FMT_VYUY8_2X8, |
---|
70 | 65 | .flags = FMT_FLAGS_YUV, |
---|
71 | 66 | }, { |
---|
72 | | - .name = "YUV 4:2:2 packed, YCrYCb", |
---|
73 | 67 | .fourcc = V4L2_PIX_FMT_YVYU, |
---|
74 | 68 | .colorspace = V4L2_COLORSPACE_JPEG, |
---|
75 | 69 | .depth = { 16 }, |
---|
.. | .. |
---|
78 | 72 | .mbus_code = MEDIA_BUS_FMT_YVYU8_2X8, |
---|
79 | 73 | .flags = FMT_FLAGS_YUV, |
---|
80 | 74 | }, { |
---|
81 | | - .name = "RAW8 (GRBG)", |
---|
82 | 75 | .fourcc = V4L2_PIX_FMT_SGRBG8, |
---|
83 | 76 | .colorspace = V4L2_COLORSPACE_SRGB, |
---|
84 | 77 | .depth = { 8 }, |
---|
.. | .. |
---|
87 | 80 | .mbus_code = MEDIA_BUS_FMT_SGRBG8_1X8, |
---|
88 | 81 | .flags = FMT_FLAGS_RAW_BAYER, |
---|
89 | 82 | }, { |
---|
90 | | - .name = "RAW10 (GRBG)", |
---|
91 | 83 | .fourcc = V4L2_PIX_FMT_SGRBG10, |
---|
92 | 84 | .colorspace = V4L2_COLORSPACE_SRGB, |
---|
93 | 85 | .depth = { 16 }, |
---|
.. | .. |
---|
96 | 88 | .mbus_code = MEDIA_BUS_FMT_SGRBG10_1X10, |
---|
97 | 89 | .flags = FMT_FLAGS_RAW_BAYER, |
---|
98 | 90 | }, { |
---|
99 | | - .name = "RAW12 (GRBG)", |
---|
100 | 91 | .fourcc = V4L2_PIX_FMT_SGRBG12, |
---|
101 | 92 | .colorspace = V4L2_COLORSPACE_SRGB, |
---|
102 | 93 | .depth = { 16 }, |
---|
.. | .. |
---|
478 | 469 | } |
---|
479 | 470 | |
---|
480 | 471 | set_bit(ST_FLITE_IN_USE, &fimc->state); |
---|
481 | | - ret = pm_runtime_get_sync(&fimc->pdev->dev); |
---|
| 472 | + ret = pm_runtime_resume_and_get(&fimc->pdev->dev); |
---|
482 | 473 | if (ret < 0) |
---|
483 | | - goto err_pm; |
---|
| 474 | + goto err_in_use; |
---|
484 | 475 | |
---|
485 | 476 | ret = v4l2_fh_open(file); |
---|
486 | 477 | if (ret < 0) |
---|
.. | .. |
---|
508 | 499 | v4l2_fh_release(file); |
---|
509 | 500 | err_pm: |
---|
510 | 501 | pm_runtime_put_sync(&fimc->pdev->dev); |
---|
| 502 | +err_in_use: |
---|
511 | 503 | clear_bit(ST_FLITE_IN_USE, &fimc->state); |
---|
512 | 504 | unlock: |
---|
513 | 505 | mutex_unlock(&fimc->lock); |
---|
.. | .. |
---|
654 | 646 | { |
---|
655 | 647 | struct fimc_lite *fimc = video_drvdata(file); |
---|
656 | 648 | |
---|
657 | | - strlcpy(cap->driver, FIMC_LITE_DRV_NAME, sizeof(cap->driver)); |
---|
658 | | - strlcpy(cap->card, FIMC_LITE_DRV_NAME, sizeof(cap->card)); |
---|
| 649 | + strscpy(cap->driver, FIMC_LITE_DRV_NAME, sizeof(cap->driver)); |
---|
| 650 | + strscpy(cap->card, FIMC_LITE_DRV_NAME, sizeof(cap->card)); |
---|
659 | 651 | snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s", |
---|
660 | 652 | dev_name(&fimc->pdev->dev)); |
---|
661 | | - |
---|
662 | | - cap->device_caps = V4L2_CAP_STREAMING; |
---|
663 | | - cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; |
---|
664 | 653 | return 0; |
---|
665 | 654 | } |
---|
666 | 655 | |
---|
667 | | -static int fimc_lite_enum_fmt_mplane(struct file *file, void *priv, |
---|
668 | | - struct v4l2_fmtdesc *f) |
---|
| 656 | +static int fimc_lite_enum_fmt(struct file *file, void *priv, |
---|
| 657 | + struct v4l2_fmtdesc *f) |
---|
669 | 658 | { |
---|
670 | 659 | const struct fimc_fmt *fmt; |
---|
671 | 660 | |
---|
.. | .. |
---|
673 | 662 | return -EINVAL; |
---|
674 | 663 | |
---|
675 | 664 | fmt = &fimc_lite_formats[f->index]; |
---|
676 | | - strlcpy(f->description, fmt->name, sizeof(f->description)); |
---|
677 | 665 | f->pixelformat = fmt->fourcc; |
---|
678 | 666 | |
---|
679 | 667 | return 0; |
---|
.. | .. |
---|
882 | 870 | return ret; |
---|
883 | 871 | } |
---|
884 | 872 | |
---|
885 | | -/* Return 1 if rectangle a is enclosed in rectangle b, or 0 otherwise. */ |
---|
886 | | -static int enclosed_rectangle(struct v4l2_rect *a, struct v4l2_rect *b) |
---|
887 | | -{ |
---|
888 | | - if (a->left < b->left || a->top < b->top) |
---|
889 | | - return 0; |
---|
890 | | - if (a->left + a->width > b->left + b->width) |
---|
891 | | - return 0; |
---|
892 | | - if (a->top + a->height > b->top + b->height) |
---|
893 | | - return 0; |
---|
894 | | - |
---|
895 | | - return 1; |
---|
896 | | -} |
---|
897 | | - |
---|
898 | 873 | static int fimc_lite_g_selection(struct file *file, void *fh, |
---|
899 | 874 | struct v4l2_selection *sel) |
---|
900 | 875 | { |
---|
.. | .. |
---|
936 | 911 | fimc_lite_try_compose(fimc, &rect); |
---|
937 | 912 | |
---|
938 | 913 | if ((sel->flags & V4L2_SEL_FLAG_LE) && |
---|
939 | | - !enclosed_rectangle(&rect, &sel->r)) |
---|
| 914 | + !v4l2_rect_enclosed(&rect, &sel->r)) |
---|
940 | 915 | return -ERANGE; |
---|
941 | 916 | |
---|
942 | 917 | if ((sel->flags & V4L2_SEL_FLAG_GE) && |
---|
943 | | - !enclosed_rectangle(&sel->r, &rect)) |
---|
| 918 | + !v4l2_rect_enclosed(&sel->r, &rect)) |
---|
944 | 919 | return -ERANGE; |
---|
945 | 920 | |
---|
946 | 921 | sel->r = rect; |
---|
.. | .. |
---|
954 | 929 | |
---|
955 | 930 | static const struct v4l2_ioctl_ops fimc_lite_ioctl_ops = { |
---|
956 | 931 | .vidioc_querycap = fimc_lite_querycap, |
---|
957 | | - .vidioc_enum_fmt_vid_cap_mplane = fimc_lite_enum_fmt_mplane, |
---|
| 932 | + .vidioc_enum_fmt_vid_cap = fimc_lite_enum_fmt, |
---|
958 | 933 | .vidioc_try_fmt_vid_cap_mplane = fimc_lite_try_fmt_mplane, |
---|
959 | 934 | .vidioc_s_fmt_vid_cap_mplane = fimc_lite_s_fmt_mplane, |
---|
960 | 935 | .vidioc_g_fmt_vid_cap_mplane = fimc_lite_g_fmt_mplane, |
---|
.. | .. |
---|
1282 | 1257 | vfd->minor = -1; |
---|
1283 | 1258 | vfd->release = video_device_release_empty; |
---|
1284 | 1259 | vfd->queue = q; |
---|
| 1260 | + vfd->device_caps = V4L2_CAP_VIDEO_CAPTURE_MPLANE | V4L2_CAP_STREAMING; |
---|
1285 | 1261 | fimc->reqbufs_count = 0; |
---|
1286 | 1262 | |
---|
1287 | 1263 | INIT_LIST_HEAD(&fimc->pending_buf_q); |
---|
.. | .. |
---|
1310 | 1286 | video_set_drvdata(vfd, fimc); |
---|
1311 | 1287 | fimc->ve.pipe = v4l2_get_subdev_hostdata(sd); |
---|
1312 | 1288 | |
---|
1313 | | - ret = video_register_device(vfd, VFL_TYPE_GRABBER, -1); |
---|
| 1289 | + ret = video_register_device(vfd, VFL_TYPE_VIDEO, -1); |
---|
1314 | 1290 | if (ret < 0) { |
---|
1315 | 1291 | media_entity_cleanup(&vfd->entity); |
---|
1316 | 1292 | fimc->ve.pipe = NULL; |
---|
.. | .. |
---|
1627 | 1603 | struct fimc_lite *fimc = platform_get_drvdata(pdev); |
---|
1628 | 1604 | struct device *dev = &pdev->dev; |
---|
1629 | 1605 | |
---|
| 1606 | + if (!pm_runtime_enabled(dev)) |
---|
| 1607 | + clk_disable_unprepare(fimc->clock); |
---|
| 1608 | + |
---|
1630 | 1609 | pm_runtime_disable(dev); |
---|
1631 | 1610 | pm_runtime_set_suspended(dev); |
---|
1632 | 1611 | fimc_lite_unregister_capture_subdev(fimc); |
---|