linux-davinci git: add vfpe driver for davinci and dm355, enable it in dm355-leopard...
authorKoen Kooi <koen@openembedded.org>
Tue, 17 Mar 2009 21:51:32 +0000 (22:51 +0100)
committerKoen Kooi <koen@openembedded.org>
Tue, 17 Mar 2009 21:51:32 +0000 (22:51 +0100)
recipes/linux/linux-davinci/dm355-leopard/defconfig
recipes/linux/linux-davinci/dm355-leopard/vfpe.patch [new file with mode: 0644]
recipes/linux/linux-davinci/vfpe1.patch [new file with mode: 0644]
recipes/linux/linux-davinci/vfpe2.patch [new file with mode: 0644]
recipes/linux/linux-davinci/vfpe3.patch [new file with mode: 0644]
recipes/linux/linux-davinci/vfpe4.patch [new file with mode: 0644]
recipes/linux/linux-davinci/vfpe5.patch [new file with mode: 0644]
recipes/linux/linux-davinci/vfpe6.patch [new file with mode: 0644]
recipes/linux/linux-davinci/vfpe7.patch [new file with mode: 0644]
recipes/linux/linux-davinci_git.bb

index 8b3f41a..d8bd0cd 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.29-rc7-davinci1
-# Tue Mar 17 20:58:19 2009
+# Tue Mar 17 22:47:40 2009
 #
 CONFIG_ARM=y
 CONFIG_SYS_SUPPORTS_APM_EMULATION=y
@@ -941,19 +941,96 @@ CONFIG_MEDIA_TUNER_XC2028=y
 CONFIG_MEDIA_TUNER_XC5000=y
 CONFIG_VIDEO_V4L2=y
 CONFIG_VIDEO_V4L1=y
+CONFIG_VIDEOBUF_GEN=y
+CONFIG_VIDEOBUF_DMA_CONTIG=y
 CONFIG_VIDEO_CAPTURE_DRIVERS=y
 # CONFIG_VIDEO_ADV_DEBUG is not set
 # CONFIG_VIDEO_FIXED_MINOR_RANGES is not set
-CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
+# CONFIG_VIDEO_HELPER_CHIPS_AUTO is not set
+
+#
+# Encoders/decoders and other helper chips
+#
+
+#
+# Audio decoders
+#
+# CONFIG_VIDEO_TVAUDIO is not set
+# CONFIG_VIDEO_TDA7432 is not set
+# CONFIG_VIDEO_TDA9840 is not set
+# CONFIG_VIDEO_TDA9875 is not set
+# CONFIG_VIDEO_TEA6415C is not set
+# CONFIG_VIDEO_TEA6420 is not set
+# CONFIG_VIDEO_MSP3400 is not set
+# CONFIG_VIDEO_CS5345 is not set
+# CONFIG_VIDEO_CS53L32A is not set
+# CONFIG_VIDEO_M52790 is not set
+CONFIG_VIDEO_TLV320AIC23B=y
+# CONFIG_VIDEO_WM8775 is not set
+# CONFIG_VIDEO_WM8739 is not set
+# CONFIG_VIDEO_VP27SMPX is not set
+
+#
+# Video decoders
+#
+# CONFIG_VIDEO_BT819 is not set
+# CONFIG_VIDEO_BT856 is not set
+# CONFIG_VIDEO_BT866 is not set
+# CONFIG_VIDEO_KS0127 is not set
+# CONFIG_VIDEO_OV7670 is not set
+# CONFIG_VIDEO_TCM825X is not set
+# CONFIG_VIDEO_SAA7110 is not set
+# CONFIG_VIDEO_SAA7111 is not set
+# CONFIG_VIDEO_SAA7114 is not set
+# CONFIG_VIDEO_SAA711X is not set
+# CONFIG_VIDEO_SAA717X is not set
+# CONFIG_VIDEO_SAA7191 is not set
+CONFIG_VIDEO_TVP514X=y
+CONFIG_VIDEO_TVP5150=y
+CONFIG_VIDEO_VPX3220=y
+
+#
+# Video and audio decoders
+#
+# CONFIG_VIDEO_CX25840 is not set
+
+#
+# MPEG video encoders
+#
+# CONFIG_VIDEO_CX2341X is not set
+
+#
+# Video encoders
+#
+# CONFIG_VIDEO_SAA7127 is not set
+# CONFIG_VIDEO_SAA7185 is not set
+# CONFIG_VIDEO_ADV7170 is not set
+# CONFIG_VIDEO_ADV7175 is not set
+
+#
+# Video improvement chips
+#
+# CONFIG_VIDEO_UPD64031A is not set
+# CONFIG_VIDEO_UPD64083 is not set
 # CONFIG_VIDEO_VIVI is not set
-# CONFIG_VIDEO_TVP5146 is not set
+CONFIG_VIDEO_VPFE_CAPTURE=y
+CONFIG_VIDEO_DM355_CCDC=y
 # CONFIG_VIDEO_CPIA is not set
 # CONFIG_VIDEO_CPIA2 is not set
 # CONFIG_VIDEO_SAA5246A is not set
 # CONFIG_VIDEO_SAA5249 is not set
-# CONFIG_SOC_CAMERA is not set
+CONFIG_SOC_CAMERA=y
+# CONFIG_SOC_CAMERA_MT9M001 is not set
+# CONFIG_SOC_CAMERA_MT9M111 is not set
+CONFIG_SOC_CAMERA_MT9T031=y
+# CONFIG_SOC_CAMERA_MT9V022 is not set
+# CONFIG_SOC_CAMERA_TW9910 is not set
+CONFIG_SOC_CAMERA_PLATFORM=y
+# CONFIG_SOC_CAMERA_OV772X is not set
+# CONFIG_VIDEO_SH_MOBILE_CEU is not set
 CONFIG_V4L_USB_DRIVERS=y
-# CONFIG_USB_VIDEO_CLASS is not set
+CONFIG_USB_VIDEO_CLASS=y
+CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y
 CONFIG_USB_GSPCA=m
 # CONFIG_USB_M5602 is not set
 # CONFIG_USB_STV06XX is not set
@@ -1010,9 +1087,9 @@ CONFIG_FB=y
 CONFIG_FIRMWARE_EDID=y
 # CONFIG_FB_DDC is not set
 # CONFIG_FB_BOOT_VESA_SUPPORT is not set
-# CONFIG_FB_CFB_FILLRECT is not set
-# CONFIG_FB_CFB_COPYAREA is not set
-# CONFIG_FB_CFB_IMAGEBLIT is not set
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
 # CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
 # CONFIG_FB_SYS_FILLRECT is not set
 # CONFIG_FB_SYS_COPYAREA is not set
@@ -1029,7 +1106,7 @@ CONFIG_FIRMWARE_EDID=y
 # Frame buffer hardware drivers
 #
 # CONFIG_FB_S1D13XXX is not set
-# CONFIG_FB_DAVINCI is not set
+CONFIG_FB_DAVINCI=y
 # CONFIG_FB_VIRTUAL is not set
 # CONFIG_FB_METRONOME is not set
 # CONFIG_FB_MB862XX is not set
@@ -1052,10 +1129,36 @@ CONFIG_FRAMEBUFFER_CONSOLE=y
 CONFIG_FONT_8x8=y
 CONFIG_FONT_8x16=y
 # CONFIG_LOGO is not set
-CONFIG_SOUND=m
+CONFIG_SOUND=y
 CONFIG_SOUND_OSS_CORE=y
-# CONFIG_SND is not set
-CONFIG_SOUND_PRIME=m
+CONFIG_SND=y
+CONFIG_SND_TIMER=y
+CONFIG_SND_PCM=y
+# CONFIG_SND_SEQUENCER is not set
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=y
+CONFIG_SND_PCM_OSS=y
+CONFIG_SND_PCM_OSS_PLUGINS=y
+# CONFIG_SND_HRTIMER is not set
+# CONFIG_SND_DYNAMIC_MINORS is not set
+CONFIG_SND_SUPPORT_OLD_API=y
+CONFIG_SND_VERBOSE_PROCFS=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+CONFIG_SND_DRIVERS=y
+# CONFIG_SND_DUMMY is not set
+# CONFIG_SND_MTPAV is not set
+# CONFIG_SND_SERIAL_U16550 is not set
+# CONFIG_SND_MPU401 is not set
+# CONFIG_SND_ARM is not set
+CONFIG_SND_USB=y
+# CONFIG_SND_USB_AUDIO is not set
+# CONFIG_SND_USB_CAIAQ is not set
+CONFIG_SND_SOC=y
+# CONFIG_SND_DAVINCI_SOC is not set
+CONFIG_SND_SOC_I2C_AND_SPI=y
+# CONFIG_SND_SOC_ALL_CODECS is not set
+# CONFIG_SOUND_PRIME is not set
 CONFIG_HID_SUPPORT=y
 CONFIG_HID=y
 # CONFIG_HID_DEBUG is not set
diff --git a/recipes/linux/linux-davinci/dm355-leopard/vfpe.patch b/recipes/linux/linux-davinci/dm355-leopard/vfpe.patch
new file mode 100644 (file)
index 0000000..4c644b6
--- /dev/null
@@ -0,0 +1,143 @@
+Subject:
+[PATCH 7/7] DM355 platform related changes for vpfe capture driver
+From:
+m-karicheri2-l0cyMroinI0@public.gmane.org
+Date:
+Fri, 13 Mar 2009 17:24:34 -0400
+To:
+davinci-linux-open-source-VycZQUHpC/PFrsHnngEfi1aTQe2KTcn/@public.gmane.org, davinci_opensource_ccb-uAqBSO/uNfhBDgjK7y7TUQ@public.gmane.org, psp_video-uAqBSO/uNfhBDgjK7y7TUQ@public.gmane.org
+Newsgroups:
+gmane.linux.davinci
+
+Add platform related changes for vpfe capture driver on DM355
+
+Signed-off-by: Murali Karicheri <m-karicheri2-l0cyMroinI0@public.gmane.org>
+---
+ arch/arm/mach-davinci/board-dm355-leopard.c    |   91 +++++++++++++++++++++++++++-
+
+diff --git a/arch/arm/mach-davinci/board-dm355-leopard.c b/arch/arm/mach-davinci/board-dm355-leopard.c
+index e104650..aaa58ba 100644
+--- a/arch/arm/mach-davinci/board-dm355-leopard.c
++++ b/arch/arm/mach-davinci/board-dm355-leopard.c
+@@ -20,6 +20,8 @@
+ #include <linux/io.h>
+ #include <linux/gpio.h>
+ #include <linux/clk.h>
++#include <media/v4l2-int-device.h>
++#include <media/tvp514x.h>
+ #include <linux/spi/spi.h>
+ #include <linux/spi/eeprom.h>
+@@ -134,12 +136,58 @@ static void dm355leopard_mmcsd_gpios(unsigned gpio)
+       dm355leopard_mmc_gpios = gpio;
+ }
++#define TVP5146_I2C_ADDR              0x5D
++static struct v4l2_ifparm tvp5146_ifparm = {
++      .if_type = V4L2_IF_TYPE_BT656,
++      .u = {
++            .bt656 = {
++                      .frame_start_on_rising_vs = 1,
++                      .bt_sync_correct = 0,
++                      .swap = 0,
++                      .latch_clk_inv = 0,
++                      .nobt_hs_inv = 0,       /* active high */
++                      .nobt_vs_inv = 0,       /* active high */
++                      .mode = V4L2_IF_TYPE_BT656_MODE_BT_8BIT,
++                      .clock_min = TVP514X_XCLK_BT656,
++                      .clock_max = TVP514X_XCLK_BT656,
++                      },
++            },
++};
++
++/**
++ * @brief tvp5146_g_ifparm - Returns the TVP5146 decoder interface parameters
++ *
++ * @param p - pointer to v4l2_ifparm structure
++ * @return result of operation - 0 is success
++ */
++static int tvp5146_g_ifparm(struct v4l2_ifparm *p)
++{
++      if (p == NULL)
++              return -EINVAL;
++
++      *p = tvp5146_ifparm;
++      return 0;
++}
++
++#define TVP5146_NUM_INPUTS            ARRAY_SIZE(tvp5146_input_list)
++
++static struct tvp514x_platform_data tvp5146_pdata = {
++      .master = CAPTURE_DRV_NAME,
++      .ifparm = tvp5146_g_ifparm,
++      .hs_polarity = 1,
++      .vs_polarity = 1
++};
++
+ static struct i2c_board_info dm355leopard_i2c_info[] = {
+-      { I2C_BOARD_INFO("dm355leopard_msp", 0x25),
++      {       I2C_BOARD_INFO("dm355leopard_msp", 0x25),
+               .platform_data = dm355leopard_mmcsd_gpios,
+-              /* plus irq */ },
++      },
++      {
++              I2C_BOARD_INFO("tvp5146", TVP5146_I2C_ADDR),
++              .platform_data = &tvp5146_pdata,
++      },
++      /* { plus irq  }, */
+       /* { I2C_BOARD_INFO("tlv320aic3x", 0x1b), }, */
+-      /* { I2C_BOARD_INFO("tvp5146", 0x5d), }, */
+ };
+ static void __init leopard_init_i2c(void)
+@@ -178,6 +226,41 @@ static struct platform_device dm355leopard_dm9000 = {
+       .num_resources  = ARRAY_SIZE(dm355leopard_dm9000_rsrc),
+ };
++#define TVP514X_STD_ALL       (V4L2_STD_NTSC | V4L2_STD_PAL)
++
++static struct vpfe_capture_input vpfe_capture_inputs = {
++      .num_inputs = VPFE_MAX_DEC_INPUTS,
++      .current_input = 0,
++      .inputs[0] = {
++              .dec_name = TVP514X_MODULE_NAME,
++              .input = {
++                      .index = 0,
++                      .name = "COMPOSITE",
++                      .type = V4L2_INPUT_TYPE_CAMERA,
++                      .std = TVP514X_STD_ALL,
++              },
++              .route = {
++                      .input = INPUT_CVBS_VI2B,
++                      .output = OUTPUT_10BIT_422_EMBEDDED_SYNC,
++              },
++              .routing_supported = 1,
++      },
++      .inputs[1] = {
++              .dec_name = TVP514X_MODULE_NAME,
++              .input = {
++                      .index = 1,
++                      .name = "SVIDEO",
++                      .type = V4L2_INPUT_TYPE_CAMERA,
++                      .std = TVP514X_STD_ALL,
++              },
++              .route = {
++                      .input = INPUT_SVIDEO_VI2C_VI1C,
++                      .output = OUTPUT_10BIT_422_EMBEDDED_SYNC,
++              },
++              .routing_supported = 1,
++      },
++};
++
+ static struct platform_device *davinci_leopard_devices[] __initdata = {
+       &dm355leopard_dm9000,
+       &davinci_nand_device,
+@@ -190,6 +273,8 @@ static struct davinci_uart_config uart_config __initdata = {
+ static void __init dm355_leopard_map_io(void)
+ {
+       davinci_map_common_io();
++      /* setup input configuration for VPFE input devices */
++      setup_vpfe_input_config(&vpfe_capture_inputs);
+       dm355_init();
+ }
diff --git a/recipes/linux/linux-davinci/vfpe1.patch b/recipes/linux/linux-davinci/vfpe1.patch
new file mode 100644 (file)
index 0000000..8694d1b
--- /dev/null
@@ -0,0 +1,3928 @@
+Subject:
+[PATCH 1/7] VPFE capture driver for DM355 and DM6446
+From:
+m-karicheri2-l0cyMroinI0@public.gmane.org
+Date:
+Fri, 13 Mar 2009 17:15:31 -0400
+To:
+davinci-linux-open-source-VycZQUHpC/PFrsHnngEfi1aTQe2KTcn/@public.gmane.org, davinci_opensource_ccb-uAqBSO/uNfhBDgjK7y7TUQ@public.gmane.org, psp_video-uAqBSO/uNfhBDgjK7y7TUQ@public.gmane.org
+Newsgroups:
+gmane.linux.davinci
+
+This patch is for the vpfe capture driver for DM355 &
+DM6446 from Texas instruments. VPFE stands for Video
+Processing Front End which is the basic IP on DMxxx
+family for video capture and processing. vpfe capture
+driver is a v4l2 bridge driver developed based on
+v4l2-int-device model. It interfaces slave decoder devices
+to the bridge driver using this model. V4L2 community
+has already developed a v4l2 sub device model for this
+purpose. But at this time, tvp514x, the only slave
+decoder that can work with DM355 and DM6446 VPFE, is using
+the v4l2-int-device model. So decision is taken to first
+use this model to submit the driver to the community and
+plan for a migration to sub device model when tvp514x
+driver become sub device compliant.  
+
+The driver uses ccdc_hw_device interface to configure
+CCDC based on the interface requirement of the slave
+decoder device. This driver is integrated with the tvp514x
+driver available in open source kernel. The driver is
+tested using a loopback application (Will be made
+available upon request) that captures video frames from the
+capture driver and display it at the output of VPBE using
+the FBDev video output device.
+
+Signed-off-by: Murali Karicheri <m-karicheri2-l0cyMroinI0@public.gmane.org>
+---
+ drivers/media/video/davinci/vpfe_capture.c | 2248 ++++++++++++++++++++++++++++
+ drivers/media/video/davinci_vpfe.c         | 1136 --------------
+ include/media/davinci/vpfe_capture.h       |  272 ++++
+ include/media/davinci/vpfe_types.h         |   71 +
+ include/media/davinci_vpfe.h               |  121 --
+ 5 files changed, 2591 insertions(+), 1257 deletions(-)
+ create mode 100644 drivers/media/video/davinci/vpfe_capture.c
+ delete mode 100644 drivers/media/video/davinci_vpfe.c
+ create mode 100644 include/media/davinci/vpfe_capture.h
+ create mode 100644 include/media/davinci/vpfe_types.h
+ delete mode 100644 include/media/davinci_vpfe.h
+
+diff --git a/drivers/media/video/davinci/vpfe_capture.c b/drivers/media/video/davinci/vpfe_capture.c
+new file mode 100644
+index 0000000..decbffc
+--- /dev/null
++++ b/drivers/media/video/davinci/vpfe_capture.c
+@@ -0,0 +1,2248 @@
++/*
++ * 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
++ */
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/platform_device.h>
++#include <linux/interrupt.h>
++#include <linux/version.h>
++#include <media/v4l2-common.h>
++#include <linux/io.h>
++#include <mach/cpu.h>
++#include <media/davinci/vpfe_capture.h>
++#include <media/tvp514x.h>
++static int debug;
++static char *ch0_decoder = "TVP514X";
++static u32 ch0_numbuffers = 3;
++static u32 ch0_bufsize = (720 * 576 * 2);
++module_param(ch0_decoder, charp, S_IRUGO);
++module_param(ch0_numbuffers, uint, S_IRUGO);
++module_param(ch0_bufsize, uint, S_IRUGO);
++module_param(debug, int, 0);
++
++static struct vpfe_config_params config_params = {
++      .min_numbuffers = 3,
++      .numbuffers[0] = 3,
++      .min_bufsize[0] = 720 * 480 * 2,
++      .channel_bufsize[0] = 720 * 576 * 2,
++};
++
++static int vpfe_nr[] = { 0 };
++
++static struct vpfe_device vpfe_obj = { {NULL} };
++static struct device *vpfe_dev;
++
++static struct v4l2_capability vpfe_videocap = {
++      .driver = CAPTURE_DRV_NAME,
++      .card = "DaVinci EVM",
++      .bus_info = "Platform",
++      .version = VPFE_CAPTURE_VERSION_CODE,
++      .capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING
++};
++
++#define VPFE_PIXELASPECT_NTSC       {11, 10}
++#define VPFE_PIXELASPECT_PAL        {54, 59}
++
++/* standard information */
++struct vpfe_standard {
++      v4l2_std_id std_id;
++      unsigned int width;
++      unsigned int height;
++      struct v4l2_fract pixelaspect;
++      /* 0 - progressive, 1 - interlaced */
++      char frame_format;
++};
++
++struct vpfe_standard vpfe_standards[] = {
++      {V4L2_STD_NTSC, 720, 480, VPFE_PIXELASPECT_NTSC, 1},
++      {V4L2_STD_PAL,  720, 576, VPFE_PIXELASPECT_PAL, 1},
++};
++
++static int vpfe_max_standards = ARRAY_SIZE(vpfe_standards);
++
++/* Used when raw Bayer image from ccdc is directly captured to SDRAM */
++static struct vpfe_pixel_format
++ vpfe_pix_fmts[VPFE_MAX_PIX_FORMATS] = {
++      {
++              .pix_fmt = V4L2_PIX_FMT_SBGGR8,
++              .desc = "Raw Bayer GrRBGb 8bit A-Law compressed",
++              .hw_fmt = VPFE_BAYER_8BIT_PACK_ALAW,
++      },
++      {
++              .pix_fmt = V4L2_PIX_FMT_SBGGR16,
++              .desc = "Raw Bayer GrRBGb - 16bit",
++              .hw_fmt = VPFE_BAYER,
++      },
++      {
++              .pix_fmt = V4L2_PIX_FMT_SGRBG10DPCM8,
++              .desc = "Raw Bayer GrRBGb 8 bit DPCM compressed",
++              .hw_fmt = VPFE_BAYER_8BIT_PACK_DPCM,
++      },
++      {
++              .pix_fmt = V4L2_PIX_FMT_UYVY,
++              .desc = "YCbCr 4:2:2 Interleaved UYVY",
++              .hw_fmt = VPFE_UYVY,
++      },
++      {
++              .pix_fmt = V4L2_PIX_FMT_YUYV,
++              .desc = "YCbCr 4:2:2 Interleaved YUYV",
++              .hw_fmt = VPFE_YUYV,
++      },
++      {
++              .pix_fmt = V4L2_PIX_FMT_NV12,
++              .desc = "Y/CbCr 4:2:0 - Semi planar",
++              .hw_fmt = VPFE_YUV420,
++      },
++};
++
++
++static int vpfe_lookup_hw_format(u32 pix_format)
++{
++      int i, ret = -EINVAL;
++
++      for (i = 0; i < VPFE_MAX_PIX_FORMATS; i++) {
++              if (pix_format == vpfe_pix_fmts[i].pix_fmt) {
++                      ret = i;
++                      break;
++              }
++      }
++      return ret;
++}
++
++static int vpfe_lookup_v4l2_pix_format(enum vpfe_hw_pix_format hw_pix)
++{
++      int i, ret = -EINVAL;
++
++      for (i = 0; i < VPFE_MAX_PIX_FORMATS; i++) {
++              if (hw_pix == vpfe_pix_fmts[i].hw_fmt) {
++                      ret = i;
++                      break;
++              }
++      }
++      return ret;
++}
++
++
++/*    Used when raw YUV image from ccdc is directly captured to SDRAM */
++static void vpfe_slave_device_unregister(struct v4l2_int_device *s)
++{
++      int index;
++      struct channel_obj *channel = s->u.slave->master->priv;
++
++      for (index = 0; index < VPFE_CAPTURE_NUM_DECODERS; index++) {
++              if ((channel->decoder[index] == s)
++                      && (index == channel->current_decoder)) {
++                      if (channel->common->started) {
++                              /* Streaming is ON. So return busy */
++                              v4l2_err(vpfe_dev->driver,
++                                      "Steaming ON. Cannot unregister"
++                                      "decoder %s\n", s->name);
++                              return;
++                      } else {
++                              channel->decoder[index] = NULL;
++                              channel->numdecoders--;
++                              break;
++                      }
++              }
++      }
++      if (index == VPFE_CAPTURE_NUM_DECODERS)
++              v4l2_err(vpfe_dev->driver,
++                      "No matching decoder registered"
++                      "decoder %s\n", s->name);
++}
++
++static int vpfe_get_stdinfo(struct channel_obj *ch, v4l2_std_id *std_id)
++{
++      int i;
++      struct video_obj *vid_ch = NULL;
++
++      vid_ch = &(ch->video);
++
++      for (i = 0; i < vpfe_max_standards; i++) {
++              if (vpfe_standards[i].std_id == *std_id) {
++                      vid_ch->std_info.activepixels =
++                                      vpfe_standards[i].width;
++                      vid_ch->std_info.activelines =
++                                      vpfe_standards[i].height;
++                      vid_ch->std_info.frame_format =
++                                      vpfe_standards[i].frame_format;
++                      vid_ch->index = i;
++                      break;
++              }
++      }
++      if (i == vpfe_max_standards) {
++              v4l2_err(vpfe_dev->driver, "standard not supported\n");
++              return -EFAULT;
++      }
++      return 0;
++}
++
++/*    vpfe_device_register: Used for registering a slave decoder
++ *    device with master
++ */
++static int vpfe_slave_device_register(struct v4l2_int_device *s)
++{
++      struct channel_obj *channel = s->u.slave->master->priv;
++      struct common_obj *common = &channel->common[VPFE_VIDEO_INDEX];
++      int err = 0, index;
++      dev_notice(vpfe_dev, "register slave %s \n", s->name);
++      if (ISNULL(channel))
++              return -EINVAL;
++
++      if (!channel->numdecoders) {
++              if (!vidioc_int_dev_init(s)) {
++                      channel->current_decoder = 0;
++                      channel->decoder[channel->current_decoder] = s;
++                      v4l2_info(vpfe_dev->driver, "Current decoder is set to"
++                               " %s\n", (s->name));
++              }
++      } else {
++              /* search through the array for an empty entry */
++              for (index = 0; index < VPFE_CAPTURE_NUM_DECODERS; index++) {
++                      if (ISNULL(channel->decoder[index])) {
++                              channel->decoder[index] = s;
++                              break;
++                      }
++              }
++              if (index == VPFE_CAPTURE_NUM_DECODERS) {
++                      v4l2_err(vpfe_dev->driver,
++                              "decoder count reached"
++                              " maximum allowed\n");
++                      return -ENOMEM;
++              }
++              if (!strncmp(ch0_decoder, s->name, strlen(ch0_decoder))) {
++                      if (!common->started) {
++                              if (!vidioc_int_dev_init(s)) {
++                                      channel->current_decoder = index;
++                                      v4l2_info(vpfe_dev->driver,
++                                              "Current decoder is"
++                                              " set to %s\n", (s->name));
++                              }
++                      }
++              }
++      }
++      channel->numdecoders++;
++      return err;
++}
++
++/*    vpfe capture master. All slave decoders registers
++ *    with master using vpfe_device_register and deregisters
++ *    using vpfe_slave_device_unregister
++ */
++static struct v4l2_int_master vpfe_master = {
++      .attach = vpfe_slave_device_register,
++      .detach = vpfe_slave_device_unregister,
++};
++
++static struct v4l2_int_device vpfe_capture = {
++      .module = THIS_MODULE,
++      .name   = CAPTURE_DRV_NAME,
++      .type   = v4l2_int_type_master,
++      .u      = {
++              .master = &vpfe_master
++      },
++};
++
++/* Call this after storing ifparams in channel block */
++static int vpfe_set_hw_if_type(struct channel_obj *channel)
++{
++      struct vpfe_capture_input *input = channel->video.input;
++
++      switch (input->inputs[input->current_input].route.output) {
++      case OUTPUT_10BIT_422_EMBEDDED_SYNC:
++              channel->vpfe_if = VPFE_BT656;
++              break;
++      case OUTPUT_20BIT_422_SEPERATE_SYNC:
++              channel->vpfe_if = VPFE_YCBCR_SYNC_16;
++              break;
++      case OUTPUT_10BIT_422_SEPERATE_SYNC:
++              channel->vpfe_if = VPFE_YCBCR_SYNC_8;
++      default:
++              v4l2_err(vpfe_dev->driver, "decoder output"
++                      " not supported, %d\n",
++                      input->inputs[input->current_input].route.output);
++              return -EFAULT;
++      }
++      return ccdc_hw_dev.set_hw_if_type(channel->vpfe_if);
++}
++
++static int vpfe_get_image_format(struct v4l2_format *f)
++{
++      struct v4l2_rect image_win;
++      enum ccdc_buftype buf_type;
++      enum ccdc_frmfmt frm_fmt;
++      enum vpfe_hw_pix_format hw_pix;
++      int ret = 0;
++
++      memset(f, 0, sizeof(struct v4l2_format));
++      f->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
++      ccdc_hw_dev.get_image_window(&image_win);
++      f->fmt.pix.width = image_win.width;
++      f->fmt.pix.height = image_win.height;
++      ccdc_hw_dev.get_line_length(&f->fmt.pix.bytesperline);
++      f->fmt.pix.sizeimage = f->fmt.pix.bytesperline *
++                              f->fmt.pix.height;
++      ccdc_hw_dev.get_buftype(&buf_type);
++      ccdc_hw_dev.get_pixelformat(&hw_pix);
++
++      if (hw_pix == VPFE_BAYER)
++              f->fmt.pix.pixelformat = V4L2_PIX_FMT_SBGGR16;
++      else if (hw_pix == VPFE_BAYER_8BIT_PACK_ALAW)
++              f->fmt.pix.pixelformat = V4L2_PIX_FMT_SBGGR8;
++      else if (hw_pix == VPFE_UYVY)
++              f->fmt.pix.pixelformat = V4L2_PIX_FMT_UYVY;
++      else if (hw_pix == VPFE_YUYV)
++              f->fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
++      else {
++              v4l2_err(vpfe_dev->driver, "Invalid HW pix format detected");
++              ret =  -EINVAL;
++              goto out;
++      }
++      ccdc_hw_dev.get_frame_format(&frm_fmt);
++      if (frm_fmt == CCDC_FRMFMT_PROGRESSIVE)
++              f->fmt.pix.field = V4L2_FIELD_NONE;
++      else if (frm_fmt == CCDC_FRMFMT_INTERLACED) {
++              if (buf_type == CCDC_BUFTYPE_FLD_INTERLEAVED)
++                      f->fmt.pix.field = V4L2_FIELD_INTERLACED;
++              else if (buf_type == CCDC_BUFTYPE_FLD_SEPARATED)
++                      f->fmt.pix.field = V4L2_FIELD_SEQ_TB;
++              else
++                      ret = -EINVAL;
++      } else
++              ret =  -EINVAL;
++out:
++      return ret;
++}
++
++/*    vpfe_config_default_format: Update format information */
++static int vpfe_config_default_format(struct channel_obj *ch)
++{
++      struct common_obj *common = &(ch->common[VPFE_VIDEO_INDEX]);
++      struct v4l2_int_device *dec = ch->decoder[ch->current_decoder];
++      struct v4l2_rect win;
++      int err = 0;
++      struct video_obj *vid_ch = NULL;
++
++      vid_ch = &(ch->video);
++      common->crop.top = 0;
++      common->crop.left = 0;
++      /* first get format information from the decoder.
++       * if not available, get it from CCDC
++       */
++      if ((vidioc_int_g_fmt_cap(dec, &common->fmt)) < 0)
++              vpfe_get_image_format(&common->fmt);
++      else {
++              /* set up all parameters in CCDC */
++              win.top = common->crop.top;
++              win.left = common->crop.left;
++              win.width = common->fmt.fmt.pix.width;
++              win.height = common->fmt.fmt.pix.height;
++              ccdc_hw_dev.set_image_window(&win);
++              if (common->fmt.fmt.pix.field ==
++                  V4L2_FIELD_INTERLACED) {
++                      err |=
++                      ccdc_hw_dev.set_buftype(CCDC_BUFTYPE_FLD_INTERLEAVED);
++                      err |=
++                      ccdc_hw_dev.set_frame_format(CCDC_FRMFMT_INTERLACED);
++              } else if (common->fmt.fmt.pix.field ==
++                         V4L2_FIELD_SEQ_TB) {
++                      err |=
++                      ccdc_hw_dev.set_buftype(CCDC_BUFTYPE_FLD_SEPARATED);
++                      err |=
++                      ccdc_hw_dev.set_frame_format(CCDC_FRMFMT_INTERLACED);
++              } else if (common->fmt.fmt.pix.field ==
++                         V4L2_FIELD_NONE) {
++                      err |=
++                      ccdc_hw_dev.set_frame_format(CCDC_FRMFMT_PROGRESSIVE);
++              } else {
++                      v4l2_dbg(1, debug, vpfe_dev->driver,
++                              "\n Decoder field not supported!");
++                      err = -EINVAL;
++                      goto out;
++              }
++      }
++      /* set the crop limits */
++      vid_ch->std_info.activepixels = common->fmt.fmt.pix.width;
++      vid_ch->std_info.activelines = common->fmt.fmt.pix.height;
++      if (config_params.numbuffers[ch->channel_id] == 0)
++              common->memory = V4L2_MEMORY_USERPTR;
++      else
++              common->memory = V4L2_MEMORY_MMAP;
++out:
++      return err;
++}
++
++static int vpfe_initialize_channel(struct channel_obj *channel,
++      struct v4l2_int_device *dec)
++{
++      struct common_obj *common = NULL;
++      struct video_obj *vid_ch = NULL;
++      int err = 0;
++
++      common = &(channel->common[VPFE_VIDEO_INDEX]);
++      vid_ch = &(channel->video);
++      channel->out_from = VPFE_CCDC_OUT;
++      vid_ch->input->current_input = 0;
++
++      err = vidioc_int_g_ifparm(dec, &channel->ifparams);
++      if (err) {
++              v4l2_err(vpfe_dev->driver,
++                      "vidioc_int_g_ifparm failed with %d\n", err);
++              return err;
++      }
++
++      err = vpfe_set_hw_if_type(channel);
++      if (err)
++              return err;
++
++      /* Initialize decoder by calling initialize function */
++      err = vidioc_int_s_power(dec, 1);
++      if (err) {
++              v4l2_err(vpfe_dev->driver,
++                      "unable to power on the decoder, %s, error %d\n",
++                      dec->name,
++                      err);
++              return err;
++      }
++
++      err = vidioc_int_init(dec);
++      if (err) {
++              v4l2_err(vpfe_dev->driver,
++                      "cannot initialize decoder - error %d\n",
++                      err);
++              return err;
++      }
++
++      /* Configure the default format information */
++      err = vpfe_config_default_format(channel);
++
++      /* now open the ccdc device to initialize it */
++      ccdc_hw_dev.open(vpfe_dev);
++      channel->initialized = 1;
++      return err;
++}
++
++/*    vpfe_open : It creates object of file handle structure and
++ *    stores it in private_data  member of filepointer
++ */
++static int vpfe_open(struct file *filep)
++{
++      int minor = iminor(filep->f_path.dentry->d_inode);
++      struct channel_obj *channel = NULL;
++      struct v4l2_int_device *dec = NULL;
++      struct common_obj *common = NULL;
++      struct vpfe_fh *fh = NULL;
++
++      v4l2_dbg(1, debug, vpfe_dev->driver, "vpfe_open\n");
++
++      /* Check for valid minor number */
++      channel = vpfe_obj.dev[0];
++      common = &(channel->common[VPFE_VIDEO_INDEX]);
++      if (minor != channel->video_dev->minor) {
++              v4l2_err(vpfe_dev->driver, "device not found\n");
++              return -ENODEV;
++      }
++
++      if (!channel->numdecoders) {
++              v4l2_err(vpfe_dev->driver, "No decoder registered\n");
++              return -ENODEV;
++      }
++
++      dec = channel->decoder[channel->current_decoder];
++
++      /* Allocate memory for the file handle object */
++      fh = kmalloc(sizeof(struct vpfe_fh), GFP_KERNEL);
++      if (ISNULL(fh)) {
++              v4l2_err(vpfe_dev->driver,
++                      "unable to allocate memory for file handle object\n");
++              return -ENOMEM;
++      }
++      /* store pointer to fh in private_data member of filep */
++      filep->private_data = fh;
++      fh->channel = channel;
++      fh->initialized = 0;
++      /* If decoder is not initialized. initialize it */
++      if (!channel->initialized) {
++              if (vpfe_initialize_channel(channel, dec))
++                      return -ENODEV;
++              fh->initialized = 1;
++      }
++      /* Increment channel usrs counter */
++      channel->usrs++;
++      /* Set io_allowed member to false */
++      fh->io_allowed[VPFE_VIDEO_INDEX] = 0;
++      /* Initialize priority of this instance to default priority */
++      fh->prio = V4L2_PRIORITY_UNSET;
++      v4l2_prio_open(&channel->prio, &fh->prio);
++
++      v4l2_dbg(1, debug, vpfe_dev->driver, "</vpfe_open>\n");
++      return 0;
++}
++
++/*ISR for VINT0*/
++static irqreturn_t vpfe_isr(int irq, void *dev_id)
++{
++      struct timeval timevalue;
++      struct channel_obj *channel = NULL;
++      struct common_obj *common = NULL;
++      struct video_obj *vid_ch = NULL;
++      struct vpfe_device *dev = dev_id;
++      unsigned long addr;
++      int fid;
++      enum v4l2_field field;
++      channel = dev->dev[VPFE_CHANNEL0_VIDEO];
++      common = &(channel->common[VPFE_VIDEO_INDEX]);
++      vid_ch = &(channel->video);
++      field = common->fmt.fmt.pix.field;
++      do_gettimeofday(&timevalue);
++
++      v4l2_dbg(1, debug, vpfe_dev->driver, "\nStarting vpfe_isr...");
++
++      /* only for 6446 this will be applicable */
++      if (!(ISNULL(ccdc_hw_dev.reset)))
++              ccdc_hw_dev.reset();
++
++      if (field == V4L2_FIELD_INTERLACED ||
++          (field == V4L2_FIELD_SEQ_TB)) {
++              /* Interlaced */
++              /* check which field we are in hardware */
++              fid = ccdc_hw_dev.getfid();
++              /* switch the software maintained field id */
++              channel->field_id ^= 1;
++              v4l2_dbg(1, debug, vpfe_dev->driver, "field id = %x:%x.\n", fid,
++                      channel->field_id);
++              if (fid == channel->field_id) {
++                      /* we are in-sync here,continue */
++                      if (fid == 0) {
++                              /* One frame is just being captured. If the
++                               * next frame is available, release the current
++                               * frame and move on
++                               */
++                              if (common->curFrm != common->nextFrm) {
++                                      /* Copy frame capture time value in
++                                       * curFrm->ts
++                                       */
++                                      common->curFrm->ts = timevalue;
++                                      common->curFrm->state = VIDEOBUF_DONE;
++                                      wake_up_interruptible(&common->curFrm->
++                                                            done);
++                                      common->curFrm = common->nextFrm;
++                              }
++                              /* based on whether the two fields are stored
++                               * interleavely or separately in memory,
++                               * reconfigure the CCDC memory address
++                               */
++                              if (channel->out_from == VPFE_CCDC_OUT &&
++                                  field == V4L2_FIELD_SEQ_TB) {
++                                      addr =
++                                      videobuf_to_dma_contig(common->curFrm);
++                                      addr += common->field_off;
++                                      ccdc_hw_dev.setfbaddr(addr);
++                              }
++                      } else if (fid == 1) {
++                              /* if one field is just being captured
++                               * configure the next frame
++                               * get the next frame from the empty queue
++                               * if no frame is available
++                               * hold on to the current buffer
++                               */
++                              if (channel->out_from == VPFE_CCDC_OUT &&
++                                  !list_empty(&common->dma_queue) &&
++                                  common->curFrm == common->nextFrm) {
++                                      common->nextFrm =
++                                              list_entry(common->
++                                                         dma_queue.next,
++                                                         struct
++                                                         videobuf_buffer,
++                                                         queue);
++                                      list_del(&common->nextFrm->queue);
++                                      common->nextFrm->state =
++                                              VIDEOBUF_ACTIVE;
++                                      addr = videobuf_to_dma_contig(common->
++                                                                    nextFrm);
++                                      ccdc_hw_dev.setfbaddr(addr);
++                              }
++                      }
++              } else if (fid == 0) {
++                      /* recover from any hardware out-of-sync due to
++                       * possible switch of video source
++                       * for fid == 0, sync up the two fids
++                       * for fid == 1, no action, one bad frame will
++                       * go out, but it is not a big deal
++                       */
++                      channel->field_id = fid;
++              }
++      } else if (field == V4L2_FIELD_NONE) {
++
++              v4l2_dbg(1, debug, vpfe_dev->driver,
++                      "\nframe format is progressive...");
++              if (common->curFrm != common->nextFrm) {
++                      /* Copy frame capture time value in curFrm->ts */
++                      common->curFrm->ts = timevalue;
++                      common->curFrm->state = VIDEOBUF_DONE;
++                      wake_up_interruptible(&common->curFrm->done);
++                      common->curFrm = common->nextFrm;
++              }
++
++      }
++      v4l2_dbg(1, debug, vpfe_dev->driver, "interrupt returned.\n");
++      return IRQ_RETVAL(1);
++}
++
++static irqreturn_t vdint1_isr(int irq, void *dev_id)
++{
++      struct channel_obj *channel = NULL;
++      struct common_obj *common = NULL;
++      struct vpfe_device *dev = dev_id;
++      unsigned long addr;
++      channel = dev->dev[VPFE_CHANNEL0_VIDEO];
++      common = &(channel->common[VPFE_VIDEO_INDEX]);
++
++      v4l2_dbg(1, debug, vpfe_dev->driver, "\nInside vdint1_isr...");
++
++      if ((common->fmt.fmt.pix.field == V4L2_FIELD_NONE) &&
++          !list_empty(&common->dma_queue) &&
++          common->curFrm == common->nextFrm) {
++              common->nextFrm =
++                  list_entry(common->dma_queue.next,
++                             struct videobuf_buffer, queue);
++              list_del(&common->nextFrm->queue);
++              common->nextFrm->state = VIDEOBUF_ACTIVE;
++              addr = videobuf_to_dma_contig(common->nextFrm);
++              ccdc_hw_dev.setfbaddr(addr);
++      }
++      return IRQ_RETVAL(1);
++}
++
++static int vpfe_detach_irq(struct channel_obj *channel)
++{
++      enum ccdc_frmfmt frame_format;
++      int err = 0;
++
++      /* First clear irq if already in use */
++      switch (channel->irq_type) {
++      case VPFE_USE_CCDC_IRQ:
++              ccdc_hw_dev.get_frame_format(&frame_format);
++              if (frame_format == CCDC_FRMFMT_PROGRESSIVE)
++                      free_irq(IRQ_VDINT1, &vpfe_obj);
++              channel->irq_type = VPFE_NO_IRQ;
++              break;
++      case VPFE_NO_IRQ:
++              break;
++      default:
++              return -1;
++      }
++      return err;
++}
++
++static int vpfe_attach_irq(struct channel_obj *channel)
++{
++      enum ccdc_frmfmt frame_format;
++      int err = 0;
++
++      channel->irq_type = VPFE_USE_CCDC_IRQ;
++
++      switch (channel->irq_type) {
++      case VPFE_USE_CCDC_IRQ:
++              {
++                      ccdc_hw_dev.get_frame_format(&frame_format);
++                      if (frame_format == CCDC_FRMFMT_PROGRESSIVE) {
++                              err =
++                                      request_irq(channel->ccdc_irq1,
++                                                  vdint1_isr,
++                                                   IRQF_DISABLED,
++                                                   "vpfe_capture1",
++                                                   (void *)&vpfe_obj);
++                              if (err < 0)
++                                      return -1;
++                      }
++              }
++              break;
++      default:
++              return -1;
++      }
++      return 0;
++}
++
++/* vpfe_release : This function deletes buffer queue, frees the
++ * buffers and the vpfe file  handle
++ */
++static int vpfe_release(struct file *filep)
++{
++      int ret;
++      struct common_obj *common = NULL;
++      /* Get the channel object and file handle object */
++      struct vpfe_fh *fh = filep->private_data;
++      struct channel_obj *channel = fh->channel;
++      struct v4l2_int_device *dec =
++                      channel->decoder[channel->current_decoder];
++
++      v4l2_dbg(1, debug, vpfe_dev->driver, "<vpfe_release>\n");
++      common = &(channel->common[VPFE_VIDEO_INDEX]);
++      /* If this is doing IO and other channels are not closed */
++      if ((channel->usrs != 1) && fh->io_allowed[VPFE_VIDEO_INDEX]) {
++              v4l2_err(vpfe_dev->driver, "Close other instances\n");
++              return -EAGAIN;
++      }
++      /* Get the lock on channel object */
++      ret = mutex_lock_interruptible(&common->lock);
++      if (ret)
++              return ret;
++      /* if this instance is doing IO */
++      if (fh->io_allowed[VPFE_VIDEO_INDEX]) {
++              /* Reset io_usrs member of channel object */
++              if (common->started) {
++                      ccdc_hw_dev.enable(0);
++                      if (ccdc_hw_dev.enable_out_to_sdram)
++                              ccdc_hw_dev.enable_out_to_sdram(0);
++                      if (vpfe_detach_irq(channel) < 0) {
++                              v4l2_err(vpfe_dev->driver,
++                                      "Error in detaching IRQ\n");
++                              mutex_unlock(&common->lock);
++                              return -EFAULT;
++                      }
++              }
++
++              common->io_usrs = 0;
++              /* Disable channel/vbi as per its device type and channel id */
++              common->started = 0;
++              /* Free buffers allocated */
++              common->numbuffers =
++                  config_params.numbuffers[channel->channel_id];
++      }
++
++      /* Decrement channel usrs counter */
++      channel->usrs--;
++      /* unlock semaphore on channel object */
++      mutex_unlock(&common->lock);
++      /* Close the priority */
++      v4l2_prio_close(&channel->prio, &fh->prio);
++      /* If this file handle has initialize decoder device, reset it */
++      if (fh->initialized) {
++              vidioc_int_s_power(dec, 0);
++              channel->initialized = 0;
++              if (ccdc_hw_dev.close)
++                      ccdc_hw_dev.close(vpfe_dev);
++      }
++      filep->private_data = NULL;
++      /* Free memory allocated to file handle object */
++      kfree(fh);
++
++      v4l2_dbg(1, debug, vpfe_dev->driver, "</vpfe_release>\n");
++      return 0;
++}
++
++/*  vpfe_mmap : It is used to map kernel space buffers
++ *  into user spaces
++ */
++static int vpfe_mmap(struct file *filep, struct vm_area_struct *vma)
++{
++      /* Get the channel object and file handle object */
++      struct vpfe_fh *fh = filep->private_data;
++      struct channel_obj *channel = fh->channel;
++      struct common_obj *common;
++      int err = 0;
++      v4l2_dbg(1, debug, vpfe_dev->driver, "Start of vpfe mmap\n");
++      common = &(channel->common[VPFE_VIDEO_INDEX]);
++
++      err = videobuf_mmap_mapper(&common->buffer_queue, vma);
++      v4l2_dbg(1, debug, vpfe_dev->driver, "End of vpfe mmap\n");
++      return err;
++}
++
++/* vpfe_poll: It is used for select/poll system call
++ */
++static unsigned int vpfe_poll(struct file *filep, poll_table *wait)
++{
++      int err = 0;
++      struct vpfe_fh *fh = filep->private_data;
++      struct channel_obj *channel = fh->channel;
++      struct common_obj *common = &(channel->common[VPFE_VIDEO_INDEX]);
++
++      v4l2_dbg(1, debug, vpfe_dev->driver, "<vpfe_poll>");
++
++      if (common->started)
++              err = videobuf_poll_stream(filep, &common->buffer_queue, wait);
++
++      v4l2_dbg(1, debug, vpfe_dev->driver, "</vpfe_poll>");
++      return err;
++}
++
++/* vpfe capture driver file operations */
++static struct v4l2_file_operations vpfe_fops = {
++      .owner = THIS_MODULE,
++      .open = vpfe_open,
++      .release = vpfe_release,
++      .ioctl = video_ioctl2,
++      .mmap = vpfe_mmap,
++      .poll = vpfe_poll
++};
++
++static  struct vpfe_pixel_format *
++      vpfe_check_format(struct channel_obj *channel,
++                        struct v4l2_pix_format *pixfmt,
++                        int check)
++{
++      struct common_obj *common = &(channel->common[VPFE_VIDEO_INDEX]);
++      struct video_obj *vid_ch = &(channel->video);
++      struct vpfe_pixel_format *pix_fmt;
++      enum vpfe_hw_pix_format hw_pix;
++      int temp, found, hpitch, vpitch, bpp, min_height = 1,
++              min_width = 32, max_width, max_height;
++
++
++      temp = vpfe_lookup_hw_format(pixfmt->pixelformat);
++      if (temp < 0) {
++              if (check) {
++                      v4l2_err(vpfe_dev->driver, "invalid pixel format\n");
++                      return NULL;
++              }
++              /* if invalid and this is a try format, then use hw default */
++              pixfmt->pixelformat = common->fmt.fmt.pix.pixelformat;
++              /* Since this is hw default, we will find this pix format */
++              temp = vpfe_lookup_hw_format(pixfmt->pixelformat);
++
++      } else {
++              /* check if hw supports it */
++              pix_fmt = &vpfe_pix_fmts[temp];
++              temp = 0;
++              found = 0;
++              while (ccdc_hw_dev.enum_pix(&hw_pix, temp) >= 0) {
++                      if (pix_fmt->hw_fmt == hw_pix) {
++                              found = 1;
++                              break;
++                      }
++                      temp++;
++              }
++              if (!found) {
++                      if (check) {
++                              v4l2_err(vpfe_dev->driver, "hw doesn't"
++                                       "support the pixel format\n");
++                              return NULL;
++                      }
++                      /* Since this is hw default, we will find this
++                       * pix format
++                       */
++                      pixfmt->pixelformat = common->fmt.fmt.pix.pixelformat;
++                      temp = vpfe_lookup_hw_format(pixfmt->pixelformat);
++              }
++      }
++      pix_fmt = &vpfe_pix_fmts[temp];
++      if (pixfmt->field == V4L2_FIELD_ANY) {
++              /* if ANY set the field to match with decoder */
++              pixfmt->field = common->fmt.fmt.pix.field;
++      }
++
++      /* Try matching the field with the decoder scan field */
++      if (common->fmt.fmt.pix.field != pixfmt->field) {
++              if (!(VPFE_VALID_FIELD(pixfmt->field)) && check) {
++                      v4l2_err(vpfe_dev->driver, "invalid field format\n");
++                      return NULL;
++              }
++              if (common->fmt.fmt.pix.field == V4L2_FIELD_INTERLACED) {
++                      if (pixfmt->field != V4L2_FIELD_SEQ_TB) {
++                              if (check) {
++                                      v4l2_err(vpfe_dev->driver,
++                                              "invalid field format\n");
++                                      return NULL;
++                              }
++                              pixfmt->field = common->fmt.fmt.pix.field;
++                      }
++              } else if (common->fmt.fmt.pix.field == V4L2_FIELD_NONE) {
++                      if (check) {
++                              v4l2_err(vpfe_dev->driver,
++                                      "invalid field format\n");
++                              return NULL;
++                      }
++                      pixfmt->field = common->fmt.fmt.pix.field;
++              } else
++                      pixfmt->field = common->fmt.fmt.pix.field;
++      }
++
++      if (pixfmt->field == V4L2_FIELD_INTERLACED)
++              min_height = 2;
++
++      max_width = vid_ch->std_info.activepixels;
++      max_height = vid_ch->std_info.activelines;
++      if ((pixfmt->pixelformat == V4L2_PIX_FMT_SBGGR8) ||
++         (pixfmt->pixelformat == V4L2_PIX_FMT_NV12) ||
++         (pixfmt->pixelformat == V4L2_PIX_FMT_SGRBG10DPCM8))
++              bpp = 1;
++      else
++              bpp = 2;
++      min_width /= bpp;
++      hpitch = pixfmt->width;
++      vpitch = pixfmt->height;
++      v4l2_info(vpfe_dev->driver, "hpitch = %d, vpitch = %d, bpp = %d\n",
++                hpitch, vpitch, bpp);
++      if (hpitch < min_width)
++              hpitch = min_width;
++      if (vpitch < min_width)
++              vpitch = min_height;
++
++      /* Check for upper limits of pitch */
++      if (hpitch > max_width)
++              hpitch = max_width;
++      if (vpitch > max_height)
++              vpitch = max_height;
++
++      /* recalculate bytesperline and sizeimage since width
++       * and height might have changed
++       */
++      pixfmt->bytesperline = (((hpitch * bpp) + 31) & ~31);
++      if (pixfmt->pixelformat == V4L2_PIX_FMT_NV12)
++              pixfmt->sizeimage = pixfmt->bytesperline * vpitch +
++                                  ((pixfmt->bytesperline * vpitch) >> 1);
++      else
++              pixfmt->sizeimage = pixfmt->bytesperline * vpitch;
++      pixfmt->width = hpitch;
++      pixfmt->height = vpitch;
++      v4l2_info(vpfe_dev->driver, "adjusted hpitch = %d, vpitch ="
++                " %d, bpp = %d\n", hpitch, vpitch, bpp);
++      return pix_fmt;
++}
++
++static int vpfe_querycap(struct file *file, void  *priv,
++                             struct v4l2_capability *cap)
++{
++      struct vpfe_fh *fh = file->private_data;
++      struct channel_obj *channel = fh->channel;
++      v4l2_dbg(1, debug, vpfe_dev->driver, "VIDIOC_QUERYCAP\n");
++      memset(cap, 0, sizeof(*cap));
++      if ((VPFE_CHANNEL0_VIDEO == channel->channel_id))
++              *cap = vpfe_videocap;
++      else
++              return -EINVAL;
++      return 0;
++}
++
++static int vpfe_g_fmt_vid_cap(struct file *file, void *priv,
++                              struct v4l2_format *fmt)
++{
++      int ret = 0;
++      struct vpfe_fh *fh = file->private_data;
++      struct channel_obj *channel = fh->channel;
++      struct common_obj *common = NULL;
++      common = &(channel->common[VPFE_VIDEO_INDEX]);
++
++      v4l2_dbg(1, debug, vpfe_dev->driver, "VIDIOC_G_FMT\n");
++      /* Fill in the information about
++       * format
++       */
++      ret = mutex_lock_interruptible(&(common->lock));
++      if (ret)
++              goto lock_out;
++      *fmt = common->fmt;
++lock_out:
++      mutex_unlock(&(common->lock));
++      return ret;
++}
++
++static int vpfe_enum_fmt_vid_cap(struct file *file, void  *priv,
++                                 struct v4l2_fmtdesc *fmt)
++{
++      int ret;
++      enum vpfe_hw_pix_format hw_pix;
++
++      v4l2_dbg(1, debug, vpfe_dev->driver, "VIDIOC_ENUM_FMT\n");
++      /* Fill in the information about format */
++      fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
++      ret = ccdc_hw_dev.enum_pix(&hw_pix, fmt->index);
++      if (!ret) {
++              ret = vpfe_lookup_v4l2_pix_format(hw_pix);
++              if (ret >= 0) {
++                      strcpy(fmt->description, vpfe_pix_fmts[ret].desc);
++                      fmt->pixelformat = vpfe_pix_fmts[ret].pix_fmt;
++                      ret = 0;
++              }
++      }
++      return ret;
++}
++
++static int vpfe_s_fmt_vid_cap(struct file *file, void *priv,
++                              struct v4l2_format *fmt)
++{
++      struct vpfe_fh *fh = file->private_data;
++      struct channel_obj *channel = fh->channel;
++      struct common_obj *common = NULL;
++      struct v4l2_rect win;
++      struct vpfe_pixel_format *pix_fmts;
++      int ret = 0;
++      common = &(channel->common[VPFE_VIDEO_INDEX]);
++
++      v4l2_dbg(1, debug, vpfe_dev->driver, "VIDIOC_S_FMT\n");
++      /* If streaming is started, return error */
++      if (common->started) {
++              v4l2_err(vpfe_dev->driver, "Streaming is started\n");
++              ret = -EBUSY;
++              goto out;
++      }
++      /* Check for valid frame format */
++      pix_fmts = vpfe_check_format(channel, &fmt->fmt.pix, 1);
++
++      if (ISNULL(pix_fmts)) {
++              ret = -EINVAL;
++              goto out;
++      }
++
++      /* store the pixel format in the channel
++       * object */
++      ret = mutex_lock_interruptible(&common->lock);
++      if (ret)
++              goto out;
++
++      /* First detach any IRQ if currently attached */
++      if (vpfe_detach_irq(channel) < 0) {
++              v4l2_err(vpfe_dev->driver, "Error in detaching IRQ\n");
++              ret = -EFAULT;
++              goto lock_out;
++      }
++
++      common->fmt = *fmt;
++
++      /* we are using same variable for setting crop window
++       * at ccdc. For ccdc, this is same as
++       * image window
++       */
++      ccdc_hw_dev.get_image_window(&win);
++      win.width = common->fmt.fmt.pix.width;
++      win.height = common->fmt.fmt.pix.height;
++      ccdc_hw_dev.set_image_window(&win);
++
++      /* In this case, image window and crop window are
++       * the same
++       */
++      if (common->fmt.fmt.pix.pixelformat == V4L2_PIX_FMT_SBGGR16)
++              ccdc_hw_dev.set_pixelformat(VPFE_BAYER);
++      else if (common->fmt.fmt.pix.pixelformat == V4L2_PIX_FMT_SBGGR8)
++              ccdc_hw_dev.set_pixelformat(VPFE_BAYER_8BIT_PACK_ALAW);
++      else if (common->fmt.fmt.pix.pixelformat == V4L2_PIX_FMT_UYVY)
++              ccdc_hw_dev.set_pixelformat(VPFE_UYVY);
++      else if (common->fmt.fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV)
++              ccdc_hw_dev.set_pixelformat(VPFE_YUYV);
++      else {
++              /* invalid pix format */
++              ret = -EINVAL;
++              goto lock_out;
++      }
++      if (common->fmt.fmt.pix.field ==
++          V4L2_FIELD_INTERLACED) {
++              ccdc_hw_dev.set_buftype(CCDC_BUFTYPE_FLD_INTERLEAVED);
++              ccdc_hw_dev.set_frame_format(CCDC_FRMFMT_INTERLACED);
++      } else if (common->fmt.fmt.pix.field ==
++                 V4L2_FIELD_SEQ_TB) {
++              ccdc_hw_dev.set_buftype(CCDC_BUFTYPE_FLD_SEPARATED);
++              ccdc_hw_dev.set_frame_format(CCDC_FRMFMT_INTERLACED);
++      } else if (common->fmt.fmt.pix.field == V4L2_FIELD_NONE)
++              ccdc_hw_dev.set_frame_format(CCDC_FRMFMT_PROGRESSIVE);
++      else {
++              v4l2_err(vpfe_dev->driver, "\n field error!");
++              ret = -EINVAL;
++      }
++lock_out:
++      mutex_unlock(&common->lock);
++out:
++      return ret;
++}
++
++static int vpfe_try_fmt_vid_cap(struct file *file, void *priv,
++                                struct v4l2_format *f)
++{
++      struct vpfe_fh *fh = file->private_data;
++      struct channel_obj *channel = fh->channel;
++      struct vpfe_pixel_format *pix_fmts;
++
++      v4l2_dbg(1, debug, vpfe_dev->driver, "VIDIOC_TRY_FMT\n");
++
++      pix_fmts = vpfe_check_format(channel, &f->fmt.pix, 0);
++      if (ISNULL(pix_fmts))
++              return -EINVAL;
++      return 0;
++}
++
++static void vpfe_config_format(struct channel_obj *ch)
++{
++      struct common_obj *common = &(ch->common[VPFE_VIDEO_INDEX]);
++      struct v4l2_rect win;
++      struct video_obj *vid_ch = NULL;
++
++      vid_ch = &(ch->video);
++      common->crop.top = 0;
++      common->crop.top = 0;
++      common->crop.width = common->fmt.fmt.pix.width =
++                      vid_ch->std_info.activepixels;
++      common->crop.height = common->fmt.fmt.pix.height =
++                      vid_ch->std_info.activelines;
++      win.top = common->crop.top;
++      win.left = common->crop.left;
++      win.width = common->fmt.fmt.pix.width;
++      win.height = common->fmt.fmt.pix.height;
++      ccdc_hw_dev.set_image_window(&win);
++      if (vid_ch->std_info.frame_format) {
++              common->fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
++              ccdc_hw_dev.set_frame_format(CCDC_FRMFMT_INTERLACED);
++              ccdc_hw_dev.set_buftype(CCDC_BUFTYPE_FLD_INTERLEAVED);
++      } else {
++              common->fmt.fmt.pix.field = V4L2_FIELD_NONE;
++              ccdc_hw_dev.set_frame_format(CCDC_FRMFMT_PROGRESSIVE);
++      }
++      ccdc_hw_dev.get_line_length(&common->fmt.fmt.pix.bytesperline);
++      common->fmt.fmt.pix.sizeimage = common->fmt.fmt.pix.bytesperline *
++                                  common->fmt.fmt.pix.height;
++}
++
++static int vpfe_enum_input(struct file *file, void *priv,
++                               struct v4l2_input *inp)
++{
++      struct vpfe_fh *fh = file->private_data;
++      struct channel_obj *channel = fh->channel;
++      struct vpfe_capture_input *vpfe_inputs = channel->video.input;
++      int ret = -EINVAL;
++
++      v4l2_dbg(1, debug, vpfe_dev->driver, "VIDIOC_ENUMINPUT\n");
++
++      if (inp->index > vpfe_inputs->num_inputs)
++              return ret;
++
++      if (vpfe_inputs->inputs[inp->index].input.name[0]) {
++              memcpy(inp, &vpfe_inputs->inputs[inp->index].input,
++                      sizeof(struct v4l2_input));
++              return 0;
++      }
++      return ret;
++}
++
++static int vpfe_g_input(struct file *file, void *priv, unsigned int *index)
++{
++      struct vpfe_fh *fh = file->private_data;
++      struct channel_obj *channel = fh->channel;
++      struct common_obj *common =
++                          &(channel->common[VPFE_VIDEO_INDEX]);
++      struct vpfe_capture_input *vpfe_inputs = channel->video.input;
++      int ret = 0;
++
++      v4l2_dbg(1, debug, vpfe_dev->driver, "VIDIOC_G_INPUT\n");
++      ret = mutex_lock_interruptible(&common->lock);
++      if (!ret)
++              *index = vpfe_inputs->current_input;
++      mutex_unlock(&common->lock);
++      return ret;
++}
++
++
++static int vpfe_s_input(struct file *file, void *priv, unsigned int index)
++{
++      int i, ret = -EINVAL;
++      v4l2_std_id std_id;
++      struct vpfe_fh *fh = file->private_data;
++      struct channel_obj *channel = fh->channel;
++      struct v4l2_int_device *new_dec, *curr_dec =
++              channel->decoder[channel->current_decoder];
++      struct common_obj *common =
++                          &(channel->common[VPFE_VIDEO_INDEX]);
++      struct vpfe_capture_input *vpfe_inputs = channel->video.input;
++      char *new_dec_name;
++
++      v4l2_dbg(1, debug, vpfe_dev->driver, "VIDIOC_S_INPUT\n");
++      if (index > vpfe_inputs->num_inputs) {
++              v4l2_err(vpfe_dev->driver, "input index exceeds limit\n");
++              return ret;
++      }
++
++      if (!vpfe_inputs->inputs[index].input.name[0]) {
++              v4l2_err(vpfe_dev->driver, "input index exceeds limit\n");
++              return ret;
++      }
++
++      ret = mutex_lock_interruptible(&common->lock);
++      if (ret)
++              goto out;
++      /* If streaming is started return device busy
++       * error
++       */
++      if (common->started) {
++              v4l2_err(vpfe_dev->driver, "Streaming is on\n");
++              ret = -EBUSY;
++              goto lock_out;
++      }
++      new_dec_name = vpfe_inputs->inputs[index].dec_name;
++      /* switch in new decoder to be active */
++      if (strcmp(new_dec_name, curr_dec->name)) {
++              for (i = 0; i < VPFE_CAPTURE_NUM_DECODERS; i++) {
++                      if (channel->decoder[i] &&
++                              !strcmp(new_dec_name,
++                                      channel->decoder[i]->name)) {
++                              new_dec = channel->decoder[i];
++                              channel->current_decoder = i;
++                              /* Deinitialize the previous decoder
++                               * and power down
++                               */
++                              vidioc_int_s_power(curr_dec, 0);
++
++                              ret = vidioc_int_s_power(new_dec, 1);
++                              if (ret)
++                                      goto lock_out;
++                              ret = vidioc_int_init(new_dec);
++                              if (ret)
++                                      goto lock_out;
++                              curr_dec = new_dec;
++                      }
++              }
++
++              if (i == VPFE_CAPTURE_NUM_DECODERS)
++                      /* couldn't find the decoder */
++                      goto lock_out;
++      }
++      ret = 0;
++      /* Set the input in the decoder */
++      if (vpfe_inputs->inputs[index].routing_supported)
++              ret = vidioc_int_s_video_routing(curr_dec,
++                              &vpfe_inputs->inputs[index].route);
++
++      if (ret) {
++              v4l2_err(vpfe_dev->driver,
++                      "vpfe_doioctl:error in setting input in decoder \n");
++              ret = -EINVAL;
++              goto lock_out;
++      }
++
++      vpfe_inputs->current_input = index;
++      ret = vpfe_set_hw_if_type(channel);
++      if (ret)
++              goto lock_out;
++
++      ret = vpfe_config_default_format(channel);
++      if (ret)
++              goto lock_out;
++
++      /* Detect default standard */
++      ret = vidioc_int_querystd(curr_dec, &std_id);
++      if (!ret)
++              ret = vpfe_get_stdinfo(channel, &std_id);
++
++      if (ret)
++              goto lock_out;
++
++      vpfe_config_format(channel);
++lock_out:
++      mutex_unlock(&common->lock);
++out:
++      return ret;
++}
++
++static int vpfe_querystd(struct file *file, void *priv, v4l2_std_id *std_id)
++{
++      int ret = 0;
++      struct vpfe_fh *fh = file->private_data;
++      struct channel_obj *channel = fh->channel;
++      struct common_obj *common =
++                          &(channel->common[VPFE_VIDEO_INDEX]);
++      struct v4l2_int_device *dec =
++              channel->decoder[channel->current_decoder];
++      ret = mutex_lock_interruptible(&common->lock);
++      if (ret)
++              goto lock_out;
++      /* Call querystd function of decoder device */
++      ret = vidioc_int_querystd(dec, std_id);
++      /* Set format based on the standard selected */
++      if (!ret)
++              ret = vpfe_get_stdinfo(channel, std_id);
++      vpfe_config_format(channel);
++lock_out:
++      mutex_unlock(&common->lock);
++      return ret;
++}
++
++static int vpfe_s_std(struct file *file, void *priv, v4l2_std_id *std_id)
++{
++      int ret = 0;
++      struct vpfe_fh *fh = file->private_data;
++      struct channel_obj *channel = fh->channel;
++      struct common_obj *common =
++          &(channel->common[VPFE_VIDEO_INDEX]);
++      struct v4l2_int_device *dec =
++              channel->decoder[channel->current_decoder];
++      v4l2_dbg(1, debug, vpfe_dev->driver, "VIDIOC_S_STD\n");
++
++      /* If streaming is started, return device
++         busy error */
++      if (common->started) {
++              v4l2_err(vpfe_dev->driver, "streaming is started\n");
++              ret = -EBUSY;
++              goto out;
++      }
++      /* Call decoder driver function to set the
++         standard */
++      ret = mutex_lock_interruptible(&common->lock);
++      if (ret)
++              goto out;
++      ret = vidioc_int_s_std(dec, std_id);
++
++      /* If it returns error, return error */
++      if (!ret)
++              ret = vpfe_get_stdinfo(channel, std_id);
++
++      if (!ret)
++              vpfe_config_format(channel);
++out:
++      mutex_unlock(&common->lock);
++      return ret;
++}
++
++static int vpfe_g_std(struct file *file, void *priv, v4l2_std_id *std_id)
++{
++      struct vpfe_fh *fh = file->private_data;
++      struct channel_obj *channel = fh->channel;
++      struct v4l2_int_device *dec =
++              channel->decoder[channel->current_decoder];
++      int ret;
++      v4l2_dbg(1, debug, vpfe_dev->driver, "VIDIOC_G_STD\n");
++      ret = vidioc_int_querystd(dec, std_id);
++      if (ret)
++              goto out;
++
++      ret = vpfe_get_stdinfo(channel, std_id);
++      if (!ret)
++              vpfe_config_format(channel);
++out:
++      return ret;
++}
++/*
++ *  Videobuf operations
++ */
++static int vpfe_videobuf_setup(struct videobuf_queue *vq,
++                              unsigned int *count,
++                              unsigned int *size)
++{
++      /* Get the file handle object and channel object */
++      struct vpfe_fh *fh = vq->priv_data;
++      struct channel_obj *channel = fh->channel;
++      v4l2_dbg(1, debug, vpfe_dev->driver, "<vpfe_buffer_setup>\n");
++      *size = config_params.channel_bufsize[channel->channel_id];
++
++      if (*count < config_params.min_numbuffers)
++              *count = config_params.min_numbuffers;
++      v4l2_dbg(1, debug, vpfe_dev->driver,
++              "count=%d, size=%d\n", *count, *size);
++      return 0;
++}
++
++static int vpfe_videobuf_prepare(struct videobuf_queue *vq,
++                              struct videobuf_buffer *vb,
++                              enum v4l2_field field)
++{
++      int ret = 0;
++      /* Get the file handle object and channel object */
++      struct vpfe_fh *fh = vq->priv_data;
++      struct channel_obj *channel = fh->channel;
++      struct common_obj *common;
++      unsigned long addr;
++
++      v4l2_dbg(1, debug, vpfe_dev->driver, "<vpfe_buffer_prepare>\n");
++
++      common = &(channel->common[VPFE_VIDEO_INDEX]);
++
++      if (V4L2_MEMORY_USERPTR == common->memory) {
++              /* we don't support user ptr IO */
++              v4l2_dbg(1, debug, vpfe_dev->driver,
++                      "<vpfe_buffer_prepare: USERPTR IO"
++                      " not supported>\n");
++              ret = -EINVAL;
++              goto out;
++      }
++
++      /* If buffer is not initialized, initialize it */
++      if (VIDEOBUF_NEEDS_INIT == vb->state) {
++              vb->width = common->width;
++              vb->height = common->height;
++              vb->size = vb->width * vb->height * 2;
++              vb->field = field;
++      }
++      addr = videobuf_to_dma_contig(vb);
++      if (vq->streaming) {
++              if (!ISALIGNED(addr)) {
++                      v4l2_err(vpfe_dev->driver, "buffer_prepare:offset is"
++                              "not aligned to 32 bytes\n");
++                      ret = -EINVAL;
++                      goto out;
++              }
++      }
++      vb->state = VIDEOBUF_PREPARED;
++      v4l2_dbg(1, debug, vpfe_dev->driver, "</vpfe_buffer_prepare>\n");
++out:
++      return ret;
++}
++
++static void vpfe_videobuf_queue(struct videobuf_queue *vq,
++                              struct videobuf_buffer *vb)
++{
++      /* Get the file handle object and channel object */
++      struct vpfe_fh *fh = vq->priv_data;
++      struct channel_obj *channel = fh->channel;
++      struct common_obj *common = NULL;
++
++      v4l2_dbg(1, debug, vpfe_dev->driver, "<vpfe_buffer_queue>\n");
++      common = &(channel->common[VPFE_VIDEO_INDEX]);
++
++      /* add the buffer to the DMA queue */
++      list_add_tail(&vb->queue, &common->dma_queue);
++      /* Change state of the buffer */
++      vb->state = VIDEOBUF_QUEUED;
++      v4l2_dbg(1, debug, vpfe_dev->driver, "</vpfe_buffer_queue>\n");
++}
++
++static void vpfe_videobuf_release(struct videobuf_queue *vq,
++                              struct videobuf_buffer *vb)
++{
++      v4l2_dbg(1, debug, vpfe_dev->driver, "vpfe_videobuf_release\n");
++      videobuf_dma_contig_free(vq, vb);
++      vb->state = VIDEOBUF_NEEDS_INIT;
++}
++
++static struct videobuf_queue_ops vpfe_videobuf_qops = {
++      .buf_setup      = vpfe_videobuf_setup,
++      .buf_prepare    = vpfe_videobuf_prepare,
++      .buf_queue      = vpfe_videobuf_queue,
++      .buf_release    = vpfe_videobuf_release,
++};
++
++static int vpfe_reqbufs(struct file *file, void *priv,
++                            struct v4l2_requestbuffers *p)
++{
++      int ret = 0;
++      struct vpfe_fh *fh = file->private_data;
++      struct channel_obj *channel = fh->channel;
++      struct common_obj *common = NULL;
++      enum v4l2_field field;
++
++      v4l2_dbg(1, debug, vpfe_dev->driver, "<vpfe_buffer_queue>\n");
++      common = &(channel->common[VPFE_VIDEO_INDEX]);
++
++      v4l2_dbg(1, debug, vpfe_dev->driver, "\nEnd of VIDIOC_REQBUFS ioctl");
++
++      if (V4L2_BUF_TYPE_VIDEO_CAPTURE != p->type) {
++              ret = -EINVAL;
++              goto out;
++      }
++      if (common->io_usrs != 0) {
++              ret = -EBUSY;
++              goto out;
++      }
++
++      ret = mutex_lock_interruptible(&common->lock);
++      if (ret)
++              goto out;
++
++      if (common->fmt.fmt.pix.field != V4L2_FIELD_ANY)
++              field = common->fmt.fmt.pix.field;
++      else if (channel->vpfe_if == VPFE_RAW_BAYER)
++              field = V4L2_FIELD_NONE;
++      else
++              field = V4L2_FIELD_INTERLACED;
++
++      videobuf_queue_dma_contig_init(&common->buffer_queue,
++                              &vpfe_videobuf_qops,
++                              NULL,
++                              &common->irqlock,
++                              p->type,
++                              field,
++                              sizeof(struct videobuf_buffer),
++                              fh);
++
++      fh->io_allowed[VPFE_VIDEO_INDEX] = 1;
++      common->io_usrs = 1;
++      INIT_LIST_HEAD(&common->dma_queue);
++      ret = videobuf_reqbufs(&common->buffer_queue, p);
++      mutex_unlock(&common->lock);
++out:
++      return ret;
++}
++
++static int vpfe_querybuf(struct file *file, void *priv,
++                             struct v4l2_buffer *p)
++{
++
++      struct vpfe_fh *fh = file->private_data;
++      struct channel_obj *channel = fh->channel;
++      struct common_obj *common = NULL;
++      int ret = 0;
++      u8 buf_type_index = 0;
++      v4l2_dbg(1, debug, vpfe_dev->driver, "VIDIOC_QUERYBUF\n");
++      buf_type_index = VPFE_VIDEO_INDEX;
++      if (V4L2_BUF_TYPE_VIDEO_CAPTURE != p->type) {
++              v4l2_err(vpfe_dev->driver,
++                      "VIDIOC_QUERYBUF:Invalid buf type\n");
++              ret = -EINVAL;
++              goto out;
++      }
++      common = &(channel->common[buf_type_index]);
++      if (p->memory != V4L2_MEMORY_MMAP) {
++              v4l2_err(vpfe_dev->driver,
++                      "VIDIOC_QUERYBUF:Invalid memory\n");
++              ret = -EINVAL;
++              goto out;
++      }
++      /* Call videobuf_querybuf to get information */
++      return videobuf_querybuf(&common->buffer_queue, p);
++out:
++      return ret;
++}
++
++static int vpfe_qbuf(struct file *file, void *priv,
++                         struct v4l2_buffer *p)
++{
++      struct vpfe_fh *fh = file->private_data;
++      struct channel_obj *channel = fh->channel;
++      struct common_obj *common = NULL;
++      int buf_type_index, ret = 0;
++      v4l2_dbg(1, debug, vpfe_dev->driver, "VIDIOC_QBUF\n");
++      buf_type_index = VPFE_VIDEO_INDEX;
++      if (V4L2_BUF_TYPE_VIDEO_CAPTURE != p->type) {
++              v4l2_err(vpfe_dev->driver, "VIDIOC_QBUF:Invalid buf type\n");
++              ret = -EINVAL;
++              goto out;
++      }
++      common = &(channel->common[buf_type_index]);
++
++      /* If this file handle is not allowed to do IO,
++       * return error
++       */
++      if (!fh->io_allowed[buf_type_index]) {
++              v4l2_err(vpfe_dev->driver, "fh->io_allowed\n");
++              ret = -EACCES;
++              goto out;
++      }
++      return videobuf_qbuf(&common->buffer_queue, p);
++out:
++      return ret;
++}
++static int vpfe_dqbuf(struct file *file, void *priv,
++                          struct v4l2_buffer *p)
++{
++      struct vpfe_fh *fh = file->private_data;
++      struct channel_obj *channel = fh->channel;
++      struct common_obj *common = NULL;
++      int buf_type_index = 0, ret = 0;
++      buf_type_index = VPFE_VIDEO_INDEX;
++      common = &(channel->common[buf_type_index]);
++
++      if (V4L2_BUF_TYPE_VIDEO_CAPTURE != p->type) {
++              v4l2_err(vpfe_dev->driver, "VIDIOC_DQBUF:Invalid buf type\n");
++              ret = -EINVAL;
++              goto out;
++      }
++      if (file->f_flags & O_NONBLOCK)
++              ret = videobuf_dqbuf(&common->buffer_queue, p, 1);
++      else
++              ret = videobuf_dqbuf(&common->buffer_queue, p, 0);
++out:
++      return ret;
++}
++
++/*  vpfe_calculate_offsets : This function calculates buffers offset
++ *  for top and bottom field
++ */
++static void vpfe_calculate_offsets(struct channel_obj *channel)
++{
++      struct common_obj *common = &(channel->common[VPFE_VIDEO_INDEX]);
++
++      struct v4l2_rect image_win;
++
++      v4l2_dbg(1, debug, vpfe_dev->driver, "<vpfe_calculate_offsets>\n");
++
++      common->field_off = 0;
++      ccdc_hw_dev.get_image_window(&image_win);
++      common->field_off = (image_win.height - 2) * image_win.width;
++      v4l2_dbg(1, debug, vpfe_dev->driver, "</vpfe_calculate_offsets>\n");
++}
++
++static int vpfe_streamon(struct file *file, void *priv,
++                             enum v4l2_buf_type i)
++{
++      int ret = 0;
++      struct vpfe_fh *fh = file->private_data;
++      struct channel_obj *channel = fh->channel;
++      struct common_obj *common = NULL;
++      int buf_type_index = VPFE_VIDEO_INDEX;
++      unsigned long addr;
++      v4l2_dbg(1, debug, vpfe_dev->driver, "VIDIOC_STREAMON\n");
++      if (V4L2_BUF_TYPE_VIDEO_CAPTURE != i) {
++              v4l2_err(vpfe_dev->driver,
++                      "VIDIOC_STREAMON:Invalid buf type\n");
++              ret = -EINVAL;
++              goto out;
++      }
++      common = &(channel->common[buf_type_index]);
++      /* If file handle is not allowed IO,
++       * return error
++       */
++      if (!fh->io_allowed[buf_type_index]) {
++              v4l2_err(vpfe_dev->driver, "fh->io_allowed\n");
++              ret = -EACCES;
++              goto out;
++      }
++      /* If Streaming is already started,
++       * return error
++       */
++      if (common->started) {
++              v4l2_err(vpfe_dev->driver, "channel->started\n");
++              ret = -EBUSY;
++              goto out;
++      }
++      /* Call videobuf_streamon to start streaming
++       * in videobuf
++       */
++      ret = videobuf_streamon(&common->buffer_queue);
++      if (ret)
++              goto out;
++
++      ret = mutex_lock_interruptible(&common->lock);
++      if (ret)
++              goto out;
++      /* If buffer queue is empty, return error */
++      if (list_empty(&common->dma_queue)) {
++              v4l2_err(vpfe_dev->driver, "buffer queue is empty\n");
++              ret = -EIO;
++              goto lock_out;
++      }
++      /* Get the next frame from the buffer queue */
++      common->nextFrm = common->curFrm =
++          list_entry(common->dma_queue.next,
++                     struct videobuf_buffer, queue);
++      /* Remove buffer from the buffer queue */
++      list_del(&common->curFrm->queue);
++      /* Mark state of the current frame to active */
++      common->curFrm->state = VIDEOBUF_ACTIVE;
++      /* Initialize field_id and started member */
++      channel->field_id = 0;
++      common->started = 1;
++
++      addr = videobuf_to_dma_contig(common->curFrm);
++
++      /* Calculate field offset */
++      vpfe_calculate_offsets(channel);
++
++      if (vpfe_attach_irq(channel) < 0) {
++              v4l2_err(vpfe_dev->driver,
++                      "Error in attaching interrupt handle\n");
++              ret = -EFAULT;
++              goto lock_out;
++      }
++
++      ccdc_hw_dev.configure();
++      ccdc_hw_dev.setfbaddr((unsigned long)(addr));
++      ccdc_hw_dev.enable(1);
++      if (ccdc_hw_dev.enable_out_to_sdram)
++              ccdc_hw_dev.enable_out_to_sdram(1);
++lock_out:
++      mutex_unlock(&common->lock);
++out:
++      return ret;
++}
++
++static int vpfe_streamoff(struct file *file, void *priv,
++                              enum v4l2_buf_type i)
++{
++      struct vpfe_fh *fh = file->private_data;
++      struct channel_obj *channel = fh->channel;
++      struct common_obj *common = NULL;
++      int buf_type_index = VPFE_VIDEO_INDEX, ret = 0;
++      if (V4L2_BUF_TYPE_VIDEO_CAPTURE != i) {
++              v4l2_err(vpfe_dev->driver,
++                      "VIDIOC_STREAMOFF:Invalid buf type\n");
++              return -EINVAL;
++      }
++      common = &(channel->common[buf_type_index]);
++      v4l2_dbg(1, debug, vpfe_dev->driver, "VIDIOC_STREAMOFF\n");
++      /* If io is allowed for this file handle,
++       * return error
++       */
++      if (!fh->io_allowed[buf_type_index]) {
++              v4l2_err(vpfe_dev->driver, "fh->io_allowed\n");
++              ret = -EACCES;
++              goto out;
++      }
++      /* If streaming is not started, return error */
++      if (!common->started) {
++              v4l2_err(vpfe_dev->driver, "channel->started\n");
++              ret = -EINVAL;
++              goto out;
++      }
++      ret = mutex_lock_interruptible(&common->lock);
++      if (ret)
++              goto out;
++      common->started = 0;
++      ccdc_hw_dev.enable(0);
++      if (ccdc_hw_dev.enable_out_to_sdram)
++              ccdc_hw_dev.enable_out_to_sdram(0);
++      if (vpfe_detach_irq(channel) < 0) {
++              v4l2_err(vpfe_dev->driver,
++                      "Error in detaching interrupt handler\n");
++              mutex_unlock(&common->lock);
++              ret = -EFAULT;
++              goto lock_out;
++      }
++      ret = videobuf_streamoff(&common->buffer_queue);
++lock_out:
++      mutex_unlock(&common->lock);
++out:
++      return ret;
++}
++
++static int vpfe_queryctrl(struct file *file, void *priv,
++                              struct v4l2_queryctrl *qc)
++{
++      struct vpfe_fh *fh = file->private_data;
++      struct channel_obj *channel = fh->channel;
++      struct v4l2_int_device *dec =
++              channel->decoder[channel->current_decoder];
++      v4l2_dbg(1, debug, vpfe_dev->driver, "VIDIOC_QUERYCTRL\n");
++      /* Call queryctrl function of decoder device */
++      return vidioc_int_queryctrl(dec, qc);
++}
++
++static int vpfe_g_ctrl(struct file *file, void *priv,
++                           struct v4l2_control *ctrl)
++{
++      struct vpfe_fh *fh = file->private_data;
++      struct channel_obj *channel = fh->channel;
++      struct v4l2_int_device *dec =
++              channel->decoder[channel->current_decoder];
++      struct common_obj *common =
++          &(channel->common[VPFE_VIDEO_INDEX]);
++      int ret = 0;
++      v4l2_dbg(1, debug, vpfe_dev->driver, "VIDIOC_G_CTRL\n");
++      /* Call getcontrol function of decoder device */
++      ret = mutex_lock_interruptible(&common->lock);
++      if (ret)
++              return ret;
++      ret = vidioc_int_g_ctrl(dec, ctrl);
++      mutex_unlock(&common->lock);
++      return ret;
++}
++
++static int vpfe_s_ctrl(struct file *file, void *priv,
++                           struct v4l2_control *ctrl)
++{
++      int ret = 0;
++      struct vpfe_fh *fh = file->private_data;
++      struct channel_obj *channel = fh->channel;
++      struct common_obj *common =
++          &(channel->common[VPFE_VIDEO_INDEX]);
++      struct v4l2_int_device *dec =
++              channel->decoder[channel->current_decoder];
++      v4l2_dbg(1, debug, vpfe_dev->driver, "VIDIOC_S_CTRL\n");
++      /* Call setcontrol function of decoder device */
++      ret = mutex_lock_interruptible(&common->lock);
++      if (ret)
++              return ret;
++      ret = vidioc_int_s_ctrl(dec, ctrl);
++      mutex_unlock(&common->lock);
++      return ret;
++}
++
++static int vpfe_cropcap(struct file *file, void *priv,
++                            struct v4l2_cropcap *crop)
++{
++      struct vpfe_fh *fh = file->private_data;
++      struct channel_obj *channel = fh->channel;
++      struct video_obj *vid_ch = NULL;
++      vid_ch = &(channel->video);
++
++      if (vid_ch->index > vpfe_max_standards)
++              return -EINVAL;
++      memset(crop, 0, sizeof(struct v4l2_cropcap));
++      crop->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
++      crop->bounds.width = crop->defrect.width =
++              vpfe_standards[vid_ch->index].width;
++      crop->bounds.height = crop->defrect.height =
++              vpfe_standards[vid_ch->index].height;
++      crop->pixelaspect = vpfe_standards[vid_ch->index].pixelaspect;
++      return 0;
++}
++
++static int vpfe_g_crop(struct file *file, void *priv,
++                           struct v4l2_crop *crop)
++{
++      struct vpfe_fh *fh = file->private_data;
++      struct channel_obj *channel = fh->channel;
++      struct common_obj *common = NULL;
++      common = &(channel->common[VPFE_VIDEO_INDEX]);
++      v4l2_dbg(1, debug, vpfe_dev->driver, "\nStarting VIDIOC_G_CROP ioctl");
++      crop->c = common->crop;
++      return 0;
++}
++
++static int vpfe_s_crop(struct file *file, void *priv,
++                           struct v4l2_crop *crop)
++{
++      int ret = 0;
++      struct vpfe_fh *fh = file->private_data;
++      struct channel_obj *channel = fh->channel;
++      struct common_obj *common = NULL;
++      struct video_obj *vid_ch = NULL;
++      common = &(channel->common[VPFE_VIDEO_INDEX]);
++      vid_ch = &(channel->video);
++      v4l2_dbg(1, debug, vpfe_dev->driver, "\nStarting VIDIOC_S_CROP ioctl");
++      if (common->started) {
++              /* make sure streaming is not started */
++              v4l2_err(vpfe_dev->driver,
++                      "Cannot change crop when streaming is ON\n");
++              ret = -EBUSY;
++              goto out;
++      }
++
++      ret = mutex_lock_interruptible(&common->lock);
++      if (ret)
++              goto out;
++      /* make sure parameters are valid */
++      if ((crop->c.left + crop->c.width <= vid_ch->std_info.activepixels) &&
++          (crop->c.top + crop->c.height <= vid_ch->std_info.activelines)) {
++              /* adjust the width to 16 pixel boundry */
++              crop->c.width = ((crop->c.width + 15) & ~0xf);
++              ccdc_hw_dev.set_image_window(&crop->c);
++              common->fmt.fmt.pix.width = crop->c.width;
++              common->fmt.fmt.pix.height = crop->c.height;
++              ccdc_hw_dev.get_line_length(&common->fmt.fmt.pix.bytesperline);
++              common->fmt.fmt.pix.sizeimage =
++                                  common->fmt.fmt.pix.
++                                  bytesperline *
++                                  common->fmt.fmt.pix.height;
++              common->crop = crop->c;
++      } else {
++              v4l2_err(vpfe_dev->driver, "Error in S_CROP params\n");
++              ret = -EINVAL;
++      }
++      mutex_unlock(&common->lock);
++out:
++      return ret;
++}
++
++
++static long vpfe_param_handler(struct file *file, void *priv,
++              int cmd, void *param)
++{
++      struct vpfe_fh *fh = file->private_data;
++      struct channel_obj *channel = fh->channel;
++      struct common_obj *common = NULL;
++      int ret = 0;
++      common = &(channel->common[VPFE_VIDEO_INDEX]);
++
++      if (common->started) {
++              /* only allowed if streaming is not started */
++              v4l2_err(vpfe_dev->driver, "channel already started\n");
++              ret = -EBUSY;
++              goto out;
++      }
++      ret = mutex_lock_interruptible(&common->lock);
++      if (ret)
++              goto out;
++      switch (cmd) {
++      case VPFE_CMD_S_SOC_PARAMS:
++      {
++              ret = ccdc_hw_dev.setparams(param);
++              if (ret) {
++                      v4l2_err(vpfe_dev->driver,
++                              "Error in setting parameters"
++                              " in CCDC \n");
++                      goto lock_out;
++              }
++              if (vpfe_get_image_format(&common->fmt) < 0) {
++                      v4l2_err(vpfe_dev->driver,
++                              "Invalid image format at CCDC \n");
++                      goto lock_out;
++              }
++              break;
++      }
++      default:
++              ret = -EINVAL;
++      }
++lock_out:
++      mutex_unlock(&common->lock);
++out:
++      return ret;
++}
++
++
++/* vpfe capture ioctl operations */
++static const struct v4l2_ioctl_ops vpfe_ioctl_ops = {
++      .vidioc_querycap         = vpfe_querycap,
++      .vidioc_g_fmt_vid_cap    = vpfe_g_fmt_vid_cap,
++      .vidioc_enum_fmt_vid_cap = vpfe_enum_fmt_vid_cap,
++      .vidioc_s_fmt_vid_cap    = vpfe_s_fmt_vid_cap,
++      .vidioc_try_fmt_vid_cap  = vpfe_try_fmt_vid_cap,
++      .vidioc_enum_input       = vpfe_enum_input,
++      .vidioc_g_input          = vpfe_g_input,
++      .vidioc_s_input          = vpfe_s_input,
++      .vidioc_querystd         = vpfe_querystd,
++      .vidioc_s_std            = vpfe_s_std,
++      .vidioc_g_std            = vpfe_g_std,
++      .vidioc_reqbufs          = vpfe_reqbufs,
++      .vidioc_querybuf         = vpfe_querybuf,
++      .vidioc_qbuf             = vpfe_qbuf,
++      .vidioc_dqbuf            = vpfe_dqbuf,
++      .vidioc_streamon         = vpfe_streamon,
++      .vidioc_streamoff        = vpfe_streamoff,
++      .vidioc_queryctrl        = vpfe_queryctrl,
++      .vidioc_g_ctrl           = vpfe_g_ctrl,
++      .vidioc_s_ctrl           = vpfe_s_ctrl,
++      .vidioc_cropcap          = vpfe_cropcap,
++      .vidioc_g_crop           = vpfe_g_crop,
++      .vidioc_s_crop           = vpfe_s_crop,
++      .vidioc_default          = vpfe_param_handler,
++};
++
++/*    vpfe_probe : This function creates device entries by register
++ *    itself to the V4L2 driver and initializes fields of each
++ *    channel objects
++ */
++static __init int vpfe_probe(struct platform_device *device)
++{
++      struct common_obj *common = NULL;
++      int err = -ENOMEM, index = 0;
++      struct video_device *vfd = NULL;
++      struct channel_obj *channel = NULL;
++      struct video_obj *vid_ch = NULL;
++      struct resource *res1, *res2;
++      void *__iomem mem1;
++      void *__iomem mem2;
++
++      vpfe_dev = &device->dev;
++
++      /* Get the pointer to the channel object */
++      channel = vpfe_obj.dev[0];
++      /* Allocate memory for video device */
++      vfd = video_device_alloc();
++      if (ISNULL(vfd)) {
++              v4l2_err(vpfe_dev->driver,
++                      "Unable to alloc video device\n");
++              return err;
++      }
++
++      /* Initialize field of video device */
++      vfd->release = video_device_release;
++      vfd->current_norm       = V4L2_STD_UNKNOWN;
++      vfd->fops               = &vpfe_fops;
++      vfd->ioctl_ops          = &vpfe_ioctl_ops;
++      vfd->minor              = -1;
++      vfd->tvnorms            = V4L2_STD_UNKNOWN,
++      vfd->dev                = device->dev;
++      snprintf(vfd->name, sizeof(vfd->name),
++               "%s_V%d.%d.%d",
++               CAPTURE_DRV_NAME,
++               (VPFE_CAPTURE_VERSION_CODE >> 16) & 0xff,
++               (VPFE_CAPTURE_VERSION_CODE >> 8) & 0xff,
++               (VPFE_CAPTURE_VERSION_CODE) & 0xff);
++      /* Set video_dev to the video device */
++      channel->video_dev = vfd;
++
++      channel->usrs = 0;
++      common = &(channel->common[VPFE_VIDEO_INDEX]);
++      common->io_usrs = 0;
++      common->started = 0;
++      spin_lock_init(&common->irqlock);
++      common->numbuffers = 0;
++      common->field_off = 0;
++      common->curFrm = common->nextFrm = NULL;
++      memset(&common->fmt, 0, sizeof(struct v4l2_format));
++      channel->initialized = 0;
++      channel->channel_id = 0;
++      vid_ch = &(channel->video);
++      vid_ch->input = device->dev.platform_data;
++      if (!vid_ch->input) {
++              v4l2_err(vpfe_dev->driver,
++                      "Unable to get inputs to vpfe\n");
++              err = -ENOENT;
++              goto probe_out_release;
++      }
++      vid_ch->index = 0;
++      channel->irq_type = VPFE_NO_IRQ;
++      /* Get VINT0 irq resource */
++      res1 = platform_get_resource(device, IORESOURCE_IRQ, 0);
++      if (!res1) {
++              err = -ENOENT;
++              v4l2_err(vpfe_dev->driver, "Unable to get interrupt for VINT0");
++              goto probe_out_release;
++      }
++      channel->ccdc_irq0 = res1->start;
++
++      /* Get VINT1 irq resource */
++      res1 = platform_get_resource(device,
++                              IORESOURCE_IRQ, 1);
++      if (!res1) {
++              err = -ENOENT;
++              v4l2_err(vpfe_dev->driver,
++                      "Unable to get interrupt for VINT1");
++              goto probe_out_release;
++      }
++      channel->ccdc_irq1 = res1->start;
++      channel->res1 = platform_get_resource(device, IORESOURCE_MEM, 0);
++      channel->res2 = platform_get_resource(device, IORESOURCE_MEM, 1);
++      if (!channel->res1 || !channel->res2) {
++              v4l2_err(vpfe_dev->driver,
++                      "Unable to get register address map\n");
++              err = -ENOENT;
++              goto probe_out_release;
++      }
++      res1 = (struct resource *)channel->res1;
++      res2 = (struct resource *)channel->res2;
++      if (!request_mem_region(res1->start, res1->end - res1->start + 1,
++                              vpfe_dev->driver->name)) {
++              err = -ENXIO;
++              v4l2_err(vpfe_dev->driver,
++                      "Failed request_mem_region for ccdc base\n");
++              goto probe_out_release;
++      }
++
++      mem1 = ioremap_nocache(res1->start, res1->end - res1->start + 1);
++      if (!mem1) {
++              v4l2_err(vpfe_dev->driver, "Unable to ioremap ccdc address\n");
++              goto probe_out_release_mem1;
++      }
++
++      ccdc_hw_dev.set_ccdc_base(mem1, res1->end - res1->start + 1);
++
++      if (!request_mem_region(res2->start, res2->end - res2->start + 1,
++                              vpfe_dev->driver->name)) {
++              err = -ENXIO;
++              v4l2_err(vpfe_dev->driver,
++                      "Failed request_mem_region for"
++                                " vpss base\n");
++              goto probe_out_unmap1;
++      }
++
++      mem2 = ioremap_nocache(res2->start, res2->end - res2->start + 1);
++      if (!mem2) {
++              v4l2_err(vpfe_dev->driver, "Unable to ioremap vpss address\n");
++              goto probe_out_release_mem2;
++      }
++
++      ccdc_hw_dev.set_vpss_base(mem2, res2->end - res2->start + 1);
++
++      err = request_irq(channel->ccdc_irq0, vpfe_isr, IRQF_DISABLED,
++                        "vpfe_capture0", (void *)&vpfe_obj);
++
++      if (0 != err) {
++              v4l2_err(vpfe_dev->driver,
++                      "Unable to request interrupt\n");
++              goto probe_out_unmap2;
++      }
++
++      /* Initialize field of the channel objects */
++      channel->usrs = common->io_usrs = 0;
++      common->started = channel->initialized = 0;
++      channel->channel_id = 0;
++      common->numbuffers = config_params.numbuffers[channel->channel_id];
++      channel->numdecoders = 0;
++      channel->current_decoder = 0;
++      for (index = 0; index < VPFE_CAPTURE_NUM_DECODERS; index++)
++              channel->decoder[index] = NULL;
++
++      /* Initialize prio member of channel object */
++      v4l2_prio_init(&channel->prio);
++
++      /* register video device */
++      v4l2_dbg(1, debug, vpfe_dev->driver,
++              "trying to register vpfe device.\n");
++      v4l2_dbg(1, debug, vpfe_dev->driver,
++              "channel=%x,channel->video_dev=%x\n",
++              (int)channel, (int)&channel->video_dev);
++      channel->common[VPFE_VIDEO_INDEX].fmt.type =
++                  V4L2_BUF_TYPE_VIDEO_CAPTURE;
++      err = video_register_device(channel->video_dev,
++                                  VFL_TYPE_GRABBER, vpfe_nr[0]);
++
++      dev_notice(vpfe_dev, "video device registered\n");
++      if (err) {
++              v4l2_err(vpfe_dev->driver,
++                      "Unable to register video device.\n");
++              goto probe_out_release_irq;
++      }
++
++      vpfe_capture.priv = channel;
++      err = v4l2_int_device_register(&vpfe_capture);
++      if (err) {
++              v4l2_err(vpfe_dev->driver,
++                      "Unable to register int master device.\n");
++              goto probe_out;
++      }
++      dev_notice(vpfe_dev, "v4l2 int master registered\n");
++      mutex_init(&common->lock);
++      return 0;
++
++probe_out:
++      /* Get the pointer to the channel object */
++      channel = vpfe_obj.dev[0];
++      /* Unregister video device */
++      video_unregister_device(channel->video_dev);
++      v4l2_int_device_unregister(&vpfe_capture);
++
++probe_out_release_irq:
++      free_irq(channel->ccdc_irq0, (void *)&vpfe_obj);
++probe_out_unmap2:
++      iounmap(mem2);
++probe_out_unmap1:
++      iounmap(mem1);
++probe_out_release_mem1:
++      release_mem_region(res1->start, res1->end -
++                              res1->start + 1);
++probe_out_release_mem2:
++      release_mem_region(res2->start,
++                              res2->end -
++                              res2->start + 1);
++probe_out_release:
++      video_device_release(channel->video_dev);
++      channel->video_dev = NULL;
++      v4l2_dbg(1, debug, vpfe_dev->driver, "</vpfe_probe>\n");
++      return err;
++}
++
++/*  vpfe_remove : It un-register channels from V4L2 driver
++ */
++static int vpfe_remove(struct platform_device *device)
++{
++      struct channel_obj *channel;
++      struct common_obj *common = NULL;
++      struct resource *res;
++      v4l2_dbg(1, debug, vpfe_dev->driver, "<vpfe_remove>\n");
++
++      /* un-register device */
++      channel = vpfe_obj.dev[0];
++      common = &(channel->common[VPFE_VIDEO_INDEX]);
++      free_irq(channel->ccdc_irq0, (void *)&vpfe_obj);
++      /* Unregister video device */
++      video_unregister_device(channel->video_dev);
++      video_device_release(channel->video_dev);
++      v4l2_int_device_unregister(&vpfe_capture);
++      channel->video_dev = NULL;
++      res = (struct resource *)channel->res1;
++      release_mem_region(res->start, res->end - res->start + 1);
++      res = (struct resource *)channel->res2;
++      release_mem_region(res->start, res->end - res->start + 1);
++      iounmap(ccdc_hw_dev.get_ccdc_base());
++      iounmap(ccdc_hw_dev.get_vpss_base());
++      v4l2_dbg(1, debug, vpfe_dev->driver, "</vpfe_remove>\n");
++      return 0;
++}
++
++static int
++vpfe_suspend(struct platform_device *dev, pm_message_t state)
++{
++      /* add suspend code here later */
++      return 0;
++}
++
++static int
++vpfe_resume(struct platform_device *dev)
++{
++      /* add resume code here later */
++      return 0;
++}
++
++static struct platform_driver vpfe_driver = {
++      .driver = {
++              .name = CAPTURE_DRV_NAME,
++              .owner = THIS_MODULE,
++      },
++      .probe = vpfe_probe,
++      .remove = __devexit_p(vpfe_remove),
++      .suspend = vpfe_suspend,
++      .resume  = vpfe_resume,
++};
++
++static __init int vpfe_init(void)
++{
++      int err = 0;
++
++      /* Default number of buffers should be 3 */
++      if ((ch0_numbuffers > 0) &&
++          (ch0_numbuffers < config_params.min_numbuffers))
++              ch0_numbuffers = config_params.min_numbuffers;
++
++      /* Set buffer size to min buffers size if invalid buffer size is
++       * given
++       */
++      if (ch0_bufsize < config_params.min_bufsize[VPFE_CHANNEL0_VIDEO])
++              ch0_bufsize =
++                  config_params.min_bufsize[VPFE_CHANNEL0_VIDEO];
++
++      config_params.numbuffers[VPFE_CHANNEL0_VIDEO] = ch0_numbuffers;
++
++      if (ch0_numbuffers)
++              config_params.channel_bufsize[VPFE_CHANNEL0_VIDEO]
++                  = ch0_bufsize;
++
++      if (ISNULL(ccdc_hw_dev.enable) ||
++          ISNULL(ccdc_hw_dev.open) ||
++          ISNULL(ccdc_hw_dev.set_hw_if_type) ||
++          ISNULL(ccdc_hw_dev.configure) ||
++          ISNULL(ccdc_hw_dev.set_buftype) ||
++          ISNULL(ccdc_hw_dev.get_buftype) ||
++          ISNULL(ccdc_hw_dev.enum_pix) ||
++          ISNULL(ccdc_hw_dev.set_frame_format) ||
++          ISNULL(ccdc_hw_dev.get_frame_format) ||
++          ISNULL(ccdc_hw_dev.get_pixelformat) ||
++          ISNULL(ccdc_hw_dev.set_pixelformat) ||
++          ISNULL(ccdc_hw_dev.setparams) ||
++          ISNULL(ccdc_hw_dev.set_image_window) ||
++          ISNULL(ccdc_hw_dev.get_image_window) ||
++          ISNULL(ccdc_hw_dev.get_line_length) ||
++          ISNULL(ccdc_hw_dev.setfbaddr) ||
++          ISNULL(ccdc_hw_dev.getfid)) {
++              printk(KERN_ERR "vpfe_init:CCDC module interface"
++                              "has missing mandatory functions\n");
++              return -ENODEV;
++      }
++
++      /* Allocate memory for channel objects */
++      vpfe_obj.dev[0] = kmalloc(sizeof(struct channel_obj), GFP_KERNEL);
++      /* If memory allocation fails, return error */
++      if (!vpfe_obj.dev[0]) {
++              err = -ENOMEM;
++              printk(KERN_ERR "vpfe_init:Memory allocation failed\n");
++              goto vpfe_init_free_channel_object;
++      }
++
++      /* Register driver to the kernel */
++      err = platform_driver_register(&vpfe_driver);
++      if (0 != err)
++              goto vpfe_init_free_channel_object;
++
++      printk(KERN_NOTICE "vpfe_capture: init successful\n");
++      return err;
++
++vpfe_init_free_channel_object:
++      kfree(vpfe_obj.dev[0]);
++      vpfe_obj.dev[0] = NULL;
++      return err;
++}
++
++/* vpfe_cleanup : This function un-registers device and driver
++ * to the kernel, frees requested irq handler and de-allocates memory
++ * allocated for channel objects.
++ */
++static void vpfe_cleanup(void)
++{
++      platform_driver_unregister(&vpfe_driver);
++      kfree(vpfe_obj.dev[0]);
++      vpfe_obj.dev[0] = NULL;
++}
++module_init(vpfe_init);
++module_exit(vpfe_cleanup);
++MODULE_AUTHOR("Texas Instruments.");
++MODULE_DESCRIPTION("VPFE Video for Linux Capture Driver");
++MODULE_LICENSE("GPL");
+diff --git a/drivers/media/video/davinci_vpfe.c b/drivers/media/video/davinci_vpfe.c
+deleted file mode 100644
+index 1128eb5..0000000
+--- a/drivers/media/video/davinci_vpfe.c
++++ /dev/null
+@@ -1,1136 +0,0 @@
+-/*
+- *
+- *
+- * Copyright (C) 2006 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
+- */
+-/* davinci_vpfe.c */
+-
+-#include <linux/init.h>
+-#include <linux/module.h>
+-#include <linux/delay.h>
+-#include <linux/errno.h>
+-#include <linux/fs.h>
+-#include <linux/kernel.h>
+-#include <linux/sched.h>
+-#include <linux/interrupt.h>
+-#include <linux/kdev_t.h>
+-#include <linux/string.h>
+-#include <linux/videodev.h>
+-#include <linux/wait.h>
+-#include <linux/dma-mapping.h>
+-#include <linux/platform_device.h>
+-
+-#include <asm/irq.h>
+-#include <asm/page.h>
+-#include <asm/io.h>
+-#include <asm/dma-mapping.h>
+-
+-#include <media/davinci_vpfe.h>
+-
+-#define debug_print(x...)     //printk(x)
+-
+-MODULE_LICENSE("GPL");
+-
+-static struct v4l2_rect ntsc_bounds = VPFE_WIN_NTSC;
+-static struct v4l2_rect pal_bounds = VPFE_WIN_PAL;
+-static struct v4l2_fract ntsc_aspect = VPFE_PIXELASPECT_NTSC;
+-static struct v4l2_fract pal_aspect = VPFE_PIXELASPECT_PAL;
+-static struct v4l2_rect ntscsp_bounds = VPFE_WIN_NTSC_SP;
+-static struct v4l2_rect palsp_bounds = VPFE_WIN_PAL_SP;
+-static struct v4l2_fract sp_aspect = VPFE_PIXELASPECT_NTSC_SP;
+-
+-static vpfe_obj vpfe_device = {       /* the default format is NTSC */
+-      .usrs = 0,
+-      .io_usrs = 0,
+-      .std = VPFE_STD_AUTO,
+-      .vwin = VPFE_WIN_PAL,
+-      .bounds = VPFE_WIN_PAL,
+-      .pixelaspect = VPFE_PIXELASPECT_NTSC,
+-      .pixelfmt = V4L2_PIX_FMT_UYVY,
+-      .field = V4L2_FIELD_INTERLACED,
+-      .numbuffers = VPFE_DEFNUM_FBUFS,
+-      .ccdc_params = {
+-              .pix_fmt = CCDC_PIXFMT_YCBCR_8BIT,
+-              .frm_fmt = CCDC_FRMFMT_INTERLACED,
+-              .win = VPFE_WIN_PAL,
+-              .fid_pol = CCDC_PINPOL_POSITIVE,
+-              .vd_pol = CCDC_PINPOL_POSITIVE,
+-              .hd_pol = CCDC_PINPOL_POSITIVE,
+-              .bt656_enable = TRUE,
+-              .pix_order = CCDC_PIXORDER_CBYCRY,
+-              .buf_type = CCDC_BUFTYPE_FLD_INTERLEAVED
+-      },
+-      .tvp5146_params = {
+-              .mode = TVP5146_MODE_AUTO,
+-              .amuxmode = TVP5146_AMUX_COMPOSITE,
+-              .enablebt656sync = TRUE
+-      },
+-        .irqlock = SPIN_LOCK_UNLOCKED
+-};
+-
+-struct v4l2_capability vpfe_drvcap = {
+-      .driver = "vpfe driver",
+-      .card = "DaVinci EVM",
+-      .bus_info = "Platform",
+-      .version = VPFE_VERSION_CODE,
+-      .capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING
+-};
+-
+-static int sense_std(v4l2_std_id* std_id)
+-{
+-      v4l2_std_id id = 0;
+-      tvp5146_mode mode;
+-      int ret;
+-      ret = tvp5146_ctrl(TVP5146_GET_STD, &mode);
+-      if(ret < 0)
+-              return ret;
+-      switch (mode & 0x7) {
+-      case TVP5146_MODE_NTSC:
+-              id = V4L2_STD_NTSC;
+-              break;
+-      case TVP5146_MODE_PAL:
+-              id = V4L2_STD_PAL;
+-              break;
+-      case TVP5146_MODE_PAL_M:
+-              id = V4L2_STD_PAL_M;
+-              break;
+-      case TVP5146_MODE_PAL_CN:
+-              id = V4L2_STD_PAL_N;
+-              break;
+-      case TVP5146_MODE_SECAM:
+-              id = V4L2_STD_SECAM;
+-              break;
+-      case TVP5146_MODE_PAL_60:
+-              id = V4L2_STD_PAL_60;
+-              break;
+-      }
+-      if (mode & 0x8) {       /* square pixel mode */
+-              id <<= 32;
+-      }
+-      if (mode == TVP5146_MODE_AUTO) {
+-              id = VPFE_STD_AUTO;     /* auto-detection for all other modes */
+-      } else if (mode == TVP5146_MODE_AUTO_SQP) {
+-              id = VPFE_STD_AUTO_SQP;
+-      }
+-      if(id == 0)
+-              return -EINVAL;
+-      *std_id =  id;
+-      return 0;
+-}
+-
+-static irqreturn_t vpfe_isr(int irq, void *dev_id)
+-{
+-      vpfe_obj *vpfe = &vpfe_device;
+-      int fid;
+-
+-      /* check which field we are in hardware */
+-      fid = ccdc_getfid();
+-      vpfe->field_id ^= 1;    /* switch the software maintained field id */
+-      debug_print(KERN_INFO "field id = %x:%x.\n", fid, vpfe->field_id);
+-      if (fid == vpfe->field_id) {    /* we are in-sync here, continue */
+-              if (fid == 0) {
+-                      /*  One frame is just being captured. If the next frame
+-                      is available, release the current frame and move on */
+-                      if (vpfe->curFrm != vpfe->nextFrm) {
+-                              vpfe->curFrm->state = STATE_DONE;
+-                              wake_up_interruptible(&vpfe->curFrm->done);
+-                              vpfe->curFrm = vpfe->nextFrm;
+-                      }
+-                      /* based on whether the two fields are stored interleavely      */
+-                      /* or separately in memory, reconfigure the CCDC memory address */
+-                      if (vpfe->field == V4L2_FIELD_SEQ_TB) {
+-                              u32 addr =
+-                                  vpfe->curFrm->boff + vpfe->field_offset;
+-                              ccdc_setfbaddr((unsigned long)addr);
+-                      }
+-      } else if (fid == 1) {
+-                      /* if one field is just being captured */
+-                      /* configure the next frame */
+-                      /* get the next frame from the empty queue */
+-                      /* if no frame is available, hold on to the current buffer */
+-                      if (!list_empty(&vpfe->dma_queue)
+-                          && vpfe->curFrm == vpfe->nextFrm) {
+-                              vpfe->nextFrm = list_entry(vpfe->dma_queue.next,
+-                                      struct videobuf_buffer, queue);
+-                              list_del(&vpfe->nextFrm->queue);
+-                              vpfe->nextFrm->state = STATE_ACTIVE;
+-                              ccdc_setfbaddr(
+-                                      (unsigned long)vpfe->nextFrm->boff);
+-                      }
+-                      if (vpfe->mode_changed) {
+-                              ccdc_setwin(&vpfe->ccdc_params);
+-                              /* update the field offset */
+-                              vpfe->field_offset =
+-                                  (vpfe->vwin.height - 2) * vpfe->vwin.width;
+-                              vpfe->mode_changed = FALSE;
+-                      }
+-              }
+-      } else if (fid == 0) {
+-              /* recover from any hardware out-of-sync due to */
+-              /* possible switch of video source              */
+-              /* for fid == 0, sync up the two fids           */
+-              /* for fid == 1, no action, one bad frame will  */
+-              /* go out, but it is not a big deal             */
+-              vpfe->field_id = fid;
+-      }
+-      debug_print(KERN_INFO "interrupt returned.\n");
+-      return IRQ_RETVAL(1);
+-}
+-
+-/* this is the callback function called from videobuf_qbuf() function */
+-/* the buffer is prepared and queued into the dma queue */
+-static int buffer_prepare(struct videobuf_queue *q,
+-                        struct videobuf_buffer *vb,
+-                        enum v4l2_field field)
+-{
+-      vpfe_obj *vpfe = &vpfe_device;
+-
+-
+-      if (vb->state == STATE_NEEDS_INIT) {
+-              vb->width  = vpfe->vwin.width;
+-              vb->height = vpfe->vwin.height;
+-              vb->size   = VPFE_MAX_FBUF_SIZE;
+-              vb->field  = field;
+-      }
+-      vb->state = STATE_PREPARED;
+-
+-      return 0;
+-
+-}
+-static void
+-buffer_config(struct videobuf_queue *q, unsigned int count)
+-{
+-      vpfe_obj *vpfe = &vpfe_device;
+-      int i;
+-      for(i = 0; i < count; i++) {
+-              q->bufs[i]->boff = virt_to_phys(vpfe->fbuffers[i]);
+-              debug_print(KERN_INFO "buffer address: %x\n", q->bufs[i]->boff);
+-      }
+-}
+-
+-static int
+-buffer_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size)
+-{
+-      vpfe_obj *vpfe = &vpfe_device;
+-      int i;
+-      *size = VPFE_MAX_FBUF_SIZE;
+-
+-
+-      for (i = VPFE_DEFNUM_FBUFS; i < *count; i++) {
+-              u32 size = PAGE_SIZE << VPFE_MAX_FBUF_ORDER;
+-              void *mem = (void *)__get_free_pages(GFP_KERNEL |GFP_DMA,
+-                                                   VPFE_MAX_FBUF_ORDER);
+-              if (mem) {
+-                      unsigned long adr = (unsigned long)mem;
+-                      while (size > 0) {
+-                              /* make sure the frame buffers are never
+-                                 swapped out of memory */
+-                              SetPageReserved(virt_to_page(adr));
+-                              adr += PAGE_SIZE;
+-                              size -= PAGE_SIZE;
+-                      }
+-                      vpfe->fbuffers[i] = mem;
+-              } else {
+-                      break;
+-              }
+-      }
+-      *count = vpfe->numbuffers = i;
+-
+-      return 0;
+-}
+-
+-static void buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
+-{
+-      vpfe_obj *vpfe = &vpfe_device;
+-        /* add the buffer to the DMA queue */
+-      list_add_tail(&vb->queue, &vpfe->dma_queue);
+-      vb->state = STATE_QUEUED;
+-}
+-
+-static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
+-{
+-      /* free the buffer if it is not one of the 3 allocated at initializaiton time */
+-      if(vb->i < vpfe_device.numbuffers
+-       && vb->i >= VPFE_DEFNUM_FBUFS
+-       && vpfe_device.fbuffers[vb->i]){
+-              free_pages((unsigned long)vpfe_device.fbuffers[vb->i],
+-                         VPFE_MAX_FBUF_ORDER);
+-              vpfe_device.fbuffers[vb->i] = NULL;
+-      }
+-}
+-
+-
+-static struct videobuf_queue_ops video_qops = {
+-      .buf_setup    = buffer_setup,
+-      .buf_prepare  = buffer_prepare,
+-      .buf_queue    = buffer_queue,
+-      .buf_release  = buffer_release,
+-      .buf_config   = buffer_config,
+-};
+-
+-
+-
+-
+-static int vpfe_doioctl(struct inode *inode, struct file *file,
+-                      unsigned int cmd, void *arg)
+-{
+-      vpfe_obj *vpfe = &vpfe_device;
+-      vpfe_fh *fh = file->private_data;
+-      int ret = 0;
+-      switch (cmd) {
+-      case VIDIOC_S_CTRL:
+-      case VIDIOC_S_FMT:
+-      case VIDIOC_S_STD:
+-      case VIDIOC_S_CROP:
+-              ret = v4l2_prio_check(&vpfe->prio, &fh->prio);
+-              if (0 != ret) {
+-                      return ret;
+-              }
+-              break;
+-      }
+-
+-      switch (cmd) {
+-      case VIDIOC_QUERYCAP:
+-      {
+-              struct v4l2_capability *cap =
+-                  (struct v4l2_capability *)arg;
+-              memset(cap, 0, sizeof(*cap));
+-              *cap = vpfe_drvcap;
+-              break;
+-      }
+-      case VIDIOC_ENUM_FMT:
+-      {
+-              struct v4l2_fmtdesc *fmt = (struct v4l2_fmtdesc *)arg;
+-              u32 index = fmt->index;
+-              memset(fmt, 0, sizeof(*fmt));
+-              fmt->index = index;
+-              if (index == 0) {
+-                      /* only yuv4:2:2 format is supported at this point */
+-                      fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+-                      strcpy(fmt->description,
+-                             "YCbCr4:2:2 Interleaved UYUV");
+-                      fmt->pixelformat = V4L2_PIX_FMT_UYVY;
+-              } else if (index == 1) {
+-                      fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+-                      strcpy(fmt->description,
+-                             "YCbCr4:2:2 Interleaved YUYV");
+-                      fmt->pixelformat = V4L2_PIX_FMT_YUYV;
+-              } else {
+-                      ret = -EINVAL;
+-              }
+-              break;
+-      }
+-      case VIDIOC_G_FMT:
+-      {
+-              struct v4l2_format *fmt = (struct v4l2_format *)arg;
+-              if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+-                      ret = -EINVAL;
+-              } else {
+-                      struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
+-                      down_interruptible(&vpfe->lock);
+-                      pixfmt->width = vpfe->vwin.width;
+-                      pixfmt->height = vpfe->vwin.height;
+-                      pixfmt->field = vpfe->field;
+-                      pixfmt->pixelformat = vpfe->pixelfmt;
+-                      pixfmt->bytesperline = pixfmt->width * 2;
+-                      pixfmt->sizeimage =
+-                          pixfmt->bytesperline * pixfmt->height;
+-                      pixfmt->colorspace = V4L2_COLORSPACE_SMPTE170M;
+-                      up(&vpfe->lock);
+-              }
+-              break;
+-      }
+-      case VIDIOC_S_FMT:
+-      {
+-              struct v4l2_format *fmt = (struct v4l2_format *)arg;
+-              struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
+-              ccdc_params_ycbcr *params = &vpfe->ccdc_params;
+-              if (vpfe->started) {    /* make sure streaming is not started */
+-                      ret = -EBUSY;
+-                      break;
+-              }
+-
+-              down_interruptible(&vpfe->lock);
+-              if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+-                      ret = -EINVAL;
+-                      up(&vpfe->lock);
+-                      break;
+-              }
+-              if ((pixfmt->width + vpfe->vwin.left <=
+-                   vpfe->bounds.width)
+-                  & (pixfmt->height + vpfe->vwin.top <=
+-                     vpfe->bounds.height)) {
+-                      /* this is the case when no scaling is supported */
+-                      /* crop window is directed modified */
+-                      vpfe->vwin.height = pixfmt->height;
+-                      vpfe->vwin.width = pixfmt->width;
+-                      params->win.width = pixfmt->width;
+-                      params->win.height = pixfmt->height;
+-              } else {
+-                      ret = -EINVAL;
+-                      up(&vpfe->lock);
+-                      break;
+-              }
+-              /* setup the CCDC parameters accordingly */
+-              if (pixfmt->pixelformat == V4L2_PIX_FMT_YUYV) {
+-                      params->pix_order = CCDC_PIXORDER_YCBYCR;
+-                      vpfe->pixelfmt = pixfmt->pixelformat;
+-              } else if (pixfmt->pixelformat == V4L2_PIX_FMT_UYVY) {
+-                      params->pix_order = CCDC_PIXORDER_CBYCRY;
+-                      vpfe->pixelfmt = pixfmt->pixelformat;
+-              } else {
+-                      ret = -EINVAL;  /* not supported format */
+-                      up(&vpfe->lock);
+-                      break;
+-              }
+-              if (pixfmt->field == V4L2_FIELD_NONE
+-                  || pixfmt->field == V4L2_FIELD_INTERLACED) {
+-                      params->buf_type = CCDC_BUFTYPE_FLD_INTERLEAVED;
+-                      vpfe->field = pixfmt->field;
+-              } else if (pixfmt->field == V4L2_FIELD_SEQ_TB) {
+-                      params->buf_type = CCDC_BUFTYPE_FLD_SEPARATED;
+-                      vpfe->field = pixfmt->field;
+-              } else {
+-                      ret = -EINVAL;
+-              }
+-              up(&vpfe->lock);
+-              break;
+-      }
+-      case VIDIOC_TRY_FMT:
+-      {
+-              struct v4l2_format *fmt = (struct v4l2_format *)arg;
+-              if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+-                      ret = -EINVAL;
+-              } else {
+-                      struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
+-                      if (pixfmt->width > vpfe->bounds.width
+-                          || pixfmt->height > vpfe->bounds.height
+-                          || (pixfmt->pixelformat != V4L2_PIX_FMT_UYVY
+-                              && pixfmt->pixelformat !=
+-                              V4L2_PIX_FMT_YUYV)) {
+-                              ret = -EINVAL;
+-                      }
+-              }
+-              break;
+-      }
+-      case VIDIOC_G_STD:
+-      {
+-              v4l2_std_id *id = (v4l2_std_id *) arg;
+-              *id = vpfe->std;
+-              break;
+-      }
+-      case VIDIOC_S_STD:
+-      {
+-              v4l2_std_id id = *(v4l2_std_id *) arg;
+-              tvp5146_mode mode = TVP5146_MODE_INV;
+-              int sqp = 0;
+-
+-              if (vpfe->started) {    /* make sure streaming is not started */
+-                      ret = -EBUSY;
+-                      break;
+-              }
+-              down_interruptible(&vpfe->lock);
+-              if (id & V4L2_STD_625_50) {
+-                      vpfe->std = id;
+-                      vpfe->bounds = vpfe->vwin = pal_bounds;
+-                      vpfe->pixelaspect = pal_aspect;
+-                      vpfe->ccdc_params.win = pal_bounds;
+-
+-              } else if (id & V4L2_STD_525_60) {
+-                      vpfe->std = id;
+-                      vpfe->bounds = vpfe->vwin = ntsc_bounds;
+-                      vpfe->pixelaspect = ntsc_aspect;
+-                      vpfe->ccdc_params.win = ntsc_bounds;
+-              } else if (id & VPFE_STD_625_50_SQP) {
+-                      vpfe->std = id;
+-                      vpfe->bounds = vpfe->vwin = palsp_bounds;
+-                      vpfe->pixelaspect = sp_aspect;
+-                      sqp = 1;
+-                      id >>= 32;
+-              } else if (id & VPFE_STD_525_60_SQP) {
+-                      vpfe->std = id;
+-                      sqp = 1;
+-                      vpfe->std = id;
+-                      id >>= 32;
+-                      vpfe->bounds = vpfe->vwin = ntscsp_bounds;
+-                      vpfe->pixelaspect = sp_aspect;
+-                      vpfe->ccdc_params.win = ntscsp_bounds;
+-              } else if (id & VPFE_STD_AUTO) {
+-                      mode = TVP5146_MODE_AUTO;
+-                      vpfe->bounds = vpfe->vwin = pal_bounds;
+-                      vpfe->pixelaspect = pal_aspect;
+-                      vpfe->ccdc_params.win = pal_bounds;
+-                      vpfe->std = id;
+-              } else if (id & VPFE_STD_AUTO_SQP) {
+-                      vpfe->std = id;
+-                      vpfe->bounds = vpfe->vwin = palsp_bounds;
+-                      vpfe->pixelaspect = sp_aspect;
+-                      sqp = 1;
+-                      mode = TVP5146_MODE_AUTO_SQP;
+-                      vpfe->pixelaspect = sp_aspect;
+-              } else {
+-                      ret = -EINVAL;
+-              }
+-              if (id == V4L2_STD_PAL_60) {
+-                      mode = TVP5146_MODE_PAL_60;
+-              } else if (id == V4L2_STD_PAL_M) {
+-                      mode = TVP5146_MODE_PAL_M;
+-              } else if (id == V4L2_STD_PAL_Nc
+-                         || id == V4L2_STD_PAL_N) {
+-                      mode = TVP5146_MODE_PAL_CN;
+-              } else if (id & V4L2_STD_PAL) {
+-                      mode = TVP5146_MODE_PAL;
+-              } else if (id & V4L2_STD_NTSC) {
+-                      mode = TVP5146_MODE_NTSC;
+-              } else if (id & V4L2_STD_SECAM) {
+-                      mode = TVP5146_MODE_SECAM;
+-              }
+-              vpfe->tvp5146_params.mode = mode | (sqp << 3);
+-              tvp5146_ctrl(TVP5146_CONFIG, &vpfe->tvp5146_params);
+-
+-              up(&vpfe->lock);
+-              break;
+-      }
+-      case VIDIOC_ENUMSTD:
+-      {
+-              struct v4l2_standard *std = (struct v4l2_standard *)arg;
+-              u32 index = std->index;
+-              memset(std, 0, sizeof(*std));
+-              std->index = index;
+-              if (index == 0) {
+-                      std->id = V4L2_STD_525_60;
+-                      strcpy(std->name, "SD-525line-30fps");
+-                      std->framelines = 525;
+-                      std->frameperiod.numerator = 1001;
+-                      std->frameperiod.denominator = 30000;
+-              } else if (index == 1) {
+-                      std->id = V4L2_STD_625_50;
+-                      strcpy(std->name, "SD-625line-25fps");
+-                      std->framelines = 625;
+-                      std->frameperiod.numerator = 1;
+-                      std->frameperiod.denominator = 25;
+-              } else if (index == 2) {
+-                      std->id = VPFE_STD_625_50_SQP;
+-                      strcpy(std->name,
+-                             "SD-625line-25fps square pixel");
+-                      std->framelines = 625;
+-                      std->frameperiod.numerator = 1;
+-                      std->frameperiod.denominator = 25;
+-              } else if (index == 3) {
+-                      std->id = VPFE_STD_525_60_SQP;
+-                      strcpy(std->name,
+-                             "SD-525line-25fps square pixel");
+-                      std->framelines = 525;
+-                      std->frameperiod.numerator = 1001;
+-                      std->frameperiod.denominator = 30000;
+-              } else if (index == 4) {
+-                      std->id = VPFE_STD_AUTO;
+-                      strcpy(std->name, "automatic detect");
+-                      std->framelines = 625;
+-                      std->frameperiod.numerator = 1;
+-                      std->frameperiod.denominator = 1;
+-              } else if (index == 5) {
+-                      std->id = VPFE_STD_AUTO_SQP;
+-                      strcpy(std->name,
+-                             "automatic detect square pixel");
+-                      std->framelines = 625;
+-                      std->frameperiod.numerator = 1;
+-                      std->frameperiod.denominator = 1;
+-              } else {
+-                      ret = -EINVAL;
+-              }
+-              break;
+-      }
+-      case VIDIOC_ENUMINPUT:
+-      {
+-              u32 index=0;
+-              struct v4l2_input *input = (struct v4l2_input *)arg;
+-              if (input->index > 1)   /* only two inputs are available */
+-                      ret = -EINVAL;
+-              index = input->index;
+-              memset(input, 0, sizeof(*input));
+-                input->index = index;
+-              input->type = V4L2_INPUT_TYPE_CAMERA;
+-              input->std = V4L2_STD_ALL;
+-              if(input->index == 0){
+-                      sprintf(input->name, "COMPOSITE");
+-              }else if(input->index == 1) {
+-                      sprintf(input->name, "S-VIDEO");
+-              }
+-              break;
+-      }
+-      case VIDIOC_G_INPUT:
+-      {
+-              int *index = (int *)arg;
+-              *index = vpfe->tvp5146_params.amuxmode;
+-              break;
+-      }
+-      case VIDIOC_S_INPUT:
+-      {
+-              int *index = (int *)arg;
+-              if (*index > 1 || *index < 0) {
+-                      ret = -EINVAL;
+-              }
+-              vpfe->tvp5146_params.amuxmode = *index;
+-              tvp5146_ctrl(TVP5146_SET_AMUXMODE, index);
+-              break;
+-      }
+-      case VIDIOC_CROPCAP:
+-      {
+-              struct v4l2_cropcap *cropcap =
+-                  (struct v4l2_cropcap *)arg;
+-              cropcap->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+-              down_interruptible(&vpfe->lock);
+-              cropcap->bounds = cropcap->defrect = vpfe->vwin;
+-              cropcap->pixelaspect = vpfe->pixelaspect;
+-              up(&vpfe->lock);
+-              break;
+-      }
+-      case VIDIOC_G_PARM:
+-      {
+-              struct v4l2_streamparm *parm =
+-                  (struct v4l2_streamparm *)arg;
+-              if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+-                      /* only capture is supported */
+-                      ret = -EINVAL;
+-              } else {
+-                      struct v4l2_captureparm *capparm =
+-                          &parm->parm.capture;
+-                      memset(capparm, 0,
+-                             sizeof(struct v4l2_captureparm));
+-                      down_interruptible(&vpfe->lock);
+-                      if (vpfe->std & V4L2_STD_625_50) {
+-                              capparm->timeperframe.numerator = 1;
+-                              capparm->timeperframe.denominator = 25; /* PAL 25fps */
+-                      } else {
+-                              capparm->timeperframe.numerator = 1001;
+-                              capparm->timeperframe.denominator = 30000;      /*NTSC 29.97fps */
+-                      }
+-                      capparm->readbuffers = vpfe->numbuffers;
+-                      up(&vpfe->lock);
+-              }
+-              break;
+-      }
+-      case VIDIOC_G_CTRL:
+-              down_interruptible(&vpfe->lock);
+-              tvp5146_ctrl(VIDIOC_G_CTRL, arg);
+-              up(&vpfe->lock);
+-              break;
+-      case VIDIOC_S_CTRL:
+-              down_interruptible(&vpfe->lock);
+-              tvp5146_ctrl(VIDIOC_S_CTRL, arg);
+-              up(&vpfe->lock);
+-              break;
+-      case VIDIOC_QUERYCTRL:
+-              down_interruptible(&vpfe->lock);
+-              tvp5146_ctrl(VIDIOC_QUERYCTRL, arg);
+-              up(&vpfe->lock);
+-              break;
+-      case VIDIOC_G_CROP:
+-      {
+-              struct v4l2_crop *crop = arg;
+-              if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+-                      ret = -EINVAL;
+-              } else {
+-                      crop->c = vpfe->vwin;
+-              }
+-              break;
+-      }
+-      case VIDIOC_S_CROP:
+-      {
+-              struct v4l2_crop *crop = arg;
+-              ccdc_params_ycbcr *params = &vpfe->ccdc_params;
+-              if (vpfe->started) {    /* make sure streaming is not started */
+-                      ret = -EBUSY;
+-                      break;
+-              }
+-              /*adjust the width to 16 pixel boundry */
+-                crop->c.width = ((crop->c.width + 15 )/16 ) * 16;
+-
+-              /* make sure parameters are valid */
+-              if (crop->type == V4L2_BUF_TYPE_VIDEO_CAPTURE
+-                  && (crop->c.left + crop->c.width
+-                      <= vpfe->bounds.left + vpfe->bounds.width)
+-                  && (crop->c.top + crop->c.height
+-                      <= vpfe->bounds.top + vpfe->bounds.height)) {
+-
+-                      down_interruptible(&vpfe->lock);
+-                      vpfe->vwin = crop->c;
+-                      params->win = vpfe->vwin;
+-                      up(&vpfe->lock);
+-              } else {
+-                      ret = -EINVAL;
+-              }
+-              break;
+-      }
+-      case VIDIOC_QUERYSTD:
+-      {
+-              v4l2_std_id *id = (v4l2_std_id *) arg;
+-              down_interruptible(&vpfe->lock);
+-              ret = sense_std(id);
+-              up(&vpfe->lock);
+-              break;
+-      }
+-      case VIDIOC_G_PRIORITY:
+-      {
+-              enum v4l2_priority *p = arg;
+-              *p = v4l2_prio_max(&vpfe->prio);
+-              break;
+-      }
+-      case VIDIOC_S_PRIORITY:
+-      {
+-              enum v4l2_priority *p = arg;
+-              ret = v4l2_prio_change(&vpfe->prio, &fh->prio, *p);
+-              break;
+-      }
+-
+-      case VIDIOC_REQBUFS:
+-              if (vpfe->io_usrs != 0) {
+-                      ret = -EBUSY;
+-                      break;
+-              }
+-              down_interruptible(&vpfe->lock);
+-              videobuf_queue_init(&vpfe->bufqueue, &video_qops, NULL,
+-              &vpfe->irqlock, V4L2_BUF_TYPE_VIDEO_CAPTURE, vpfe->field,
+-              sizeof(struct videobuf_buffer), fh);
+-
+-              videobuf_set_buftype(&vpfe->bufqueue, VIDEOBUF_BUF_LINEAR);
+-
+-              fh->io_allowed = TRUE;
+-              vpfe->io_usrs = 1;
+-              INIT_LIST_HEAD(&vpfe->dma_queue);
+-              ret = videobuf_reqbufs(&vpfe->bufqueue, arg);
+-              up(&vpfe->lock);
+-              break;
+-      case VIDIOC_QUERYBUF:
+-              ret = videobuf_querybuf(&vpfe->bufqueue, arg);
+-              break;
+-      case VIDIOC_QBUF:
+-              if (!fh->io_allowed)
+-                      ret = -EACCES;
+-              else
+-                      ret = videobuf_qbuf(&vpfe->bufqueue, arg);
+-              break;
+-      case VIDIOC_DQBUF:
+-              if (!fh->io_allowed)
+-                      ret = -EACCES;
+-              else
+-                      ret =  videobuf_dqbuf(&vpfe->bufqueue, arg, 0);
+-              break;
+-      case VIDIOC_STREAMON:
+-              if (!fh->io_allowed) {
+-                      ret = -EACCES;
+-                      break;
+-              }
+-              if(vpfe->started){
+-                      ret = -EBUSY;
+-                      break;
+-              }
+-              ret = videobuf_streamon(&vpfe->bufqueue);
+-              if(ret) break;
+-
+-              down_interruptible(&vpfe->lock);
+-              /* get the current and next frame buffers */
+-              /* we expect at least one buffer is in driver at this point */
+-              /* if not, error is returned */
+-              if (list_empty(&vpfe->dma_queue)) {
+-                      ret = -EIO;
+-                      break;
+-              }
+-              debug_print(KERN_INFO "cur frame %x.\n",
+-                          vpfe->dma_queue.next);
+-              vpfe->nextFrm = vpfe->curFrm =
+-                  list_entry(vpfe->dma_queue.next,
+-                             struct videobuf_buffer, queue);
+-              /* remove the buffer from the queue */
+-              list_del(&vpfe->curFrm->queue);
+-              vpfe->curFrm->state = STATE_ACTIVE;
+-
+-              /* sense the current video input standard */
+-              tvp5146_ctrl(TVP5146_CONFIG, &vpfe->tvp5146_params);
+-              /* configure the ccdc and resizer as needed   */
+-              /* start capture by enabling CCDC and resizer */
+-              ccdc_config_ycbcr(&vpfe->ccdc_params);
+-              /* setup the memory address for the frame buffer */
+-              ccdc_setfbaddr(((unsigned long)(vpfe->curFrm->boff)));
+-              /* enable CCDC */
+-              vpfe->field_id = 0;
+-              vpfe->started = TRUE;
+-              vpfe->mode_changed = FALSE;
+-              vpfe->field_offset =
+-                  (vpfe->vwin.height - 2) * vpfe->vwin.width;
+-              ccdc_enable(TRUE);
+-              up(&vpfe->lock);
+-              debug_print(KERN_INFO "started video streaming.\n");
+-              break;
+-      case VIDIOC_STREAMOFF:
+-      {
+-              if (!fh->io_allowed) {
+-                      ret = -EACCES;
+-                      break;
+-              }
+-              if(!vpfe->started){
+-                      ret = -EINVAL;
+-                      break;
+-              }
+-              /* disable CCDC */
+-              down_interruptible(&vpfe->lock);
+-              ccdc_enable(FALSE);
+-              vpfe->started = FALSE;
+-              up(&vpfe->lock);
+-              ret = videobuf_streamoff(&vpfe->bufqueue);
+-              break;
+-      }
+-      case VPFE_CMD_CONFIG_CCDC:
+-      {
+-              /* this can be used directly and bypass the V4L2 APIs */
+-              ccdc_params_ycbcr *params = &vpfe->ccdc_params;
+-              if(vpfe->started){
+-              /* only allowed if streaming is not started */
+-                      ret = -EBUSY;
+-                      break;
+-              }
+-              down_interruptible(&vpfe->lock);
+-              /* make sure the other v4l2 related fields
+-                 have consistant settings */
+-              *params = (*(ccdc_params_ycbcr *) arg);
+-              vpfe->vwin = params->win;
+-              if (params->buf_type == CCDC_BUFTYPE_FLD_INTERLEAVED) {
+-                      vpfe->field = V4L2_FIELD_INTERLACED;
+-              } else if (params->buf_type ==
+-                 CCDC_BUFTYPE_FLD_SEPARATED) {
+-                      vpfe->field = V4L2_FIELD_SEQ_TB;
+-              }
+-              if (params->pix_order == CCDC_PIXORDER_YCBYCR) {
+-                      vpfe->pixelfmt = V4L2_PIX_FMT_YUYV;
+-              } else if (params->pix_order == CCDC_PIXORDER_CBYCRY) {
+-                      vpfe->pixelfmt = V4L2_PIX_FMT_UYVY;
+-              }
+-              up(&vpfe->lock);
+-              break;
+-      }
+-      case VPFE_CMD_CONFIG_TVP5146:
+-      /* this can be used directly and bypass the V4L2 APIs */
+-      {
+-              /* the settings here must be consistant with that of the CCDC's,
+-                 driver does not check the consistancy */
+-              tvp5146_params *params = (tvp5146_params *) arg;
+-              v4l2_std_id std = 0;
+-              if(vpfe->started){
+-              /* only allowed if streaming is not started */
+-                      ret = -EBUSY;
+-                      break;
+-              }
+-              down_interruptible(&vpfe->lock);
+-              /*make sure the other v4l2 related fields have consistant settings */
+-              switch (params->mode & 0x7) {
+-              case TVP5146_MODE_NTSC:
+-                      std = V4L2_STD_NTSC;
+-                      break;
+-              case TVP5146_MODE_PAL:
+-                      std = V4L2_STD_PAL;
+-                      break;
+-              case TVP5146_MODE_PAL_M:
+-                      std = V4L2_STD_PAL_M;
+-                      break;
+-              case TVP5146_MODE_PAL_CN:
+-                      std = V4L2_STD_PAL_N;
+-                      break;
+-              case TVP5146_MODE_SECAM:
+-                      std = V4L2_STD_SECAM;
+-                      break;
+-              case TVP5146_MODE_PAL_60:
+-                      std = V4L2_STD_PAL_60;
+-                      break;
+-              }
+-
+-              if (params->mode & 0x8) {       /* square pixel mode */
+-                      std <<= 32;
+-              }
+-
+-              if (params->mode == TVP5146_MODE_AUTO) {        /* auto-detection modes */
+-                      std = VPFE_STD_AUTO;
+-              } else if (params->mode == TVP5146_MODE_AUTO_SQP) {
+-                      std = VPFE_STD_AUTO_SQP;
+-              }
+-
+-              if (std & V4L2_STD_625_50) {
+-                      vpfe->bounds = pal_bounds;
+-                      vpfe->pixelaspect = pal_aspect;
+-              } else if (std & V4L2_STD_525_60) {
+-                      vpfe->bounds = ntsc_bounds;
+-                      vpfe->pixelaspect = ntsc_aspect;
+-              } else if (std & VPFE_STD_625_50_SQP) {
+-                      vpfe->bounds = palsp_bounds;
+-                      vpfe->pixelaspect = sp_aspect;
+-              } else if (std & VPFE_STD_525_60_SQP) {
+-                      vpfe->bounds = ntscsp_bounds;
+-                      vpfe->pixelaspect = sp_aspect;
+-              }
+-              vpfe->std = std;
+-              tvp5146_ctrl(TVP5146_CONFIG, params);
+-              vpfe->tvp5146_params = *params;
+-              up(&vpfe->lock);
+-              break;
+-      }
+-      default:
+-              ret = -ENOIOCTLCMD;
+-              break;
+-      }                       /* end switch(cmd) */
+-      return ret;
+-}
+-
+-static int vpfe_ioctl(struct inode *inode, struct file *file,
+-                    unsigned int cmd, unsigned long arg)
+-{
+-      int ret;
+-      ret =  video_usercopy(inode, file, cmd, arg, vpfe_doioctl);
+-      if( cmd == VIDIOC_S_FMT || cmd == VIDIOC_TRY_FMT ){
+-              ret = video_usercopy(inode, file, VIDIOC_G_FMT,
+-                      arg, vpfe_doioctl);
+-      }
+-      return ret;
+-}
+-
+-static int vpfe_mmap(struct file *file, struct vm_area_struct *vma)
+-{
+-      return videobuf_mmap_mapper(&vpfe_device.bufqueue, vma);
+-}
+-
+-static int vpfe_open(struct inode *inode, struct file *filep)
+-{
+-      int minor = iminor(inode);
+-      vpfe_obj *vpfe = NULL;
+-      vpfe_fh *fh = NULL;
+-
+-      debug_print(KERN_INFO "vpfe: open minor=%d\n", minor);
+-
+-      /* check to make sure the minor numbers match */
+-      if (vpfe_device.video_dev && vpfe_device.video_dev->minor == minor) {
+-              vpfe = &vpfe_device;
+-      } else {                /* device not found here */
+-              return -ENODEV;
+-      }
+-
+-      /* allocate per filehandle data */
+-      if ((fh = kmalloc(sizeof(*fh), GFP_KERNEL)) == NULL) {
+-              return -ENOMEM;
+-      }
+-      filep->private_data = fh;
+-      fh->dev = vpfe;
+-      fh->io_allowed = FALSE;
+-      fh->prio = V4L2_PRIORITY_UNSET;
+-      v4l2_prio_open(&vpfe->prio, &fh->prio);
+-      vpfe->usrs++;
+-
+-      return 0;
+-}
+-
+-static int vpfe_release(struct inode *inode, struct file *filep)
+-{
+-      vpfe_fh *fh = filep->private_data;
+-      vpfe_obj *vpfe = fh->dev;
+-
+-      down_interruptible(&vpfe->lock);
+-      if (fh->io_allowed) {
+-              vpfe->io_usrs = 0;
+-              ccdc_enable(FALSE);
+-              vpfe->started = FALSE;
+-              videobuf_queue_cancel(&vpfe->bufqueue);
+-              vpfe->numbuffers = VPFE_DEFNUM_FBUFS;
+-      }
+-      vpfe->usrs--;
+-      v4l2_prio_close(&vpfe->prio, &fh->prio);
+-      filep->private_data = NULL;
+-      kfree(fh);
+-      up(&vpfe->lock);
+-
+-      return 0;
+-}
+-
+-static struct file_operations vpfe_fops = {
+-      .owner = THIS_MODULE,
+-      .open = vpfe_open,
+-      .release = vpfe_release,
+-      .ioctl = vpfe_ioctl,
+-      .mmap = vpfe_mmap
+-};
+-
+-static struct video_device vpfe_video_template = {
+-      .name = "vpfe",
+-      .type = VID_TYPE_CAPTURE | VID_TYPE_CLIPPING | VID_TYPE_SCALES,
+-      .hardware = 0,
+-      .fops = &vpfe_fops,
+-      .minor = -1,
+-};
+-
+-static void vpfe_platform_release(struct device *device)
+-{
+-      /* This is called when the reference count goes to zero. */
+-}
+-
+-static int __init vpfe_probe(struct device *device)
+-{
+-      struct video_device *vfd;
+-      vpfe_obj *vpfe = &vpfe_device;
+-
+-      /* alloc video device */
+-      if ((vfd = video_device_alloc()) == NULL) {
+-              return -ENOMEM;
+-      }
+-      *vfd = vpfe_video_template;
+-      vfd->dev = device;
+-      vfd->release = video_device_release;
+-      snprintf(vfd->name, sizeof(vfd->name), "DM644X_VPFE_DRIVER_V%d.%d.%d",
+-               (VPFE_VERSION_CODE >> 16) & 0xff,
+-               (VPFE_VERSION_CODE >> 8) & 0xff, (VPFE_VERSION_CODE) & 0xff);
+-
+-      vpfe->video_dev = vfd;
+-      vpfe->usrs = 0;
+-      vpfe->io_usrs = 0;
+-      vpfe->started = FALSE;
+-      vpfe->latest_only = TRUE;
+-
+-      v4l2_prio_init(&vpfe->prio);
+-      init_MUTEX(&vpfe->lock);
+-      /* register video device */
+-      debug_print(KERN_INFO "trying to register vpfe device.\n");
+-      debug_print(KERN_INFO "vpfe=%x,vpfe->video_dev=%x\n", (int)vpfe,
+-                  (int)&vpfe->video_dev);
+-      if (video_register_device(vpfe->video_dev, VFL_TYPE_GRABBER, -1) < 0) {
+-              video_device_release(vpfe->video_dev);
+-              vpfe->video_dev = NULL;
+-              return -1;
+-      }
+-
+-      debug_print(KERN_INFO "DM644X vpfe: driver version V%d.%d.%d loaded\n",
+-                  (VPFE_VERSION_CODE >> 16) & 0xff,
+-                  (VPFE_VERSION_CODE >> 8) & 0xff,
+-                  (VPFE_VERSION_CODE) & 0xff);
+-
+-      debug_print(KERN_INFO "vpfe: registered device video%d\n",
+-                  vpfe->video_dev->minor & 0x1f);
+-
+-      /* all done */
+-      return 0;
+-}
+-
+-static int vpfe_remove(struct device *device)
+-{
+-      /* un-register device */
+-      video_unregister_device(vpfe_device.video_dev);
+-
+-      return 0;
+-}
+-
+-#ifdef NEW
+-static struct platform_driver vpfe_driver = {
+-      .driver = {
+-              .name           = "VPFE",
+-              .owner          = THIS_MODULE,
+-      },
+-      .probe                  = vpfe_probe,
+-      .remove                 = vpfe_remove,
+-};
+-
+-#else
+-static struct device_driver vpfe_driver = {
+-      .name = "vpfe",
+-      .bus = &platform_bus_type,
+-      .probe = vpfe_probe,
+-      .remove = vpfe_remove,
+-};
+-#endif
+-
+-static struct platform_device _vpfe_device = {
+-      .name = "vpfe",
+-      .id = 1,
+-      .dev = {
+-              .release = vpfe_platform_release,
+-              }
+-};
+-
+-static int vpfe_init(void)
+-{
+-      int i = 0;
+-      void *mem;
+-      /* allocate memory at initialization time to guarentee availability */
+-      for (i = 0; i < VPFE_DEFNUM_FBUFS; i++) {
+-              mem = (void *)__get_free_pages(GFP_KERNEL | GFP_DMA,
+-                                             VPFE_MAX_FBUF_ORDER);
+-              if (mem) {
+-                      unsigned long adr = (unsigned long)mem;
+-                      u32 size = PAGE_SIZE << VPFE_MAX_FBUF_ORDER;
+-                      while (size > 0) {
+-                              /* make sure the frame buffers
+-                                 are never swapped out of memory */
+-                              SetPageReserved(virt_to_page(adr));
+-                              adr += PAGE_SIZE;
+-                              size -= PAGE_SIZE;
+-                      }
+-                      vpfe_device.fbuffers[i] = (u8 *) mem;
+-                      debug_print(KERN_INFO "memory address %d\t%x\n", i,
+-                                  mem);
+-              } else {
+-                      while (--i >= 0) {
+-                              free_pages((unsigned long)vpfe_device.fbuffers[i],
+-                                         VPFE_MAX_FBUF_ORDER);
+-                      }
+-                      debug_print(KERN_INFO
+-                                  "frame buffer memory allocation failed.\n");
+-                      return -ENOMEM;
+-              }
+-      }
+-      if (driver_register(&vpfe_driver) != 0) {
+-              debug_print(KERN_INFO "driver registration failed\n");
+-              return -1;
+-      }
+-      if (platform_device_register(&_vpfe_device) != 0) {
+-              driver_unregister(&vpfe_driver);
+-              debug_print(KERN_INFO "device registration failed\n");
+-              return -1;
+-      }
+-
+-      ccdc_reset();
+-      tvp5146_ctrl(TVP5146_RESET, NULL);
+-      /* configure the tvp5146 to default parameters */
+-      tvp5146_ctrl(TVP5146_CONFIG, &vpfe_device.tvp5146_params);
+-      /* setup interrupt handling */
+-      request_irq(IRQ_VDINT0, vpfe_isr, SA_INTERRUPT,
+-                  "dm644xv4l2", (void *)&vpfe_device);
+-
+-      printk(KERN_INFO "DaVinci v4l2 capture driver V1.0 loaded\n");
+-      return 0;
+-}
+-
+-static void vpfe_cleanup(void)
+-{
+-      int i = vpfe_device.numbuffers;
+-      platform_device_unregister(&_vpfe_device);
+-      driver_unregister(&vpfe_driver);
+-      /* disable interrupt */
+-      free_irq(IRQ_VDINT0, &vpfe_device);
+-
+-      while (--i >= 0) {
+-              free_pages((unsigned long)vpfe_device.fbuffers[i],
+-                         VPFE_MAX_FBUF_ORDER);
+-      }
+-      debug_print(KERN_INFO "vpfe: un-registered device video.\n");
+-}
+-
+-module_init(vpfe_init);
+-module_exit(vpfe_cleanup);
+diff --git a/include/media/davinci/vpfe_capture.h b/include/media/davinci/vpfe_capture.h
+new file mode 100644
+index 0000000..c2b4e11
+--- /dev/null
++++ b/include/media/davinci/vpfe_capture.h
+@@ -0,0 +1,272 @@
++/*
++ * 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
++ */
++
++#ifndef _VPFE_CAPTURE_H
++#define _VPFE_CAPTURE_H
++
++#ifdef __KERNEL__
++
++/* Header files */
++#include <linux/videodev2.h>
++#include <media/v4l2-ioctl.h>
++#include <media/v4l2-int-device.h>
++#include <media/videobuf-dma-contig.h>
++#include <media/davinci/ccdc_hw_device.h>
++
++#define VPFE_CAPTURE_NUM_DECODERS        5
++
++/* Macros */
++#define VPFE_MAJOR_RELEASE              0
++#define VPFE_MINOR_RELEASE              0
++#define VPFE_BUILD                      1
++#define VPFE_CAPTURE_VERSION_CODE       ((VPFE_MAJOR_RELEASE << 16) | \
++      (VPFE_MINOR_RELEASE << 8)  | \
++      VPFE_BUILD)
++
++#define VPFE_VALID_FIELD(field)  ((V4L2_FIELD_ANY == field) || \
++      (V4L2_FIELD_NONE == field) || \
++      (V4L2_FIELD_INTERLACED == field) || \
++      (V4L2_FIELD_SEQ_TB == field))
++
++#define VPFE_VALID_BUFFER_TYPE(buftype)       { \
++                      (V4L2_BUF_TYPE_VIDEO_CAPTURE == buftype) }
++
++#define VPFE_CAPTURE_MAX_DEVICES      1
++#define VPFE_MAX_DECODER_STD          50
++#define VPFE_TIMER_COUNT              5
++#define VPFE_SLICED_BUF_SIZE          256
++#define VPFE_SLICED_MAX_SERVICES      3
++#define VPFE_HBI_INDEX                        2
++#define VPFE_VBI_INDEX                        1
++#define VPFE_VIDEO_INDEX              0
++
++/* Define for device type to be passed in init */
++#define       MT9T001                         0
++#define       TVP5146                         1
++#define       MT9T031                         2
++#define       MT9P031                         3
++#define TVP7002                               4
++
++#define VPFE_NUMBER_OF_OBJECTS                1
++
++/* Macros */
++#define ISALIGNED(a)    (0 == (a % 32))
++#define ISEXTERNALCMD(cmd)       ((VPFE_CMD_S_DECODER_PARAMS == cmd) || \
++              (VPFE_CMD_G_DECODER_PARAMS == cmd) || \
++              (VPFE_CMD_S_CCDC_PARAMS == cmd) || \
++              (VPFE_CMD_G_CCDC_PARAMS == cmd) || \
++              (VPFE_CMD_CONFIG_CCDC_YCBCR == cmd) || \
++              (VPFE_CMD_CONFIG_CCDC_RAW == cmd) || \
++              (VPFE_CMD_CONFIG_TVP5146 == cmd) || \
++              (VPFE_CMD_S_MT9T001_PARAMS == cmd) || \
++              (VPFE_CMD_G_MT9T001_PARAMS == cmd))
++
++#include <media/v4l2-dev.h>
++#define VPFE_MAX_SECOND_RESOLUTION_SIZE  (640 * 480 * 2)
++#define ROUND32(x)    ((((x)+31) >> 5) << 5)
++#define ISNULL(val) ((val == NULL) ? 1 : 0)
++#define VPFE_MAX_PIX_FORMATS  6
++enum vpfe_irq_use_type {
++      VPFE_USE_CCDC_IRQ,
++      VPFE_USE_IMP_IRQ,
++      VPFE_NO_IRQ
++};
++
++/* enumerated data types */
++/* Enumerated data type to give id to each device per channel */
++enum vpfe_channel_id {
++      /* Channel0 Video */
++      VPFE_CHANNEL0_VIDEO = 0,
++      /* Channel1 Video */
++      VPFE_CHANNEL1_VIDEO,
++};
++
++/* structures */
++/* Table to keep track of the standards supported in all the decoders */
++struct vpfe_decoder_std_tbl {
++      u8 dec_idx;
++      u8 std_idx;
++      v4l2_std_id std;
++};
++
++enum output_src {
++      VPFE_CCDC_OUT = 1,
++      VPFE_IMP_PREV_OUT = 2,
++      VPFE_IMP_RSZ_OUT = 4
++};
++
++struct vpfe_pixel_format {
++      unsigned int pix_fmt;
++      char *desc;
++      enum vpfe_hw_pix_format hw_fmt;
++};
++
++struct vpfe_std_info {
++      int activepixels;
++      int activelines;
++      /* current frame format */
++      int frame_format;
++};
++
++#define VPFE_MAX_DEC_INPUTS   5
++
++/* To map high level input name to decoder input */
++struct vpfe_dec_input {
++      char dec_name[32];
++      struct v4l2_input input;
++      struct v4l2_routing route;
++      int routing_supported;
++};
++
++struct vpfe_capture_input {
++      int num_inputs;
++      struct vpfe_dec_input inputs[VPFE_MAX_DEC_INPUTS];
++      int current_input;
++};
++
++struct video_obj {
++      /* Keeps track of the information about the standard */
++      struct vpfe_std_info std_info;
++      /* index into std table */
++      int index;
++      /* All inputs to the driver */
++      struct vpfe_capture_input *input;
++};
++
++struct common_obj {
++      /* Buffer specific parameters */
++      /* List of buffer pointers for storing frames */
++      u8 *fbuffers[VIDEO_MAX_FRAME];
++      /* number of buffers in fbuffers */
++      u32 numbuffers;
++      /* Pointer pointing to current v4l2_buffer */
++      struct videobuf_buffer *curFrm;
++      /* Pointer pointing to next v4l2_buffer */
++      struct videobuf_buffer *nextFrm;
++      /* This field keeps track of type of buffer exchange mechanism
++       * user has selected
++       */
++      enum v4l2_memory memory;
++      /* Used to store pixel format */
++      struct v4l2_format fmt;
++      /* Buffer queue used in video-buf */
++      struct videobuf_queue buffer_queue;
++      /* Queue of filled frames */
++      struct list_head dma_queue;
++      /* Used in video-buf */
++      spinlock_t irqlock;
++      /* channel specifc parameters */
++      /* lock used to access this structure */
++      struct mutex lock;
++      /* number of users performing IO */
++      u32 io_usrs;
++      /* Indicates whether streaming started */
++      u8 started;
++      /* offset where second field starts from the starting of the
++       * buffer for field seperated YCbCr formats
++       */
++      u32 field_off;
++      /* Indicates width of the image data */
++      u32 width;
++      /* Indicates height of the image data */
++      u32 height;
++      /* used when IMP is chained to store the crop window which
++       * is different from the image window
++       */
++      struct v4l2_rect crop;
++};
++
++struct channel_obj {
++      /* V4l2 specific parameters */
++      /* Identifies video device for this channel */
++      struct video_device *video_dev;
++      /* Used to keep track of state of the priority */
++      struct v4l2_prio_state prio;
++      /* number of open instances of the channel */
++      u32 usrs;
++      /* Indicates id of the field which is being displayed */
++      u32 field_id;
++      /* flag to indicate whether decoder is initialized */
++      u8 initialized;
++      /* Identifies channel */
++      enum vpfe_channel_id channel_id;
++      /* current interface parameters */
++      struct v4l2_ifparm ifparams;
++      /* current interface type */
++      enum vpfe_hw_if_type vpfe_if;
++      /* number of decoders registered with the master */
++      u8 numdecoders;
++      /* decoder slave ptrs */
++      struct v4l2_int_device *decoder[VPFE_CAPTURE_NUM_DECODERS];
++      /* Index of the currently selected decoder */
++      u8 current_decoder;
++      void *res1;
++      void *res2;
++      /* To track if we need to attach IPIPE IRQ or CCDC IRQ */
++      enum vpfe_irq_use_type irq_type;
++      /* CCDC IRQs used when CCDC/ISIF output to SDRAM */
++      unsigned int ccdc_irq0;
++      unsigned int ccdc_irq1;
++      enum output_src out_from;
++      struct common_obj common[VPFE_NUMBER_OF_OBJECTS];
++      struct video_obj video;
++};
++
++/* File handle structure */
++struct vpfe_fh {
++      /* pointer to channel object for opened device */
++      struct channel_obj *channel;
++      /* Indicates whether this file handle is doing IO */
++      u8 io_allowed[VPFE_NUMBER_OF_OBJECTS];
++      /* Used to keep track priority of this instance */
++      enum v4l2_priority prio;
++      /* Used to indicate channel is initialize or not */
++      u8 initialized;
++};
++
++/* vpfe device structure */
++struct vpfe_device {
++      struct channel_obj *dev[CCDC_CAPTURE_NUM_CHANNELS];
++};
++
++struct vpfe_config_params {
++      u8 min_numbuffers;
++      u8 numbuffers[CCDC_CAPTURE_NUM_CHANNELS];
++      u32 min_bufsize[CCDC_CAPTURE_NUM_CHANNELS];
++      u32 channel_bufsize[CCDC_CAPTURE_NUM_CHANNELS];
++};
++
++
++/* SoC Capture hardware interface */
++extern struct ccdc_hw_device ccdc_hw_dev;
++#define CAPTURE_DRV_NAME "vpfe-capture"
++#endif                                /* End of __KERNEL__ */
++
++/* IOCTLs */
++#define VPFE_CMD_LATEST_FRM_ONLY \
++                      _IOW('V', BASE_VIDIOC_PRIVATE + 1, int)
++#define VPFE_CMD_G_DECODER_PARAMS _IOR('V', BASE_VIDIOC_PRIVATE + 2, \
++                                      void *)
++#define VPFE_CMD_S_DECODER_PARAMS _IOW('V', BASE_VIDIOC_PRIVATE + 3, \
++                                      void *)
++#define VPFE_CMD_S_SOC_PARAMS _IOW('V', BASE_VIDIOC_PRIVATE + 4, \
++                                      void *)
++#define VPFE_CMD_G_SOC_PARAMS _IOW('V', BASE_VIDIOC_PRIVATE + 5, \
++                                      void *)
++
++#endif                                /* _DAVINCI_VPFE_H */
+diff --git a/include/media/davinci/vpfe_types.h b/include/media/davinci/vpfe_types.h
+new file mode 100644
+index 0000000..09d0531
+--- /dev/null
++++ b/include/media/davinci/vpfe_types.h
+@@ -0,0 +1,71 @@
++/*
++ * 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
++ */
++#ifndef _VPFE_TYPES_H
++#define _VPFE_TYPES_H
++
++#ifdef __KERNEL__
++
++enum vpfe_hw_if_type {
++      /* BT656 - 8 bit */
++      VPFE_BT656,
++      /* BT1120 - 16 bit */
++      VPFE_BT1120,
++      /* Raw Bayer */
++      VPFE_RAW_BAYER,
++      /* YCbCr - 8 bit with external sync */
++      VPFE_YCBCR_SYNC_8,
++      /* YCbCr - 16 bit with external sync */
++      VPFE_YCBCR_SYNC_16,
++      /* BT656 - 10 bit */
++      VPFE_BT656_10BIT
++};
++
++enum vpfe_sync_pol {
++      VPFE_SYNC_POSITIVE = 0,
++      VPFE_SYNC_NEGATIVE
++};
++
++/* Pixel format to be used across vpfe driver */
++enum vpfe_hw_pix_format {
++      VPFE_BAYER_8BIT_PACK,
++      VPFE_BAYER_8BIT_PACK_ALAW,
++      VPFE_BAYER_8BIT_PACK_DPCM,
++      VPFE_BAYER_12BIT_PACK,
++      /* 16 bit Bayer */
++      VPFE_BAYER,
++      VPFE_UYVY,
++      VPFE_YUYV,
++      VPFE_RGB565,
++      VPFE_RGB888,
++      /* YUV 420 */
++      VPFE_YUV420,
++      /* YUV 420, Y data */
++      VPFE_420_Y,
++      /* YUV 420, C data */
++      VPFE_420_C,
++};
++
++/* interface description */
++struct vpfe_hw_if_param {
++      enum vpfe_hw_if_type if_type;
++      enum vpfe_sync_pol hdpol;
++      enum vpfe_sync_pol vdpol;
++};
++
++#endif
++#endif
+diff --git a/include/media/davinci_vpfe.h b/include/media/davinci_vpfe.h
+deleted file mode 100644
+index 26e7b2c..0000000
+--- a/include/media/davinci_vpfe.h
++++ /dev/null
+@@ -1,121 +0,0 @@
+-/*
+- * Copyright (C) 2006 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
+- */
+-/* davinci_vpfe.h */
+-
+-#ifndef DAVINCI_VPFE_H
+-#define DAVINCI_VPFE_H
+-#ifdef __KERNEL__
+-#include <media/v4l2-dev.h>
+-#endif
+-
+-#include <media/ccdc_davinci.h>
+-#include <media/tvp5146.h>
+-
+-#define TRUE 1
+-#define FALSE 0
+-
+-/* vpfe specific video standards */
+-#define VPFE_STD_625_50_SQP ((V4L2_STD_625_50)<<32)
+-#define VPFE_STD_525_60_SQP ((V4L2_STD_525_60)<<32)
+-#define VPFE_STD_AUTO ((v4l2_std_id)(0x1000000000000000ULL))
+-#define VPFE_STD_AUTO_SQP ((v4l2_std_id)(0x2000000000000000ULL))
+-
+-#define VPFE_CMD_CONFIG_CCDC _IOW('V',BASE_VIDIOC_PRIVATE + 1,ccdc_params_ycbcr)
+-#define VPFE_CMD_LATEST_FRM_ONLY   _IOW('V',BASE_VIDIOC_PRIVATE + 2,int)
+-#define VPFE_CMD_CONFIG_TVP5146 _IOW('V',BASE_VIDIOC_PRIVATE + 3,tvp5146_params)
+-
+-/* settings for commonly used video formats */
+-#define VPFE_WIN_NTSC    {0,0,720,480}
+-#define VPFE_WIN_PAL     {0,0,720,576}
+-#define VPFE_WIN_NTSC_SP {0,0,640,480}        /* ntsc square pixel */
+-#define VPFE_WIN_PAL_SP  {0,0,768,576}        /* pal square pixel */
+-#define VPFE_WIN_CIF     {0,0,352,288}
+-#define VPFE_WIN_QCIF    {0,0,176,144}
+-#define VPFE_WIN_QVGA    {0,0,320,240}
+-#define VPFE_WIN_SIF     {0,0,352,240}
+-
+-
+-#ifdef __KERNEL__
+-
+-#include <media/video-buf.h>
+-
+-#define VPFE_MAJOR_RELEASE 0
+-#define VPFE_MINOR_RELEASE 0
+-#define VPFE_BUILD         1
+-
+-#define VPFE_VERSION_CODE \
+-     (VPFE_MAJOR_RELEASE<<16)  | (VPFE_MINOR_RELEASE<<8) | VPFE_BUILD
+-
+-/* By default, the driver is setup for auto-swich mode */
+-#define VPFE_DEFAULT_STD VPFE_STD_AUTO
+-
+-#define VPFE_PIXELASPECT_NTSC {11, 10}
+-#define VPFE_PIXELASPECT_PAL  {54, 59}
+-#define VPFE_PIXELASPECT_NTSC_SP    {1, 1}
+-#define VPFE_PIXELASPECT_PAL_SP     {1, 1}
+-#define VPFE_PIXELASPECT_DEFAULT    {1, 1}
+-
+-#define VPFE_MAX_FRAME_WIDTH      768 /* account for PAL Square pixel mode */
+-#define VPFE_MAX_FRAME_HEIGHT     576 /* account for PAL                   */
+-/* 4:2:2 data */
+-#define VPFE_MAX_FBUF_SIZE       (VPFE_MAX_FRAME_WIDTH*VPFE_MAX_FRAME_HEIGHT*2)
+-/* frame buffers allocate at driver initialization time */
+-#define VPFE_DEFNUM_FBUFS             3
+-
+-#define VPFE_MAX_FBUF_ORDER \
+-   get_order(roundup_pow_of_two(VPFE_MAX_FBUF_SIZE))
+-
+-/* device object */
+-typedef struct vpfe_obj {
+-      struct video_device *video_dev;
+-      struct videobuf_queue bufqueue;/* queue with frame buffers      */
+-      struct list_head dma_queue;
+-      u32 latest_only;                /* indicate whether to return the most */
+-                                      /* recent captured buffers only        */
+-      u32 usrs;
+-      u32 io_usrs;
+-      struct v4l2_prio_state prio;
+-      v4l2_std_id std;
+-      struct v4l2_rect vwin;
+-      struct v4l2_rect bounds;
+-      struct v4l2_fract pixelaspect;
+-              spinlock_t irqlock;
+-      struct semaphore lock;
+-      enum v4l2_field field;
+-      u32 pixelfmt;
+-      u32 numbuffers;
+-      u8* fbuffers[VIDEO_MAX_FRAME];
+-      struct videobuf_buffer *curFrm;
+-      struct videobuf_buffer *nextFrm;
+-      int field_id;
+-      int mode_changed;
+-      int started;
+-      int field_offset;
+-      tvp5146_params tvp5146_params;
+-      ccdc_params_ycbcr ccdc_params;
+-} vpfe_obj;
+-
+-/* file handle */
+-typedef struct vpfe_fh {
+-      struct vpfe_obj *dev;
+-      int io_allowed;
+-      enum v4l2_priority prio;
+-} vpfe_fh;
+-#endif
+-
+-#endif /* DAVINCI_VPFE_H */
+-- 1.6.0.4 
\ No newline at end of file
diff --git a/recipes/linux/linux-davinci/vfpe2.patch b/recipes/linux/linux-davinci/vfpe2.patch
new file mode 100644 (file)
index 0000000..8915ee3
--- /dev/null
@@ -0,0 +1,200 @@
+Subject:
+[PATCH 2/7] interface for configuring CCDC and common ccdc types
+From:
+m-karicheri2-l0cyMroinI0@public.gmane.org
+Date:
+Fri, 13 Mar 2009 17:22:39 -0400
+To:
+davinci-linux-open-source-VycZQUHpC/PFrsHnngEfi1aTQe2KTcn/@public.gmane.org, davinci_opensource_ccb-uAqBSO/uNfhBDgjK7y7TUQ@public.gmane.org, psp_video-uAqBSO/uNfhBDgjK7y7TUQ@public.gmane.org
+Newsgroups:
+gmane.linux.davinci
+
+Adding an interface for configuring ccdc as per data format of decoder
+output. Also adds a header file for common ccdc data types. 
+
+Signed-off-by: Murali Karicheri <m-karicheri2-l0cyMroinI0@public.gmane.org>
+---
+ include/media/davinci/ccdc_common.h    |   48 +++++++++++++
+ include/media/davinci/ccdc_hw_device.h |  117 ++++++++++++++++++++++++++++++++
+ 2 files changed, 165 insertions(+), 0 deletions(-)
+ create mode 100644 include/media/davinci/ccdc_common.h
+ create mode 100644 include/media/davinci/ccdc_hw_device.h
+
+diff --git a/include/media/davinci/ccdc_common.h b/include/media/davinci/ccdc_common.h
+new file mode 100644
+index 0000000..0992af5
+--- /dev/null
++++ b/include/media/davinci/ccdc_common.h
+@@ -0,0 +1,48 @@
++/*
++ * 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
++ *
++ **************************************************************************/
++#ifndef _CCDC_COMMON_H
++#define _CCDC_COMMON_H
++enum ccdc_pixfmt {
++      CCDC_PIXFMT_RAW = 0,
++      CCDC_PIXFMT_YCBCR_16BIT = 1,
++      CCDC_PIXFMT_YCBCR_8BIT = 2
++};
++
++enum ccdc_frmfmt {
++      CCDC_FRMFMT_PROGRESSIVE = 0,
++      CCDC_FRMFMT_INTERLACED = 1
++};
++
++/* PIXEL ORDER IN MEMORY from LSB to MSB */
++/* only applicable for 8-bit input mode  */
++enum ccdc_pixorder {
++      CCDC_PIXORDER_CBYCRY = 1,
++      CCDC_PIXORDER_YCBYCR = 0
++};
++
++enum ccdc_buftype {
++      CCDC_BUFTYPE_FLD_INTERLEAVED,
++      CCDC_BUFTYPE_FLD_SEPARATED
++};
++
++enum ccdc_pinpol {
++      CCDC_PINPOL_POSITIVE = 0,
++      CCDC_PINPOL_NEGATIVE = 1
++};
++#endif
+diff --git a/include/media/davinci/ccdc_hw_device.h b/include/media/davinci/ccdc_hw_device.h
+new file mode 100644
+index 0000000..4ae9876
+--- /dev/null
++++ b/include/media/davinci/ccdc_hw_device.h
+@@ -0,0 +1,117 @@
++/*
++ * Copyright (C) 2008 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
++ *
++ * ccdc device API
++ */
++#ifndef _CCDC_HW_DEVICE_H
++#define _CCDC_HW_DEVICE_H
++
++#ifdef __KERNEL__
++#include <linux/videodev2.h>
++#include <linux/device.h>
++#include <media/davinci/vpfe_types.h>
++#include <media/davinci/ccdc_common.h>
++/*
++ * Maximum number of capture channels supported by VPFE
++ */
++#define CCDC_CAPTURE_NUM_CHANNELS 1
++/*
++ * vpfe hw interface
++ */
++struct ccdc_hw_device {
++
++      /* vpfe device name */
++      char name[30];
++
++      /* Pointer to initialize function to initialize ccdc device */
++      int (*open) (struct device *dev);
++      /* Set of functions pointers for control related functions.
++       * Use queryctrl of decoder interface to check if it is a decoder
++       * control id. If not passed to ccdc to process it
++       */
++      /* set ccdc base address */
++      void (*set_ccdc_base)(void *base, int size);
++
++      /* set vpss base address */
++      void (*set_vpss_base)(void *base, int size);
++
++      /* get ccdc base */
++      void * (*get_ccdc_base)(void);
++
++      /* get vpss base */
++      void * (*get_vpss_base)(void);
++
++      void (*enable) (int en);
++      /*
++       * Pointer to function to enable or disable ccdc
++       */
++      u32 (*reset) (void);
++      /* reset sbl. only for 6446 */
++      void (*enable_out_to_sdram) (int en);
++      /* Pointer to function to set hw frame type */
++      int (*set_hw_if_type) (enum vpfe_hw_if_type iface);
++      /* get interface parameters */
++      int (*get_hw_if_params) (struct vpfe_hw_if_param *param);
++      /* Pointer to function to set parameters. Used
++       * for implementing VPFE_S_CCDC_PARAMS
++       */
++      int (*setparams) (void *params);
++      /* Pointer to function to get parameter. Used
++       * for implementing VPFE_G_CCDC_PARAMS
++       */
++      int (*getparams) (void *params);
++      /* Pointer to function to configure ccdc */
++      int (*configure) (void);
++
++      /* enumerate hw pix formats */
++      int (*enum_pix)(enum vpfe_hw_pix_format *hw_pix, int i);
++      /* Pointer to function to set buffer type */
++      int (*set_buftype) (enum ccdc_buftype buf_type);
++      /* Pointer to function to get buffer type */
++      int (*get_buftype) (enum ccdc_buftype *buf_type);
++      /* Pointer to function to set frame format */
++      int (*set_frame_format) (enum ccdc_frmfmt frm_fmt);
++      /* Pointer to function to get frame format */
++      int (*get_frame_format) (enum ccdc_frmfmt *frm_fmt);
++      /* Pointer to function to set buffer type */
++      int (*get_pixelformat) (enum vpfe_hw_pix_format *pixfmt);
++      /* Pointer to function to get pixel format. Uses V4L2 type */
++      int (*set_pixelformat) (enum vpfe_hw_pix_format pixfmt);
++      /* Pointer to function to set image window */
++      int (*set_image_window) (struct v4l2_rect *win);
++      /* Pointer to function to set image window */
++      int (*get_image_window) (struct v4l2_rect *win);
++      /* Pointer to function to get line length */
++      int (*get_line_length) (unsigned int *len);
++
++      /* Query SoC control IDs */
++      int (*queryctrl)(struct v4l2_queryctrl *qctrl);
++      /* Set SoC control */
++      int (*setcontrol)(struct v4l2_control *ctrl);
++      /* Get SoC control */
++      int (*getcontrol)(struct v4l2_control *ctrl);
++      /* Pointer to function to set current standard info */
++      /* Pointer to function to set frame buffer address */
++      void (*setfbaddr) (unsigned long addr);
++      /* Pointer to function to get field id */
++      int (*getfid) (void);
++      /* Pointer to deinitialize function */
++      int (*close) (struct device *dev);
++};
++
++#endif
++#endif
+-- 1.6.0.4 
\ No newline at end of file
diff --git a/recipes/linux/linux-davinci/vfpe3.patch b/recipes/linux/linux-davinci/vfpe3.patch
new file mode 100644 (file)
index 0000000..f655b50
--- /dev/null
@@ -0,0 +1,2558 @@
+Subject:
+[PATCH 3/7] ccdc hw module and header file for DM355
+From:
+m-karicheri2-l0cyMroinI0@public.gmane.org
+Date:
+Fri, 13 Mar 2009 17:22:56 -0400
+To:
+davinci-linux-open-source-VycZQUHpC/PFrsHnngEfi1aTQe2KTcn/@public.gmane.org, davinci_opensource_ccb-uAqBSO/uNfhBDgjK7y7TUQ@public.gmane.org, psp_video-uAqBSO/uNfhBDgjK7y7TUQ@public.gmane.org
+Newsgroups:
+gmane.linux.davinci
+
+Adds ccdc hw module and it's header file
+
+Signed-off-by: Murali Karicheri <m-karicheri2-l0cyMroinI0@public.gmane.org>
+---
+ drivers/media/video/davinci/ccdc_dm355.c | 1766 ++++++++++++++++++++++++++++++
+ drivers/media/video/davinci/ccdc_dm355.h |  758 +++++++++++++
+ 2 files changed, 2524 insertions(+), 0 deletions(-)
+ create mode 100644 drivers/media/video/davinci/ccdc_dm355.c
+ create mode 100644 drivers/media/video/davinci/ccdc_dm355.h
+
+diff --git a/drivers/media/video/davinci/ccdc_dm355.c b/drivers/media/video/davinci/ccdc_dm355.c
+new file mode 100644
+index 0000000..b03dbaf
+--- /dev/null
++++ b/drivers/media/video/davinci/ccdc_dm355.c
+@@ -0,0 +1,1766 @@
++/*
++ * Copyright (C) 2005-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
++ */
++#include <linux/platform_device.h>
++#include <linux/uaccess.h>
++#include <asm/page.h>
++#include <media/davinci/ccdc_hw_device.h>
++#include "ccdc_dm355.h"
++
++static struct device *dev;
++
++/*Object for CCDC raw mode */
++static struct ccdc_params_raw ccdc_hw_params_raw = {
++      .pix_fmt = CCDC_PIXFMT_RAW,
++      .frm_fmt = CCDC_FRMFMT_PROGRESSIVE,
++      .win = CCDC_WIN_VGA,
++      .fid_pol = CCDC_PINPOL_POSITIVE,
++      .vd_pol = CCDC_PINPOL_POSITIVE,
++      .hd_pol = CCDC_PINPOL_POSITIVE,
++      .image_invert_enable = 0,
++      .data_sz = _10BITS,
++      .med_filt_thres = 0,
++      .mfilt1 = NO_MEDIAN_FILTER1,
++      .mfilt2 = NO_MEDIAN_FILTER2,
++      .ccdc_offset = 0,
++      .gain = {
++              .r_ye = 256,
++              .gb_g = 256,
++              .gr_cy = 256,
++              .b_mg = 256
++      },
++      .lpf_enable = 0,
++      .datasft = 2,
++      .alaw = {
++              .b_alaw_enable = 0,
++              .gama_wd = 2
++      },
++      .blk_clamp = {
++              .b_clamp_enable = 0,
++              .sample_pixel = 1,
++              .start_pixel = 0,
++              .dc_sub = 25
++      },
++      .blk_comp = {
++              .b_comp = 0,
++              .gb_comp = 0,
++              .gr_comp = 0,
++              .r_comp = 0
++      },
++      .vertical_dft = {
++              .ver_dft_en = 0
++      },
++      .lens_sh_corr = {
++              .lsc_enable = 0
++      },
++      .data_formatter_r = {
++              .fmt_enable = 0
++      },
++      .color_space_con = {
++              .csc_enable = 0
++      },
++      .col_pat_field0 = {
++              .olop = CCDC_GREEN_BLUE,
++              .olep = CCDC_BLUE,
++              .elop = CCDC_RED,
++              .elep = CCDC_GREEN_RED
++      },
++      .col_pat_field1 = {
++              .olop = CCDC_GREEN_BLUE,
++              .olep = CCDC_BLUE,
++              .elop = CCDC_RED,
++              .elep = CCDC_GREEN_RED
++      }
++};
++
++
++/*Object for CCDC ycbcr mode */
++static struct ccdc_params_ycbcr ccdc_hw_params_ycbcr = {
++      .win = CCDC_WIN_PAL,
++      .pix_fmt = CCDC_PIXFMT_YCBCR_8BIT,
++      .frm_fmt = CCDC_FRMFMT_INTERLACED,
++      .fid_pol = CCDC_PINPOL_POSITIVE,
++      .vd_pol = CCDC_PINPOL_POSITIVE,
++      .hd_pol = CCDC_PINPOL_POSITIVE,
++      .bt656_enable = 1,
++      .pix_order = CCDC_PIXORDER_CBYCRY,
++      .buf_type = CCDC_BUFTYPE_FLD_INTERLEAVED
++};
++
++static struct v4l2_queryctrl ccdc_control_info[CCDC_MAX_CONTROLS] = {
++      {
++              .id = CCDC_CID_R_GAIN,
++              .name = "R/Ye WB Gain",
++              .type = V4L2_CTRL_TYPE_INTEGER,
++              .minimum = 0,
++              .maximum = 2047,
++              .step = 1,
++              .default_value = 256
++      },
++      {
++              .id = CCDC_CID_GR_GAIN,
++              .name = "Gr/Cy WB Gain",
++              .type = V4L2_CTRL_TYPE_INTEGER,
++              .minimum = 0,
++              .maximum = 2047,
++              .step = 1,
++              .default_value = 256
++      },
++      {
++              .id = CCDC_CID_GB_GAIN,
++              .name = "Gb/G WB Gain",
++              .type = V4L2_CTRL_TYPE_INTEGER,
++              .minimum = 0,
++              .maximum = 2047,
++              .step = 1,
++              .default_value = 256
++      },
++      {
++              .id = CCDC_CID_B_GAIN,
++              .name = "B/Mg WB Gain",
++              .type = V4L2_CTRL_TYPE_INTEGER,
++              .minimum = 0,
++              .maximum = 2047,
++              .step = 1,
++              .default_value = 256
++      },
++      {
++              .id = CCDC_CID_OFFSET,
++              .name = "Offset",
++              .type = V4L2_CTRL_TYPE_INTEGER,
++              .minimum = 0,
++              .maximum = 1023,
++              .step = 1,
++              .default_value = 0
++      }
++};
++
++static struct ccdc_config_params_raw ccdc_hw_params_raw_temp;
++static enum vpfe_hw_if_type ccdc_if_type;
++static void *__iomem ccdc_base_addr;
++static int ccdc_addr_size;
++static void *__iomem vpss_base_addr;
++static int vpss_addr_size;
++
++#define CCDC_MAX_RAW_BAYER_FORMATS    2
++#define CCDC_MAX_RAW_YUV_FORMATS      2
++
++/* Raw Bayer formats */
++enum vpfe_hw_pix_format ccdc_raw_bayer_hw_formats[CCDC_MAX_RAW_BAYER_FORMATS] =
++              {VPFE_BAYER_8BIT_PACK_ALAW, VPFE_BAYER};
++
++/* Raw YUV formats */
++enum vpfe_hw_pix_format ccdc_raw_yuv_hw_formats[CCDC_MAX_RAW_YUV_FORMATS] =
++              {VPFE_UYVY, VPFE_YUYV};
++
++/* register access routines */
++static inline u32 regr(u32 offset)
++{
++      if (offset <= ccdc_addr_size)
++              return __raw_readl(ccdc_base_addr + offset);
++      else {
++              dev_err(dev, "offset exceeds ccdc register address space\n");
++              return -1;
++      }
++}
++
++static inline u32 regw(u32 val, u32 offset)
++{
++      if (offset <= ccdc_addr_size) {
++              __raw_writel(val, ccdc_base_addr + offset);
++              return val;
++      } else {
++              dev_err(dev, "offset exceeds ccdc register address space\n");
++              return -1;
++      }
++}
++
++/* register access routines */
++static inline u32 regr_bl(u32 offset)
++{
++      if (offset <= vpss_addr_size)
++              return __raw_readl(vpss_base_addr + offset);
++      else {
++              dev_err(dev, "offset exceeds vpss register address space\n");
++              return -1;
++      }
++}
++
++static inline u32 regw_bl(u32 val, u32 offset)
++{
++      if (offset <= vpss_addr_size) {
++              __raw_writel(val, vpss_base_addr + offset);
++              return val;
++      } else {
++              dev_err(dev, "offset exceeds vpss register address space\n");
++              return -1;
++      }
++}
++static void ccdc_set_ccdc_base(void *addr, int size)
++{
++      ccdc_base_addr = addr;
++      ccdc_addr_size = size;
++}
++
++static void ccdc_set_vpss_base(void *addr, int size)
++{
++      vpss_base_addr = addr;
++      vpss_addr_size = size;
++}
++
++static void *ccdc_get_ccdc_base(void)
++{
++      return (void *)ccdc_base_addr;
++}
++
++static void *ccdc_get_vpss_base(void)
++{
++      return (void *)vpss_base_addr;
++}
++
++static void ccdc_enable(int en)
++{
++      unsigned int temp;
++      temp = regr(SYNCEN);
++      temp &= (~0x1);
++      temp |= (en & 0x01);
++      regw(temp, SYNCEN);
++}
++
++static void ccdc_enable_output_to_sdram(int en)
++{
++      unsigned int temp;
++      temp = regr(SYNCEN);
++      temp &= (~(0x1 << 1));
++      temp |= (en & 0x01) << 1;
++      regw(temp, SYNCEN);
++}
++
++static void ccdc_config_gain_offset(void)
++{
++      /* configure gain */
++      regw(ccdc_hw_params_raw.gain.r_ye, RYEGAIN);
++      regw(ccdc_hw_params_raw.gain.gr_cy, GRCYGAIN);
++      regw(ccdc_hw_params_raw.gain.gb_g, GBGGAIN);
++      regw(ccdc_hw_params_raw.gain.b_mg, BMGGAIN);
++      /* configure offset */
++      regw(ccdc_hw_params_raw.ccdc_offset, OFFSET);
++}
++
++/* Query control. Only applicable for Bayer capture */
++static int ccdc_queryctrl(struct v4l2_queryctrl *qctrl)
++{
++      int i, id;
++      struct v4l2_queryctrl *control = NULL;
++
++      dev_dbg(dev, "ccdc_queryctrl: start\n");
++      if (NULL == qctrl) {
++              dev_err(dev, "ccdc_queryctrl : invalid user ptr\n");
++              return -EINVAL;
++      }
++
++      if (VPFE_RAW_BAYER != ccdc_if_type) {
++              dev_err(dev,
++                     "ccdc_queryctrl : Not doing Raw Bayer Capture\n");
++              return -EINVAL;
++      }
++
++      id = qctrl->id;
++      memset(qctrl, 0, sizeof(struct v4l2_queryctrl));
++      for (i = 0; i < CCDC_MAX_CONTROLS; i++) {
++              control = &ccdc_control_info[i];
++              if (control->id == id)
++                      break;
++      }
++      if (i == CCDC_MAX_CONTROLS) {
++              dev_err(dev, "ccdc_queryctrl : Invalid control ID\n");
++              return -EINVAL;
++      }
++      memcpy(qctrl, control, sizeof(struct v4l2_queryctrl));
++      dev_dbg(dev, "ccdc_queryctrl: end\n");
++      return 0;
++}
++
++static int ccdc_setcontrol(struct v4l2_control *ctrl)
++{
++      int i;
++      struct v4l2_queryctrl *control = NULL;
++      struct ccdc_gain *gain =
++          &ccdc_hw_params_raw.gain;
++
++      if (NULL == ctrl) {
++              dev_err(dev, "ccdc_setcontrol: invalid user ptr\n");
++              return -EINVAL;
++      }
++
++      if (ccdc_if_type != VPFE_RAW_BAYER) {
++              dev_err(dev,
++                     "ccdc_setcontrol: Not doing Raw Bayer Capture\n");
++              return -EINVAL;
++      }
++
++      for (i = 0; i < CCDC_MAX_CONTROLS; i++) {
++              control = &ccdc_control_info[i];
++              if (control->id == ctrl->id)
++                      break;
++      }
++
++      if (i == CCDC_MAX_CONTROLS) {
++              dev_err(dev, "ccdc_queryctrl : Invalid control ID, 0x%x\n",
++                     control->id);
++              return -EINVAL;
++      }
++
++      if (ctrl->value > control->maximum) {
++              dev_err(dev, "ccdc_queryctrl : Invalid control value\n");
++              return -EINVAL;
++      }
++
++      switch (ctrl->id) {
++      case CCDC_CID_R_GAIN:
++              gain->r_ye = ctrl->value & CCDC_GAIN_MASK;
++              break;
++      case CCDC_CID_GR_GAIN:
++              gain->gr_cy = ctrl->value & CCDC_GAIN_MASK;
++              break;
++      case CCDC_CID_GB_GAIN:
++              gain->gb_g = ctrl->value  & CCDC_GAIN_MASK;
++              break;
++
++      case CCDC_CID_B_GAIN:
++              gain->b_mg = ctrl->value  & CCDC_GAIN_MASK;
++              break;
++      default:
++              ccdc_hw_params_raw.ccdc_offset = ctrl->value & CCDC_OFFSET_MASK;
++      }
++
++      /* set it in hardware */
++      ccdc_config_gain_offset();
++      return 0;
++}
++
++static int ccdc_getcontrol(struct v4l2_control *ctrl)
++{
++      int i;
++      struct v4l2_queryctrl *control = NULL;
++
++      if (NULL == ctrl) {
++              dev_err(dev, "ccdc_setcontrol: invalid user ptr\n");
++              return -EINVAL;
++      }
++
++      if (ccdc_if_type != VPFE_RAW_BAYER) {
++              dev_err(dev,
++                     "ccdc_setcontrol: Not doing Raw Bayer Capture\n");
++              return -EINVAL;
++      }
++
++      for (i = 0; i < CCDC_MAX_CONTROLS; i++) {
++              control = &ccdc_control_info[i];
++              if (control->id == ctrl->id)
++                      break;
++      }
++
++      if (i == CCDC_MAX_CONTROLS) {
++              dev_err(dev, "ccdc_queryctrl : Invalid control ID\n");
++              return -EINVAL;
++      }
++
++      switch (ctrl->id) {
++      case CCDC_CID_R_GAIN:
++              ctrl->value = ccdc_hw_params_raw.gain.r_ye;
++              break;
++      case CCDC_CID_GR_GAIN:
++              ctrl->value = ccdc_hw_params_raw.gain.gr_cy;
++              break;
++      case CCDC_CID_GB_GAIN:
++              ctrl->value = ccdc_hw_params_raw.gain.gb_g;
++              break;
++      case CCDC_CID_B_GAIN:
++              ctrl->value = ccdc_hw_params_raw.gain.b_mg;
++              break;
++      default:
++              /* offset */
++              ctrl->value = ccdc_hw_params_raw.ccdc_offset;
++      }
++      /* set it in hardware */
++      return 0;
++}
++
++static void ccdc_reset(void)
++{
++      int i, clkctrl;
++      /* disable CCDC */
++      dev_dbg(dev, "\nstarting ccdc_reset...");
++      ccdc_enable(0);
++      /* set all registers to default value */
++      for (i = 0; i <= 0x15c; i += 4)
++              regw(0, i);
++      /* no culling support */
++      regw(0xffff, CULH);
++      regw(0xff, CULV);
++      /* Set default Gain and Offset */
++      ccdc_hw_params_raw.gain.r_ye = 256;
++      ccdc_hw_params_raw.gain.gb_g = 256;
++      ccdc_hw_params_raw.gain.gr_cy = 256;
++      ccdc_hw_params_raw.gain.b_mg = 256;
++      ccdc_hw_params_raw.ccdc_offset = 0;
++      ccdc_config_gain_offset();
++      /* up to 12 bit sensor */
++      regw(0x0FFF, OUTCLIP);
++      /* CCDC input Mux select directly from sensor */
++      regw_bl(0x00, CCDCMUX);
++      dev_dbg(dev, "\nEnd of ccdc_reset...");
++}
++
++static int ccdc_open(struct device *device)
++{
++      dev = device;
++      ccdc_reset();
++      return 0;
++}
++
++/*
++ * ======== ccdc_setwin  ========
++ *
++ * This function will configure the window size to
++ * be capture in CCDC reg
++ */
++static void ccdc_setwin(struct ccdc_imgwin *image_win,
++                      enum ccdc_frmfmt frm_fmt, int ppc)
++{
++      int horz_start, horz_nr_pixels;
++      int vert_start, vert_nr_lines;
++      int mid_img = 0;
++      dev_dbg(dev, "\nStarting ccdc_setwin...");
++      /* configure horizonal and vertical starts and sizes */
++      horz_start = image_win->left << (ppc - 1);
++      horz_nr_pixels = ((image_win->width) << (ppc - 1)) - 1;
++
++      /*Writing the horizontal info into the registers */
++      regw(horz_start & START_PX_HOR_MASK, SPH);
++      regw(horz_nr_pixels & NUM_PX_HOR_MASK, NPH);
++      vert_start = image_win->top;
++
++      if (frm_fmt == CCDC_FRMFMT_INTERLACED) {
++              vert_nr_lines = (image_win->height >> 1) - 1;
++              vert_start >>= 1;
++              vert_start += 1; /* Since first line doesn't have any data */
++              /* configure VDINT0 and VDINT1 */
++              regw(vert_start, VDINT0);
++      } else {
++              vert_start += 1; /* Since first line doesn't have any data */
++              vert_nr_lines = image_win->height - 1;
++              /* configure VDINT0 and VDINT1 */
++              mid_img = vert_start + (image_win->height / 2);
++              regw(vert_start, VDINT0);
++              regw(mid_img, VDINT1);
++      }
++      regw(vert_start & START_VER_ONE_MASK, SLV0);
++      regw(vert_start & START_VER_TWO_MASK, SLV1);
++      regw(vert_nr_lines & NUM_LINES_VER, NLV);
++      dev_dbg(dev, "\nEnd of ccdc_setwin...");
++}
++
++static int validate_ccdc_param(struct ccdc_config_params_raw *ccdcparam)
++{
++      if (ccdcparam->pix_fmt != 0) {
++              dev_err(dev,
++                     "Invalid value of pix_fmt, only raw supported\n");
++              return -1;
++      }
++
++      if (ccdcparam->frm_fmt != 0) {
++              dev_err(dev,
++                     "Only Progressive frame format is supported\n");
++              return -1;
++      }
++
++      if (ccdcparam->fid_pol != CCDC_PINPOL_POSITIVE
++          && ccdcparam->fid_pol != CCDC_PINPOL_NEGATIVE) {
++              dev_err(dev, "Invalid value of field id polarity\n");
++              return -1;
++      }
++
++      if (ccdcparam->vd_pol != CCDC_PINPOL_POSITIVE
++          && ccdcparam->vd_pol != CCDC_PINPOL_NEGATIVE) {
++              dev_err(dev, "Invalid value of VD polarity\n");
++              return -1;
++      }
++
++      if (ccdcparam->hd_pol != CCDC_PINPOL_POSITIVE
++          && ccdcparam->hd_pol != CCDC_PINPOL_NEGATIVE) {
++              dev_err(dev, "Invalid value of HD polarity\n");
++              return -1;
++      }
++
++      if (ccdcparam->datasft < NO_SHIFT || ccdcparam->datasft > _6BIT) {
++              dev_err(dev, "Invalid value of data shift\n");
++              return -1;
++      }
++
++      if (ccdcparam->mfilt1 < NO_MEDIAN_FILTER1
++          || ccdcparam->mfilt1 > MEDIAN_FILTER1) {
++              dev_err(dev, "Invalid value of median filter1\n");
++              return -1;
++      }
++
++      if (ccdcparam->mfilt2 < NO_MEDIAN_FILTER2
++          || ccdcparam->mfilt2 > MEDIAN_FILTER2) {
++              dev_err(dev, "Invalid value of median filter2\n");
++              return -1;
++      }
++
++      if (ccdcparam->ccdc_offset < 0 || ccdcparam->ccdc_offset > 1023) {
++              dev_err(dev, "Invalid value of offset\n");
++              return -1;
++      }
++
++      if ((ccdcparam->med_filt_thres < 0)
++              || (ccdcparam->med_filt_thres > 0x3FFF)) {
++              dev_err(dev, "Invalid value of median filter thresold\n");
++              return -1;
++      }
++
++      if (ccdcparam->data_sz < _16BITS || ccdcparam->data_sz > _8BITS) {
++              dev_err(dev, "Invalid value of data size\n");
++              return -1;
++      }
++
++      if (ccdcparam->alaw.b_alaw_enable) {
++              if (ccdcparam->alaw.gama_wd < BITS_13_4
++                  || ccdcparam->alaw.gama_wd > BITS_09_0) {
++                      dev_err(dev, "Invalid value of ALAW\n");
++                      return -1;
++              }
++      }
++
++      if (ccdcparam->blk_clamp.b_clamp_enable) {
++              if (ccdcparam->blk_clamp.sample_pixel < _1PIXELS
++                  || ccdcparam->blk_clamp.sample_pixel > _16PIXELS) {
++                      dev_err(dev, "Invalid value of sample pixel\n");
++                      return -1;
++              }
++              if (ccdcparam->blk_clamp.sample_ln < _1LINES
++                  || ccdcparam->blk_clamp.sample_ln > _16LINES) {
++                      dev_err(dev, "Invalid value of sample lines\n");
++                      return -1;
++              }
++
++      }
++
++      if (ccdcparam->lens_sh_corr.lsc_enable) {
++              dev_err(dev, "Lens shadding correction is not supported\n");
++              return -1;
++      }
++      return 0;
++}
++
++static int ccdc_update_raw_params(void *arg)
++{
++      struct ccdc_config_params_raw *raw =
++              (struct ccdc_config_params_raw *)arg;
++
++      ccdc_hw_params_raw.pix_fmt =
++              raw->pix_fmt;
++      ccdc_hw_params_raw.frm_fmt =
++              raw->frm_fmt;
++      ccdc_hw_params_raw.win =
++              raw->win;
++      ccdc_hw_params_raw.fid_pol =
++              raw->fid_pol;
++      ccdc_hw_params_raw.vd_pol =
++              raw->vd_pol;
++      ccdc_hw_params_raw.hd_pol =
++              raw->hd_pol;
++      ccdc_hw_params_raw.buf_type =
++              raw->buf_type;
++      ccdc_hw_params_raw.datasft =
++              raw->datasft;
++      ccdc_hw_params_raw.mfilt1 =
++              raw->mfilt1;
++      ccdc_hw_params_raw.mfilt2 =
++              raw->mfilt2;
++      ccdc_hw_params_raw.lpf_enable =
++              raw->lpf_enable;
++      ccdc_hw_params_raw.horz_flip_enable =
++              raw->horz_flip_enable;
++      ccdc_hw_params_raw.ccdc_offset =
++              raw->ccdc_offset;
++      ccdc_hw_params_raw.med_filt_thres =
++              raw->med_filt_thres;
++      ccdc_hw_params_raw.image_invert_enable =
++              raw->image_invert_enable;
++      ccdc_hw_params_raw.data_sz =
++              raw->data_sz;
++      ccdc_hw_params_raw.alaw =
++              raw->alaw;
++      ccdc_hw_params_raw.data_offset_s =
++              raw->data_offset_s;
++      ccdc_hw_params_raw.blk_clamp =
++              raw->blk_clamp;
++      ccdc_hw_params_raw.vertical_dft =
++              raw->vertical_dft;
++      ccdc_hw_params_raw.lens_sh_corr =
++              raw->lens_sh_corr;
++      ccdc_hw_params_raw.data_formatter_r =
++              raw->data_formatter_r;
++      ccdc_hw_params_raw.color_space_con =
++              raw->color_space_con;
++      ccdc_hw_params_raw.col_pat_field0 =
++              raw->col_pat_field0;
++      ccdc_hw_params_raw.col_pat_field1 =
++              raw->col_pat_field1;
++
++      return 0;
++}
++
++static int ccdc_update_ycbcr_params(void *arg)
++{
++      if (copy_from_user(&ccdc_hw_params_ycbcr,
++                         (struct ccdc_params_ycbcr *)arg,
++                         sizeof(struct ccdc_params_ycbcr))) {
++              dev_err(dev, "ccdc_update_ycbcr_params: error"
++                         "in copying ccdc params\n");
++              return -EFAULT;
++      }
++      return 0;
++}
++
++/* Parameter operations */
++static int ccdc_setparams(void *params)
++{
++      int x;
++      if (ccdc_if_type == VPFE_RAW_BAYER) {
++              x = copy_from_user(&ccdc_hw_params_raw_temp,
++                                 (struct ccdc_config_params_raw *)params,
++                                 sizeof(struct ccdc_config_params_raw));
++              if (x) {
++                      dev_err(dev, "ccdc_setparams: error in copying ccdc"
++                              "params, %d\n", x);
++                      return -EFAULT;
++              }
++
++              if (!validate_ccdc_param(&ccdc_hw_params_raw_temp)) {
++                      if (!ccdc_update_raw_params(&ccdc_hw_params_raw_temp))
++                              return 0;
++              }
++      } else
++              return ccdc_update_ycbcr_params(params);
++      return -EINVAL;
++}
++
++
++/*This function will configure CCDC for YCbCr parameters*/
++static void ccdc_config_ycbcr(void)
++{
++      u32 modeset;
++      struct ccdc_params_ycbcr *params = &ccdc_hw_params_ycbcr;
++
++      /* first reset the CCDC                                          */
++      /* all registers have default values after reset                 */
++      /* This is important since we assume default values to be set in */
++      /* a lot of registers that we didn't touch                       */
++      dev_dbg(dev, "\nStarting ccdc_config_ycbcr...");
++      ccdc_reset();
++
++      /* configure pixel format */
++      modeset = (params->pix_fmt & 0x3) << 12;
++
++      /* configure video frame format */
++      modeset |= (params->frm_fmt & 0x1) << 7;
++
++      /* setup BT.656 sync mode */
++      if (params->bt656_enable) {
++              regw(3, REC656IF);
++              /* configure the FID, VD, HD pin polarity */
++              /* fld,hd pol positive, vd negative, 8-bit pack mode */
++              modeset |= 0x04;
++      } else {                /* y/c external sync mode */
++              modeset |= ((params->fid_pol & 0x1) << 4);
++              modeset |= ((params->hd_pol & 0x1) << 3);
++              modeset |= ((params->vd_pol & 0x1) << 2);
++      }
++
++      /* pack the data to 8-bit */
++      modeset |= 0x1 << 11;
++
++      regw(modeset, MODESET);
++
++      /* configure video window */
++      ccdc_setwin(&params->win, params->frm_fmt, 2);
++      /* configure the order of y cb cr in SD-RAM */
++      regw((params->pix_order << 11) | 0x8040, CCDCFG);
++
++      /* configure the horizontal line offset */
++      /* this is done by rounding up width to a multiple of 16 pixels */
++      /* and multiply by two to account for y:cb:cr 4:2:2 data */
++      regw(((((params->win.width * 2) + 31) & 0xffffffe0) >> 5), HSIZE);
++
++      /* configure the memory line offset */
++      if (params->buf_type == CCDC_BUFTYPE_FLD_INTERLEAVED) {
++              /* two fields are interleaved in memory */
++              regw(0x00000249, SDOFST);
++      }
++
++      dev_dbg(dev, "\nEnd of ccdc_config_ycbcr...\n");
++}
++
++
++/*
++ * ======== ccdc_config_raw  ========
++ *
++ * This function will configure CCDC for Raw mode parameters
++ */
++static void ccdc_config_raw(void)
++{
++      struct ccdc_params_raw *params = &ccdc_hw_params_raw;
++      unsigned int mode_set = 0;
++      unsigned int val = 0, val1 = 0;
++      int temp1 = 0, temp2 = 0, i = 0, fmtreg_v = 0, shift_v = 0, flag = 0;
++      int temp_gf = 0, temp_lcs = 0;
++      dev_dbg(dev, "\nStarting ccdc_config_raw...");
++      /*      Reset CCDC */
++      ccdc_reset();
++
++      /*
++       *      C O N F I G U R I N G  T H E  C C D C F G  R E G I S T E R
++       */
++
++      /*Set CCD Not to swap input since input is RAW data */
++      val |= CCDC_YCINSWP_RAW;
++
++      /*set FID detection function to Latch at V-Sync */
++      val |= CCDC_CCDCFG_FIDMD_LATCH_VSYNC << CCDC_CCDCFG_FIDMD_SHIFT;
++
++      /*set WENLOG - ccdc valid area */
++      val |= CCDC_CCDCFG_WENLOG_AND << CCDC_CCDCFG_WENLOG_SHIFT;
++
++      /*set TRGSEL */
++      val |= CCDC_CCDCFG_TRGSEL_WEN << CCDC_CCDCFG_TRGSEL_SHIFT;
++
++      /*set EXTRG */
++      val |= CCDC_CCDCFG_EXTRG_DISABLE << CCDC_CCDCFG_EXTRG_SHIFT;
++
++      /* Disable latching function registers on VSYNC-busy writable
++         registers  */
++
++      /* Enable latching function registers on VSYNC-shadowed registers */
++      val |= CCDC_LATCH_ON_VSYNC_DISABLE;
++      regw(val, CCDCFG);
++      /*
++       *      C O N F I G U R I N G  T H E  M O D E S E T  R E G I S T E R
++       */
++
++      /*Set VDHD direction to input */
++      mode_set |=
++          (CCDC_VDHDOUT_INPUT & CCDC_VDHDOUT_MASK) << CCDC_VDHDOUT_SHIFT;
++
++      /*Set input type to raw input */
++      mode_set |=
++          (CCDC_RAW_IP_MODE & CCDC_RAW_INPUT_MASK) << CCDC_RAW_INPUT_SHIFT;
++
++      /*      Configure the vertical sync polarity(MODESET.VDPOL) */
++      mode_set = (params->vd_pol & CCDC_VD_POL_MASK) << CCDC_VD_POL_SHIFT;
++
++      /*      Configure the horizontal sync polarity (MODESET.HDPOL) */
++      mode_set |= (params->hd_pol & CCDC_HD_POL_MASK) << CCDC_HD_POL_SHIFT;
++
++      /*      Configure frame id polarity (MODESET.FLDPOL) */
++      mode_set |= (params->fid_pol & CCDC_FID_POL_MASK) << CCDC_FID_POL_SHIFT;
++
++      /*      Configure data polarity */
++      mode_set |=
++          (CCDC_DATAPOL_NORMAL & CCDC_DATAPOL_MASK) << CCDC_DATAPOL_SHIFT;
++
++      /*      Configure External WEN Selection */
++      mode_set |= (CCDC_EXWEN_DISABLE & CCDC_EXWEN_MASK) << CCDC_EXWEN_SHIFT;
++
++      /* Configure frame format(progressive or interlace) */
++      mode_set |= (params->frm_fmt & CCDC_FRM_FMT_MASK) << CCDC_FRM_FMT_SHIFT;
++
++      /* Configure pixel format (Input mode) */
++      mode_set |= (params->pix_fmt & CCDC_PIX_FMT_MASK) << CCDC_PIX_FMT_SHIFT;
++
++      if ((params->data_sz == _8BITS) || params->alaw.b_alaw_enable)
++              mode_set |= CCDC_DATA_PACK_ENABLE;
++
++      /* Configure for LPF */
++      if (params->lpf_enable)
++              mode_set |= (params->lpf_enable & CCDC_LPF_MASK) <<
++                              CCDC_LPF_SHIFT;
++      /* Configure the data shift */
++      mode_set |= (params->datasft & CCDC_DATASFT_MASK) << CCDC_DATASFT_SHIFT;
++      regw(mode_set, MODESET);
++      dev_dbg(dev, "\nWriting 0x%x to MODESET...\n", mode_set);
++
++      /* Configure the Median Filter threshold */
++      regw((params->med_filt_thres) & 0x3fff, MEDFILT);
++
++      /*
++       *      C O N F I G U R E   T H E   G A M M A W D   R E G I S T E R
++       */
++
++      val = 8;
++      val |=
++          (CCDC_CFA_MOSAIC & CCDC_GAMMAWD_CFA_MASK) << CCDC_GAMMAWD_CFA_SHIFT;
++
++      /* Enable and configure aLaw register if needed */
++      if (params->alaw.b_alaw_enable) {
++              val |= (params->alaw.gama_wd & CCDC_ALAW_GAMA_WD_MASK) << 2;
++              val |= CCDC_ALAW_ENABLE;        /*set enable bit of alaw */
++      }
++
++      /* Configure Median filter1 for IPIPE capture */
++      val |= params->mfilt1 << CCDC_MFILT1_SHIFT;
++
++      /* Configure Median filter2 for SDRAM capture */
++      val |= params->mfilt2 << CCDC_MFILT2_SHIFT;
++
++      regw(val, GAMMAWD);
++      dev_dbg(dev, "\nWriting 0x%x to GAMMAWD...\n", val);
++
++      /* configure video window */
++      ccdc_setwin(&params->win, params->frm_fmt, 1);
++
++      /*
++       *      O P T I C A L   B L A C K   A V E R A G I N G
++       */
++      val = 0;
++      if (params->blk_clamp.b_clamp_enable) {
++              val |= (params->blk_clamp.start_pixel & CCDC_BLK_ST_PXL_MASK);
++
++              /* No of line to be avg */
++              val1 |= (params->blk_clamp.sample_ln & CCDC_NUM_LINE_CALC_MASK)
++                  << CCDC_NUM_LINE_CALC_SHIFT;
++              /* No of pixel/line to be avg */
++              val |=
++                  (params->blk_clamp.sample_pixel & CCDC_BLK_SAMPLE_LN_MASK)
++                  << CCDC_BLK_SAMPLE_LN_SHIFT;
++              /* Enable the Black clamping */
++              val |= CCDC_BLK_CLAMP_ENABLE;
++              regw(val, CLAMP);
++
++              dev_dbg(dev, "\nWriting 0x%x to CLAMP...\n", val);
++              /* If Black clamping is enable then make dcsub 0 */
++              regw(val1, DCSUB);
++              dev_dbg(dev, "\nWriting 0x00000000 to DCSUB...\n");
++
++      } else {
++              /* configure DCSub */
++              val = (params->blk_clamp.dc_sub) & CCDC_BLK_DC_SUB_MASK;
++              regw(val, DCSUB);
++
++              dev_dbg(dev, "\nWriting 0x%x to DCSUB...\n", val);
++              regw(0x0000, CLAMP);
++
++              dev_dbg(dev, "\nWriting 0x0000 to CLAMP...\n");
++      }
++
++      /*
++       *  C O N F I G U R E   B L A C K   L E V E L   C O M P E N S A T I O N
++       */
++      val = 0;
++      val = (params->blk_comp.b_comp & CCDC_BLK_COMP_MASK);
++      val |= (params->blk_comp.gb_comp & CCDC_BLK_COMP_MASK)
++          << CCDC_BLK_COMP_GB_COMP_SHIFT;
++      regw(val, BLKCMP1);
++
++      val1 = 0;
++      val1 |= (params->blk_comp.gr_comp & CCDC_BLK_COMP_MASK)
++          << CCDC_BLK_COMP_GR_COMP_SHIFT;
++      val1 |= (params->blk_comp.r_comp & CCDC_BLK_COMP_MASK)
++          << CCDC_BLK_COMP_R_COMP_SHIFT;
++      regw(val1, BLKCMP0);
++
++      dev_dbg(dev, "\nWriting 0x%x to BLKCMP1...\n", val);
++      dev_dbg(dev, "\nWriting 0x%x to BLKCMP0...\n", val1);
++
++      /* Configure Vertical Defect Correction if needed */
++      if (params->vertical_dft.ver_dft_en) {
++
++              shift_v = 0;
++              shift_v = 0 << CCDC_DFCCTL_VDFCEN_SHIFT;
++              shift_v |=
++                  params->vertical_dft.gen_dft_en & CCDC_DFCCTL_GDFCEN_MASK;
++              shift_v |=
++                  (params->vertical_dft.dft_corr_ctl.
++                   vdfcsl & CCDC_DFCCTL_VDFCSL_MASK) <<
++                  CCDC_DFCCTL_VDFCSL_SHIFT;
++              shift_v |=
++                  (params->vertical_dft.dft_corr_ctl.
++                   vdfcuda & CCDC_DFCCTL_VDFCUDA_MASK) <<
++                  CCDC_DFCCTL_VDFCUDA_SHIFT;
++              shift_v |=
++                  (params->vertical_dft.dft_corr_ctl.
++                   vdflsft & CCDC_DFCCTL_VDFLSFT_MASK) <<
++                  CCDC_DFCCTL_VDFLSFT_SHIFT;
++              regw(shift_v, DFCCTL);
++              regw(params->vertical_dft.dft_corr_vert[0], DFCMEM0);
++              regw(params->vertical_dft.dft_corr_horz[0], DFCMEM1);
++              regw(params->vertical_dft.dft_corr_sub1[0], DFCMEM2);
++              regw(params->vertical_dft.dft_corr_sub2[0], DFCMEM3);
++              regw(params->vertical_dft.dft_corr_sub3[0], DFCMEM4);
++
++              shift_v = 0;
++              shift_v = regr(DFCMEMCTL);
++              shift_v |= 1 << CCDC_DFCMEMCTL_DFCMARST_SHIFT;
++              shift_v |= 1;
++              regw(shift_v, DFCMEMCTL);
++
++              while (1) {
++                      flag = regr(DFCMEMCTL);
++                      if ((flag & 0x01) == 0x00)
++                              break;
++              }
++              flag = 0;
++              shift_v = 0;
++              shift_v = regr(DFCMEMCTL);
++              shift_v |= 0 << CCDC_DFCMEMCTL_DFCMARST_SHIFT;
++              regw(shift_v, DFCMEMCTL);
++
++              for (i = 1; i < 16; i++) {
++                      regw(params->vertical_dft.dft_corr_vert[i], DFCMEM0);
++                      regw(params->vertical_dft.dft_corr_horz[i], DFCMEM1);
++                      regw(params->vertical_dft.dft_corr_sub1[i], DFCMEM2);
++                      regw(params->vertical_dft.dft_corr_sub2[i], DFCMEM3);
++                      regw(params->vertical_dft.dft_corr_sub3[i], DFCMEM4);
++
++                      shift_v = 0;
++                      shift_v = regr(DFCMEMCTL);
++                      shift_v |= 1;
++                      regw(shift_v, DFCMEMCTL);
++
++                      while (1) {
++                              flag = regr(DFCMEMCTL);
++                              if ((flag & 0x01) == 0x00)
++                                      break;
++                      }
++                      flag = 0;
++              }
++              regw(params->vertical_dft.
++                   saturation_ctl & CCDC_VDC_DFCVSAT_MASK, DFCVSAT);
++
++              shift_v = 0;
++              shift_v = regr(DFCCTL);
++              shift_v |= 1 << CCDC_DFCCTL_VDFCEN_SHIFT;
++              regw(shift_v, DFCCTL);
++      }
++
++      /* Configure Lens Shading Correction if needed */
++      if (params->lens_sh_corr.lsc_enable) {
++              dev_dbg(dev, "\nlens shading Correction entered....\n");
++
++              /* first disable the LSC */
++              regw(CCDC_LSC_DISABLE, LSCCFG1);
++
++              /* UPDATE PROCEDURE FOR GAIN FACTOR TABLE 1 */
++
++              /* select table 1 */
++              regw(CCDC_LSC_TABLE1_SLC, LSCMEMCTL);
++
++              /* Reset memory address */
++              temp_lcs = regr(LSCMEMCTL);
++              temp_lcs |= CCDC_LSC_MEMADDR_RESET;
++              regw(temp_lcs, LSCMEMCTL);
++
++              /* Update gainfactor for table 1 - u8q8 */
++              temp_gf =
++                  ((int)(params->lens_sh_corr.gf_table1[0].frac_no * 256))
++                  & CCDC_LSC_FRAC_MASK_T1;
++              temp_gf |=
++                  (((int)(params->lens_sh_corr.gf_table1[0].frac_no * 256))
++                   & CCDC_LSC_FRAC_MASK_T1) << 8;
++              regw(temp_gf, LSCMEMD);
++
++              while (1) {
++                      if ((regr(LSCMEMCTL) & 0x10) == 0)
++                              break;
++              }
++
++              /* set the address to incremental mode */
++              temp_lcs = 0;
++              temp_lcs = regr(LSCMEMCTL);
++              temp_lcs |= CCDC_LSC_MEMADDR_INCR;
++              regw(temp_lcs, LSCMEMCTL);
++
++              for (i = 2; i < 255; i += 2) {
++                      temp_gf = 0;
++                      temp_gf = ((int)
++                                 (params->lens_sh_corr.gf_table1[0].frac_no *
++                                  256))
++                          & CCDC_LSC_FRAC_MASK_T1;
++                      temp_gf |= (((int)
++                                   (params->lens_sh_corr.gf_table1[0].
++                                    frac_no * 256))
++                                  & CCDC_LSC_FRAC_MASK_T1) << 8;
++                      regw(temp_gf, LSCMEMD);
++
++                      while (1) {
++                              if ((regr(LSCMEMCTL) & 0x10) == 0)
++                                      break;
++                      }
++              }
++
++              /* UPDATE PROCEDURE FOR GAIN FACTOR TABLE 2 */
++
++              /* select table 2 */
++              temp_lcs = 0;
++              temp_lcs = regr(LSCMEMCTL);
++              temp_lcs |= CCDC_LSC_TABLE2_SLC;
++              regw(temp_lcs, LSCMEMCTL);
++
++              /*Reset memory address */
++              temp_lcs = 0;
++              temp_lcs = regr(LSCMEMCTL);
++              temp_lcs |= CCDC_LSC_MEMADDR_RESET;
++              regw(temp_lcs, LSCMEMCTL);
++
++              /*Update gainfactor for table 2 - u16q14 */
++              temp_gf =
++                  (params->lens_sh_corr.gf_table2[0].
++                   int_no & CCDC_LSC_INT_MASK) << 14;
++              temp_gf |=
++                  ((int)(params->lens_sh_corr.gf_table2[0].frac_no) * 16384)
++                  & CCDC_LSC_FRAC_MASK;
++              regw(temp_gf, LSCMEMD);
++
++              while (1) {
++                      if ((regr(LSCMEMCTL) & 0x10) == 0)
++                              break;
++              }
++
++              /*set the address to incremental mode */
++              temp_lcs = 0;
++              temp_lcs = regr(LSCMEMCTL);
++              temp_lcs |= CCDC_LSC_MEMADDR_INCR;
++              regw(temp_lcs, LSCMEMCTL);
++
++              for (i = 1; i < 128; i++) {
++                      temp_gf = 0;
++                      temp_gf =
++                          (params->lens_sh_corr.gf_table2[i].
++                           int_no & CCDC_LSC_INT_MASK) << 14;
++                      temp_gf |=
++                          ((int)(params->lens_sh_corr.gf_table2[0].frac_no) *
++                           16384)
++                          & CCDC_LSC_FRAC_MASK;
++                      regw(temp_gf, LSCMEMD);
++
++                      while (1) {
++                              if ((regr(LSCMEMCTL) & 0x10) == 0)
++                                      break;
++                      }
++              }
++
++              /*UPDATE PROCEDURE FOR GAIN FACTOR TABLE 3 */
++
++              /*select table 3 */
++              temp_lcs = 0;
++              temp_lcs = regr(LSCMEMCTL);
++              temp_lcs |= CCDC_LSC_TABLE3_SLC;
++              regw(temp_lcs, LSCMEMCTL);
++
++              /*Reset memory address */
++              temp_lcs = 0;
++              temp_lcs = regr(LSCMEMCTL);
++              temp_lcs |= CCDC_LSC_MEMADDR_RESET;
++              regw(temp_lcs, LSCMEMCTL);
++
++              /*Update gainfactor for table 2 - u16q14 */
++              temp_gf =
++                  (params->lens_sh_corr.gf_table3[0].
++                   int_no & CCDC_LSC_INT_MASK) << 14;
++              temp_gf |=
++                  ((int)(params->lens_sh_corr.gf_table3[0].frac_no) * 16384)
++                  & CCDC_LSC_FRAC_MASK;
++              regw(temp_gf, LSCMEMD);
++
++              while (1) {
++                      if ((regr(LSCMEMCTL) & 0x10) == 0)
++                              break;
++              }
++
++              /*set the address to incremental mode */
++              temp_lcs = 0;
++              temp_lcs = regr(LSCMEMCTL);
++              temp_lcs |= CCDC_LSC_MEMADDR_INCR;
++              regw(temp_lcs, LSCMEMCTL);
++
++              for (i = 1; i < 128; i++) {
++                      temp_gf = 0;
++                      temp_gf =
++                          (params->lens_sh_corr.gf_table3[i].
++                           int_no & CCDC_LSC_INT_MASK) << 14;
++                      temp_gf |=
++                          ((int)(params->lens_sh_corr.gf_table3[0].frac_no) *
++                           16384)
++                          & CCDC_LSC_FRAC_MASK;
++                      regw(temp_gf, LSCMEMD);
++
++                      while (1) {
++                              if ((regr(LSCMEMCTL) & 0x10) == 0)
++                                      break;
++                      }
++              }
++              /*Configuring the optical centre of the lens */
++              regw(params->lens_sh_corr.
++                   lens_center_horz & CCDC_LSC_CENTRE_MASK, LSCH0);
++              regw(params->lens_sh_corr.
++                   lens_center_vert & CCDC_LSC_CENTRE_MASK, LSCV0);
++
++              val = 0;
++              val =
++                  ((int)(params->lens_sh_corr.horz_left_coef.frac_no * 128)) &
++                  0x7f;
++              val |= (params->lens_sh_corr.horz_left_coef.int_no & 0x01) << 7;
++              val |=
++                  (((int)(params->lens_sh_corr.horz_right_coef.frac_no * 128))
++                   & 0x7f) << 8;
++              val |=
++                  (params->lens_sh_corr.horz_right_coef.int_no & 0x01) << 15;
++              regw(val, LSCKH);
++
++              val = 0;
++              val =
++                  ((int)(params->lens_sh_corr.ver_up_coef.frac_no * 128)) &
++                  0x7f;
++              val |= (params->lens_sh_corr.ver_up_coef.int_no & 0x01) << 7;
++              val |=
++                  (((int)(params->lens_sh_corr.ver_low_coef.frac_no * 128)) &
++                   0x7f) << 8;
++              val |= (params->lens_sh_corr.ver_low_coef.int_no & 0x01) << 15;
++              regw(val, LSCKV);
++
++              /*configuring the lsc configuration register 2 */
++              temp_lcs = 0;
++              temp_lcs |=
++                  (params->lens_sh_corr.lsc_config.
++                   gf_table_scaling_fact & CCDC_LSCCFG_GFTSF_MASK) <<
++                  CCDC_LSCCFG_GFTSF_SHIFT;
++              temp_lcs |=
++                  (params->lens_sh_corr.lsc_config.
++                   gf_table_interval & CCDC_LSCCFG_GFTINV_MASK) <<
++                  CCDC_LSCCFG_GFTINV_SHIFT;
++              temp_lcs |=
++                  (params->lens_sh_corr.lsc_config.
++                   epel & CCDC_LSC_GFTABLE_SEL_MASK) <<
++                  CCDC_LSC_GFTABLE_EPEL_SHIFT;
++              temp_lcs |=
++                  (params->lens_sh_corr.lsc_config.
++                   opel & CCDC_LSC_GFTABLE_SEL_MASK) <<
++                  CCDC_LSC_GFTABLE_OPEL_SHIFT;
++              temp_lcs |=
++                  (params->lens_sh_corr.lsc_config.
++                   epol & CCDC_LSC_GFTABLE_SEL_MASK) <<
++                  CCDC_LSC_GFTABLE_EPOL_SHIFT;
++              temp_lcs |=
++                  (params->lens_sh_corr.lsc_config.
++                   opol & CCDC_LSC_GFTABLE_SEL_MASK) <<
++                  CCDC_LSC_GFTABLE_OPOL_SHIFT;
++              regw(temp_lcs, LSCCFG2);
++
++              /*configuring the LSC configuration register 1 */
++              temp_lcs = 0;
++              temp_lcs |= CCDC_LSC_ENABLE;
++              temp_lcs |= (params->lens_sh_corr.lsc_config.mode &
++                           CCDC_LSC_GFMODE_MASK) << CCDC_LSC_GFMODE_SHIFT;
++              regw(temp_lcs, LSCCFG1);
++      }
++
++      /* Configure data formatter if needed */
++      if (params->data_formatter_r.fmt_enable
++          && (!params->color_space_con.csc_enable)) {
++              dev_dbg(dev,
++                     "\ndata formatter will be configured now....\n");
++
++              /*Configuring the FMTPLEN */
++              fmtreg_v = 0;
++              fmtreg_v |=
++                  (params->data_formatter_r.plen.
++                   plen0 & CCDC_FMTPLEN_P0_MASK);
++              fmtreg_v |=
++                  ((params->data_formatter_r.plen.
++                    plen1 & CCDC_FMTPLEN_P1_MASK)
++                   << CCDC_FMTPLEN_P1_SHIFT);
++              fmtreg_v |=
++                  ((params->data_formatter_r.plen.
++                    plen2 & CCDC_FMTPLEN_P2_MASK)
++                   << CCDC_FMTPLEN_P2_SHIFT);
++              fmtreg_v |=
++                  ((params->data_formatter_r.plen.
++                    plen3 & CCDC_FMTPLEN_P3_MASK)
++                   << CCDC_FMTPLEN_P3_SHIFT);
++              regw(fmtreg_v, FMTPLEN);
++
++              /*Configurring the FMTSPH */
++              regw((params->data_formatter_r.fmtsph & CCDC_FMTSPH_MASK),
++                   FMTSPH);
++
++              /*Configurring the FMTLNH */
++              regw((params->data_formatter_r.fmtlnh & CCDC_FMTLNH_MASK),
++                   FMTLNH);
++
++              /*Configurring the FMTSLV */
++              regw((params->data_formatter_r.fmtslv & CCDC_FMTSLV_MASK),
++                   FMTSLV);
++
++              /*Configurring the FMTLNV */
++              regw((params->data_formatter_r.fmtlnv & CCDC_FMTLNV_MASK),
++                   FMTLNV);
++
++              /*Configurring the FMTRLEN */
++              regw((params->data_formatter_r.fmtrlen & CCDC_FMTRLEN_MASK),
++                   FMTRLEN);
++
++              /*Configurring the FMTHCNT */
++              regw((params->data_formatter_r.fmthcnt & CCDC_FMTHCNT_MASK),
++                   FMTHCNT);
++
++              /*Configuring the FMTADDR_PTR */
++              for (i = 0; i < 8; i++) {
++                      fmtreg_v = 0;
++
++                      if (params->data_formatter_r.addr_ptr[i].init >
++                          (params->data_formatter_r.fmtrlen - 1)) {
++                              dev_dbg(dev, "\nInvalid init parameter for"
++                                         "FMTADDR_PTR....\n");
++                              return;
++                      }
++
++                      fmtreg_v =
++                          (params->data_formatter_r.addr_ptr[i].
++                           init & CCDC_ADP_INIT_MASK);
++                      fmtreg_v |=
++                          ((params->data_formatter_r.addr_ptr[i].
++                            line & CCDC_ADP_LINE_MASK) <<
++                           CCDC_ADP_LINE_SHIFT);
++                      regw(fmtreg_v, FMT_ADDR_PTR(i));
++              }
++
++              /* Configuring the FMTPGM_VF0 */
++              fmtreg_v = 0;
++              for (i = 0; i < 16; i++)
++                      fmtreg_v |= params->data_formatter_r.pgm_en[i] << i;
++              regw(fmtreg_v, FMTPGM_VF0);
++
++              /* Configuring the FMTPGM_VF1 */
++              fmtreg_v = 0;
++              for (i = 16; i < 32; i++) {
++                      fmtreg_v |=
++                          params->data_formatter_r.pgm_en[i] << (i - 16);
++              }
++              regw(fmtreg_v, FMTPGM_VF1);
++
++              /* Configuring the FMTPGM_AP0 */
++              fmtreg_v = 0;
++              shift_v = 0;
++              for (i = 0; i < 4; i++) {
++                      fmtreg_v |=
++                          ((params->data_formatter_r.pgm_ap[i].
++                            pgm_aptr & CCDC_FMTPGN_APTR_MASK) << shift_v);
++                      fmtreg_v |=
++                          (params->data_formatter_r.pgm_ap[i].
++                           pgmupdt << (shift_v + 3));
++                      shift_v += 4;
++              }
++              regw(fmtreg_v, FMTPGM_AP0);
++
++              /* Configuring the FMTPGM_AP1 */
++              fmtreg_v = 0;
++              shift_v = 0;
++              for (i = 4; i < 8; i++) {
++                      fmtreg_v |=
++                          ((params->data_formatter_r.pgm_ap[i].
++                            pgm_aptr & CCDC_FMTPGN_APTR_MASK) << shift_v);
++                      fmtreg_v |=
++                          (params->data_formatter_r.pgm_ap[i].
++                           pgmupdt << (shift_v + 3));
++                      shift_v += 4;
++              }
++              regw(fmtreg_v, FMTPGM_AP1);
++
++              /* Configuring the FMTPGM_AP2 */
++              fmtreg_v = 0;
++              shift_v = 0;
++              for (i = 8; i < 12; i++) {
++                      fmtreg_v |=
++                          ((params->data_formatter_r.pgm_ap[i].
++                            pgm_aptr & CCDC_FMTPGN_APTR_MASK) << shift_v);
++                      fmtreg_v |=
++                          (params->data_formatter_r.pgm_ap[i].
++                           pgmupdt << (shift_v + 3));
++                      shift_v += 4;
++              }
++              regw(fmtreg_v, FMTPGM_AP2);
++
++              /* Configuring the FMTPGM_AP3 */
++              fmtreg_v = 0;
++              shift_v = 0;
++              for (i = 12; i < 16; i++) {
++                      fmtreg_v |=
++                          ((params->data_formatter_r.pgm_ap[i].
++                            pgm_aptr & CCDC_FMTPGN_APTR_MASK) << shift_v);
++                      fmtreg_v |=
++                          (params->data_formatter_r.pgm_ap[i].
++                           pgmupdt << (shift_v + 3));
++                      shift_v += 4;
++              }
++              regw(fmtreg_v, FMTPGM_AP3);
++
++              /* Configuring the FMTPGM_AP4 */
++              fmtreg_v = 0;
++              shift_v = 0;
++              for (i = 16; i < 20; i++) {
++                      fmtreg_v |=
++                          ((params->data_formatter_r.pgm_ap[i].
++                            pgm_aptr & CCDC_FMTPGN_APTR_MASK) << shift_v);
++                      fmtreg_v |=
++                          (params->data_formatter_r.pgm_ap[i].
++                           pgmupdt << (shift_v + 3));
++                      shift_v += 4;
++              }
++              regw(fmtreg_v, FMTPGM_AP4);
++
++              /* Configuring the FMTPGM_AP5 */
++              fmtreg_v = 0;
++              shift_v = 0;
++              for (i = 20; i < 24; i++) {
++                      fmtreg_v |=
++                          ((params->data_formatter_r.pgm_ap[i].
++                            pgm_aptr & CCDC_FMTPGN_APTR_MASK) << shift_v);
++                      fmtreg_v |=
++                          (params->data_formatter_r.pgm_ap[i].
++                           pgmupdt << (shift_v + 3));
++                      shift_v += 4;
++              }
++              regw(fmtreg_v, FMTPGM_AP5);
++
++              /* Configuring the FMTPGM_AP6 */
++              fmtreg_v = 0;
++              shift_v = 0;
++              for (i = 24; i < 28; i++) {
++                      fmtreg_v |=
++                          ((params->data_formatter_r.pgm_ap[i].
++                            pgm_aptr & CCDC_FMTPGN_APTR_MASK) << shift_v);
++                      fmtreg_v |=
++                          (params->data_formatter_r.pgm_ap[i].
++                           pgmupdt << (shift_v + 3));
++                      shift_v += 4;
++              }
++              regw(fmtreg_v, FMTPGM_AP6);
++
++              /* Configuring the FMTPGM_AP7 */
++              fmtreg_v = 0;
++              shift_v = 0;
++              for (i = 28; i < 32; i++) {
++                      fmtreg_v |=
++                          ((params->data_formatter_r.pgm_ap[i].
++                            pgm_aptr & CCDC_FMTPGN_APTR_MASK) << shift_v);
++                      fmtreg_v |=
++                          (params->data_formatter_r.pgm_ap[i].
++                           pgmupdt << (shift_v + 3));
++                      shift_v += 4;
++              }
++              regw(fmtreg_v, FMTPGM_AP7);
++
++              /* Configuring the FMTCFG register */
++              fmtreg_v = 0;
++              fmtreg_v = CCDC_DF_ENABLE;
++              fmtreg_v |=
++                  ((params->data_formatter_r.cfg.
++                    mode & CCDC_FMTCFG_FMTMODE_MASK)
++                   << CCDC_FMTCFG_FMTMODE_SHIFT);
++              fmtreg_v |=
++                  ((params->data_formatter_r.cfg.
++                    lnum & CCDC_FMTCFG_LNUM_MASK)
++                   << CCDC_FMTCFG_LNUM_SHIFT);
++              fmtreg_v |=
++                  ((params->data_formatter_r.cfg.
++                    addrinc & CCDC_FMTCFG_ADDRINC_MASK)
++                   << CCDC_FMTCFG_ADDRINC_SHIFT);
++              regw(fmtreg_v, FMTCFG);
++
++      } else if (params->data_formatter_r.fmt_enable) {
++              dev_dbg(dev,
++                     "\nCSC and Data Formatter Enabled at same time....\n");
++      }
++
++      /*
++       *      C O N F I G U R E   C O L O R   S P A C E   C O N V E R T E R
++       */
++
++      if ((params->color_space_con.csc_enable)
++          && (!params->data_formatter_r.fmt_enable)) {
++              dev_dbg(dev, "\nconfiguring the CSC Now....\n");
++
++              /* Enable the CSC sub-module */
++              regw(CCDC_CSC_ENABLE, CSCCTL);
++
++              /* Converting the co-eff as per the format of the register */
++              for (i = 0; i < 16; i++) {
++                      temp1 = params->color_space_con.csc_dec_coeff[i];
++                      /* Masking the data for 3 bits */
++                      temp1 &= CCDC_CSC_COEFF_DEC_MASK;
++                      /* Recovering the fractional part and converting to
++                       * binary of 5 bits
++                       */
++                      temp2 =
++                          (int)(params->color_space_con.csc_frac_coeff[i] *
++                                (32 / 10));
++                      temp2 &= CCDC_CSC_COEFF_FRAC_MASK;
++                      /* shifting the decimal to the MSB */
++                      temp1 = temp1 << CCDC_CSC_DEC_SHIFT;
++                      temp1 |= temp2;
++                      params->color_space_con.csc_dec_coeff[i] = temp1;
++              }
++              regw(params->color_space_con.csc_dec_coeff[0], CSCM0);
++              regw(params->color_space_con.
++                   csc_dec_coeff[1] << CCDC_CSC_COEFF_SHIFT, CSCM0);
++              regw(params->color_space_con.csc_dec_coeff[2], CSCM1);
++              regw(params->color_space_con.
++                   csc_dec_coeff[3] << CCDC_CSC_COEFF_SHIFT, CSCM1);
++              regw(params->color_space_con.csc_dec_coeff[4], CSCM2);
++              regw(params->color_space_con.
++                   csc_dec_coeff[5] << CCDC_CSC_COEFF_SHIFT, CSCM2);
++              regw(params->color_space_con.csc_dec_coeff[6], CSCM3);
++              regw(params->color_space_con.
++                   csc_dec_coeff[7] << CCDC_CSC_COEFF_SHIFT, CSCM3);
++              regw(params->color_space_con.csc_dec_coeff[8], CSCM4);
++              regw(params->color_space_con.
++                   csc_dec_coeff[9] << CCDC_CSC_COEFF_SHIFT, CSCM4);
++              regw(params->color_space_con.csc_dec_coeff[10], CSCM5);
++              regw(params->color_space_con.
++                   csc_dec_coeff[11] << CCDC_CSC_COEFF_SHIFT, CSCM5);
++              regw(params->color_space_con.csc_dec_coeff[12], CSCM6);
++              regw(params->color_space_con.
++                   csc_dec_coeff[13] << CCDC_CSC_COEFF_SHIFT, CSCM6);
++              regw(params->color_space_con.csc_dec_coeff[14], CSCM7);
++              regw(params->color_space_con.
++                   csc_dec_coeff[15] << CCDC_CSC_COEFF_SHIFT, CSCM7);
++
++      } else if (params->color_space_con.csc_enable) {
++              dev_dbg(dev,
++                     "\nCSC and Data Formatter Enabled at same time....\n");
++      }
++
++      /* Configure the Gain  & offset control */
++      ccdc_config_gain_offset();
++
++      /*
++       *      C O N F I G U R E  C O L O R  P A T T E R N  A S
++       *      P E R  N N 1 2 8 6 A  S E N S O R
++       */
++
++      val = (params->col_pat_field0.olop);
++      val |= (params->col_pat_field0.olep << 2);
++      val |= (params->col_pat_field0.elop << 4);
++      val |= (params->col_pat_field0.elep << 6);
++      val |= (params->col_pat_field1.olop << 8);
++      val |= (params->col_pat_field1.olep << 10);
++      val |= (params->col_pat_field1.elop << 12);
++      val |= (params->col_pat_field1.elep << 14);
++      regw(val, COLPTN);
++
++      dev_dbg(dev, "\nWriting %x to COLPTN...\n", val);
++
++      /*
++       *      C O N F I G U R I N G  T H E  H S I Z E  R E G I S T E R
++       */
++      val = 0;
++      val |=
++          (params->data_offset_s.
++           horz_offset & CCDC_DATAOFST_MASK) << CCDC_DATAOFST_H_SHIFT;
++      val |=
++          (params->data_offset_s.
++           vert_offset & CCDC_DATAOFST_MASK) << CCDC_DATAOFST_V_SHIFT;
++      regw(val, DATAOFST);
++
++      /*
++       *      C O N F I G U R I N G  T H E  H S I Z E  R E G I S T E R
++       */
++      val = 0;
++      val |=
++          (params->
++           horz_flip_enable & CCDC_HSIZE_FLIP_MASK) << CCDC_HSIZE_FLIP_SHIFT;
++
++      /* If pack 8 is enable then 1 pixel will take 1 byte */
++      if ((params->data_sz == _8BITS) || params->alaw.b_alaw_enable) {
++              val |= (((params->win.width) + 31) >> 5) & 0x0fff;
++
++              dev_dbg(dev, "\nWriting 0x%x to HSIZE...\n",
++                     (((params->win.width) + 31) >> 5) & 0x0fff);
++      } else {
++              /* else one pixel will take 2 byte */
++              val |= (((params->win.width * 2) + 31) >> 5) & 0x0fff;
++
++              dev_dbg(dev, "\nWriting 0x%x to HSIZE...\n",
++                     (((params->win.width * 2) + 31) >> 5) & 0x0fff);
++      }
++      regw(val, HSIZE);
++
++      /*
++       *      C O N F I G U R E   S D O F S T  R E G I S T E R
++       */
++
++      if (params->frm_fmt == CCDC_FRMFMT_INTERLACED) {
++              if (params->image_invert_enable) {
++                      /* For interlace inverse mode */
++                      regw(0x4B6D, SDOFST);
++                      dev_dbg(dev, "\nWriting 0x4B6D to SDOFST...\n");
++              }
++
++              else {
++                      /* For interlace non inverse mode */
++                      regw(0x0B6D, SDOFST);
++                      dev_dbg(dev, "\nWriting 0x0B6D to SDOFST...\n");
++              }
++      } else if (params->frm_fmt == CCDC_FRMFMT_PROGRESSIVE) {
++              if (params->image_invert_enable) {
++                      /* For progessive inverse mode */
++                      regw(0x4000, SDOFST);
++                      dev_dbg(dev, "\nWriting 0x4000 to SDOFST...\n");
++              }
++
++              else {
++                      /* For progessive non inverse mode */
++                      regw(0x0000, SDOFST);
++                      dev_dbg(dev, "\nWriting 0x0000 to SDOFST...\n");
++              }
++
++      }
++
++      /*
++       *      C O N F I G U R E   I N T E R R U P T   R E G I S T E R S
++       */
++      if (params->frm_fmt == CCDC_FRMFMT_PROGRESSIVE) {
++              val = params->win.height / 2;
++              regw(136, VDINT0);
++              regw(149, VDINT0);
++              regw(0, VDINT1);
++      } else {
++              regw(0, VDINT0);
++              regw(0, VDINT1);
++      }
++
++      dev_dbg(dev, "\nend of ccdc_config_raw...");
++}
++
++static int ccdc_configure(void)
++{
++      if (ccdc_if_type == VPFE_RAW_BAYER) {
++              dev_info(dev, "calling ccdc_config_raw()\n");
++              ccdc_config_raw();
++      } else {
++              dev_info(dev, "calling ccdc_config_ycbcr()\n");
++              ccdc_config_ycbcr();
++      }
++      return 0;
++}
++
++static int ccdc_set_buftype(enum ccdc_buftype buf_type)
++{
++      if (ccdc_if_type == VPFE_RAW_BAYER)
++              ccdc_hw_params_raw.buf_type = buf_type;
++      else
++              ccdc_hw_params_ycbcr.buf_type = buf_type;
++      return 0;
++}
++static int ccdc_get_buftype(enum ccdc_buftype *buf_type)
++{
++      if (ccdc_if_type == VPFE_RAW_BAYER)
++              *buf_type = ccdc_hw_params_raw.buf_type;
++      else
++              *buf_type = ccdc_hw_params_ycbcr.buf_type;
++      return 0;
++}
++
++static int ccdc_enum_pix(enum vpfe_hw_pix_format *hw_pix, int i)
++{
++      int ret = -EINVAL;
++      if (ccdc_if_type == VPFE_RAW_BAYER) {
++              if (i < CCDC_MAX_RAW_BAYER_FORMATS) {
++                      *hw_pix = ccdc_raw_bayer_hw_formats[i];
++                      ret = 0;
++              }
++      } else {
++              if (i < CCDC_MAX_RAW_YUV_FORMATS) {
++                      *hw_pix = ccdc_raw_yuv_hw_formats[i];
++                      ret = 0;
++              }
++      }
++      return ret;
++}
++
++static int ccdc_set_pixel_format(enum vpfe_hw_pix_format pixfmt)
++{
++      if (ccdc_if_type == VPFE_RAW_BAYER) {
++              ccdc_hw_params_raw.pix_fmt = CCDC_PIXFMT_RAW;
++              if (pixfmt == VPFE_BAYER_8BIT_PACK_ALAW)
++                      ccdc_hw_params_raw.alaw.b_alaw_enable = 1;
++              else if (pixfmt != VPFE_BAYER)
++                      return -1;
++      } else {
++              if (pixfmt == VPFE_YUYV)
++                      ccdc_hw_params_ycbcr.pix_order = CCDC_PIXORDER_YCBYCR;
++              else if (pixfmt == VPFE_UYVY)
++                      ccdc_hw_params_ycbcr.pix_order = CCDC_PIXORDER_CBYCRY;
++              else
++                      return -1;
++      }
++      return 0;
++}
++static int ccdc_get_pixel_format(enum vpfe_hw_pix_format *pixfmt)
++{
++      if (ccdc_if_type == VPFE_RAW_BAYER)
++              if (ccdc_hw_params_raw.alaw.b_alaw_enable)
++                      *pixfmt = VPFE_BAYER_8BIT_PACK_ALAW;
++              else
++                      *pixfmt = VPFE_BAYER;
++      else {
++              if (ccdc_hw_params_ycbcr.pix_order == CCDC_PIXORDER_YCBYCR)
++                      *pixfmt = VPFE_YUYV;
++              else
++                      *pixfmt = VPFE_UYVY;
++      }
++      return 0;
++}
++static int ccdc_set_image_window(struct v4l2_rect *win)
++{
++      if (ccdc_if_type == VPFE_RAW_BAYER) {
++              ccdc_hw_params_raw.win.top = win->top;
++              ccdc_hw_params_raw.win.left = win->left;
++              ccdc_hw_params_raw.win.width = win->width;
++              ccdc_hw_params_raw.win.height = win->height;
++      } else {
++              ccdc_hw_params_ycbcr.win.top = win->top;
++              ccdc_hw_params_ycbcr.win.left = win->left;
++              ccdc_hw_params_ycbcr.win.width = win->width;
++              ccdc_hw_params_ycbcr.win.height = win->height;
++      }
++      return 0;
++}
++static int ccdc_get_image_window(struct v4l2_rect *win)
++{
++      if (ccdc_if_type == VPFE_RAW_BAYER) {
++              win->top = ccdc_hw_params_raw.win.top;
++              win->left = ccdc_hw_params_raw.win.left;
++              win->width = ccdc_hw_params_raw.win.width;
++              win->height = ccdc_hw_params_raw.win.height;
++      } else {
++              win->top = ccdc_hw_params_ycbcr.win.top;
++              win->left = ccdc_hw_params_ycbcr.win.left;
++              win->width = ccdc_hw_params_ycbcr.win.width;
++              win->height = ccdc_hw_params_ycbcr.win.height;
++      }
++      return 0;
++}
++static int ccdc_get_line_length(unsigned int *len)
++{
++      if (ccdc_if_type == VPFE_RAW_BAYER) {
++              if ((ccdc_hw_params_raw.alaw.b_alaw_enable) ||
++                  (ccdc_hw_params_raw.data_sz == _8BITS)) {
++                      *len = ccdc_hw_params_raw.win.width;
++              } else {
++                      *len = ccdc_hw_params_raw.win.width * 2;
++              }
++      } else {
++              *len = ccdc_hw_params_ycbcr.win.width * 2;
++      }
++      *len = ((*len + 31) & ~0x1f);
++      return 0;
++}
++
++static int ccdc_set_frame_format(enum ccdc_frmfmt frm_fmt)
++{
++      if (ccdc_if_type == VPFE_RAW_BAYER)
++              ccdc_hw_params_raw.frm_fmt = frm_fmt;
++      else
++              ccdc_hw_params_ycbcr.frm_fmt = frm_fmt;
++      return 0;
++}
++static int ccdc_get_frame_format(enum ccdc_frmfmt *frm_fmt)
++{
++      if (ccdc_if_type == VPFE_RAW_BAYER)
++              *frm_fmt = ccdc_hw_params_raw.frm_fmt;
++      else
++              *frm_fmt = ccdc_hw_params_ycbcr.frm_fmt;
++      return 0;
++}
++
++static int ccdc_getfid(void)
++{
++      int fid = (regr(MODESET) >> 15) & 0x1;
++      return fid;
++}
++
++/* misc operations */
++static inline void ccdc_setfbaddr(unsigned long addr)
++{
++      regw((addr >> 21) & 0x007f, STADRH);
++      regw((addr >> 5) & 0x0ffff, STADRL);
++}
++
++static int ccdc_set_hw_if_type(enum vpfe_hw_if_type iface)
++{
++      ccdc_if_type = iface;
++      return 0;
++}
++
++struct ccdc_hw_device ccdc_hw_dev = {
++      .name = "DM355 CCDC",
++      .set_ccdc_base = ccdc_set_ccdc_base,
++      .set_vpss_base = ccdc_set_vpss_base,
++      .get_ccdc_base = ccdc_get_ccdc_base,
++      .get_vpss_base = ccdc_get_vpss_base,
++      .open = ccdc_open,
++      .enable = ccdc_enable,
++      .enable_out_to_sdram = ccdc_enable_output_to_sdram,
++      .set_hw_if_type = ccdc_set_hw_if_type,
++      .setparams = ccdc_setparams,
++      .configure = ccdc_configure,
++      .set_buftype = ccdc_set_buftype,
++      .get_buftype = ccdc_get_buftype,
++      .enum_pix = ccdc_enum_pix,
++      .set_pixelformat = ccdc_set_pixel_format,
++      .get_pixelformat = ccdc_get_pixel_format,
++      .set_frame_format = ccdc_set_frame_format,
++      .get_frame_format = ccdc_get_frame_format,
++      .set_image_window = ccdc_set_image_window,
++      .get_image_window = ccdc_get_image_window,
++      .get_line_length = ccdc_get_line_length,
++      .queryctrl = ccdc_queryctrl,
++      .setcontrol = ccdc_setcontrol,
++      .getcontrol = ccdc_getcontrol,
++      .setfbaddr = ccdc_setfbaddr,
++      .getfid = ccdc_getfid,
++};
++EXPORT_SYMBOL(ccdc_hw_dev);
++
++static int dm355_ccdc_init(void)
++{
++      return 0;
++}
++
++static void dm355_ccdc_exit(void)
++{
++}
++
++subsys_initcall(dm355_ccdc_init);
++module_exit(dm355_ccdc_exit);
++
++MODULE_LICENSE("GPL");
+diff --git a/drivers/media/video/davinci/ccdc_dm355.h b/drivers/media/video/davinci/ccdc_dm355.h
+new file mode 100644
+index 0000000..a78349a
+--- /dev/null
++++ b/drivers/media/video/davinci/ccdc_dm355.h
+@@ -0,0 +1,758 @@
++/*
++ * Copyright (C) 2005-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
++ */
++#ifndef _CCDC_DM355_H
++#define _CCDC_DM355_H
++#include <media/davinci/ccdc_common.h>
++
++/* Define to enable/disable video port */
++
++#define CCDC_WIN_PAL  {0, 0, 720, 576}
++#define CCDC_WIN_VGA  {0, 0, 640, 480}
++
++/* enum for No of pixel per line to be avg. in Black Clamping*/
++enum sample_length {
++      _1PIXELS,
++      _2PIXELS,
++      _4PIXELS,
++      _8PIXELS,
++      _16PIXELS
++};
++
++/* enum for No of lines in Black Clamping */
++enum sample_line {
++      _1LINES,
++      _2LINES,
++      _4LINES,
++      _8LINES,
++      _16LINES
++};
++
++/* enum for Alaw gama width */
++enum gama_width {
++      BITS_13_4,
++      BITS_12_3,
++      BITS_11_2,
++      BITS_10_1,
++      BITS_09_0
++};
++
++enum ccdc_colpats {
++      CCDC_RED,
++      CCDC_GREEN_RED,
++      CCDC_GREEN_BLUE,
++      CCDC_BLUE
++};
++
++struct ccdc_col_pat {
++      enum ccdc_colpats olop;
++      enum ccdc_colpats olep;
++      enum ccdc_colpats elop;
++      enum ccdc_colpats elep;
++};
++
++enum ccdc_datasft {
++      NO_SHIFT,
++      _1BIT,
++      _2BIT,
++      _3BIT,
++      _4BIT,
++      _5BIT,
++      _6BIT
++};
++
++enum data_size {
++      _16BITS,
++      _15BITS,
++      _14BITS,
++      _13BITS,
++      _12BITS,
++      _11BITS,
++      _10BITS,
++      _8BITS
++};
++enum ccdc_mfilt1 {
++      NO_MEDIAN_FILTER1,
++      AVERAGE_FILTER1,
++      MEDIAN_FILTER1
++};
++
++enum ccdc_mfilt2 {
++      NO_MEDIAN_FILTER2 = 0,
++      AVERAGE_FILTER2,
++      MEDIAN_FILTER2
++};
++
++struct ccdc_imgwin {
++      unsigned int top;
++      unsigned int left;
++      unsigned int width;
++      unsigned int height;
++};
++
++/* structure for ALaw */
++struct ccdc_a_law {
++      /* Enable/disable A-Law */
++      unsigned char b_alaw_enable;
++      /*Gama Width Input */
++      enum gama_width gama_wd;
++};
++
++/* structure for Black Clamping */
++struct ccdc_black_clamp {
++      /* only if bClampEnable is TRUE */
++      unsigned char b_clamp_enable;
++      /* only if bClampEnable is TRUE */
++      enum sample_length sample_pixel;
++      /* only if bClampEnable is TRUE */
++      enum sample_line sample_ln;
++      /* only if bClampEnable is TRUE */
++      unsigned short start_pixel;
++      /* only if bClampEnable is FALSE */
++      unsigned short sgain;
++      unsigned short dc_sub;
++};
++
++/* structure for Black Level Compensation */
++struct black_compensation {
++      /* Constant value to subtract from Red component */
++      unsigned char r_comp;
++      /* Constant value to subtract from Gr component */
++      unsigned char gr_comp;
++      /* Constant value to subtract from Blue component */
++      unsigned char b_comp;
++      /* Constant value to subtract from Gb component */
++      unsigned char gb_comp;
++};
++
++/*structures for lens shading correction*/
++
++/*gain factor modes*/
++enum gfmode {
++      u8q8_interpol,
++      u16q14_interpol,
++      reserved,
++      u16q14
++};
++
++enum gf_table_sel {
++      table1 = 0,
++      table2,
++      table3
++};
++
++/*LSC configuration structure*/
++struct lsccfg {
++      enum gfmode mode;
++      int gf_table_scaling_fact;
++      int gf_table_interval;
++      enum gf_table_sel epel;
++      enum gf_table_sel opel;
++      enum gf_table_sel epol;
++      enum gf_table_sel opol;
++};
++
++struct float_ccdc {
++      unsigned int int_no;
++      unsigned int frac_no;
++};
++
++/*Main structure for lens shading correction*/
++struct lens_shading_corr {
++      unsigned char lsc_enable;
++      struct lsccfg lsc_config;
++      unsigned int lens_center_horz;
++      unsigned int lens_center_vert;
++      struct float_ccdc horz_left_coef;
++      struct float_ccdc horz_right_coef;
++      struct float_ccdc ver_low_coef;
++      struct float_ccdc ver_up_coef;
++      struct float_ccdc gf_table1[256];
++      /*int_no will be always 0 since it is u8q8 */
++      struct float_ccdc gf_table2[128];
++      struct float_ccdc gf_table3[128];
++};
++
++/*structure for color space converter*/
++struct color_space_converter {
++      unsigned char csc_enable;
++      int csc_dec_coeff[16];
++      int csc_frac_coeff[16];
++};
++
++/*supporting structures for data formatter*/
++enum fmtmode {
++      split,
++      combine,
++      line_alt_mode
++};
++
++enum line_num {
++      _1line,
++      _2lines,
++      _3lines,
++      _4lines
++};
++
++enum line_pos {
++      _1stline,
++      _2ndline,
++      _3rdline,
++      _4thline
++};
++
++struct fmtplen {
++      unsigned int plen0;
++      unsigned int plen1;
++      unsigned int plen2;
++      unsigned int plen3;
++};
++
++struct fmtcfg {
++      enum fmtmode mode;
++      enum line_num lnum;
++      unsigned int addrinc;
++};
++
++struct fmtaddr_ptr {
++      unsigned int init;
++      enum line_pos line;
++};
++
++struct fmtpgm_ap {
++      unsigned int pgm_aptr;
++      unsigned char pgmupdt;
++};
++
++/* Main Structure for data formatter*/
++struct data_formatter {
++      unsigned char fmt_enable;
++      struct fmtcfg cfg;
++      struct fmtplen plen;
++      unsigned int fmtsph;
++      unsigned int fmtlnh;
++      unsigned int fmtslv;
++      unsigned int fmtlnv;
++      unsigned int fmtrlen;
++      unsigned int fmthcnt;
++      struct fmtaddr_ptr addr_ptr[8];
++      unsigned char pgm_en[32];
++      struct fmtpgm_ap pgm_ap[32];
++};
++
++/* Structures for Vertical Defect Correction*/
++enum vdf_csl {
++      normal = 0,
++      horz_interpol_sat,
++      horz_interpol
++};
++
++enum vdf_cuda {
++      whole_line_correct,
++      upper_disable
++};
++
++enum dfc_mwr {
++      write_complete,
++      write_reg
++};
++
++enum dfc_mrd {
++      read_complete,
++      read_reg
++};
++
++enum dfc_ma_rst {
++      incr_addr,
++      clr_addr
++};
++
++enum dfc_mclr {
++      clear_complete,
++      clear
++};
++
++struct dft_corr_ctl_s {
++      enum vdf_csl vdfcsl;
++      enum vdf_cuda vdfcuda;
++      unsigned int vdflsft;
++};
++
++struct dft_corr_mem_ctl_s {
++      enum dfc_mwr dfcmwr;
++      enum dfc_mrd dfcmrd;
++      enum dfc_ma_rst dfcmarst;
++      enum dfc_mclr dfcmclr;
++};
++
++/* Main Structure for vertical defect correction. Vertical defect
++ * correction can correct upto 16 defects if defects less than 16
++ * then pad the rest with 0
++ */
++struct vertical_dft_s {
++      unsigned char ver_dft_en;
++      unsigned char gen_dft_en;
++      unsigned int saturation_ctl;
++      struct dft_corr_ctl_s dft_corr_ctl;
++      struct dft_corr_mem_ctl_s dft_corr_mem_ctl;
++      unsigned int dft_corr_horz[16];
++      unsigned int dft_corr_vert[16];
++      unsigned int dft_corr_sub1[16];
++      unsigned int dft_corr_sub2[16];
++      unsigned int dft_corr_sub3[16];
++};
++
++struct data_offset {
++      unsigned char horz_offset;
++      unsigned char vert_offset;
++};
++
++/* Structure for CCDC configuration parameters for raw capture mode passed
++ * by application
++ */
++struct ccdc_config_params_raw {
++      /* pixel format */
++      enum ccdc_pixfmt pix_fmt;
++      /* progressive or interlaced frame */
++      enum ccdc_frmfmt frm_fmt;
++      /* video window */
++      struct ccdc_imgwin win;
++      /* field id polarity */
++      enum ccdc_pinpol fid_pol;
++      /* vertical sync polarity */
++      enum ccdc_pinpol vd_pol;
++      /* horizontal sync polarity */
++      enum ccdc_pinpol hd_pol;
++      /* interleaved or separated fields */
++      enum ccdc_buftype buf_type;
++      /*data shift to be applied before storing */
++      enum ccdc_datasft datasft;
++      /*median filter for sdram */
++      enum ccdc_mfilt1 mfilt1;
++      enum ccdc_mfilt2 mfilt2;
++      /*median filter for ipipe */
++      /*low pass filter enable/disable */
++      unsigned char lpf_enable;
++      unsigned char horz_flip_enable;
++      /*offset value to be applied to data */
++      /*Range is 0 to 1023 */
++      unsigned int ccdc_offset;
++      /*Threshold of median filter */
++      int med_filt_thres;
++      /* enable to store the image in inverse */
++      unsigned char image_invert_enable;
++      /* data size value from 8 to 16 bits */
++      enum data_size data_sz;
++      /*horz and vertical data offset */
++      struct data_offset data_offset_s;
++      /* Structure for Optional A-Law */
++      struct ccdc_a_law alaw;
++      /* Structure for Optical Black Clamp */
++      struct ccdc_black_clamp blk_clamp;
++      /* Structure for Black Compensation */
++      struct black_compensation blk_comp;
++      /*struture for vertical Defect Correction Module Configuration */
++      struct vertical_dft_s vertical_dft;
++      /*structure for lens shading Correction Module Configuration */
++      struct lens_shading_corr lens_sh_corr;
++      /*structure for data formatter Module Configuration */
++      struct data_formatter data_formatter_r;
++      /*structure for color space converter Module Configuration */
++      struct color_space_converter color_space_con;
++      struct ccdc_col_pat col_pat_field0;
++      struct ccdc_col_pat col_pat_field1;
++};
++
++#ifdef __KERNEL__
++#include <linux/io.h>
++/* SOC specific controls for Bayer capture. The CIDs
++ * listed here should match with that in davinci_vpfe.h
++ */
++/* White balance on Bayer RGB. U11Q8 */
++#define CCDC_CID_R_GAIN               (V4L2_CID_PRIVATE_BASE + 0)
++#define CCDC_CID_GR_GAIN      (V4L2_CID_PRIVATE_BASE + 1)
++#define CCDC_CID_GB_GAIN      (V4L2_CID_PRIVATE_BASE + 2)
++#define CCDC_CID_B_GAIN       (V4L2_CID_PRIVATE_BASE + 3)
++/* Offsets */
++#define CCDC_CID_OFFSET       (V4L2_CID_PRIVATE_BASE + 4)
++#define CCDC_CID_MAX          (V4L2_CID_PRIVATE_BASE + 5)
++#define CCDC_MAX_CONTROLS 5
++
++/* Gain applied to Raw Bayer data */
++struct ccdc_gain {
++      unsigned short r_ye;
++      unsigned short gr_cy;
++      unsigned short gb_g;
++      unsigned short b_mg;
++};
++
++/* Structure for CCDC configuration parameters for raw capture mode */
++struct ccdc_params_raw {
++      /* pixel format */
++      enum ccdc_pixfmt pix_fmt;
++      /* progressive or interlaced frame */
++      enum ccdc_frmfmt frm_fmt;
++      /* video window */
++      struct ccdc_imgwin win;
++      /* field id polarity */
++      enum ccdc_pinpol fid_pol;
++      /* vertical sync polarity */
++      enum ccdc_pinpol vd_pol;
++      /* horizontal sync polarity */
++      enum ccdc_pinpol hd_pol;
++      /* interleaved or separated fields */
++      enum ccdc_buftype buf_type;
++      /*data shift to be applied before storing */
++      enum ccdc_datasft datasft;
++      /*median filter for sdram */
++      enum ccdc_mfilt1 mfilt1;
++      /*median filter for ipipe */
++      enum ccdc_mfilt2 mfilt2;
++      /*low pass filter enable/disable */
++      unsigned char lpf_enable;
++      unsigned char horz_flip_enable;
++      /*offset value to be applied to data */
++      /*Range is 0 to 1023 */
++      unsigned int ccdc_offset;
++      /* Gain values */
++      struct ccdc_gain gain;
++      /*Threshold of median filter */
++      int med_filt_thres;
++      /* enable to store the image in inverse order in memory
++       * (bottom to top)
++       */
++      unsigned char image_invert_enable;
++      /* data size value from 8 to 16 bits */
++      enum data_size data_sz;
++      /* Structure for Optional A-Law */
++      struct ccdc_a_law alaw;
++      /*horz and vertical data offset */
++      struct data_offset data_offset_s;
++      /* Structure for Optical Black Clamp */
++      struct ccdc_black_clamp blk_clamp;
++      /* Structure for Black Compensation */
++      struct black_compensation blk_comp;
++      /*struture for vertical Defect Correction Module Configuration */
++      struct vertical_dft_s vertical_dft;
++      /*structure for lens shading Correction Module Configuration */
++      struct lens_shading_corr lens_sh_corr;
++      /*structure for data formatter Module Configuration */
++      struct data_formatter data_formatter_r;
++      /*structure for color space converter Module Configuration */
++      struct color_space_converter color_space_con;
++      struct ccdc_col_pat col_pat_field0;
++      struct ccdc_col_pat col_pat_field1;
++};
++
++struct ccdc_params_ycbcr {
++      /* pixel format */
++      enum ccdc_pixfmt pix_fmt;
++      /* progressive or interlaced frame */
++      enum ccdc_frmfmt frm_fmt;
++      /* video window */
++      struct ccdc_imgwin win;
++      /* field id polarity */
++      enum ccdc_pinpol fid_pol;
++      /* vertical sync polarity */
++      enum ccdc_pinpol vd_pol;
++      /* horizontal sync polarity */
++      enum ccdc_pinpol hd_pol;
++      /* enable BT.656 embedded sync mode */
++      int bt656_enable;
++      /* cb:y:cr:y or y:cb:y:cr in memory */
++      enum ccdc_pixorder pix_order;
++      /* interleaved or separated fields  */
++      enum ccdc_buftype buf_type;
++};
++
++struct ccdc_supported_pix_fmt {
++      int index;
++      unsigned int pix_fmt;
++};
++
++/**************************************************************************\
++* Register OFFSET Definitions
++\**************************************************************************/
++#define SYNCEN                                0x00
++#define MODESET                               0x04
++#define HDWIDTH                               0x08
++#define VDWIDTH                               0x0c
++#define PPLN                          0x10
++#define LPFR                          0x14
++#define SPH                           0x18
++#define NPH                           0x1c
++#define SLV0                          0x20
++#define SLV1                          0x24
++#define NLV                           0x28
++#define CULH                          0x2c
++#define CULV                          0x30
++#define HSIZE                         0x34
++#define SDOFST                                0x38
++#define STADRH                                0x3c
++#define STADRL                                0x40
++#define CLAMP                         0x44
++#define DCSUB                         0x48
++#define COLPTN                                0x4c
++#define BLKCMP0                               0x50
++#define BLKCMP1                               0x54
++#define MEDFILT                               0x58
++#define RYEGAIN                               0x5c
++#define GRCYGAIN                      0x60
++#define GBGGAIN                               0x64
++#define BMGGAIN                               0x68
++#define OFFSET                                0x6c
++#define OUTCLIP                               0x70
++#define VDINT0                                0x74
++#define VDINT1                                0x78
++#define RSV0                          0x7c
++#define GAMMAWD                               0x80
++#define REC656IF                      0x84
++#define CCDCFG                                0x88
++#define FMTCFG                                0x8c
++#define FMTPLEN                               0x90
++#define FMTSPH                                0x94
++#define FMTLNH                                0x98
++#define FMTSLV                                0x9c
++#define FMTLNV                                0xa0
++#define FMTRLEN                               0xa4
++#define FMTHCNT                               0xa8
++#define FMT_ADDR_PTR_B                        0xac
++#define FMT_ADDR_PTR(i)                       (FMT_ADDR_PTR_B + (i*4))
++#define FMTPGM_VF0                    0xcc
++#define FMTPGM_VF1                    0xd0
++#define FMTPGM_AP0                    0xd4
++#define FMTPGM_AP1                    0xd8
++#define FMTPGM_AP2                    0xdc
++#define FMTPGM_AP3                      0xe0
++#define FMTPGM_AP4                      0xe4
++#define FMTPGM_AP5                      0xe8
++#define FMTPGM_AP6                      0xec
++#define FMTPGM_AP7                      0xf0
++#define LSCCFG1                         0xf4
++#define LSCCFG2                         0xf8
++#define LSCH0                           0xfc
++#define LSCV0                           0x100
++#define LSCKH                           0x104
++#define LSCKV                           0x108
++#define LSCMEMCTL                       0x10c
++#define LSCMEMD                         0x110
++#define LSCMEMQ                         0x114
++#define DFCCTL                          0x118
++#define DFCVSAT                         0x11c
++#define DFCMEMCTL                       0x120
++#define DFCMEM0                         0x124
++#define DFCMEM1                         0x128
++#define DFCMEM2                         0x12c
++#define DFCMEM3                         0x130
++#define DFCMEM4                         0x134
++#define CSCCTL                          0x138
++#define CSCM0                           0x13c
++#define CSCM1                           0x140
++#define CSCM2                           0x144
++#define CSCM3                           0x148
++#define CSCM4                           0x14c
++#define CSCM5                           0x150
++#define CSCM6                           0x154
++#define CSCM7                           0x158
++#define DATAOFST                      0x15c
++
++#define CLKCTRL                               (0x04)
++
++/* offset relative to 0x1c70800 */
++#define INTSTAT                               (0xC)
++#define INTSEL                                (0x10)
++#define       EVTSEL                          (0x14)
++#define MEMCTRL                               (0x18)
++#define CCDCMUX                               (0x1C)
++
++/**************************************************************
++*     Define for various register bit mask and shifts for CCDC
++*
++**************************************************************/
++#define CCDC_RAW_IP_MODE                      (0x00)
++#define CCDC_VDHDOUT_INPUT                    (0x00)
++#define CCDC_YCINSWP_RAW                      (0x00 << 4)
++#define CCDC_EXWEN_DISABLE                    (0x00)
++#define CCDC_DATAPOL_NORMAL                   (0x00)
++#define CCDC_CCDCFG_FIDMD_LATCH_VSYNC         (0x00)
++#define CCDC_CCDCFG_WENLOG_AND                        (0x00)
++#define CCDC_CCDCFG_TRGSEL_WEN                        (0x00)
++#define CCDC_CCDCFG_EXTRG_DISABLE             (0x00)
++#define CCDC_CFA_MOSAIC                               (0x00)
++
++#define CCDC_VDC_DFCVSAT_MASK                 (0x3fff)
++#define CCDC_DATAOFST_MASK                    (0x0ff)
++#define CCDC_DATAOFST_H_SHIFT                 (0)
++#define CCDC_DATAOFST_V_SHIFT                 (8)
++#define CCDC_GAMMAWD_CFA_MASK                 (0x01)
++#define CCDC_GAMMAWD_CFA_SHIFT                        (5)
++#define CCDC_FID_POL_MASK                     (0x01)
++#define CCDC_FID_POL_SHIFT                    (4)
++#define CCDC_HD_POL_MASK                      (0x01)
++#define CCDC_HD_POL_SHIFT                     (3)
++#define CCDC_VD_POL_MASK                      (0x01)
++#define CCDC_VD_POL_SHIFT                     (2)
++#define CCDC_FRM_FMT_MASK                     (0x01)
++#define CCDC_FRM_FMT_SHIFT                    (7)
++#define CCDC_DATA_SZ_MASK                     (0x07)
++#define CCDC_DATA_SZ_SHIFT                    (8)
++#define CCDC_VDHDOUT_MASK                     (0x01)
++#define CCDC_VDHDOUT_SHIFT                    (0)
++#define CCDC_EXWEN_MASK                               (0x01)
++#define CCDC_EXWEN_SHIFT                      (5)
++#define CCDC_RAW_INPUT_MASK                   (0x03)
++#define CCDC_RAW_INPUT_SHIFT                  (12)
++#define CCDC_PIX_FMT_MASK                     (0x03)
++#define CCDC_PIX_FMT_SHIFT                    (12)
++#define CCDC_DATAPOL_MASK                     (0x01)
++#define CCDC_DATAPOL_SHIFT                    (6)
++#define CCDC_WEN_ENABLE                               (0x01 << 1)
++#define CCDC_VDHDEN_ENABLE                    (0x01 << 16)
++#define CCDC_LPF_ENABLE                               (0x01 << 14)
++#define CCDC_ALAW_ENABLE                      (0x01)
++#define CCDC_ALAW_GAMA_WD_MASK                        (0x07)
++
++#define CCDC_FMTCFG_FMTMODE_MASK              (0x03)
++#define CCDC_FMTCFG_FMTMODE_SHIFT             (1)
++#define CCDC_FMTCFG_LNUM_MASK                 (0x03)
++#define CCDC_FMTCFG_LNUM_SHIFT                        (4)
++#define CCDC_FMTCFG_ADDRINC_MASK              (0x07)
++#define CCDC_FMTCFG_ADDRINC_SHIFT             (8)
++
++#define CCDC_CCDCFG_FIDMD_SHIFT                       (6)
++#define       CCDC_CCDCFG_WENLOG_SHIFT                (8)
++#define CCDC_CCDCFG_TRGSEL_SHIFT              (9)
++#define CCDC_CCDCFG_EXTRG_SHIFT                       (10)
++#define CCDC_CCDCFG_MSBINVI_SHIFT             (13)
++
++#define CCDC_HSIZE_FLIP_SHIFT                 (12)
++#define CCDC_HSIZE_FLIP_MASK                  (0x01)
++
++#define START_PX_HOR_MASK                     (0x7FFF)
++#define NUM_PX_HOR_MASK                               (0x7FFF)
++#define START_VER_ONE_MASK                    (0x7FFF)
++#define START_VER_TWO_MASK                    (0x7FFF)
++#define NUM_LINES_VER                         (0x7FFF)
++
++#define CCDC_BLK_CLAMP_ENABLE                 (0x01 << 15)
++#define CCDC_BLK_SGAIN_MASK                   (0x1F)
++#define CCDC_BLK_ST_PXL_MASK                  (0x1FFF)
++#define CCDC_BLK_SAMPLE_LN_MASK                       (0x03)
++#define CCDC_BLK_SAMPLE_LN_SHIFT              (13)
++
++#define CCDC_NUM_LINE_CALC_MASK                       (0x03)
++#define CCDC_NUM_LINE_CALC_SHIFT              (14)
++
++#define CCDC_BLK_DC_SUB_MASK                  (0x03FFF)
++#define CCDC_BLK_COMP_MASK                    (0x000000FF)
++#define CCDC_BLK_COMP_GB_COMP_SHIFT           (8)
++#define CCDC_BLK_COMP_GR_COMP_SHIFT           (0)
++#define CCDC_BLK_COMP_R_COMP_SHIFT            (8)
++#define CCDC_LATCH_ON_VSYNC_DISABLE           (0x01 << 15)
++#define CCDC_LATCH_ON_VSYNC_ENABLE            (0x00 << 15)
++#define CCDC_FPC_ENABLE                               (0x01 << 15)
++#define CCDC_FPC_FPC_NUM_MASK                         (0x7FFF)
++#define CCDC_DATA_PACK_ENABLE                 (0x01 << 11)
++#define CCDC_FMT_HORZ_FMTLNH_MASK             (0x1FFF)
++#define CCDC_FMT_HORZ_FMTSPH_MASK             (0x1FFF)
++#define CCDC_FMT_HORZ_FMTSPH_SHIFT            (16)
++#define CCDC_FMT_VERT_FMTLNV_MASK             (0x1FFF)
++#define CCDC_FMT_VERT_FMTSLV_MASK             (0x1FFF)
++#define CCDC_FMT_VERT_FMTSLV_SHIFT            (16)
++#define CCDC_VP_OUT_VERT_NUM_MASK             (0x3FFF)
++#define CCDC_VP_OUT_VERT_NUM_SHIFT            (17)
++#define CCDC_VP_OUT_HORZ_NUM_MASK             (0x1FFF)
++#define CCDC_VP_OUT_HORZ_NUM_SHIFT            (4)
++#define CCDC_VP_OUT_HORZ_ST_MASK              (0x000F)
++
++#define CCDC_CSC_COEFF_SHIFT                  (8)
++#define CCDC_CSC_COEFF_DEC_MASK                       (0x0007)
++#define CCDC_CSC_COEFF_FRAC_MASK              (0x001F)
++#define CCDC_CSC_DEC_SHIFT                    (5)
++#define CCDC_CSC_ENABLE                               (0x01)
++#define CCDC_MFILT1_SHIFT                     (10)
++#define CCDC_MFILT2_SHIFT                     (8)
++#define CCDC_LPF_MASK                         (0x01)
++#define CCDC_LPF_SHIFT                                (14)
++#define CCDC_OFFSET_MASK                      (0x3FF)
++#define CCDC_DATASFT_MASK                     (0x07)
++#define CCDC_DATASFT_SHIFT                    (8)
++#define CCDC_DF_ENABLE                                (0x01)
++
++#define CCDC_FMTPLEN_P0_MASK                  (0x000F)
++#define CCDC_FMTPLEN_P1_MASK                  (0x000F)
++#define CCDC_FMTPLEN_P2_MASK                  (0x0007)
++#define CCDC_FMTPLEN_P3_MASK                  (0x0007)
++#define CCDC_FMTPLEN_P0_SHIFT                 (0)
++#define CCDC_FMTPLEN_P1_SHIFT                 (4)
++#define CCDC_FMTPLEN_P2_SHIFT                 (8)
++#define CCDC_FMTPLEN_P3_SHIFT                 (12)
++
++#define CCDC_FMTSPH_MASK                      (0x01FFF)
++#define CCDC_FMTLNH_MASK                      (0x01FFF)
++#define CCDC_FMTSLV_MASK                      (0x01FFF)
++#define CCDC_FMTLNV_MASK                      (0x07FFF)
++#define CCDC_FMTRLEN_MASK                     (0x01FFF)
++#define CCDC_FMTHCNT_MASK                     (0x01FFF)
++
++#define CCDC_ADP_INIT_MASK                    (0x01FFF)
++#define CCDC_ADP_LINE_SHIFT                   (13)
++#define CCDC_ADP_LINE_MASK                    (0x0003)
++#define CCDC_FMTPGN_APTR_MASK                 (0x0007)
++
++#define CCDC_DFCCTL_GDFCEN_MASK                       (0x01)
++#define CCDC_DFCCTL_VDFCEN_MASK                       (0x01)
++#define CCDC_DFCCTL_VDFCEN_SHIFT              (4)
++#define CCDC_DFCCTL_VDFCSL_MASK                       (0x03)
++#define CCDC_DFCCTL_VDFCSL_SHIFT              (5)
++#define CCDC_DFCCTL_VDFCUDA_MASK              (0x01)
++#define CCDC_DFCCTL_VDFCUDA_SHIFT             (7)
++#define CCDC_DFCCTL_VDFLSFT_MASK              (0x03)
++#define CCDC_DFCCTL_VDFLSFT_SHIFT             (8)
++#define CCDC_DFCMEMCTL_DFCMARST_MASK          (0x01)
++#define CCDC_DFCMEMCTL_DFCMARST_SHIFT         (2)
++#define CCDC_DFCMEMCTL_DFCMWR_MASK            (0x01)
++#define CCDC_DFCMEMCTL_DFCMWR_SHIFT           (0)
++
++#define CCDC_LSCCFG_GFTSF_MASK                        (0x07)
++#define CCDC_LSCCFG_GFTSF_SHIFT                       (1)
++#define CCDC_LSCCFG_GFTINV_MASK                       (0x0f)
++#define CCDC_LSCCFG_GFTINV_SHIFT              (4)
++#define CCDC_LSC_GFTABLE_SEL_MASK             (0x03)
++#define CCDC_LSC_GFTABLE_EPEL_SHIFT           (8)
++#define CCDC_LSC_GFTABLE_OPEL_SHIFT           (10)
++#define CCDC_LSC_GFTABLE_EPOL_SHIFT           (12)
++#define CCDC_LSC_GFTABLE_OPOL_SHIFT           (14)
++#define CCDC_LSC_GFMODE_MASK                  (0x03)
++#define CCDC_LSC_GFMODE_SHIFT                 (4)
++#define CCDC_LSC_DISABLE                      (0)
++#define CCDC_LSC_ENABLE                               (1)
++#define CCDC_LSC_TABLE1_SLC                   (0)
++#define CCDC_LSC_TABLE2_SLC                   (1)
++#define CCDC_LSC_TABLE3_SLC                   (2)
++#define CCDC_LSC_MEMADDR_RESET                        (1 << 2)
++#define CCDC_LSC_MEMADDR_INCR                 (0 << 2)
++#define CCDC_LSC_FRAC_MASK_T1                 (0xFF)
++#define CCDC_LSC_INT_MASK                     (0x03)
++#define CCDC_LSC_FRAC_MASK                    (0x3FFF)
++#define CCDC_LSC_CENTRE_MASK                  (0x3FFF)
++#define CCDC_LSC_COEF_MASK                    (0x0ff)
++#define CCDC_LSC_COEFL_SHIFT                  (0)
++#define CCDC_LSC_COEFU_SHIFT                  (8)
++#define CCDC_GAIN_MASK                                (0x7FF)
++#endif
++#endif                                /* CCDC_DM355_H */
+-- 1.6.0.4 
\ No newline at end of file
diff --git a/recipes/linux/linux-davinci/vfpe4.patch b/recipes/linux/linux-davinci/vfpe4.patch
new file mode 100644 (file)
index 0000000..2e95f9e
--- /dev/null
@@ -0,0 +1,1660 @@
+Subject:
+[PATCH 4/7] ccdc hw module and header file for DM6446
+From:
+m-karicheri2-l0cyMroinI0@public.gmane.org
+Date:
+Fri, 13 Mar 2009 17:23:16 -0400
+To:
+davinci-linux-open-source-VycZQUHpC/PFrsHnngEfi1aTQe2KTcn/@public.gmane.org, davinci_opensource_ccb-uAqBSO/uNfhBDgjK7y7TUQ@public.gmane.org, psp_video-uAqBSO/uNfhBDgjK7y7TUQ@public.gmane.org
+Newsgroups:
+gmane.linux.davinci
+
+Adds ccdc hw module and it's header file
+
+Signed-off-by: Murali Karicheri <m-karicheri2-l0cyMroinI0@public.gmane.org>
+---
+ drivers/media/video/ccdc_davinci.c         |  124 ----
+ drivers/media/video/davinci/ccdc_davinci.c | 1007 ++++++++++++++++++++++++++++
+ drivers/media/video/davinci/ccdc_davinci.h |  335 +++++++++
+ include/media/ccdc_davinci.h               |  144 ----
+ 4 files changed, 1342 insertions(+), 268 deletions(-)
+ delete mode 100644 drivers/media/video/ccdc_davinci.c
+ create mode 100644 drivers/media/video/davinci/ccdc_davinci.c
+ create mode 100644 drivers/media/video/davinci/ccdc_davinci.h
+ delete mode 100644 include/media/ccdc_davinci.h
+
+diff --git a/drivers/media/video/ccdc_davinci.c b/drivers/media/video/ccdc_davinci.c
+deleted file mode 100644
+index d3cd333..0000000
+--- a/drivers/media/video/ccdc_davinci.c
++++ /dev/null
+@@ -1,124 +0,0 @@
+-/*
+- *
+- *
+- * Copyright (C) 2006 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
+- */
+-/* ccdc_davinci.c */
+-
+-#include <media/ccdc_davinci.h>
+-#define debug_print(x...)     //printk(x)
+-void ccdc_reset()
+-{
+-      int i;
+-      /* disable CCDC */
+-      ccdc_enable(0);
+-      /* set all registers to default value */
+-      for (i = 0; i <= 0x94; i += 4) {
+-              regw(0, i);
+-      }
+-      regw(0, PCR);
+-      regw(0, SYN_MODE);
+-      regw(0, HD_VD_WID);
+-      regw(0, PIX_LINES);
+-      regw(0, HORZ_INFO);
+-      regw(0, VERT_START);
+-      regw(0, VERT_LINES);
+-      regw(0xffff00ff, CULLING);
+-      regw(0, HSIZE_OFF);
+-      regw(0, SDOFST);
+-      regw(0, SDR_ADDR);
+-      regw(0, VDINT);
+-      regw(0, REC656IF);
+-      regw(0, CCDCFG);
+-      regw(0, FMTCFG);
+-      regw(0, VP_OUT);
+-}
+-
+-void ccdc_setwin(ccdc_params_ycbcr * params)
+-{
+-      int horz_start, horz_nr_pixels;
+-      int vert_start, vert_nr_lines;
+-
+-      /* configure horizonal and vertical starts and sizes */
+-      horz_start = params->win.left << 1;
+-      horz_nr_pixels = (params->win.width <<1) - 1;
+-      regw((horz_start << 16) | horz_nr_pixels, HORZ_INFO);
+-
+-      vert_start = params->win.top;
+-
+-      if (params->frm_fmt == CCDC_FRMFMT_INTERLACED) {
+-              vert_nr_lines = (params->win.height >> 1) - 1;
+-              vert_start >>= 1;
+-      } else {
+-              vert_nr_lines = params->win.height - 1;
+-      }
+-      regw((vert_start << 16) | vert_start, VERT_START);
+-      regw(vert_nr_lines, VERT_LINES);
+-}
+-
+-void ccdc_config_ycbcr(ccdc_params_ycbcr * params)
+-{
+-      u32 syn_mode;
+-
+-      /* first reset the CCDC                                          */
+-      /* all registers have default values after reset                 */
+-      /* This is important since we assume default values to be set in */
+-      /* a lot of registers that we didn't touch                       */
+-      ccdc_reset();
+-
+-      /* configure pixel format */
+-      syn_mode = (params->pix_fmt & 0x3) << 12;
+-
+-      /* configure video frame format */
+-      syn_mode |= (params->frm_fmt & 0x1) << 7;
+-
+-      /* setup BT.656 sync mode */
+-      if (params->bt656_enable) {
+-              regw(3, REC656IF);
+-
+-              /* configure the FID, VD, HD pin polarity */
+-              /* fld,hd pol positive, vd negative, 8-bit pack mode */
+-              syn_mode |= 0x00000F04;
+-      } else {/* y/c external sync mode */
+-              syn_mode |= ((params->fid_pol & 0x1) << 4);
+-              syn_mode |= ((params->hd_pol & 0x1) << 3);
+-              syn_mode |= ((params->vd_pol & 0x1) << 2);
+-      }
+-
+-      /* configure video window */
+-      ccdc_setwin(params);
+-
+-      /* configure the order of y cb cr in SD-RAM */
+-      regw((params->pix_order << 11) | 0x8000, CCDCFG);
+-
+-      /* configure the horizontal line offset */
+-      /* this is done by rounding up width to a multiple of 16 pixels */
+-      /* and multiply by two to account for y:cb:cr 4:2:2 data */
+-      regw(((params->win.width * 2) + 31) & 0xffffffe0, HSIZE_OFF);
+-
+-      /* configure the memory line offset */
+-      if (params->buf_type == CCDC_BUFTYPE_FLD_INTERLEAVED) {
+-              /* two fields are interleaved in memory */
+-              regw(0x00000249, SDOFST);
+-      }
+-      /* enable output to SDRAM */
+-      syn_mode |= (0x1 << 17);
+-      /* enable internal timing generator */
+-      syn_mode |= (0x1 << 16);
+-
+-      regw(syn_mode, SYN_MODE);
+-}
+diff --git a/drivers/media/video/davinci/ccdc_davinci.c b/drivers/media/video/davinci/ccdc_davinci.c
+new file mode 100644
+index 0000000..0bb596e
+--- /dev/null
++++ b/drivers/media/video/davinci/ccdc_davinci.c
+@@ -0,0 +1,1007 @@
++/*
++ * Copyright (C) 2006-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
++ */
++#include <linux/platform_device.h>
++#include <linux/uaccess.h>
++#include <asm/page.h>
++#include <media/davinci/ccdc_hw_device.h>
++#include "ccdc_davinci.h"
++
++static struct device *dev;
++
++/* Object for CCDC raw mode */
++static struct ccdc_params_raw ccdc_hw_params_raw = {
++      .pix_fmt = CCDC_PIXFMT_RAW,
++      .frm_fmt = CCDC_FRMFMT_PROGRESSIVE,
++      .win = CCDC_WIN_VGA,
++      .fid_pol = CCDC_PINPOL_POSITIVE,
++      .vd_pol = CCDC_PINPOL_POSITIVE,
++      .hd_pol = CCDC_PINPOL_POSITIVE,
++      .image_invert_enable = 0,
++      .data_sz = _10BITS,
++      .alaw = {
++              .b_alaw_enable = 0
++      },
++      .blk_clamp = {
++              .b_clamp_enable = 0,
++              .dc_sub = 0
++      },
++      .blk_comp = {0, 0, 0, 0},
++      .fault_pxl = {
++              .fpc_enable = 0
++      },
++};
++
++/* Object for CCDC ycbcr mode */
++static struct ccdc_params_ycbcr ccdc_hw_params_ycbcr = {
++      .pix_fmt = CCDC_PIXFMT_YCBCR_8BIT,
++      .frm_fmt = CCDC_FRMFMT_INTERLACED,
++      .win = CCDC_WIN_PAL,
++      .fid_pol = CCDC_PINPOL_POSITIVE,
++      .vd_pol = CCDC_PINPOL_POSITIVE,
++      .hd_pol = CCDC_PINPOL_POSITIVE,
++      .bt656_enable = 1,
++      .pix_order = CCDC_PIXORDER_CBYCRY,
++      .buf_type = CCDC_BUFTYPE_FLD_INTERLEAVED
++};
++
++#define CCDC_MAX_RAW_BAYER_FORMATS    2
++#define CCDC_MAX_RAW_YUV_FORMATS      2
++
++/* Raw Bayer formats */
++enum vpfe_hw_pix_format ccdc_raw_bayer_hw_formats[CCDC_MAX_RAW_BAYER_FORMATS] =
++              {VPFE_BAYER_8BIT_PACK_ALAW, VPFE_BAYER};
++
++/* Raw YUV formats */
++enum vpfe_hw_pix_format ccdc_raw_yuv_hw_formats[CCDC_MAX_RAW_YUV_FORMATS] =
++              {VPFE_UYVY, VPFE_YUYV};
++
++static void *__iomem ccdc_base_addr;
++static int ccdc_addr_size;
++static void *__iomem vpss_base_addr;
++static int vpss_addr_size;
++static struct ccdc_config_params_raw ccdc_hw_params_raw_temp;
++static enum vpfe_hw_if_type ccdc_if_type;
++
++/* register access routines */
++static inline u32 regr(u32 offset)
++{
++      if (offset <= ccdc_addr_size)
++              return __raw_readl(ccdc_base_addr + offset);
++      else {
++              dev_err(dev, "offset exceeds ccdc register address space\n");
++              return -1;
++      }
++}
++
++static inline u32 regw(u32 val, u32 offset)
++{
++      if (offset <= ccdc_addr_size) {
++              __raw_writel(val, ccdc_base_addr + offset);
++              return val;
++      } else {
++              dev_err(dev, "offset exceeds ccdc register address space\n");
++              return -1;
++      }
++}
++
++/* register access routines */
++static inline u32 regr_sb(u32 offset)
++{
++      if (offset <= vpss_addr_size)
++              return __raw_readl(vpss_base_addr + offset);
++      else {
++              dev_err(dev, "offset exceeds vpss register address space\n");
++              return -1;
++      }
++}
++
++static inline u32 regw_sb(u32 val, u32 offset)
++{
++      if (offset <= vpss_addr_size) {
++              __raw_writel(val, vpss_base_addr + offset);
++              return val;
++      } else {
++              dev_err(dev, "offset exceeds vpss register address space\n");
++              return -1;
++      }
++}
++
++static void ccdc_set_ccdc_base(void *addr, int size)
++{
++      ccdc_base_addr = addr;
++      ccdc_addr_size = size;
++}
++
++static void ccdc_set_vpss_base(void *addr, int size)
++{
++      vpss_base_addr = addr;
++      vpss_addr_size = size;
++}
++
++static void *ccdc_get_ccdc_base(void)
++{
++      return (void *)ccdc_base_addr;
++}
++
++static void *ccdc_get_vpss_base(void)
++{
++      return (void *)vpss_base_addr;
++}
++
++static void ccdc_enable(int flag)
++{
++      regw(flag, PCR);
++}
++
++static void ccdc_enable_vport(int flag)
++{
++      if (flag)
++              /* enable video port */
++              regw(ENABLE_VIDEO_PORT, FMTCFG);
++      else
++              regw(DISABLE_VIDEO_PORT, FMTCFG);
++}
++
++/*
++ * ======== ccdc_setwin  ========
++ * This function will configure the window size
++ * to be capture in CCDC reg
++ */
++void ccdc_setwin(struct ccdc_imgwin *image_win,
++              enum ccdc_frmfmt frm_fmt,
++              int ppc)
++{
++      int horz_start, horz_nr_pixels;
++      int vert_start, vert_nr_lines;
++      int val = 0, mid_img = 0;
++      dev_dbg(dev, "\nStarting ccdc_setwin...");
++      /* configure horizonal and vertical starts and sizes */
++      /* Here, (ppc-1) will be different for raw and yuv modes */
++      horz_start = image_win->left << (ppc - 1);
++      horz_nr_pixels = (image_win->width << (ppc - 1)) - 1;
++      regw((horz_start << CCDC_HORZ_INFO_SPH_SHIFT) | horz_nr_pixels,
++           HORZ_INFO);
++
++      vert_start = image_win->top;
++
++      if (frm_fmt == CCDC_FRMFMT_INTERLACED) {
++              vert_nr_lines = (image_win->height >> 1) - 1;
++              vert_start >>= 1;
++              /* Since first line doesn't have any data */
++              vert_start += 1;
++              /* configure VDINT0 */
++              val = (vert_start << CCDC_VDINT_VDINT0_SHIFT);
++              regw(val, VDINT);
++
++      } else {
++              /* Since first line doesn't have any data */
++              vert_start += 1;
++              vert_nr_lines = image_win->height - 1;
++              /* configure VDINT0 and VDINT1 */
++              /* VDINT1 will be at half of image height */
++              mid_img = vert_start + (image_win->height / 2);
++              val = (vert_start << CCDC_VDINT_VDINT0_SHIFT) |
++                  (mid_img & CCDC_VDINT_VDINT1_MASK);
++              regw(val, VDINT);
++
++      }
++      regw((vert_start << CCDC_VERT_START_SLV0_SHIFT) | vert_start,
++           VERT_START);
++      regw(vert_nr_lines, VERT_LINES);
++      dev_dbg(dev, "\nEnd of ccdc_setwin...");
++}
++
++static void ccdc_readregs(void)
++{
++      unsigned int val = 0;
++
++      val = regr(ALAW);
++      dev_notice(dev, "\nReading 0x%x to ALAW...\n", val);
++      val = regr(CLAMP);
++      dev_notice(dev, "\nReading 0x%x to CLAMP...\n", val);
++      val = regr(DCSUB);
++      dev_notice(dev, "\nReading 0x%x to DCSUB...\n", val);
++      val = regr(BLKCMP);
++      dev_notice(dev, "\nReading 0x%x to BLKCMP...\n", val);
++      val = regr(FPC_ADDR);
++      dev_notice(dev, "\nReading 0x%x to FPC_ADDR...\n", val);
++      val = regr(FPC);
++      dev_notice(dev, "\nReading 0x%x to FPC...\n", val);
++      val = regr(FMTCFG);
++      dev_notice(dev, "\nReading 0x%x to FMTCFG...\n", val);
++      val = regr(COLPTN);
++      dev_notice(dev, "\nReading 0x%x to COLPTN...\n", val);
++      val = regr(FMT_HORZ);
++      dev_notice(dev, "\nReading 0x%x to FMT_HORZ...\n", val);
++      val = regr(FMT_VERT);
++      dev_notice(dev, "\nReading 0x%x to FMT_VERT...\n", val);
++      val = regr(HSIZE_OFF);
++      dev_notice(dev, "\nReading 0x%x to HSIZE_OFF...\n", val);
++      val = regr(SDOFST);
++      dev_notice(dev, "\nReading 0x%x to SDOFST...\n", val);
++      val = regr(VP_OUT);
++      dev_notice(dev, "\nReading 0x%x to VP_OUT...\n", val);
++      val = regr(SYN_MODE);
++      dev_notice(dev, "\nReading 0x%x to SYN_MODE...\n", val);
++      val = regr(HORZ_INFO);
++      dev_notice(dev, "\nReading 0x%x to HORZ_INFO...\n", val);
++      val = regr(VERT_START);
++      dev_notice(dev, "\nReading 0x%x to VERT_START...\n", val);
++      val = regr(VERT_LINES);
++      dev_notice(dev, "\nReading 0x%x to VERT_LINES...\n", val);
++}
++
++static int validate_ccdc_param(struct ccdc_config_params_raw *ccdcparam)
++{
++      if ((ccdc_hw_params_raw.frm_fmt != CCDC_FRMFMT_INTERLACED)
++          && (ccdcparam->image_invert_enable == 1)) {
++              dev_err(dev, "\nImage invert not supported");
++              return -1;
++      }
++      if (ccdc_hw_params_raw.alaw.b_alaw_enable) {
++              if ((ccdcparam->alaw.gama_wd > BITS_09_0)
++                  || (ccdcparam->alaw.gama_wd < BITS_15_6)
++                  || (ccdcparam->alaw.gama_wd < ccdcparam->data_sz)) {
++                      dev_err(dev, "\nInvalid data line select");
++                      return -1;
++              }
++      }
++      return 0;
++}
++
++static int ccdc_update_ycbcr_params(void *arg)
++{
++      memcpy(&ccdc_hw_params_ycbcr,
++             (struct ccdc_params_ycbcr *)arg,
++             sizeof(struct ccdc_params_ycbcr));
++      return 0;
++}
++
++static int ccdc_update_raw_params(void *arg)
++{
++      unsigned int *fpc_virtaddr = NULL;
++      unsigned int *fpc_physaddr = NULL;
++      struct ccdc_params_raw *ccd_params = &ccdc_hw_params_raw;
++      struct ccdc_config_params_raw *raw_params =
++                      (struct ccdc_config_params_raw *) arg;
++      ccd_params->image_invert_enable = raw_params->image_invert_enable;
++
++      dev_dbg(dev, "\nimage_invert_enable = %d",
++             ccd_params->image_invert_enable);
++
++      ccd_params->data_sz = raw_params->data_sz;
++      dev_dbg(dev, "\ndata_sz = %d", ccd_params->data_sz);
++
++      ccd_params->alaw.b_alaw_enable = raw_params->alaw.b_alaw_enable;
++      dev_dbg(dev, "\nALaw Enable = %d", ccd_params->alaw.b_alaw_enable);
++      /* copy A-Law configurations to vpfe_device, from arg
++       * passed by application */
++      if (ccd_params->alaw.b_alaw_enable) {
++              ccd_params->alaw.gama_wd = raw_params->alaw.gama_wd;
++              dev_dbg(dev, "\nALaw Gama width = %d",
++                     ccd_params->alaw.gama_wd);
++      }
++
++      /* copy Optical Balck Clamping configurations to
++       * vpfe_device,from arg passed by application */
++      ccd_params->blk_clamp.b_clamp_enable
++          = raw_params->blk_clamp.b_clamp_enable;
++      dev_dbg(dev, "\nb_clamp_enable = %d",
++             ccd_params->blk_clamp.b_clamp_enable);
++      if (ccd_params->blk_clamp.b_clamp_enable) {
++              /*gain */
++              ccd_params->blk_clamp.sgain = raw_params->blk_clamp.sgain;
++              dev_dbg(dev, "\nblk_clamp.sgain = %d",
++                     ccd_params->blk_clamp.sgain);
++              /*Start pixel */
++              ccd_params->blk_clamp.start_pixel
++                  = raw_params->blk_clamp.start_pixel;
++              dev_dbg(dev, "\nblk_clamp.start_pixel = %d",
++                     ccd_params->blk_clamp.start_pixel);
++              /*No of line to be avg */
++              ccd_params->blk_clamp.sample_ln
++                  = raw_params->blk_clamp.sample_ln;
++              dev_dbg(dev, "\nblk_clamp.sample_ln = %d",
++                     ccd_params->blk_clamp.sample_ln);
++              /*No of pixel/line to be avg */
++              ccd_params->blk_clamp.sample_pixel
++                  = raw_params->blk_clamp.sample_pixel;
++              dev_dbg(dev, "\nblk_clamp.sample_pixel  = %d",
++                     ccd_params->blk_clamp.sample_pixel);
++      } else {                /* configure DCSub */
++
++              ccd_params->blk_clamp.dc_sub = raw_params->blk_clamp.dc_sub;
++              dev_dbg(dev, "\nblk_clamp.dc_sub  = %d",
++                     ccd_params->blk_clamp.dc_sub);
++      }
++
++      /* copy BalckLevel Compansation configurations to
++       * vpfe_device,from arg passed by application
++       */
++      ccd_params->blk_comp.r_comp = raw_params->blk_comp.r_comp;
++      ccd_params->blk_comp.gr_comp = raw_params->blk_comp.gr_comp;
++      ccd_params->blk_comp.b_comp = raw_params->blk_comp.b_comp;
++      ccd_params->blk_comp.gb_comp = raw_params->blk_comp.gb_comp;
++      dev_dbg(dev, "\nblk_comp.r_comp   = %d",
++             ccd_params->blk_comp.r_comp);
++      dev_dbg(dev, "\nblk_comp.gr_comp  = %d",
++             ccd_params->blk_comp.gr_comp);
++      dev_dbg(dev, "\nblk_comp.b_comp   = %d",
++             ccd_params->blk_comp.b_comp);
++      dev_dbg(dev, "\nblk_comp.gb_comp  = %d",
++             ccd_params->blk_comp.gb_comp);
++
++      /* copy FPC configurations to vpfe_device,from
++       * arg passed by application
++       */
++      ccd_params->fault_pxl.fpc_enable = raw_params->fault_pxl.fpc_enable;
++      dev_dbg(dev, "\nfault_pxl.fpc_enable  = %d",
++             ccd_params->fault_pxl.fpc_enable);
++
++      if (ccd_params->fault_pxl.fpc_enable) {
++              fpc_physaddr =
++                  (unsigned int *)ccd_params->fault_pxl.fpc_table_addr;
++
++              fpc_virtaddr = (unsigned int *)
++                  phys_to_virt((unsigned long)
++                               fpc_physaddr);
++
++              /* Allocate memory for FPC table if current
++               * FPC table buffer is not big enough to
++               * accomodate FPC Number requested
++               */
++              if (raw_params->fault_pxl.fp_num !=
++                  ccd_params->fault_pxl.fp_num) {
++                      if (fpc_physaddr != NULL) {
++                              free_pages((unsigned long)
++                                         fpc_physaddr,
++                                         get_order
++                                         (ccd_params->
++                                          fault_pxl.fp_num * FP_NUM_BYTES));
++
++                      }
++
++                      /* Allocate memory for FPC table */
++                      fpc_virtaddr = (unsigned int *)
++                          __get_free_pages(GFP_KERNEL |
++                                           GFP_DMA,
++                                           get_order
++                                           (raw_params->
++                                            fault_pxl.fp_num * FP_NUM_BYTES));
++
++                      if (fpc_virtaddr == NULL) {
++                              dev_err(dev,
++                                      "\nUnable to allocate memory for FPC");
++                              return -1;
++                      }
++                      fpc_physaddr =
++                          (unsigned int *)virt_to_phys((void *)fpc_virtaddr);
++              }
++
++              /* Copy number of fault pixels and FPC table */
++              ccd_params->fault_pxl.fp_num = raw_params->fault_pxl.fp_num;
++              if (copy_from_user((void *)fpc_virtaddr,
++                             (void *)raw_params->
++                             fault_pxl.fpc_table_addr,
++                             (unsigned long)ccd_params->
++                             fault_pxl.fp_num * FP_NUM_BYTES)) {
++                              dev_err(dev, "\n copy_from_user failed");
++                              return -1;
++              }
++
++              ccd_params->fault_pxl.fpc_table_addr =
++                  (unsigned int)fpc_physaddr;
++      }
++      return 0;
++}
++
++static int ccdc_close(struct device *dev)
++{
++      unsigned int *fpc_physaddr = NULL, *fpc_virtaddr = NULL;
++      fpc_physaddr = (unsigned int *)
++          ccdc_hw_params_raw.fault_pxl.fpc_table_addr;
++
++      if (fpc_physaddr != NULL) {
++              fpc_virtaddr = (unsigned int *)
++                  phys_to_virt((unsigned long)fpc_physaddr);
++              free_pages((unsigned long)fpc_virtaddr,
++                         get_order(ccdc_hw_params_raw.fault_pxl.
++                                   fp_num * FP_NUM_BYTES));
++      }
++      return 0;
++}
++
++/*
++ * ======== ccdc_reset  ========
++ *
++ * This function will reset all CCDc reg
++ */
++static void ccdc_reset(void)
++{
++      int i;
++
++      /* disable CCDC */
++      ccdc_enable(0);
++      /* set all registers to default value */
++      for (i = 0; i <= 0x94; i += 4)
++              regw(0,  i);
++      regw(0, PCR);
++      regw(0, SYN_MODE);
++      regw(0, HD_VD_WID);
++      regw(0, PIX_LINES);
++      regw(0, HORZ_INFO);
++      regw(0, VERT_START);
++      regw(0, VERT_LINES);
++      regw(0xffff00ff, CULLING);
++      regw(0, HSIZE_OFF);
++      regw(0, SDOFST);
++      regw(0, SDR_ADDR);
++      regw(0, VDINT);
++      regw(0, REC656IF);
++      regw(0, CCDCFG);
++      regw(0, FMTCFG);
++      regw(0, VP_OUT);
++}
++
++static int ccdc_open(struct device *device)
++{
++      dev = device;
++      ccdc_reset();
++      if (ccdc_if_type == VPFE_RAW_BAYER)
++              ccdc_enable_vport(1);
++      return 0;
++}
++
++static u32 ccdc_sbl_reset(void)
++{
++      u32 sb_reset;
++      sb_reset = regr_sb(SBL_PCR_VPSS);
++      regw_sb((sb_reset & SBL_PCR_CCDC_WBL_O), SBL_PCR_VPSS);
++      return sb_reset;
++}
++
++/* Parameter operations */
++static int ccdc_setparams(void *params)
++{
++      int x;
++      if (ccdc_if_type == VPFE_RAW_BAYER) {
++              x = copy_from_user(&ccdc_hw_params_raw_temp,
++                                 (struct ccdc_config_params_raw *)params,
++                                 sizeof(struct ccdc_config_params_raw));
++              if (x) {
++                      dev_err(dev, "ccdc_setparams: error in copying"
++                                 "ccdc params, %d\n", x);
++                      return -1;
++              }
++
++              if (!validate_ccdc_param(&ccdc_hw_params_raw_temp)) {
++                      if (!ccdc_update_raw_params(&ccdc_hw_params_raw_temp))
++                              return 0;
++              }
++      } else
++              return ccdc_update_ycbcr_params(params);
++      return -1;
++}
++
++/*
++ * ======== ccdc_config_ycbcr  ========
++ * This function will configure CCDC for YCbCr parameters
++ */
++void ccdc_config_ycbcr(void)
++{
++      u32 syn_mode;
++      unsigned int val;
++      struct ccdc_params_ycbcr *params = &ccdc_hw_params_ycbcr;
++
++      /* first reset the CCDC                                          */
++      /* all registers have default values after reset                 */
++      /* This is important since we assume default values to be set in */
++      /* a lot of registers that we didn't touch                       */
++      dev_dbg(dev, "\nStarting ccdc_config_ycbcr...");
++      ccdc_reset();
++
++      /* configure pixel format */
++      syn_mode = (params->pix_fmt & 0x3) << 12;
++
++      /* configure video frame format */
++      syn_mode |= (params->frm_fmt & 0x1) << 7;
++
++      /* setup BT.656 sync mode */
++      if (params->bt656_enable) {
++              regw(3, REC656IF);
++
++              /* configure the FID, VD, HD pin polarity */
++              /* fld,hd pol positive, vd negative, 8-bit pack mode */
++              syn_mode |= 0x00000F04;
++      } else {
++              /* y/c external sync mode */
++              syn_mode |= ((params->fid_pol & 0x1) << 4);
++              syn_mode |= ((params->hd_pol & 0x1) << 3);
++              syn_mode |= ((params->vd_pol & 0x1) << 2);
++      }
++
++      /* configure video window */
++      ccdc_setwin(&params->win, params->frm_fmt, 2);
++
++      /* configure the order of y cb cr in SD-RAM */
++      regw((params->pix_order << 11) | 0x8000, CCDCFG);
++
++      /* configure the horizontal line offset */
++      /* this is done by rounding up width to a multiple of 16 pixels */
++      /* and multiply by two to account for y:cb:cr 4:2:2 data */
++      regw(((params->win.width * 2) + 31) & 0xffffffe0, HSIZE_OFF);
++
++      /* configure the memory line offset */
++      if (params->buf_type == CCDC_BUFTYPE_FLD_INTERLEAVED)
++              /* two fields are interleaved in memory */
++              regw(0x00000249, SDOFST);
++      /* enable output to SDRAM */
++      syn_mode |= (0x1 << 17);
++      /* enable internal timing generator */
++      syn_mode |= (0x1 << 16);
++
++      syn_mode |= CCDC_DATA_PACK_ENABLE;
++      regw(syn_mode, SYN_MODE);
++
++      val = (unsigned int)ccdc_sbl_reset();
++      dev_dbg(dev, "\nReading 0x%x from SBL...\n", val);
++      dev_dbg(dev, "\nEnd of ccdc_config_ycbcr...\n");
++      ccdc_readregs();
++}
++
++/*
++ * ======== ccdc_config_raw  ========
++ *
++ * This function will configure CCDC for Raw mode parameters
++ */
++void ccdc_config_raw(void)
++{
++      struct ccdc_params_raw *params = &ccdc_hw_params_raw;
++      unsigned int syn_mode = 0;
++      unsigned int val;
++      dev_dbg(dev, "\nStarting ccdc_config_raw...");
++      /*      Reset CCDC */
++      ccdc_reset();
++      /* Disable latching function registers on VSYNC  */
++      regw(CCDC_LATCH_ON_VSYNC_DISABLE, CCDCFG);
++
++      /*      Configure the vertical sync polarity(SYN_MODE.VDPOL) */
++      syn_mode = (params->vd_pol & CCDC_VD_POL_MASK) << CCDC_VD_POL_SHIFT;
++
++      /*      Configure the horizontal sync polarity (SYN_MODE.HDPOL) */
++      syn_mode |= (params->hd_pol & CCDC_HD_POL_MASK) << CCDC_HD_POL_SHIFT;
++
++      /*      Configure frame id polarity (SYN_MODE.FLDPOL) */
++      syn_mode |= (params->fid_pol & CCDC_FID_POL_MASK) << CCDC_FID_POL_SHIFT;
++
++      /* Configure frame format(progressive or interlace) */
++      syn_mode |= (params->frm_fmt & CCDC_FRM_FMT_MASK) << CCDC_FRM_FMT_SHIFT;
++
++      /* Configure the data size(SYNMODE.DATSIZ) */
++      syn_mode |= (params->data_sz & CCDC_DATA_SZ_MASK) << CCDC_DATA_SZ_SHIFT;
++
++      /* Configure pixel format (Input mode) */
++      syn_mode |= (params->pix_fmt & CCDC_PIX_FMT_MASK) << CCDC_PIX_FMT_SHIFT;
++
++      /* Configure VP2SDR bit of syn_mode = 0 */
++      syn_mode &= CCDC_VP2SDR_DISABLE;
++
++      /* Enable write enable bit */
++      syn_mode |= CCDC_WEN_ENABLE;
++
++      /* Disable output to resizer */
++      syn_mode &= CCDC_SDR2RSZ_DISABLE;
++
++      /* enable internal timing generator */
++      syn_mode |= CCDC_VDHDEN_ENABLE;
++
++      /* Enable and configure aLaw register if needed */
++      if (params->alaw.b_alaw_enable) {
++              val = (params->alaw.gama_wd & CCDC_ALAW_GAMA_WD_MASK);
++              /*set enable bit of alaw */
++              val |= CCDC_ALAW_ENABLE;
++              regw(val, ALAW);
++
++              dev_dbg(dev, "\nWriting 0x%x to ALAW...\n", val);
++      }
++
++      /* configure video window */
++      ccdc_setwin(&params->win, params->frm_fmt, PPC_RAW);
++
++      if (params->blk_clamp.b_clamp_enable) {
++              /*gain */
++              val = (params->blk_clamp.sgain) & CCDC_BLK_SGAIN_MASK;
++              /*Start pixel */
++              val |= (params->blk_clamp.start_pixel & CCDC_BLK_ST_PXL_MASK)
++                  << CCDC_BLK_ST_PXL_SHIFT;
++              /*No of line to be avg */
++              val |= (params->blk_clamp.sample_ln & CCDC_BLK_SAMPLE_LINE_MASK)
++                  << CCDC_BLK_SAMPLE_LINE_SHIFT;
++              /*No of pixel/line to be avg */
++              val |=
++                  (params->blk_clamp.sample_pixel & CCDC_BLK_SAMPLE_LN_MASK)
++                  << CCDC_BLK_SAMPLE_LN_SHIFT;
++              /*Enable the Black clamping */
++              val |= CCDC_BLK_CLAMP_ENABLE;
++              regw(val, CLAMP);
++
++              dev_dbg(dev, "\nWriting 0x%x to CLAMP...\n", val);
++              /*If Black clamping is enable then make dcsub 0 */
++              regw(DCSUB_DEFAULT_VAL, DCSUB);
++              dev_dbg(dev, "\nWriting 0x00000000 to DCSUB...\n");
++
++      } else {
++              /* configure DCSub */
++              val = (params->blk_clamp.dc_sub) & CCDC_BLK_DC_SUB_MASK;
++              regw(val, DCSUB);
++
++              dev_dbg(dev, "\nWriting 0x%x to DCSUB...\n", val);
++              regw(CLAMP_DEFAULT_VAL, CLAMP);
++
++              dev_dbg(dev, "\nWriting 0x0000 to CLAMP...\n");
++      }
++
++      /*      Configure Black level compensation */
++      val = (params->blk_comp.b_comp & CCDC_BLK_COMP_MASK);
++      val |= (params->blk_comp.gb_comp & CCDC_BLK_COMP_MASK)
++          << CCDC_BLK_COMP_GB_COMP_SHIFT;
++      val |= (params->blk_comp.gr_comp & CCDC_BLK_COMP_MASK)
++          << CCDC_BLK_COMP_GR_COMP_SHIFT;
++      val |= (params->blk_comp.r_comp & CCDC_BLK_COMP_MASK)
++          << CCDC_BLK_COMP_R_COMP_SHIFT;
++
++      regw(val, BLKCMP);
++
++      dev_dbg(dev, "\nWriting 0x%x to BLKCMP...\n", val);
++      dev_dbg(dev, "\nbelow   regw(val, BLKCMP)...");
++      /* Initially disable FPC */
++      val = CCDC_FPC_DISABLE;
++      regw(val, FPC);
++      /* Configure Fault pixel if needed */
++      if (params->fault_pxl.fpc_enable) {
++              regw(params->fault_pxl.fpc_table_addr, FPC_ADDR);
++
++              dev_dbg(dev, "\nWriting 0x%x to FPC_ADDR...\n",
++                     (params->fault_pxl.fpc_table_addr));
++              /* Write the FPC params with FPC disable */
++              val = params->fault_pxl.fp_num & CCDC_FPC_FPC_NUM_MASK;
++              regw(val, FPC);
++
++              dev_dbg(dev, "\nWriting 0x%x to FPC...\n", val);
++              /* read the FPC register */
++              val = regr(FPC);
++              val |= CCDC_FPC_ENABLE;
++              regw(val, FPC);
++
++              dev_dbg(dev, "\nWriting 0x%x to FPC...\n", val);
++      }
++      /* If data size is 8 bit then pack the data */
++      if ((params->data_sz == _8BITS) || params->alaw.b_alaw_enable)
++              syn_mode |= CCDC_DATA_PACK_ENABLE;
++#if VIDEO_PORT_ENABLE
++      /* enable video port */
++      val = ENABLE_VIDEO_PORT;
++#else
++      /* disable video port */
++      val = DISABLE_VIDEO_PORT;
++#endif
++
++      if (params->data_sz == _8BITS)
++              val |= (_10BITS & CCDC_FMTCFG_VPIN_MASK)
++                  << CCDC_FMTCFG_VPIN_SHIFT;
++      else
++              val |= (params->data_sz & CCDC_FMTCFG_VPIN_MASK)
++                  << CCDC_FMTCFG_VPIN_SHIFT;
++
++      /* Write value in FMTCFG */
++      regw(val, FMTCFG);
++
++      dev_dbg(dev, "\nWriting 0x%x to FMTCFG...\n", val);
++
++      /* Configure the color pattern according to mt9t001 sensor */
++      regw(CCDC_COLPTN_VAL, COLPTN);
++
++      dev_dbg(dev, "\nWriting 0xBB11BB11 to COLPTN...\n");
++      /* Configure Data formatter(Video port) pixel selection
++       * (FMT_HORZ, FMT_VERT)
++       */
++      val = 0;
++      val |= ((params->win.left) & CCDC_FMT_HORZ_FMTSPH_MASK)
++          << CCDC_FMT_HORZ_FMTSPH_SHIFT;
++      val |= (((params->win.width)) & CCDC_FMT_HORZ_FMTLNH_MASK);
++      regw(val, FMT_HORZ);
++
++      dev_dbg(dev, "\nWriting 0x%x to FMT_HORZ...\n", val);
++      val = 0;
++      val |= (params->win.top & CCDC_FMT_VERT_FMTSLV_MASK)
++          << CCDC_FMT_VERT_FMTSLV_SHIFT;
++      if (params->frm_fmt == CCDC_FRMFMT_PROGRESSIVE)
++              val |= (params->win.height) & CCDC_FMT_VERT_FMTLNV_MASK;
++      else
++              val |= (params->win.height >> 1) & CCDC_FMT_VERT_FMTLNV_MASK;
++
++      dev_dbg(dev, "\nparams->win.height  0x%x ...\n",
++             params->win.height);
++      regw(val, FMT_VERT);
++
++      dev_dbg(dev, "\nWriting 0x%x to FMT_VERT...\n", val);
++
++      dev_dbg(dev, "\nbelow regw(val, FMT_VERT)...");
++
++      /* Configure Horizontal offset register */
++      /* If pack 8 is enabled then 1 pixel will take 1 byte */
++      if ((params->data_sz == _8BITS) || params->alaw.b_alaw_enable)
++              regw(((params->win.width) + CCDC_32BYTE_ALIGN_VAL)
++                   & CCDC_HSIZE_OFF_MASK, HSIZE_OFF);
++
++      else
++              /* else one pixel will take 2 byte */
++              regw(((params->win.width * TWO_BYTES_PER_PIXEL)
++                    + CCDC_32BYTE_ALIGN_VAL)
++                   & CCDC_HSIZE_OFF_MASK, HSIZE_OFF);
++
++      /* Set value for SDOFST */
++      if (params->frm_fmt == CCDC_FRMFMT_INTERLACED) {
++              if (params->image_invert_enable) {
++                      /* For intelace inverse mode */
++                      regw(INTERLACED_IMAGE_INVERT, SDOFST);
++                      dev_dbg(dev, "\nWriting 0x4B6D to SDOFST...\n");
++              }
++
++              else {
++                      /* For intelace non inverse mode */
++                      regw(INTERLACED_NO_IMAGE_INVERT, SDOFST);
++                      dev_dbg(dev, "\nWriting 0x0249 to SDOFST...\n");
++              }
++      } else if (params->frm_fmt == CCDC_FRMFMT_PROGRESSIVE) {
++              regw(PROGRESSIVE_NO_IMAGE_INVERT, SDOFST);
++              dev_dbg(dev, "\nWriting 0x0000 to SDOFST...\n");
++      }
++
++      /* Configure video port pixel selection (VPOUT) */
++      /* Here -1 is to make the height value less than FMT_VERT.FMTLNV */
++      if (params->frm_fmt == CCDC_FRMFMT_PROGRESSIVE)
++              val = (((params->win.height - 1) & CCDC_VP_OUT_VERT_NUM_MASK))
++                  << CCDC_VP_OUT_VERT_NUM_SHIFT;
++      else
++              val =
++                  ((((params->win.
++                      height >> CCDC_INTERLACED_HEIGHT_SHIFT) -
++                     1) & CCDC_VP_OUT_VERT_NUM_MASK))
++                  << CCDC_VP_OUT_VERT_NUM_SHIFT;
++
++      val |= ((((params->win.width))) & CCDC_VP_OUT_HORZ_NUM_MASK)
++          << CCDC_VP_OUT_HORZ_NUM_SHIFT;
++      val |= (params->win.left) & CCDC_VP_OUT_HORZ_ST_MASK;
++      regw(val, VP_OUT);
++
++      dev_dbg(dev, "\nWriting 0x%x to VP_OUT...\n", val);
++      regw(syn_mode, SYN_MODE);
++      dev_dbg(dev, "\nWriting 0x%x to SYN_MODE...\n", syn_mode);
++
++      val = (unsigned int)ccdc_sbl_reset();
++      dev_dbg(dev, "\nReading 0x%x from SBL...\n", val);
++
++      dev_dbg(dev, "\nend of ccdc_config_raw...");
++      ccdc_readregs();
++}
++
++static int ccdc_configure(void)
++{
++      if (ccdc_if_type == VPFE_RAW_BAYER) {
++              dev_info(dev, "calling ccdc_config_raw()\n");
++              ccdc_config_raw();
++      } else {
++              dev_info(dev, "calling ccdc_config_ycbcr()\n");
++              ccdc_config_ycbcr();
++      }
++      return 0;
++}
++
++static int ccdc_set_buftype(enum ccdc_buftype buf_type)
++{
++      if (ccdc_if_type == VPFE_RAW_BAYER)
++              ccdc_hw_params_raw.buf_type = buf_type;
++      else
++              ccdc_hw_params_ycbcr.buf_type = buf_type;
++      return 0;
++}
++
++static int ccdc_get_buftype(enum ccdc_buftype *buf_type)
++{
++      if (ccdc_if_type == VPFE_RAW_BAYER)
++              *buf_type = ccdc_hw_params_raw.buf_type;
++      else
++              *buf_type = ccdc_hw_params_ycbcr.buf_type;
++      return 0;
++}
++
++static int ccdc_enum_pix(enum vpfe_hw_pix_format *hw_pix, int i)
++{
++      int ret = -EINVAL;
++      if (ccdc_if_type == VPFE_RAW_BAYER) {
++              if (i < CCDC_MAX_RAW_BAYER_FORMATS) {
++                      *hw_pix = ccdc_raw_bayer_hw_formats[i];
++                      ret = 0;
++              }
++      } else {
++              if (i < CCDC_MAX_RAW_YUV_FORMATS) {
++                      *hw_pix = ccdc_raw_yuv_hw_formats[i];
++                      ret = 0;
++              }
++      }
++      return ret;
++}
++
++static int ccdc_set_pixel_format(enum vpfe_hw_pix_format pixfmt)
++{
++      if (ccdc_if_type == VPFE_RAW_BAYER) {
++              ccdc_hw_params_raw.pix_fmt = CCDC_PIXFMT_RAW;
++              if (pixfmt == VPFE_BAYER_8BIT_PACK_ALAW)
++                      ccdc_hw_params_raw.alaw.b_alaw_enable = 1;
++              else if (pixfmt != VPFE_BAYER)
++                      return -1;
++      } else {
++              if (pixfmt == VPFE_YUYV)
++                      ccdc_hw_params_ycbcr.pix_order = CCDC_PIXORDER_YCBYCR;
++              else if (pixfmt == VPFE_UYVY)
++                      ccdc_hw_params_ycbcr.pix_order = CCDC_PIXORDER_CBYCRY;
++              else
++                      return -1;
++      }
++      return 0;
++}
++
++static int ccdc_get_pixel_format(enum vpfe_hw_pix_format *pixfmt)
++{
++      if (ccdc_if_type == VPFE_RAW_BAYER)
++              if (ccdc_hw_params_raw.alaw.b_alaw_enable)
++                      *pixfmt = VPFE_BAYER_8BIT_PACK_ALAW;
++              else
++                      *pixfmt = VPFE_BAYER;
++      else {
++              if (ccdc_hw_params_ycbcr.pix_order == CCDC_PIXORDER_YCBYCR)
++                      *pixfmt = VPFE_YUYV;
++              else
++                      *pixfmt = VPFE_UYVY;
++      }
++      return 0;
++}
++
++static int ccdc_set_image_window(struct v4l2_rect *win)
++{
++      if (ccdc_if_type == VPFE_RAW_BAYER) {
++              ccdc_hw_params_raw.win.top = win->top;
++              ccdc_hw_params_raw.win.left = win->left;
++              ccdc_hw_params_raw.win.width = win->width;
++              ccdc_hw_params_raw.win.height = win->height;
++      } else {
++              ccdc_hw_params_ycbcr.win.top = win->top;
++              ccdc_hw_params_ycbcr.win.left = win->left;
++              ccdc_hw_params_ycbcr.win.width = win->width;
++              ccdc_hw_params_ycbcr.win.height = win->height;
++      }
++      return 0;
++}
++
++static int ccdc_get_image_window(struct v4l2_rect *win)
++{
++      if (ccdc_if_type == VPFE_RAW_BAYER) {
++              win->top = ccdc_hw_params_raw.win.top;
++              win->left = ccdc_hw_params_raw.win.left;
++              win->width = ccdc_hw_params_raw.win.width;
++              win->height = ccdc_hw_params_raw.win.height;
++      } else {
++              win->top = ccdc_hw_params_ycbcr.win.top;
++              win->left = ccdc_hw_params_ycbcr.win.left;
++              win->width = ccdc_hw_params_ycbcr.win.width;
++              win->height = ccdc_hw_params_ycbcr.win.height;
++      }
++      return 0;
++}
++
++static int ccdc_get_line_length(unsigned int *len)
++{
++      if (ccdc_if_type == VPFE_RAW_BAYER) {
++              if ((ccdc_hw_params_raw.alaw.b_alaw_enable) ||
++                  (ccdc_hw_params_raw.data_sz == _8BITS))
++                      *len = ccdc_hw_params_raw.win.width;
++              else
++                      *len = ccdc_hw_params_raw.win.width * 2;
++      } else
++              *len = ccdc_hw_params_ycbcr.win.width * 2;
++      return 0;
++}
++
++static int ccdc_set_frame_format(enum ccdc_frmfmt frm_fmt)
++{
++      if (ccdc_if_type == VPFE_RAW_BAYER)
++              ccdc_hw_params_raw.frm_fmt = frm_fmt;
++      else
++              ccdc_hw_params_ycbcr.frm_fmt = frm_fmt;
++      return 0;
++}
++
++static int ccdc_get_frame_format(enum ccdc_frmfmt *frm_fmt)
++{
++      if (ccdc_if_type == VPFE_RAW_BAYER)
++              *frm_fmt = ccdc_hw_params_raw.frm_fmt;
++      else
++              *frm_fmt = ccdc_hw_params_ycbcr.frm_fmt;
++      return 0;
++}
++
++static int ccdc_getfid(void)
++{
++      int fid = (regr(SYN_MODE) >> 15) & 0x1;
++      return fid;
++}
++
++/* misc operations */
++static inline void ccdc_setfbaddr(unsigned long addr)
++{
++      regw(addr & 0xffffffe0, SDR_ADDR);
++}
++
++static int ccdc_set_hw_if_type(enum vpfe_hw_if_type iface)
++{
++      ccdc_if_type = iface;
++      return 0;
++}
++
++struct ccdc_hw_device ccdc_hw_dev = {
++      .name = "DM6446 CCDC",
++      .set_ccdc_base = ccdc_set_ccdc_base,
++      .set_vpss_base = ccdc_set_vpss_base,
++      .get_ccdc_base = ccdc_get_ccdc_base,
++      .get_vpss_base = ccdc_get_vpss_base,
++      .open = ccdc_open,
++      .reset = ccdc_sbl_reset,
++      .enable = ccdc_enable,
++      .set_hw_if_type = ccdc_set_hw_if_type,
++      .setparams = ccdc_setparams,
++      .configure = ccdc_configure,
++      .set_buftype = ccdc_set_buftype,
++      .get_buftype = ccdc_get_buftype,
++      .enum_pix = ccdc_enum_pix,
++      .set_pixelformat = ccdc_set_pixel_format,
++      .get_pixelformat = ccdc_get_pixel_format,
++      .set_frame_format = ccdc_set_frame_format,
++      .get_frame_format = ccdc_get_frame_format,
++      .set_image_window = ccdc_set_image_window,
++      .get_image_window = ccdc_get_image_window,
++      .get_line_length = ccdc_get_line_length,
++      .setfbaddr = ccdc_setfbaddr,
++      .getfid = ccdc_getfid,
++      .close = ccdc_close
++};
++EXPORT_SYMBOL(ccdc_hw_dev);
++
++static int davinci_ccdc_init(void)
++{
++      return 0;
++}
++
++static void davinci_ccdc_exit(void)
++{
++}
++
++subsys_initcall(davinci_ccdc_init);
++module_exit(davinci_ccdc_exit);
++
++MODULE_LICENSE("GPL");
+diff --git a/drivers/media/video/davinci/ccdc_davinci.h b/drivers/media/video/davinci/ccdc_davinci.h
+new file mode 100644
+index 0000000..188e4f1
+--- /dev/null
++++ b/drivers/media/video/davinci/ccdc_davinci.h
+@@ -0,0 +1,335 @@
++/*
++ * Copyright (C) 2006-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
++ */
++#ifndef _CCDC_DAVINCI_H
++#define _CCDC_DAVINCI_H
++#include <media/davinci/ccdc_common.h>
++
++/* enum for No of pixel per line to be avg. in Black Clamping*/
++enum sample_length {
++      _1PIXELS = 0,
++      _2PIXELS,
++      _4PIXELS,
++      _8PIXELS,
++      _16PIXELS
++};
++
++/* Define to enable/disable video port */
++#define VIDEO_PORT_ENABLE     (1)
++#define FP_NUM_BYTES          (4)
++/* Define for extra pixel/line and extra lines/frame */
++#define NUM_EXTRAPIXELS               8
++#define NUM_EXTRALINES                8
++
++/* settings for commonly used video formats */
++#define CCDC_WIN_PAL     {0, 0, 720, 576}
++/* ntsc square pixel */
++#define CCDC_WIN_VGA  {0, 0, (640 + NUM_EXTRAPIXELS), (480 + NUM_EXTRALINES)}
++
++/* enum for No of lines in Black Clamping */
++enum sample_line {
++      _1LINES = 0,
++      _2LINES,
++      _4LINES,
++      _8LINES,
++      _16LINES
++};
++
++/* enum for Alaw gama width */
++enum gama_width {
++      BITS_15_6 = 0,
++      BITS_14_5,
++      BITS_13_4,
++      BITS_12_3,
++      BITS_11_2,
++      BITS_10_1,
++      BITS_09_0
++};
++
++enum data_size {
++      _16BITS = 0,
++      _15BITS,
++      _14BITS,
++      _13BITS,
++      _12BITS,
++      _11BITS,
++      _10BITS,
++      _8BITS
++};
++
++struct ccdc_imgwin {
++      unsigned int top;
++      unsigned int left;
++      unsigned int width;
++      unsigned int height;
++};
++
++/* structure for ALaw */
++struct a_law {
++      /* Enable/disable A-Law */
++      unsigned char b_alaw_enable;
++      /*Gama Width Input */
++      enum gama_width gama_wd;
++};
++
++/* structure for Black Clamping */
++struct black_clamp {
++      unsigned char b_clamp_enable;
++      /* only if bClampEnable is TRUE */
++      enum sample_length sample_pixel;
++      /* only if bClampEnable is TRUE */
++      enum sample_line sample_ln;
++      /* only if bClampEnable is TRUE */
++      unsigned short start_pixel;
++      /* only if bClampEnable is TRUE */
++      unsigned short sgain;
++      /* only if bClampEnable is FALSE */
++      unsigned short dc_sub;
++};
++
++/* structure for Black Level Compensation */
++struct black_compensation {
++      /* Constant value to subtract from Red component */
++      char r_comp;
++      /* Constant value to subtract from Gr component */
++      char gr_comp;
++      /* Constant value to subtract from Blue component */
++      char b_comp;
++      /* Constant value to subtract from Gb component */
++      char gb_comp;
++};
++
++/* structure for fault pixel correction */
++struct fault_pixel {
++      /*Enable or Disable fault pixel correction */
++      unsigned char fpc_enable;
++      /*Number of fault pixel */
++      unsigned short fp_num;
++      /*Address of fault pixel table */
++      unsigned int fpc_table_addr;
++};
++
++/* Structure for CCDC configuration parameters for raw capture mode passed
++ * by application
++ */
++struct ccdc_config_params_raw {
++      /* pixel format */
++      enum ccdc_pixfmt pix_fmt;
++      /* progressive or interlaced frame */
++      enum ccdc_frmfmt frm_fmt;
++      /* video window */
++      struct ccdc_imgwin win;
++      /* field id polarity */
++      enum ccdc_pinpol fid_pol;
++      /* vertical sync polarity */
++      enum ccdc_pinpol vd_pol;
++      /* horizontal sync polarity */
++      enum ccdc_pinpol hd_pol;
++      /* enable to store the image in inverse order in
++       * memory(bottom to top)
++       */
++      unsigned char image_invert_enable;
++      /* data size value from 8 to 16 bits */
++      enum data_size data_sz;
++      /* Structure for Optional A-Law */
++      struct a_law alaw;
++      /* Structure for Optical Black Clamp */
++      struct black_clamp blk_clamp;
++      /* Structure for Black Compensation */
++      struct black_compensation blk_comp;
++      /* Structure for Fault Pixel Module Configuration */
++      struct fault_pixel fault_pxl;
++};
++
++struct ccdc_params_ycbcr {
++      /* pixel format */
++      enum ccdc_pixfmt pix_fmt;
++      /* progressive or interlaced frame */
++      enum ccdc_frmfmt frm_fmt;
++      /* video window */
++      struct ccdc_imgwin win;
++      /* field id polarity */
++      enum ccdc_pinpol fid_pol;
++      /* vertical sync polarity */
++      enum ccdc_pinpol vd_pol;
++      /* horizontal sync polarity */
++      enum ccdc_pinpol hd_pol;
++      /* enable BT.656 embedded sync mode */
++      int bt656_enable;
++      /* cb:y:cr:y or y:cb:y:cr in memory */
++      enum ccdc_pixorder pix_order;
++      /* interleaved or separated fields  */
++      enum ccdc_buftype buf_type;
++};
++
++#ifdef __KERNEL__
++#include <linux/io.h>
++/* Structure for CCDC configuration parameters for raw capture mode */
++struct ccdc_params_raw {
++      /* pixel format */
++      enum ccdc_pixfmt pix_fmt;
++      /* progressive or interlaced frame */
++      enum ccdc_frmfmt frm_fmt;
++      /* video window */
++      struct ccdc_imgwin win;
++      /* field id polarity */
++      enum ccdc_pinpol fid_pol;
++      /* vertical sync polarity */
++      enum ccdc_pinpol vd_pol;
++      /* horizontal sync polarity */
++      enum ccdc_pinpol hd_pol;
++      /* interleaved or separated fields */
++      enum ccdc_buftype buf_type;
++      /* enable to store the image in inverse
++       * order in memory(bottom to top)
++       */
++      unsigned char image_invert_enable;
++      /* data size value from 8 to 16 bits */
++      enum data_size data_sz;
++      /* Structure for Optional A-Law */
++      struct a_law alaw;
++      /* Structure for Optical Black Clamp */
++      struct black_clamp blk_clamp;
++      /* Structure for Black Compensation */
++      struct black_compensation blk_comp;
++      /* Structure for Fault Pixel Module Configuration */
++      struct fault_pixel fault_pxl;
++};
++
++/**************************************************************************\
++* Register OFFSET Definitions
++\**************************************************************************/
++
++#define PID                             0x0
++#define PCR                             0x4
++#define SYN_MODE                        0x8
++#define HD_VD_WID                       0xc
++#define PIX_LINES                       0x10
++#define HORZ_INFO                       0x14
++#define VERT_START                      0x18
++#define VERT_LINES                      0x1c
++#define CULLING                         0x20
++#define HSIZE_OFF                       0x24
++#define SDOFST                          0x28
++#define SDR_ADDR                        0x2c
++#define CLAMP                           0x30
++#define DCSUB                           0x34
++#define COLPTN                          0x38
++#define BLKCMP                          0x3c
++#define FPC                             0x40
++#define FPC_ADDR                        0x44
++#define VDINT                           0x48
++#define ALAW                            0x4c
++#define REC656IF                        0x50
++#define CCDCFG                          0x54
++#define FMTCFG                          0x58
++#define FMT_HORZ                        0x5c
++#define FMT_VERT                        0x60
++#define FMT_ADDR0                       0x64
++#define FMT_ADDR1                       0x68
++#define FMT_ADDR2                       0x6c
++#define FMT_ADDR3                       0x70
++#define FMT_ADDR4                       0x74
++#define FMT_ADDR5                       0x78
++#define FMT_ADDR6                       0x7c
++#define FMT_ADDR7                       0x80
++#define PRGEVEN_0                       0x84
++#define PRGEVEN_1                       0x88
++#define PRGODD_0                        0x8c
++#define PRGODD_1                        0x90
++#define VP_OUT                          0x94
++
++
++/***************************************************************
++*     Define for various register bit mask and shifts for CCDC
++****************************************************************/
++#define CCDC_FID_POL_MASK                     (0x01)
++#define CCDC_FID_POL_SHIFT                    (4)
++#define CCDC_HD_POL_MASK                      (0x01)
++#define CCDC_HD_POL_SHIFT                     (3)
++#define CCDC_VD_POL_MASK                      (0x01)
++#define CCDC_VD_POL_SHIFT                     (2)
++#define CCDC_HSIZE_OFF_MASK                   (0xffffffe0)
++#define CCDC_32BYTE_ALIGN_VAL                 (31)
++#define CCDC_FRM_FMT_MASK                     (0x01)
++#define CCDC_FRM_FMT_SHIFT                    (7)
++#define CCDC_DATA_SZ_MASK                     (0x07)
++#define CCDC_DATA_SZ_SHIFT                    (8)
++#define CCDC_PIX_FMT_MASK                     (0x03)
++#define CCDC_PIX_FMT_SHIFT                    (12)
++#define CCDC_VP2SDR_DISABLE                   (0xFFFBFFFF)
++#define CCDC_WEN_ENABLE                               (0x01 << 17)
++#define CCDC_SDR2RSZ_DISABLE                  (0xFFF7FFFF)
++#define CCDC_VDHDEN_ENABLE                    (0x01 << 16)
++#define CCDC_LPF_ENABLE                               (0x01 << 14)
++#define CCDC_ALAW_ENABLE                      (0x01 << 3)
++#define CCDC_ALAW_GAMA_WD_MASK                        (0x07)
++#define CCDC_BLK_CLAMP_ENABLE                 (0x01 << 31)
++#define CCDC_BLK_SGAIN_MASK                   (0x1F)
++#define CCDC_BLK_ST_PXL_MASK                  (0x7FFF)
++#define CCDC_BLK_ST_PXL_SHIFT                 (10)
++#define CCDC_BLK_SAMPLE_LN_MASK                       (0x07)
++#define CCDC_BLK_SAMPLE_LN_SHIFT              (28)
++#define CCDC_BLK_SAMPLE_LINE_MASK             (0x07)
++#define CCDC_BLK_SAMPLE_LINE_SHIFT            (25)
++#define CCDC_BLK_DC_SUB_MASK                  (0x03FFF)
++#define CCDC_BLK_COMP_MASK                    (0x000000FF)
++#define CCDC_BLK_COMP_GB_COMP_SHIFT           (8)
++#define CCDC_BLK_COMP_GR_COMP_SHIFT           (16)
++#define CCDC_BLK_COMP_R_COMP_SHIFT            (24)
++#define CCDC_LATCH_ON_VSYNC_DISABLE           (0x01 << 15)
++#define CCDC_FPC_ENABLE                               (0x01 << 15)
++#define CCDC_FPC_DISABLE                      (0x0)
++#define CCDC_FPC_FPC_NUM_MASK                         (0x7FFF)
++#define CCDC_DATA_PACK_ENABLE                 (0x01<<11)
++#define CCDC_FMTCFG_VPIN_MASK                 (0x07)
++#define CCDC_FMTCFG_VPIN_SHIFT                        (12)
++#define CCDC_FMT_HORZ_FMTLNH_MASK             (0x1FFF)
++#define CCDC_FMT_HORZ_FMTSPH_MASK             (0x1FFF)
++#define CCDC_FMT_HORZ_FMTSPH_SHIFT            (16)
++#define CCDC_FMT_VERT_FMTLNV_MASK             (0x1FFF)
++#define CCDC_FMT_VERT_FMTSLV_MASK             (0x1FFF)
++#define CCDC_FMT_VERT_FMTSLV_SHIFT            (16)
++#define CCDC_VP_OUT_VERT_NUM_MASK             (0x3FFF)
++#define CCDC_VP_OUT_VERT_NUM_SHIFT            (17)
++#define CCDC_VP_OUT_HORZ_NUM_MASK             (0x1FFF)
++#define CCDC_VP_OUT_HORZ_NUM_SHIFT            (4)
++#define CCDC_VP_OUT_HORZ_ST_MASK              (0x000F)
++#define CCDC_HORZ_INFO_SPH_SHIFT              (16)
++#define CCDC_VERT_START_SLV0_SHIFT            (16)
++#define CCDC_VDINT_VDINT0_SHIFT                       (16)
++#define CCDC_VDINT_VDINT1_MASK                        (0xFFFF)
++
++/* SBL register and mask defination */
++#define SBL_PCR_VPSS                          (4)
++#define SBL_PCR_CCDC_WBL_O                    (0xFF7FFFFF)
++
++#define PPC_RAW                                       (1)
++#define DCSUB_DEFAULT_VAL                     (0)
++#define CLAMP_DEFAULT_VAL                     (0)
++#define ENABLE_VIDEO_PORT                     (0x00008000)
++#define DISABLE_VIDEO_PORT                    (0)
++#define CCDC_COLPTN_VAL                               (0xBB11BB11)
++#define TWO_BYTES_PER_PIXEL                   (2)
++#define INTERLACED_IMAGE_INVERT                       (0x4B6D)
++#define INTERLACED_NO_IMAGE_INVERT            (0x0249)
++#define PROGRESSIVE_IMAGE_INVERT              (0x4000)
++#define PROGRESSIVE_NO_IMAGE_INVERT           (0)
++#define CCDC_INTERLACED_HEIGHT_SHIFT          (1)
++
++#endif
++#endif                                /* CCDC_DAVINCI_H */
+diff --git a/include/media/ccdc_davinci.h b/include/media/ccdc_davinci.h
+deleted file mode 100644
+index 9f0a08d..0000000
+--- a/include/media/ccdc_davinci.h
++++ /dev/null
+@@ -1,144 +0,0 @@
+-/*
+- *
+- * Copyright (C) 2006 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
+- */
+-/* ccdc_davinci.h */
+-
+-#ifndef CCDC_DAVINCI_H
+-#define CCDC_DAVINCI_H
+-#include <linux/types.h>
+-
+-#ifdef __KERNEL__
+-#include <asm/arch/hardware.h>
+-#include <asm/io.h>
+-#endif
+-
+-#include <linux/videodev.h>
+-
+-typedef enum ccdc_pixfmt {
+-      CCDC_PIXFMT_RAW = 0,
+-      CCDC_PIXFMT_YCBCR_16BIT = 1,
+-      CCDC_PIXFMT_YCBCR_8BIT = 2
+-} ccdc_pixfmt;
+-
+-typedef enum ccdc_frmfmt {
+-      CCDC_FRMFMT_PROGRESSIVE = 0,
+-      CCDC_FRMFMT_INTERLACED = 1
+-} ccdc_frmfmt;
+-
+-typedef enum ccdc_pinpol {
+-      CCDC_PINPOL_POSITIVE = 0,
+-      CCDC_PINPOL_NEGATIVE = 1
+-} ccdc_pinpol;
+-
+-/* PIXEL ORDER IN MEMORY from LSB to MSB */
+-/* only applicable for 8-bit input mode  */
+-typedef enum ccdc_pixorder {
+-      CCDC_PIXORDER_CBYCRY = 1,
+-      CCDC_PIXORDER_YCBYCR = 0
+-} ccdc_pixorder;
+-
+-typedef enum ccdc_buftype {
+-      CCDC_BUFTYPE_FLD_INTERLEAVED,
+-      CCDC_BUFTYPE_FLD_SEPARATED
+-} ccdc_buftype;
+-
+-typedef struct v4l2_rect ccdc_imgwin;
+-
+-typedef struct ccdc_params_ycbcr {
+-      ccdc_pixfmt pix_fmt;    /* pixel format                     */
+-      ccdc_frmfmt frm_fmt;    /* progressive or interlaced frame  */
+-      ccdc_imgwin win;        /* video window                     */
+-      ccdc_pinpol fid_pol;    /* field id polarity                */
+-      ccdc_pinpol vd_pol;     /* vertical sync polarity           */
+-      ccdc_pinpol hd_pol;     /* horizontal sync polarity         */
+-      int bt656_enable;       /* enable BT.656 embedded sync mode */
+-      ccdc_pixorder pix_order;/* cb:y:cr:y or y:cb:y:cr in memory */
+-      ccdc_buftype buf_type;  /* interleaved or separated fields  */
+-} ccdc_params_ycbcr;
+-
+-#ifdef __KERNEL__
+-/**************************************************************************\
+-* Register OFFSET Definitions
+-\**************************************************************************/
+-#define PID                             0x0
+-#define PCR                             0x4
+-#define SYN_MODE                        0x8
+-#define HD_VD_WID                       0xc
+-#define PIX_LINES                       0x10
+-#define HORZ_INFO                       0x14
+-#define VERT_START                      0x18
+-#define VERT_LINES                      0x1c
+-#define CULLING                         0x20
+-#define HSIZE_OFF                       0x24
+-#define SDOFST                          0x28
+-#define SDR_ADDR                        0x2c
+-#define CLAMP                           0x30
+-#define DCSUB                           0x34
+-#define COLPTN                          0x38
+-#define BLKCMP                          0x3c
+-#define FPC                             0x40
+-#define FPC_ADDR                        0x44
+-#define VDINT                           0x48
+-#define ALAW                            0x4c
+-#define REC656IF                        0x50
+-#define CCDCFG                          0x54
+-#define FMTCFG                          0x58
+-#define FMT_HORZ                        0x5c
+-#define FMT_VERT                        0x50
+-#define FMT_ADDR0                       0x64
+-#define FMT_ADDR1                       0x68
+-#define FMT_ADDR2                       0x6c
+-#define FMT_ADDR3                       0x70
+-#define FMT_ADDR4                       0x74
+-#define FMT_ADDR5                       0x78
+-#define FMT_ADDR6                       0x7c
+-#define FMT_ADDR7                       0x80
+-#define PRGEVEN_0                       0x84
+-#define PRGEVEN_1                       0x88
+-#define PRGODD_0                        0x8c
+-#define PRGODD_1                        0x90
+-#define VP_OUT                          0x94
+-
+-#define CCDC_IOBASE                     (0x01c70400)
+-
+-#define regw(val, reg)    davinci_writel(val, (reg)+CCDC_IOBASE)
+-#define regr(reg)         davinci_readl((reg)+CCDC_IOBASE)
+-
+-extern void ccdc_reset(void);
+-extern void ccdc_config_ycbcr(ccdc_params_ycbcr * params);
+-extern void ccdc_setwin(ccdc_params_ycbcr * params);
+-
+-/* inline functions that must be fast because they are called frequently */
+-static inline void ccdc_enable(int flag)
+-{
+-      regw(flag, PCR);
+-}
+-
+-static inline void ccdc_setfbaddr(unsigned long paddr)
+-{
+-      regw(paddr & 0xffffffe0, SDR_ADDR);
+-}
+-
+-static inline int ccdc_getfid(void)
+-{
+-      int fid = (regr(SYN_MODE) >> 15) & 0x1;
+-      return fid;
+-}
+-#endif
+-
+-#endif /* CCDC_DAVINCI_H */
+-- 1.6.0.4 
\ No newline at end of file
diff --git a/recipes/linux/linux-davinci/vfpe5.patch b/recipes/linux/linux-davinci/vfpe5.patch
new file mode 100644 (file)
index 0000000..160908a
--- /dev/null
@@ -0,0 +1,132 @@
+Subject:
+[PATCH 5/7] Kconfig and Makefile changes for vpfe capture driver
+From:
+m-karicheri2-l0cyMroinI0@public.gmane.org
+Date:
+Fri, 13 Mar 2009 17:23:32 -0400
+To:
+davinci-linux-open-source-VycZQUHpC/PFrsHnngEfi1aTQe2KTcn/@public.gmane.org, davinci_opensource_ccb-uAqBSO/uNfhBDgjK7y7TUQ@public.gmane.org, psp_video-uAqBSO/uNfhBDgjK7y7TUQ@public.gmane.org
+Newsgroups:
+gmane.linux.davinci
+
+Adding updates to video Kconfig and Makefile and adding
+Makefile for building vpfe-capture files
+
+Signed-off-by: Murali Karicheri <m-karicheri2-l0cyMroinI0@public.gmane.org>
+---
+ drivers/media/video/Kconfig          |   48 ++++++++++++++++++++++++----------
+ drivers/media/video/Makefile         |    6 +---
+ drivers/media/video/davinci/Makefile |    8 +++++
+ 3 files changed, 43 insertions(+), 19 deletions(-)
+ create mode 100644 drivers/media/video/davinci/Makefile
+
+diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
+index 1dd98d8..ea3a526 100644
+--- a/drivers/media/video/Kconfig
++++ b/drivers/media/video/Kconfig
+@@ -485,25 +485,45 @@ config VIDEO_VIVI
+         Say Y here if you want to test video apps or debug V4L devices.
+         In doubt, say N.
+-config VIDEO_TVP5146
+-      tristate "TVP5146 video decoder"
+-      depends on I2C && ARCH_DAVINCI
++config VIDEO_VPFE_CAPTURE
++      tristate "VPFE Video Capture Driver"
++      depends on VIDEO_V4L2 && ARCH_DAVINCI
++      select VIDEOBUF_DMA_CONTIG
+       help
+-        Support for I2C bus based TVP5146 configuration.
++        Support for DMXXXX VPFE based frame grabber. This is the
++        common V4L2 module for following DMXXX SoCs from Texas
++        Instruments:- DM6446 & DM355.
+         To compile this driver as a module, choose M here: the
+-        module will be called tvp5146.
++        module will be called vpfe-capture.
+-config VIDEO_DAVINCI
+-      tristate "Davinci Video Capture"
+-      depends on VIDEO_DEV && VIDEO_TVP5146 && ARCH_DAVINCI
+-      select VIDEOBUF_GEN
+-      select VIDEOBUF_DMA_SG
++config VIDEO_DAVINCI_CCDC
++      tristate "DM6446 CCDC HW module"
++      depends on ARCH_DAVINCI_DM644x && VIDEO_VPFE_CAPTURE
++      default y
+       help
+-        Support for Davinci based frame grabber through CCDC.
+-
+-        To compile this driver as a module, choose M here: the
+-        module will be called vpfe.
++         Enables DaVinci CCD hw module. DaVinci CCDC hw interfaces
++         with decoder modules such as TVP5146 over BT656 or
++         sensor module such as MT9T001 over a raw interface. This
++         module configures the interface and CCDC/ISIF to do
++         video frame capture from slave decoders.
++
++         To compile this driver as a module, choose M here: the
++         module will be called vpfe.
++
++config VIDEO_DM355_CCDC
++      tristate "DM355 CCDC HW module"
++      depends on ARCH_DAVINCI_DM355 && VIDEO_VPFE_CAPTURE
++      default y
++      help
++         Enables DM355 CCD hw module. DM355 CCDC hw interfaces
++         with decoder modules such as TVP5146 over BT656 or
++         sensor module such as MT9T001 over a raw interface. This
++         module configures the interface and CCDC/ISIF to do
++         video frame capture from a slave decoders
++
++         To compile this driver as a module, choose M here: the
++         module will be called vpfe.
+ source "drivers/media/video/bt8xx/Kconfig"
+diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
+index 863b5c8..f8b6c0c 100644
+--- a/drivers/media/video/Makefile
++++ b/drivers/media/video/Makefile
+@@ -10,8 +10,6 @@ stkwebcam-objs       :=      stk-webcam.o stk-sensor.o
+ omap2cam-objs :=      omap24xxcam.o omap24xxcam-dma.o
+-davinci-vpfe-objs   :=  ccdc_davinci.o davinci_vpfe.o
+-
+ videodev-objs :=      v4l2-dev.o v4l2-ioctl.o
+ videodev-objs :=      v4l2-dev.o v4l2-ioctl.o v4l2-device.o v4l2-subdev.o
+@@ -29,6 +27,7 @@ endif
+ obj-$(CONFIG_VIDEO_TUNER) += tuner.o
++obj-$(CONFIG_ARCH_DAVINCI)        += davinci/
+ obj-$(CONFIG_VIDEO_BT848) += bt8xx/
+ obj-$(CONFIG_VIDEO_IR_I2C)  += ir-kbd-i2c.o
+ obj-$(CONFIG_VIDEO_TVAUDIO) += tvaudio.o
+@@ -135,9 +134,6 @@ obj-$(CONFIG_USB_S2255)            += s2255drv.o
+ obj-$(CONFIG_VIDEO_IVTV) += ivtv/
+ obj-$(CONFIG_VIDEO_CX18) += cx18/
+-obj-$(CONFIG_VIDEO_DAVINCI)     += davinci-vpfe.o
+-obj-$(CONFIG_VIDEO_TVP5146)     += tvp5146.o
+-
+ obj-$(CONFIG_VIDEO_VIVI) += vivi.o
+ obj-$(CONFIG_VIDEO_CX23885) += cx23885/
+diff --git a/drivers/media/video/davinci/Makefile b/drivers/media/video/davinci/Makefile
+new file mode 100644
+index 0000000..77fe038
+--- /dev/null
++++ b/drivers/media/video/davinci/Makefile
+@@ -0,0 +1,8 @@
++#
++# Makefile for the davinci video device drivers.
++#
++
++# Capture: DaVinci and DM355
++obj-$(CONFIG_VIDEO_DAVINCI_CCDC) += ccdc_davinci.o
++obj-$(CONFIG_VIDEO_DM355_CCDC) += ccdc_dm355.o
++obj-$(CONFIG_VIDEO_VPFE_CAPTURE) += vpfe_capture.o
+-- 1.6.0.4 
\ No newline at end of file
diff --git a/recipes/linux/linux-davinci/vfpe6.patch b/recipes/linux/linux-davinci/vfpe6.patch
new file mode 100644 (file)
index 0000000..b425eea
--- /dev/null
@@ -0,0 +1,224 @@
+Subject:
+[PATCH 6/7] platform-related-updates for vpfe capture driver on DM6446
+From:
+m-karicheri2-l0cyMroinI0@public.gmane.org
+Date:
+Fri, 13 Mar 2009 17:24:04 -0400
+To:
+davinci-linux-open-source-VycZQUHpC/PFrsHnngEfi1aTQe2KTcn/@public.gmane.org, davinci_opensource_ccb-uAqBSO/uNfhBDgjK7y7TUQ@public.gmane.org, psp_video-uAqBSO/uNfhBDgjK7y7TUQ@public.gmane.org
+Newsgroups:
+gmane.linux.davinci
+
+Add platform related changes for vpfe capture driver on DM6446
+
+Signed-off-by: Murali Karicheri <m-karicheri2-l0cyMroinI0@public.gmane.org>
+---
+ arch/arm/mach-davinci/board-dm644x-evm.c    |   88 ++++++++++++++++++++++++++-
+ arch/arm/mach-davinci/dm644x.c              |   42 +++++++++++++
+ arch/arm/mach-davinci/include/mach/dm644x.h |    2 +
+ 3 files changed, 130 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm/mach-davinci/board-dm644x-evm.c b/arch/arm/mach-davinci/board-dm644x-evm.c
+index 20ec961..5f4d9a8 100644
+--- a/arch/arm/mach-davinci/board-dm644x-evm.c
++++ b/arch/arm/mach-davinci/board-dm644x-evm.c
+@@ -27,7 +27,9 @@
+ #include <linux/io.h>
+ #include <linux/phy.h>
+ #include <linux/clk.h>
+-
++#include <linux/videodev2.h>
++#include <media/v4l2-int-device.h>
++#include <media/tvp514x.h>
+ #include <asm/setup.h>
+ #include <asm/mach-types.h>
+@@ -161,6 +163,41 @@ static struct platform_device davinci_fb_device = {
+       .num_resources = 0,
+ };
++
++#define TVP514X_STD_ALL       (V4L2_STD_NTSC | V4L2_STD_PAL)
++static struct vpfe_capture_input vpfe_capture_inputs = {
++      .num_inputs = VPFE_MAX_DEC_INPUTS,
++      .current_input = 0,
++      .inputs[0] = {
++              .dec_name = TVP514X_MODULE_NAME,
++              .input = {
++                      .index = 0,
++                      .name = "COMPOSITE",
++                      .type = V4L2_INPUT_TYPE_CAMERA,
++                      .std = TVP514X_STD_ALL,
++              },
++              .route = {
++                      .input = INPUT_CVBS_VI2B,
++                      .output = OUTPUT_10BIT_422_EMBEDDED_SYNC,
++              },
++              .routing_supported = 1,
++      },
++      .inputs[1] = {
++              .dec_name = TVP514X_MODULE_NAME,
++              .input = {
++                      .index = 1,
++                      .name = "SVIDEO",
++                      .type = V4L2_INPUT_TYPE_CAMERA,
++                      .std = TVP514X_STD_ALL,
++              },
++              .route = {
++                      .input = INPUT_SVIDEO_VI2C_VI1C,
++                      .output = OUTPUT_10BIT_422_EMBEDDED_SYNC,
++              },
++              .routing_supported = 1,
++      },
++};
++
+ static struct platform_device rtc_dev = {
+       .name           = "rtc_davinci_evm",
+       .id             = -1,
+@@ -447,6 +484,48 @@ int dm6446evm_eeprom_write(void *buf, off_t off, size_t count)
+ }
+ EXPORT_SYMBOL(dm6446evm_eeprom_write);
++#define TVP5146_I2C_ADDR              (0x5D)
++static struct v4l2_ifparm tvp5146_ifparm = {
++      .if_type = V4L2_IF_TYPE_BT656,
++      .u = {
++            .bt656 = {
++                      .frame_start_on_rising_vs = 1,
++                      .bt_sync_correct = 0,
++                      .swap = 0,
++                      .latch_clk_inv = 0,
++                      .nobt_hs_inv = 0,       /* active high */
++                      .nobt_vs_inv = 0,       /* active high */
++                      .mode = V4L2_IF_TYPE_BT656_MODE_BT_8BIT,
++                      .clock_min = TVP514X_XCLK_BT656,
++                      .clock_max = TVP514X_XCLK_BT656,
++                      },
++            },
++};
++
++/**
++ * @brief tvp5146_g_ifparm - Returns the TVP5146 decoder interface parameters
++ *
++ * @param p - pointer to v4l2_ifparm structure
++ * @return result of operation - 0 is success
++ */
++static int tvp5146_g_ifparm(struct v4l2_ifparm *p)
++{
++      if (p == NULL)
++              return -EINVAL;
++
++      *p = tvp5146_ifparm;
++      return 0;
++}
++
++#define TVP5146_NUM_INPUTS            ARRAY_SIZE(tvp5146_input_list)
++
++static struct tvp514x_platform_data tvp5146_pdata = {
++      .master = CAPTURE_DRV_NAME,
++      .ifparm = tvp5146_g_ifparm,
++      .hs_polarity = 1,
++      .vs_polarity = 1
++};
++
+ /*
+  * MSP430 supports RTC, card detection, input from IR remote, and
+  * a bit more.  It triggers interrupts on GPIO(7) from pressing
+@@ -557,9 +636,12 @@ static struct i2c_board_info __initdata i2c_info[] =  {
+               I2C_BOARD_INFO("24c256", 0x50),
+               .platform_data  = &eeprom_info,
+       },
++      {
++              I2C_BOARD_INFO("tvp5146", TVP5146_I2C_ADDR),
++              .platform_data = &tvp5146_pdata,
++      },
+       /* ALSO:
+        * - tvl320aic33 audio codec (0x1b)
+-       * - tvp5146 video decoder (0x5d)
+        */
+ };
+@@ -591,6 +673,8 @@ static void __init
+ davinci_evm_map_io(void)
+ {
+       davinci_map_common_io();
++      /* setup input configuration for VPFE input devices */
++      setup_vpfe_input_config(&vpfe_capture_inputs);
+       dm644x_init();
+ }
+diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c
+index 03946fd..f46095e 100644
+--- a/arch/arm/mach-davinci/dm644x.c
++++ b/arch/arm/mach-davinci/dm644x.c
+@@ -419,6 +419,46 @@ static struct platform_device dm644x_edma_device = {
+       .resource               = edma_resources,
+ };
++static struct resource vpfe_resources[] = {
++      {
++              .start          = IRQ_VDINT0,
++              .end            = IRQ_VDINT0,
++              .flags          = IORESOURCE_IRQ,
++      },
++      {
++              .start          = IRQ_VDINT1,
++              .end            = IRQ_VDINT1,
++              .flags          = IORESOURCE_IRQ,
++      },
++      {
++              .start          = 0x01c70400,
++              .end            = 0x01c70400 + 0xff,
++              .flags          = IORESOURCE_MEM,
++      },
++      {
++              .start          = 0x01c73400,
++              .end            = 0x01c73400 + 0xff,
++              .flags          = IORESOURCE_MEM,
++      },
++};
++
++static u64 vpfe_capture_dma_mask = DMA_32BIT_MASK;
++static struct platform_device vpfe_capture_dev = {
++      .name           = CAPTURE_DRV_NAME,
++      .id             = -1,
++      .num_resources  = ARRAY_SIZE(vpfe_resources),
++      .resource       = vpfe_resources,
++      .dev = {
++              .dma_mask               = &vpfe_capture_dma_mask,
++              .coherent_dma_mask      = DMA_32BIT_MASK,
++      },
++};
++
++void setup_vpfe_input_config(struct vpfe_capture_input *input_config)
++{
++      vpfe_capture_dev.dev.platform_data = input_config;
++}
++
+ /*----------------------------------------------------------------------*/
+ void __init dm644x_init(void)
+@@ -433,6 +473,8 @@ static int __init dm644x_init_devices(void)
+               return 0;
+       platform_device_register(&dm644x_edma_device);
++      /* Register VPFE capture device */
++      platform_device_register(&vpfe_capture_dev);
+       return 0;
+ }
+ postcore_initcall(dm644x_init_devices);
+diff --git a/arch/arm/mach-davinci/include/mach/dm644x.h b/arch/arm/mach-davinci/include/mach/dm644x.h
+index 5b3d512..14f9a8a 100644
+--- a/arch/arm/mach-davinci/include/mach/dm644x.h
++++ b/arch/arm/mach-davinci/include/mach/dm644x.h
+@@ -23,7 +23,9 @@
+ #define __ASM_ARCH_DM644X_H
+ #include <mach/hardware.h>
++#include <media/davinci/vpfe_capture.h>
+ void __init dm644x_init(void);
++void setup_vpfe_input_config(struct vpfe_capture_input *input_config);
+ #endif /* __ASM_ARCH_DM644X_H */
+-- 1.6.0.4 
\ No newline at end of file
diff --git a/recipes/linux/linux-davinci/vfpe7.patch b/recipes/linux/linux-davinci/vfpe7.patch
new file mode 100644 (file)
index 0000000..a6695a8
--- /dev/null
@@ -0,0 +1,283 @@
+Subject:
+[PATCH 7/7] DM355 platform related changes for vpfe capture driver
+From:
+m-karicheri2-l0cyMroinI0@public.gmane.org
+Date:
+Fri, 13 Mar 2009 17:24:34 -0400
+To:
+davinci-linux-open-source-VycZQUHpC/PFrsHnngEfi1aTQe2KTcn/@public.gmane.org, davinci_opensource_ccb-uAqBSO/uNfhBDgjK7y7TUQ@public.gmane.org, psp_video-uAqBSO/uNfhBDgjK7y7TUQ@public.gmane.org
+Newsgroups:
+gmane.linux.davinci
+
+Add platform related changes for vpfe capture driver on DM355
+
+Signed-off-by: Murali Karicheri <m-karicheri2-l0cyMroinI0@public.gmane.org>
+---
+ arch/arm/mach-davinci/board-dm355-evm.c    |   91 +++++++++++++++++++++++++++-
+ arch/arm/mach-davinci/dm355.c              |   64 +++++++++++++++++++
+ arch/arm/mach-davinci/include/mach/dm355.h |    2 +
+ arch/arm/mach-davinci/include/mach/mux.h   |    9 +++
+ 4 files changed, 163 insertions(+), 3 deletions(-)
+
+diff --git a/arch/arm/mach-davinci/board-dm355-evm.c b/arch/arm/mach-davinci/board-dm355-evm.c
+index e104650..aaa58ba 100644
+--- a/arch/arm/mach-davinci/board-dm355-evm.c
++++ b/arch/arm/mach-davinci/board-dm355-evm.c
+@@ -20,6 +20,8 @@
+ #include <linux/io.h>
+ #include <linux/gpio.h>
+ #include <linux/clk.h>
++#include <media/v4l2-int-device.h>
++#include <media/tvp514x.h>
+ #include <linux/spi/spi.h>
+ #include <linux/spi/eeprom.h>
+@@ -134,12 +136,58 @@ static void dm355evm_mmcsd_gpios(unsigned gpio)
+       dm355evm_mmc_gpios = gpio;
+ }
++#define TVP5146_I2C_ADDR              0x5D
++static struct v4l2_ifparm tvp5146_ifparm = {
++      .if_type = V4L2_IF_TYPE_BT656,
++      .u = {
++            .bt656 = {
++                      .frame_start_on_rising_vs = 1,
++                      .bt_sync_correct = 0,
++                      .swap = 0,
++                      .latch_clk_inv = 0,
++                      .nobt_hs_inv = 0,       /* active high */
++                      .nobt_vs_inv = 0,       /* active high */
++                      .mode = V4L2_IF_TYPE_BT656_MODE_BT_8BIT,
++                      .clock_min = TVP514X_XCLK_BT656,
++                      .clock_max = TVP514X_XCLK_BT656,
++                      },
++            },
++};
++
++/**
++ * @brief tvp5146_g_ifparm - Returns the TVP5146 decoder interface parameters
++ *
++ * @param p - pointer to v4l2_ifparm structure
++ * @return result of operation - 0 is success
++ */
++static int tvp5146_g_ifparm(struct v4l2_ifparm *p)
++{
++      if (p == NULL)
++              return -EINVAL;
++
++      *p = tvp5146_ifparm;
++      return 0;
++}
++
++#define TVP5146_NUM_INPUTS            ARRAY_SIZE(tvp5146_input_list)
++
++static struct tvp514x_platform_data tvp5146_pdata = {
++      .master = CAPTURE_DRV_NAME,
++      .ifparm = tvp5146_g_ifparm,
++      .hs_polarity = 1,
++      .vs_polarity = 1
++};
++
+ static struct i2c_board_info dm355evm_i2c_info[] = {
+-      { I2C_BOARD_INFO("dm355evm_msp", 0x25),
++      {       I2C_BOARD_INFO("dm355evm_msp", 0x25),
+               .platform_data = dm355evm_mmcsd_gpios,
+-              /* plus irq */ },
++      },
++      {
++              I2C_BOARD_INFO("tvp5146", TVP5146_I2C_ADDR),
++              .platform_data = &tvp5146_pdata,
++      },
++      /* { plus irq  }, */
+       /* { I2C_BOARD_INFO("tlv320aic3x", 0x1b), }, */
+-      /* { I2C_BOARD_INFO("tvp5146", 0x5d), }, */
+ };
+ static void __init evm_init_i2c(void)
+@@ -178,6 +226,41 @@ static struct platform_device dm355evm_dm9000 = {
+       .num_resources  = ARRAY_SIZE(dm355evm_dm9000_rsrc),
+ };
++#define TVP514X_STD_ALL       (V4L2_STD_NTSC | V4L2_STD_PAL)
++
++static struct vpfe_capture_input vpfe_capture_inputs = {
++      .num_inputs = VPFE_MAX_DEC_INPUTS,
++      .current_input = 0,
++      .inputs[0] = {
++              .dec_name = TVP514X_MODULE_NAME,
++              .input = {
++                      .index = 0,
++                      .name = "COMPOSITE",
++                      .type = V4L2_INPUT_TYPE_CAMERA,
++                      .std = TVP514X_STD_ALL,
++              },
++              .route = {
++                      .input = INPUT_CVBS_VI2B,
++                      .output = OUTPUT_10BIT_422_EMBEDDED_SYNC,
++              },
++              .routing_supported = 1,
++      },
++      .inputs[1] = {
++              .dec_name = TVP514X_MODULE_NAME,
++              .input = {
++                      .index = 1,
++                      .name = "SVIDEO",
++                      .type = V4L2_INPUT_TYPE_CAMERA,
++                      .std = TVP514X_STD_ALL,
++              },
++              .route = {
++                      .input = INPUT_SVIDEO_VI2C_VI1C,
++                      .output = OUTPUT_10BIT_422_EMBEDDED_SYNC,
++              },
++              .routing_supported = 1,
++      },
++};
++
+ static struct platform_device *davinci_evm_devices[] __initdata = {
+       &dm355evm_dm9000,
+       &davinci_nand_device,
+@@ -190,6 +273,8 @@ static struct davinci_uart_config uart_config __initdata = {
+ static void __init dm355_evm_map_io(void)
+ {
+       davinci_map_common_io();
++      /* setup input configuration for VPFE input devices */
++      setup_vpfe_input_config(&vpfe_capture_inputs);
+       dm355_init();
+ }
+diff --git a/arch/arm/mach-davinci/dm355.c b/arch/arm/mach-davinci/dm355.c
+index 5f31649..e2612dd 100644
+--- a/arch/arm/mach-davinci/dm355.c
++++ b/arch/arm/mach-davinci/dm355.c
+@@ -463,6 +463,14 @@ INT_CFG(DM355,  INT_EDMA_TC1_ERR,     4,    1,    1,     false)
+ EVT_CFG(DM355,  EVT8_ASP1_TX,       0,    1,    0,     false)
+ EVT_CFG(DM355,  EVT9_ASP1_RX,       1,    1,    0,     false)
+ EVT_CFG(DM355,  EVT26_MMC0_RX,              2,    1,    0,     false)
++
++MUX_CFG(DM355,        VIN_PCLK,       0,   14,    1,    1,     false)
++MUX_CFG(DM355,        VIN_CAM_WEN,    0,   13,    1,    1,     false)
++MUX_CFG(DM355,        VIN_CAM_VD,     0,   12,    1,    1,     false)
++MUX_CFG(DM355,        VIN_CAM_HD,     0,   11,    1,    1,     false)
++MUX_CFG(DM355,        VIN_YIN_EN,     0,   10,    1,    1,     false)
++MUX_CFG(DM355,        VIN_CINL_EN,    0,   0,   0xff, 0x55,    false)
++MUX_CFG(DM355,        VIN_CINH_EN,    0,   8,     3,    3,     false)
+ };
+ /*----------------------------------------------------------------------*/
+@@ -520,6 +528,47 @@ static struct platform_device dm355_edma_device = {
+       .resource               = edma_resources,
+ };
++static struct resource vpfe_resources[] = {
++      {
++              .start          = IRQ_VDINT0,
++              .end            = IRQ_VDINT0,
++              .flags          = IORESOURCE_IRQ,
++      },
++      {
++              .start          = IRQ_VDINT1,
++              .end            = IRQ_VDINT1,
++              .flags          = IORESOURCE_IRQ,
++      },
++      /* CCDC Base address */
++      {
++              .flags          = IORESOURCE_MEM,
++              .start          = 0x01c70600,
++              .end            = 0x01c70600 + 0x1ff,
++      },
++      /* VPSS Base address */
++      {
++              .start          = 0x01c70800,
++              .end            = 0x01c70800 + 0xff,
++              .flags          = IORESOURCE_MEM,
++      },
++};
++
++static u64 vpfe_capture_dma_mask = DMA_32BIT_MASK;
++static struct platform_device vpfe_capture_dev = {
++      .name           = CAPTURE_DRV_NAME,
++      .id             = -1,
++      .num_resources  = ARRAY_SIZE(vpfe_resources),
++      .resource       = vpfe_resources,
++      .dev = {
++              .dma_mask               = &vpfe_capture_dma_mask,
++              .coherent_dma_mask      = DMA_32BIT_MASK,
++      },
++};
++
++void setup_vpfe_input_config(struct vpfe_capture_input *input_config)
++{
++      vpfe_capture_dev.dev.platform_data = input_config;
++}
+ /*----------------------------------------------------------------------*/
+ void __init dm355_init(void)
+@@ -528,13 +577,28 @@ void __init dm355_init(void)
+       davinci_mux_register(dm355_pins, ARRAY_SIZE(dm355_pins));;
+ }
++#define DM355_VPSSCLK_CLKCTRL_REG     0x1c70004
+ static int __init dm355_init_devices(void)
+ {
++      void __iomem *base = IO_ADDRESS(DM355_VPSSCLK_CLKCTRL_REG);
+       if (!cpu_is_davinci_dm355())
+               return 0;
+       davinci_cfg_reg(DM355_INT_EDMA_CC);
+       platform_device_register(&dm355_edma_device);
++      /* setup clock for vpss modules */
++      __raw_writel(0x79, base);
++      /* setup Mux configuration for vpfe input and register
++       * vpfe capture platform device
++       */
++      davinci_cfg_reg(DM355_VIN_PCLK);
++      davinci_cfg_reg(DM355_VIN_CAM_WEN);
++      davinci_cfg_reg(DM355_VIN_CAM_VD);
++      davinci_cfg_reg(DM355_VIN_CAM_HD);
++      davinci_cfg_reg(DM355_VIN_YIN_EN);
++      davinci_cfg_reg(DM355_VIN_CINL_EN);
++      davinci_cfg_reg(DM355_VIN_CINH_EN);
++      platform_device_register(&vpfe_capture_dev);
+       return 0;
+ }
+ postcore_initcall(dm355_init_devices);
+diff --git a/arch/arm/mach-davinci/include/mach/dm355.h b/arch/arm/mach-davinci/include/mach/dm355.h
+index f7100b6..0b3bd76 100644
+--- a/arch/arm/mach-davinci/include/mach/dm355.h
++++ b/arch/arm/mach-davinci/include/mach/dm355.h
+@@ -12,6 +12,7 @@
+ #define __ASM_ARCH_DM355_H
+ #include <mach/hardware.h>
++#include <media/davinci/vpfe_capture.h>
+ void __init dm355_init(void);
+@@ -19,5 +20,6 @@ struct spi_board_info;
+ void dm355_init_spi0(unsigned chipselect_mask,
+               struct spi_board_info *info, unsigned len);
++void setup_vpfe_input_config(struct vpfe_capture_input *input_config);
+ #endif /* __ASM_ARCH_DM355_H */
+diff --git a/arch/arm/mach-davinci/include/mach/mux.h b/arch/arm/mach-davinci/include/mach/mux.h
+index cd95629..4c135b0 100644
+--- a/arch/arm/mach-davinci/include/mach/mux.h
++++ b/arch/arm/mach-davinci/include/mach/mux.h
+@@ -149,6 +149,15 @@ enum davinci_dm355_index {
+       DM355_EVT8_ASP1_TX,
+       DM355_EVT9_ASP1_RX,
+       DM355_EVT26_MMC0_RX,
++
++      /* Video In Pin Mux */
++      DM355_VIN_PCLK,
++      DM355_VIN_CAM_WEN,
++      DM355_VIN_CAM_VD,
++      DM355_VIN_CAM_HD,
++      DM355_VIN_YIN_EN,
++      DM355_VIN_CINL_EN,
++      DM355_VIN_CINH_EN,
+ };
+ #ifdef CONFIG_DAVINCI_MUX
+-- 1.6.0.4 
\ No newline at end of file
index 779f012..332aeb6 100644 (file)
@@ -10,10 +10,17 @@ DEFAULT_PREFERENCE = "-1"
 SRCREV = "486afa37130356662213cc1a2199a285b4fd72af"
 
 PV = "2.6.29+2.6.29-rc7-${PR}+gitr${SRCREV}"
-PR = "r2"
+PR = "r3"
 
 SRC_URI = "git://git.kernel.org/pub/scm/linux/kernel/git/khilman/linux-davinci.git;protocol=git \
            file://update-mach-types.patch;patch=1 \
+           file://vfpe1.patch;patch=1 \
+           file://vfpe2.patch;patch=1 \
+           file://vfpe3.patch;patch=1 \
+           file://vfpe4.patch;patch=1 \
+           file://vfpe5.patch;patch=1 \
+           file://vfpe6.patch;patch=1 \
+           file://vfpe7.patch;patch=1 \
            file://defconfig"
 
 SRC_URI_append_davinci-sffsdr = " \
@@ -33,6 +40,7 @@ SRC_URI_append_davinci-sffsdr = " \
 
 SRC_URI_append_dm355-leopard = " \
           file://0001-dm355-leopard-add-board-file-based-on-board-dm355-e.patch;patch=1 \
-         "
+          file://vfpe.patch;patch=1 \
+"
 
 S = "${WORKDIR}/git"