17da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri/* 27da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * Copyright (C) 2008-2009 Texas Instruments Inc 37da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * 47da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * This program is free software; you can redistribute it and/or modify 57da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * it under the terms of the GNU General Public License as published by 67da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * the Free Software Foundation; either version 2 of the License, or 77da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * (at your option) any later version. 87da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * 97da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * This program is distributed in the hope that it will be useful, 107da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * but WITHOUT ANY WARRANTY; without even the implied warranty of 117da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 127da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * GNU General Public License for more details. 137da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * 147da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * You should have received a copy of the GNU General Public License 157da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * along with this program; if not, write to the Free Software 167da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 177da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * 187da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * Driver name : VPFE Capture driver 197da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * VPFE Capture driver allows applications to capture and stream video 207da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * frames on DaVinci SoCs (DM6446, DM355 etc) from a YUV source such as 217da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * TVP5146 or Raw Bayer RGB image data from an image sensor 227da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * such as Microns' MT9T001, MT9T031 etc. 237da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * 247da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * These SoCs have, in common, a Video Processing Subsystem (VPSS) that 257da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * consists of a Video Processing Front End (VPFE) for capturing 267da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * video/raw image data and Video Processing Back End (VPBE) for displaying 277da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * YUV data through an in-built analog encoder or Digital LCD port. This 287da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * driver is for capture through VPFE. A typical EVM using these SoCs have 297da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * following high level configuration. 307da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * 317da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * 327da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * decoder(TVP5146/ YUV/ 337da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * MT9T001) --> Raw Bayer RGB ---> MUX -> VPFE (CCDC/ISIF) 347da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * data input | | 357da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * V | 367da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * SDRAM | 377da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * V 387da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * Image Processor 397da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * | 407da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * V 417da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * SDRAM 427da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * The data flow happens from a decoder connected to the VPFE over a 437da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * YUV embedded (BT.656/BT.1120) or separate sync or raw bayer rgb interface 447da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * and to the input of VPFE through an optional MUX (if more inputs are 457da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * to be interfaced on the EVM). The input data is first passed through 467da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * CCDC (CCD Controller, a.k.a Image Sensor Interface, ISIF). The CCDC 477da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * does very little or no processing on YUV data and does pre-process Raw 487da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * Bayer RGB data through modules such as Defect Pixel Correction (DFC) 497da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * Color Space Conversion (CSC), data gain/offset etc. After this, data 507da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * can be written to SDRAM or can be connected to the image processing 517da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * block such as IPIPE (on DM355 only). 527da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * 537da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * Features supported 547da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * - MMAP IO 557da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * - Capture using TVP5146 over BT.656 567da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * - support for interfacing decoders using sub device model 577da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * - Work with DM355 or DM6446 CCDC to do Raw Bayer RGB/YUV 587da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * data capture to SDRAM. 597da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * TODO list 607da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * - Support multiple REQBUF after open 617da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * - Support for de-allocating buffers through REQBUF 627da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * - Support for Raw Bayer RGB capture 637da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * - Support for chaining Image Processor 647da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * - Support for static allocation of buffers 657da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * - Support for USERPTR IO 667da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * - Support for STREAMON before QBUF 677da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * - Support for control ioctls 687da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri */ 697da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri#include <linux/module.h> 705a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h> 717da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri#include <linux/init.h> 727da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri#include <linux/platform_device.h> 737da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri#include <linux/interrupt.h> 747da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri#include <media/v4l2-common.h> 757da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri#include <linux/io.h> 767da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri#include <media/davinci/vpfe_capture.h> 777da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri#include "ccdc_hw_device.h" 787da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 797da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic int debug; 807da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic u32 numbuffers = 3; 817da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic u32 bufsize = (720 * 576 * 2); 827da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 837da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicherimodule_param(numbuffers, uint, S_IRUGO); 847da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicherimodule_param(bufsize, uint, S_IRUGO); 857da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicherimodule_param(debug, int, 0644); 867da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 877da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan KaricheriMODULE_PARM_DESC(numbuffers, "buffer count (default:3)"); 887da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan KaricheriMODULE_PARM_DESC(bufsize, "buffer size in bytes (default:720 x 576 x 2)"); 897da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan KaricheriMODULE_PARM_DESC(debug, "Debug level 0-1"); 907da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 917da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan KaricheriMODULE_DESCRIPTION("VPFE Video for Linux Capture Driver"); 927da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan KaricheriMODULE_LICENSE("GPL"); 937da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan KaricheriMODULE_AUTHOR("Texas Instruments"); 947da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 957da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri/* standard information */ 967da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristruct vpfe_standard { 977da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_std_id std_id; 987da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri unsigned int width; 997da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri unsigned int height; 1007da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct v4l2_fract pixelaspect; 1017da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* 0 - progressive, 1 - interlaced */ 1027da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri int frame_format; 1037da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri}; 1047da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 1057da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri/* ccdc configuration */ 1067da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristruct ccdc_config { 1077da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* This make sure vpfe is probed and ready to go */ 1087da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri int vpfe_probed; 1097da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* name of ccdc device */ 1107da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri char name[32]; 1117da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri}; 1127da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 1137da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri/* data structures */ 1147da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic struct vpfe_config_params config_params = { 1157da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .min_numbuffers = 3, 1167da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .numbuffers = 3, 1177da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .min_bufsize = 720 * 480 * 2, 1187da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .device_bufsize = 720 * 576 * 2, 1197da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri}; 1207da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 1217da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri/* ccdc device registered */ 1227da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic struct ccdc_hw_device *ccdc_dev; 1237da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri/* lock for accessing ccdc information */ 1247da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic DEFINE_MUTEX(ccdc_lock); 1257da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri/* ccdc configuration */ 1267da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic struct ccdc_config *ccdc_cfg; 1277da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 1287da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karichericonst struct vpfe_standard vpfe_standards[] = { 1297da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri {V4L2_STD_525_60, 720, 480, {11, 10}, 1}, 1307da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri {V4L2_STD_625_50, 720, 576, {54, 59}, 1}, 1317da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri}; 1327da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 1337da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri/* Used when raw Bayer image from ccdc is directly captured to SDRAM */ 1347da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic const struct vpfe_pixel_format vpfe_pix_fmts[] = { 1357da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri { 1367da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .fmtdesc = { 1377da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .index = 0, 1387da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .type = V4L2_BUF_TYPE_VIDEO_CAPTURE, 1397da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .description = "Bayer GrRBGb 8bit A-Law compr.", 1407da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .pixelformat = V4L2_PIX_FMT_SBGGR8, 1417da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri }, 1427da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .bpp = 1, 1437da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri }, 1447da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri { 1457da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .fmtdesc = { 1467da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .index = 1, 1477da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .type = V4L2_BUF_TYPE_VIDEO_CAPTURE, 1487da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .description = "Bayer GrRBGb - 16bit", 1497da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .pixelformat = V4L2_PIX_FMT_SBGGR16, 1507da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri }, 1517da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .bpp = 2, 1527da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri }, 1537da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri { 1547da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .fmtdesc = { 1557da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .index = 2, 1567da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .type = V4L2_BUF_TYPE_VIDEO_CAPTURE, 1577da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .description = "Bayer GrRBGb 8bit DPCM compr.", 1587da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .pixelformat = V4L2_PIX_FMT_SGRBG10DPCM8, 1597da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri }, 1607da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .bpp = 1, 1617da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri }, 1627da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri { 1637da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .fmtdesc = { 1647da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .index = 3, 1657da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .type = V4L2_BUF_TYPE_VIDEO_CAPTURE, 1667da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .description = "YCbCr 4:2:2 Interleaved UYVY", 1677da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .pixelformat = V4L2_PIX_FMT_UYVY, 1687da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri }, 1697da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .bpp = 2, 1707da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri }, 1717da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri { 1727da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .fmtdesc = { 1737da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .index = 4, 1747da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .type = V4L2_BUF_TYPE_VIDEO_CAPTURE, 1757da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .description = "YCbCr 4:2:2 Interleaved YUYV", 1767da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .pixelformat = V4L2_PIX_FMT_YUYV, 1777da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri }, 1787da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .bpp = 2, 1797da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri }, 1807da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri { 1817da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .fmtdesc = { 1827da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .index = 5, 1837da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .type = V4L2_BUF_TYPE_VIDEO_CAPTURE, 1847da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .description = "Y/CbCr 4:2:0 - Semi planar", 1857da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .pixelformat = V4L2_PIX_FMT_NV12, 1867da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri }, 1877da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .bpp = 1, 1887da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri }, 1897da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri}; 1907da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 1917da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri/* 1927da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * vpfe_lookup_pix_format() 1937da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * lookup an entry in the vpfe pix format table based on pix_format 1947da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri */ 1957da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic const struct vpfe_pixel_format *vpfe_lookup_pix_format(u32 pix_format) 1967da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 1977da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri int i; 1987da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 1997da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri for (i = 0; i < ARRAY_SIZE(vpfe_pix_fmts); i++) { 2007da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (pix_format == vpfe_pix_fmts[i].fmtdesc.pixelformat) 2017da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return &vpfe_pix_fmts[i]; 2027da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 2037da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return NULL; 2047da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 2057da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 2067da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri/* 2077da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * vpfe_register_ccdc_device. CCDC module calls this to 2087da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * register with vpfe capture 2097da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri */ 2107da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheriint vpfe_register_ccdc_device(struct ccdc_hw_device *dev) 2117da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 2127da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri int ret = 0; 2137da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri printk(KERN_NOTICE "vpfe_register_ccdc_device: %s\n", dev->name); 2147da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 2157da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri BUG_ON(!dev->hw_ops.open); 2167da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri BUG_ON(!dev->hw_ops.enable); 2177da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri BUG_ON(!dev->hw_ops.set_hw_if_params); 2187da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri BUG_ON(!dev->hw_ops.configure); 2197da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri BUG_ON(!dev->hw_ops.set_buftype); 2207da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri BUG_ON(!dev->hw_ops.get_buftype); 2217da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri BUG_ON(!dev->hw_ops.enum_pix); 2227da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri BUG_ON(!dev->hw_ops.set_frame_format); 2237da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri BUG_ON(!dev->hw_ops.get_frame_format); 2247da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri BUG_ON(!dev->hw_ops.get_pixel_format); 2257da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri BUG_ON(!dev->hw_ops.set_pixel_format); 2267da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri BUG_ON(!dev->hw_ops.set_image_window); 2277da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri BUG_ON(!dev->hw_ops.get_image_window); 2287da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri BUG_ON(!dev->hw_ops.get_line_length); 2297da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri BUG_ON(!dev->hw_ops.getfid); 2307da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 2317da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri mutex_lock(&ccdc_lock); 2327da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (NULL == ccdc_cfg) { 2337da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* 2347da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * TODO. Will this ever happen? if so, we need to fix it. 2357da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * Proabably we need to add the request to a linked list and 2367da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * walk through it during vpfe probe 2377da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri */ 2387da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri printk(KERN_ERR "vpfe capture not initialized\n"); 23951444ea3d4f5baa0338297aba7065fd695528a36Muralidharan Karicheri ret = -EFAULT; 2407da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri goto unlock; 2417da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 2427da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 2437da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (strcmp(dev->name, ccdc_cfg->name)) { 2447da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* ignore this ccdc */ 24551444ea3d4f5baa0338297aba7065fd695528a36Muralidharan Karicheri ret = -EINVAL; 2467da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri goto unlock; 2477da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 2487da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 2497da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (ccdc_dev) { 2507da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri printk(KERN_ERR "ccdc already registered\n"); 25151444ea3d4f5baa0338297aba7065fd695528a36Muralidharan Karicheri ret = -EINVAL; 2527da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri goto unlock; 2537da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 2547da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 2557da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ccdc_dev = dev; 2567da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheriunlock: 2577da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri mutex_unlock(&ccdc_lock); 2587da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return ret; 2597da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 2607da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan KaricheriEXPORT_SYMBOL(vpfe_register_ccdc_device); 2617da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 2627da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri/* 2637da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * vpfe_unregister_ccdc_device. CCDC module calls this to 2647da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * unregister with vpfe capture 2657da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri */ 2667da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicherivoid vpfe_unregister_ccdc_device(struct ccdc_hw_device *dev) 2677da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 2687da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (NULL == dev) { 2697da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri printk(KERN_ERR "invalid ccdc device ptr\n"); 2707da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return; 2717da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 2727da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 2737da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri printk(KERN_NOTICE "vpfe_unregister_ccdc_device, dev->name = %s\n", 2747da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri dev->name); 2757da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 2767da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (strcmp(dev->name, ccdc_cfg->name)) { 2777da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* ignore this ccdc */ 2787da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return; 2797da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 2807da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 2817da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri mutex_lock(&ccdc_lock); 2827da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ccdc_dev = NULL; 2837da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri mutex_unlock(&ccdc_lock); 2847da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return; 2857da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 2867da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan KaricheriEXPORT_SYMBOL(vpfe_unregister_ccdc_device); 2877da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 2887da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri/* 2897da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * vpfe_get_ccdc_image_format - Get image parameters based on CCDC settings 2907da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri */ 2917da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic int vpfe_get_ccdc_image_format(struct vpfe_device *vpfe_dev, 2927da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct v4l2_format *f) 2937da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 2947da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct v4l2_rect image_win; 2957da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri enum ccdc_buftype buf_type; 2967da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri enum ccdc_frmfmt frm_fmt; 2977da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 2987da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri memset(f, 0, sizeof(*f)); 2997da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri f->type = V4L2_BUF_TYPE_VIDEO_OUTPUT; 3007da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ccdc_dev->hw_ops.get_image_window(&image_win); 3017da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri f->fmt.pix.width = image_win.width; 3027da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri f->fmt.pix.height = image_win.height; 3037da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri f->fmt.pix.bytesperline = ccdc_dev->hw_ops.get_line_length(); 3047da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * 3057da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri f->fmt.pix.height; 3067da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri buf_type = ccdc_dev->hw_ops.get_buftype(); 3077da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri f->fmt.pix.pixelformat = ccdc_dev->hw_ops.get_pixel_format(); 3087da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri frm_fmt = ccdc_dev->hw_ops.get_frame_format(); 3097da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (frm_fmt == CCDC_FRMFMT_PROGRESSIVE) 3107da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri f->fmt.pix.field = V4L2_FIELD_NONE; 3117da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri else if (frm_fmt == CCDC_FRMFMT_INTERLACED) { 3127da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (buf_type == CCDC_BUFTYPE_FLD_INTERLEAVED) 3137da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri f->fmt.pix.field = V4L2_FIELD_INTERLACED; 3147da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri else if (buf_type == CCDC_BUFTYPE_FLD_SEPARATED) 3157da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri f->fmt.pix.field = V4L2_FIELD_SEQ_TB; 3167da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri else { 3177da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(&vpfe_dev->v4l2_dev, "Invalid buf_type\n"); 3187da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return -EINVAL; 3197da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 3207da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } else { 3217da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(&vpfe_dev->v4l2_dev, "Invalid frm_fmt\n"); 3227da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return -EINVAL; 3237da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 3247da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return 0; 3257da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 3267da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 3277da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri/* 3287da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * vpfe_config_ccdc_image_format() 3297da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * For a pix format, configure ccdc to setup the capture 3307da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri */ 3317da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic int vpfe_config_ccdc_image_format(struct vpfe_device *vpfe_dev) 3327da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 3337da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri enum ccdc_frmfmt frm_fmt = CCDC_FRMFMT_INTERLACED; 3347da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri int ret = 0; 3357da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 3367da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (ccdc_dev->hw_ops.set_pixel_format( 3377da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->fmt.fmt.pix.pixelformat) < 0) { 3387da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(&vpfe_dev->v4l2_dev, 3397da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri "couldn't set pix format in ccdc\n"); 3407da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return -EINVAL; 3417da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 3427da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* configure the image window */ 3437da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ccdc_dev->hw_ops.set_image_window(&vpfe_dev->crop); 3447da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 3457da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri switch (vpfe_dev->fmt.fmt.pix.field) { 3467da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri case V4L2_FIELD_INTERLACED: 3477da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* do nothing, since it is default */ 3487da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = ccdc_dev->hw_ops.set_buftype( 3497da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri CCDC_BUFTYPE_FLD_INTERLEAVED); 3507da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri break; 3517da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri case V4L2_FIELD_NONE: 3527da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri frm_fmt = CCDC_FRMFMT_PROGRESSIVE; 3537da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* buffer type only applicable for interlaced scan */ 3547da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri break; 3557da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri case V4L2_FIELD_SEQ_TB: 3567da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = ccdc_dev->hw_ops.set_buftype( 3577da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri CCDC_BUFTYPE_FLD_SEPARATED); 3587da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri break; 3597da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri default: 3607da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return -EINVAL; 3617da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 3627da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 3637da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* set the frame format */ 3647da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (!ret) 3657da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = ccdc_dev->hw_ops.set_frame_format(frm_fmt); 3667da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return ret; 3677da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 3687da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri/* 3697da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * vpfe_config_image_format() 3707da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * For a given standard, this functions sets up the default 3717da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * pix format & crop values in the vpfe device and ccdc. It first 3727da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * starts with defaults based values from the standard table. 373d3ca77595f4b1f17a6d41a89f942fea2b3b17d0cHans Verkuil * It then checks if sub device support g_mbus_fmt and then override the 3747da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * values based on that.Sets crop values to match with scan resolution 3757da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * starting at 0,0. It calls vpfe_config_ccdc_image_format() set the 3767da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * values in ccdc 3777da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri */ 3787da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic int vpfe_config_image_format(struct vpfe_device *vpfe_dev, 3797da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri const v4l2_std_id *std_id) 3807da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 3817da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_subdev_info *sdinfo = vpfe_dev->current_subdev; 382d3ca77595f4b1f17a6d41a89f942fea2b3b17d0cHans Verkuil struct v4l2_mbus_framefmt mbus_fmt; 383d3ca77595f4b1f17a6d41a89f942fea2b3b17d0cHans Verkuil struct v4l2_pix_format *pix = &vpfe_dev->fmt.fmt.pix; 3847da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri int i, ret = 0; 3857da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 3867da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri for (i = 0; i < ARRAY_SIZE(vpfe_standards); i++) { 3877da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (vpfe_standards[i].std_id & *std_id) { 3887da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->std_info.active_pixels = 3897da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_standards[i].width; 3907da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->std_info.active_lines = 3917da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_standards[i].height; 3927da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->std_info.frame_format = 3937da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_standards[i].frame_format; 3947da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->std_index = i; 3957da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri break; 3967da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 3977da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 3987da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 3997da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (i == ARRAY_SIZE(vpfe_standards)) { 4007da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(&vpfe_dev->v4l2_dev, "standard not supported\n"); 4017da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return -EINVAL; 4027da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 4037da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 4047da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->crop.top = 0; 4057da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->crop.left = 0; 4067da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->crop.width = vpfe_dev->std_info.active_pixels; 4077da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->crop.height = vpfe_dev->std_info.active_lines; 408d3ca77595f4b1f17a6d41a89f942fea2b3b17d0cHans Verkuil pix->width = vpfe_dev->crop.width; 409d3ca77595f4b1f17a6d41a89f942fea2b3b17d0cHans Verkuil pix->height = vpfe_dev->crop.height; 4107da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 4117da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* first field and frame format based on standard frame format */ 4127da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (vpfe_dev->std_info.frame_format) { 413d3ca77595f4b1f17a6d41a89f942fea2b3b17d0cHans Verkuil pix->field = V4L2_FIELD_INTERLACED; 4147da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* assume V4L2_PIX_FMT_UYVY as default */ 415d3ca77595f4b1f17a6d41a89f942fea2b3b17d0cHans Verkuil pix->pixelformat = V4L2_PIX_FMT_UYVY; 416d3ca77595f4b1f17a6d41a89f942fea2b3b17d0cHans Verkuil v4l2_fill_mbus_format(&mbus_fmt, pix, 417d3ca77595f4b1f17a6d41a89f942fea2b3b17d0cHans Verkuil V4L2_MBUS_FMT_YUYV10_2X10); 4187da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } else { 419d3ca77595f4b1f17a6d41a89f942fea2b3b17d0cHans Verkuil pix->field = V4L2_FIELD_NONE; 4207da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* assume V4L2_PIX_FMT_SBGGR8 */ 421d3ca77595f4b1f17a6d41a89f942fea2b3b17d0cHans Verkuil pix->pixelformat = V4L2_PIX_FMT_SBGGR8; 422d3ca77595f4b1f17a6d41a89f942fea2b3b17d0cHans Verkuil v4l2_fill_mbus_format(&mbus_fmt, pix, 423d3ca77595f4b1f17a6d41a89f942fea2b3b17d0cHans Verkuil V4L2_MBUS_FMT_SBGGR8_1X8); 4247da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 4257da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 426d3ca77595f4b1f17a6d41a89f942fea2b3b17d0cHans Verkuil /* if sub device supports g_mbus_fmt, override the defaults */ 4277da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = v4l2_device_call_until_err(&vpfe_dev->v4l2_dev, 428d3ca77595f4b1f17a6d41a89f942fea2b3b17d0cHans Verkuil sdinfo->grp_id, video, g_mbus_fmt, &mbus_fmt); 4297da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 4307da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (ret && ret != -ENOIOCTLCMD) { 4317da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(&vpfe_dev->v4l2_dev, 432d3ca77595f4b1f17a6d41a89f942fea2b3b17d0cHans Verkuil "error in getting g_mbus_fmt from sub device\n"); 4337da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return ret; 4347da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 435d3ca77595f4b1f17a6d41a89f942fea2b3b17d0cHans Verkuil v4l2_fill_pix_format(pix, &mbus_fmt); 436d3ca77595f4b1f17a6d41a89f942fea2b3b17d0cHans Verkuil pix->bytesperline = pix->width * 2; 437d3ca77595f4b1f17a6d41a89f942fea2b3b17d0cHans Verkuil pix->sizeimage = pix->bytesperline * pix->height; 4387da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 4397da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* Sets the values in CCDC */ 4407da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = vpfe_config_ccdc_image_format(vpfe_dev); 4417da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (ret) 4427da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return ret; 4437da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 4447da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* Update the values of sizeimage and bytesperline */ 4457da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (!ret) { 446d3ca77595f4b1f17a6d41a89f942fea2b3b17d0cHans Verkuil pix->bytesperline = ccdc_dev->hw_ops.get_line_length(); 447d3ca77595f4b1f17a6d41a89f942fea2b3b17d0cHans Verkuil pix->sizeimage = pix->bytesperline * pix->height; 4487da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 4497da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return ret; 4507da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 4517da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 4527da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic int vpfe_initialize_device(struct vpfe_device *vpfe_dev) 4537da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 4547da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri int ret = 0; 4557da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 4567da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* set first input of current subdevice as the current input */ 4577da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->current_input = 0; 4587da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 4597da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* set default standard */ 4607da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->std_index = 0; 4617da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 4627da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* Configure the default format information */ 4637da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = vpfe_config_image_format(vpfe_dev, 4647da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri &vpfe_standards[vpfe_dev->std_index].std_id); 4657da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (ret) 4667da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return ret; 4677da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 4687da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* now open the ccdc device to initialize it */ 4697da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri mutex_lock(&ccdc_lock); 4707da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (NULL == ccdc_dev) { 4717da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(&vpfe_dev->v4l2_dev, "ccdc device not registered\n"); 4727da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = -ENODEV; 4737da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri goto unlock; 4747da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 4757da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 4767da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (!try_module_get(ccdc_dev->owner)) { 4777da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(&vpfe_dev->v4l2_dev, "Couldn't lock ccdc module\n"); 4787da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = -ENODEV; 4797da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri goto unlock; 4807da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 4817da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = ccdc_dev->hw_ops.open(vpfe_dev->pdev); 4827da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (!ret) 4837da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->initialized = 1; 484085b54a24fd0c7353cd1b2d462879b7a4a4070faVaibhav Hiremath 485085b54a24fd0c7353cd1b2d462879b7a4a4070faVaibhav Hiremath /* Clear all VPFE/CCDC interrupts */ 486085b54a24fd0c7353cd1b2d462879b7a4a4070faVaibhav Hiremath if (vpfe_dev->cfg->clr_intr) 487085b54a24fd0c7353cd1b2d462879b7a4a4070faVaibhav Hiremath vpfe_dev->cfg->clr_intr(-1); 488085b54a24fd0c7353cd1b2d462879b7a4a4070faVaibhav Hiremath 4897da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheriunlock: 4907da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri mutex_unlock(&ccdc_lock); 4917da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return ret; 4927da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 4937da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 4947da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri/* 4957da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * vpfe_open : It creates object of file handle structure and 4967da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * stores it in private_data member of filepointer 4977da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri */ 4987da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic int vpfe_open(struct file *file) 4997da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 5007da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_device *vpfe_dev = video_drvdata(file); 5017da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_fh *fh; 5027da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 5037da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_open\n"); 5047da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 5057da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (!vpfe_dev->cfg->num_subdevs) { 5067da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(&vpfe_dev->v4l2_dev, "No decoder registered\n"); 5077da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return -ENODEV; 5087da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 5097da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 5107da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* Allocate memory for the file handle object */ 5117da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri fh = kmalloc(sizeof(struct vpfe_fh), GFP_KERNEL); 5127da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (NULL == fh) { 5137da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(&vpfe_dev->v4l2_dev, 5147da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri "unable to allocate memory for file handle object\n"); 5157da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return -ENOMEM; 5167da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 5177da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* store pointer to fh in private_data member of file */ 5187da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri file->private_data = fh; 5197da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri fh->vpfe_dev = vpfe_dev; 5207da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri mutex_lock(&vpfe_dev->lock); 5217da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* If decoder is not initialized. initialize it */ 5227da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (!vpfe_dev->initialized) { 5237da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (vpfe_initialize_device(vpfe_dev)) { 5247da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri mutex_unlock(&vpfe_dev->lock); 5257da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return -ENODEV; 5267da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 5277da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 5287da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* Increment device usrs counter */ 5297da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->usrs++; 5307da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* Set io_allowed member to false */ 5317da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri fh->io_allowed = 0; 5327da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* Initialize priority of this instance to default priority */ 5337da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri fh->prio = V4L2_PRIORITY_UNSET; 5347da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_prio_open(&vpfe_dev->prio, &fh->prio); 5357da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri mutex_unlock(&vpfe_dev->lock); 5367da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return 0; 5377da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 5387da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 5397da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic void vpfe_schedule_next_buffer(struct vpfe_device *vpfe_dev) 5407da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 5417da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri unsigned long addr; 5427da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 5437da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->next_frm = list_entry(vpfe_dev->dma_queue.next, 5447da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct videobuf_buffer, queue); 5457da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri list_del(&vpfe_dev->next_frm->queue); 5467da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->next_frm->state = VIDEOBUF_ACTIVE; 5477da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri addr = videobuf_to_dma_contig(vpfe_dev->next_frm); 548844cc0dcb588ee7005c70cffd92ee7a0c1270729Vaibhav Hiremath 549844cc0dcb588ee7005c70cffd92ee7a0c1270729Vaibhav Hiremath ccdc_dev->hw_ops.setfbaddr(addr); 550844cc0dcb588ee7005c70cffd92ee7a0c1270729Vaibhav Hiremath} 551844cc0dcb588ee7005c70cffd92ee7a0c1270729Vaibhav Hiremath 552844cc0dcb588ee7005c70cffd92ee7a0c1270729Vaibhav Hiremathstatic void vpfe_schedule_bottom_field(struct vpfe_device *vpfe_dev) 553844cc0dcb588ee7005c70cffd92ee7a0c1270729Vaibhav Hiremath{ 554844cc0dcb588ee7005c70cffd92ee7a0c1270729Vaibhav Hiremath unsigned long addr; 555844cc0dcb588ee7005c70cffd92ee7a0c1270729Vaibhav Hiremath 556844cc0dcb588ee7005c70cffd92ee7a0c1270729Vaibhav Hiremath addr = videobuf_to_dma_contig(vpfe_dev->cur_frm); 557844cc0dcb588ee7005c70cffd92ee7a0c1270729Vaibhav Hiremath addr += vpfe_dev->field_off; 5587da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ccdc_dev->hw_ops.setfbaddr(addr); 5597da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 5607da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 5617da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic void vpfe_process_buffer_complete(struct vpfe_device *vpfe_dev) 5627da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 5637da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct timeval timevalue; 5647da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 5657da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri do_gettimeofday(&timevalue); 5667da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->cur_frm->ts = timevalue; 5677da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->cur_frm->state = VIDEOBUF_DONE; 5687da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->cur_frm->size = vpfe_dev->fmt.fmt.pix.sizeimage; 5697da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri wake_up_interruptible(&vpfe_dev->cur_frm->done); 5707da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->cur_frm = vpfe_dev->next_frm; 5717da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 5727da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 5737da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri/* ISR for VINT0*/ 5747da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic irqreturn_t vpfe_isr(int irq, void *dev_id) 5757da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 5767da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_device *vpfe_dev = dev_id; 5777da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri enum v4l2_field field; 5787da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri int fid; 5797da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 5807da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "\nStarting vpfe_isr...\n"); 5817da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri field = vpfe_dev->fmt.fmt.pix.field; 5827da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 5837da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* if streaming not started, don't do anything */ 5847da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (!vpfe_dev->started) 585085b54a24fd0c7353cd1b2d462879b7a4a4070faVaibhav Hiremath goto clear_intr; 5867da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 5877da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* only for 6446 this will be applicable */ 5887da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (NULL != ccdc_dev->hw_ops.reset) 5897da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ccdc_dev->hw_ops.reset(); 5907da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 5917da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (field == V4L2_FIELD_NONE) { 5927da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* handle progressive frame capture */ 5937da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, 5947da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri "frame format is progressive...\n"); 5957da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (vpfe_dev->cur_frm != vpfe_dev->next_frm) 5967da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_process_buffer_complete(vpfe_dev); 597085b54a24fd0c7353cd1b2d462879b7a4a4070faVaibhav Hiremath goto clear_intr; 5987da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 5997da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 6007da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* interlaced or TB capture check which field we are in hardware */ 6017da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri fid = ccdc_dev->hw_ops.getfid(); 6027da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 6037da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* switch the software maintained field id */ 6047da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->field_id ^= 1; 6057da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "field id = %x:%x.\n", 6067da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri fid, vpfe_dev->field_id); 6077da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (fid == vpfe_dev->field_id) { 6087da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* we are in-sync here,continue */ 6097da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (fid == 0) { 6107da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* 6117da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * One frame is just being captured. If the next frame 6127da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * is available, release the current frame and move on 6137da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri */ 6147da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (vpfe_dev->cur_frm != vpfe_dev->next_frm) 6157da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_process_buffer_complete(vpfe_dev); 6167da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* 6177da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * based on whether the two fields are stored 6187da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * interleavely or separately in memory, reconfigure 6197da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * the CCDC memory address 6207da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri */ 6217da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (field == V4L2_FIELD_SEQ_TB) { 622844cc0dcb588ee7005c70cffd92ee7a0c1270729Vaibhav Hiremath vpfe_schedule_bottom_field(vpfe_dev); 6237da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 624085b54a24fd0c7353cd1b2d462879b7a4a4070faVaibhav Hiremath goto clear_intr; 6257da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 6267da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* 6277da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * if one field is just being captured configure 6287da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * the next frame get the next frame from the empty 6297da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * queue if no frame is available hold on to the 6307da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * current buffer 6317da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri */ 6327da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri spin_lock(&vpfe_dev->dma_queue_lock); 6337da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (!list_empty(&vpfe_dev->dma_queue) && 6347da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->cur_frm == vpfe_dev->next_frm) 6357da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_schedule_next_buffer(vpfe_dev); 6367da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri spin_unlock(&vpfe_dev->dma_queue_lock); 6377da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } else if (fid == 0) { 6387da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* 6397da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * out of sync. Recover from any hardware out-of-sync. 6407da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * May loose one frame 6417da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri */ 6427da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->field_id = fid; 6437da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 644085b54a24fd0c7353cd1b2d462879b7a4a4070faVaibhav Hiremathclear_intr: 645085b54a24fd0c7353cd1b2d462879b7a4a4070faVaibhav Hiremath if (vpfe_dev->cfg->clr_intr) 646085b54a24fd0c7353cd1b2d462879b7a4a4070faVaibhav Hiremath vpfe_dev->cfg->clr_intr(irq); 647085b54a24fd0c7353cd1b2d462879b7a4a4070faVaibhav Hiremath 6487da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return IRQ_HANDLED; 6497da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 6507da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 6517da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri/* vdint1_isr - isr handler for VINT1 interrupt */ 6527da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic irqreturn_t vdint1_isr(int irq, void *dev_id) 6537da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 6547da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_device *vpfe_dev = dev_id; 6557da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 6567da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "\nInside vdint1_isr...\n"); 6577da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 6587da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* if streaming not started, don't do anything */ 659085b54a24fd0c7353cd1b2d462879b7a4a4070faVaibhav Hiremath if (!vpfe_dev->started) { 660085b54a24fd0c7353cd1b2d462879b7a4a4070faVaibhav Hiremath if (vpfe_dev->cfg->clr_intr) 661085b54a24fd0c7353cd1b2d462879b7a4a4070faVaibhav Hiremath vpfe_dev->cfg->clr_intr(irq); 6627da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return IRQ_HANDLED; 663085b54a24fd0c7353cd1b2d462879b7a4a4070faVaibhav Hiremath } 6647da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 6657da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri spin_lock(&vpfe_dev->dma_queue_lock); 6667da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if ((vpfe_dev->fmt.fmt.pix.field == V4L2_FIELD_NONE) && 6677da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri !list_empty(&vpfe_dev->dma_queue) && 6687da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->cur_frm == vpfe_dev->next_frm) 6697da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_schedule_next_buffer(vpfe_dev); 6707da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri spin_unlock(&vpfe_dev->dma_queue_lock); 671085b54a24fd0c7353cd1b2d462879b7a4a4070faVaibhav Hiremath 672085b54a24fd0c7353cd1b2d462879b7a4a4070faVaibhav Hiremath if (vpfe_dev->cfg->clr_intr) 673085b54a24fd0c7353cd1b2d462879b7a4a4070faVaibhav Hiremath vpfe_dev->cfg->clr_intr(irq); 674085b54a24fd0c7353cd1b2d462879b7a4a4070faVaibhav Hiremath 6757da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return IRQ_HANDLED; 6767da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 6777da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 6787da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic void vpfe_detach_irq(struct vpfe_device *vpfe_dev) 6797da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 6807da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri enum ccdc_frmfmt frame_format; 6817da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 6827da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri frame_format = ccdc_dev->hw_ops.get_frame_format(); 6837da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (frame_format == CCDC_FRMFMT_PROGRESSIVE) 6841ead696b4c1b719eeae313618bca89e7b37c7d9bVaibhav Hiremath free_irq(vpfe_dev->ccdc_irq1, vpfe_dev); 6857da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 6867da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 6877da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic int vpfe_attach_irq(struct vpfe_device *vpfe_dev) 6887da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 6897da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri enum ccdc_frmfmt frame_format; 6907da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 6917da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri frame_format = ccdc_dev->hw_ops.get_frame_format(); 6927da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (frame_format == CCDC_FRMFMT_PROGRESSIVE) { 6937da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return request_irq(vpfe_dev->ccdc_irq1, vdint1_isr, 6947da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri IRQF_DISABLED, "vpfe_capture1", 6957da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev); 6967da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 6977da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return 0; 6987da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 6997da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 7007da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri/* vpfe_stop_ccdc_capture: stop streaming in ccdc/isif */ 7017da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic void vpfe_stop_ccdc_capture(struct vpfe_device *vpfe_dev) 7027da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 7037da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->started = 0; 7047da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ccdc_dev->hw_ops.enable(0); 7057da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (ccdc_dev->hw_ops.enable_out_to_sdram) 7067da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ccdc_dev->hw_ops.enable_out_to_sdram(0); 7077da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 7087da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 7097da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri/* 7107da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * vpfe_release : This function deletes buffer queue, frees the 7117da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * buffers and the vpfe file handle 7127da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri */ 7137da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic int vpfe_release(struct file *file) 7147da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 7157da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_device *vpfe_dev = video_drvdata(file); 7167da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_fh *fh = file->private_data; 7177da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_subdev_info *sdinfo; 7187da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri int ret; 7197da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 7207da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_release\n"); 7217da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 7227da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* Get the device lock */ 7237da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri mutex_lock(&vpfe_dev->lock); 7247da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* if this instance is doing IO */ 7257da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (fh->io_allowed) { 7267da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (vpfe_dev->started) { 7277da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri sdinfo = vpfe_dev->current_subdev; 7287da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = v4l2_device_call_until_err(&vpfe_dev->v4l2_dev, 7297da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri sdinfo->grp_id, 7307da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri video, s_stream, 0); 7317da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (ret && (ret != -ENOIOCTLCMD)) 7327da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(&vpfe_dev->v4l2_dev, 7337da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri "stream off failed in subdev\n"); 7347da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_stop_ccdc_capture(vpfe_dev); 7357da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_detach_irq(vpfe_dev); 7367da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri videobuf_streamoff(&vpfe_dev->buffer_queue); 7377da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 7387da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->io_usrs = 0; 7397da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->numbuffers = config_params.numbuffers; 7407da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 7417da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 7427da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* Decrement device usrs counter */ 7437da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->usrs--; 7447da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* Close the priority */ 745ffb4877ba013f94322083f77cbb05b35c2a218aaHans Verkuil v4l2_prio_close(&vpfe_dev->prio, fh->prio); 7467da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* If this is the last file handle */ 7477da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (!vpfe_dev->usrs) { 7487da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->initialized = 0; 7497da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (ccdc_dev->hw_ops.close) 7507da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ccdc_dev->hw_ops.close(vpfe_dev->pdev); 7517da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri module_put(ccdc_dev->owner); 7527da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 7537da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri mutex_unlock(&vpfe_dev->lock); 7547da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri file->private_data = NULL; 7557da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* Free memory allocated to file handle object */ 7567da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri kfree(fh); 7577da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return 0; 7587da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 7597da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 7607da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri/* 7617da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * vpfe_mmap : It is used to map kernel space buffers 7627da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * into user spaces 7637da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri */ 7647da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic int vpfe_mmap(struct file *file, struct vm_area_struct *vma) 7657da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 7667da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* Get the device object and file handle object */ 7677da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_device *vpfe_dev = video_drvdata(file); 7687da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 7697da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_mmap\n"); 7707da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 7717da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return videobuf_mmap_mapper(&vpfe_dev->buffer_queue, vma); 7727da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 7737da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 7747da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri/* 7757da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * vpfe_poll: It is used for select/poll system call 7767da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri */ 7777da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic unsigned int vpfe_poll(struct file *file, poll_table *wait) 7787da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 7797da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_device *vpfe_dev = video_drvdata(file); 7807da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 7817da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_poll\n"); 7827da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 7837da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (vpfe_dev->started) 7847da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return videobuf_poll_stream(file, 7857da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri &vpfe_dev->buffer_queue, wait); 7867da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return 0; 7877da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 7887da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 7897da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri/* vpfe capture driver file operations */ 7907da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic const struct v4l2_file_operations vpfe_fops = { 7917da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .owner = THIS_MODULE, 7927da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .open = vpfe_open, 7937da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .release = vpfe_release, 7947da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .unlocked_ioctl = video_ioctl2, 7957da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .mmap = vpfe_mmap, 7967da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .poll = vpfe_poll 7977da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri}; 7987da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 7997da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri/* 8007da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * vpfe_check_format() 8017da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * This function adjust the input pixel format as per hardware 8027da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * capabilities and update the same in pixfmt. 8037da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * Following algorithm used :- 8047da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * 8057da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * If given pixformat is not in the vpfe list of pix formats or not 8067da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * supported by the hardware, current value of pixformat in the device 8077da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * is used 8087da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * If given field is not supported, then current field is used. If field 8097da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * is different from current, then it is matched with that from sub device. 8107da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * Minimum height is 2 lines for interlaced or tb field and 1 line for 8117da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * progressive. Maximum height is clamped to active active lines of scan 8127da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * Minimum width is 32 bytes in memory and width is clamped to active 8137da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * pixels of scan. 8147da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * bytesperline is a multiple of 32. 8157da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri */ 8167da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic const struct vpfe_pixel_format * 8177da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_check_format(struct vpfe_device *vpfe_dev, 8187da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct v4l2_pix_format *pixfmt) 8197da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 8207da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri u32 min_height = 1, min_width = 32, max_width, max_height; 8217da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri const struct vpfe_pixel_format *vpfe_pix_fmt; 8227da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri u32 pix; 8237da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri int temp, found; 8247da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 8257da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_pix_fmt = vpfe_lookup_pix_format(pixfmt->pixelformat); 8267da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (NULL == vpfe_pix_fmt) { 8277da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* 8287da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * use current pixel format in the vpfe device. We 8297da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * will find this pix format in the table 8307da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri */ 8317da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri pixfmt->pixelformat = vpfe_dev->fmt.fmt.pix.pixelformat; 8327da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_pix_fmt = vpfe_lookup_pix_format(pixfmt->pixelformat); 8337da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 8347da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 8357da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* check if hw supports it */ 8367da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri temp = 0; 8377da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri found = 0; 8387da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri while (ccdc_dev->hw_ops.enum_pix(&pix, temp) >= 0) { 8397da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (vpfe_pix_fmt->fmtdesc.pixelformat == pix) { 8407da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri found = 1; 8417da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri break; 8427da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 8437da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri temp++; 8447da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 8457da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 8467da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (!found) { 8477da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* use current pixel format */ 8487da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri pixfmt->pixelformat = vpfe_dev->fmt.fmt.pix.pixelformat; 8497da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* 8507da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * Since this is currently used in the vpfe device, we 8517da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * will find this pix format in the table 8527da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri */ 8537da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_pix_fmt = vpfe_lookup_pix_format(pixfmt->pixelformat); 8547da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 8557da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 8567da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* check what field format is supported */ 8577da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (pixfmt->field == V4L2_FIELD_ANY) { 8587da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* if field is any, use current value as default */ 8597da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri pixfmt->field = vpfe_dev->fmt.fmt.pix.field; 8607da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 8617da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 8627da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* 8637da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * if field is not same as current field in the vpfe device 8647da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * try matching the field with the sub device field 8657da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri */ 8667da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (vpfe_dev->fmt.fmt.pix.field != pixfmt->field) { 8677da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* 8687da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * If field value is not in the supported fields, use current 8697da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * field used in the device as default 8707da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri */ 8717da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri switch (pixfmt->field) { 8727da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri case V4L2_FIELD_INTERLACED: 8737da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri case V4L2_FIELD_SEQ_TB: 8747da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* if sub device is supporting progressive, use that */ 8757da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (!vpfe_dev->std_info.frame_format) 8767da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri pixfmt->field = V4L2_FIELD_NONE; 8777da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri break; 8787da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri case V4L2_FIELD_NONE: 8797da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (vpfe_dev->std_info.frame_format) 8807da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri pixfmt->field = V4L2_FIELD_INTERLACED; 8817da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri break; 8827da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 8837da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri default: 8847da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* use current field as default */ 8857da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri pixfmt->field = vpfe_dev->fmt.fmt.pix.field; 8867da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri break; 8877da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 8887da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 8897da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 8907da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* Now adjust image resolutions supported */ 8917da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (pixfmt->field == V4L2_FIELD_INTERLACED || 8927da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri pixfmt->field == V4L2_FIELD_SEQ_TB) 8937da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri min_height = 2; 8947da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 8957da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri max_width = vpfe_dev->std_info.active_pixels; 8967da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri max_height = vpfe_dev->std_info.active_lines; 8977da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri min_width /= vpfe_pix_fmt->bpp; 8987da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 8997da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_info(&vpfe_dev->v4l2_dev, "width = %d, height = %d, bpp = %d\n", 9007da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri pixfmt->width, pixfmt->height, vpfe_pix_fmt->bpp); 9017da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 9027da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri pixfmt->width = clamp((pixfmt->width), min_width, max_width); 9037da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri pixfmt->height = clamp((pixfmt->height), min_height, max_height); 9047da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 9057da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* If interlaced, adjust height to be a multiple of 2 */ 9067da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (pixfmt->field == V4L2_FIELD_INTERLACED) 9077da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri pixfmt->height &= (~1); 9087da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* 9097da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * recalculate bytesperline and sizeimage since width 9107da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * and height might have changed 9117da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri */ 9127da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri pixfmt->bytesperline = (((pixfmt->width * vpfe_pix_fmt->bpp) + 31) 9137da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri & ~31); 9147da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (pixfmt->pixelformat == V4L2_PIX_FMT_NV12) 9157da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri pixfmt->sizeimage = 9167da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri pixfmt->bytesperline * pixfmt->height + 9177da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ((pixfmt->bytesperline * pixfmt->height) >> 1); 9187da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri else 9197da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri pixfmt->sizeimage = pixfmt->bytesperline * pixfmt->height; 9207da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 9217da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_info(&vpfe_dev->v4l2_dev, "adjusted width = %d, height =" 9227da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri " %d, bpp = %d, bytesperline = %d, sizeimage = %d\n", 9237da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri pixfmt->width, pixfmt->height, vpfe_pix_fmt->bpp, 9247da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri pixfmt->bytesperline, pixfmt->sizeimage); 9257da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return vpfe_pix_fmt; 9267da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 9277da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 9287da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic int vpfe_querycap(struct file *file, void *priv, 9297da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct v4l2_capability *cap) 9307da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 9317da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_device *vpfe_dev = video_drvdata(file); 9327da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 9337da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_querycap\n"); 9347da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 9357da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri cap->version = VPFE_CAPTURE_VERSION_CODE; 9367da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; 9377da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri strlcpy(cap->driver, CAPTURE_DRV_NAME, sizeof(cap->driver)); 9387da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri strlcpy(cap->bus_info, "VPFE", sizeof(cap->bus_info)); 9397da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri strlcpy(cap->card, vpfe_dev->cfg->card_name, sizeof(cap->card)); 9407da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return 0; 9417da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 9427da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 9437da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic int vpfe_g_fmt_vid_cap(struct file *file, void *priv, 9447da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct v4l2_format *fmt) 9457da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 9467da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_device *vpfe_dev = video_drvdata(file); 9477da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri int ret = 0; 9487da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 9497da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_g_fmt_vid_cap\n"); 9507da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* Fill in the information about format */ 9517da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri *fmt = vpfe_dev->fmt; 9527da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return ret; 9537da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 9547da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 9557da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic int vpfe_enum_fmt_vid_cap(struct file *file, void *priv, 9567da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct v4l2_fmtdesc *fmt) 9577da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 9587da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_device *vpfe_dev = video_drvdata(file); 9597da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri const struct vpfe_pixel_format *pix_fmt; 9607da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri int temp_index; 9617da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri u32 pix; 9627da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 9637da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_enum_fmt_vid_cap\n"); 9647da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 9657da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (ccdc_dev->hw_ops.enum_pix(&pix, fmt->index) < 0) 9667da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return -EINVAL; 9677da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 9687da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* Fill in the information about format */ 9697da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri pix_fmt = vpfe_lookup_pix_format(pix); 9707da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (NULL != pix_fmt) { 9717da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri temp_index = fmt->index; 9727da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri *fmt = pix_fmt->fmtdesc; 9737da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri fmt->index = temp_index; 9747da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return 0; 9757da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 9767da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return -EINVAL; 9777da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 9787da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 9797da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic int vpfe_s_fmt_vid_cap(struct file *file, void *priv, 9807da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct v4l2_format *fmt) 9817da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 9827da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_device *vpfe_dev = video_drvdata(file); 9837da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri const struct vpfe_pixel_format *pix_fmts; 9847da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri int ret = 0; 9857da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 9867da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_s_fmt_vid_cap\n"); 9877da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 9887da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* If streaming is started, return error */ 9897da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (vpfe_dev->started) { 9907da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(&vpfe_dev->v4l2_dev, "Streaming is started\n"); 9917da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return -EBUSY; 9927da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 9937da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 9947da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* Check for valid frame format */ 9957da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri pix_fmts = vpfe_check_format(vpfe_dev, &fmt->fmt.pix); 9967da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 9977da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (NULL == pix_fmts) 9987da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return -EINVAL; 9997da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 10007da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* store the pixel format in the device object */ 10017da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = mutex_lock_interruptible(&vpfe_dev->lock); 10027da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (ret) 10037da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return ret; 10047da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 10057da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* First detach any IRQ if currently attached */ 10067da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_detach_irq(vpfe_dev); 10077da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->fmt = *fmt; 10087da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* set image capture parameters in the ccdc */ 10097da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = vpfe_config_ccdc_image_format(vpfe_dev); 10107da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri mutex_unlock(&vpfe_dev->lock); 10117da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return ret; 10127da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 10137da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 10147da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic int vpfe_try_fmt_vid_cap(struct file *file, void *priv, 10157da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct v4l2_format *f) 10167da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 10177da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_device *vpfe_dev = video_drvdata(file); 10187da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri const struct vpfe_pixel_format *pix_fmts; 10197da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 10207da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_try_fmt_vid_cap\n"); 10217da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 10227da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri pix_fmts = vpfe_check_format(vpfe_dev, &f->fmt.pix); 10237da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (NULL == pix_fmts) 10247da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return -EINVAL; 10257da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return 0; 10267da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 10277da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 10287da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri/* 10297da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * vpfe_get_subdev_input_index - Get subdev index and subdev input index for a 10307da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * given app input index 10317da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri */ 10327da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic int vpfe_get_subdev_input_index(struct vpfe_device *vpfe_dev, 10337da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri int *subdev_index, 10347da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri int *subdev_input_index, 10357da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri int app_input_index) 10367da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 10377da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_config *cfg = vpfe_dev->cfg; 10387da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_subdev_info *sdinfo; 10397da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri int i, j = 0; 10407da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 10417da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri for (i = 0; i < cfg->num_subdevs; i++) { 10427da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri sdinfo = &cfg->sub_devs[i]; 10437da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (app_input_index < (j + sdinfo->num_inputs)) { 10447da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri *subdev_index = i; 10457da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri *subdev_input_index = app_input_index - j; 10467da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return 0; 10477da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 10487da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri j += sdinfo->num_inputs; 10497da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 10507da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return -EINVAL; 10517da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 10527da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 10537da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri/* 10547da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * vpfe_get_app_input - Get app input index for a given subdev input index 10557da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * driver stores the input index of the current sub device and translate it 10567da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * when application request the current input 10577da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri */ 10587da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic int vpfe_get_app_input_index(struct vpfe_device *vpfe_dev, 10597da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri int *app_input_index) 10607da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 10617da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_config *cfg = vpfe_dev->cfg; 10627da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_subdev_info *sdinfo; 10637da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri int i, j = 0; 10647da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 10657da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri for (i = 0; i < cfg->num_subdevs; i++) { 10667da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri sdinfo = &cfg->sub_devs[i]; 10677da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (!strcmp(sdinfo->name, vpfe_dev->current_subdev->name)) { 10687da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (vpfe_dev->current_input >= sdinfo->num_inputs) 10697da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return -1; 10707da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri *app_input_index = j + vpfe_dev->current_input; 10717da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return 0; 10727da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 10737da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri j += sdinfo->num_inputs; 10747da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 10757da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return -EINVAL; 10767da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 10777da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 10787da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic int vpfe_enum_input(struct file *file, void *priv, 10797da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct v4l2_input *inp) 10807da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 10817da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_device *vpfe_dev = video_drvdata(file); 10827da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_subdev_info *sdinfo; 10837da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri int subdev, index ; 10847da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 10857da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_enum_input\n"); 10867da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 10877da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (vpfe_get_subdev_input_index(vpfe_dev, 10887da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri &subdev, 10897da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri &index, 10907da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri inp->index) < 0) { 10917da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(&vpfe_dev->v4l2_dev, "input information not found" 10927da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri " for the subdev\n"); 10937da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return -EINVAL; 10947da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 10957da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri sdinfo = &vpfe_dev->cfg->sub_devs[subdev]; 10967da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri memcpy(inp, &sdinfo->inputs[index], sizeof(struct v4l2_input)); 10977da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return 0; 10987da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 10997da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 11007da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic int vpfe_g_input(struct file *file, void *priv, unsigned int *index) 11017da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 11027da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_device *vpfe_dev = video_drvdata(file); 11037da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 11047da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_g_input\n"); 11057da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 11067da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return vpfe_get_app_input_index(vpfe_dev, index); 11077da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 11087da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 11097da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 11107da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic int vpfe_s_input(struct file *file, void *priv, unsigned int index) 11117da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 11127da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_device *vpfe_dev = video_drvdata(file); 11137da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_subdev_info *sdinfo; 11147da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri int subdev_index, inp_index; 11157da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_route *route; 11167da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri u32 input = 0, output = 0; 11177da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri int ret = -EINVAL; 11187da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 11197da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_s_input\n"); 11207da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 11217da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = mutex_lock_interruptible(&vpfe_dev->lock); 11227da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (ret) 11237da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return ret; 11247da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 11257da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* 11267da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * If streaming is started return device busy 11277da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * error 11287da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri */ 11297da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (vpfe_dev->started) { 11307da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(&vpfe_dev->v4l2_dev, "Streaming is on\n"); 11317da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = -EBUSY; 11327da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri goto unlock_out; 11337da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 11347da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 11357da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (vpfe_get_subdev_input_index(vpfe_dev, 11367da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri &subdev_index, 11377da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri &inp_index, 11387da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri index) < 0) { 11397da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(&vpfe_dev->v4l2_dev, "invalid input index\n"); 11407da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri goto unlock_out; 11417da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 11427da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 11437da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri sdinfo = &vpfe_dev->cfg->sub_devs[subdev_index]; 11447da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri route = &sdinfo->routes[inp_index]; 11457da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (route && sdinfo->can_route) { 11467da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri input = route->input; 11477da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri output = route->output; 11487da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 11497da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 11507da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = v4l2_device_call_until_err(&vpfe_dev->v4l2_dev, sdinfo->grp_id, 11517da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri video, s_routing, input, output, 0); 11527da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 11537da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (ret) { 11547da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(&vpfe_dev->v4l2_dev, 11557da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri "vpfe_doioctl:error in setting input in decoder\n"); 11567da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = -EINVAL; 11577da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri goto unlock_out; 11587da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 11597da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->current_subdev = sdinfo; 11607da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->current_input = index; 11617da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->std_index = 0; 11627da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 11637da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* set the bus/interface parameter for the sub device in ccdc */ 11647da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = ccdc_dev->hw_ops.set_hw_if_params(&sdinfo->ccdc_if_params); 11657da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (ret) 11667da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri goto unlock_out; 11677da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 11687da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* set the default image parameters in the device */ 11697da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = vpfe_config_image_format(vpfe_dev, 11707da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri &vpfe_standards[vpfe_dev->std_index].std_id); 11717da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheriunlock_out: 11727da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri mutex_unlock(&vpfe_dev->lock); 11737da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return ret; 11747da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 11757da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 11767da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic int vpfe_querystd(struct file *file, void *priv, v4l2_std_id *std_id) 11777da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 11787da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_device *vpfe_dev = video_drvdata(file); 11797da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_subdev_info *sdinfo; 11807da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri int ret = 0; 11817da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 11827da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_querystd\n"); 11837da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 11847da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = mutex_lock_interruptible(&vpfe_dev->lock); 11857da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri sdinfo = vpfe_dev->current_subdev; 11867da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (ret) 11877da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return ret; 11887da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* Call querystd function of decoder device */ 11897da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = v4l2_device_call_until_err(&vpfe_dev->v4l2_dev, sdinfo->grp_id, 11907da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri video, querystd, std_id); 11917da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri mutex_unlock(&vpfe_dev->lock); 11927da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return ret; 11937da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 11947da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 11957da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic int vpfe_s_std(struct file *file, void *priv, v4l2_std_id *std_id) 11967da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 11977da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_device *vpfe_dev = video_drvdata(file); 11987da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_subdev_info *sdinfo; 11997da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri int ret = 0; 12007da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 12017da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_s_std\n"); 12027da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 12037da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* Call decoder driver function to set the standard */ 12047da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = mutex_lock_interruptible(&vpfe_dev->lock); 12057da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (ret) 12067da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return ret; 12077da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 12087da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri sdinfo = vpfe_dev->current_subdev; 12097da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* If streaming is started, return device busy error */ 12107da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (vpfe_dev->started) { 12117da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(&vpfe_dev->v4l2_dev, "streaming is started\n"); 12127da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = -EBUSY; 12137da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri goto unlock_out; 12147da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 12157da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 12167da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = v4l2_device_call_until_err(&vpfe_dev->v4l2_dev, sdinfo->grp_id, 12177da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri core, s_std, *std_id); 12187da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (ret < 0) { 12197da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(&vpfe_dev->v4l2_dev, "Failed to set standard\n"); 12207da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri goto unlock_out; 12217da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 12227da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = vpfe_config_image_format(vpfe_dev, std_id); 12237da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 12247da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheriunlock_out: 12257da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri mutex_unlock(&vpfe_dev->lock); 12267da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return ret; 12277da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 12287da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 12297da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic int vpfe_g_std(struct file *file, void *priv, v4l2_std_id *std_id) 12307da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 12317da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_device *vpfe_dev = video_drvdata(file); 12327da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 12337da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_g_std\n"); 12347da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 12357da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri *std_id = vpfe_standards[vpfe_dev->std_index].std_id; 12367da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return 0; 12377da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 12387da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri/* 12397da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * Videobuf operations 12407da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri */ 12417da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic int vpfe_videobuf_setup(struct videobuf_queue *vq, 12427da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri unsigned int *count, 12437da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri unsigned int *size) 12447da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 12457da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_fh *fh = vq->priv_data; 12467da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_device *vpfe_dev = fh->vpfe_dev; 12477da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 12487da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_buffer_setup\n"); 1249844cc0dcb588ee7005c70cffd92ee7a0c1270729Vaibhav Hiremath *size = vpfe_dev->fmt.fmt.pix.sizeimage; 1250844cc0dcb588ee7005c70cffd92ee7a0c1270729Vaibhav Hiremath if (vpfe_dev->memory == V4L2_MEMORY_MMAP && 1251844cc0dcb588ee7005c70cffd92ee7a0c1270729Vaibhav Hiremath vpfe_dev->fmt.fmt.pix.sizeimage > config_params.device_bufsize) 1252844cc0dcb588ee7005c70cffd92ee7a0c1270729Vaibhav Hiremath *size = config_params.device_bufsize; 12537da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 12547da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (*count < config_params.min_numbuffers) 12557da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri *count = config_params.min_numbuffers; 12567da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, 12577da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri "count=%d, size=%d\n", *count, *size); 12587da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return 0; 12597da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 12607da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 12617da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic int vpfe_videobuf_prepare(struct videobuf_queue *vq, 12627da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct videobuf_buffer *vb, 12637da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri enum v4l2_field field) 12647da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 12657da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_fh *fh = vq->priv_data; 12667da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_device *vpfe_dev = fh->vpfe_dev; 1267844cc0dcb588ee7005c70cffd92ee7a0c1270729Vaibhav Hiremath unsigned long addr; 1268844cc0dcb588ee7005c70cffd92ee7a0c1270729Vaibhav Hiremath int ret; 12697da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 12707da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_buffer_prepare\n"); 12717da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 12727da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* If buffer is not initialized, initialize it */ 12737da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (VIDEOBUF_NEEDS_INIT == vb->state) { 12747da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vb->width = vpfe_dev->fmt.fmt.pix.width; 12757da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vb->height = vpfe_dev->fmt.fmt.pix.height; 12767da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vb->size = vpfe_dev->fmt.fmt.pix.sizeimage; 12777da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vb->field = field; 1278844cc0dcb588ee7005c70cffd92ee7a0c1270729Vaibhav Hiremath 1279b1dc614a81258eb7ff482892e7bc894f1089c144Joe Perches ret = videobuf_iolock(vq, vb, NULL); 1280844cc0dcb588ee7005c70cffd92ee7a0c1270729Vaibhav Hiremath if (ret < 0) 1281844cc0dcb588ee7005c70cffd92ee7a0c1270729Vaibhav Hiremath return ret; 1282844cc0dcb588ee7005c70cffd92ee7a0c1270729Vaibhav Hiremath 1283844cc0dcb588ee7005c70cffd92ee7a0c1270729Vaibhav Hiremath addr = videobuf_to_dma_contig(vb); 1284844cc0dcb588ee7005c70cffd92ee7a0c1270729Vaibhav Hiremath /* Make sure user addresses are aligned to 32 bytes */ 1285844cc0dcb588ee7005c70cffd92ee7a0c1270729Vaibhav Hiremath if (!ALIGN(addr, 32)) 1286844cc0dcb588ee7005c70cffd92ee7a0c1270729Vaibhav Hiremath return -EINVAL; 1287844cc0dcb588ee7005c70cffd92ee7a0c1270729Vaibhav Hiremath 1288844cc0dcb588ee7005c70cffd92ee7a0c1270729Vaibhav Hiremath vb->state = VIDEOBUF_PREPARED; 12897da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 12907da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return 0; 12917da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 12927da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 12937da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic void vpfe_videobuf_queue(struct videobuf_queue *vq, 12947da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct videobuf_buffer *vb) 12957da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 12967da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* Get the file handle object and device object */ 12977da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_fh *fh = vq->priv_data; 12987da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_device *vpfe_dev = fh->vpfe_dev; 12997da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri unsigned long flags; 13007da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 13017da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_buffer_queue\n"); 13027da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 13037da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* add the buffer to the DMA queue */ 13047da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri spin_lock_irqsave(&vpfe_dev->dma_queue_lock, flags); 13057da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri list_add_tail(&vb->queue, &vpfe_dev->dma_queue); 13067da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri spin_unlock_irqrestore(&vpfe_dev->dma_queue_lock, flags); 13077da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 13087da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* Change state of the buffer */ 13097da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vb->state = VIDEOBUF_QUEUED; 13107da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 13117da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 13127da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic void vpfe_videobuf_release(struct videobuf_queue *vq, 13137da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct videobuf_buffer *vb) 13147da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 13157da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_fh *fh = vq->priv_data; 13167da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_device *vpfe_dev = fh->vpfe_dev; 13177da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri unsigned long flags; 13187da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 13197da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_videobuf_release\n"); 13207da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 13217da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* 13227da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * We need to flush the buffer from the dma queue since 13237da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * they are de-allocated 13247da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri */ 13257da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri spin_lock_irqsave(&vpfe_dev->dma_queue_lock, flags); 13267da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri INIT_LIST_HEAD(&vpfe_dev->dma_queue); 13277da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri spin_unlock_irqrestore(&vpfe_dev->dma_queue_lock, flags); 13287da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri videobuf_dma_contig_free(vq, vb); 13297da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vb->state = VIDEOBUF_NEEDS_INIT; 13307da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 13317da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 13327da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic struct videobuf_queue_ops vpfe_videobuf_qops = { 13337da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .buf_setup = vpfe_videobuf_setup, 13347da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .buf_prepare = vpfe_videobuf_prepare, 13357da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .buf_queue = vpfe_videobuf_queue, 13367da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .buf_release = vpfe_videobuf_release, 13377da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri}; 13387da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 13397da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri/* 13407da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * vpfe_reqbufs. currently support REQBUF only once opening 13417da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * the device. 13427da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri */ 13437da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic int vpfe_reqbufs(struct file *file, void *priv, 13447da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct v4l2_requestbuffers *req_buf) 13457da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 13467da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_device *vpfe_dev = video_drvdata(file); 13477da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_fh *fh = file->private_data; 13487da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri int ret = 0; 13497da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 13507da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_reqbufs\n"); 13517da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 13527da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (V4L2_BUF_TYPE_VIDEO_CAPTURE != req_buf->type) { 13537da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(&vpfe_dev->v4l2_dev, "Invalid buffer type\n"); 13547da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return -EINVAL; 13557da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 13567da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 13577da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = mutex_lock_interruptible(&vpfe_dev->lock); 13587da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (ret) 13597da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return ret; 13607da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 13617da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (vpfe_dev->io_usrs != 0) { 13627da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(&vpfe_dev->v4l2_dev, "Only one IO user allowed\n"); 13637da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = -EBUSY; 13647da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri goto unlock_out; 13657da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 13667da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 13677da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->memory = req_buf->memory; 13687da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri videobuf_queue_dma_contig_init(&vpfe_dev->buffer_queue, 13697da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri &vpfe_videobuf_qops, 1370204e6ea981ac46974508ddf403dbb72dc804dcb3Vaibhav Hiremath vpfe_dev->pdev, 13717da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri &vpfe_dev->irqlock, 13727da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri req_buf->type, 13737da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->fmt.fmt.pix.field, 13747da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri sizeof(struct videobuf_buffer), 1375e3cfd447d01cf723ccda0ad6bfa2e85b73d3d747Hans Verkuil fh, NULL); 13767da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 13777da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri fh->io_allowed = 1; 13787da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->io_usrs = 1; 13797da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri INIT_LIST_HEAD(&vpfe_dev->dma_queue); 13807da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = videobuf_reqbufs(&vpfe_dev->buffer_queue, req_buf); 13817da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheriunlock_out: 13827da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri mutex_unlock(&vpfe_dev->lock); 13837da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return ret; 13847da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 13857da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 13867da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic int vpfe_querybuf(struct file *file, void *priv, 13877da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct v4l2_buffer *buf) 13887da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 13897da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_device *vpfe_dev = video_drvdata(file); 13907da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 13917da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_querybuf\n"); 13927da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 13937da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (V4L2_BUF_TYPE_VIDEO_CAPTURE != buf->type) { 13947da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(&vpfe_dev->v4l2_dev, "Invalid buf type\n"); 13957da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return -EINVAL; 13967da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 13977da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 13987da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (vpfe_dev->memory != V4L2_MEMORY_MMAP) { 13997da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(&vpfe_dev->v4l2_dev, "Invalid memory\n"); 14007da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return -EINVAL; 14017da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 14027da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* Call videobuf_querybuf to get information */ 14037da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return videobuf_querybuf(&vpfe_dev->buffer_queue, buf); 14047da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 14057da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 14067da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic int vpfe_qbuf(struct file *file, void *priv, 14077da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct v4l2_buffer *p) 14087da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 14097da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_device *vpfe_dev = video_drvdata(file); 14107da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_fh *fh = file->private_data; 14117da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 14127da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_qbuf\n"); 14137da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 14147da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (V4L2_BUF_TYPE_VIDEO_CAPTURE != p->type) { 14157da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(&vpfe_dev->v4l2_dev, "Invalid buf type\n"); 14167da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return -EINVAL; 14177da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 14187da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 14197da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* 14207da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * If this file handle is not allowed to do IO, 14217da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * return error 14227da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri */ 14237da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (!fh->io_allowed) { 14247da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(&vpfe_dev->v4l2_dev, "fh->io_allowed\n"); 14257da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return -EACCES; 14267da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 14277da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return videobuf_qbuf(&vpfe_dev->buffer_queue, p); 14287da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 14297da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 14307da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic int vpfe_dqbuf(struct file *file, void *priv, 14317da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct v4l2_buffer *buf) 14327da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 14337da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_device *vpfe_dev = video_drvdata(file); 14347da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 14357da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_dqbuf\n"); 14367da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 14377da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (V4L2_BUF_TYPE_VIDEO_CAPTURE != buf->type) { 14387da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(&vpfe_dev->v4l2_dev, "Invalid buf type\n"); 14397da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return -EINVAL; 14407da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 14417da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return videobuf_dqbuf(&vpfe_dev->buffer_queue, 14427da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri buf, file->f_flags & O_NONBLOCK); 14437da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 14447da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 1445d73bfc5fe625f6962d0ced84066e201249f14e53Vaibhav Hiremathstatic int vpfe_queryctrl(struct file *file, void *priv, 1446d73bfc5fe625f6962d0ced84066e201249f14e53Vaibhav Hiremath struct v4l2_queryctrl *qctrl) 1447d73bfc5fe625f6962d0ced84066e201249f14e53Vaibhav Hiremath{ 1448d73bfc5fe625f6962d0ced84066e201249f14e53Vaibhav Hiremath struct vpfe_device *vpfe_dev = video_drvdata(file); 1449d73bfc5fe625f6962d0ced84066e201249f14e53Vaibhav Hiremath struct vpfe_subdev_info *sdinfo; 1450d73bfc5fe625f6962d0ced84066e201249f14e53Vaibhav Hiremath 1451d73bfc5fe625f6962d0ced84066e201249f14e53Vaibhav Hiremath sdinfo = vpfe_dev->current_subdev; 1452d73bfc5fe625f6962d0ced84066e201249f14e53Vaibhav Hiremath 1453d73bfc5fe625f6962d0ced84066e201249f14e53Vaibhav Hiremath return v4l2_device_call_until_err(&vpfe_dev->v4l2_dev, sdinfo->grp_id, 1454d73bfc5fe625f6962d0ced84066e201249f14e53Vaibhav Hiremath core, queryctrl, qctrl); 1455d73bfc5fe625f6962d0ced84066e201249f14e53Vaibhav Hiremath 1456d73bfc5fe625f6962d0ced84066e201249f14e53Vaibhav Hiremath} 1457d73bfc5fe625f6962d0ced84066e201249f14e53Vaibhav Hiremath 1458d73bfc5fe625f6962d0ced84066e201249f14e53Vaibhav Hiremathstatic int vpfe_g_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl) 1459d73bfc5fe625f6962d0ced84066e201249f14e53Vaibhav Hiremath{ 1460d73bfc5fe625f6962d0ced84066e201249f14e53Vaibhav Hiremath struct vpfe_device *vpfe_dev = video_drvdata(file); 1461d73bfc5fe625f6962d0ced84066e201249f14e53Vaibhav Hiremath struct vpfe_subdev_info *sdinfo; 1462d73bfc5fe625f6962d0ced84066e201249f14e53Vaibhav Hiremath 1463d73bfc5fe625f6962d0ced84066e201249f14e53Vaibhav Hiremath sdinfo = vpfe_dev->current_subdev; 1464d73bfc5fe625f6962d0ced84066e201249f14e53Vaibhav Hiremath 1465d73bfc5fe625f6962d0ced84066e201249f14e53Vaibhav Hiremath return v4l2_device_call_until_err(&vpfe_dev->v4l2_dev, sdinfo->grp_id, 1466d73bfc5fe625f6962d0ced84066e201249f14e53Vaibhav Hiremath core, g_ctrl, ctrl); 1467d73bfc5fe625f6962d0ced84066e201249f14e53Vaibhav Hiremath} 1468d73bfc5fe625f6962d0ced84066e201249f14e53Vaibhav Hiremath 1469d73bfc5fe625f6962d0ced84066e201249f14e53Vaibhav Hiremathstatic int vpfe_s_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl) 1470d73bfc5fe625f6962d0ced84066e201249f14e53Vaibhav Hiremath{ 1471d73bfc5fe625f6962d0ced84066e201249f14e53Vaibhav Hiremath struct vpfe_device *vpfe_dev = video_drvdata(file); 1472d73bfc5fe625f6962d0ced84066e201249f14e53Vaibhav Hiremath struct vpfe_subdev_info *sdinfo; 1473d73bfc5fe625f6962d0ced84066e201249f14e53Vaibhav Hiremath 1474d73bfc5fe625f6962d0ced84066e201249f14e53Vaibhav Hiremath sdinfo = vpfe_dev->current_subdev; 1475d73bfc5fe625f6962d0ced84066e201249f14e53Vaibhav Hiremath 1476d73bfc5fe625f6962d0ced84066e201249f14e53Vaibhav Hiremath return v4l2_device_call_until_err(&vpfe_dev->v4l2_dev, sdinfo->grp_id, 1477d73bfc5fe625f6962d0ced84066e201249f14e53Vaibhav Hiremath core, s_ctrl, ctrl); 1478d73bfc5fe625f6962d0ced84066e201249f14e53Vaibhav Hiremath} 1479d73bfc5fe625f6962d0ced84066e201249f14e53Vaibhav Hiremath 14807da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri/* 14817da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * vpfe_calculate_offsets : This function calculates buffers offset 14827da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * for top and bottom field 14837da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri */ 14847da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic void vpfe_calculate_offsets(struct vpfe_device *vpfe_dev) 14857da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 14867da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct v4l2_rect image_win; 14877da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 14887da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_calculate_offsets\n"); 14897da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 14907da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ccdc_dev->hw_ops.get_image_window(&image_win); 14917da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->field_off = image_win.height * image_win.width; 14927da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 14937da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 14947da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri/* vpfe_start_ccdc_capture: start streaming in ccdc/isif */ 14957da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic void vpfe_start_ccdc_capture(struct vpfe_device *vpfe_dev) 14967da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 14977da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ccdc_dev->hw_ops.enable(1); 14987da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (ccdc_dev->hw_ops.enable_out_to_sdram) 14997da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ccdc_dev->hw_ops.enable_out_to_sdram(1); 15007da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->started = 1; 15017da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 15027da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 15037da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri/* 15047da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * vpfe_streamon. Assume the DMA queue is not empty. 15057da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * application is expected to call QBUF before calling 15067da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * this ioctl. If not, driver returns error 15077da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri */ 15087da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic int vpfe_streamon(struct file *file, void *priv, 15097da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri enum v4l2_buf_type buf_type) 15107da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 15117da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_device *vpfe_dev = video_drvdata(file); 15127da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_fh *fh = file->private_data; 15137da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_subdev_info *sdinfo; 15147da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri unsigned long addr; 15157da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri int ret = 0; 15167da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 15177da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_streamon\n"); 15187da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 15197da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (V4L2_BUF_TYPE_VIDEO_CAPTURE != buf_type) { 15207da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(&vpfe_dev->v4l2_dev, "Invalid buf type\n"); 15217da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return -EINVAL; 15227da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 15237da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 15247da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* If file handle is not allowed IO, return error */ 15257da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (!fh->io_allowed) { 15267da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(&vpfe_dev->v4l2_dev, "fh->io_allowed\n"); 15277da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return -EACCES; 15287da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 15297da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 15307da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri sdinfo = vpfe_dev->current_subdev; 15317da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = v4l2_device_call_until_err(&vpfe_dev->v4l2_dev, sdinfo->grp_id, 15327da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri video, s_stream, 1); 15337da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 15347da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (ret && (ret != -ENOIOCTLCMD)) { 15357da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(&vpfe_dev->v4l2_dev, "stream on failed in subdev\n"); 15367da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return -EINVAL; 15377da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 15387da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 15397da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* If buffer queue is empty, return error */ 15407da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (list_empty(&vpfe_dev->buffer_queue.stream)) { 15417da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(&vpfe_dev->v4l2_dev, "buffer queue is empty\n"); 15427da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return -EIO; 15437da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 15447da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 15457da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* Call videobuf_streamon to start streaming * in videobuf */ 15467da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = videobuf_streamon(&vpfe_dev->buffer_queue); 15477da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (ret) 15487da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return ret; 15497da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 15507da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 15517da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = mutex_lock_interruptible(&vpfe_dev->lock); 15527da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (ret) 15537da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri goto streamoff; 15547da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* Get the next frame from the buffer queue */ 15557da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->next_frm = list_entry(vpfe_dev->dma_queue.next, 15567da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct videobuf_buffer, queue); 15577da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->cur_frm = vpfe_dev->next_frm; 15587da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* Remove buffer from the buffer queue */ 15597da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri list_del(&vpfe_dev->cur_frm->queue); 15607da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* Mark state of the current frame to active */ 15617da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->cur_frm->state = VIDEOBUF_ACTIVE; 15627da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* Initialize field_id and started member */ 15637da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->field_id = 0; 15647da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri addr = videobuf_to_dma_contig(vpfe_dev->cur_frm); 15657da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 15667da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* Calculate field offset */ 15677da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_calculate_offsets(vpfe_dev); 15687da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 15697da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (vpfe_attach_irq(vpfe_dev) < 0) { 15707da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(&vpfe_dev->v4l2_dev, 15717da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri "Error in attaching interrupt handle\n"); 15727da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = -EFAULT; 15737da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri goto unlock_out; 15747da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 15757da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (ccdc_dev->hw_ops.configure() < 0) { 15767da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(&vpfe_dev->v4l2_dev, 15777da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri "Error in configuring ccdc\n"); 15787da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = -EINVAL; 15797da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri goto unlock_out; 15807da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 15817da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ccdc_dev->hw_ops.setfbaddr((unsigned long)(addr)); 15827da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_start_ccdc_capture(vpfe_dev); 15837da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri mutex_unlock(&vpfe_dev->lock); 15847da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return ret; 15857da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheriunlock_out: 15867da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri mutex_unlock(&vpfe_dev->lock); 15877da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristreamoff: 15887da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = videobuf_streamoff(&vpfe_dev->buffer_queue); 15897da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return ret; 15907da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 15917da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 15927da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic int vpfe_streamoff(struct file *file, void *priv, 15937da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri enum v4l2_buf_type buf_type) 15947da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 15957da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_device *vpfe_dev = video_drvdata(file); 15967da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_fh *fh = file->private_data; 15977da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_subdev_info *sdinfo; 15987da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri int ret = 0; 15997da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 16007da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_streamoff\n"); 16017da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 16027da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (V4L2_BUF_TYPE_VIDEO_CAPTURE != buf_type) { 16037da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(&vpfe_dev->v4l2_dev, "Invalid buf type\n"); 16047da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return -EINVAL; 16057da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 16067da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 16077da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* If io is allowed for this file handle, return error */ 16087da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (!fh->io_allowed) { 16097da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(&vpfe_dev->v4l2_dev, "fh->io_allowed\n"); 16107da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return -EACCES; 16117da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 16127da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 16137da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* If streaming is not started, return error */ 16147da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (!vpfe_dev->started) { 16157da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(&vpfe_dev->v4l2_dev, "device started\n"); 16167da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return -EINVAL; 16177da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 16187da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 16197da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = mutex_lock_interruptible(&vpfe_dev->lock); 16207da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (ret) 16217da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return ret; 16227da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 16237da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_stop_ccdc_capture(vpfe_dev); 16247da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_detach_irq(vpfe_dev); 16257da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 16267da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri sdinfo = vpfe_dev->current_subdev; 16277da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = v4l2_device_call_until_err(&vpfe_dev->v4l2_dev, sdinfo->grp_id, 16287da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri video, s_stream, 0); 16297da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 16307da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (ret && (ret != -ENOIOCTLCMD)) 16317da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(&vpfe_dev->v4l2_dev, "stream off failed in subdev\n"); 16327da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = videobuf_streamoff(&vpfe_dev->buffer_queue); 16337da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri mutex_unlock(&vpfe_dev->lock); 16347da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return ret; 16357da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 16367da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 16377da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic int vpfe_cropcap(struct file *file, void *priv, 16387da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct v4l2_cropcap *crop) 16397da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 16407da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_device *vpfe_dev = video_drvdata(file); 16417da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 16427da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_cropcap\n"); 16437da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 16440b66cf90371dcd28c6eb98904adb694ae98eb20fRoel Kluin if (vpfe_dev->std_index >= ARRAY_SIZE(vpfe_standards)) 16457da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return -EINVAL; 16467da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 16477da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri memset(crop, 0, sizeof(struct v4l2_cropcap)); 16487da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri crop->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 16497da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri crop->bounds.width = crop->defrect.width = 16507da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_standards[vpfe_dev->std_index].width; 16517da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri crop->bounds.height = crop->defrect.height = 16527da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_standards[vpfe_dev->std_index].height; 16537da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri crop->pixelaspect = vpfe_standards[vpfe_dev->std_index].pixelaspect; 16547da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return 0; 16557da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 16567da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 16577da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic int vpfe_g_crop(struct file *file, void *priv, 16587da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct v4l2_crop *crop) 16597da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 16607da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_device *vpfe_dev = video_drvdata(file); 16617da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 16627da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_g_crop\n"); 16637da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 16647da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri crop->c = vpfe_dev->crop; 16657da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return 0; 16667da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 16677da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 16687da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic int vpfe_s_crop(struct file *file, void *priv, 16697da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct v4l2_crop *crop) 16707da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 16717da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_device *vpfe_dev = video_drvdata(file); 16727da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri int ret = 0; 16737da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 16747da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_s_crop\n"); 16757da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 16767da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (vpfe_dev->started) { 16777da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* make sure streaming is not started */ 16787da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(&vpfe_dev->v4l2_dev, 16797da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri "Cannot change crop when streaming is ON\n"); 16807da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return -EBUSY; 16817da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 16827da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 16837da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = mutex_lock_interruptible(&vpfe_dev->lock); 16847da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (ret) 16857da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return ret; 16867da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 16877da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (crop->c.top < 0 || crop->c.left < 0) { 16887da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(&vpfe_dev->v4l2_dev, 16897da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri "doesn't support negative values for top & left\n"); 16907da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = -EINVAL; 16917da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri goto unlock_out; 16927da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 16937da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 169425985edcedea6396277003854657b5f3cb31a628Lucas De Marchi /* adjust the width to 16 pixel boundary */ 16957da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri crop->c.width = ((crop->c.width + 15) & ~0xf); 16967da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 16977da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* make sure parameters are valid */ 16987da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if ((crop->c.left + crop->c.width > 16997da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->std_info.active_pixels) || 17007da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri (crop->c.top + crop->c.height > 17017da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->std_info.active_lines)) { 17027da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(&vpfe_dev->v4l2_dev, "Error in S_CROP params\n"); 17037da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = -EINVAL; 17047da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri goto unlock_out; 17057da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 17067da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ccdc_dev->hw_ops.set_image_window(&crop->c); 17077da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->fmt.fmt.pix.width = crop->c.width; 17087da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->fmt.fmt.pix.height = crop->c.height; 17097da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->fmt.fmt.pix.bytesperline = 17107da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ccdc_dev->hw_ops.get_line_length(); 17117da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->fmt.fmt.pix.sizeimage = 17127da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->fmt.fmt.pix.bytesperline * 17137da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->fmt.fmt.pix.height; 17147da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->crop = crop->c; 17157da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheriunlock_out: 17167da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri mutex_unlock(&vpfe_dev->lock); 17177da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return ret; 17187da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 17197da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 17207da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 17217da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic long vpfe_param_handler(struct file *file, void *priv, 172299cd47bc733436da282016e629eef6baa0f6047cHans Verkuil bool valid_prio, int cmd, void *param) 17237da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 17247da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_device *vpfe_dev = video_drvdata(file); 17257da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri int ret = 0; 17267da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 17276a4f0623a4ebe46c743d213db808067553953913Muralidharan Karicheri v4l2_dbg(2, debug, &vpfe_dev->v4l2_dev, "vpfe_param_handler\n"); 17287da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 17297da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (vpfe_dev->started) { 17307da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* only allowed if streaming is not started */ 17316a4f0623a4ebe46c743d213db808067553953913Muralidharan Karicheri v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, 17326a4f0623a4ebe46c743d213db808067553953913Muralidharan Karicheri "device already started\n"); 17337da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return -EBUSY; 17347da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 17357da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 17367da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = mutex_lock_interruptible(&vpfe_dev->lock); 17377da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (ret) 17387da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return ret; 17397da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 17407da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri switch (cmd) { 17417da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri case VPFE_CMD_S_CCDC_RAW_PARAMS: 17427da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_warn(&vpfe_dev->v4l2_dev, 17437da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri "VPFE_CMD_S_CCDC_RAW_PARAMS: experimental ioctl\n"); 17446a4f0623a4ebe46c743d213db808067553953913Muralidharan Karicheri if (ccdc_dev->hw_ops.set_params) { 17456a4f0623a4ebe46c743d213db808067553953913Muralidharan Karicheri ret = ccdc_dev->hw_ops.set_params(param); 17466a4f0623a4ebe46c743d213db808067553953913Muralidharan Karicheri if (ret) { 17476a4f0623a4ebe46c743d213db808067553953913Muralidharan Karicheri v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, 17486a4f0623a4ebe46c743d213db808067553953913Muralidharan Karicheri "Error setting parameters in CCDC\n"); 17496a4f0623a4ebe46c743d213db808067553953913Muralidharan Karicheri goto unlock_out; 17506a4f0623a4ebe46c743d213db808067553953913Muralidharan Karicheri } 17516a4f0623a4ebe46c743d213db808067553953913Muralidharan Karicheri if (vpfe_get_ccdc_image_format(vpfe_dev, 17526a4f0623a4ebe46c743d213db808067553953913Muralidharan Karicheri &vpfe_dev->fmt) < 0) { 17536a4f0623a4ebe46c743d213db808067553953913Muralidharan Karicheri v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, 17546a4f0623a4ebe46c743d213db808067553953913Muralidharan Karicheri "Invalid image format at CCDC\n"); 17556a4f0623a4ebe46c743d213db808067553953913Muralidharan Karicheri goto unlock_out; 17566a4f0623a4ebe46c743d213db808067553953913Muralidharan Karicheri } 17576a4f0623a4ebe46c743d213db808067553953913Muralidharan Karicheri } else { 17586a4f0623a4ebe46c743d213db808067553953913Muralidharan Karicheri ret = -EINVAL; 17596a4f0623a4ebe46c743d213db808067553953913Muralidharan Karicheri v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, 17606a4f0623a4ebe46c743d213db808067553953913Muralidharan Karicheri "VPFE_CMD_S_CCDC_RAW_PARAMS not supported\n"); 17617da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 17627da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri break; 17637da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri default: 17647da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = -EINVAL; 17657da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 17667da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheriunlock_out: 17677da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri mutex_unlock(&vpfe_dev->lock); 17687da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return ret; 17697da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 17707da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 17717da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 17727da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri/* vpfe capture ioctl operations */ 17737da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic const struct v4l2_ioctl_ops vpfe_ioctl_ops = { 17747da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .vidioc_querycap = vpfe_querycap, 17757da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .vidioc_g_fmt_vid_cap = vpfe_g_fmt_vid_cap, 17767da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .vidioc_enum_fmt_vid_cap = vpfe_enum_fmt_vid_cap, 17777da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .vidioc_s_fmt_vid_cap = vpfe_s_fmt_vid_cap, 17787da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .vidioc_try_fmt_vid_cap = vpfe_try_fmt_vid_cap, 17797da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .vidioc_enum_input = vpfe_enum_input, 17807da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .vidioc_g_input = vpfe_g_input, 17817da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .vidioc_s_input = vpfe_s_input, 17827da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .vidioc_querystd = vpfe_querystd, 17837da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .vidioc_s_std = vpfe_s_std, 17847da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .vidioc_g_std = vpfe_g_std, 1785d73bfc5fe625f6962d0ced84066e201249f14e53Vaibhav Hiremath .vidioc_queryctrl = vpfe_queryctrl, 1786d73bfc5fe625f6962d0ced84066e201249f14e53Vaibhav Hiremath .vidioc_g_ctrl = vpfe_g_ctrl, 1787d73bfc5fe625f6962d0ced84066e201249f14e53Vaibhav Hiremath .vidioc_s_ctrl = vpfe_s_ctrl, 17887da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .vidioc_reqbufs = vpfe_reqbufs, 17897da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .vidioc_querybuf = vpfe_querybuf, 17907da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .vidioc_qbuf = vpfe_qbuf, 17917da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .vidioc_dqbuf = vpfe_dqbuf, 17927da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .vidioc_streamon = vpfe_streamon, 17937da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .vidioc_streamoff = vpfe_streamoff, 17947da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .vidioc_cropcap = vpfe_cropcap, 17957da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .vidioc_g_crop = vpfe_g_crop, 17967da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .vidioc_s_crop = vpfe_s_crop, 17977da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .vidioc_default = vpfe_param_handler, 17987da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri}; 17997da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 18007da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic struct vpfe_device *vpfe_initialize(void) 18017da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 18027da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_device *vpfe_dev; 18037da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 18047da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* Default number of buffers should be 3 */ 18057da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if ((numbuffers > 0) && 18067da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri (numbuffers < config_params.min_numbuffers)) 18077da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri numbuffers = config_params.min_numbuffers; 18087da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 18097da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* 18107da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * Set buffer size to min buffers size if invalid buffer size is 18117da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * given 18127da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri */ 18137da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (bufsize < config_params.min_bufsize) 18147da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri bufsize = config_params.min_bufsize; 18157da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 18167da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri config_params.numbuffers = numbuffers; 18177da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 18187da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (numbuffers) 18197da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri config_params.device_bufsize = bufsize; 18207da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 18217da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* Allocate memory for device objects */ 18227da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev = kzalloc(sizeof(*vpfe_dev), GFP_KERNEL); 18237da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 18247da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return vpfe_dev; 18257da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 18267da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 18277da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri/* 18287da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * vpfe_probe : This function creates device entries by register 18297da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * itself to the V4L2 driver and initializes fields of each 18307da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * device objects 18317da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri */ 18327da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic __init int vpfe_probe(struct platform_device *pdev) 18337da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 18347da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_subdev_info *sdinfo; 18357da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_config *vpfe_cfg; 18367da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct resource *res1; 18377da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_device *vpfe_dev; 18387da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct i2c_adapter *i2c_adap; 18397da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct video_device *vfd; 18407da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri int ret = -ENOMEM, i, j; 18417da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri int num_subdevs = 0; 18427da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 18437da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* Get the pointer to the device object */ 18447da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev = vpfe_initialize(); 18457da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 18467da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (!vpfe_dev) { 18477da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(pdev->dev.driver, 18487da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri "Failed to allocate memory for vpfe_dev\n"); 18497da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return ret; 18507da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 18517da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 18527da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->pdev = &pdev->dev; 18537da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 18547da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (NULL == pdev->dev.platform_data) { 18557da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(pdev->dev.driver, "Unable to get vpfe config\n"); 185651444ea3d4f5baa0338297aba7065fd695528a36Muralidharan Karicheri ret = -ENODEV; 18577da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri goto probe_free_dev_mem; 18587da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 18597da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 18607da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_cfg = pdev->dev.platform_data; 18617da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->cfg = vpfe_cfg; 18627da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (NULL == vpfe_cfg->ccdc || 18637da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri NULL == vpfe_cfg->card_name || 18647da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri NULL == vpfe_cfg->sub_devs) { 18657da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(pdev->dev.driver, "null ptr in vpfe_cfg\n"); 18667da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = -ENOENT; 18677da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri goto probe_free_dev_mem; 18687da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 18697da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 18707da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* Allocate memory for ccdc configuration */ 18717da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ccdc_cfg = kmalloc(sizeof(struct ccdc_config), GFP_KERNEL); 18727da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (NULL == ccdc_cfg) { 18737da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(pdev->dev.driver, 18747da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri "Memory allocation failed for ccdc_cfg\n"); 1875ab51bec1f852f6b858a26e745b32a79cd1a67eecMurali Karicheri goto probe_free_lock; 18767da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 18777da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 18782b080c5df00e431baec09222aa8d623f0cd77314Dan Carpenter mutex_lock(&ccdc_lock); 18792b080c5df00e431baec09222aa8d623f0cd77314Dan Carpenter 18807da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri strncpy(ccdc_cfg->name, vpfe_cfg->ccdc, 32); 18817da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* Get VINT0 irq resource */ 18827da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri res1 = platform_get_resource(pdev, IORESOURCE_IRQ, 0); 18837da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (!res1) { 18847da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(pdev->dev.driver, 18857da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri "Unable to get interrupt for VINT0\n"); 188651444ea3d4f5baa0338297aba7065fd695528a36Muralidharan Karicheri ret = -ENODEV; 188751444ea3d4f5baa0338297aba7065fd695528a36Muralidharan Karicheri goto probe_free_ccdc_cfg_mem; 18887da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 18897da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->ccdc_irq0 = res1->start; 18907da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 18917da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* Get VINT1 irq resource */ 189251444ea3d4f5baa0338297aba7065fd695528a36Muralidharan Karicheri res1 = platform_get_resource(pdev, IORESOURCE_IRQ, 1); 18937da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (!res1) { 18947da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(pdev->dev.driver, 18957da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri "Unable to get interrupt for VINT1\n"); 189651444ea3d4f5baa0338297aba7065fd695528a36Muralidharan Karicheri ret = -ENODEV; 189751444ea3d4f5baa0338297aba7065fd695528a36Muralidharan Karicheri goto probe_free_ccdc_cfg_mem; 18987da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 18997da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->ccdc_irq1 = res1->start; 19007da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 19017da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = request_irq(vpfe_dev->ccdc_irq0, vpfe_isr, IRQF_DISABLED, 19027da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri "vpfe_capture0", vpfe_dev); 19037da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 19047da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (0 != ret) { 19057da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(pdev->dev.driver, "Unable to request interrupt\n"); 190651444ea3d4f5baa0338297aba7065fd695528a36Muralidharan Karicheri goto probe_free_ccdc_cfg_mem; 19077da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 19087da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 19097da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* Allocate memory for video device */ 19107da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vfd = video_device_alloc(); 19117da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (NULL == vfd) { 19127da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = -ENOMEM; 191351444ea3d4f5baa0338297aba7065fd695528a36Muralidharan Karicheri v4l2_err(pdev->dev.driver, "Unable to alloc video device\n"); 19147da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri goto probe_out_release_irq; 19157da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 19167da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 19177da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* Initialize field of video device */ 19187da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vfd->release = video_device_release; 19197da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vfd->fops = &vpfe_fops; 19207da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vfd->ioctl_ops = &vpfe_ioctl_ops; 19217da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vfd->tvnorms = 0; 19227da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vfd->current_norm = V4L2_STD_PAL; 19237da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vfd->v4l2_dev = &vpfe_dev->v4l2_dev; 19247da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri snprintf(vfd->name, sizeof(vfd->name), 19257da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri "%s_V%d.%d.%d", 19267da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri CAPTURE_DRV_NAME, 19277da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri (VPFE_CAPTURE_VERSION_CODE >> 16) & 0xff, 19287da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri (VPFE_CAPTURE_VERSION_CODE >> 8) & 0xff, 19297da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri (VPFE_CAPTURE_VERSION_CODE) & 0xff); 19307da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* Set video_dev to the video device */ 19317da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->video_dev = vfd; 19327da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 19337da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = v4l2_device_register(&pdev->dev, &vpfe_dev->v4l2_dev); 19347da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (ret) { 19357da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(pdev->dev.driver, 19367da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri "Unable to register v4l2 device.\n"); 19377da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri goto probe_out_video_release; 19387da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 19397da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_info(&vpfe_dev->v4l2_dev, "v4l2 device registered\n"); 19407da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri spin_lock_init(&vpfe_dev->irqlock); 19417da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri spin_lock_init(&vpfe_dev->dma_queue_lock); 19427da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri mutex_init(&vpfe_dev->lock); 19437da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 19447da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* Initialize field of the device objects */ 19457da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->numbuffers = config_params.numbuffers; 19467da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 19477da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* Initialize prio member of device object */ 19487da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_prio_init(&vpfe_dev->prio); 19497da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* register video device */ 19507da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, 19517da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri "trying to register vpfe device.\n"); 19527da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, 19537da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri "video_dev=%x\n", (int)&vpfe_dev->video_dev); 19547da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 19557da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = video_register_device(vpfe_dev->video_dev, 19567da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri VFL_TYPE_GRABBER, -1); 19577da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 19587da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (ret) { 19597da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(pdev->dev.driver, 19607da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri "Unable to register video device.\n"); 19617da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri goto probe_out_v4l2_unregister; 19627da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 19637da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 19647da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_info(&vpfe_dev->v4l2_dev, "video device registered\n"); 19657da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* set the driver data in platform device */ 19667da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri platform_set_drvdata(pdev, vpfe_dev); 19677da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* set driver private data */ 19687da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri video_set_drvdata(vpfe_dev->video_dev, vpfe_dev); 196914cbaafe6f8587aed632de747322cd3add421a76Vaibhav Hiremath i2c_adap = i2c_get_adapter(vpfe_cfg->i2c_adapter_id); 19707da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri num_subdevs = vpfe_cfg->num_subdevs; 19717da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->sd = kmalloc(sizeof(struct v4l2_subdev *) * num_subdevs, 19727da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri GFP_KERNEL); 19737da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (NULL == vpfe_dev->sd) { 19747da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(&vpfe_dev->v4l2_dev, 19757da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri "unable to allocate memory for subdevice pointers\n"); 19767da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = -ENOMEM; 19777da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri goto probe_out_video_unregister; 19787da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 19797da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 19807da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri for (i = 0; i < num_subdevs; i++) { 19817da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct v4l2_input *inps; 19827da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 19837da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri sdinfo = &vpfe_cfg->sub_devs[i]; 19847da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 19857da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* Load up the subdevice */ 19867da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->sd[i] = 19877da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_i2c_new_subdev_board(&vpfe_dev->v4l2_dev, 19887da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri i2c_adap, 19897da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri &sdinfo->board_info, 19907da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri NULL); 19917da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (vpfe_dev->sd[i]) { 19927da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_info(&vpfe_dev->v4l2_dev, 19937da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri "v4l2 sub device %s registered\n", 19947da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri sdinfo->name); 19957da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->sd[i]->grp_id = sdinfo->grp_id; 19967da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* update tvnorms from the sub devices */ 19977da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri for (j = 0; j < sdinfo->num_inputs; j++) { 19987da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri inps = &sdinfo->inputs[j]; 19997da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vfd->tvnorms |= inps->std; 20007da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 20017da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } else { 20027da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_info(&vpfe_dev->v4l2_dev, 20037da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri "v4l2 sub device %s register fails\n", 20047da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri sdinfo->name); 20057da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri goto probe_sd_out; 20067da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 20077da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 20087da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 20097da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* set first sub device as current one */ 20107da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->current_subdev = &vpfe_cfg->sub_devs[0]; 20117da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 20127da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* We have at least one sub device to work with */ 20137da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri mutex_unlock(&ccdc_lock); 20147da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return 0; 20157da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 20167da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheriprobe_sd_out: 20177da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri kfree(vpfe_dev->sd); 20187da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheriprobe_out_video_unregister: 20197da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri video_unregister_device(vpfe_dev->video_dev); 20207da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheriprobe_out_v4l2_unregister: 20217da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_device_unregister(&vpfe_dev->v4l2_dev); 20227da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheriprobe_out_video_release: 2023f0813b4c9f7ffbeaddcba1c08a1812f7ff30e1b7Laurent Pinchart if (!video_is_registered(vpfe_dev->video_dev)) 20247da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri video_device_release(vpfe_dev->video_dev); 20257da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheriprobe_out_release_irq: 20267da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri free_irq(vpfe_dev->ccdc_irq0, vpfe_dev); 202751444ea3d4f5baa0338297aba7065fd695528a36Muralidharan Karicheriprobe_free_ccdc_cfg_mem: 20287da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri kfree(ccdc_cfg); 2029ab51bec1f852f6b858a26e745b32a79cd1a67eecMurali Karicheriprobe_free_lock: 2030ab51bec1f852f6b858a26e745b32a79cd1a67eecMurali Karicheri mutex_unlock(&ccdc_lock); 20317da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheriprobe_free_dev_mem: 20327da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri kfree(vpfe_dev); 20337da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return ret; 20347da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 20357da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 20367da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri/* 20377da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * vpfe_remove : It un-register device from V4L2 driver 20387da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri */ 20399d8938248c3b67904a8108a6fc3dcceb9d7f2aadUwe Kleine-Königstatic int __devexit vpfe_remove(struct platform_device *pdev) 20407da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 20417da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_device *vpfe_dev = platform_get_drvdata(pdev); 20427da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 20437da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_info(pdev->dev.driver, "vpfe_remove\n"); 20447da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 20457da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri free_irq(vpfe_dev->ccdc_irq0, vpfe_dev); 20467da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri kfree(vpfe_dev->sd); 20477da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_device_unregister(&vpfe_dev->v4l2_dev); 20487da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri video_unregister_device(vpfe_dev->video_dev); 20497da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri kfree(vpfe_dev); 20507da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri kfree(ccdc_cfg); 20517da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return 0; 20527da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 20537da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 2054aa2dc9034859531206889b6bf07b5f9adae487a6Vaibhav Hiremathstatic int vpfe_suspend(struct device *dev) 20557da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 2056aa2dc9034859531206889b6bf07b5f9adae487a6Vaibhav Hiremath return 0; 20577da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 20587da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 2059aa2dc9034859531206889b6bf07b5f9adae487a6Vaibhav Hiremathstatic int vpfe_resume(struct device *dev) 20607da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 2061aa2dc9034859531206889b6bf07b5f9adae487a6Vaibhav Hiremath return 0; 20627da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 20637da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 2064471452104b8520337ae2fb48c4e61cd4896e025dAlexey Dobriyanstatic const struct dev_pm_ops vpfe_dev_pm_ops = { 20657da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .suspend = vpfe_suspend, 20667da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .resume = vpfe_resume, 20677da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri}; 20687da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 20697da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic struct platform_driver vpfe_driver = { 20707da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .driver = { 20717da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .name = CAPTURE_DRV_NAME, 20727da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .owner = THIS_MODULE, 20737da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .pm = &vpfe_dev_pm_ops, 20747da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri }, 20757da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .probe = vpfe_probe, 20767da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .remove = __devexit_p(vpfe_remove), 20777da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri}; 20787da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 20791d6629b1561ad34a6e6d17ece00bd65e1bab3724Axel Linmodule_platform_driver(vpfe_driver); 2080