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