vpfe_capture.c revision 9d8938248c3b67904a8108a6fc3dcceb9d7f2aad
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> 707da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri#include <linux/init.h> 717da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri#include <linux/platform_device.h> 727da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri#include <linux/interrupt.h> 737da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri#include <linux/version.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 /* for storing mem maps for CCDC */ 1127da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri int ccdc_addr_size; 1137da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri void *__iomem ccdc_addr; 1147da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri}; 1157da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 1167da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri/* data structures */ 1177da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic struct vpfe_config_params config_params = { 1187da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .min_numbuffers = 3, 1197da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .numbuffers = 3, 1207da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .min_bufsize = 720 * 480 * 2, 1217da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .device_bufsize = 720 * 576 * 2, 1227da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri}; 1237da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 1247da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri/* ccdc device registered */ 1257da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic struct ccdc_hw_device *ccdc_dev; 1267da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri/* lock for accessing ccdc information */ 1277da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic DEFINE_MUTEX(ccdc_lock); 1287da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri/* ccdc configuration */ 1297da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic struct ccdc_config *ccdc_cfg; 1307da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 1317da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karichericonst struct vpfe_standard vpfe_standards[] = { 1327da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri {V4L2_STD_525_60, 720, 480, {11, 10}, 1}, 1337da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri {V4L2_STD_625_50, 720, 576, {54, 59}, 1}, 1347da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri}; 1357da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 1367da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri/* Used when raw Bayer image from ccdc is directly captured to SDRAM */ 1377da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic const struct vpfe_pixel_format vpfe_pix_fmts[] = { 1387da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri { 1397da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .fmtdesc = { 1407da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .index = 0, 1417da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .type = V4L2_BUF_TYPE_VIDEO_CAPTURE, 1427da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .description = "Bayer GrRBGb 8bit A-Law compr.", 1437da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .pixelformat = V4L2_PIX_FMT_SBGGR8, 1447da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri }, 1457da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .bpp = 1, 1467da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri }, 1477da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri { 1487da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .fmtdesc = { 1497da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .index = 1, 1507da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .type = V4L2_BUF_TYPE_VIDEO_CAPTURE, 1517da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .description = "Bayer GrRBGb - 16bit", 1527da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .pixelformat = V4L2_PIX_FMT_SBGGR16, 1537da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri }, 1547da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .bpp = 2, 1557da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri }, 1567da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri { 1577da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .fmtdesc = { 1587da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .index = 2, 1597da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .type = V4L2_BUF_TYPE_VIDEO_CAPTURE, 1607da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .description = "Bayer GrRBGb 8bit DPCM compr.", 1617da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .pixelformat = V4L2_PIX_FMT_SGRBG10DPCM8, 1627da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri }, 1637da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .bpp = 1, 1647da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri }, 1657da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri { 1667da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .fmtdesc = { 1677da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .index = 3, 1687da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .type = V4L2_BUF_TYPE_VIDEO_CAPTURE, 1697da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .description = "YCbCr 4:2:2 Interleaved UYVY", 1707da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .pixelformat = V4L2_PIX_FMT_UYVY, 1717da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri }, 1727da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .bpp = 2, 1737da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri }, 1747da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri { 1757da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .fmtdesc = { 1767da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .index = 4, 1777da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .type = V4L2_BUF_TYPE_VIDEO_CAPTURE, 1787da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .description = "YCbCr 4:2:2 Interleaved YUYV", 1797da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .pixelformat = V4L2_PIX_FMT_YUYV, 1807da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri }, 1817da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .bpp = 2, 1827da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri }, 1837da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri { 1847da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .fmtdesc = { 1857da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .index = 5, 1867da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .type = V4L2_BUF_TYPE_VIDEO_CAPTURE, 1877da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .description = "Y/CbCr 4:2:0 - Semi planar", 1887da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .pixelformat = V4L2_PIX_FMT_NV12, 1897da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri }, 1907da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .bpp = 1, 1917da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri }, 1927da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri}; 1937da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 1947da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri/* 1957da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * vpfe_lookup_pix_format() 1967da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * lookup an entry in the vpfe pix format table based on pix_format 1977da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri */ 1987da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic const struct vpfe_pixel_format *vpfe_lookup_pix_format(u32 pix_format) 1997da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 2007da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri int i; 2017da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 2027da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri for (i = 0; i < ARRAY_SIZE(vpfe_pix_fmts); i++) { 2037da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (pix_format == vpfe_pix_fmts[i].fmtdesc.pixelformat) 2047da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return &vpfe_pix_fmts[i]; 2057da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 2067da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return NULL; 2077da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 2087da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 2097da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri/* 2107da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * vpfe_register_ccdc_device. CCDC module calls this to 2117da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * register with vpfe capture 2127da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri */ 2137da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheriint vpfe_register_ccdc_device(struct ccdc_hw_device *dev) 2147da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 2157da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri int ret = 0; 2167da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri printk(KERN_NOTICE "vpfe_register_ccdc_device: %s\n", dev->name); 2177da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 2187da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri BUG_ON(!dev->hw_ops.open); 2197da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri BUG_ON(!dev->hw_ops.enable); 2207da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri BUG_ON(!dev->hw_ops.set_hw_if_params); 2217da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri BUG_ON(!dev->hw_ops.configure); 2227da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri BUG_ON(!dev->hw_ops.set_buftype); 2237da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri BUG_ON(!dev->hw_ops.get_buftype); 2247da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri BUG_ON(!dev->hw_ops.enum_pix); 2257da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri BUG_ON(!dev->hw_ops.set_frame_format); 2267da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri BUG_ON(!dev->hw_ops.get_frame_format); 2277da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri BUG_ON(!dev->hw_ops.get_pixel_format); 2287da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri BUG_ON(!dev->hw_ops.set_pixel_format); 2297da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri BUG_ON(!dev->hw_ops.set_params); 2307da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri BUG_ON(!dev->hw_ops.set_image_window); 2317da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri BUG_ON(!dev->hw_ops.get_image_window); 2327da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri BUG_ON(!dev->hw_ops.get_line_length); 2337da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri BUG_ON(!dev->hw_ops.setfbaddr); 2347da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri BUG_ON(!dev->hw_ops.getfid); 2357da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 2367da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri mutex_lock(&ccdc_lock); 2377da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (NULL == ccdc_cfg) { 2387da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* 2397da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * TODO. Will this ever happen? if so, we need to fix it. 2407da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * Proabably we need to add the request to a linked list and 2417da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * walk through it during vpfe probe 2427da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri */ 2437da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri printk(KERN_ERR "vpfe capture not initialized\n"); 2447da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = -1; 2457da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri goto unlock; 2467da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 2477da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 2487da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (strcmp(dev->name, ccdc_cfg->name)) { 2497da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* ignore this ccdc */ 2507da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = -1; 2517da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri goto unlock; 2527da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 2537da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 2547da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (ccdc_dev) { 2557da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri printk(KERN_ERR "ccdc already registered\n"); 2567da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = -1; 2577da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri goto unlock; 2587da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 2597da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 2607da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ccdc_dev = dev; 2617da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri dev->hw_ops.set_ccdc_base(ccdc_cfg->ccdc_addr, 2627da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ccdc_cfg->ccdc_addr_size); 2637da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheriunlock: 2647da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri mutex_unlock(&ccdc_lock); 2657da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return ret; 2667da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 2677da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan KaricheriEXPORT_SYMBOL(vpfe_register_ccdc_device); 2687da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 2697da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri/* 2707da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * vpfe_unregister_ccdc_device. CCDC module calls this to 2717da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * unregister with vpfe capture 2727da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri */ 2737da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicherivoid vpfe_unregister_ccdc_device(struct ccdc_hw_device *dev) 2747da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 2757da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (NULL == dev) { 2767da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri printk(KERN_ERR "invalid ccdc device ptr\n"); 2777da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return; 2787da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 2797da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 2807da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri printk(KERN_NOTICE "vpfe_unregister_ccdc_device, dev->name = %s\n", 2817da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri dev->name); 2827da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 2837da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (strcmp(dev->name, ccdc_cfg->name)) { 2847da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* ignore this ccdc */ 2857da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return; 2867da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 2877da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 2887da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri mutex_lock(&ccdc_lock); 2897da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ccdc_dev = NULL; 2907da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri mutex_unlock(&ccdc_lock); 2917da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return; 2927da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 2937da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan KaricheriEXPORT_SYMBOL(vpfe_unregister_ccdc_device); 2947da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 2957da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri/* 2967da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * vpfe_get_ccdc_image_format - Get image parameters based on CCDC settings 2977da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri */ 2987da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic int vpfe_get_ccdc_image_format(struct vpfe_device *vpfe_dev, 2997da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct v4l2_format *f) 3007da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 3017da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct v4l2_rect image_win; 3027da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri enum ccdc_buftype buf_type; 3037da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri enum ccdc_frmfmt frm_fmt; 3047da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 3057da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri memset(f, 0, sizeof(*f)); 3067da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri f->type = V4L2_BUF_TYPE_VIDEO_OUTPUT; 3077da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ccdc_dev->hw_ops.get_image_window(&image_win); 3087da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri f->fmt.pix.width = image_win.width; 3097da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri f->fmt.pix.height = image_win.height; 3107da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri f->fmt.pix.bytesperline = ccdc_dev->hw_ops.get_line_length(); 3117da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * 3127da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri f->fmt.pix.height; 3137da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri buf_type = ccdc_dev->hw_ops.get_buftype(); 3147da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri f->fmt.pix.pixelformat = ccdc_dev->hw_ops.get_pixel_format(); 3157da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri frm_fmt = ccdc_dev->hw_ops.get_frame_format(); 3167da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (frm_fmt == CCDC_FRMFMT_PROGRESSIVE) 3177da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri f->fmt.pix.field = V4L2_FIELD_NONE; 3187da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri else if (frm_fmt == CCDC_FRMFMT_INTERLACED) { 3197da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (buf_type == CCDC_BUFTYPE_FLD_INTERLEAVED) 3207da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri f->fmt.pix.field = V4L2_FIELD_INTERLACED; 3217da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri else if (buf_type == CCDC_BUFTYPE_FLD_SEPARATED) 3227da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri f->fmt.pix.field = V4L2_FIELD_SEQ_TB; 3237da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri else { 3247da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(&vpfe_dev->v4l2_dev, "Invalid buf_type\n"); 3257da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return -EINVAL; 3267da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 3277da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } else { 3287da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(&vpfe_dev->v4l2_dev, "Invalid frm_fmt\n"); 3297da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return -EINVAL; 3307da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 3317da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return 0; 3327da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 3337da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 3347da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri/* 3357da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * vpfe_config_ccdc_image_format() 3367da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * For a pix format, configure ccdc to setup the capture 3377da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri */ 3387da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic int vpfe_config_ccdc_image_format(struct vpfe_device *vpfe_dev) 3397da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 3407da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri enum ccdc_frmfmt frm_fmt = CCDC_FRMFMT_INTERLACED; 3417da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri int ret = 0; 3427da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 3437da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (ccdc_dev->hw_ops.set_pixel_format( 3447da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->fmt.fmt.pix.pixelformat) < 0) { 3457da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(&vpfe_dev->v4l2_dev, 3467da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri "couldn't set pix format in ccdc\n"); 3477da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return -EINVAL; 3487da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 3497da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* configure the image window */ 3507da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ccdc_dev->hw_ops.set_image_window(&vpfe_dev->crop); 3517da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 3527da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri switch (vpfe_dev->fmt.fmt.pix.field) { 3537da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri case V4L2_FIELD_INTERLACED: 3547da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* do nothing, since it is default */ 3557da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = ccdc_dev->hw_ops.set_buftype( 3567da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri CCDC_BUFTYPE_FLD_INTERLEAVED); 3577da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri break; 3587da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri case V4L2_FIELD_NONE: 3597da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri frm_fmt = CCDC_FRMFMT_PROGRESSIVE; 3607da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* buffer type only applicable for interlaced scan */ 3617da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri break; 3627da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri case V4L2_FIELD_SEQ_TB: 3637da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = ccdc_dev->hw_ops.set_buftype( 3647da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri CCDC_BUFTYPE_FLD_SEPARATED); 3657da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri break; 3667da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri default: 3677da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return -EINVAL; 3687da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 3697da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 3707da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* set the frame format */ 3717da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (!ret) 3727da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = ccdc_dev->hw_ops.set_frame_format(frm_fmt); 3737da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return ret; 3747da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 3757da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri/* 3767da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * vpfe_config_image_format() 3777da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * For a given standard, this functions sets up the default 3787da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * pix format & crop values in the vpfe device and ccdc. It first 3797da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * starts with defaults based values from the standard table. 3807da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * It then checks if sub device support g_fmt and then override the 3817da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * values based on that.Sets crop values to match with scan resolution 3827da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * starting at 0,0. It calls vpfe_config_ccdc_image_format() set the 3837da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * values in ccdc 3847da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri */ 3857da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic int vpfe_config_image_format(struct vpfe_device *vpfe_dev, 3867da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri const v4l2_std_id *std_id) 3877da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 3887da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_subdev_info *sdinfo = vpfe_dev->current_subdev; 3897da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri int i, ret = 0; 3907da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 3917da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri for (i = 0; i < ARRAY_SIZE(vpfe_standards); i++) { 3927da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (vpfe_standards[i].std_id & *std_id) { 3937da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->std_info.active_pixels = 3947da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_standards[i].width; 3957da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->std_info.active_lines = 3967da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_standards[i].height; 3977da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->std_info.frame_format = 3987da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_standards[i].frame_format; 3997da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->std_index = i; 4007da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri break; 4017da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 4027da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 4037da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 4047da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (i == ARRAY_SIZE(vpfe_standards)) { 4057da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(&vpfe_dev->v4l2_dev, "standard not supported\n"); 4067da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return -EINVAL; 4077da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 4087da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 4097da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->crop.top = 0; 4107da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->crop.left = 0; 4117da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->crop.width = vpfe_dev->std_info.active_pixels; 4127da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->crop.height = vpfe_dev->std_info.active_lines; 4137da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->fmt.fmt.pix.width = vpfe_dev->crop.width; 4147da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->fmt.fmt.pix.height = vpfe_dev->crop.height; 4157da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 4167da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* first field and frame format based on standard frame format */ 4177da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (vpfe_dev->std_info.frame_format) { 4187da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->fmt.fmt.pix.field = V4L2_FIELD_INTERLACED; 4197da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* assume V4L2_PIX_FMT_UYVY as default */ 4207da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_UYVY; 4217da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } else { 4227da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->fmt.fmt.pix.field = V4L2_FIELD_NONE; 4237da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* assume V4L2_PIX_FMT_SBGGR8 */ 4247da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_SBGGR8; 4257da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 4267da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 4277da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* if sub device supports g_fmt, override the defaults */ 4287da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = v4l2_device_call_until_err(&vpfe_dev->v4l2_dev, 4297da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri sdinfo->grp_id, video, g_fmt, &vpfe_dev->fmt); 4307da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 4317da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (ret && ret != -ENOIOCTLCMD) { 4327da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(&vpfe_dev->v4l2_dev, 4337da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri "error in getting g_fmt from sub device\n"); 4347da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return ret; 4357da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 4367da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 4377da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* Sets the values in CCDC */ 4387da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = vpfe_config_ccdc_image_format(vpfe_dev); 4397da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (ret) 4407da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return ret; 4417da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 4427da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* Update the values of sizeimage and bytesperline */ 4437da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (!ret) { 4447da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->fmt.fmt.pix.bytesperline = 4457da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ccdc_dev->hw_ops.get_line_length(); 4467da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->fmt.fmt.pix.sizeimage = 4477da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->fmt.fmt.pix.bytesperline * 4487da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->fmt.fmt.pix.height; 4497da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 4507da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return ret; 4517da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 4527da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 4537da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic int vpfe_initialize_device(struct vpfe_device *vpfe_dev) 4547da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 4557da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri int ret = 0; 4567da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 4577da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* set first input of current subdevice as the current input */ 4587da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->current_input = 0; 4597da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 4607da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* set default standard */ 4617da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->std_index = 0; 4627da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 4637da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* Configure the default format information */ 4647da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = vpfe_config_image_format(vpfe_dev, 4657da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri &vpfe_standards[vpfe_dev->std_index].std_id); 4667da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (ret) 4677da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return ret; 4687da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 4697da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* now open the ccdc device to initialize it */ 4707da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri mutex_lock(&ccdc_lock); 4717da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (NULL == ccdc_dev) { 4727da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(&vpfe_dev->v4l2_dev, "ccdc device not registered\n"); 4737da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = -ENODEV; 4747da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri goto unlock; 4757da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 4767da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 4777da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (!try_module_get(ccdc_dev->owner)) { 4787da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(&vpfe_dev->v4l2_dev, "Couldn't lock ccdc module\n"); 4797da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = -ENODEV; 4807da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri goto unlock; 4817da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 4827da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = ccdc_dev->hw_ops.open(vpfe_dev->pdev); 4837da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (!ret) 4847da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->initialized = 1; 4857da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheriunlock: 4867da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri mutex_unlock(&ccdc_lock); 4877da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return ret; 4887da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 4897da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 4907da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri/* 4917da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * vpfe_open : It creates object of file handle structure and 4927da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * stores it in private_data member of filepointer 4937da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri */ 4947da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic int vpfe_open(struct file *file) 4957da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 4967da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_device *vpfe_dev = video_drvdata(file); 4977da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_fh *fh; 4987da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 4997da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_open\n"); 5007da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 5017da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (!vpfe_dev->cfg->num_subdevs) { 5027da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(&vpfe_dev->v4l2_dev, "No decoder registered\n"); 5037da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return -ENODEV; 5047da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 5057da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 5067da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* Allocate memory for the file handle object */ 5077da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri fh = kmalloc(sizeof(struct vpfe_fh), GFP_KERNEL); 5087da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (NULL == fh) { 5097da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(&vpfe_dev->v4l2_dev, 5107da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri "unable to allocate memory for file handle object\n"); 5117da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return -ENOMEM; 5127da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 5137da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* store pointer to fh in private_data member of file */ 5147da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri file->private_data = fh; 5157da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri fh->vpfe_dev = vpfe_dev; 5167da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri mutex_lock(&vpfe_dev->lock); 5177da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* If decoder is not initialized. initialize it */ 5187da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (!vpfe_dev->initialized) { 5197da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (vpfe_initialize_device(vpfe_dev)) { 5207da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri mutex_unlock(&vpfe_dev->lock); 5217da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return -ENODEV; 5227da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 5237da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 5247da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* Increment device usrs counter */ 5257da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->usrs++; 5267da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* Set io_allowed member to false */ 5277da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri fh->io_allowed = 0; 5287da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* Initialize priority of this instance to default priority */ 5297da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri fh->prio = V4L2_PRIORITY_UNSET; 5307da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_prio_open(&vpfe_dev->prio, &fh->prio); 5317da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri mutex_unlock(&vpfe_dev->lock); 5327da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return 0; 5337da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 5347da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 5357da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic void vpfe_schedule_next_buffer(struct vpfe_device *vpfe_dev) 5367da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 5377da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri unsigned long addr; 5387da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 5397da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->next_frm = list_entry(vpfe_dev->dma_queue.next, 5407da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct videobuf_buffer, queue); 5417da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri list_del(&vpfe_dev->next_frm->queue); 5427da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->next_frm->state = VIDEOBUF_ACTIVE; 5437da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri addr = videobuf_to_dma_contig(vpfe_dev->next_frm); 5447da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ccdc_dev->hw_ops.setfbaddr(addr); 5457da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 5467da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 5477da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic void vpfe_process_buffer_complete(struct vpfe_device *vpfe_dev) 5487da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 5497da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct timeval timevalue; 5507da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 5517da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri do_gettimeofday(&timevalue); 5527da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->cur_frm->ts = timevalue; 5537da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->cur_frm->state = VIDEOBUF_DONE; 5547da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->cur_frm->size = vpfe_dev->fmt.fmt.pix.sizeimage; 5557da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri wake_up_interruptible(&vpfe_dev->cur_frm->done); 5567da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->cur_frm = vpfe_dev->next_frm; 5577da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 5587da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 5597da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri/* ISR for VINT0*/ 5607da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic irqreturn_t vpfe_isr(int irq, void *dev_id) 5617da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 5627da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_device *vpfe_dev = dev_id; 5637da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri enum v4l2_field field; 5647da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri unsigned long addr; 5657da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri int fid; 5667da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 5677da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "\nStarting vpfe_isr...\n"); 5687da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri field = vpfe_dev->fmt.fmt.pix.field; 5697da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 5707da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* if streaming not started, don't do anything */ 5717da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (!vpfe_dev->started) 5727da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return IRQ_HANDLED; 5737da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 5747da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* only for 6446 this will be applicable */ 5757da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (NULL != ccdc_dev->hw_ops.reset) 5767da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ccdc_dev->hw_ops.reset(); 5777da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 5787da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (field == V4L2_FIELD_NONE) { 5797da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* handle progressive frame capture */ 5807da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, 5817da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri "frame format is progressive...\n"); 5827da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (vpfe_dev->cur_frm != vpfe_dev->next_frm) 5837da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_process_buffer_complete(vpfe_dev); 5847da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return IRQ_HANDLED; 5857da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 5867da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 5877da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* interlaced or TB capture check which field we are in hardware */ 5887da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri fid = ccdc_dev->hw_ops.getfid(); 5897da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 5907da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* switch the software maintained field id */ 5917da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->field_id ^= 1; 5927da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "field id = %x:%x.\n", 5937da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri fid, vpfe_dev->field_id); 5947da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (fid == vpfe_dev->field_id) { 5957da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* we are in-sync here,continue */ 5967da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (fid == 0) { 5977da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* 5987da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * One frame is just being captured. If the next frame 5997da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * is available, release the current frame and move on 6007da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri */ 6017da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (vpfe_dev->cur_frm != vpfe_dev->next_frm) 6027da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_process_buffer_complete(vpfe_dev); 6037da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* 6047da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * based on whether the two fields are stored 6057da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * interleavely or separately in memory, reconfigure 6067da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * the CCDC memory address 6077da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri */ 6087da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (field == V4L2_FIELD_SEQ_TB) { 6097da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri addr = 6107da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri videobuf_to_dma_contig(vpfe_dev->cur_frm); 6117da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri addr += vpfe_dev->field_off; 6127da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ccdc_dev->hw_ops.setfbaddr(addr); 6137da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 6147da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return IRQ_HANDLED; 6157da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 6167da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* 6177da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * if one field is just being captured configure 6187da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * the next frame get the next frame from the empty 6197da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * queue if no frame is available hold on to the 6207da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * current buffer 6217da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri */ 6227da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri spin_lock(&vpfe_dev->dma_queue_lock); 6237da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (!list_empty(&vpfe_dev->dma_queue) && 6247da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->cur_frm == vpfe_dev->next_frm) 6257da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_schedule_next_buffer(vpfe_dev); 6267da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri spin_unlock(&vpfe_dev->dma_queue_lock); 6277da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } else if (fid == 0) { 6287da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* 6297da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * out of sync. Recover from any hardware out-of-sync. 6307da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * May loose one frame 6317da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri */ 6327da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->field_id = fid; 6337da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 6347da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return IRQ_HANDLED; 6357da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 6367da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 6377da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri/* vdint1_isr - isr handler for VINT1 interrupt */ 6387da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic irqreturn_t vdint1_isr(int irq, void *dev_id) 6397da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 6407da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_device *vpfe_dev = dev_id; 6417da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 6427da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "\nInside vdint1_isr...\n"); 6437da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 6447da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* if streaming not started, don't do anything */ 6457da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (!vpfe_dev->started) 6467da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return IRQ_HANDLED; 6477da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 6487da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri spin_lock(&vpfe_dev->dma_queue_lock); 6497da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if ((vpfe_dev->fmt.fmt.pix.field == V4L2_FIELD_NONE) && 6507da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri !list_empty(&vpfe_dev->dma_queue) && 6517da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->cur_frm == vpfe_dev->next_frm) 6527da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_schedule_next_buffer(vpfe_dev); 6537da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri spin_unlock(&vpfe_dev->dma_queue_lock); 6547da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return IRQ_HANDLED; 6557da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 6567da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 6577da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic void vpfe_detach_irq(struct vpfe_device *vpfe_dev) 6587da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 6597da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri enum ccdc_frmfmt frame_format; 6607da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 6617da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri frame_format = ccdc_dev->hw_ops.get_frame_format(); 6627da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (frame_format == CCDC_FRMFMT_PROGRESSIVE) 6631ead696b4c1b719eeae313618bca89e7b37c7d9bVaibhav Hiremath free_irq(vpfe_dev->ccdc_irq1, vpfe_dev); 6647da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 6657da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 6667da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic int vpfe_attach_irq(struct vpfe_device *vpfe_dev) 6677da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 6687da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri enum ccdc_frmfmt frame_format; 6697da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 6707da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri frame_format = ccdc_dev->hw_ops.get_frame_format(); 6717da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (frame_format == CCDC_FRMFMT_PROGRESSIVE) { 6727da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return request_irq(vpfe_dev->ccdc_irq1, vdint1_isr, 6737da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri IRQF_DISABLED, "vpfe_capture1", 6747da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev); 6757da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 6767da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return 0; 6777da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 6787da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 6797da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri/* vpfe_stop_ccdc_capture: stop streaming in ccdc/isif */ 6807da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic void vpfe_stop_ccdc_capture(struct vpfe_device *vpfe_dev) 6817da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 6827da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->started = 0; 6837da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ccdc_dev->hw_ops.enable(0); 6847da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (ccdc_dev->hw_ops.enable_out_to_sdram) 6857da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ccdc_dev->hw_ops.enable_out_to_sdram(0); 6867da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 6877da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 6887da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri/* 6897da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * vpfe_release : This function deletes buffer queue, frees the 6907da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * buffers and the vpfe file handle 6917da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri */ 6927da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic int vpfe_release(struct file *file) 6937da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 6947da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_device *vpfe_dev = video_drvdata(file); 6957da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_fh *fh = file->private_data; 6967da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_subdev_info *sdinfo; 6977da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri int ret; 6987da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 6997da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_release\n"); 7007da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 7017da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* Get the device lock */ 7027da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri mutex_lock(&vpfe_dev->lock); 7037da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* if this instance is doing IO */ 7047da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (fh->io_allowed) { 7057da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (vpfe_dev->started) { 7067da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri sdinfo = vpfe_dev->current_subdev; 7077da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = v4l2_device_call_until_err(&vpfe_dev->v4l2_dev, 7087da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri sdinfo->grp_id, 7097da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri video, s_stream, 0); 7107da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (ret && (ret != -ENOIOCTLCMD)) 7117da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(&vpfe_dev->v4l2_dev, 7127da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri "stream off failed in subdev\n"); 7137da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_stop_ccdc_capture(vpfe_dev); 7147da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_detach_irq(vpfe_dev); 7157da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri videobuf_streamoff(&vpfe_dev->buffer_queue); 7167da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 7177da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->io_usrs = 0; 7187da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->numbuffers = config_params.numbuffers; 7197da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 7207da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 7217da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* Decrement device usrs counter */ 7227da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->usrs--; 7237da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* Close the priority */ 7247da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_prio_close(&vpfe_dev->prio, &fh->prio); 7257da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* If this is the last file handle */ 7267da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (!vpfe_dev->usrs) { 7277da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->initialized = 0; 7287da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (ccdc_dev->hw_ops.close) 7297da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ccdc_dev->hw_ops.close(vpfe_dev->pdev); 7307da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri module_put(ccdc_dev->owner); 7317da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 7327da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri mutex_unlock(&vpfe_dev->lock); 7337da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri file->private_data = NULL; 7347da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* Free memory allocated to file handle object */ 7357da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri kfree(fh); 7367da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return 0; 7377da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 7387da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 7397da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri/* 7407da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * vpfe_mmap : It is used to map kernel space buffers 7417da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * into user spaces 7427da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri */ 7437da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic int vpfe_mmap(struct file *file, struct vm_area_struct *vma) 7447da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 7457da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* Get the device object and file handle object */ 7467da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_device *vpfe_dev = video_drvdata(file); 7477da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 7487da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_mmap\n"); 7497da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 7507da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return videobuf_mmap_mapper(&vpfe_dev->buffer_queue, vma); 7517da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 7527da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 7537da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri/* 7547da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * vpfe_poll: It is used for select/poll system call 7557da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri */ 7567da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic unsigned int vpfe_poll(struct file *file, poll_table *wait) 7577da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 7587da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_device *vpfe_dev = video_drvdata(file); 7597da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 7607da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_poll\n"); 7617da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 7627da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (vpfe_dev->started) 7637da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return videobuf_poll_stream(file, 7647da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri &vpfe_dev->buffer_queue, wait); 7657da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return 0; 7667da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 7677da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 7687da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri/* vpfe capture driver file operations */ 7697da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic const struct v4l2_file_operations vpfe_fops = { 7707da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .owner = THIS_MODULE, 7717da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .open = vpfe_open, 7727da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .release = vpfe_release, 7737da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .unlocked_ioctl = video_ioctl2, 7747da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .mmap = vpfe_mmap, 7757da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .poll = vpfe_poll 7767da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri}; 7777da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 7787da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri/* 7797da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * vpfe_check_format() 7807da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * This function adjust the input pixel format as per hardware 7817da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * capabilities and update the same in pixfmt. 7827da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * Following algorithm used :- 7837da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * 7847da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * If given pixformat is not in the vpfe list of pix formats or not 7857da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * supported by the hardware, current value of pixformat in the device 7867da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * is used 7877da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * If given field is not supported, then current field is used. If field 7887da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * is different from current, then it is matched with that from sub device. 7897da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * Minimum height is 2 lines for interlaced or tb field and 1 line for 7907da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * progressive. Maximum height is clamped to active active lines of scan 7917da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * Minimum width is 32 bytes in memory and width is clamped to active 7927da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * pixels of scan. 7937da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * bytesperline is a multiple of 32. 7947da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri */ 7957da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic const struct vpfe_pixel_format * 7967da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_check_format(struct vpfe_device *vpfe_dev, 7977da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct v4l2_pix_format *pixfmt) 7987da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 7997da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri u32 min_height = 1, min_width = 32, max_width, max_height; 8007da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri const struct vpfe_pixel_format *vpfe_pix_fmt; 8017da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri u32 pix; 8027da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri int temp, found; 8037da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 8047da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_pix_fmt = vpfe_lookup_pix_format(pixfmt->pixelformat); 8057da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (NULL == vpfe_pix_fmt) { 8067da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* 8077da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * use current pixel format in the vpfe device. We 8087da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * will find this pix format in the table 8097da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri */ 8107da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri pixfmt->pixelformat = vpfe_dev->fmt.fmt.pix.pixelformat; 8117da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_pix_fmt = vpfe_lookup_pix_format(pixfmt->pixelformat); 8127da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 8137da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 8147da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* check if hw supports it */ 8157da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri temp = 0; 8167da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri found = 0; 8177da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri while (ccdc_dev->hw_ops.enum_pix(&pix, temp) >= 0) { 8187da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (vpfe_pix_fmt->fmtdesc.pixelformat == pix) { 8197da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri found = 1; 8207da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri break; 8217da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 8227da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri temp++; 8237da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 8247da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 8257da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (!found) { 8267da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* use current pixel format */ 8277da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri pixfmt->pixelformat = vpfe_dev->fmt.fmt.pix.pixelformat; 8287da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* 8297da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * Since this is currently used in the vpfe device, we 8307da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * will find this pix format in the table 8317da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri */ 8327da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_pix_fmt = vpfe_lookup_pix_format(pixfmt->pixelformat); 8337da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 8347da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 8357da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* check what field format is supported */ 8367da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (pixfmt->field == V4L2_FIELD_ANY) { 8377da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* if field is any, use current value as default */ 8387da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri pixfmt->field = vpfe_dev->fmt.fmt.pix.field; 8397da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 8407da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 8417da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* 8427da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * if field is not same as current field in the vpfe device 8437da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * try matching the field with the sub device field 8447da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri */ 8457da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (vpfe_dev->fmt.fmt.pix.field != pixfmt->field) { 8467da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* 8477da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * If field value is not in the supported fields, use current 8487da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * field used in the device as default 8497da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri */ 8507da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri switch (pixfmt->field) { 8517da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri case V4L2_FIELD_INTERLACED: 8527da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri case V4L2_FIELD_SEQ_TB: 8537da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* if sub device is supporting progressive, use that */ 8547da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (!vpfe_dev->std_info.frame_format) 8557da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri pixfmt->field = V4L2_FIELD_NONE; 8567da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri break; 8577da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri case V4L2_FIELD_NONE: 8587da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (vpfe_dev->std_info.frame_format) 8597da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri pixfmt->field = V4L2_FIELD_INTERLACED; 8607da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri break; 8617da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 8627da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri default: 8637da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* use current field as default */ 8647da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri pixfmt->field = vpfe_dev->fmt.fmt.pix.field; 8657da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri break; 8667da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 8677da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 8687da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 8697da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* Now adjust image resolutions supported */ 8707da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (pixfmt->field == V4L2_FIELD_INTERLACED || 8717da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri pixfmt->field == V4L2_FIELD_SEQ_TB) 8727da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri min_height = 2; 8737da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 8747da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri max_width = vpfe_dev->std_info.active_pixels; 8757da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri max_height = vpfe_dev->std_info.active_lines; 8767da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri min_width /= vpfe_pix_fmt->bpp; 8777da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 8787da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_info(&vpfe_dev->v4l2_dev, "width = %d, height = %d, bpp = %d\n", 8797da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri pixfmt->width, pixfmt->height, vpfe_pix_fmt->bpp); 8807da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 8817da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri pixfmt->width = clamp((pixfmt->width), min_width, max_width); 8827da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri pixfmt->height = clamp((pixfmt->height), min_height, max_height); 8837da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 8847da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* If interlaced, adjust height to be a multiple of 2 */ 8857da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (pixfmt->field == V4L2_FIELD_INTERLACED) 8867da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri pixfmt->height &= (~1); 8877da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* 8887da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * recalculate bytesperline and sizeimage since width 8897da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * and height might have changed 8907da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri */ 8917da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri pixfmt->bytesperline = (((pixfmt->width * vpfe_pix_fmt->bpp) + 31) 8927da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri & ~31); 8937da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (pixfmt->pixelformat == V4L2_PIX_FMT_NV12) 8947da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri pixfmt->sizeimage = 8957da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri pixfmt->bytesperline * pixfmt->height + 8967da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ((pixfmt->bytesperline * pixfmt->height) >> 1); 8977da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri else 8987da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri pixfmt->sizeimage = pixfmt->bytesperline * pixfmt->height; 8997da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 9007da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_info(&vpfe_dev->v4l2_dev, "adjusted width = %d, height =" 9017da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri " %d, bpp = %d, bytesperline = %d, sizeimage = %d\n", 9027da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri pixfmt->width, pixfmt->height, vpfe_pix_fmt->bpp, 9037da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri pixfmt->bytesperline, pixfmt->sizeimage); 9047da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return vpfe_pix_fmt; 9057da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 9067da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 9077da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic int vpfe_querycap(struct file *file, void *priv, 9087da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct v4l2_capability *cap) 9097da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 9107da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_device *vpfe_dev = video_drvdata(file); 9117da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 9127da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_querycap\n"); 9137da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 9147da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri cap->version = VPFE_CAPTURE_VERSION_CODE; 9157da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; 9167da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri strlcpy(cap->driver, CAPTURE_DRV_NAME, sizeof(cap->driver)); 9177da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri strlcpy(cap->bus_info, "VPFE", sizeof(cap->bus_info)); 9187da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri strlcpy(cap->card, vpfe_dev->cfg->card_name, sizeof(cap->card)); 9197da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return 0; 9207da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 9217da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 9227da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic int vpfe_g_fmt_vid_cap(struct file *file, void *priv, 9237da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct v4l2_format *fmt) 9247da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 9257da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_device *vpfe_dev = video_drvdata(file); 9267da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri int ret = 0; 9277da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 9287da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_g_fmt_vid_cap\n"); 9297da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* Fill in the information about format */ 9307da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri *fmt = vpfe_dev->fmt; 9317da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return ret; 9327da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 9337da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 9347da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic int vpfe_enum_fmt_vid_cap(struct file *file, void *priv, 9357da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct v4l2_fmtdesc *fmt) 9367da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 9377da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_device *vpfe_dev = video_drvdata(file); 9387da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri const struct vpfe_pixel_format *pix_fmt; 9397da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri int temp_index; 9407da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri u32 pix; 9417da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 9427da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_enum_fmt_vid_cap\n"); 9437da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 9447da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (ccdc_dev->hw_ops.enum_pix(&pix, fmt->index) < 0) 9457da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return -EINVAL; 9467da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 9477da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* Fill in the information about format */ 9487da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri pix_fmt = vpfe_lookup_pix_format(pix); 9497da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (NULL != pix_fmt) { 9507da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri temp_index = fmt->index; 9517da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri *fmt = pix_fmt->fmtdesc; 9527da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri fmt->index = temp_index; 9537da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return 0; 9547da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 9557da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return -EINVAL; 9567da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 9577da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 9587da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic int vpfe_s_fmt_vid_cap(struct file *file, void *priv, 9597da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct v4l2_format *fmt) 9607da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 9617da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_device *vpfe_dev = video_drvdata(file); 9627da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri const struct vpfe_pixel_format *pix_fmts; 9637da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri int ret = 0; 9647da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 9657da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_s_fmt_vid_cap\n"); 9667da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 9677da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* If streaming is started, return error */ 9687da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (vpfe_dev->started) { 9697da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(&vpfe_dev->v4l2_dev, "Streaming is started\n"); 9707da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return -EBUSY; 9717da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 9727da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 9737da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* Check for valid frame format */ 9747da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri pix_fmts = vpfe_check_format(vpfe_dev, &fmt->fmt.pix); 9757da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 9767da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (NULL == pix_fmts) 9777da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return -EINVAL; 9787da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 9797da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* store the pixel format in the device object */ 9807da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = mutex_lock_interruptible(&vpfe_dev->lock); 9817da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (ret) 9827da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return ret; 9837da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 9847da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* First detach any IRQ if currently attached */ 9857da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_detach_irq(vpfe_dev); 9867da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->fmt = *fmt; 9877da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* set image capture parameters in the ccdc */ 9887da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = vpfe_config_ccdc_image_format(vpfe_dev); 9897da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri mutex_unlock(&vpfe_dev->lock); 9907da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return ret; 9917da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 9927da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 9937da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic int vpfe_try_fmt_vid_cap(struct file *file, void *priv, 9947da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct v4l2_format *f) 9957da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 9967da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_device *vpfe_dev = video_drvdata(file); 9977da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri const struct vpfe_pixel_format *pix_fmts; 9987da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 9997da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_try_fmt_vid_cap\n"); 10007da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 10017da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri pix_fmts = vpfe_check_format(vpfe_dev, &f->fmt.pix); 10027da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (NULL == pix_fmts) 10037da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return -EINVAL; 10047da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return 0; 10057da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 10067da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 10077da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri/* 10087da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * vpfe_get_subdev_input_index - Get subdev index and subdev input index for a 10097da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * given app input index 10107da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri */ 10117da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic int vpfe_get_subdev_input_index(struct vpfe_device *vpfe_dev, 10127da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri int *subdev_index, 10137da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri int *subdev_input_index, 10147da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri int app_input_index) 10157da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 10167da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_config *cfg = vpfe_dev->cfg; 10177da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_subdev_info *sdinfo; 10187da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri int i, j = 0; 10197da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 10207da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri for (i = 0; i < cfg->num_subdevs; i++) { 10217da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri sdinfo = &cfg->sub_devs[i]; 10227da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (app_input_index < (j + sdinfo->num_inputs)) { 10237da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri *subdev_index = i; 10247da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri *subdev_input_index = app_input_index - j; 10257da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return 0; 10267da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 10277da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri j += sdinfo->num_inputs; 10287da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 10297da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return -EINVAL; 10307da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 10317da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 10327da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri/* 10337da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * vpfe_get_app_input - Get app input index for a given subdev input index 10347da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * driver stores the input index of the current sub device and translate it 10357da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * when application request the current input 10367da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri */ 10377da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic int vpfe_get_app_input_index(struct vpfe_device *vpfe_dev, 10387da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri int *app_input_index) 10397da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 10407da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_config *cfg = vpfe_dev->cfg; 10417da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_subdev_info *sdinfo; 10427da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri int i, j = 0; 10437da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 10447da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri for (i = 0; i < cfg->num_subdevs; i++) { 10457da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri sdinfo = &cfg->sub_devs[i]; 10467da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (!strcmp(sdinfo->name, vpfe_dev->current_subdev->name)) { 10477da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (vpfe_dev->current_input >= sdinfo->num_inputs) 10487da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return -1; 10497da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri *app_input_index = j + vpfe_dev->current_input; 10507da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return 0; 10517da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 10527da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri j += sdinfo->num_inputs; 10537da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 10547da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return -EINVAL; 10557da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 10567da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 10577da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic int vpfe_enum_input(struct file *file, void *priv, 10587da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct v4l2_input *inp) 10597da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 10607da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_device *vpfe_dev = video_drvdata(file); 10617da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_subdev_info *sdinfo; 10627da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri int subdev, index ; 10637da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 10647da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_enum_input\n"); 10657da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 10667da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (vpfe_get_subdev_input_index(vpfe_dev, 10677da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri &subdev, 10687da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri &index, 10697da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri inp->index) < 0) { 10707da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(&vpfe_dev->v4l2_dev, "input information not found" 10717da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri " for the subdev\n"); 10727da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return -EINVAL; 10737da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 10747da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri sdinfo = &vpfe_dev->cfg->sub_devs[subdev]; 10757da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri memcpy(inp, &sdinfo->inputs[index], sizeof(struct v4l2_input)); 10767da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return 0; 10777da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 10787da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 10797da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic int vpfe_g_input(struct file *file, void *priv, unsigned int *index) 10807da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 10817da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_device *vpfe_dev = video_drvdata(file); 10827da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 10837da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_g_input\n"); 10847da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 10857da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return vpfe_get_app_input_index(vpfe_dev, index); 10867da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 10877da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 10887da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 10897da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic int vpfe_s_input(struct file *file, void *priv, unsigned int index) 10907da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 10917da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_device *vpfe_dev = video_drvdata(file); 10927da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_subdev_info *sdinfo; 10937da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri int subdev_index, inp_index; 10947da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_route *route; 10957da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri u32 input = 0, output = 0; 10967da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri int ret = -EINVAL; 10977da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 10987da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_s_input\n"); 10997da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 11007da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = mutex_lock_interruptible(&vpfe_dev->lock); 11017da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (ret) 11027da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return ret; 11037da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 11047da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* 11057da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * If streaming is started return device busy 11067da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * error 11077da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri */ 11087da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (vpfe_dev->started) { 11097da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(&vpfe_dev->v4l2_dev, "Streaming is on\n"); 11107da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = -EBUSY; 11117da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri goto unlock_out; 11127da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 11137da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 11147da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (vpfe_get_subdev_input_index(vpfe_dev, 11157da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri &subdev_index, 11167da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri &inp_index, 11177da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri index) < 0) { 11187da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(&vpfe_dev->v4l2_dev, "invalid input index\n"); 11197da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri goto unlock_out; 11207da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 11217da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 11227da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri sdinfo = &vpfe_dev->cfg->sub_devs[subdev_index]; 11237da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri route = &sdinfo->routes[inp_index]; 11247da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (route && sdinfo->can_route) { 11257da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri input = route->input; 11267da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri output = route->output; 11277da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 11287da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 11297da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = v4l2_device_call_until_err(&vpfe_dev->v4l2_dev, sdinfo->grp_id, 11307da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri video, s_routing, input, output, 0); 11317da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 11327da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (ret) { 11337da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(&vpfe_dev->v4l2_dev, 11347da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri "vpfe_doioctl:error in setting input in decoder\n"); 11357da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = -EINVAL; 11367da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri goto unlock_out; 11377da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 11387da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->current_subdev = sdinfo; 11397da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->current_input = index; 11407da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->std_index = 0; 11417da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 11427da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* set the bus/interface parameter for the sub device in ccdc */ 11437da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = ccdc_dev->hw_ops.set_hw_if_params(&sdinfo->ccdc_if_params); 11447da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (ret) 11457da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri goto unlock_out; 11467da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 11477da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* set the default image parameters in the device */ 11487da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = vpfe_config_image_format(vpfe_dev, 11497da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri &vpfe_standards[vpfe_dev->std_index].std_id); 11507da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheriunlock_out: 11517da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri mutex_unlock(&vpfe_dev->lock); 11527da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return ret; 11537da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 11547da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 11557da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic int vpfe_querystd(struct file *file, void *priv, v4l2_std_id *std_id) 11567da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 11577da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_device *vpfe_dev = video_drvdata(file); 11587da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_subdev_info *sdinfo; 11597da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri int ret = 0; 11607da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 11617da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_querystd\n"); 11627da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 11637da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = mutex_lock_interruptible(&vpfe_dev->lock); 11647da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri sdinfo = vpfe_dev->current_subdev; 11657da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (ret) 11667da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return ret; 11677da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* Call querystd function of decoder device */ 11687da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = v4l2_device_call_until_err(&vpfe_dev->v4l2_dev, sdinfo->grp_id, 11697da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri video, querystd, std_id); 11707da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri mutex_unlock(&vpfe_dev->lock); 11717da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return ret; 11727da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 11737da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 11747da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic int vpfe_s_std(struct file *file, void *priv, v4l2_std_id *std_id) 11757da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 11767da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_device *vpfe_dev = video_drvdata(file); 11777da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_subdev_info *sdinfo; 11787da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri int ret = 0; 11797da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 11807da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_s_std\n"); 11817da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 11827da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* Call decoder driver function to set the standard */ 11837da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = mutex_lock_interruptible(&vpfe_dev->lock); 11847da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (ret) 11857da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return ret; 11867da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 11877da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri sdinfo = vpfe_dev->current_subdev; 11887da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* If streaming is started, return device busy error */ 11897da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (vpfe_dev->started) { 11907da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(&vpfe_dev->v4l2_dev, "streaming is started\n"); 11917da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = -EBUSY; 11927da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri goto unlock_out; 11937da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 11947da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 11957da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = v4l2_device_call_until_err(&vpfe_dev->v4l2_dev, sdinfo->grp_id, 11967da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri core, s_std, *std_id); 11977da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (ret < 0) { 11987da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(&vpfe_dev->v4l2_dev, "Failed to set standard\n"); 11997da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri goto unlock_out; 12007da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 12017da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = vpfe_config_image_format(vpfe_dev, std_id); 12027da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 12037da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheriunlock_out: 12047da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri mutex_unlock(&vpfe_dev->lock); 12057da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return ret; 12067da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 12077da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 12087da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic int vpfe_g_std(struct file *file, void *priv, v4l2_std_id *std_id) 12097da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 12107da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_device *vpfe_dev = video_drvdata(file); 12117da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 12127da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_g_std\n"); 12137da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 12147da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri *std_id = vpfe_standards[vpfe_dev->std_index].std_id; 12157da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return 0; 12167da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 12177da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri/* 12187da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * Videobuf operations 12197da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri */ 12207da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic int vpfe_videobuf_setup(struct videobuf_queue *vq, 12217da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri unsigned int *count, 12227da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri unsigned int *size) 12237da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 12247da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_fh *fh = vq->priv_data; 12257da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_device *vpfe_dev = fh->vpfe_dev; 12267da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 12277da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_buffer_setup\n"); 12287da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri *size = config_params.device_bufsize; 12297da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 12307da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (*count < config_params.min_numbuffers) 12317da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri *count = config_params.min_numbuffers; 12327da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, 12337da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri "count=%d, size=%d\n", *count, *size); 12347da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return 0; 12357da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 12367da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 12377da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic int vpfe_videobuf_prepare(struct videobuf_queue *vq, 12387da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct videobuf_buffer *vb, 12397da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri enum v4l2_field field) 12407da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 12417da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_fh *fh = vq->priv_data; 12427da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_device *vpfe_dev = fh->vpfe_dev; 12437da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 12447da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_buffer_prepare\n"); 12457da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 12467da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* If buffer is not initialized, initialize it */ 12477da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (VIDEOBUF_NEEDS_INIT == vb->state) { 12487da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vb->width = vpfe_dev->fmt.fmt.pix.width; 12497da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vb->height = vpfe_dev->fmt.fmt.pix.height; 12507da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vb->size = vpfe_dev->fmt.fmt.pix.sizeimage; 12517da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vb->field = field; 12527da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 12537da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vb->state = VIDEOBUF_PREPARED; 12547da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return 0; 12557da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 12567da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 12577da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic void vpfe_videobuf_queue(struct videobuf_queue *vq, 12587da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct videobuf_buffer *vb) 12597da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 12607da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* Get the file handle object and device object */ 12617da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_fh *fh = vq->priv_data; 12627da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_device *vpfe_dev = fh->vpfe_dev; 12637da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri unsigned long flags; 12647da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 12657da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_buffer_queue\n"); 12667da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 12677da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* add the buffer to the DMA queue */ 12687da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri spin_lock_irqsave(&vpfe_dev->dma_queue_lock, flags); 12697da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri list_add_tail(&vb->queue, &vpfe_dev->dma_queue); 12707da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri spin_unlock_irqrestore(&vpfe_dev->dma_queue_lock, flags); 12717da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 12727da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* Change state of the buffer */ 12737da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vb->state = VIDEOBUF_QUEUED; 12747da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 12757da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 12767da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic void vpfe_videobuf_release(struct videobuf_queue *vq, 12777da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct videobuf_buffer *vb) 12787da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 12797da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_fh *fh = vq->priv_data; 12807da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_device *vpfe_dev = fh->vpfe_dev; 12817da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri unsigned long flags; 12827da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 12837da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_videobuf_release\n"); 12847da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 12857da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* 12867da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * We need to flush the buffer from the dma queue since 12877da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * they are de-allocated 12887da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri */ 12897da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri spin_lock_irqsave(&vpfe_dev->dma_queue_lock, flags); 12907da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri INIT_LIST_HEAD(&vpfe_dev->dma_queue); 12917da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri spin_unlock_irqrestore(&vpfe_dev->dma_queue_lock, flags); 12927da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri videobuf_dma_contig_free(vq, vb); 12937da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vb->state = VIDEOBUF_NEEDS_INIT; 12947da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 12957da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 12967da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic struct videobuf_queue_ops vpfe_videobuf_qops = { 12977da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .buf_setup = vpfe_videobuf_setup, 12987da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .buf_prepare = vpfe_videobuf_prepare, 12997da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .buf_queue = vpfe_videobuf_queue, 13007da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .buf_release = vpfe_videobuf_release, 13017da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri}; 13027da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 13037da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri/* 13047da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * vpfe_reqbufs. currently support REQBUF only once opening 13057da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * the device. 13067da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri */ 13077da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic int vpfe_reqbufs(struct file *file, void *priv, 13087da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct v4l2_requestbuffers *req_buf) 13097da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 13107da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_device *vpfe_dev = video_drvdata(file); 13117da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_fh *fh = file->private_data; 13127da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri int ret = 0; 13137da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 13147da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_reqbufs\n"); 13157da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 13167da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (V4L2_BUF_TYPE_VIDEO_CAPTURE != req_buf->type) { 13177da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(&vpfe_dev->v4l2_dev, "Invalid buffer type\n"); 13187da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return -EINVAL; 13197da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 13207da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 13217da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (V4L2_MEMORY_USERPTR == req_buf->memory) { 13227da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* we don't support user ptr IO */ 13237da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_reqbufs:" 13247da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri " USERPTR IO not supported\n"); 13257da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return -EINVAL; 13267da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 13277da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 13287da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = mutex_lock_interruptible(&vpfe_dev->lock); 13297da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (ret) 13307da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return ret; 13317da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 13327da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (vpfe_dev->io_usrs != 0) { 13337da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(&vpfe_dev->v4l2_dev, "Only one IO user allowed\n"); 13347da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = -EBUSY; 13357da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri goto unlock_out; 13367da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 13377da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 13387da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->memory = req_buf->memory; 13397da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri videobuf_queue_dma_contig_init(&vpfe_dev->buffer_queue, 13407da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri &vpfe_videobuf_qops, 1341204e6ea981ac46974508ddf403dbb72dc804dcb3Vaibhav Hiremath vpfe_dev->pdev, 13427da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri &vpfe_dev->irqlock, 13437da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri req_buf->type, 13447da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->fmt.fmt.pix.field, 13457da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri sizeof(struct videobuf_buffer), 13467da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri fh); 13477da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 13487da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri fh->io_allowed = 1; 13497da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->io_usrs = 1; 13507da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri INIT_LIST_HEAD(&vpfe_dev->dma_queue); 13517da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = videobuf_reqbufs(&vpfe_dev->buffer_queue, req_buf); 13527da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheriunlock_out: 13537da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri mutex_unlock(&vpfe_dev->lock); 13547da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return ret; 13557da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 13567da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 13577da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic int vpfe_querybuf(struct file *file, void *priv, 13587da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct v4l2_buffer *buf) 13597da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 13607da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_device *vpfe_dev = video_drvdata(file); 13617da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 13627da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_querybuf\n"); 13637da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 13647da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (V4L2_BUF_TYPE_VIDEO_CAPTURE != buf->type) { 13657da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(&vpfe_dev->v4l2_dev, "Invalid buf type\n"); 13667da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return -EINVAL; 13677da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 13687da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 13697da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (vpfe_dev->memory != V4L2_MEMORY_MMAP) { 13707da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(&vpfe_dev->v4l2_dev, "Invalid memory\n"); 13717da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return -EINVAL; 13727da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 13737da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* Call videobuf_querybuf to get information */ 13747da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return videobuf_querybuf(&vpfe_dev->buffer_queue, buf); 13757da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 13767da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 13777da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic int vpfe_qbuf(struct file *file, void *priv, 13787da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct v4l2_buffer *p) 13797da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 13807da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_device *vpfe_dev = video_drvdata(file); 13817da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_fh *fh = file->private_data; 13827da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 13837da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_qbuf\n"); 13847da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 13857da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (V4L2_BUF_TYPE_VIDEO_CAPTURE != p->type) { 13867da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(&vpfe_dev->v4l2_dev, "Invalid buf type\n"); 13877da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return -EINVAL; 13887da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 13897da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 13907da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* 13917da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * If this file handle is not allowed to do IO, 13927da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * return error 13937da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri */ 13947da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (!fh->io_allowed) { 13957da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(&vpfe_dev->v4l2_dev, "fh->io_allowed\n"); 13967da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return -EACCES; 13977da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 13987da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return videobuf_qbuf(&vpfe_dev->buffer_queue, p); 13997da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 14007da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 14017da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic int vpfe_dqbuf(struct file *file, void *priv, 14027da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct v4l2_buffer *buf) 14037da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 14047da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_device *vpfe_dev = video_drvdata(file); 14057da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 14067da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_dqbuf\n"); 14077da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 14087da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (V4L2_BUF_TYPE_VIDEO_CAPTURE != buf->type) { 14097da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(&vpfe_dev->v4l2_dev, "Invalid buf type\n"); 14107da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return -EINVAL; 14117da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 14127da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return videobuf_dqbuf(&vpfe_dev->buffer_queue, 14137da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri buf, file->f_flags & O_NONBLOCK); 14147da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 14157da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 1416d73bfc5fe625f6962d0ced84066e201249f14e53Vaibhav Hiremathstatic int vpfe_queryctrl(struct file *file, void *priv, 1417d73bfc5fe625f6962d0ced84066e201249f14e53Vaibhav Hiremath struct v4l2_queryctrl *qctrl) 1418d73bfc5fe625f6962d0ced84066e201249f14e53Vaibhav Hiremath{ 1419d73bfc5fe625f6962d0ced84066e201249f14e53Vaibhav Hiremath struct vpfe_device *vpfe_dev = video_drvdata(file); 1420d73bfc5fe625f6962d0ced84066e201249f14e53Vaibhav Hiremath struct vpfe_subdev_info *sdinfo; 1421d73bfc5fe625f6962d0ced84066e201249f14e53Vaibhav Hiremath 1422d73bfc5fe625f6962d0ced84066e201249f14e53Vaibhav Hiremath sdinfo = vpfe_dev->current_subdev; 1423d73bfc5fe625f6962d0ced84066e201249f14e53Vaibhav Hiremath 1424d73bfc5fe625f6962d0ced84066e201249f14e53Vaibhav Hiremath return v4l2_device_call_until_err(&vpfe_dev->v4l2_dev, sdinfo->grp_id, 1425d73bfc5fe625f6962d0ced84066e201249f14e53Vaibhav Hiremath core, queryctrl, qctrl); 1426d73bfc5fe625f6962d0ced84066e201249f14e53Vaibhav Hiremath 1427d73bfc5fe625f6962d0ced84066e201249f14e53Vaibhav Hiremath} 1428d73bfc5fe625f6962d0ced84066e201249f14e53Vaibhav Hiremath 1429d73bfc5fe625f6962d0ced84066e201249f14e53Vaibhav Hiremathstatic int vpfe_g_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl) 1430d73bfc5fe625f6962d0ced84066e201249f14e53Vaibhav Hiremath{ 1431d73bfc5fe625f6962d0ced84066e201249f14e53Vaibhav Hiremath struct vpfe_device *vpfe_dev = video_drvdata(file); 1432d73bfc5fe625f6962d0ced84066e201249f14e53Vaibhav Hiremath struct vpfe_subdev_info *sdinfo; 1433d73bfc5fe625f6962d0ced84066e201249f14e53Vaibhav Hiremath 1434d73bfc5fe625f6962d0ced84066e201249f14e53Vaibhav Hiremath sdinfo = vpfe_dev->current_subdev; 1435d73bfc5fe625f6962d0ced84066e201249f14e53Vaibhav Hiremath 1436d73bfc5fe625f6962d0ced84066e201249f14e53Vaibhav Hiremath return v4l2_device_call_until_err(&vpfe_dev->v4l2_dev, sdinfo->grp_id, 1437d73bfc5fe625f6962d0ced84066e201249f14e53Vaibhav Hiremath core, g_ctrl, ctrl); 1438d73bfc5fe625f6962d0ced84066e201249f14e53Vaibhav Hiremath} 1439d73bfc5fe625f6962d0ced84066e201249f14e53Vaibhav Hiremath 1440d73bfc5fe625f6962d0ced84066e201249f14e53Vaibhav Hiremathstatic int vpfe_s_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl) 1441d73bfc5fe625f6962d0ced84066e201249f14e53Vaibhav Hiremath{ 1442d73bfc5fe625f6962d0ced84066e201249f14e53Vaibhav Hiremath struct vpfe_device *vpfe_dev = video_drvdata(file); 1443d73bfc5fe625f6962d0ced84066e201249f14e53Vaibhav Hiremath struct vpfe_subdev_info *sdinfo; 1444d73bfc5fe625f6962d0ced84066e201249f14e53Vaibhav Hiremath 1445d73bfc5fe625f6962d0ced84066e201249f14e53Vaibhav Hiremath sdinfo = vpfe_dev->current_subdev; 1446d73bfc5fe625f6962d0ced84066e201249f14e53Vaibhav Hiremath 1447d73bfc5fe625f6962d0ced84066e201249f14e53Vaibhav Hiremath return v4l2_device_call_until_err(&vpfe_dev->v4l2_dev, sdinfo->grp_id, 1448d73bfc5fe625f6962d0ced84066e201249f14e53Vaibhav Hiremath core, s_ctrl, ctrl); 1449d73bfc5fe625f6962d0ced84066e201249f14e53Vaibhav Hiremath} 1450d73bfc5fe625f6962d0ced84066e201249f14e53Vaibhav Hiremath 14517da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri/* 14527da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * vpfe_calculate_offsets : This function calculates buffers offset 14537da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * for top and bottom field 14547da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri */ 14557da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic void vpfe_calculate_offsets(struct vpfe_device *vpfe_dev) 14567da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 14577da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct v4l2_rect image_win; 14587da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 14597da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_calculate_offsets\n"); 14607da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 14617da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ccdc_dev->hw_ops.get_image_window(&image_win); 14627da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->field_off = image_win.height * image_win.width; 14637da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 14647da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 14657da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri/* vpfe_start_ccdc_capture: start streaming in ccdc/isif */ 14667da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic void vpfe_start_ccdc_capture(struct vpfe_device *vpfe_dev) 14677da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 14687da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ccdc_dev->hw_ops.enable(1); 14697da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (ccdc_dev->hw_ops.enable_out_to_sdram) 14707da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ccdc_dev->hw_ops.enable_out_to_sdram(1); 14717da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->started = 1; 14727da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 14737da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 14747da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri/* 14757da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * vpfe_streamon. Assume the DMA queue is not empty. 14767da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * application is expected to call QBUF before calling 14777da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * this ioctl. If not, driver returns error 14787da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri */ 14797da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic int vpfe_streamon(struct file *file, void *priv, 14807da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri enum v4l2_buf_type buf_type) 14817da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 14827da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_device *vpfe_dev = video_drvdata(file); 14837da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_fh *fh = file->private_data; 14847da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_subdev_info *sdinfo; 14857da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri unsigned long addr; 14867da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri int ret = 0; 14877da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 14887da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_streamon\n"); 14897da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 14907da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (V4L2_BUF_TYPE_VIDEO_CAPTURE != buf_type) { 14917da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(&vpfe_dev->v4l2_dev, "Invalid buf type\n"); 14927da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return -EINVAL; 14937da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 14947da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 14957da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* If file handle is not allowed IO, return error */ 14967da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (!fh->io_allowed) { 14977da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(&vpfe_dev->v4l2_dev, "fh->io_allowed\n"); 14987da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return -EACCES; 14997da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 15007da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 15017da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri sdinfo = vpfe_dev->current_subdev; 15027da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = v4l2_device_call_until_err(&vpfe_dev->v4l2_dev, sdinfo->grp_id, 15037da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri video, s_stream, 1); 15047da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 15057da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (ret && (ret != -ENOIOCTLCMD)) { 15067da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(&vpfe_dev->v4l2_dev, "stream on failed in subdev\n"); 15077da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return -EINVAL; 15087da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 15097da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 15107da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* If buffer queue is empty, return error */ 15117da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (list_empty(&vpfe_dev->buffer_queue.stream)) { 15127da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(&vpfe_dev->v4l2_dev, "buffer queue is empty\n"); 15137da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return -EIO; 15147da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 15157da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 15167da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* Call videobuf_streamon to start streaming * in videobuf */ 15177da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = videobuf_streamon(&vpfe_dev->buffer_queue); 15187da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (ret) 15197da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return ret; 15207da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 15217da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 15227da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = mutex_lock_interruptible(&vpfe_dev->lock); 15237da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (ret) 15247da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri goto streamoff; 15257da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* Get the next frame from the buffer queue */ 15267da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->next_frm = list_entry(vpfe_dev->dma_queue.next, 15277da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct videobuf_buffer, queue); 15287da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->cur_frm = vpfe_dev->next_frm; 15297da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* Remove buffer from the buffer queue */ 15307da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri list_del(&vpfe_dev->cur_frm->queue); 15317da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* Mark state of the current frame to active */ 15327da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->cur_frm->state = VIDEOBUF_ACTIVE; 15337da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* Initialize field_id and started member */ 15347da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->field_id = 0; 15357da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri addr = videobuf_to_dma_contig(vpfe_dev->cur_frm); 15367da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 15377da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* Calculate field offset */ 15387da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_calculate_offsets(vpfe_dev); 15397da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 15407da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (vpfe_attach_irq(vpfe_dev) < 0) { 15417da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(&vpfe_dev->v4l2_dev, 15427da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri "Error in attaching interrupt handle\n"); 15437da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = -EFAULT; 15447da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri goto unlock_out; 15457da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 15467da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (ccdc_dev->hw_ops.configure() < 0) { 15477da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(&vpfe_dev->v4l2_dev, 15487da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri "Error in configuring ccdc\n"); 15497da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = -EINVAL; 15507da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri goto unlock_out; 15517da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 15527da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ccdc_dev->hw_ops.setfbaddr((unsigned long)(addr)); 15537da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_start_ccdc_capture(vpfe_dev); 15547da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri mutex_unlock(&vpfe_dev->lock); 15557da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return ret; 15567da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheriunlock_out: 15577da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri mutex_unlock(&vpfe_dev->lock); 15587da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristreamoff: 15597da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = videobuf_streamoff(&vpfe_dev->buffer_queue); 15607da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return ret; 15617da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 15627da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 15637da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic int vpfe_streamoff(struct file *file, void *priv, 15647da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri enum v4l2_buf_type buf_type) 15657da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 15667da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_device *vpfe_dev = video_drvdata(file); 15677da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_fh *fh = file->private_data; 15687da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_subdev_info *sdinfo; 15697da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri int ret = 0; 15707da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 15717da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_streamoff\n"); 15727da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 15737da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (V4L2_BUF_TYPE_VIDEO_CAPTURE != buf_type) { 15747da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(&vpfe_dev->v4l2_dev, "Invalid buf type\n"); 15757da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return -EINVAL; 15767da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 15777da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 15787da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* If io is allowed for this file handle, return error */ 15797da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (!fh->io_allowed) { 15807da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(&vpfe_dev->v4l2_dev, "fh->io_allowed\n"); 15817da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return -EACCES; 15827da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 15837da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 15847da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* If streaming is not started, return error */ 15857da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (!vpfe_dev->started) { 15867da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(&vpfe_dev->v4l2_dev, "device started\n"); 15877da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return -EINVAL; 15887da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 15897da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 15907da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = mutex_lock_interruptible(&vpfe_dev->lock); 15917da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (ret) 15927da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return ret; 15937da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 15947da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_stop_ccdc_capture(vpfe_dev); 15957da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_detach_irq(vpfe_dev); 15967da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 15977da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri sdinfo = vpfe_dev->current_subdev; 15987da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = v4l2_device_call_until_err(&vpfe_dev->v4l2_dev, sdinfo->grp_id, 15997da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri video, s_stream, 0); 16007da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 16017da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (ret && (ret != -ENOIOCTLCMD)) 16027da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(&vpfe_dev->v4l2_dev, "stream off failed in subdev\n"); 16037da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = videobuf_streamoff(&vpfe_dev->buffer_queue); 16047da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri mutex_unlock(&vpfe_dev->lock); 16057da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return ret; 16067da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 16077da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 16087da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic int vpfe_cropcap(struct file *file, void *priv, 16097da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct v4l2_cropcap *crop) 16107da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 16117da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_device *vpfe_dev = video_drvdata(file); 16127da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 16137da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_cropcap\n"); 16147da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 16150b66cf90371dcd28c6eb98904adb694ae98eb20fRoel Kluin if (vpfe_dev->std_index >= ARRAY_SIZE(vpfe_standards)) 16167da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return -EINVAL; 16177da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 16187da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri memset(crop, 0, sizeof(struct v4l2_cropcap)); 16197da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri crop->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 16207da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri crop->bounds.width = crop->defrect.width = 16217da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_standards[vpfe_dev->std_index].width; 16227da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri crop->bounds.height = crop->defrect.height = 16237da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_standards[vpfe_dev->std_index].height; 16247da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri crop->pixelaspect = vpfe_standards[vpfe_dev->std_index].pixelaspect; 16257da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return 0; 16267da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 16277da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 16287da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic int vpfe_g_crop(struct file *file, void *priv, 16297da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct v4l2_crop *crop) 16307da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 16317da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_device *vpfe_dev = video_drvdata(file); 16327da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 16337da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_g_crop\n"); 16347da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 16357da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri crop->c = vpfe_dev->crop; 16367da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return 0; 16377da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 16387da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 16397da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic int vpfe_s_crop(struct file *file, void *priv, 16407da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct v4l2_crop *crop) 16417da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 16427da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_device *vpfe_dev = video_drvdata(file); 16437da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri int ret = 0; 16447da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 16457da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_s_crop\n"); 16467da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 16477da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (vpfe_dev->started) { 16487da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* make sure streaming is not started */ 16497da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(&vpfe_dev->v4l2_dev, 16507da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri "Cannot change crop when streaming is ON\n"); 16517da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return -EBUSY; 16527da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 16537da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 16547da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = mutex_lock_interruptible(&vpfe_dev->lock); 16557da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (ret) 16567da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return ret; 16577da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 16587da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (crop->c.top < 0 || crop->c.left < 0) { 16597da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(&vpfe_dev->v4l2_dev, 16607da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri "doesn't support negative values for top & left\n"); 16617da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = -EINVAL; 16627da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri goto unlock_out; 16637da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 16647da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 16657da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* adjust the width to 16 pixel boundry */ 16667da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri crop->c.width = ((crop->c.width + 15) & ~0xf); 16677da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 16687da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* make sure parameters are valid */ 16697da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if ((crop->c.left + crop->c.width > 16707da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->std_info.active_pixels) || 16717da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri (crop->c.top + crop->c.height > 16727da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->std_info.active_lines)) { 16737da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(&vpfe_dev->v4l2_dev, "Error in S_CROP params\n"); 16747da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = -EINVAL; 16757da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri goto unlock_out; 16767da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 16777da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ccdc_dev->hw_ops.set_image_window(&crop->c); 16787da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->fmt.fmt.pix.width = crop->c.width; 16797da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->fmt.fmt.pix.height = crop->c.height; 16807da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->fmt.fmt.pix.bytesperline = 16817da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ccdc_dev->hw_ops.get_line_length(); 16827da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->fmt.fmt.pix.sizeimage = 16837da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->fmt.fmt.pix.bytesperline * 16847da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->fmt.fmt.pix.height; 16857da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->crop = crop->c; 16867da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheriunlock_out: 16877da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri mutex_unlock(&vpfe_dev->lock); 16887da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return ret; 16897da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 16907da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 16917da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 16927da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic long vpfe_param_handler(struct file *file, void *priv, 16937da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri int cmd, void *param) 16947da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 16957da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_device *vpfe_dev = video_drvdata(file); 16967da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri int ret = 0; 16977da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 16987da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_param_handler\n"); 16997da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 17007da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (vpfe_dev->started) { 17017da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* only allowed if streaming is not started */ 17027da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(&vpfe_dev->v4l2_dev, "device already started\n"); 17037da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return -EBUSY; 17047da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 17057da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 17067da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = mutex_lock_interruptible(&vpfe_dev->lock); 17077da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (ret) 17087da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return ret; 17097da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 17107da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri switch (cmd) { 17117da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri case VPFE_CMD_S_CCDC_RAW_PARAMS: 17127da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_warn(&vpfe_dev->v4l2_dev, 17137da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri "VPFE_CMD_S_CCDC_RAW_PARAMS: experimental ioctl\n"); 17147da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = ccdc_dev->hw_ops.set_params(param); 17157da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (ret) { 17167da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(&vpfe_dev->v4l2_dev, 17177da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri "Error in setting parameters in CCDC\n"); 17187da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri goto unlock_out; 17197da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 17207da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (vpfe_get_ccdc_image_format(vpfe_dev, &vpfe_dev->fmt) < 0) { 17217da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(&vpfe_dev->v4l2_dev, 17227da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri "Invalid image format at CCDC\n"); 17237da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri goto unlock_out; 17247da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 17257da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri break; 17267da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri default: 17277da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = -EINVAL; 17287da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 17297da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheriunlock_out: 17307da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri mutex_unlock(&vpfe_dev->lock); 17317da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return ret; 17327da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 17337da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 17347da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 17357da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri/* vpfe capture ioctl operations */ 17367da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic const struct v4l2_ioctl_ops vpfe_ioctl_ops = { 17377da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .vidioc_querycap = vpfe_querycap, 17387da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .vidioc_g_fmt_vid_cap = vpfe_g_fmt_vid_cap, 17397da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .vidioc_enum_fmt_vid_cap = vpfe_enum_fmt_vid_cap, 17407da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .vidioc_s_fmt_vid_cap = vpfe_s_fmt_vid_cap, 17417da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .vidioc_try_fmt_vid_cap = vpfe_try_fmt_vid_cap, 17427da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .vidioc_enum_input = vpfe_enum_input, 17437da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .vidioc_g_input = vpfe_g_input, 17447da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .vidioc_s_input = vpfe_s_input, 17457da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .vidioc_querystd = vpfe_querystd, 17467da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .vidioc_s_std = vpfe_s_std, 17477da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .vidioc_g_std = vpfe_g_std, 1748d73bfc5fe625f6962d0ced84066e201249f14e53Vaibhav Hiremath .vidioc_queryctrl = vpfe_queryctrl, 1749d73bfc5fe625f6962d0ced84066e201249f14e53Vaibhav Hiremath .vidioc_g_ctrl = vpfe_g_ctrl, 1750d73bfc5fe625f6962d0ced84066e201249f14e53Vaibhav Hiremath .vidioc_s_ctrl = vpfe_s_ctrl, 17517da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .vidioc_reqbufs = vpfe_reqbufs, 17527da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .vidioc_querybuf = vpfe_querybuf, 17537da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .vidioc_qbuf = vpfe_qbuf, 17547da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .vidioc_dqbuf = vpfe_dqbuf, 17557da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .vidioc_streamon = vpfe_streamon, 17567da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .vidioc_streamoff = vpfe_streamoff, 17577da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .vidioc_cropcap = vpfe_cropcap, 17587da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .vidioc_g_crop = vpfe_g_crop, 17597da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .vidioc_s_crop = vpfe_s_crop, 17607da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .vidioc_default = vpfe_param_handler, 17617da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri}; 17627da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 17637da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic struct vpfe_device *vpfe_initialize(void) 17647da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 17657da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_device *vpfe_dev; 17667da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 17677da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* Default number of buffers should be 3 */ 17687da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if ((numbuffers > 0) && 17697da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri (numbuffers < config_params.min_numbuffers)) 17707da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri numbuffers = config_params.min_numbuffers; 17717da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 17727da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* 17737da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * Set buffer size to min buffers size if invalid buffer size is 17747da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * given 17757da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri */ 17767da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (bufsize < config_params.min_bufsize) 17777da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri bufsize = config_params.min_bufsize; 17787da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 17797da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri config_params.numbuffers = numbuffers; 17807da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 17817da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (numbuffers) 17827da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri config_params.device_bufsize = bufsize; 17837da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 17847da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* Allocate memory for device objects */ 17857da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev = kzalloc(sizeof(*vpfe_dev), GFP_KERNEL); 17867da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 17877da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return vpfe_dev; 17887da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 17897da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 17907da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic void vpfe_disable_clock(struct vpfe_device *vpfe_dev) 17917da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 17927da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_config *vpfe_cfg = vpfe_dev->cfg; 17937da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 17947da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri clk_disable(vpfe_cfg->vpssclk); 17957da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri clk_put(vpfe_cfg->vpssclk); 17967da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri clk_disable(vpfe_cfg->slaveclk); 17977da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri clk_put(vpfe_cfg->slaveclk); 17987da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_info(vpfe_dev->pdev->driver, 17997da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri "vpfe vpss master & slave clocks disabled\n"); 18007da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 18017da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 18027da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic int vpfe_enable_clock(struct vpfe_device *vpfe_dev) 18037da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 18047da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_config *vpfe_cfg = vpfe_dev->cfg; 18057da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri int ret = -ENOENT; 18067da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 18077da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_cfg->vpssclk = clk_get(vpfe_dev->pdev, "vpss_master"); 18087da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (NULL == vpfe_cfg->vpssclk) { 18097da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(vpfe_dev->pdev->driver, "No clock defined for" 18107da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri "vpss_master\n"); 18117da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return ret; 18127da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 18137da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 18147da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (clk_enable(vpfe_cfg->vpssclk)) { 18157da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(vpfe_dev->pdev->driver, 18167da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri "vpfe vpss master clock not enabled\n"); 18177da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri goto out; 18187da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 18197da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_info(vpfe_dev->pdev->driver, 18207da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri "vpfe vpss master clock enabled\n"); 18217da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 18227da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_cfg->slaveclk = clk_get(vpfe_dev->pdev, "vpss_slave"); 18237da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (NULL == vpfe_cfg->slaveclk) { 18247da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(vpfe_dev->pdev->driver, 18257da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri "No clock defined for vpss slave\n"); 18267da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri goto out; 18277da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 18287da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 18297da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (clk_enable(vpfe_cfg->slaveclk)) { 18307da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(vpfe_dev->pdev->driver, 18317da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri "vpfe vpss slave clock not enabled\n"); 18327da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri goto out; 18337da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 18347da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_info(vpfe_dev->pdev->driver, "vpfe vpss slave clock enabled\n"); 18357da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return 0; 18367da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheriout: 18377da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (vpfe_cfg->vpssclk) 18387da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri clk_put(vpfe_cfg->vpssclk); 18397da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (vpfe_cfg->slaveclk) 18407da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri clk_put(vpfe_cfg->slaveclk); 18417da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 18427da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return -1; 18437da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 18447da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 18457da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri/* 18467da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * vpfe_probe : This function creates device entries by register 18477da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * itself to the V4L2 driver and initializes fields of each 18487da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * device objects 18497da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri */ 18507da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic __init int vpfe_probe(struct platform_device *pdev) 18517da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 18527da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_subdev_info *sdinfo; 18537da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_config *vpfe_cfg; 18547da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct resource *res1; 18557da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_device *vpfe_dev; 18567da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct i2c_adapter *i2c_adap; 18577da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct video_device *vfd; 18587da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri int ret = -ENOMEM, i, j; 18597da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri int num_subdevs = 0; 18607da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 18617da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* Get the pointer to the device object */ 18627da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev = vpfe_initialize(); 18637da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 18647da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (!vpfe_dev) { 18657da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(pdev->dev.driver, 18667da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri "Failed to allocate memory for vpfe_dev\n"); 18677da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return ret; 18687da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 18697da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 18707da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->pdev = &pdev->dev; 18717da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 18727da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (NULL == pdev->dev.platform_data) { 18737da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(pdev->dev.driver, "Unable to get vpfe config\n"); 18747da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = -ENOENT; 18757da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri goto probe_free_dev_mem; 18767da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 18777da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 18787da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_cfg = pdev->dev.platform_data; 18797da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->cfg = vpfe_cfg; 18807da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (NULL == vpfe_cfg->ccdc || 18817da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri NULL == vpfe_cfg->card_name || 18827da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri NULL == vpfe_cfg->sub_devs) { 18837da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(pdev->dev.driver, "null ptr in vpfe_cfg\n"); 18847da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = -ENOENT; 18857da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri goto probe_free_dev_mem; 18867da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 18877da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 18887da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* enable vpss clocks */ 18897da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = vpfe_enable_clock(vpfe_dev); 18907da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (ret) 18917da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri goto probe_free_dev_mem; 18927da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 18937da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri mutex_lock(&ccdc_lock); 18947da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* Allocate memory for ccdc configuration */ 18957da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ccdc_cfg = kmalloc(sizeof(struct ccdc_config), GFP_KERNEL); 18967da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (NULL == ccdc_cfg) { 18977da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(pdev->dev.driver, 18987da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri "Memory allocation failed for ccdc_cfg\n"); 18997da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri goto probe_disable_clock; 19007da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 19017da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 19027da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri strncpy(ccdc_cfg->name, vpfe_cfg->ccdc, 32); 19037da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* Get VINT0 irq resource */ 19047da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri res1 = platform_get_resource(pdev, IORESOURCE_IRQ, 0); 19057da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (!res1) { 19067da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(pdev->dev.driver, 19077da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri "Unable to get interrupt for VINT0\n"); 19087da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = -ENOENT; 19097da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri goto probe_disable_clock; 19107da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 19117da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->ccdc_irq0 = res1->start; 19127da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 19137da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* Get VINT1 irq resource */ 19147da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri res1 = platform_get_resource(pdev, 19157da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri IORESOURCE_IRQ, 1); 19167da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (!res1) { 19177da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(pdev->dev.driver, 19187da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri "Unable to get interrupt for VINT1\n"); 19197da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = -ENOENT; 19207da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri goto probe_disable_clock; 19217da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 19227da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->ccdc_irq1 = res1->start; 19237da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 19247da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* Get address base of CCDC */ 19257da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri res1 = platform_get_resource(pdev, IORESOURCE_MEM, 0); 19267da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (!res1) { 19277da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(pdev->dev.driver, 19287da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri "Unable to get register address map\n"); 19297da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = -ENOENT; 19307da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri goto probe_disable_clock; 19317da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 19327da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 19337da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ccdc_cfg->ccdc_addr_size = res1->end - res1->start + 1; 19347da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (!request_mem_region(res1->start, ccdc_cfg->ccdc_addr_size, 19357da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri pdev->dev.driver->name)) { 19367da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(pdev->dev.driver, 19377da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri "Failed request_mem_region for ccdc base\n"); 19387da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = -ENXIO; 19397da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri goto probe_disable_clock; 19407da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 19417da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ccdc_cfg->ccdc_addr = ioremap_nocache(res1->start, 19427da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ccdc_cfg->ccdc_addr_size); 19437da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (!ccdc_cfg->ccdc_addr) { 19447da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(pdev->dev.driver, "Unable to ioremap ccdc addr\n"); 19457da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = -ENXIO; 19467da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri goto probe_out_release_mem1; 19477da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 19487da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 19497da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = request_irq(vpfe_dev->ccdc_irq0, vpfe_isr, IRQF_DISABLED, 19507da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri "vpfe_capture0", vpfe_dev); 19517da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 19527da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (0 != ret) { 19537da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(pdev->dev.driver, "Unable to request interrupt\n"); 19547da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri goto probe_out_unmap1; 19557da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 19567da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 19577da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* Allocate memory for video device */ 19587da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vfd = video_device_alloc(); 19597da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (NULL == vfd) { 19607da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = -ENOMEM; 19617da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(pdev->dev.driver, 19627da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri "Unable to alloc video device\n"); 19637da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri goto probe_out_release_irq; 19647da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 19657da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 19667da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* Initialize field of video device */ 19677da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vfd->release = video_device_release; 19687da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vfd->fops = &vpfe_fops; 19697da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vfd->ioctl_ops = &vpfe_ioctl_ops; 19707da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vfd->tvnorms = 0; 19717da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vfd->current_norm = V4L2_STD_PAL; 19727da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vfd->v4l2_dev = &vpfe_dev->v4l2_dev; 19737da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri snprintf(vfd->name, sizeof(vfd->name), 19747da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri "%s_V%d.%d.%d", 19757da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri CAPTURE_DRV_NAME, 19767da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri (VPFE_CAPTURE_VERSION_CODE >> 16) & 0xff, 19777da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri (VPFE_CAPTURE_VERSION_CODE >> 8) & 0xff, 19787da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri (VPFE_CAPTURE_VERSION_CODE) & 0xff); 19797da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* Set video_dev to the video device */ 19807da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->video_dev = vfd; 19817da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 19827da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = v4l2_device_register(&pdev->dev, &vpfe_dev->v4l2_dev); 19837da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (ret) { 19847da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(pdev->dev.driver, 19857da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri "Unable to register v4l2 device.\n"); 19867da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri goto probe_out_video_release; 19877da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 19887da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_info(&vpfe_dev->v4l2_dev, "v4l2 device registered\n"); 19897da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri spin_lock_init(&vpfe_dev->irqlock); 19907da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri spin_lock_init(&vpfe_dev->dma_queue_lock); 19917da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri mutex_init(&vpfe_dev->lock); 19927da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 19937da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* Initialize field of the device objects */ 19947da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->numbuffers = config_params.numbuffers; 19957da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 19967da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* Initialize prio member of device object */ 19977da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_prio_init(&vpfe_dev->prio); 19987da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* register video device */ 19997da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, 20007da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri "trying to register vpfe device.\n"); 20017da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, 20027da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri "video_dev=%x\n", (int)&vpfe_dev->video_dev); 20037da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 20047da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = video_register_device(vpfe_dev->video_dev, 20057da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri VFL_TYPE_GRABBER, -1); 20067da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 20077da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (ret) { 20087da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(pdev->dev.driver, 20097da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri "Unable to register video device.\n"); 20107da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri goto probe_out_v4l2_unregister; 20117da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 20127da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 20137da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_info(&vpfe_dev->v4l2_dev, "video device registered\n"); 20147da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* set the driver data in platform device */ 20157da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri platform_set_drvdata(pdev, vpfe_dev); 20167da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* set driver private data */ 20177da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri video_set_drvdata(vpfe_dev->video_dev, vpfe_dev); 201814cbaafe6f8587aed632de747322cd3add421a76Vaibhav Hiremath i2c_adap = i2c_get_adapter(vpfe_cfg->i2c_adapter_id); 20197da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri num_subdevs = vpfe_cfg->num_subdevs; 20207da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->sd = kmalloc(sizeof(struct v4l2_subdev *) * num_subdevs, 20217da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri GFP_KERNEL); 20227da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (NULL == vpfe_dev->sd) { 20237da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_err(&vpfe_dev->v4l2_dev, 20247da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri "unable to allocate memory for subdevice pointers\n"); 20257da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri ret = -ENOMEM; 20267da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri goto probe_out_video_unregister; 20277da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 20287da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 20297da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri for (i = 0; i < num_subdevs; i++) { 20307da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct v4l2_input *inps; 20317da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 20327da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri sdinfo = &vpfe_cfg->sub_devs[i]; 20337da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 20347da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* Load up the subdevice */ 20357da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->sd[i] = 20367da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_i2c_new_subdev_board(&vpfe_dev->v4l2_dev, 20377da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri i2c_adap, 20387da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri sdinfo->name, 20397da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri &sdinfo->board_info, 20407da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri NULL); 20417da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri if (vpfe_dev->sd[i]) { 20427da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_info(&vpfe_dev->v4l2_dev, 20437da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri "v4l2 sub device %s registered\n", 20447da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri sdinfo->name); 20457da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->sd[i]->grp_id = sdinfo->grp_id; 20467da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* update tvnorms from the sub devices */ 20477da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri for (j = 0; j < sdinfo->num_inputs; j++) { 20487da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri inps = &sdinfo->inputs[j]; 20497da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vfd->tvnorms |= inps->std; 20507da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 20517da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } else { 20527da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_info(&vpfe_dev->v4l2_dev, 20537da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri "v4l2 sub device %s register fails\n", 20547da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri sdinfo->name); 20557da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri goto probe_sd_out; 20567da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 20577da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri } 20587da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 20597da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* set first sub device as current one */ 20607da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_dev->current_subdev = &vpfe_cfg->sub_devs[0]; 20617da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 20627da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* We have at least one sub device to work with */ 20637da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri mutex_unlock(&ccdc_lock); 20647da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return 0; 20657da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 20667da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheriprobe_sd_out: 20677da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri kfree(vpfe_dev->sd); 20687da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheriprobe_out_video_unregister: 20697da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri video_unregister_device(vpfe_dev->video_dev); 20707da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheriprobe_out_v4l2_unregister: 20717da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_device_unregister(&vpfe_dev->v4l2_dev); 20727da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheriprobe_out_video_release: 2073f0813b4c9f7ffbeaddcba1c08a1812f7ff30e1b7Laurent Pinchart if (!video_is_registered(vpfe_dev->video_dev)) 20747da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri video_device_release(vpfe_dev->video_dev); 20757da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheriprobe_out_release_irq: 20767da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri free_irq(vpfe_dev->ccdc_irq0, vpfe_dev); 20777da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheriprobe_out_unmap1: 20787da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri iounmap(ccdc_cfg->ccdc_addr); 20797da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheriprobe_out_release_mem1: 20807da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri release_mem_region(res1->start, res1->end - res1->start + 1); 20817da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheriprobe_disable_clock: 20827da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_disable_clock(vpfe_dev); 20837da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri mutex_unlock(&ccdc_lock); 20847da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri kfree(ccdc_cfg); 20857da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheriprobe_free_dev_mem: 20867da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri kfree(vpfe_dev); 20877da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return ret; 20887da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 20897da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 20907da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri/* 20917da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * vpfe_remove : It un-register device from V4L2 driver 20927da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri */ 20939d8938248c3b67904a8108a6fc3dcceb9d7f2aadUwe Kleine-Königstatic int __devexit vpfe_remove(struct platform_device *pdev) 20947da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 20957da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct vpfe_device *vpfe_dev = platform_get_drvdata(pdev); 20967da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri struct resource *res; 20977da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 20987da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_info(pdev->dev.driver, "vpfe_remove\n"); 20997da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 21007da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri free_irq(vpfe_dev->ccdc_irq0, vpfe_dev); 21017da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri kfree(vpfe_dev->sd); 21027da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri v4l2_device_unregister(&vpfe_dev->v4l2_dev); 21037da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri video_unregister_device(vpfe_dev->video_dev); 21047da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri mutex_lock(&ccdc_lock); 21057da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 21067da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri release_mem_region(res->start, res->end - res->start + 1); 21077da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri iounmap(ccdc_cfg->ccdc_addr); 21087da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri mutex_unlock(&ccdc_lock); 21097da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri vpfe_disable_clock(vpfe_dev); 21107da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri kfree(vpfe_dev); 21117da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri kfree(ccdc_cfg); 21127da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return 0; 21137da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 21147da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 21157da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic int 21167da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicherivpfe_suspend(struct device *dev) 21177da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 21187da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* add suspend code here later */ 21197da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return -1; 21207da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 21217da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 21227da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic int 21237da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicherivpfe_resume(struct device *dev) 21247da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 21257da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* add resume code here later */ 21267da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return -1; 21277da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 21287da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 2129471452104b8520337ae2fb48c4e61cd4896e025dAlexey Dobriyanstatic const struct dev_pm_ops vpfe_dev_pm_ops = { 21307da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .suspend = vpfe_suspend, 21317da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .resume = vpfe_resume, 21327da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri}; 21337da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 21347da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic struct platform_driver vpfe_driver = { 21357da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .driver = { 21367da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .name = CAPTURE_DRV_NAME, 21377da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .owner = THIS_MODULE, 21387da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .pm = &vpfe_dev_pm_ops, 21397da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri }, 21407da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .probe = vpfe_probe, 21417da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri .remove = __devexit_p(vpfe_remove), 21427da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri}; 21437da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 21447da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic __init int vpfe_init(void) 21457da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 21467da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri printk(KERN_NOTICE "vpfe_init\n"); 21477da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri /* Register driver to the kernel */ 21487da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri return platform_driver_register(&vpfe_driver); 21497da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 21507da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 21517da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri/* 21527da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri * vpfe_cleanup : This function un-registers device driver 21537da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri */ 21547da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheristatic void vpfe_cleanup(void) 21557da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri{ 21567da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri platform_driver_unregister(&vpfe_driver); 21577da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri} 21587da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicheri 21597da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicherimodule_init(vpfe_init); 21607da8a6cb3e5b60e73b196f1c71031423e0791032Muralidharan Karicherimodule_exit(vpfe_cleanup); 2161