/*
* Copyright (C) 2008-2009 Texas Instruments Inc
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Driver name : VPFE Capture driver
* VPFE Capture driver allows applications to capture and stream video
* frames on DaVinci SoCs (DM6446, DM355 etc) from a YUV source such as
* TVP5146 or Raw Bayer RGB image data from an image sensor
* such as Microns' MT9T001, mt9p031 etc.
*
* These SoCs have, in common, a Video Processing Subsystem (VPSS) that
* consists of a Video Processing Front End (VPFE) for capturing
* video/raw image data and Video Processing Back End (VPBE) for displaying
* YUV data through an in-built analog encoder or Digital LCD port. This
* driver is for capture through VPFE. A typical EVM using these SoCs have
* following high level configuration.
*
*
* decoder(TVP5146/ YUV/
* MT9T001) --> Raw Bayer RGB ---> MUX -> VPFE (CCDC/ISIF)
* data input | |
* V |
* SDRAM |
* V
* Image Processor
* |
* V
* SDRAM
* The data flow happens from a decoder connected to the VPFE over a
* YUV embedded (BT.656/BT.1120) or separate sync or raw bayer rgb interface
* and to the input of VPFE through an optional MUX (if more inputs are
* to be interfaced on the EVM). The input data is first passed through
* CCDC (CCD Controller, a.k.a Image Sensor Interface, ISIF). The CCDC
* does very little or no processing on YUV data and does pre-process Raw
* Bayer RGB data through modules such as Defect Pixel Correction (DFC)
* Color Space Conversion (CSC), data gain/offset etc. After this, data
* can be written to SDRAM or can be connected to the image processing
* block such as IPIPE (on DM355 only).
*
* Features supported
* - MMAP IO
* - Capture using TVP5146 over BT.656
* - support for interfacing decoders using sub device model
* - Work with DM355 or DM6446 CCDC to do Raw Bayer RGB/YUV
* data capture to SDRAM.
* TODO list
* - Support multiple REQBUF after open
* - Support for de-allocating buffers through REQBUF
* - Support for chaining Image Processor
* - Support for static allocation of buffers
* - Support for STREAMON before QBUF
* - Support for control ioctls
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/interrupt.h>
#include <linux/version.h>
#include <linux/io.h>
#include <media/v4l2-common.h>
#include <media/davinci/videohd.h>
#include <media/davinci/vpfe_capture.h>
#include <media/davinci/imp_hw_if.h>
#include <mach/cputype.h>
#include "ccdc_hw_device.h"
#define HD_IMAGE_SIZE (2176 * 2176 * 2)
#define PAL_IMAGE_SIZE (720 * 576 * 2)
#define SECOND_IMAGE_SIZE_MAX (640 * 480 * 2)
static int debug;
static u32 numbuffers = 3;
static u32 bufsize = HD_IMAGE_SIZE + SECOND_IMAGE_SIZE_MAX;
static int interface;
static u32 cont_bufoffset = 0;
static u32 cont_bufsize = 0;
module_param(interface, bool, S_IRUGO);
module_param(numbuffers, uint, S_IRUGO);
module_param(bufsize, uint, S_IRUGO);
module_param(debug, bool, 0644);
module_param(cont_bufoffset, uint, S_IRUGO);
module_param(cont_bufsize, uint, S_IRUGO);
/**
* VPFE capture can be used for capturing video such as from TVP5146 or TVP7002
* and for capture raw bayer data from camera sensors such as mt9p031. At this
* point there is problem in co-existence of mt9p031 and tvp5146 due to i2c
* address collision. So set the variable below from bootargs to do either video
* capture or camera capture.
* interface = 0 - video capture (from TVP514x or such),
* interface = 1 - Camera capture (from mt9p031 or such)
* Re-visit this when we fix the co-existence issue
*/
MODULE_PARM_DESC(interface, "interface 0-1 (default:0)");
MODULE_PARM_DESC(numbuffers, "buffer count (default:3)");
MODULE_PARM_DESC(bufsize, "buffer size in bytes, (default:4147200 bytes)");
MODULE_PARM_DESC(debug, "Debug level 0-1");
MODULE_PARM_DESC(cont_bufoffset, "Capture buffer offset (default 0)");
MODULE_PARM_DESC(cont_bufsize, "Capture buffer size (default 0)");
MODULE_DESCRIPTION("VPFE Video for Linux Capture Driver");
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Texas Instruments");
/* standard information */
struct vpfe_standard {
v4l2_std_id std_id;
unsigned int width;
unsigned int height;
struct v4l2_fract pixelaspect;
/* 0 - progressive, 1 - interlaced */
int frame_format;
struct v4l2_fract fps;
};
/* ccdc configuration */
struct ccdc_config {
/* This make sure vpfe is probed and ready to go */
int vpfe_probed;
/* name of ccdc device */
char name[32];
};
/* data structures */
static struct vpfe_config_params config_params = {
.min_numbuffers = 3,
.numbuffers = 3,
.min_bufsize = 1280 * 720 * 2,
/* DM365 IPIPE supports up to 2176 pixels, otherwise you need to use raw */
.device_bufsize = 2176 * 2176 * 2,
};
/* ccdc device registered */
static struct ccdc_hw_device *ccdc_dev;
/* lock for accessing ccdc information */
static DEFINE_MUTEX(ccdc_lock);
/* ccdc configuration */
static struct ccdc_config *ccdc_cfg;
/* hardware interface for image processing pipeline */
static struct imp_hw_interface *imp_hw_if;
const struct vpfe_standard vpfe_standards[] = {
{V4L2_STD_525_60, 720, 480, {11, 10}, 1, {1001, 30000} },
{V4L2_STD_625_50, 720, 576, {54, 59}, 1, {1, 25} },
{V4L2_STD_525P_60, 720, 480, {11, 10}, 0, {1001, 30000} },
{V4L2_STD_625P_50, 720, 576, {54, 59}, 0, {1, 25} },
{V4L2_STD_720P_30, 1280, 720, {1, 1}, 0, {1, 30} },
{V4L2_STD_720P_50, 1280, 720, {1, 1}, 0, {1, 50} },
{V4L2_STD_720P_60, 1280, 720, {1, 1}, 0, {1, 60} },
{V4L2_STD_1080I_30, 1920, 1080, {1, 1}, 1, {1, 30} },
{V4L2_STD_1080I_50, 1920, 1080, {1, 1}, 1, {1, 50} },
{V4L2_STD_1080I_60, 1920, 1080, {1, 1}, 1, {1, 60} },
{V4L2_STD_1080P_30, 1920, 1080, {1, 1}, 0, {1, 30} },
{V4L2_STD_1080P_50, 1920, 1080, {1, 1}, 0, {1, 50} },
{V4L2_STD_1080P_60, 1920, 1080, {1, 1}, 0, {1, 60} },
};
/* Used when raw Bayer image from ccdc is directly captured to SDRAM */
static const struct vpfe_pixel_format vpfe_pix_fmts[] = {
{
.fmtdesc = {
.index = 0,
.type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
.description = "Bayer GrRBGb 8bit A-Law compr.",
.pixelformat = V4L2_PIX_FMT_SBGGR8,
},
.bpp = 1,
.subdev_pix_fmt = V4L2_PIX_FMT_SGRBG10,
},
{
.fmtdesc = {
.index = 1,
.type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
.description = "Bayer GrRBGb - 16bit",
.pixelformat = V4L2_PIX_FMT_SBGGR16,
},
.bpp = 2,
.subdev_pix_fmt = V4L2_PIX_FMT_SGRBG10,
},
{
.fmtdesc = {
.index = 2,
.type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
.description = "Bayer GrRBGb 8bit DPCM compr.",
.pixelformat = V4L2_PIX_FMT_SGRBG10DPCM8,
},
.bpp = 1,
.subdev_pix_fmt = V4L2_PIX_FMT_SGRBG10,
},
{
.fmtdesc = {
.index = 3,
.type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
.description = "YCbCr 4:2:2 Interleaved UYVY",
.pixelformat = V4L2_PIX_FMT_UYVY,
},
.bpp = 2,
.subdev_pix_fmt = V4L2_PIX_FMT_UYVY,
},
{
.fmtdesc = {
.index = 4,
.type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
.description = "YCbCr 4:2:2 Interleaved YUYV",
.pixelformat = V4L2_PIX_FMT_YUYV,
},
.bpp = 2,
.subdev_pix_fmt = V4L2_PIX_FMT_UYVY,
},
{
.fmtdesc = {
.index = 5,
.type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
.