| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Copyright (C) 2008-2009 Texas Instruments Inc |
|---|
| 3 | | - * |
|---|
| 4 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 5 | | - * it under the terms of the GNU General Public License as published by |
|---|
| 6 | | - * the Free Software Foundation; either version 2 of the License, or |
|---|
| 7 | | - * (at your option) any later version. |
|---|
| 8 | | - * |
|---|
| 9 | | - * This program is distributed in the hope that it will be useful, |
|---|
| 10 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 11 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 12 | | - * GNU General Public License for more details. |
|---|
| 13 | 4 | * |
|---|
| 14 | 5 | * Driver name : VPFE Capture driver |
|---|
| 15 | 6 | * VPFE Capture driver allows applications to capture and stream video |
|---|
| .. | .. |
|---|
| 23 | 14 | * YUV data through an in-built analog encoder or Digital LCD port. This |
|---|
| 24 | 15 | * driver is for capture through VPFE. A typical EVM using these SoCs have |
|---|
| 25 | 16 | * following high level configuration. |
|---|
| 26 | | - * |
|---|
| 27 | 17 | * |
|---|
| 28 | 18 | * decoder(TVP5146/ YUV/ |
|---|
| 29 | 19 | * MT9T001) --> Raw Bayer RGB ---> MUX -> VPFE (CCDC/ISIF) |
|---|
| .. | .. |
|---|
| 129 | 119 | /* Used when raw Bayer image from ccdc is directly captured to SDRAM */ |
|---|
| 130 | 120 | static const struct vpfe_pixel_format vpfe_pix_fmts[] = { |
|---|
| 131 | 121 | { |
|---|
| 132 | | - .fmtdesc = { |
|---|
| 133 | | - .index = 0, |
|---|
| 134 | | - .type = V4L2_BUF_TYPE_VIDEO_CAPTURE, |
|---|
| 135 | | - .description = "Bayer GrRBGb 8bit A-Law compr.", |
|---|
| 136 | | - .pixelformat = V4L2_PIX_FMT_SBGGR8, |
|---|
| 137 | | - }, |
|---|
| 122 | + .pixelformat = V4L2_PIX_FMT_SBGGR8, |
|---|
| 138 | 123 | .bpp = 1, |
|---|
| 139 | 124 | }, |
|---|
| 140 | 125 | { |
|---|
| 141 | | - .fmtdesc = { |
|---|
| 142 | | - .index = 1, |
|---|
| 143 | | - .type = V4L2_BUF_TYPE_VIDEO_CAPTURE, |
|---|
| 144 | | - .description = "Bayer GrRBGb - 16bit", |
|---|
| 145 | | - .pixelformat = V4L2_PIX_FMT_SBGGR16, |
|---|
| 146 | | - }, |
|---|
| 126 | + .pixelformat = V4L2_PIX_FMT_SBGGR16, |
|---|
| 147 | 127 | .bpp = 2, |
|---|
| 148 | 128 | }, |
|---|
| 149 | 129 | { |
|---|
| 150 | | - .fmtdesc = { |
|---|
| 151 | | - .index = 2, |
|---|
| 152 | | - .type = V4L2_BUF_TYPE_VIDEO_CAPTURE, |
|---|
| 153 | | - .description = "Bayer GrRBGb 8bit DPCM compr.", |
|---|
| 154 | | - .pixelformat = V4L2_PIX_FMT_SGRBG10DPCM8, |
|---|
| 155 | | - }, |
|---|
| 130 | + .pixelformat = V4L2_PIX_FMT_SGRBG10DPCM8, |
|---|
| 156 | 131 | .bpp = 1, |
|---|
| 157 | 132 | }, |
|---|
| 158 | 133 | { |
|---|
| 159 | | - .fmtdesc = { |
|---|
| 160 | | - .index = 3, |
|---|
| 161 | | - .type = V4L2_BUF_TYPE_VIDEO_CAPTURE, |
|---|
| 162 | | - .description = "YCbCr 4:2:2 Interleaved UYVY", |
|---|
| 163 | | - .pixelformat = V4L2_PIX_FMT_UYVY, |
|---|
| 164 | | - }, |
|---|
| 134 | + .pixelformat = V4L2_PIX_FMT_UYVY, |
|---|
| 165 | 135 | .bpp = 2, |
|---|
| 166 | 136 | }, |
|---|
| 167 | 137 | { |
|---|
| 168 | | - .fmtdesc = { |
|---|
| 169 | | - .index = 4, |
|---|
| 170 | | - .type = V4L2_BUF_TYPE_VIDEO_CAPTURE, |
|---|
| 171 | | - .description = "YCbCr 4:2:2 Interleaved YUYV", |
|---|
| 172 | | - .pixelformat = V4L2_PIX_FMT_YUYV, |
|---|
| 173 | | - }, |
|---|
| 138 | + .pixelformat = V4L2_PIX_FMT_YUYV, |
|---|
| 174 | 139 | .bpp = 2, |
|---|
| 175 | 140 | }, |
|---|
| 176 | 141 | { |
|---|
| 177 | | - .fmtdesc = { |
|---|
| 178 | | - .index = 5, |
|---|
| 179 | | - .type = V4L2_BUF_TYPE_VIDEO_CAPTURE, |
|---|
| 180 | | - .description = "Y/CbCr 4:2:0 - Semi planar", |
|---|
| 181 | | - .pixelformat = V4L2_PIX_FMT_NV12, |
|---|
| 182 | | - }, |
|---|
| 142 | + .pixelformat = V4L2_PIX_FMT_NV12, |
|---|
| 183 | 143 | .bpp = 1, |
|---|
| 184 | 144 | }, |
|---|
| 185 | 145 | }; |
|---|
| .. | .. |
|---|
| 193 | 153 | int i; |
|---|
| 194 | 154 | |
|---|
| 195 | 155 | for (i = 0; i < ARRAY_SIZE(vpfe_pix_fmts); i++) { |
|---|
| 196 | | - if (pix_format == vpfe_pix_fmts[i].fmtdesc.pixelformat) |
|---|
| 156 | + if (pix_format == vpfe_pix_fmts[i].pixelformat) |
|---|
| 197 | 157 | return &vpfe_pix_fmts[i]; |
|---|
| 198 | 158 | } |
|---|
| 199 | 159 | return NULL; |
|---|
| .. | .. |
|---|
| 208 | 168 | int ret = 0; |
|---|
| 209 | 169 | printk(KERN_NOTICE "vpfe_register_ccdc_device: %s\n", dev->name); |
|---|
| 210 | 170 | |
|---|
| 211 | | - BUG_ON(!dev->hw_ops.open); |
|---|
| 212 | | - BUG_ON(!dev->hw_ops.enable); |
|---|
| 213 | | - BUG_ON(!dev->hw_ops.set_hw_if_params); |
|---|
| 214 | | - BUG_ON(!dev->hw_ops.configure); |
|---|
| 215 | | - BUG_ON(!dev->hw_ops.set_buftype); |
|---|
| 216 | | - BUG_ON(!dev->hw_ops.get_buftype); |
|---|
| 217 | | - BUG_ON(!dev->hw_ops.enum_pix); |
|---|
| 218 | | - BUG_ON(!dev->hw_ops.set_frame_format); |
|---|
| 219 | | - BUG_ON(!dev->hw_ops.get_frame_format); |
|---|
| 220 | | - BUG_ON(!dev->hw_ops.get_pixel_format); |
|---|
| 221 | | - BUG_ON(!dev->hw_ops.set_pixel_format); |
|---|
| 222 | | - BUG_ON(!dev->hw_ops.set_image_window); |
|---|
| 223 | | - BUG_ON(!dev->hw_ops.get_image_window); |
|---|
| 224 | | - BUG_ON(!dev->hw_ops.get_line_length); |
|---|
| 225 | | - BUG_ON(!dev->hw_ops.getfid); |
|---|
| 171 | + if (!dev->hw_ops.open || |
|---|
| 172 | + !dev->hw_ops.enable || |
|---|
| 173 | + !dev->hw_ops.set_hw_if_params || |
|---|
| 174 | + !dev->hw_ops.configure || |
|---|
| 175 | + !dev->hw_ops.set_buftype || |
|---|
| 176 | + !dev->hw_ops.get_buftype || |
|---|
| 177 | + !dev->hw_ops.enum_pix || |
|---|
| 178 | + !dev->hw_ops.set_frame_format || |
|---|
| 179 | + !dev->hw_ops.get_frame_format || |
|---|
| 180 | + !dev->hw_ops.get_pixel_format || |
|---|
| 181 | + !dev->hw_ops.set_pixel_format || |
|---|
| 182 | + !dev->hw_ops.set_image_window || |
|---|
| 183 | + !dev->hw_ops.get_image_window || |
|---|
| 184 | + !dev->hw_ops.get_line_length || |
|---|
| 185 | + !dev->hw_ops.getfid) |
|---|
| 186 | + return -EINVAL; |
|---|
| 226 | 187 | |
|---|
| 227 | 188 | mutex_lock(&ccdc_lock); |
|---|
| 228 | 189 | if (!ccdc_cfg) { |
|---|
| .. | .. |
|---|
| 518 | 479 | |
|---|
| 519 | 480 | static void vpfe_process_buffer_complete(struct vpfe_device *vpfe_dev) |
|---|
| 520 | 481 | { |
|---|
| 521 | | - v4l2_get_timestamp(&vpfe_dev->cur_frm->ts); |
|---|
| 482 | + vpfe_dev->cur_frm->ts = ktime_get_ns(); |
|---|
| 522 | 483 | vpfe_dev->cur_frm->state = VIDEOBUF_DONE; |
|---|
| 523 | 484 | vpfe_dev->cur_frm->size = vpfe_dev->fmt.fmt.pix.sizeimage; |
|---|
| 524 | 485 | wake_up_interruptible(&vpfe_dev->cur_frm->done); |
|---|
| .. | .. |
|---|
| 792 | 753 | temp = 0; |
|---|
| 793 | 754 | found = 0; |
|---|
| 794 | 755 | while (ccdc_dev->hw_ops.enum_pix(&pix, temp) >= 0) { |
|---|
| 795 | | - if (vpfe_pix_fmt->fmtdesc.pixelformat == pix) { |
|---|
| 756 | + if (vpfe_pix_fmt->pixelformat == pix) { |
|---|
| 796 | 757 | found = 1; |
|---|
| 797 | 758 | break; |
|---|
| 798 | 759 | } |
|---|
| .. | .. |
|---|
| 887 | 848 | |
|---|
| 888 | 849 | v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_querycap\n"); |
|---|
| 889 | 850 | |
|---|
| 890 | | - cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; |
|---|
| 891 | | - cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; |
|---|
| 892 | | - strlcpy(cap->driver, CAPTURE_DRV_NAME, sizeof(cap->driver)); |
|---|
| 893 | | - strlcpy(cap->bus_info, "VPFE", sizeof(cap->bus_info)); |
|---|
| 894 | | - strlcpy(cap->card, vpfe_dev->cfg->card_name, sizeof(cap->card)); |
|---|
| 851 | + strscpy(cap->driver, CAPTURE_DRV_NAME, sizeof(cap->driver)); |
|---|
| 852 | + strscpy(cap->bus_info, "VPFE", sizeof(cap->bus_info)); |
|---|
| 853 | + strscpy(cap->card, vpfe_dev->cfg->card_name, sizeof(cap->card)); |
|---|
| 895 | 854 | return 0; |
|---|
| 896 | 855 | } |
|---|
| 897 | 856 | |
|---|
| .. | .. |
|---|
| 911 | 870 | { |
|---|
| 912 | 871 | struct vpfe_device *vpfe_dev = video_drvdata(file); |
|---|
| 913 | 872 | const struct vpfe_pixel_format *pix_fmt; |
|---|
| 914 | | - int temp_index; |
|---|
| 915 | 873 | u32 pix; |
|---|
| 916 | 874 | |
|---|
| 917 | 875 | v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_enum_fmt_vid_cap\n"); |
|---|
| .. | .. |
|---|
| 922 | 880 | /* Fill in the information about format */ |
|---|
| 923 | 881 | pix_fmt = vpfe_lookup_pix_format(pix); |
|---|
| 924 | 882 | if (pix_fmt) { |
|---|
| 925 | | - temp_index = fmt->index; |
|---|
| 926 | | - *fmt = pix_fmt->fmtdesc; |
|---|
| 927 | | - fmt->index = temp_index; |
|---|
| 883 | + fmt->pixelformat = pix_fmt->pixelformat; |
|---|
| 928 | 884 | return 0; |
|---|
| 929 | 885 | } |
|---|
| 930 | 886 | return -EINVAL; |
|---|
| .. | .. |
|---|
| 1558 | 1514 | return ret; |
|---|
| 1559 | 1515 | } |
|---|
| 1560 | 1516 | |
|---|
| 1561 | | -static int vpfe_cropcap(struct file *file, void *priv, |
|---|
| 1562 | | - struct v4l2_cropcap *crop) |
|---|
| 1517 | +static int vpfe_g_pixelaspect(struct file *file, void *priv, |
|---|
| 1518 | + int type, struct v4l2_fract *f) |
|---|
| 1563 | 1519 | { |
|---|
| 1564 | 1520 | struct vpfe_device *vpfe_dev = video_drvdata(file); |
|---|
| 1565 | 1521 | |
|---|
| 1566 | | - v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_cropcap\n"); |
|---|
| 1522 | + v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_g_pixelaspect\n"); |
|---|
| 1567 | 1523 | |
|---|
| 1568 | | - if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) |
|---|
| 1524 | + if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE) |
|---|
| 1569 | 1525 | return -EINVAL; |
|---|
| 1570 | 1526 | /* If std_index is invalid, then just return (== 1:1 aspect) */ |
|---|
| 1571 | 1527 | if (vpfe_dev->std_index >= ARRAY_SIZE(vpfe_standards)) |
|---|
| 1572 | 1528 | return 0; |
|---|
| 1573 | 1529 | |
|---|
| 1574 | | - crop->pixelaspect = vpfe_standards[vpfe_dev->std_index].pixelaspect; |
|---|
| 1530 | + *f = vpfe_standards[vpfe_dev->std_index].pixelaspect; |
|---|
| 1575 | 1531 | return 0; |
|---|
| 1576 | 1532 | } |
|---|
| 1577 | 1533 | |
|---|
| .. | .. |
|---|
| 1677 | 1633 | .vidioc_dqbuf = vpfe_dqbuf, |
|---|
| 1678 | 1634 | .vidioc_streamon = vpfe_streamon, |
|---|
| 1679 | 1635 | .vidioc_streamoff = vpfe_streamoff, |
|---|
| 1680 | | - .vidioc_cropcap = vpfe_cropcap, |
|---|
| 1636 | + .vidioc_g_pixelaspect = vpfe_g_pixelaspect, |
|---|
| 1681 | 1637 | .vidioc_g_selection = vpfe_g_selection, |
|---|
| 1682 | 1638 | .vidioc_s_selection = vpfe_s_selection, |
|---|
| 1683 | 1639 | }; |
|---|
| .. | .. |
|---|
| 1759 | 1715 | |
|---|
| 1760 | 1716 | mutex_lock(&ccdc_lock); |
|---|
| 1761 | 1717 | |
|---|
| 1762 | | - strncpy(ccdc_cfg->name, vpfe_cfg->ccdc, 32); |
|---|
| 1718 | + strscpy(ccdc_cfg->name, vpfe_cfg->ccdc, sizeof(ccdc_cfg->name)); |
|---|
| 1763 | 1719 | /* Get VINT0 irq resource */ |
|---|
| 1764 | 1720 | res1 = platform_get_resource(pdev, IORESOURCE_IRQ, 0); |
|---|
| 1765 | 1721 | if (!res1) { |
|---|
| .. | .. |
|---|
| 1795 | 1751 | vfd->ioctl_ops = &vpfe_ioctl_ops; |
|---|
| 1796 | 1752 | vfd->tvnorms = 0; |
|---|
| 1797 | 1753 | vfd->v4l2_dev = &vpfe_dev->v4l2_dev; |
|---|
| 1754 | + vfd->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; |
|---|
| 1798 | 1755 | snprintf(vfd->name, sizeof(vfd->name), |
|---|
| 1799 | 1756 | "%s_V%d.%d.%d", |
|---|
| 1800 | 1757 | CAPTURE_DRV_NAME, |
|---|
| .. | .. |
|---|
| 1823 | 1780 | "video_dev=%p\n", &vpfe_dev->video_dev); |
|---|
| 1824 | 1781 | vpfe_dev->fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
|---|
| 1825 | 1782 | ret = video_register_device(&vpfe_dev->video_dev, |
|---|
| 1826 | | - VFL_TYPE_GRABBER, -1); |
|---|
| 1783 | + VFL_TYPE_VIDEO, -1); |
|---|
| 1827 | 1784 | |
|---|
| 1828 | 1785 | if (ret) { |
|---|
| 1829 | 1786 | v4l2_err(pdev->dev.driver, |
|---|